touch-all 2.1.0 → 2.1.1

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/dist/lib/index.js CHANGED
@@ -778,7 +778,7 @@ class PathTraversalError {
778
778
  this.path = path;
779
779
  }
780
780
  toString() {
781
- return `${this._tag}: The path cannot be used ${this.path}`;
781
+ return `${this._tag}: path escapes root ${this.path}`;
782
782
  }
783
783
  }
784
784
 
@@ -1,4 +1,4 @@
1
1
  import { Path, Terminal } from '@effect/platform';
2
2
  import { Effect } from 'effect';
3
3
  import { type ParserResult } from './types';
4
- export declare const checkOutsideSymlinks: (treeString: string, projectRoot: string, yes: boolean) => Effect.Effect<ParserResult, Error, Path.Path | Terminal.Terminal>;
4
+ export declare const parseAndGuardSymlinks: (treeString: string, projectRoot: string, yes: boolean) => Effect.Effect<ParserResult, Error, Path.Path | Terminal.Terminal>;
@@ -805,7 +805,7 @@ class PathTraversalError {
805
805
  this.path = path;
806
806
  }
807
807
  toString() {
808
- return `${this._tag}: The path cannot be used ${this.path}`;
808
+ return `${this._tag}: path escapes root ${this.path}`;
809
809
  }
810
810
  }
811
811
 
@@ -920,7 +920,7 @@ function countLeadingSpaces(str) {
920
920
  }
921
921
 
922
922
  // src/symlinkGuard.ts
923
- var checkOutsideSymlinks = (treeString, projectRoot, yes) => Effect5.gen(function* () {
923
+ var parseAndGuardSymlinks = (treeString, projectRoot, yes) => Effect5.gen(function* () {
924
924
  const nodePath = yield* exports_Path.Path;
925
925
  const items = parserFolderStructure(treeString);
926
926
  const resolvedRoot = nodePath.resolve(projectRoot);
@@ -932,13 +932,13 @@ var checkOutsideSymlinks = (treeString, projectRoot, yes) => Effect5.gen(functio
932
932
  return items;
933
933
  const listing = outsideSymlinks.map((item) => ` ${item.path} -> ${item.target}`).join(`
934
934
  `);
935
- yield* Console2.log(`Warning: the following symlinks point outside PROJECT_ROOT (${resolvedRoot}):
935
+ yield* Console2.error(`Warning: the following symlinks point outside PROJECT_ROOT (${resolvedRoot}):
936
936
  ${listing}`);
937
937
  const terminal = yield* exports_Terminal.Terminal;
938
938
  yield* terminal.display("Proceed? (y/N) ");
939
939
  const answer = yield* terminal.readLine.pipe(Effect5.catchTag("QuitException", () => Effect5.fail(new Error(`Non-interactive mode: use --yes to allow symlinks outside project root`))));
940
940
  if (answer.trim().toLowerCase() !== "y") {
941
- yield* Console2.log("Aborted.");
941
+ yield* Console2.error("Aborted.");
942
942
  return yield* Effect5.fail(new Error("Aborted by user"));
943
943
  }
944
944
  return items;
@@ -948,19 +948,23 @@ ${listing}`);
948
948
  import { createInterface } from "node:readline";
949
949
  import { Effect as Effect6 } from "effect";
950
950
  var readStdin = Effect6.tryPromise({
951
- try: () => new Promise((resolve3) => {
952
- const rl = createInterface({ input: process.stdin });
953
- const lines = [];
954
- rl.on("line", (line) => lines.push(line));
955
- rl.on("close", () => resolve3(lines.join(`
951
+ try: () => new Promise((resolve3, reject) => {
952
+ try {
953
+ const rl = createInterface({ input: process.stdin });
954
+ const lines = [];
955
+ rl.on("line", (line) => lines.push(line));
956
+ rl.on("close", () => resolve3(lines.join(`
956
957
  `)));
958
+ } catch (e) {
959
+ reject(e);
960
+ }
957
961
  }),
958
962
  catch: (e) => new Error(`Failed to read stdin: ${String(e)}`)
959
963
  });
960
964
  // package.json
961
965
  var package_default = {
962
966
  name: "touch-all",
963
- version: "2.1.0",
967
+ version: "2.1.1",
964
968
  description: "CLI tool to create folder structures from markdown tree representations",
965
969
  keywords: [
966
970
  "cli",
@@ -1036,24 +1040,24 @@ var command = Command2.make(name, {
1036
1040
  dryRun: dryRunOption,
1037
1041
  verbose: verboseOption,
1038
1042
  yes: yesOption
1039
- }).pipe(Command2.withDescription("Create directory structure from a tree representation"), Command2.withHandler(({ tree, path: targetPath, dryRun = false, verbose, yes }) => {
1043
+ }).pipe(Command2.withDescription("Create directory structure from a tree representation"), Command2.withHandler(({ tree, path: targetPath, dryRun, verbose, yes }) => {
1040
1044
  const program = Effect7.gen(function* () {
1041
1045
  const rawTree = Option2.isSome(tree) ? tree.value : yield* readStdin;
1042
1046
  const treeString = Option2.isSome(tree) ? rawTree.replace(/\\(\\|n)/g, (_, c) => c === "n" ? `
1043
1047
  ` : "\\") : rawTree;
1044
1048
  if (dryRun) {
1045
- yield* Effect7.logInfo("Running in dry mode. No one file system node will be created.");
1049
+ yield* Effect7.logInfo("Dry run: no changes will be made to the file system.");
1046
1050
  }
1047
1051
  yield* Effect7.logInfo("Parsing tree structure...");
1048
- const items = yield* checkOutsideSymlinks(treeString, targetPath, yes);
1052
+ const items = yield* parseAndGuardSymlinks(treeString, targetPath, yes);
1049
1053
  if (items.length === 0) {
1050
1054
  yield* Console3.error("No valid items found in the tree structure");
1051
1055
  return yield* Effect7.fail(new Error("Invalid tree structure"));
1052
1056
  }
1053
1057
  yield* Effect7.logInfo(`Found ${items.length} items to create`);
1054
- yield* Effect7.logInfo(`Found:
1055
- ${items.map((i) => `${i.path}
1056
- `).join("")}`);
1058
+ yield* Effect7.logInfo(`Found:
1059
+ ${items.map((i) => i.path).join(`
1060
+ `)}`);
1057
1061
  if (!dryRun) {
1058
1062
  yield* fileStructureCreator(items, targetPath, { allowOutsideSymlinks: yes });
1059
1063
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "touch-all",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "description": "CLI tool to create folder structures from markdown tree representations",
5
5
  "keywords": [
6
6
  "cli",