From e91774fe3b91910a44b3bc10a4572443725083fd Mon Sep 17 00:00:00 2001 From: wancat Date: Tue, 6 Feb 2024 09:20:01 +0800 Subject: [PATCH] refactor utils --- packages/utils/src/{auth.js => auth.ts} | 4 +- .../utils/src/{commands.js => commands.ts} | 13 +++- packages/utils/src/dag.js | 73 ------------------ packages/utils/src/dag.ts | 76 +++++++++++++++++++ packages/utils/src/{index.js => index.ts} | 0 packages/utils/tests/commands.test.ts | 7 +- 6 files changed, 93 insertions(+), 80 deletions(-) rename packages/utils/src/{auth.js => auth.ts} (87%) rename packages/utils/src/{commands.js => commands.ts} (50%) delete mode 100644 packages/utils/src/dag.js create mode 100644 packages/utils/src/dag.ts rename packages/utils/src/{index.js => index.ts} (100%) diff --git a/packages/utils/src/auth.js b/packages/utils/src/auth.ts similarity index 87% rename from packages/utils/src/auth.js rename to packages/utils/src/auth.ts index 59caef6..b3170e1 100644 --- a/packages/utils/src/auth.js +++ b/packages/utils/src/auth.ts @@ -1,4 +1,4 @@ -export function isValidUsername(username) { +export function isValidUsername(username: string): boolean { // check if the username is between 1 and 32 characters if (username.length > 32) { return false @@ -29,7 +29,7 @@ export function isValidUsername(username) { return true } -export function isValidEmail(email) { +export function isValidEmail(email: string): boolean { // Define a regular expression pattern for a valid email address. const emailPattern = /^[\w-.+]+@([\w][\w-]*\.)+[\w-]{2,}$/ diff --git a/packages/utils/src/commands.js b/packages/utils/src/commands.ts similarity index 50% rename from packages/utils/src/commands.js rename to packages/utils/src/commands.ts index c64a33a..b40ea2e 100644 --- a/packages/utils/src/commands.js +++ b/packages/utils/src/commands.ts @@ -3,14 +3,21 @@ const fileTypes = { folder: '-d', link: '-L', socket: '-S', + unknown: '-e', } -function sanitizePath(path) { +export type FileType = keyof typeof fileTypes + +export type File = { + path: string + type: FileType +} + +function sanitizePath(path: string): string { return path.replace(/[^a-zA-Z0-9._/-]/g, '') } -// eslint-disable-next-line import/prefer-default-export -export function buildFileCheckCmd(file) { +export function buildFileCheckCmd(file: File): string[] { const { path, type } = file return ['test', fileTypes[type] || '-e', sanitizePath(path)] } diff --git a/packages/utils/src/dag.js b/packages/utils/src/dag.js deleted file mode 100644 index 6a3a911..0000000 --- a/packages/utils/src/dag.js +++ /dev/null @@ -1,73 +0,0 @@ -export default class DAG { - #nodes = new Map() - - #edges = new Set() - - #layers = [] - - constructor(nodes) { - this.#nodes = new Map(nodes.map((node) => [node._id, node])) - this.#edges = new Set() - this.#nodes.forEach((_, id) => { - this.#setLayer(id) - this.#addEdges(id) - }) - } - - getNode(id) { - return this.#nodes.get(id) - } - - getNodes() { - return Array.from(this.#nodes.values()) - } - - getEdges() { - return this.#edges - } - - getEdgesArray() { - return Array.from(this.#edges.values()) - } - - getLayers() { - return this.#layers - } - - getLayer(id) { - const node = this.getNode(id) - if (!node) { - throw new Error(`Node ${id} not found`) - } - return this.#layers[node.layer - 1] - } - - #setLayer(id) { - const node = this.getNode(id) - if (!node) { - throw new Error(`Node ${id} not found`) - } - if (node.layer !== undefined) { - return node.layer - } - const previousLayer = node.requirements.map((rId) => this.#setLayer(rId)) - node.layer = Math.max(...previousLayer, 0) + 1 - if (this.#layers.length < node.layer) { - this.#layers.push(1) - } else { - this.#layers[node.layer - 1] += 1 - } - node.index = this.#layers[node.layer - 1] - return node.layer - } - - #addEdges(id) { - const node = this.getNode(id) - if (!node) { - throw new Error(`Node ${id} not found`) - } - node.requirements.forEach((rId) => { - this.#edges.add([rId, id]) - }) - } -} diff --git a/packages/utils/src/dag.ts b/packages/utils/src/dag.ts new file mode 100644 index 0000000..b428e80 --- /dev/null +++ b/packages/utils/src/dag.ts @@ -0,0 +1,76 @@ +interface Node { + _id: string + requirements: string[] +} + +export default class DAG { + private nodes = new Map() + private edges = new Set() + private layers: number[] = [] + + constructor(nodes: Node[]) { + this.nodes = new Map(nodes.map((node) => [node._id, node])) + this.edges = new Set() + this.nodes.forEach((_, id) => { + this.setLayer(id) + this.addEdges(id) + }) + } + + getNode(id: string) { + return this.nodes.get(id) + } + + getNodes() { + return Array.from(this.nodes.values()) + } + + getEdges() { + return this.edges + } + + getEdgesArray() { + return Array.from(this.edges.values()) + } + + getLayers() { + return this.layers + } + + getLayer(id: string) { + const node = this.getNode(id) + if (!node) { + throw new Error(`Node ${id} not found`) + } + return this.layers[node.layer - 1] + } + + private setLayer(id: string) { + const node = this.getNode(id) + if (!node) { + throw new Error(`Node ${id} not found`) + } + if (node.layer !== undefined) { + return node.layer + } + const previousLayer = node.requirements.map((rId: string) => this.setLayer(rId)) + node.layer = Math.max(...previousLayer, 0) + 1 + if (this.layers.length < node.layer) { + this.layers.push(1) + } else { + this.layers[node.layer - 1] += 1 + } + node.index = this.layers[node.layer - 1] + return node.layer + } + + addEdges(id: string) { + const node = this.getNode(id) + if (!node) { + throw new Error(`Node ${id} not found`) + } + node.requirements.forEach((rId: string) => { + this.edges.add([rId, id]) + }) + } +} diff --git a/packages/utils/src/index.js b/packages/utils/src/index.ts similarity index 100% rename from packages/utils/src/index.js rename to packages/utils/src/index.ts diff --git a/packages/utils/tests/commands.test.ts b/packages/utils/tests/commands.test.ts index 9ac76ff..e1888ca 100644 --- a/packages/utils/tests/commands.test.ts +++ b/packages/utils/tests/commands.test.ts @@ -1,8 +1,11 @@ -import { buildFileCheckCmd } from '../src/commands' +import { buildFileCheckCmd, File } from '../src/commands' describe('buildFileCheckCmd function', () => { it('builds the file check command correctly', () => { - const testcases = [ + const testcases: { + input: File + output: string[] + }[] = [ { input: { path: '/etc/passwd', type: 'file' }, output: ['test', '-f', '/etc/passwd'],