shell-dsl 0.0.18 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -0
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/src/commands/awk/awk.cjs +4 -2
- package/dist/cjs/src/commands/awk/awk.cjs.map +3 -3
- package/dist/cjs/src/commands/echo/echo.cjs +11 -4
- package/dist/cjs/src/commands/echo/echo.cjs.map +3 -3
- package/dist/cjs/src/commands/grep/grep.cjs +3 -2
- package/dist/cjs/src/commands/grep/grep.cjs.map +3 -3
- package/dist/cjs/src/commands/sed/sed.cjs +3 -2
- package/dist/cjs/src/commands/sed/sed.cjs.map +3 -3
- package/dist/cjs/src/commands/tr/tr.cjs +3 -43
- package/dist/cjs/src/commands/tr/tr.cjs.map +3 -3
- package/dist/cjs/src/fs/real-fs.cjs.map +2 -2
- package/dist/cjs/src/utils/expand-escapes.cjs +77 -0
- package/dist/cjs/src/utils/expand-escapes.cjs.map +10 -0
- package/dist/cjs/src/utils/index.cjs +3 -1
- package/dist/cjs/src/utils/index.cjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/src/commands/awk/awk.mjs +4 -2
- package/dist/mjs/src/commands/awk/awk.mjs.map +3 -3
- package/dist/mjs/src/commands/echo/echo.mjs +11 -4
- package/dist/mjs/src/commands/echo/echo.mjs.map +3 -3
- package/dist/mjs/src/commands/grep/grep.mjs +3 -2
- package/dist/mjs/src/commands/grep/grep.mjs.map +3 -3
- package/dist/mjs/src/commands/sed/sed.mjs +3 -2
- package/dist/mjs/src/commands/sed/sed.mjs.map +3 -3
- package/dist/mjs/src/commands/tr/tr.mjs +2 -42
- package/dist/mjs/src/commands/tr/tr.mjs.map +3 -3
- package/dist/mjs/src/fs/real-fs.mjs.map +2 -2
- package/dist/mjs/src/utils/expand-escapes.mjs +47 -0
- package/dist/mjs/src/utils/expand-escapes.mjs.map +10 -0
- package/dist/mjs/src/utils/index.mjs +3 -1
- package/dist/mjs/src/utils/index.mjs.map +3 -3
- package/dist/types/src/fs/real-fs.d.ts +2 -2
- package/dist/types/src/utils/expand-escapes.d.ts +1 -0
- package/dist/types/src/utils/index.d.ts +1 -0
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/commands/sed/sed.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type { Command } from \"../../types.cjs\";\n\ninterface SedCommand {\n type: \"s\" | \"d\" | \"p\" | \"h\" | \"H\" | \"g_hold\" | \"G\" | \"x\" | \"n\" | \"N\" | \"P\" | \"D\" | \"b\" | \"label\" | \"group\";\n addressPattern?: RegExp;\n negated?: boolean;\n pattern?: RegExp;\n replacement?: string;\n globalFlag: boolean;\n printFlag: boolean;\n label?: string;\n children?: SedCommand[];\n}\n\ninterface SedOptions {\n suppressOutput: boolean; // -n\n inPlace: boolean; // -i\n commands: SedCommand[];\n}\n\nfunction parseSubstitution(script: string): SedCommand | null {\n const match = script.match(/^s(.)(.+?)\\1(.*?)\\1([gi]*)$/);\n if (!match) return null;\n\n const [, , rawPattern, rawReplacement, flags] = match;\n const globalFlag = flags!.includes(\"g\");\n const caseInsensitive = flags!.includes(\"i\");\n\n const patternStr = rawPattern!.replace(/\\\\\\(/g, \"(\").replace(/\\\\\\)/g, \")\");\n const replacement = rawReplacement!\n .replace(/\\\\([0-9])/g, \"\\x00BACKREF$1\\x00\")\n .replace(/\\$/g, \"$$$$\")\n .replace(/\\x00BACKREF([0-9])\\x00/g, \"$$$1\");\n\n try {\n const regexFlags = caseInsensitive ? \"i\" : \"\";\n return {\n type: \"s\",\n pattern: new RegExp(patternStr, regexFlags),\n replacement,\n globalFlag,\n printFlag: false,\n };\n } catch {\n return null;\n }\n}\n\nfunction parseCommand(script: string): SedCommand | null {\n const trimmed = script.trim();\n\n // Label command :name\n if (trimmed.startsWith(\":\")) {\n return {\n type: \"label\",\n label: trimmed.slice(1).trim(),\n globalFlag: false,\n printFlag: false,\n };\n }\n\n // Branch command: b or b label\n if (trimmed === \"b\" || trimmed.startsWith(\"b \") || trimmed.startsWith(\"b\\t\")) {\n return {\n type: \"b\",\n label: trimmed.length > 1 ? trimmed.slice(1).trim() : undefined,\n globalFlag: false,\n printFlag: false,\n };\n }\n\n // Group { ... }\n if (trimmed.startsWith(\"{\") && trimmed.endsWith(\"}\")) {\n const inner = trimmed.slice(1, -1).trim();\n const parts = splitScriptParts(inner);\n const children: SedCommand[] = [];\n for (const part of parts) {\n const cmd = parseCommand(part);\n if (cmd) children.push(cmd);\n }\n return {\n type: \"group\",\n children,\n globalFlag: false,\n printFlag: false,\n };\n }\n\n // Simple single-char commands (no address)\n const simpleCommands: Record<string, SedCommand[\"type\"]> = {\n h: \"h\",\n H: \"H\",\n g: \"g_hold\",\n G: \"G\",\n x: \"x\",\n n: \"n\",\n N: \"N\",\n P: \"P\",\n D: \"D\",\n d: \"d\",\n p: \"p\",\n };\n if (simpleCommands[trimmed]) {\n return {\n type: simpleCommands[trimmed]!,\n globalFlag: false,\n printFlag: false,\n };\n }\n\n // Check for address pattern: /pattern/ followed by optional ! and command\n const addressWithCmd = trimmed.match(/^\\/(.+?)\\/(!)?\\s*(.*)$/);\n if (addressWithCmd) {\n const [, addressPatternStr, negation, rest] = addressWithCmd;\n const negated = negation === \"!\";\n const restTrimmed = rest!.trim();\n\n try {\n const addressPattern = new RegExp(addressPatternStr!);\n\n // /pattern/ alone — not valid, but handle gracefully\n if (!restTrimmed) return null;\n\n // /pattern/[!]d or /pattern/[!]p etc (simple commands)\n if (simpleCommands[restTrimmed]) {\n return {\n type: simpleCommands[restTrimmed]!,\n addressPattern,\n negated,\n globalFlag: false,\n printFlag: false,\n };\n }\n\n // /pattern/[!]b or /pattern/[!]b label\n if (restTrimmed === \"b\" || restTrimmed.startsWith(\"b \")) {\n return {\n type: \"b\",\n addressPattern,\n negated,\n label: restTrimmed.length > 1 ? restTrimmed.slice(1).trim() : undefined,\n globalFlag: false,\n printFlag: false,\n };\n }\n\n // /pattern/[!]{ ... }\n if (restTrimmed.startsWith(\"{\") && restTrimmed.endsWith(\"}\")) {\n const inner = restTrimmed.slice(1, -1).trim();\n const parts = splitScriptParts(inner);\n const children: SedCommand[] = [];\n for (const part of parts) {\n const cmd = parseCommand(part);\n if (cmd) children.push(cmd);\n }\n return {\n type: \"group\",\n addressPattern,\n negated,\n children,\n globalFlag: false,\n printFlag: false,\n };\n }\n\n // /pattern/[!]s/old/new/flags\n const subCmd = parseSubstitution(restTrimmed);\n if (subCmd) {\n subCmd.addressPattern = addressPattern;\n subCmd.negated = negated;\n return subCmd;\n }\n } catch {\n return null;\n }\n }\n\n // Substitution command (no address)\n const subCmd = parseSubstitution(trimmed);\n if (subCmd) return subCmd;\n\n return null;\n}\n\nfunction splitScriptParts(script: string): string[] {\n const parts: string[] = [];\n let i = 0;\n let current = \"\";\n let braceDepth = 0;\n\n while (i < script.length) {\n if (script[i] === \"{\") {\n braceDepth++;\n current += script[i];\n i++;\n } else if (script[i] === \"}\") {\n braceDepth--;\n current += script[i];\n i++;\n } else if (script[i] === \"s\" && braceDepth === 0 && i + 1 < script.length && !/[a-zA-Z0-9]/.test(script[i + 1]!)) {\n // Detect substitution command — consume s/pattern/replacement/flags\n const delim = script[i + 1]!;\n let j = i + 2;\n let delimCount = 0;\n while (j < script.length && delimCount < 2) {\n if (script[j] === \"\\\\\") {\n j += 2;\n continue;\n }\n if (script[j] === delim) delimCount++;\n j++;\n }\n // Consume trailing flags\n while (j < script.length && /[gi]/.test(script[j]!)) j++;\n current += script.slice(i, j);\n i = j;\n } else if (script[i] === \";\" && braceDepth === 0) {\n const trimmed = current.trim();\n if (trimmed) parts.push(trimmed);\n current = \"\";\n i++;\n } else {\n current += script[i];\n i++;\n }\n }\n const trimmed = current.trim();\n if (trimmed) parts.push(trimmed);\n return parts;\n}\n\ninterface ParseArgsResult {\n options: SedOptions;\n files: string[];\n error?: { type: \"unrecognized_option\" | \"missing_value\"; option: string };\n}\n\nfunction parseArgs(args: string[]): ParseArgsResult {\n const options: SedOptions = {\n suppressOutput: false,\n inPlace: false,\n commands: [],\n };\n const files: string[] = [];\n\n let i = 0;\n while (i < args.length) {\n const arg = args[i]!;\n\n if (arg === \"--\") {\n i++;\n while (i < args.length) {\n const remaining = args[i]!;\n if (options.commands.length === 0) {\n const parts = splitScriptParts(remaining);\n for (const part of parts) {\n const cmd = parseCommand(part);\n if (cmd) options.commands.push(cmd);\n }\n } else {\n files.push(remaining);\n }\n i++;\n }\n break;\n }\n\n if (arg.startsWith(\"--\")) {\n return {\n options,\n files,\n error: { type: \"unrecognized_option\", option: arg },\n };\n }\n\n if (arg.startsWith(\"-\") && arg.length > 1) {\n const flagChars = arg.slice(1);\n\n for (let j = 0; j < flagChars.length; j++) {\n const char = flagChars[j]!;\n\n if (char === \"n\") {\n options.suppressOutput = true;\n } else if (char === \"i\") {\n options.inPlace = true;\n } else if (char === \"e\") {\n const restOfArg = flagChars.slice(j + 1);\n let script: string;\n\n if (restOfArg.length > 0) {\n script = restOfArg;\n } else if (i + 1 < args.length) {\n script = args[++i]!;\n } else {\n return {\n options,\n files,\n error: { type: \"missing_value\", option: \"-e\" },\n };\n }\n\n const parts = splitScriptParts(script);\n for (const part of parts) {\n const cmd = parseCommand(part);\n if (cmd) options.commands.push(cmd);\n }\n break;\n } else {\n return {\n options,\n files,\n error: { type: \"unrecognized_option\", option: `-${char}` },\n };\n }\n }\n i++;\n continue;\n }\n\n if (options.commands.length === 0) {\n const parts = splitScriptParts(arg);\n for (const part of parts) {\n const cmd = parseCommand(part);\n if (cmd) options.commands.push(cmd);\n }\n } else {\n files.push(arg);\n }\n i++;\n }\n\n return { options, files };\n}\n\nfunction formatError(error: NonNullable<ParseArgsResult[\"error\"]>): string {\n let message: string;\n if (error.type === \"unrecognized_option\") {\n if (error.option.startsWith(\"--\")) {\n message = `sed: unrecognized option '${error.option}'\\n`;\n } else {\n message = `sed: invalid option -- '${error.option.slice(1)}'\\n`;\n }\n } else {\n message = `sed: option '${error.option}' requires an argument\\n`;\n }\n return message + `usage: sed [-ni] [-e script] script [file ...]\\n`;\n}\n\nfunction applySubstitution(line: string, cmd: SedCommand): string {\n if (!cmd.pattern) return line;\n\n if (cmd.globalFlag) {\n return line.replace(new RegExp(cmd.pattern.source, cmd.pattern.flags + \"g\"), cmd.replacement!);\n } else {\n return line.replace(cmd.pattern, cmd.replacement!);\n }\n}\n\ninterface SedState {\n patternSpace: string;\n holdSpace: string;\n lineIndex: number;\n lines: string[];\n suppressOutput: boolean;\n output: string[];\n deleted: boolean;\n restart: boolean; // for D command\n}\n\nfunction addressMatches(cmd: SedCommand, state: SedState): boolean {\n if (!cmd.addressPattern) {\n return cmd.negated ? false : true;\n }\n const matches = cmd.addressPattern.test(state.patternSpace);\n return cmd.negated ? !matches : matches;\n}\n\nfunction findLabel(commands: SedCommand[], label: string): number {\n for (let i = 0; i < commands.length; i++) {\n if (commands[i]!.type === \"label\" && commands[i]!.label === label) {\n return i;\n }\n }\n return -1;\n}\n\ninterface ExecResult {\n branchToEnd: boolean;\n branchLabel?: string;\n nextLine: boolean; // n command: output and advance\n deleted: boolean;\n restart: boolean; // D command\n}\n\nfunction executeCommands(\n commands: SedCommand[],\n state: SedState,\n topLevel: boolean\n): ExecResult {\n let pc = 0;\n while (pc < commands.length) {\n const cmd = commands[pc]!;\n\n // Labels are no-ops\n if (cmd.type === \"label\") {\n pc++;\n continue;\n }\n\n // Check address\n if (!addressMatches(cmd, state)) {\n pc++;\n continue;\n }\n\n switch (cmd.type) {\n case \"s\":\n state.patternSpace = applySubstitution(state.patternSpace, cmd);\n break;\n case \"d\":\n state.deleted = true;\n return { branchToEnd: false, deleted: true, nextLine: false, restart: false };\n case \"p\":\n state.output.push(state.patternSpace);\n break;\n case \"h\":\n state.holdSpace = state.patternSpace;\n break;\n case \"H\":\n state.holdSpace = state.holdSpace + \"\\n\" + state.patternSpace;\n break;\n case \"g_hold\":\n state.patternSpace = state.holdSpace;\n break;\n case \"G\":\n state.patternSpace = state.patternSpace + \"\\n\" + state.holdSpace;\n break;\n case \"x\": {\n const tmp = state.patternSpace;\n state.patternSpace = state.holdSpace;\n state.holdSpace = tmp;\n break;\n }\n case \"n\":\n // Output current pattern space, then read next line\n if (!state.suppressOutput) {\n state.output.push(state.patternSpace);\n }\n state.lineIndex++;\n if (state.lineIndex < state.lines.length) {\n state.patternSpace = state.lines[state.lineIndex]!;\n } else {\n // No more lines\n state.deleted = true;\n return { branchToEnd: false, deleted: true, nextLine: false, restart: false };\n }\n break;\n case \"N\":\n // Append next line to pattern space\n state.lineIndex++;\n if (state.lineIndex < state.lines.length) {\n state.patternSpace = state.patternSpace + \"\\n\" + state.lines[state.lineIndex]!;\n } else {\n // No more lines: output pattern space and exit (POSIX behavior)\n if (!state.suppressOutput) {\n state.output.push(state.patternSpace);\n }\n state.deleted = true;\n return { branchToEnd: false, deleted: true, nextLine: false, restart: false };\n }\n break;\n case \"P\": {\n // Print up to first \\n\n const nlIdx = state.patternSpace.indexOf(\"\\n\");\n if (nlIdx >= 0) {\n state.output.push(state.patternSpace.slice(0, nlIdx));\n } else {\n state.output.push(state.patternSpace);\n }\n break;\n }\n case \"D\": {\n // Delete up to first \\n, restart; if no \\n, delete all\n const nlIdx2 = state.patternSpace.indexOf(\"\\n\");\n if (nlIdx2 >= 0) {\n state.patternSpace = state.patternSpace.slice(nlIdx2 + 1);\n state.restart = true;\n return { branchToEnd: false, deleted: false, nextLine: false, restart: true };\n } else {\n state.deleted = true;\n return { branchToEnd: false, deleted: true, nextLine: false, restart: false };\n }\n }\n case \"b\":\n if (cmd.label) {\n // Branch to label — only works at top level\n if (topLevel) {\n const idx = findLabel(commands, cmd.label);\n if (idx >= 0) {\n pc = idx;\n continue;\n }\n }\n // Label not found or not top-level: branch to end\n return { branchToEnd: true, branchLabel: cmd.label, deleted: false, nextLine: false, restart: false };\n }\n // No label: branch to end of script\n return { branchToEnd: true, deleted: false, nextLine: false, restart: false };\n case \"group\":\n if (cmd.children) {\n const result = executeCommands(cmd.children, state, false);\n if (result.deleted || result.branchToEnd || result.restart) {\n // Propagate branch labels up for top-level resolution\n if (result.branchLabel && topLevel) {\n const idx = findLabel(commands, result.branchLabel);\n if (idx >= 0) {\n pc = idx;\n continue;\n }\n }\n return result;\n }\n }\n break;\n }\n pc++;\n }\n return { branchToEnd: false, deleted: false, nextLine: false, restart: false };\n}\n\nexport const sed: Command = async (ctx) => {\n const { options, files, error } = parseArgs(ctx.args);\n\n if (error) {\n await ctx.stderr.writeText(formatError(error));\n return 1;\n }\n\n if (options.commands.length === 0) {\n await ctx.stderr.writeText(\"sed: missing script\\n\");\n return 1;\n }\n\n const processContent = async (content: string): Promise<string[]> => {\n const lines = content.split(\"\\n\");\n if (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n\n const allOutput: string[] = [];\n const state: SedState = {\n patternSpace: \"\",\n holdSpace: \"\",\n lineIndex: 0,\n lines,\n suppressOutput: options.suppressOutput,\n output: [],\n deleted: false,\n restart: false,\n };\n\n while (state.lineIndex < lines.length) {\n state.patternSpace = lines[state.lineIndex]!;\n state.deleted = false;\n state.output = [];\n\n // Execute commands, possibly restarting on D\n let restarting = true;\n while (restarting) {\n restarting = false;\n state.restart = false;\n const result = executeCommands(options.commands, state, true);\n\n if (result.restart) {\n restarting = true;\n // output collected so far in this cycle goes out\n allOutput.push(...state.output);\n state.output = [];\n continue;\n }\n\n if (result.deleted) {\n allOutput.push(...state.output);\n state.lineIndex++;\n break;\n }\n\n // Normal end: collect printed lines, then auto-print\n allOutput.push(...state.output);\n if (!options.suppressOutput) {\n allOutput.push(state.patternSpace);\n }\n state.lineIndex++;\n }\n }\n\n return allOutput;\n };\n\n if (files.length === 0) {\n const content = await ctx.stdin.text();\n const outputLines = await processContent(content);\n for (const line of outputLines) {\n await ctx.stdout.writeText(line + \"\\n\");\n }\n } else if (options.inPlace) {\n for (const file of files) {\n try {\n const path = ctx.fs.resolve(ctx.cwd, file);\n const content = await ctx.fs.readFile(path);\n const outputLines = await processContent(content.toString());\n const result = outputLines.length > 0 ? outputLines.join(\"\\n\") + \"\\n\" : \"\";\n await ctx.fs.writeFile(path, result);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n await ctx.stderr.writeText(`sed: ${file}: ${message}\\n`);\n return 1;\n }\n }\n } else {\n for (const file of files) {\n try {\n const path = ctx.fs.resolve(ctx.cwd, file);\n const content = await ctx.fs.readFile(path);\n const outputLines = await processContent(content.toString());\n for (const line of outputLines) {\n await ctx.stdout.writeText(line + \"\\n\");\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n await ctx.stderr.writeText(`sed: ${file}: ${message}\\n`);\n return 1;\n }\n }\n }\n\n return 0;\n};\n"
|
|
5
|
+
"import type { Command } from \"../../types.cjs\";\n\ninterface SedCommand {\n type: \"s\" | \"d\" | \"p\" | \"h\" | \"H\" | \"g_hold\" | \"G\" | \"x\" | \"n\" | \"N\" | \"P\" | \"D\" | \"b\" | \"label\" | \"group\";\n addressPattern?: RegExp;\n negated?: boolean;\n pattern?: RegExp;\n replacement?: string;\n globalFlag: boolean;\n printFlag: boolean;\n label?: string;\n children?: SedCommand[];\n}\n\ninterface SedOptions {\n suppressOutput: boolean; // -n\n inPlace: boolean; // -i\n commands: SedCommand[];\n}\n\nfunction parseSubstitution(script: string): SedCommand | null {\n const match = script.match(/^s(.)(.+?)\\1(.*?)\\1([gi]*)$/);\n if (!match) return null;\n\n const [, , rawPattern, rawReplacement, flags] = match;\n const globalFlag = flags!.includes(\"g\");\n const caseInsensitive = flags!.includes(\"i\");\n\n const patternStr = rawPattern!.replace(/\\\\\\(/g, \"(\").replace(/\\\\\\)/g, \")\");\n const replacement = rawReplacement!\n .replace(/\\\\([0-9])/g, \"\\x00BACKREF$1\\x00\")\n .replace(/\\\\n/g, \"\\n\")\n .replace(/\\\\t/g, \"\\t\")\n .replace(/\\\\\\\\/g, \"\\x00BSLASH\\x00\")\n .replace(/\\$/g, \"$$$$\")\n .replace(/\\x00BACKREF([0-9])\\x00/g, \"$$$1\")\n .replace(/\\x00BSLASH\\x00/g, \"\\\\\");\n\n try {\n const regexFlags = caseInsensitive ? \"i\" : \"\";\n return {\n type: \"s\",\n pattern: new RegExp(patternStr, regexFlags),\n replacement,\n globalFlag,\n printFlag: false,\n };\n } catch {\n return null;\n }\n}\n\nfunction parseCommand(script: string): SedCommand | null {\n const trimmed = script.trim();\n\n // Label command :name\n if (trimmed.startsWith(\":\")) {\n return {\n type: \"label\",\n label: trimmed.slice(1).trim(),\n globalFlag: false,\n printFlag: false,\n };\n }\n\n // Branch command: b or b label\n if (trimmed === \"b\" || trimmed.startsWith(\"b \") || trimmed.startsWith(\"b\\t\")) {\n return {\n type: \"b\",\n label: trimmed.length > 1 ? trimmed.slice(1).trim() : undefined,\n globalFlag: false,\n printFlag: false,\n };\n }\n\n // Group { ... }\n if (trimmed.startsWith(\"{\") && trimmed.endsWith(\"}\")) {\n const inner = trimmed.slice(1, -1).trim();\n const parts = splitScriptParts(inner);\n const children: SedCommand[] = [];\n for (const part of parts) {\n const cmd = parseCommand(part);\n if (cmd) children.push(cmd);\n }\n return {\n type: \"group\",\n children,\n globalFlag: false,\n printFlag: false,\n };\n }\n\n // Simple single-char commands (no address)\n const simpleCommands: Record<string, SedCommand[\"type\"]> = {\n h: \"h\",\n H: \"H\",\n g: \"g_hold\",\n G: \"G\",\n x: \"x\",\n n: \"n\",\n N: \"N\",\n P: \"P\",\n D: \"D\",\n d: \"d\",\n p: \"p\",\n };\n if (simpleCommands[trimmed]) {\n return {\n type: simpleCommands[trimmed]!,\n globalFlag: false,\n printFlag: false,\n };\n }\n\n // Check for address pattern: /pattern/ followed by optional ! and command\n const addressWithCmd = trimmed.match(/^\\/(.+?)\\/(!)?\\s*(.*)$/);\n if (addressWithCmd) {\n const [, addressPatternStr, negation, rest] = addressWithCmd;\n const negated = negation === \"!\";\n const restTrimmed = rest!.trim();\n\n try {\n const addressPattern = new RegExp(addressPatternStr!);\n\n // /pattern/ alone — not valid, but handle gracefully\n if (!restTrimmed) return null;\n\n // /pattern/[!]d or /pattern/[!]p etc (simple commands)\n if (simpleCommands[restTrimmed]) {\n return {\n type: simpleCommands[restTrimmed]!,\n addressPattern,\n negated,\n globalFlag: false,\n printFlag: false,\n };\n }\n\n // /pattern/[!]b or /pattern/[!]b label\n if (restTrimmed === \"b\" || restTrimmed.startsWith(\"b \")) {\n return {\n type: \"b\",\n addressPattern,\n negated,\n label: restTrimmed.length > 1 ? restTrimmed.slice(1).trim() : undefined,\n globalFlag: false,\n printFlag: false,\n };\n }\n\n // /pattern/[!]{ ... }\n if (restTrimmed.startsWith(\"{\") && restTrimmed.endsWith(\"}\")) {\n const inner = restTrimmed.slice(1, -1).trim();\n const parts = splitScriptParts(inner);\n const children: SedCommand[] = [];\n for (const part of parts) {\n const cmd = parseCommand(part);\n if (cmd) children.push(cmd);\n }\n return {\n type: \"group\",\n addressPattern,\n negated,\n children,\n globalFlag: false,\n printFlag: false,\n };\n }\n\n // /pattern/[!]s/old/new/flags\n const subCmd = parseSubstitution(restTrimmed);\n if (subCmd) {\n subCmd.addressPattern = addressPattern;\n subCmd.negated = negated;\n return subCmd;\n }\n } catch {\n return null;\n }\n }\n\n // Substitution command (no address)\n const subCmd = parseSubstitution(trimmed);\n if (subCmd) return subCmd;\n\n return null;\n}\n\nfunction splitScriptParts(script: string): string[] {\n const parts: string[] = [];\n let i = 0;\n let current = \"\";\n let braceDepth = 0;\n\n while (i < script.length) {\n if (script[i] === \"{\") {\n braceDepth++;\n current += script[i];\n i++;\n } else if (script[i] === \"}\") {\n braceDepth--;\n current += script[i];\n i++;\n } else if (script[i] === \"s\" && braceDepth === 0 && i + 1 < script.length && !/[a-zA-Z0-9]/.test(script[i + 1]!)) {\n // Detect substitution command — consume s/pattern/replacement/flags\n const delim = script[i + 1]!;\n let j = i + 2;\n let delimCount = 0;\n while (j < script.length && delimCount < 2) {\n if (script[j] === \"\\\\\") {\n j += 2;\n continue;\n }\n if (script[j] === delim) delimCount++;\n j++;\n }\n // Consume trailing flags\n while (j < script.length && /[gi]/.test(script[j]!)) j++;\n current += script.slice(i, j);\n i = j;\n } else if (script[i] === \";\" && braceDepth === 0) {\n const trimmed = current.trim();\n if (trimmed) parts.push(trimmed);\n current = \"\";\n i++;\n } else {\n current += script[i];\n i++;\n }\n }\n const trimmed = current.trim();\n if (trimmed) parts.push(trimmed);\n return parts;\n}\n\ninterface ParseArgsResult {\n options: SedOptions;\n files: string[];\n error?: { type: \"unrecognized_option\" | \"missing_value\"; option: string };\n}\n\nfunction parseArgs(args: string[]): ParseArgsResult {\n const options: SedOptions = {\n suppressOutput: false,\n inPlace: false,\n commands: [],\n };\n const files: string[] = [];\n\n let i = 0;\n while (i < args.length) {\n const arg = args[i]!;\n\n if (arg === \"--\") {\n i++;\n while (i < args.length) {\n const remaining = args[i]!;\n if (options.commands.length === 0) {\n const parts = splitScriptParts(remaining);\n for (const part of parts) {\n const cmd = parseCommand(part);\n if (cmd) options.commands.push(cmd);\n }\n } else {\n files.push(remaining);\n }\n i++;\n }\n break;\n }\n\n if (arg.startsWith(\"--\")) {\n return {\n options,\n files,\n error: { type: \"unrecognized_option\", option: arg },\n };\n }\n\n if (arg.startsWith(\"-\") && arg.length > 1) {\n const flagChars = arg.slice(1);\n\n for (let j = 0; j < flagChars.length; j++) {\n const char = flagChars[j]!;\n\n if (char === \"n\") {\n options.suppressOutput = true;\n } else if (char === \"i\") {\n options.inPlace = true;\n } else if (char === \"e\") {\n const restOfArg = flagChars.slice(j + 1);\n let script: string;\n\n if (restOfArg.length > 0) {\n script = restOfArg;\n } else if (i + 1 < args.length) {\n script = args[++i]!;\n } else {\n return {\n options,\n files,\n error: { type: \"missing_value\", option: \"-e\" },\n };\n }\n\n const parts = splitScriptParts(script);\n for (const part of parts) {\n const cmd = parseCommand(part);\n if (cmd) options.commands.push(cmd);\n }\n break;\n } else {\n return {\n options,\n files,\n error: { type: \"unrecognized_option\", option: `-${char}` },\n };\n }\n }\n i++;\n continue;\n }\n\n if (options.commands.length === 0) {\n const parts = splitScriptParts(arg);\n for (const part of parts) {\n const cmd = parseCommand(part);\n if (cmd) options.commands.push(cmd);\n }\n } else {\n files.push(arg);\n }\n i++;\n }\n\n return { options, files };\n}\n\nfunction formatError(error: NonNullable<ParseArgsResult[\"error\"]>): string {\n let message: string;\n if (error.type === \"unrecognized_option\") {\n if (error.option.startsWith(\"--\")) {\n message = `sed: unrecognized option '${error.option}'\\n`;\n } else {\n message = `sed: invalid option -- '${error.option.slice(1)}'\\n`;\n }\n } else {\n message = `sed: option '${error.option}' requires an argument\\n`;\n }\n return message + `usage: sed [-ni] [-e script] script [file ...]\\n`;\n}\n\nfunction applySubstitution(line: string, cmd: SedCommand): string {\n if (!cmd.pattern) return line;\n\n if (cmd.globalFlag) {\n return line.replace(new RegExp(cmd.pattern.source, cmd.pattern.flags + \"g\"), cmd.replacement!);\n } else {\n return line.replace(cmd.pattern, cmd.replacement!);\n }\n}\n\ninterface SedState {\n patternSpace: string;\n holdSpace: string;\n lineIndex: number;\n lines: string[];\n suppressOutput: boolean;\n output: string[];\n deleted: boolean;\n restart: boolean; // for D command\n}\n\nfunction addressMatches(cmd: SedCommand, state: SedState): boolean {\n if (!cmd.addressPattern) {\n return cmd.negated ? false : true;\n }\n const matches = cmd.addressPattern.test(state.patternSpace);\n return cmd.negated ? !matches : matches;\n}\n\nfunction findLabel(commands: SedCommand[], label: string): number {\n for (let i = 0; i < commands.length; i++) {\n if (commands[i]!.type === \"label\" && commands[i]!.label === label) {\n return i;\n }\n }\n return -1;\n}\n\ninterface ExecResult {\n branchToEnd: boolean;\n branchLabel?: string;\n nextLine: boolean; // n command: output and advance\n deleted: boolean;\n restart: boolean; // D command\n}\n\nfunction executeCommands(\n commands: SedCommand[],\n state: SedState,\n topLevel: boolean\n): ExecResult {\n let pc = 0;\n while (pc < commands.length) {\n const cmd = commands[pc]!;\n\n // Labels are no-ops\n if (cmd.type === \"label\") {\n pc++;\n continue;\n }\n\n // Check address\n if (!addressMatches(cmd, state)) {\n pc++;\n continue;\n }\n\n switch (cmd.type) {\n case \"s\":\n state.patternSpace = applySubstitution(state.patternSpace, cmd);\n break;\n case \"d\":\n state.deleted = true;\n return { branchToEnd: false, deleted: true, nextLine: false, restart: false };\n case \"p\":\n state.output.push(state.patternSpace);\n break;\n case \"h\":\n state.holdSpace = state.patternSpace;\n break;\n case \"H\":\n state.holdSpace = state.holdSpace + \"\\n\" + state.patternSpace;\n break;\n case \"g_hold\":\n state.patternSpace = state.holdSpace;\n break;\n case \"G\":\n state.patternSpace = state.patternSpace + \"\\n\" + state.holdSpace;\n break;\n case \"x\": {\n const tmp = state.patternSpace;\n state.patternSpace = state.holdSpace;\n state.holdSpace = tmp;\n break;\n }\n case \"n\":\n // Output current pattern space, then read next line\n if (!state.suppressOutput) {\n state.output.push(state.patternSpace);\n }\n state.lineIndex++;\n if (state.lineIndex < state.lines.length) {\n state.patternSpace = state.lines[state.lineIndex]!;\n } else {\n // No more lines\n state.deleted = true;\n return { branchToEnd: false, deleted: true, nextLine: false, restart: false };\n }\n break;\n case \"N\":\n // Append next line to pattern space\n state.lineIndex++;\n if (state.lineIndex < state.lines.length) {\n state.patternSpace = state.patternSpace + \"\\n\" + state.lines[state.lineIndex]!;\n } else {\n // No more lines: output pattern space and exit (POSIX behavior)\n if (!state.suppressOutput) {\n state.output.push(state.patternSpace);\n }\n state.deleted = true;\n return { branchToEnd: false, deleted: true, nextLine: false, restart: false };\n }\n break;\n case \"P\": {\n // Print up to first \\n\n const nlIdx = state.patternSpace.indexOf(\"\\n\");\n if (nlIdx >= 0) {\n state.output.push(state.patternSpace.slice(0, nlIdx));\n } else {\n state.output.push(state.patternSpace);\n }\n break;\n }\n case \"D\": {\n // Delete up to first \\n, restart; if no \\n, delete all\n const nlIdx2 = state.patternSpace.indexOf(\"\\n\");\n if (nlIdx2 >= 0) {\n state.patternSpace = state.patternSpace.slice(nlIdx2 + 1);\n state.restart = true;\n return { branchToEnd: false, deleted: false, nextLine: false, restart: true };\n } else {\n state.deleted = true;\n return { branchToEnd: false, deleted: true, nextLine: false, restart: false };\n }\n }\n case \"b\":\n if (cmd.label) {\n // Branch to label — only works at top level\n if (topLevel) {\n const idx = findLabel(commands, cmd.label);\n if (idx >= 0) {\n pc = idx;\n continue;\n }\n }\n // Label not found or not top-level: branch to end\n return { branchToEnd: true, branchLabel: cmd.label, deleted: false, nextLine: false, restart: false };\n }\n // No label: branch to end of script\n return { branchToEnd: true, deleted: false, nextLine: false, restart: false };\n case \"group\":\n if (cmd.children) {\n const result = executeCommands(cmd.children, state, false);\n if (result.deleted || result.branchToEnd || result.restart) {\n // Propagate branch labels up for top-level resolution\n if (result.branchLabel && topLevel) {\n const idx = findLabel(commands, result.branchLabel);\n if (idx >= 0) {\n pc = idx;\n continue;\n }\n }\n return result;\n }\n }\n break;\n }\n pc++;\n }\n return { branchToEnd: false, deleted: false, nextLine: false, restart: false };\n}\n\nexport const sed: Command = async (ctx) => {\n const { options, files, error } = parseArgs(ctx.args);\n\n if (error) {\n await ctx.stderr.writeText(formatError(error));\n return 1;\n }\n\n if (options.commands.length === 0) {\n await ctx.stderr.writeText(\"sed: missing script\\n\");\n return 1;\n }\n\n const processContent = async (content: string): Promise<string[]> => {\n const lines = content.split(\"\\n\");\n if (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n\n const allOutput: string[] = [];\n const state: SedState = {\n patternSpace: \"\",\n holdSpace: \"\",\n lineIndex: 0,\n lines,\n suppressOutput: options.suppressOutput,\n output: [],\n deleted: false,\n restart: false,\n };\n\n while (state.lineIndex < lines.length) {\n state.patternSpace = lines[state.lineIndex]!;\n state.deleted = false;\n state.output = [];\n\n // Execute commands, possibly restarting on D\n let restarting = true;\n while (restarting) {\n restarting = false;\n state.restart = false;\n const result = executeCommands(options.commands, state, true);\n\n if (result.restart) {\n restarting = true;\n // output collected so far in this cycle goes out\n allOutput.push(...state.output);\n state.output = [];\n continue;\n }\n\n if (result.deleted) {\n allOutput.push(...state.output);\n state.lineIndex++;\n break;\n }\n\n // Normal end: collect printed lines, then auto-print\n allOutput.push(...state.output);\n if (!options.suppressOutput) {\n allOutput.push(state.patternSpace);\n }\n state.lineIndex++;\n }\n }\n\n return allOutput;\n };\n\n if (files.length === 0) {\n const content = await ctx.stdin.text();\n const outputLines = await processContent(content);\n for (const line of outputLines) {\n await ctx.stdout.writeText(line + \"\\n\");\n }\n } else if (options.inPlace) {\n for (const file of files) {\n try {\n const path = ctx.fs.resolve(ctx.cwd, file);\n const content = await ctx.fs.readFile(path);\n const outputLines = await processContent(content.toString());\n const result = outputLines.length > 0 ? outputLines.join(\"\\n\") + \"\\n\" : \"\";\n await ctx.fs.writeFile(path, result);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n await ctx.stderr.writeText(`sed: ${file}: ${message}\\n`);\n return 1;\n }\n }\n } else {\n for (const file of files) {\n try {\n const path = ctx.fs.resolve(ctx.cwd, file);\n const content = await ctx.fs.readFile(path);\n const outputLines = await processContent(content.toString());\n for (const line of outputLines) {\n await ctx.stdout.writeText(line + \"\\n\");\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n await ctx.stderr.writeText(`sed: ${file}: ${message}\\n`);\n return 1;\n }\n }\n }\n\n return 0;\n};\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoBA,SAAS,iBAAiB,CAAC,QAAmC;AAAA,EAC5D,MAAM,QAAQ,OAAO,MAAM,6BAA6B;AAAA,EACxD,IAAI,CAAC;AAAA,IAAO,OAAO;AAAA,EAEnB,WAAW,YAAY,gBAAgB,SAAS;AAAA,EAChD,MAAM,aAAa,MAAO,SAAS,GAAG;AAAA,EACtC,MAAM,kBAAkB,MAAO,SAAS,GAAG;AAAA,EAE3C,MAAM,aAAa,WAAY,QAAQ,SAAS,GAAG,EAAE,QAAQ,SAAS,GAAG;AAAA,EACzE,MAAM,cAAc,eACjB,QAAQ,cAAc,mBAAmB,EACzC,QAAQ,OAAO,MAAM,EACrB,QAAQ,2BAA2B,MAAM;AAAA,EAE5C,IAAI;AAAA,IACF,MAAM,aAAa,kBAAkB,MAAM;AAAA,IAC3C,OAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS,IAAI,OAAO,YAAY,UAAU;AAAA,MAC1C;AAAA,MACA;AAAA,MACA,WAAW;AAAA,IACb;AAAA,IACA,MAAM;AAAA,IACN,OAAO;AAAA;AAAA;AAIX,SAAS,YAAY,CAAC,QAAmC;AAAA,EACvD,MAAM,UAAU,OAAO,KAAK;AAAA,EAG5B,IAAI,QAAQ,WAAW,GAAG,GAAG;AAAA,IAC3B,OAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,QAAQ,MAAM,CAAC,EAAE,KAAK;AAAA,MAC7B,YAAY;AAAA,MACZ,WAAW;AAAA,IACb;AAAA,EACF;AAAA,EAGA,IAAI,YAAY,OAAO,QAAQ,WAAW,IAAI,KAAK,QAAQ,WAAW,KAAK,GAAG;AAAA,IAC5E,OAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,QAAQ,SAAS,IAAI,QAAQ,MAAM,CAAC,EAAE,KAAK,IAAI;AAAA,MACtD,YAAY;AAAA,MACZ,WAAW;AAAA,IACb;AAAA,EACF;AAAA,EAGA,IAAI,QAAQ,WAAW,GAAG,KAAK,QAAQ,SAAS,GAAG,GAAG;AAAA,IACpD,MAAM,QAAQ,QAAQ,MAAM,GAAG,EAAE,EAAE,KAAK;AAAA,IACxC,MAAM,QAAQ,iBAAiB,KAAK;AAAA,IACpC,MAAM,WAAyB,CAAC;AAAA,IAChC,WAAW,QAAQ,OAAO;AAAA,MACxB,MAAM,MAAM,aAAa,IAAI;AAAA,MAC7B,IAAI;AAAA,QAAK,SAAS,KAAK,GAAG;AAAA,IAC5B;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA,YAAY;AAAA,MACZ,WAAW;AAAA,IACb;AAAA,EACF;AAAA,EAGA,MAAM,iBAAqD;AAAA,IACzD,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AAAA,EACA,IAAI,eAAe,UAAU;AAAA,IAC3B,OAAO;AAAA,MACL,MAAM,eAAe;AAAA,MACrB,YAAY;AAAA,MACZ,WAAW;AAAA,IACb;AAAA,EACF;AAAA,EAGA,MAAM,iBAAiB,QAAQ,MAAM,wBAAwB;AAAA,EAC7D,IAAI,gBAAgB;AAAA,IAClB,SAAS,mBAAmB,UAAU,QAAQ;AAAA,IAC9C,MAAM,UAAU,aAAa;AAAA,IAC7B,MAAM,cAAc,KAAM,KAAK;AAAA,IAE/B,IAAI;AAAA,MACF,MAAM,iBAAiB,IAAI,OAAO,iBAAkB;AAAA,MAGpD,IAAI,CAAC;AAAA,QAAa,OAAO;AAAA,MAGzB,IAAI,eAAe,cAAc;AAAA,QAC/B,OAAO;AAAA,UACL,MAAM,eAAe;AAAA,UACrB;AAAA,UACA;AAAA,UACA,YAAY;AAAA,UACZ,WAAW;AAAA,QACb;AAAA,MACF;AAAA,MAGA,IAAI,gBAAgB,OAAO,YAAY,WAAW,IAAI,GAAG;AAAA,QACvD,OAAO;AAAA,UACL,MAAM;AAAA,UACN;AAAA,UACA;AAAA,UACA,OAAO,YAAY,SAAS,IAAI,YAAY,MAAM,CAAC,EAAE,KAAK,IAAI;AAAA,UAC9D,YAAY;AAAA,UACZ,WAAW;AAAA,QACb;AAAA,MACF;AAAA,MAGA,IAAI,YAAY,WAAW,GAAG,KAAK,YAAY,SAAS,GAAG,GAAG;AAAA,QAC5D,MAAM,QAAQ,YAAY,MAAM,GAAG,EAAE,EAAE,KAAK;AAAA,QAC5C,MAAM,QAAQ,iBAAiB,KAAK;AAAA,QACpC,MAAM,WAAyB,CAAC;AAAA,QAChC,WAAW,QAAQ,OAAO;AAAA,UACxB,MAAM,MAAM,aAAa,IAAI;AAAA,UAC7B,IAAI;AAAA,YAAK,SAAS,KAAK,GAAG;AAAA,QAC5B;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN;AAAA,UACA;AAAA,UACA;AAAA,UACA,YAAY;AAAA,UACZ,WAAW;AAAA,QACb;AAAA,MACF;AAAA,MAGA,MAAM,UAAS,kBAAkB,WAAW;AAAA,MAC5C,IAAI,SAAQ;AAAA,QACV,QAAO,iBAAiB;AAAA,QACxB,QAAO,UAAU;AAAA,QACjB,OAAO;AAAA,MACT;AAAA,MACA,MAAM;AAAA,MACN,OAAO;AAAA;AAAA,EAEX;AAAA,EAGA,MAAM,SAAS,kBAAkB,OAAO;AAAA,EACxC,IAAI;AAAA,IAAQ,OAAO;AAAA,EAEnB,OAAO;AAAA;AAGT,SAAS,gBAAgB,CAAC,QAA0B;AAAA,EAClD,MAAM,QAAkB,CAAC;AAAA,EACzB,IAAI,IAAI;AAAA,EACR,IAAI,UAAU;AAAA,EACd,IAAI,aAAa;AAAA,EAEjB,OAAO,IAAI,OAAO,QAAQ;AAAA,IACxB,IAAI,OAAO,OAAO,KAAK;AAAA,MACrB;AAAA,MACA,WAAW,OAAO;AAAA,MAClB;AAAA,IACF,EAAO,SAAI,OAAO,OAAO,KAAK;AAAA,MAC5B;AAAA,MACA,WAAW,OAAO;AAAA,MAClB;AAAA,IACF,EAAO,SAAI,OAAO,OAAO,OAAO,eAAe,KAAK,IAAI,IAAI,OAAO,UAAU,CAAC,cAAc,KAAK,OAAO,IAAI,EAAG,GAAG;AAAA,MAEhH,MAAM,QAAQ,OAAO,IAAI;AAAA,MACzB,IAAI,IAAI,IAAI;AAAA,MACZ,IAAI,aAAa;AAAA,MACjB,OAAO,IAAI,OAAO,UAAU,aAAa,GAAG;AAAA,QAC1C,IAAI,OAAO,OAAO,MAAM;AAAA,UACtB,KAAK;AAAA,UACL;AAAA,QACF;AAAA,QACA,IAAI,OAAO,OAAO;AAAA,UAAO;AAAA,QACzB;AAAA,MACF;AAAA,MAEA,OAAO,IAAI,OAAO,UAAU,OAAO,KAAK,OAAO,EAAG;AAAA,QAAG;AAAA,MACrD,WAAW,OAAO,MAAM,GAAG,CAAC;AAAA,MAC5B,IAAI;AAAA,IACN,EAAO,SAAI,OAAO,OAAO,OAAO,eAAe,GAAG;AAAA,MAChD,MAAM,WAAU,QAAQ,KAAK;AAAA,MAC7B,IAAI;AAAA,QAAS,MAAM,KAAK,QAAO;AAAA,MAC/B,UAAU;AAAA,MACV;AAAA,IACF,EAAO;AAAA,MACL,WAAW,OAAO;AAAA,MAClB;AAAA;AAAA,EAEJ;AAAA,EACA,MAAM,UAAU,QAAQ,KAAK;AAAA,EAC7B,IAAI;AAAA,IAAS,MAAM,KAAK,OAAO;AAAA,EAC/B,OAAO;AAAA;AAST,SAAS,SAAS,CAAC,MAAiC;AAAA,EAClD,MAAM,UAAsB;AAAA,IAC1B,gBAAgB;AAAA,IAChB,SAAS;AAAA,IACT,UAAU,CAAC;AAAA,EACb;AAAA,EACA,MAAM,QAAkB,CAAC;AAAA,EAEzB,IAAI,IAAI;AAAA,EACR,OAAO,IAAI,KAAK,QAAQ;AAAA,IACtB,MAAM,MAAM,KAAK;AAAA,IAEjB,IAAI,QAAQ,MAAM;AAAA,MAChB;AAAA,MACA,OAAO,IAAI,KAAK,QAAQ;AAAA,QACtB,MAAM,YAAY,KAAK;AAAA,QACvB,IAAI,QAAQ,SAAS,WAAW,GAAG;AAAA,UACjC,MAAM,QAAQ,iBAAiB,SAAS;AAAA,UACxC,WAAW,QAAQ,OAAO;AAAA,YACxB,MAAM,MAAM,aAAa,IAAI;AAAA,YAC7B,IAAI;AAAA,cAAK,QAAQ,SAAS,KAAK,GAAG;AAAA,UACpC;AAAA,QACF,EAAO;AAAA,UACL,MAAM,KAAK,SAAS;AAAA;AAAA,QAEtB;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,IAEA,IAAI,IAAI,WAAW,IAAI,GAAG;AAAA,MACxB,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,OAAO,EAAE,MAAM,uBAAuB,QAAQ,IAAI;AAAA,MACpD;AAAA,IACF;AAAA,IAEA,IAAI,IAAI,WAAW,GAAG,KAAK,IAAI,SAAS,GAAG;AAAA,MACzC,MAAM,YAAY,IAAI,MAAM,CAAC;AAAA,MAE7B,SAAS,IAAI,EAAG,IAAI,UAAU,QAAQ,KAAK;AAAA,QACzC,MAAM,OAAO,UAAU;AAAA,QAEvB,IAAI,SAAS,KAAK;AAAA,UAChB,QAAQ,iBAAiB;AAAA,QAC3B,EAAO,SAAI,SAAS,KAAK;AAAA,UACvB,QAAQ,UAAU;AAAA,QACpB,EAAO,SAAI,SAAS,KAAK;AAAA,UACvB,MAAM,YAAY,UAAU,MAAM,IAAI,CAAC;AAAA,UACvC,IAAI;AAAA,UAEJ,IAAI,UAAU,SAAS,GAAG;AAAA,YACxB,SAAS;AAAA,UACX,EAAO,SAAI,IAAI,IAAI,KAAK,QAAQ;AAAA,YAC9B,SAAS,KAAK,EAAE;AAAA,UAClB,EAAO;AAAA,YACL,OAAO;AAAA,cACL;AAAA,cACA;AAAA,cACA,OAAO,EAAE,MAAM,iBAAiB,QAAQ,KAAK;AAAA,YAC/C;AAAA;AAAA,UAGF,MAAM,QAAQ,iBAAiB,MAAM;AAAA,UACrC,WAAW,QAAQ,OAAO;AAAA,YACxB,MAAM,MAAM,aAAa,IAAI;AAAA,YAC7B,IAAI;AAAA,cAAK,QAAQ,SAAS,KAAK,GAAG;AAAA,UACpC;AAAA,UACA;AAAA,QACF,EAAO;AAAA,UACL,OAAO;AAAA,YACL;AAAA,YACA;AAAA,YACA,OAAO,EAAE,MAAM,uBAAuB,QAAQ,IAAI,OAAO;AAAA,UAC3D;AAAA;AAAA,MAEJ;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IAEA,IAAI,QAAQ,SAAS,WAAW,GAAG;AAAA,MACjC,MAAM,QAAQ,iBAAiB,GAAG;AAAA,MAClC,WAAW,QAAQ,OAAO;AAAA,QACxB,MAAM,MAAM,aAAa,IAAI;AAAA,QAC7B,IAAI;AAAA,UAAK,QAAQ,SAAS,KAAK,GAAG;AAAA,MACpC;AAAA,IACF,EAAO;AAAA,MACL,MAAM,KAAK,GAAG;AAAA;AAAA,IAEhB;AAAA,EACF;AAAA,EAEA,OAAO,EAAE,SAAS,MAAM;AAAA;AAG1B,SAAS,WAAW,CAAC,OAAsD;AAAA,EACzE,IAAI;AAAA,EACJ,IAAI,MAAM,SAAS,uBAAuB;AAAA,IACxC,IAAI,MAAM,OAAO,WAAW,IAAI,GAAG;AAAA,MACjC,UAAU,6BAA6B,MAAM;AAAA;AAAA,IAC/C,EAAO;AAAA,MACL,UAAU,2BAA2B,MAAM,OAAO,MAAM,CAAC;AAAA;AAAA;AAAA,EAE7D,EAAO;AAAA,IACL,UAAU,gBAAgB,MAAM;AAAA;AAAA;AAAA,EAElC,OAAO,UAAU;AAAA;AAAA;AAGnB,SAAS,iBAAiB,CAAC,MAAc,KAAyB;AAAA,EAChE,IAAI,CAAC,IAAI;AAAA,IAAS,OAAO;AAAA,EAEzB,IAAI,IAAI,YAAY;AAAA,IAClB,OAAO,KAAK,QAAQ,IAAI,OAAO,IAAI,QAAQ,QAAQ,IAAI,QAAQ,QAAQ,GAAG,GAAG,IAAI,WAAY;AAAA,EAC/F,EAAO;AAAA,IACL,OAAO,KAAK,QAAQ,IAAI,SAAS,IAAI,WAAY;AAAA;AAAA;AAerD,SAAS,cAAc,CAAC,KAAiB,OAA0B;AAAA,EACjE,IAAI,CAAC,IAAI,gBAAgB;AAAA,IACvB,OAAO,IAAI,UAAU,QAAQ;AAAA,EAC/B;AAAA,EACA,MAAM,UAAU,IAAI,eAAe,KAAK,MAAM,YAAY;AAAA,EAC1D,OAAO,IAAI,UAAU,CAAC,UAAU;AAAA;AAGlC,SAAS,SAAS,CAAC,UAAwB,OAAuB;AAAA,EAChE,SAAS,IAAI,EAAG,IAAI,SAAS,QAAQ,KAAK;AAAA,IACxC,IAAI,SAAS,GAAI,SAAS,WAAW,SAAS,GAAI,UAAU,OAAO;AAAA,MACjE,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA,OAAO;AAAA;AAWT,SAAS,eAAe,CACtB,UACA,OACA,UACY;AAAA,EACZ,IAAI,KAAK;AAAA,EACT,OAAO,KAAK,SAAS,QAAQ;AAAA,IAC3B,MAAM,MAAM,SAAS;AAAA,IAGrB,IAAI,IAAI,SAAS,SAAS;AAAA,MACxB;AAAA,MACA;AAAA,IACF;AAAA,IAGA,IAAI,CAAC,eAAe,KAAK,KAAK,GAAG;AAAA,MAC/B;AAAA,MACA;AAAA,IACF;AAAA,IAEA,QAAQ,IAAI;AAAA,WACL;AAAA,QACH,MAAM,eAAe,kBAAkB,MAAM,cAAc,GAAG;AAAA,QAC9D;AAAA,WACG;AAAA,QACH,MAAM,UAAU;AAAA,QAChB,OAAO,EAAE,aAAa,OAAO,SAAS,MAAM,UAAU,OAAO,SAAS,MAAM;AAAA,WACzE;AAAA,QACH,MAAM,OAAO,KAAK,MAAM,YAAY;AAAA,QACpC;AAAA,WACG;AAAA,QACH,MAAM,YAAY,MAAM;AAAA,QACxB;AAAA,WACG;AAAA,QACH,MAAM,YAAY,MAAM,YAAY;AAAA,IAAO,MAAM;AAAA,QACjD;AAAA,WACG;AAAA,QACH,MAAM,eAAe,MAAM;AAAA,QAC3B;AAAA,WACG;AAAA,QACH,MAAM,eAAe,MAAM,eAAe;AAAA,IAAO,MAAM;AAAA,QACvD;AAAA,WACG,KAAK;AAAA,QACR,MAAM,MAAM,MAAM;AAAA,QAClB,MAAM,eAAe,MAAM;AAAA,QAC3B,MAAM,YAAY;AAAA,QAClB;AAAA,MACF;AAAA,WACK;AAAA,QAEH,IAAI,CAAC,MAAM,gBAAgB;AAAA,UACzB,MAAM,OAAO,KAAK,MAAM,YAAY;AAAA,QACtC;AAAA,QACA,MAAM;AAAA,QACN,IAAI,MAAM,YAAY,MAAM,MAAM,QAAQ;AAAA,UACxC,MAAM,eAAe,MAAM,MAAM,MAAM;AAAA,QACzC,EAAO;AAAA,UAEL,MAAM,UAAU;AAAA,UAChB,OAAO,EAAE,aAAa,OAAO,SAAS,MAAM,UAAU,OAAO,SAAS,MAAM;AAAA;AAAA,QAE9E;AAAA,WACG;AAAA,QAEH,MAAM;AAAA,QACN,IAAI,MAAM,YAAY,MAAM,MAAM,QAAQ;AAAA,UACxC,MAAM,eAAe,MAAM,eAAe;AAAA,IAAO,MAAM,MAAM,MAAM;AAAA,QACrE,EAAO;AAAA,UAEL,IAAI,CAAC,MAAM,gBAAgB;AAAA,YACzB,MAAM,OAAO,KAAK,MAAM,YAAY;AAAA,UACtC;AAAA,UACA,MAAM,UAAU;AAAA,UAChB,OAAO,EAAE,aAAa,OAAO,SAAS,MAAM,UAAU,OAAO,SAAS,MAAM;AAAA;AAAA,QAE9E;AAAA,WACG,KAAK;AAAA,QAER,MAAM,QAAQ,MAAM,aAAa,QAAQ;AAAA,CAAI;AAAA,QAC7C,IAAI,SAAS,GAAG;AAAA,UACd,MAAM,OAAO,KAAK,MAAM,aAAa,MAAM,GAAG,KAAK,CAAC;AAAA,QACtD,EAAO;AAAA,UACL,MAAM,OAAO,KAAK,MAAM,YAAY;AAAA;AAAA,QAEtC;AAAA,MACF;AAAA,WACK,KAAK;AAAA,QAER,MAAM,SAAS,MAAM,aAAa,QAAQ;AAAA,CAAI;AAAA,QAC9C,IAAI,UAAU,GAAG;AAAA,UACf,MAAM,eAAe,MAAM,aAAa,MAAM,SAAS,CAAC;AAAA,UACxD,MAAM,UAAU;AAAA,UAChB,OAAO,EAAE,aAAa,OAAO,SAAS,OAAO,UAAU,OAAO,SAAS,KAAK;AAAA,QAC9E,EAAO;AAAA,UACL,MAAM,UAAU;AAAA,UAChB,OAAO,EAAE,aAAa,OAAO,SAAS,MAAM,UAAU,OAAO,SAAS,MAAM;AAAA;AAAA,MAEhF;AAAA,WACK;AAAA,QACH,IAAI,IAAI,OAAO;AAAA,UAEb,IAAI,UAAU;AAAA,YACZ,MAAM,MAAM,UAAU,UAAU,IAAI,KAAK;AAAA,YACzC,IAAI,OAAO,GAAG;AAAA,cACZ,KAAK;AAAA,cACL;AAAA,YACF;AAAA,UACF;AAAA,UAEA,OAAO,EAAE,aAAa,MAAM,aAAa,IAAI,OAAO,SAAS,OAAO,UAAU,OAAO,SAAS,MAAM;AAAA,QACtG;AAAA,QAEA,OAAO,EAAE,aAAa,MAAM,SAAS,OAAO,UAAU,OAAO,SAAS,MAAM;AAAA,WACzE;AAAA,QACH,IAAI,IAAI,UAAU;AAAA,UAChB,MAAM,SAAS,gBAAgB,IAAI,UAAU,OAAO,KAAK;AAAA,UACzD,IAAI,OAAO,WAAW,OAAO,eAAe,OAAO,SAAS;AAAA,YAE1D,IAAI,OAAO,eAAe,UAAU;AAAA,cAClC,MAAM,MAAM,UAAU,UAAU,OAAO,WAAW;AAAA,cAClD,IAAI,OAAO,GAAG;AAAA,gBACZ,KAAK;AAAA,gBACL;AAAA,cACF;AAAA,YACF;AAAA,YACA,OAAO;AAAA,UACT;AAAA,QACF;AAAA,QACA;AAAA;AAAA,IAEJ;AAAA,EACF;AAAA,EACA,OAAO,EAAE,aAAa,OAAO,SAAS,OAAO,UAAU,OAAO,SAAS,MAAM;AAAA;AAGxE,IAAM,MAAe,OAAO,QAAQ;AAAA,EACzC,QAAQ,SAAS,OAAO,UAAU,UAAU,IAAI,IAAI;AAAA,EAEpD,IAAI,OAAO;AAAA,IACT,MAAM,IAAI,OAAO,UAAU,YAAY,KAAK,CAAC;AAAA,IAC7C,OAAO;AAAA,EACT;AAAA,EAEA,IAAI,QAAQ,SAAS,WAAW,GAAG;AAAA,IACjC,MAAM,IAAI,OAAO,UAAU;AAAA,CAAuB;AAAA,IAClD,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,iBAAiB,OAAO,YAAuC;AAAA,IACnE,MAAM,QAAQ,QAAQ,MAAM;AAAA,CAAI;AAAA,IAChC,IAAI,MAAM,SAAS,KAAK,MAAM,MAAM,SAAS,OAAO,IAAI;AAAA,MACtD,MAAM,IAAI;AAAA,IACZ;AAAA,IAEA,MAAM,YAAsB,CAAC;AAAA,IAC7B,MAAM,QAAkB;AAAA,MACtB,cAAc;AAAA,MACd,WAAW;AAAA,MACX,WAAW;AAAA,MACX;AAAA,MACA,gBAAgB,QAAQ;AAAA,MACxB,QAAQ,CAAC;AAAA,MACT,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,IAEA,OAAO,MAAM,YAAY,MAAM,QAAQ;AAAA,MACrC,MAAM,eAAe,MAAM,MAAM;AAAA,MACjC,MAAM,UAAU;AAAA,MAChB,MAAM,SAAS,CAAC;AAAA,MAGhB,IAAI,aAAa;AAAA,MACjB,OAAO,YAAY;AAAA,QACjB,aAAa;AAAA,QACb,MAAM,UAAU;AAAA,QAChB,MAAM,SAAS,gBAAgB,QAAQ,UAAU,OAAO,IAAI;AAAA,QAE5D,IAAI,OAAO,SAAS;AAAA,UAClB,aAAa;AAAA,UAEb,UAAU,KAAK,GAAG,MAAM,MAAM;AAAA,UAC9B,MAAM,SAAS,CAAC;AAAA,UAChB;AAAA,QACF;AAAA,QAEA,IAAI,OAAO,SAAS;AAAA,UAClB,UAAU,KAAK,GAAG,MAAM,MAAM;AAAA,UAC9B,MAAM;AAAA,UACN;AAAA,QACF;AAAA,QAGA,UAAU,KAAK,GAAG,MAAM,MAAM;AAAA,QAC9B,IAAI,CAAC,QAAQ,gBAAgB;AAAA,UAC3B,UAAU,KAAK,MAAM,YAAY;AAAA,QACnC;AAAA,QACA,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,OAAO;AAAA;AAAA,EAGT,IAAI,MAAM,WAAW,GAAG;AAAA,IACtB,MAAM,UAAU,MAAM,IAAI,MAAM,KAAK;AAAA,IACrC,MAAM,cAAc,MAAM,eAAe,OAAO;AAAA,IAChD,WAAW,QAAQ,aAAa;AAAA,MAC9B,MAAM,IAAI,OAAO,UAAU,OAAO;AAAA,CAAI;AAAA,IACxC;AAAA,EACF,EAAO,SAAI,QAAQ,SAAS;AAAA,IAC1B,WAAW,QAAQ,OAAO;AAAA,MACxB,IAAI;AAAA,QACF,MAAM,OAAO,IAAI,GAAG,QAAQ,IAAI,KAAK,IAAI;AAAA,QACzC,MAAM,UAAU,MAAM,IAAI,GAAG,SAAS,IAAI;AAAA,QAC1C,MAAM,cAAc,MAAM,eAAe,QAAQ,SAAS,CAAC;AAAA,QAC3D,MAAM,SAAS,YAAY,SAAS,IAAI,YAAY,KAAK;AAAA,CAAI,IAAI;AAAA,IAAO;AAAA,QACxE,MAAM,IAAI,GAAG,UAAU,MAAM,MAAM;AAAA,QACnC,OAAO,KAAK;AAAA,QACZ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QAC/D,MAAM,IAAI,OAAO,UAAU,QAAQ,SAAS;AAAA,CAAW;AAAA,QACvD,OAAO;AAAA;AAAA,IAEX;AAAA,EACF,EAAO;AAAA,IACL,WAAW,QAAQ,OAAO;AAAA,MACxB,IAAI;AAAA,QACF,MAAM,OAAO,IAAI,GAAG,QAAQ,IAAI,KAAK,IAAI;AAAA,QACzC,MAAM,UAAU,MAAM,IAAI,GAAG,SAAS,IAAI;AAAA,QAC1C,MAAM,cAAc,MAAM,eAAe,QAAQ,SAAS,CAAC;AAAA,QAC3D,WAAW,QAAQ,aAAa;AAAA,UAC9B,MAAM,IAAI,OAAO,UAAU,OAAO;AAAA,CAAI;AAAA,QACxC;AAAA,QACA,OAAO,KAAK;AAAA,QACZ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QAC/D,MAAM,IAAI,OAAO,UAAU,QAAQ,SAAS;AAAA,CAAW;AAAA,QACvD,OAAO;AAAA;AAAA,IAEX;AAAA;AAAA,EAGF,OAAO;AAAA;",
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "4E24A35350169A4B64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -33,6 +33,7 @@ __export(exports_tr, {
|
|
|
33
33
|
});
|
|
34
34
|
module.exports = __toCommonJS(exports_tr);
|
|
35
35
|
var import_flag_parser = require("../../utils/flag-parser.cjs");
|
|
36
|
+
var import_expand_escapes = require("../../utils/expand-escapes.cjs");
|
|
36
37
|
var spec = {
|
|
37
38
|
name: "tr",
|
|
38
39
|
flags: [
|
|
@@ -53,47 +54,6 @@ var handler = (flags, flag) => {
|
|
|
53
54
|
flags.complement = true;
|
|
54
55
|
};
|
|
55
56
|
var parser = import_flag_parser.createFlagParser(spec, defaults, handler);
|
|
56
|
-
function expandEscapes(s) {
|
|
57
|
-
let result = "";
|
|
58
|
-
for (let i = 0;i < s.length; i++) {
|
|
59
|
-
if (s[i] === "\\" && i + 1 < s.length) {
|
|
60
|
-
i++;
|
|
61
|
-
switch (s[i]) {
|
|
62
|
-
case "n":
|
|
63
|
-
result += `
|
|
64
|
-
`;
|
|
65
|
-
break;
|
|
66
|
-
case "t":
|
|
67
|
-
result += "\t";
|
|
68
|
-
break;
|
|
69
|
-
case "\\":
|
|
70
|
-
result += "\\";
|
|
71
|
-
break;
|
|
72
|
-
case "a":
|
|
73
|
-
result += "\x07";
|
|
74
|
-
break;
|
|
75
|
-
case "b":
|
|
76
|
-
result += "\b";
|
|
77
|
-
break;
|
|
78
|
-
case "f":
|
|
79
|
-
result += "\f";
|
|
80
|
-
break;
|
|
81
|
-
case "r":
|
|
82
|
-
result += "\r";
|
|
83
|
-
break;
|
|
84
|
-
case "v":
|
|
85
|
-
result += "\v";
|
|
86
|
-
break;
|
|
87
|
-
default:
|
|
88
|
-
result += s[i];
|
|
89
|
-
break;
|
|
90
|
-
}
|
|
91
|
-
} else {
|
|
92
|
-
result += s[i];
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
return result;
|
|
96
|
-
}
|
|
97
57
|
function expandCharClass(name) {
|
|
98
58
|
switch (name) {
|
|
99
59
|
case "alpha":
|
|
@@ -142,7 +102,7 @@ function expandRange(s) {
|
|
|
142
102
|
return result;
|
|
143
103
|
}
|
|
144
104
|
function expandSet(s) {
|
|
145
|
-
s = expandEscapes(s);
|
|
105
|
+
s = import_expand_escapes.expandEscapes(s);
|
|
146
106
|
s = s.replace(/\[:(\w+):\]/g, (_, name) => expandCharClass(name));
|
|
147
107
|
return expandRange(s);
|
|
148
108
|
}
|
|
@@ -220,4 +180,4 @@ var tr = async (ctx) => {
|
|
|
220
180
|
return 0;
|
|
221
181
|
};
|
|
222
182
|
|
|
223
|
-
//# debugId=
|
|
183
|
+
//# debugId=165FDAE77F0B806764756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/commands/tr/tr.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type { Command } from \"../../types.cjs\";\nimport { createFlagParser, type FlagDefinition } from \"../../utils/flag-parser.cjs\";\n\ninterface TrFlags {\n delete: boolean;\n squeeze: boolean;\n complement: boolean;\n}\n\nconst spec = {\n name: \"tr\",\n flags: [\n { short: \"d\", long: \"delete\" },\n { short: \"s\", long: \"squeeze-repeats\" },\n { short: \"c\", long: \"complement\" },\n { short: \"C\", long: \"complement-values\" },\n ] as FlagDefinition[],\n usage: \"tr [-cCds] SET1 [SET2]\",\n};\n\nconst defaults: TrFlags = { delete: false, squeeze: false, complement: false };\n\nconst handler = (flags: TrFlags, flag: FlagDefinition) => {\n if (flag.short === \"d\") flags.delete = true;\n if (flag.short === \"s\") flags.squeeze = true;\n if (flag.short === \"c\" || flag.short === \"C\") flags.complement = true;\n};\n\nconst parser = createFlagParser(spec, defaults, handler);\n\
|
|
5
|
+
"import type { Command } from \"../../types.cjs\";\nimport { createFlagParser, type FlagDefinition } from \"../../utils/flag-parser.cjs\";\nimport { expandEscapes } from \"../../utils/expand-escapes.cjs\";\n\ninterface TrFlags {\n delete: boolean;\n squeeze: boolean;\n complement: boolean;\n}\n\nconst spec = {\n name: \"tr\",\n flags: [\n { short: \"d\", long: \"delete\" },\n { short: \"s\", long: \"squeeze-repeats\" },\n { short: \"c\", long: \"complement\" },\n { short: \"C\", long: \"complement-values\" },\n ] as FlagDefinition[],\n usage: \"tr [-cCds] SET1 [SET2]\",\n};\n\nconst defaults: TrFlags = { delete: false, squeeze: false, complement: false };\n\nconst handler = (flags: TrFlags, flag: FlagDefinition) => {\n if (flag.short === \"d\") flags.delete = true;\n if (flag.short === \"s\") flags.squeeze = true;\n if (flag.short === \"c\" || flag.short === \"C\") flags.complement = true;\n};\n\nconst parser = createFlagParser(spec, defaults, handler);\n\n\nfunction expandCharClass(name: string): string {\n switch (name) {\n case \"alpha\": return expandRange(\"a-zA-Z\");\n case \"digit\": return \"0123456789\";\n case \"alnum\": return expandRange(\"a-zA-Z\") + \"0123456789\";\n case \"lower\": return expandRange(\"a-z\");\n case \"upper\": return expandRange(\"A-Z\");\n case \"space\": return \" \\t\\n\\r\\f\\v\";\n case \"blank\": return \" \\t\";\n case \"print\": return expandRange(\" -~\");\n case \"graph\": return expandRange(\"!-~\");\n case \"punct\": return \"!\\\"#$%&'()*+,-./:;<=>?@[\\\\]^_`{|}~\";\n case \"cntrl\": return Array.from({ length: 32 }, (_, i) => String.fromCharCode(i)).join(\"\") + String.fromCharCode(127);\n case \"xdigit\": return \"0123456789abcdefABCDEF\";\n default: return \"\";\n }\n}\n\nfunction expandRange(s: string): string {\n let result = \"\";\n for (let i = 0; i < s.length; i++) {\n if (i + 2 < s.length && s[i + 1] === \"-\") {\n const start = s.charCodeAt(i);\n const end = s.charCodeAt(i + 2);\n for (let c = start; c <= end; c++) {\n result += String.fromCharCode(c);\n }\n i += 2;\n } else {\n result += s[i];\n }\n }\n return result;\n}\n\nfunction expandSet(s: string): string {\n // First expand escape sequences\n s = expandEscapes(s);\n // Expand character classes [:name:]\n s = s.replace(/\\[:(\\w+):\\]/g, (_, name) => expandCharClass(name));\n // Expand ranges\n return expandRange(s);\n}\n\nexport const tr: Command = async (ctx) => {\n const result = parser.parse(ctx.args);\n\n if (result.error) {\n await parser.writeError(result.error, ctx.stderr);\n return 1;\n }\n\n const { delete: deleteMode, squeeze, complement } = result.flags;\n const args = result.args;\n\n if (args.length < 1) {\n await ctx.stderr.writeText(\"tr: missing operand\\n\");\n return 1;\n }\n\n let set1 = expandSet(args[0]!);\n const set2 = args.length > 1 ? expandSet(args[1]!) : \"\";\n\n if (complement) {\n // Build complement: all chars 0-127 not in set1\n const set1Chars = new Set(set1);\n let comp = \"\";\n for (let i = 0; i < 128; i++) {\n const ch = String.fromCharCode(i);\n if (!set1Chars.has(ch)) comp += ch;\n }\n set1 = comp;\n }\n\n const input = await ctx.stdin.text();\n let output = \"\";\n\n if (deleteMode && squeeze) {\n // -ds: delete chars in SET1, then squeeze chars in SET2\n const deleteSet = new Set(set1);\n const squeezeSet = new Set(set2);\n let lastChar = \"\";\n for (const ch of input) {\n if (deleteSet.has(ch)) continue;\n if (squeezeSet.has(ch) && ch === lastChar) continue;\n output += ch;\n lastChar = ch;\n }\n } else if (deleteMode) {\n const deleteSet = new Set(set1);\n for (const ch of input) {\n if (!deleteSet.has(ch)) output += ch;\n }\n } else if (squeeze && set2 === \"\") {\n // -s with only SET1: squeeze chars in SET1\n const squeezeSet = new Set(set1);\n let lastChar = \"\";\n for (const ch of input) {\n if (squeezeSet.has(ch) && ch === lastChar) continue;\n output += ch;\n lastChar = ch;\n }\n } else {\n // Translation mode (possibly with -s)\n const map = new Map<string, string>();\n for (let i = 0; i < set1.length; i++) {\n const replacement = i < set2.length ? set2[i]! : set2[set2.length - 1] ?? \"\";\n map.set(set1[i]!, replacement);\n }\n\n const squeezeSet = squeeze ? new Set(set2) : null;\n let lastChar = \"\";\n\n for (const ch of input) {\n const mapped = map.has(ch) ? map.get(ch)! : ch;\n if (squeezeSet && squeezeSet.has(mapped) && mapped === lastChar) continue;\n output += mapped;\n lastChar = mapped;\n }\n }\n\n await ctx.stdout.writeText(output);\n return 0;\n};\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACsD,IAAtD;AAQA,IAAM,OAAO;AAAA,EACX,MAAM;AAAA,EACN,OAAO;AAAA,IACL,EAAE,OAAO,KAAK,MAAM,SAAS;AAAA,IAC7B,EAAE,OAAO,KAAK,MAAM,kBAAkB;AAAA,IACtC,EAAE,OAAO,KAAK,MAAM,aAAa;AAAA,IACjC,EAAE,OAAO,KAAK,MAAM,oBAAoB;AAAA,EAC1C;AAAA,EACA,OAAO;AACT;AAEA,IAAM,WAAoB,EAAE,QAAQ,OAAO,SAAS,OAAO,YAAY,MAAM;AAE7E,IAAM,UAAU,CAAC,OAAgB,SAAyB;AAAA,EACxD,IAAI,KAAK,UAAU;AAAA,IAAK,MAAM,SAAS;AAAA,EACvC,IAAI,KAAK,UAAU;AAAA,IAAK,MAAM,UAAU;AAAA,EACxC,IAAI,KAAK,UAAU,OAAO,KAAK,UAAU;AAAA,IAAK,MAAM,aAAa;AAAA;AAGnE,IAAM,SAAS,oCAAiB,MAAM,UAAU,OAAO;
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "165FDAE77F0B806764756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/fs/real-fs.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import * as path from \"path\";\nimport * as nodeFs from \"node:fs/promises\";\nimport type { VirtualFS, FileStat } from \"../types.cjs\";\n\nexport type Permission = \"read-write\" | \"read-only\" | \"excluded\";\nexport type PermissionRules = Record<string, Permission>;\n\n// Minimal interface for the underlying fs (compatible with node:fs and memfs)\nexport interface UnderlyingFS {\n promises: {\n readFile(path: string): Promise<Buffer | Uint8Array | string>;\n readdir(path: string): Promise<string[]>;\n stat(path: string): Promise<{\n isFile(): boolean;\n isDirectory(): boolean;\n size: number;\n mtime: Date;\n }>;\n writeFile(path: string, data: Buffer | string): Promise<void>;\n appendFile(path: string, data: Buffer | string): Promise<void>;\n mkdir(path: string, opts?: { recursive?: boolean }): Promise<string | undefined | void>;\n rm(path: string, opts?: { recursive?: boolean; force?: boolean }): Promise<void>;\n };\n}\n\n// Default: use real node:fs\nconst defaultFS: UnderlyingFS = { promises: nodeFs };\n\ninterface CompiledRule {\n pattern: string;\n permission: Permission;\n specificity: number;\n}\n\nexport class FileSystem implements VirtualFS {\n private readonly mountBase: string | null;\n private readonly rules: CompiledRule[];\n protected readonly underlyingFs: UnderlyingFS;\n\n constructor(mountPath?: string, permissions?: PermissionRules, fs?: UnderlyingFS) {\n this.mountBase = mountPath ? path.resolve(mountPath) : null;\n this.rules = this.compileRules(permissions ?? {});\n this.underlyingFs = fs ?? defaultFS;\n }\n\n private compileRules(permissions: PermissionRules): CompiledRule[] {\n return Object.entries(permissions)\n .map(([pattern, permission]) => ({\n pattern,\n permission,\n specificity: this.calculateSpecificity(pattern),\n }))\n .sort((a, b) => b.specificity - a.specificity); // highest first\n }\n\n private calculateSpecificity(pattern: string): number {\n const segments = pattern.split(\"/\").filter(Boolean);\n let score = segments.length * 1000; // segment count is primary\n\n for (const seg of segments) {\n if (seg === \"**\") score += 0;\n else if (seg.includes(\"*\")) score += 1;\n else score += 10; // literal segment\n }\n return score;\n }\n\n protected getPermission(virtualPath: string): Permission {\n const normalized = virtualPath.replace(/^\\/+/, \"\"); // strip leading slashes\n\n for (const rule of this.rules) {\n if (this.matchGlob(rule.pattern, normalized)) {\n return rule.permission;\n }\n }\n return \"read-write\"; // default\n }\n\n private matchGlob(pattern: string, filePath: string): boolean {\n // Convert glob to regex\n // ** matches any path segments, * matches within segment\n const regex = pattern\n .split(\"/\")\n .map((seg) => {\n if (seg === \"**\") return \".*\";\n return seg.replace(/\\*/g, \"[^/]*\").replace(/\\?/g, \"[^/]\");\n })\n .join(\"/\");\n return new RegExp(`^${regex}$`).test(filePath);\n }\n\n protected checkPermission(virtualPath: string, operation: \"read\" | \"write\"): void {\n const perm = this.getPermission(virtualPath);\n\n if (perm === \"excluded\") {\n throw new Error(`Access denied: \"${virtualPath}\" is excluded`);\n }\n if (operation === \"write\" && perm === \"read-only\") {\n throw new Error(`Access denied: \"${virtualPath}\" is read-only`);\n }\n }\n\n private resolveSafePath(virtualPath: string): string {\n if (this.mountBase === null) {\n return path.resolve(virtualPath);\n }\n\n // Check for path traversal by tracking depth\n const segments = virtualPath.split(\"/\").filter(Boolean);\n let depth = 0;\n for (const seg of segments) {\n if (seg === \"..\") {\n depth--;\n if (depth < 0) {\n throw new Error(`Path traversal blocked: \"${virtualPath}\" escapes mount point`);\n }\n } else if (seg !== \".\") {\n depth++;\n }\n }\n\n const normalized = path.normalize(virtualPath);\n const relativePath = normalized.startsWith(\"/\") ? normalized.slice(1) : normalized;\n const realPath = path.join(this.mountBase, relativePath);\n const resolved = path.resolve(realPath);\n\n // Double-check containment (defense in depth)\n if (!resolved.startsWith(this.mountBase + path.sep) && resolved !== this.mountBase) {\n throw new Error(`Path traversal blocked: \"${virtualPath}\" escapes mount point`);\n }\n\n return resolved;\n }\n\n // Read operations\n async readFile(filePath: string): Promise<Buffer> {\n this.checkPermission(filePath, \"read\");\n const realPath = this.resolveSafePath(filePath);\n const content = await this.underlyingFs.promises.readFile(realPath);\n return Buffer.from(content);\n }\n\n async readdir(dirPath: string): Promise<string[]> {\n this.checkPermission(dirPath, \"read\");\n const realPath = this.resolveSafePath(dirPath);\n const entries = await this.underlyingFs.promises.readdir(realPath);\n return entries.map(String);\n }\n\n async stat(filePath: string): Promise<FileStat> {\n this.checkPermission(filePath, \"read\");\n const realPath = this.resolveSafePath(filePath);\n const stats = await this.underlyingFs.promises.stat(realPath);\n return {\n isFile: () => stats.isFile(),\n isDirectory: () => stats.isDirectory(),\n size: stats.size,\n mtime: stats.mtime,\n };\n }\n\n async exists(filePath: string): Promise<boolean> {\n try {\n this.checkPermission(filePath, \"read\");\n const realPath = this.resolveSafePath(filePath);\n await this.underlyingFs.promises.stat(realPath);\n return true;\n } catch {\n return false;\n }\n }\n\n // Write operations\n async writeFile(filePath: string, data: Buffer | string): Promise<void> {\n this.checkPermission(filePath, \"write\");\n const realPath = this.resolveSafePath(filePath);\n await this.underlyingFs.promises.writeFile(realPath, data);\n }\n\n async appendFile(filePath: string, data: Buffer | string): Promise<void> {\n this.checkPermission(filePath, \"write\");\n const realPath = this.resolveSafePath(filePath);\n await this.underlyingFs.promises.appendFile(realPath, data);\n }\n\n async mkdir(dirPath: string, opts?: { recursive?: boolean }): Promise<void> {\n this.checkPermission(dirPath, \"write\");\n const realPath = this.resolveSafePath(dirPath);\n await this.underlyingFs.promises.mkdir(realPath, opts);\n }\n\n async rm(filePath: string, opts?: { recursive?: boolean; force?: boolean }): Promise<void> {\n this.checkPermission(filePath, \"write\");\n const realPath = this.resolveSafePath(filePath);\n await this.underlyingFs.promises.rm(realPath, opts);\n }\n\n // Path utilities (no permission check needed)\n resolve(...paths: string[]): string {\n return path.resolve(\"/\", ...paths);\n }\n\n dirname(filePath: string): string {\n return path.dirname(filePath);\n }\n\n basename(filePath: string): string {\n return path.basename(filePath);\n }\n\n // Glob with permission filtering\n async glob(pattern: string, opts?: { cwd?: string }): Promise<string[]> {\n const cwd = opts?.cwd ?? \"/\";\n this.checkPermission(cwd, \"read\");\n\n const matches = await this.expandGlob(pattern, cwd);\n\n // Filter out excluded paths\n return matches.filter((p) => this.getPermission(p) !== \"excluded\").sort();\n }\n\n // Glob expansion (similar to memfs-adapter implementation)\n private async expandGlob(pattern: string, cwd: string): Promise<string[]> {\n // Handle brace expansion first\n const patterns = this.expandBraces(pattern);\n const allMatches: string[] = [];\n\n for (const pat of patterns) {\n const matches = await this.matchPattern(pat, cwd);\n allMatches.push(...matches);\n }\n\n // Remove duplicates and sort\n return [...new Set(allMatches)].sort();\n }\n\n private expandBraces(pattern: string): string[] {\n const braceMatch = pattern.match(/\\{([^{}]+)\\}/);\n if (!braceMatch) return [pattern];\n\n const before = pattern.slice(0, braceMatch.index);\n const after = pattern.slice(braceMatch.index! + braceMatch[0].length);\n const options = braceMatch[1]!.split(\",\");\n\n const results: string[] = [];\n for (const opt of options) {\n const expanded = this.expandBraces(before + opt + after);\n results.push(...expanded);\n }\n return results;\n }\n\n private async matchPattern(pattern: string, cwd: string): Promise<string[]> {\n const parts = pattern.split(\"/\").filter((p) => p !== \"\");\n const isAbsolute = pattern.startsWith(\"/\");\n const startDir = isAbsolute ? \"/\" : cwd;\n\n return this.matchParts(parts, startDir);\n }\n\n private async matchParts(parts: string[], currentPath: string): Promise<string[]> {\n if (parts.length === 0) {\n return [currentPath];\n }\n\n const [part, ...rest] = parts;\n\n // Handle ** (recursive glob)\n if (part === \"**\") {\n const results: string[] = [];\n\n // Match current directory\n const withoutStar = await this.matchParts(rest, currentPath);\n results.push(...withoutStar);\n\n // Recurse into subdirectories\n try {\n const realPath = this.resolveSafePath(currentPath);\n const entries = await this.underlyingFs.promises.readdir(realPath);\n for (const entry of entries) {\n const entryPath = path.posix.join(currentPath, String(entry));\n try {\n const entryRealPath = this.resolveSafePath(entryPath);\n const stat = await this.underlyingFs.promises.stat(entryRealPath);\n if (stat.isDirectory()) {\n const subMatches = await this.matchParts(parts, entryPath);\n results.push(...subMatches);\n }\n } catch {\n // Skip inaccessible entries\n }\n }\n } catch {\n // Directory not readable\n }\n\n return results;\n }\n\n // Handle regular glob patterns\n const regex = this.globToRegex(part!);\n\n try {\n const realPath = this.resolveSafePath(currentPath);\n const entries = await this.underlyingFs.promises.readdir(realPath);\n const results: string[] = [];\n\n for (const entry of entries) {\n const entryName = String(entry);\n if (regex.test(entryName)) {\n const entryPath = path.posix.join(currentPath, entryName);\n if (rest.length === 0) {\n results.push(entryPath);\n } else {\n try {\n const entryRealPath = this.resolveSafePath(entryPath);\n const stat = await this.underlyingFs.promises.stat(entryRealPath);\n if (stat.isDirectory()) {\n const subMatches = await this.matchParts(rest, entryPath);\n results.push(...subMatches);\n }\n } catch {\n // Skip inaccessible entries\n }\n }\n }\n }\n\n return results;\n } catch {\n return [];\n }\n }\n\n private globToRegex(pattern: string): RegExp {\n let regex = \"^\";\n for (let i = 0; i < pattern.length; i++) {\n const char = pattern[i]!;\n if (char === \"*\") {\n regex += \"[^/]*\";\n } else if (char === \"?\") {\n regex += \"[^/]\";\n } else if (char === \"[\") {\n // Character class\n let j = i + 1;\n let classContent = \"\";\n while (j < pattern.length && pattern[j] !== \"]\") {\n classContent += pattern[j];\n j++;\n }\n regex += `[${classContent}]`;\n i = j;\n } else if (\".+^${}()|\\\\\".includes(char)) {\n regex += \"\\\\\" + char;\n } else {\n regex += char;\n }\n }\n regex += \"$\";\n return new RegExp(regex);\n }\n}\n"
|
|
5
|
+
"import * as path from \"path\";\nimport * as nodeFs from \"node:fs/promises\";\nimport type { VirtualFS, FileStat } from \"../types.cjs\";\n\nexport type Permission = \"read-write\" | \"read-only\" | \"excluded\";\nexport type PermissionRules = Record<string, Permission>;\n\n// Minimal interface for the underlying fs (compatible with node:fs and memfs)\nexport interface UnderlyingFS {\n promises: {\n readFile(path: string): Promise<Buffer | Uint8Array | string>;\n readdir(path: string): Promise<string[]>;\n stat(path: string): Promise<{\n isFile(): boolean;\n isDirectory(): boolean;\n size: number;\n mtime: Date;\n }>;\n writeFile(path: string, data: Buffer | string): Promise<void>;\n appendFile(path: string, data: Buffer | string): Promise<void>;\n mkdir(path: string, opts?: { recursive?: boolean }): Promise<string | undefined | void>;\n rm(path: string, opts?: { recursive?: boolean; force?: boolean }): Promise<void>;\n };\n}\n\n// Default: use real node:fs\nconst defaultFS: UnderlyingFS = { promises: nodeFs };\n\ninterface CompiledRule {\n pattern: string;\n permission: Permission;\n specificity: number;\n}\n\nexport class FileSystem implements VirtualFS {\n private readonly mountBase: string | null;\n private readonly rules: CompiledRule[];\n protected readonly underlyingFs: UnderlyingFS;\n\n constructor(mountPath?: string, permissions?: PermissionRules, fs?: UnderlyingFS) {\n this.mountBase = mountPath ? path.resolve(mountPath) : null;\n this.rules = this.compileRules(permissions ?? {});\n this.underlyingFs = fs ?? defaultFS;\n }\n\n private compileRules(permissions: PermissionRules): CompiledRule[] {\n return Object.entries(permissions)\n .map(([pattern, permission]) => ({\n pattern,\n permission,\n specificity: this.calculateSpecificity(pattern),\n }))\n .sort((a, b) => b.specificity - a.specificity); // highest first\n }\n\n private calculateSpecificity(pattern: string): number {\n const segments = pattern.split(\"/\").filter(Boolean);\n let score = segments.length * 1000; // segment count is primary\n\n for (const seg of segments) {\n if (seg === \"**\") score += 0;\n else if (seg.includes(\"*\")) score += 1;\n else score += 10; // literal segment\n }\n return score;\n }\n\n public getPermission(virtualPath: string): Permission {\n const normalized = virtualPath.replace(/^\\/+/, \"\"); // strip leading slashes\n\n for (const rule of this.rules) {\n if (this.matchGlob(rule.pattern, normalized)) {\n return rule.permission;\n }\n }\n return \"read-write\"; // default\n }\n\n private matchGlob(pattern: string, filePath: string): boolean {\n // Convert glob to regex\n // ** matches any path segments, * matches within segment\n const regex = pattern\n .split(\"/\")\n .map((seg) => {\n if (seg === \"**\") return \".*\";\n return seg.replace(/\\*/g, \"[^/]*\").replace(/\\?/g, \"[^/]\");\n })\n .join(\"/\");\n return new RegExp(`^${regex}$`).test(filePath);\n }\n\n public checkPermission(virtualPath: string, operation: \"read\" | \"write\"): void {\n const perm = this.getPermission(virtualPath);\n\n if (perm === \"excluded\") {\n throw new Error(`Access denied: \"${virtualPath}\" is excluded`);\n }\n if (operation === \"write\" && perm === \"read-only\") {\n throw new Error(`Access denied: \"${virtualPath}\" is read-only`);\n }\n }\n\n private resolveSafePath(virtualPath: string): string {\n if (this.mountBase === null) {\n return path.resolve(virtualPath);\n }\n\n // Check for path traversal by tracking depth\n const segments = virtualPath.split(\"/\").filter(Boolean);\n let depth = 0;\n for (const seg of segments) {\n if (seg === \"..\") {\n depth--;\n if (depth < 0) {\n throw new Error(`Path traversal blocked: \"${virtualPath}\" escapes mount point`);\n }\n } else if (seg !== \".\") {\n depth++;\n }\n }\n\n const normalized = path.normalize(virtualPath);\n const relativePath = normalized.startsWith(\"/\") ? normalized.slice(1) : normalized;\n const realPath = path.join(this.mountBase, relativePath);\n const resolved = path.resolve(realPath);\n\n // Double-check containment (defense in depth)\n if (!resolved.startsWith(this.mountBase + path.sep) && resolved !== this.mountBase) {\n throw new Error(`Path traversal blocked: \"${virtualPath}\" escapes mount point`);\n }\n\n return resolved;\n }\n\n // Read operations\n async readFile(filePath: string): Promise<Buffer> {\n this.checkPermission(filePath, \"read\");\n const realPath = this.resolveSafePath(filePath);\n const content = await this.underlyingFs.promises.readFile(realPath);\n return Buffer.from(content);\n }\n\n async readdir(dirPath: string): Promise<string[]> {\n this.checkPermission(dirPath, \"read\");\n const realPath = this.resolveSafePath(dirPath);\n const entries = await this.underlyingFs.promises.readdir(realPath);\n return entries.map(String);\n }\n\n async stat(filePath: string): Promise<FileStat> {\n this.checkPermission(filePath, \"read\");\n const realPath = this.resolveSafePath(filePath);\n const stats = await this.underlyingFs.promises.stat(realPath);\n return {\n isFile: () => stats.isFile(),\n isDirectory: () => stats.isDirectory(),\n size: stats.size,\n mtime: stats.mtime,\n };\n }\n\n async exists(filePath: string): Promise<boolean> {\n try {\n this.checkPermission(filePath, \"read\");\n const realPath = this.resolveSafePath(filePath);\n await this.underlyingFs.promises.stat(realPath);\n return true;\n } catch {\n return false;\n }\n }\n\n // Write operations\n async writeFile(filePath: string, data: Buffer | string): Promise<void> {\n this.checkPermission(filePath, \"write\");\n const realPath = this.resolveSafePath(filePath);\n await this.underlyingFs.promises.writeFile(realPath, data);\n }\n\n async appendFile(filePath: string, data: Buffer | string): Promise<void> {\n this.checkPermission(filePath, \"write\");\n const realPath = this.resolveSafePath(filePath);\n await this.underlyingFs.promises.appendFile(realPath, data);\n }\n\n async mkdir(dirPath: string, opts?: { recursive?: boolean }): Promise<void> {\n this.checkPermission(dirPath, \"write\");\n const realPath = this.resolveSafePath(dirPath);\n await this.underlyingFs.promises.mkdir(realPath, opts);\n }\n\n async rm(filePath: string, opts?: { recursive?: boolean; force?: boolean }): Promise<void> {\n this.checkPermission(filePath, \"write\");\n const realPath = this.resolveSafePath(filePath);\n await this.underlyingFs.promises.rm(realPath, opts);\n }\n\n // Path utilities (no permission check needed)\n resolve(...paths: string[]): string {\n return path.resolve(\"/\", ...paths);\n }\n\n dirname(filePath: string): string {\n return path.dirname(filePath);\n }\n\n basename(filePath: string): string {\n return path.basename(filePath);\n }\n\n // Glob with permission filtering\n async glob(pattern: string, opts?: { cwd?: string }): Promise<string[]> {\n const cwd = opts?.cwd ?? \"/\";\n this.checkPermission(cwd, \"read\");\n\n const matches = await this.expandGlob(pattern, cwd);\n\n // Filter out excluded paths\n return matches.filter((p) => this.getPermission(p) !== \"excluded\").sort();\n }\n\n // Glob expansion (similar to memfs-adapter implementation)\n private async expandGlob(pattern: string, cwd: string): Promise<string[]> {\n // Handle brace expansion first\n const patterns = this.expandBraces(pattern);\n const allMatches: string[] = [];\n\n for (const pat of patterns) {\n const matches = await this.matchPattern(pat, cwd);\n allMatches.push(...matches);\n }\n\n // Remove duplicates and sort\n return [...new Set(allMatches)].sort();\n }\n\n private expandBraces(pattern: string): string[] {\n const braceMatch = pattern.match(/\\{([^{}]+)\\}/);\n if (!braceMatch) return [pattern];\n\n const before = pattern.slice(0, braceMatch.index);\n const after = pattern.slice(braceMatch.index! + braceMatch[0].length);\n const options = braceMatch[1]!.split(\",\");\n\n const results: string[] = [];\n for (const opt of options) {\n const expanded = this.expandBraces(before + opt + after);\n results.push(...expanded);\n }\n return results;\n }\n\n private async matchPattern(pattern: string, cwd: string): Promise<string[]> {\n const parts = pattern.split(\"/\").filter((p) => p !== \"\");\n const isAbsolute = pattern.startsWith(\"/\");\n const startDir = isAbsolute ? \"/\" : cwd;\n\n return this.matchParts(parts, startDir);\n }\n\n private async matchParts(parts: string[], currentPath: string): Promise<string[]> {\n if (parts.length === 0) {\n return [currentPath];\n }\n\n const [part, ...rest] = parts;\n\n // Handle ** (recursive glob)\n if (part === \"**\") {\n const results: string[] = [];\n\n // Match current directory\n const withoutStar = await this.matchParts(rest, currentPath);\n results.push(...withoutStar);\n\n // Recurse into subdirectories\n try {\n const realPath = this.resolveSafePath(currentPath);\n const entries = await this.underlyingFs.promises.readdir(realPath);\n for (const entry of entries) {\n const entryPath = path.posix.join(currentPath, String(entry));\n try {\n const entryRealPath = this.resolveSafePath(entryPath);\n const stat = await this.underlyingFs.promises.stat(entryRealPath);\n if (stat.isDirectory()) {\n const subMatches = await this.matchParts(parts, entryPath);\n results.push(...subMatches);\n }\n } catch {\n // Skip inaccessible entries\n }\n }\n } catch {\n // Directory not readable\n }\n\n return results;\n }\n\n // Handle regular glob patterns\n const regex = this.globToRegex(part!);\n\n try {\n const realPath = this.resolveSafePath(currentPath);\n const entries = await this.underlyingFs.promises.readdir(realPath);\n const results: string[] = [];\n\n for (const entry of entries) {\n const entryName = String(entry);\n if (regex.test(entryName)) {\n const entryPath = path.posix.join(currentPath, entryName);\n if (rest.length === 0) {\n results.push(entryPath);\n } else {\n try {\n const entryRealPath = this.resolveSafePath(entryPath);\n const stat = await this.underlyingFs.promises.stat(entryRealPath);\n if (stat.isDirectory()) {\n const subMatches = await this.matchParts(rest, entryPath);\n results.push(...subMatches);\n }\n } catch {\n // Skip inaccessible entries\n }\n }\n }\n }\n\n return results;\n } catch {\n return [];\n }\n }\n\n private globToRegex(pattern: string): RegExp {\n let regex = \"^\";\n for (let i = 0; i < pattern.length; i++) {\n const char = pattern[i]!;\n if (char === \"*\") {\n regex += \"[^/]*\";\n } else if (char === \"?\") {\n regex += \"[^/]\";\n } else if (char === \"[\") {\n // Character class\n let j = i + 1;\n let classContent = \"\";\n while (j < pattern.length && pattern[j] !== \"]\") {\n classContent += pattern[j];\n j++;\n }\n regex += `[${classContent}]`;\n i = j;\n } else if (\".+^${}()|\\\\\".includes(char)) {\n regex += \"\\\\\" + char;\n } else {\n regex += char;\n }\n }\n regex += \"$\";\n return new RegExp(regex);\n }\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAsB,IAAtB;AACwB,IAAxB;AAyBA,IAAM,YAA0B,EAAE,UAAU,OAAO;AAAA;AAQ5C,MAAM,WAAgC;AAAA,EAC1B;AAAA,EACA;AAAA,EACE;AAAA,EAEnB,WAAW,CAAC,WAAoB,aAA+B,IAAmB;AAAA,IAChF,KAAK,YAAY,YAAiB,aAAQ,SAAS,IAAI;AAAA,IACvD,KAAK,QAAQ,KAAK,aAAa,eAAe,CAAC,CAAC;AAAA,IAChD,KAAK,eAAe,MAAM;AAAA;AAAA,EAGpB,YAAY,CAAC,aAA8C;AAAA,IACjE,OAAO,OAAO,QAAQ,WAAW,EAC9B,IAAI,EAAE,SAAS,iBAAiB;AAAA,MAC/B;AAAA,MACA;AAAA,MACA,aAAa,KAAK,qBAAqB,OAAO;AAAA,IAChD,EAAE,EACD,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,EAAE,WAAW;AAAA;AAAA,EAGzC,oBAAoB,CAAC,SAAyB;AAAA,IACpD,MAAM,WAAW,QAAQ,MAAM,GAAG,EAAE,OAAO,OAAO;AAAA,IAClD,IAAI,QAAQ,SAAS,SAAS;AAAA,IAE9B,WAAW,OAAO,UAAU;AAAA,MAC1B,IAAI,QAAQ;AAAA,QAAM,SAAS;AAAA,MACtB,SAAI,IAAI,SAAS,GAAG;AAAA,QAAG,SAAS;AAAA,MAChC;AAAA,iBAAS;AAAA,IAChB;AAAA,IACA,OAAO;AAAA;AAAA,
|
|
7
|
+
"mappings": "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",
|
|
8
8
|
"debugId": "FE5125D36453662C64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
6
|
+
var __toCommonJS = (from) => {
|
|
7
|
+
var entry = __moduleCache.get(from), desc;
|
|
8
|
+
if (entry)
|
|
9
|
+
return entry;
|
|
10
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function")
|
|
12
|
+
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
13
|
+
get: () => from[key],
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
}));
|
|
16
|
+
__moduleCache.set(from, entry);
|
|
17
|
+
return entry;
|
|
18
|
+
};
|
|
19
|
+
var __export = (target, all) => {
|
|
20
|
+
for (var name in all)
|
|
21
|
+
__defProp(target, name, {
|
|
22
|
+
get: all[name],
|
|
23
|
+
enumerable: true,
|
|
24
|
+
configurable: true,
|
|
25
|
+
set: (newValue) => all[name] = () => newValue
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// src/utils/expand-escapes.ts
|
|
30
|
+
var exports_expand_escapes = {};
|
|
31
|
+
__export(exports_expand_escapes, {
|
|
32
|
+
expandEscapes: () => expandEscapes
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(exports_expand_escapes);
|
|
35
|
+
function expandEscapes(s) {
|
|
36
|
+
let result = "";
|
|
37
|
+
for (let i = 0;i < s.length; i++) {
|
|
38
|
+
if (s[i] === "\\" && i + 1 < s.length) {
|
|
39
|
+
i++;
|
|
40
|
+
switch (s[i]) {
|
|
41
|
+
case "n":
|
|
42
|
+
result += `
|
|
43
|
+
`;
|
|
44
|
+
break;
|
|
45
|
+
case "t":
|
|
46
|
+
result += "\t";
|
|
47
|
+
break;
|
|
48
|
+
case "\\":
|
|
49
|
+
result += "\\";
|
|
50
|
+
break;
|
|
51
|
+
case "a":
|
|
52
|
+
result += "\x07";
|
|
53
|
+
break;
|
|
54
|
+
case "b":
|
|
55
|
+
result += "\b";
|
|
56
|
+
break;
|
|
57
|
+
case "f":
|
|
58
|
+
result += "\f";
|
|
59
|
+
break;
|
|
60
|
+
case "r":
|
|
61
|
+
result += "\r";
|
|
62
|
+
break;
|
|
63
|
+
case "v":
|
|
64
|
+
result += "\v";
|
|
65
|
+
break;
|
|
66
|
+
default:
|
|
67
|
+
result += s[i];
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
result += s[i];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
//# debugId=052B13ABAB7AAA6164756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/utils/expand-escapes.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"export function expandEscapes(s: string): string {\n let result = \"\";\n for (let i = 0; i < s.length; i++) {\n if (s[i] === \"\\\\\" && i + 1 < s.length) {\n i++;\n switch (s[i]) {\n case \"n\": result += \"\\n\"; break;\n case \"t\": result += \"\\t\"; break;\n case \"\\\\\": result += \"\\\\\"; break;\n case \"a\": result += \"\\x07\"; break;\n case \"b\": result += \"\\b\"; break;\n case \"f\": result += \"\\f\"; break;\n case \"r\": result += \"\\r\"; break;\n case \"v\": result += \"\\v\"; break;\n default: result += s[i]; break;\n }\n } else {\n result += s[i];\n }\n }\n return result;\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAO,SAAS,aAAa,CAAC,GAAmB;AAAA,EAC/C,IAAI,SAAS;AAAA,EACb,SAAS,IAAI,EAAG,IAAI,EAAE,QAAQ,KAAK;AAAA,IACjC,IAAI,EAAE,OAAO,QAAQ,IAAI,IAAI,EAAE,QAAQ;AAAA,MACrC;AAAA,MACA,QAAQ,EAAE;AAAA,aACH;AAAA,UAAK,UAAU;AAAA;AAAA,UAAM;AAAA,aACrB;AAAA,UAAK,UAAU;AAAA,UAAM;AAAA,aACrB;AAAA,UAAM,UAAU;AAAA,UAAM;AAAA,aACtB;AAAA,UAAK,UAAU;AAAA,UAAQ;AAAA,aACvB;AAAA,UAAK,UAAU;AAAA,UAAM;AAAA,aACrB;AAAA,UAAK,UAAU;AAAA,UAAM;AAAA,aACrB;AAAA,UAAK,UAAU;AAAA,UAAM;AAAA,aACrB;AAAA,UAAK,UAAU;AAAA,UAAM;AAAA;AAAA,UACjB,UAAU,EAAE;AAAA,UAAI;AAAA;AAAA,IAE7B,EAAO;AAAA,MACL,UAAU,EAAE;AAAA;AAAA,EAEhB;AAAA,EACA,OAAO;AAAA;",
|
|
8
|
+
"debugId": "052B13ABAB7AAA6164756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -29,12 +29,14 @@ var __export = (target, all) => {
|
|
|
29
29
|
// src/utils/index.ts
|
|
30
30
|
var exports_utils = {};
|
|
31
31
|
__export(exports_utils, {
|
|
32
|
+
expandEscapes: () => import_expand_escapes.expandEscapes,
|
|
32
33
|
escapeForInterpolation: () => import_escape.escapeForInterpolation,
|
|
33
34
|
escape: () => import_escape.escape,
|
|
34
35
|
createFlagParser: () => import_flag_parser.createFlagParser
|
|
35
36
|
});
|
|
36
37
|
module.exports = __toCommonJS(exports_utils);
|
|
37
38
|
var import_escape = require("./escape.cjs");
|
|
39
|
+
var import_expand_escapes = require("./expand-escapes.cjs");
|
|
38
40
|
var import_flag_parser = require("./flag-parser.cjs");
|
|
39
41
|
|
|
40
|
-
//# debugId=
|
|
42
|
+
//# debugId=D23A6A45BB39618E64756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/utils/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"export { escape, escapeForInterpolation } from \"./escape.cjs\";\nexport {\n createFlagParser,\n type FlagDefinition,\n type CommandSpec,\n type FlagError,\n type ParseResult,\n type FlagParser,\n} from \"./flag-parser.cjs\";\n"
|
|
5
|
+
"export { escape, escapeForInterpolation } from \"./escape.cjs\";\nexport { expandEscapes } from \"./expand-escapes.cjs\";\nexport {\n createFlagParser,\n type FlagDefinition,\n type CommandSpec,\n type FlagError,\n type ParseResult,\n type FlagParser,\n} from \"./flag-parser.cjs\";\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAA+C,IAA/C;AAC8B,IAA9B;AAQO,IAPP;",
|
|
8
|
+
"debugId": "D23A6A45BB39618E64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/dist/mjs/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// src/commands/awk/awk.ts
|
|
2
|
+
import { expandEscapes } from "../../utils/expand-escapes.mjs";
|
|
2
3
|
function parseProgram(programStr) {
|
|
3
4
|
const rules = [];
|
|
4
5
|
const trimmed = programStr.trim();
|
|
@@ -92,6 +93,7 @@ function parseArgs(args) {
|
|
|
92
93
|
error: { type: "missing_value", option: "-F" }
|
|
93
94
|
};
|
|
94
95
|
}
|
|
96
|
+
fs = expandEscapes(fs);
|
|
95
97
|
if (fs.length === 1) {
|
|
96
98
|
options.fieldSeparator = new RegExp(escapeRegex(fs));
|
|
97
99
|
} else {
|
|
@@ -208,7 +210,7 @@ function evaluateExpression(expr, fields, line, lineNumber) {
|
|
|
208
210
|
const parts = [];
|
|
209
211
|
for (const token of tokens) {
|
|
210
212
|
if (token.startsWith('"') && token.endsWith('"') || token.startsWith("'") && token.endsWith("'")) {
|
|
211
|
-
parts.push(token.slice(1, -1));
|
|
213
|
+
parts.push(expandEscapes(token.slice(1, -1)));
|
|
212
214
|
} else if (token.match(/^\$(\d+)$/)) {
|
|
213
215
|
const fieldNum = parseInt(token.slice(1), 10);
|
|
214
216
|
if (fieldNum === 0) {
|
|
@@ -290,4 +292,4 @@ export {
|
|
|
290
292
|
awk
|
|
291
293
|
};
|
|
292
294
|
|
|
293
|
-
//# debugId=
|
|
295
|
+
//# debugId=07693D1FE74122D064756E2164756E21
|