@nshiab/setup-data-project 1.0.29 → 1.0.31

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.
Files changed (49) hide show
  1. package/esm/helpers/createFolderStructure.d.ts +1 -1
  2. package/esm/helpers/createFolderStructure.d.ts.map +1 -1
  3. package/esm/helpers/createFolderStructure.js +4 -7
  4. package/esm/helpers/ensureAgents.d.ts.map +1 -1
  5. package/esm/helpers/ensureAgents.js +6 -1
  6. package/esm/helpers/ensureEnvFile.d.ts +1 -1
  7. package/esm/helpers/ensureEnvFile.d.ts.map +1 -1
  8. package/esm/helpers/ensureEnvFile.js +4 -6
  9. package/esm/helpers/ensureGitignore.d.ts +1 -0
  10. package/esm/helpers/ensureGitignore.d.ts.map +1 -1
  11. package/esm/helpers/ensureGitignore.js +19 -16
  12. package/esm/helpers/projectManifest.d.ts +11 -0
  13. package/esm/helpers/projectManifest.d.ts.map +1 -0
  14. package/esm/helpers/projectManifest.js +73 -0
  15. package/esm/main.js +15 -11
  16. package/package.json +1 -1
  17. package/script/helpers/createFolderStructure.d.ts +1 -1
  18. package/script/helpers/createFolderStructure.d.ts.map +1 -1
  19. package/script/helpers/createFolderStructure.js +3 -6
  20. package/script/helpers/ensureAgents.d.ts.map +1 -1
  21. package/script/helpers/ensureAgents.js +6 -1
  22. package/script/helpers/ensureEnvFile.d.ts +1 -1
  23. package/script/helpers/ensureEnvFile.d.ts.map +1 -1
  24. package/script/helpers/ensureEnvFile.js +4 -6
  25. package/script/helpers/ensureGitignore.d.ts +1 -0
  26. package/script/helpers/ensureGitignore.d.ts.map +1 -1
  27. package/script/helpers/ensureGitignore.js +19 -15
  28. package/script/helpers/projectManifest.d.ts +11 -0
  29. package/script/helpers/projectManifest.d.ts.map +1 -0
  30. package/script/helpers/projectManifest.js +77 -0
  31. package/script/main.js +14 -10
  32. package/esm/helpers/getInstalledPackages.d.ts +0 -2
  33. package/esm/helpers/getInstalledPackages.d.ts.map +0 -1
  34. package/esm/helpers/getInstalledPackages.js +0 -29
  35. package/esm/helpers/handleFileConflict.d.ts +0 -5
  36. package/esm/helpers/handleFileConflict.d.ts.map +0 -1
  37. package/esm/helpers/handleFileConflict.js +0 -50
  38. package/esm/helpers/updateProjectConfig.d.ts +0 -2
  39. package/esm/helpers/updateProjectConfig.d.ts.map +0 -1
  40. package/esm/helpers/updateProjectConfig.js +0 -42
  41. package/script/helpers/getInstalledPackages.d.ts +0 -2
  42. package/script/helpers/getInstalledPackages.d.ts.map +0 -1
  43. package/script/helpers/getInstalledPackages.js +0 -32
  44. package/script/helpers/handleFileConflict.d.ts +0 -5
  45. package/script/helpers/handleFileConflict.d.ts.map +0 -1
  46. package/script/helpers/handleFileConflict.js +0 -57
  47. package/script/helpers/updateProjectConfig.d.ts +0 -2
  48. package/script/helpers/updateProjectConfig.d.ts.map +0 -1
  49. package/script/helpers/updateProjectConfig.js +0 -45
@@ -1,2 +1,2 @@
1
- export declare function createFolderStructure(selectedPackages: string[]): Promise<string>;
1
+ export declare function createFolderStructure(selectedPackages: string[]): string;
2
2
  //# sourceMappingURL=createFolderStructure.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createFolderStructure.d.ts","sourceRoot":"","sources":["../../src/helpers/createFolderStructure.ts"],"names":[],"mappings":"AAKA,wBAAsB,qBAAqB,CAAC,gBAAgB,EAAE,MAAM,EAAE,mBA8CrE"}
1
+ {"version":3,"file":"createFolderStructure.d.ts","sourceRoot":"","sources":["../../src/helpers/createFolderStructure.ts"],"names":[],"mappings":"AAGA,wBAAgB,qBAAqB,CAAC,gBAAgB,EAAE,MAAM,EAAE,UA6C/D"}
@@ -1,8 +1,6 @@
1
- import { existsSync, mkdirSync } from "node:fs";
1
+ import { existsSync, lstatSync, mkdirSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
- import { log } from "@clack/prompts";
4
- import { handleFileConflict } from "./handleFileConflict.js";
5
- export async function createFolderStructure(selectedPackages) {
3
+ export function createFolderStructure(selectedPackages) {
6
4
  const sdaFolder = "sda";
7
5
  const folders = ["data", "helpers", "output"];
8
6
  if (!existsSync(sdaFolder)) {
@@ -34,9 +32,8 @@ await table.logTable();
34
32
  await sdb.done();
35
33
  `;
36
34
  }
37
- const status = await handleFileConflict(mainTsPath, mainTsContent);
38
- if (status === "updated") {
39
- log.info(`Updated ${mainTsPath}`);
35
+ if (lstatSync(mainTsPath, { throwIfNoEntry: false }) === undefined) {
36
+ writeFileSync(mainTsPath, mainTsContent);
40
37
  }
41
38
  return sdaFolder;
42
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ensureAgents.d.ts","sourceRoot":"","sources":["../../src/helpers/ensureAgents.ts"],"names":[],"mappings":"AAOA,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,OAAO,EAAE,MAAM,EACf,iBAAiB,GAAE,MAAM,EAA6B,QAkHvD"}
1
+ {"version":3,"file":"ensureAgents.d.ts","sourceRoot":"","sources":["../../src/helpers/ensureAgents.ts"],"names":[],"mappings":"AAOA,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,OAAO,EAAE,MAAM,EACf,iBAAiB,GAAE,MAAM,EAA6B,QAuHvD"}
@@ -4,6 +4,8 @@ import { getInstalledPackageConfigs, SUPPORTED_PACKAGES, } from "./packageRegist
4
4
  export function ensureAgents(docsMapping, runtime, installedPackages = Object.keys(docsMapping)) {
5
5
  let journalismFunctions = "";
6
6
  let sdaClassesAndMethods = "";
7
+ let sdaDocsPath = "";
8
+ let sdaLibraryName = "";
7
9
  for (const [pkg, doc] of Object.entries(docsMapping)) {
8
10
  const pkgConfig = SUPPORTED_PACKAGES.find((p) => p.value === pkg);
9
11
  const pkgType = pkgConfig?.type || "other";
@@ -21,6 +23,9 @@ export function ensureAgents(docsMapping, runtime, installedPackages = Object.ke
21
23
  .join("\n") + "\n";
22
24
  }
23
25
  else if (pkgType === "sda") {
26
+ const repoName = pkg.split("/")[1];
27
+ sdaDocsPath = `./docs/${repoName}.md`;
28
+ sdaLibraryName = pkgConfig?.label || repoName;
24
29
  sdaClassesAndMethods = doc
25
30
  .split("\n")
26
31
  .filter((line) => line.trim().startsWith("#"))
@@ -87,7 +92,7 @@ ${journalismFunctions}`;
87
92
  }
88
93
  if (sdaClassesAndMethods !== "") {
89
94
  content += `
90
- Here are the classes and their methods available in the "simple-data-analysis" library. If one of the classes or methods might be relevant, read the complete documentation at "./docs/simple-data-analysis.md" to properly use it. Remember that almost all methods are asynchronous, so you need to use \`await\` when calling them.
95
+ Here are the classes and their methods available in the "${sdaLibraryName}" library. If one of the classes or methods might be relevant, read the complete documentation at "${sdaDocsPath}" to properly use it. Remember that almost all methods are asynchronous, so you need to use \`await\` when calling them.
91
96
  ${sdaClassesAndMethods}`;
92
97
  }
93
98
  const status = ensureManagedSection({
@@ -1,2 +1,2 @@
1
- export declare function ensureEnvFile(): Promise<void>;
1
+ export declare function ensureEnvFile(): void;
2
2
  //# sourceMappingURL=ensureEnvFile.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ensureEnvFile.d.ts","sourceRoot":"","sources":["../../src/helpers/ensureEnvFile.ts"],"names":[],"mappings":"AAGA,wBAAsB,aAAa,kBAKlC"}
1
+ {"version":3,"file":"ensureEnvFile.d.ts","sourceRoot":"","sources":["../../src/helpers/ensureEnvFile.ts"],"names":[],"mappings":"AAEA,wBAAgB,aAAa,SAI5B"}
@@ -1,8 +1,6 @@
1
- import { log } from "@clack/prompts";
2
- import { handleFileConflict } from "./handleFileConflict.js";
3
- export async function ensureEnvFile() {
4
- const status = await handleFileConflict(".env", "");
5
- if (status === "updated") {
6
- log.info("Updated .env");
1
+ import { lstatSync, writeFileSync } from "node:fs";
2
+ export function ensureEnvFile() {
3
+ if (lstatSync(".env", { throwIfNoEntry: false }) === undefined) {
4
+ writeFileSync(".env", "");
7
5
  }
8
6
  }
@@ -1,2 +1,3 @@
1
+ export declare const GITIGNORE_SENTINEL = "# Added by setup-data-project. Do not remove this line.";
1
2
  export declare function ensureGitignore(): void;
2
3
  //# sourceMappingURL=ensureGitignore.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ensureGitignore.d.ts","sourceRoot":"","sources":["../../src/helpers/ensureGitignore.ts"],"names":[],"mappings":"AAIA,wBAAgB,eAAe,SAqB9B"}
1
+ {"version":3,"file":"ensureGitignore.d.ts","sourceRoot":"","sources":["../../src/helpers/ensureGitignore.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,kBAAkB,4DAC4B,CAAC;AAE5D,wBAAgB,eAAe,SA4B9B"}
@@ -1,23 +1,26 @@
1
- import { existsSync, readFileSync, writeFileSync } from "node:fs";
1
+ import { lstatSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { log } from "@clack/prompts";
3
3
  import { GITIGNORE_ENTRIES } from "./gitignoreEntries.js";
4
+ export const GITIGNORE_SENTINEL = "# Added by setup-data-project. Do not remove this line.";
4
5
  export function ensureGitignore() {
5
6
  const path = ".gitignore";
6
- let content = "";
7
- let exists = false;
8
- if (existsSync(path)) {
9
- content = readFileSync(path, "utf-8");
10
- exists = true;
7
+ const stats = lstatSync(path, { throwIfNoEntry: false });
8
+ if (stats?.isSymbolicLink()) {
9
+ return;
11
10
  }
12
- const lines = content.split("\n").map((l) => l.trim());
13
- const toAdd = GITIGNORE_ENTRIES.filter((e) => !lines.includes(e));
14
- if (toAdd.length > 0) {
15
- const prefix = content.endsWith("\n") || content === "" ? "" : "\n";
16
- const header = "\n# Added by setup-data-project\n";
17
- const newContent = prefix + header + toAdd.join("\n") + "\n";
18
- writeFileSync(path, content + newContent);
19
- if (exists) {
20
- log.info(`Updated ${path}`);
21
- }
11
+ const content = stats === undefined ? "" : readFileSync(path, "utf-8");
12
+ const hasSentinel = content.split("\n").some((line) => line.trim() === GITIGNORE_SENTINEL);
13
+ if (hasSentinel) {
14
+ return;
15
+ }
16
+ const separator = content === ""
17
+ ? ""
18
+ : content.endsWith("\n")
19
+ ? "\n"
20
+ : "\n\n";
21
+ const block = `${GITIGNORE_SENTINEL}\n${GITIGNORE_ENTRIES.join("\n")}\n`;
22
+ writeFileSync(path, content + separator + block);
23
+ if (stats !== undefined) {
24
+ log.info(`Updated ${path}`);
22
25
  }
23
26
  }
@@ -0,0 +1,11 @@
1
+ type Runtime = "deno" | "node" | "bun";
2
+ export declare class ProjectManifest {
3
+ #private;
4
+ private constructor();
5
+ static open(runtime: Runtime): ProjectManifest;
6
+ reload(): void;
7
+ getInstalledPackages(): string[];
8
+ updateTasks(tasks: Record<string, string>): void;
9
+ }
10
+ export {};
11
+ //# sourceMappingURL=projectManifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectManifest.d.ts","sourceRoot":"","sources":["../../src/helpers/projectManifest.ts"],"names":[],"mappings":"AAEA,KAAK,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAGvC,qBAAa,eAAe;;IAM1B,OAAO;IAYP,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe;IA6B9C,MAAM,IAAI,IAAI;IAId,oBAAoB,IAAI,MAAM,EAAE;IAgBhC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;CAUjD"}
@@ -0,0 +1,73 @@
1
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
+ if (kind === "m") throw new TypeError("Private method is not writable");
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
+ };
7
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
+ };
12
+ var _ProjectManifest_path, _ProjectManifest_taskKey, _ProjectManifest_dependencyKeys, _ProjectManifest_config;
13
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
14
+ export class ProjectManifest {
15
+ constructor(path, taskKey, dependencyKeys, config) {
16
+ _ProjectManifest_path.set(this, void 0);
17
+ _ProjectManifest_taskKey.set(this, void 0);
18
+ _ProjectManifest_dependencyKeys.set(this, void 0);
19
+ _ProjectManifest_config.set(this, void 0);
20
+ __classPrivateFieldSet(this, _ProjectManifest_path, path, "f");
21
+ __classPrivateFieldSet(this, _ProjectManifest_taskKey, taskKey, "f");
22
+ __classPrivateFieldSet(this, _ProjectManifest_dependencyKeys, dependencyKeys, "f");
23
+ __classPrivateFieldSet(this, _ProjectManifest_config, config, "f");
24
+ }
25
+ static open(runtime) {
26
+ if (existsSync("deno.json")) {
27
+ return new ProjectManifest("deno.json", "tasks", ["imports"], readManifest("deno.json"));
28
+ }
29
+ if (existsSync("package.json")) {
30
+ return new ProjectManifest("package.json", "scripts", ["dependencies", "devDependencies"], readManifest("package.json"));
31
+ }
32
+ return runtime === "deno"
33
+ ? new ProjectManifest("deno.json", "tasks", ["imports"], { tasks: {} })
34
+ : new ProjectManifest("package.json", "scripts", ["dependencies", "devDependencies"], { name: "data-project", type: "module", scripts: {} });
35
+ }
36
+ reload() {
37
+ __classPrivateFieldSet(this, _ProjectManifest_config, readManifest(__classPrivateFieldGet(this, _ProjectManifest_path, "f")), "f");
38
+ }
39
+ getInstalledPackages() {
40
+ const installed = [];
41
+ for (const key of __classPrivateFieldGet(this, _ProjectManifest_dependencyKeys, "f")) {
42
+ const dependencies = __classPrivateFieldGet(this, _ProjectManifest_config, "f")[key];
43
+ if (dependencies && typeof dependencies === "object" &&
44
+ !Array.isArray(dependencies)) {
45
+ installed.push(...Object.keys(dependencies));
46
+ }
47
+ }
48
+ return installed;
49
+ }
50
+ updateTasks(tasks) {
51
+ const currentTasks = __classPrivateFieldGet(this, _ProjectManifest_config, "f")[__classPrivateFieldGet(this, _ProjectManifest_taskKey, "f")];
52
+ const existingTasks = currentTasks && typeof currentTasks === "object" &&
53
+ !Array.isArray(currentTasks)
54
+ ? currentTasks
55
+ : {};
56
+ __classPrivateFieldGet(this, _ProjectManifest_config, "f")[__classPrivateFieldGet(this, _ProjectManifest_taskKey, "f")] = { ...existingTasks, ...tasks };
57
+ writeFileSync(__classPrivateFieldGet(this, _ProjectManifest_path, "f"), JSON.stringify(__classPrivateFieldGet(this, _ProjectManifest_config, "f"), null, 2), "utf-8");
58
+ }
59
+ }
60
+ _ProjectManifest_path = new WeakMap(), _ProjectManifest_taskKey = new WeakMap(), _ProjectManifest_dependencyKeys = new WeakMap(), _ProjectManifest_config = new WeakMap();
61
+ function readManifest(path) {
62
+ try {
63
+ const parsed = JSON.parse(readFileSync(path, "utf-8"));
64
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
65
+ throw new SyntaxError("the root value must be a JSON object");
66
+ }
67
+ return parsed;
68
+ }
69
+ catch (error) {
70
+ const detail = error instanceof Error ? ` ${error.message}` : "";
71
+ throw new Error(`Failed to parse ${path}.${detail}`, { cause: error });
72
+ }
73
+ }
package/esm/main.js CHANGED
@@ -2,9 +2,7 @@
2
2
  import { cancel, intro, isCancel, multiselect, outro, select, spinner, } from "@clack/prompts";
3
3
  import process from "node:process";
4
4
  import { getRuntime } from "./helpers/getRuntime.js";
5
- import { getInstalledPackages } from "./helpers/getInstalledPackages.js";
6
5
  import { PACKAGE_OPTIONS } from "./helpers/packageOptions.js";
7
- import { updateProjectConfig } from "./helpers/updateProjectConfig.js";
8
6
  import { ensureGitignore } from "./helpers/ensureGitignore.js";
9
7
  import { ensureReadme } from "./helpers/ensureReadme.js";
10
8
  import { installPackagesAndFetchDocs } from "./helpers/installPackagesAndFetchDocs.js";
@@ -12,14 +10,16 @@ import { getProjectTasks } from "./helpers/getProjectTasks.js";
12
10
  import { createFolderStructure } from "./helpers/createFolderStructure.js";
13
11
  import { ensureEnvFile } from "./helpers/ensureEnvFile.js";
14
12
  import { ensureAgents } from "./helpers/ensureAgents.js";
15
- import { SUPPORTED_PACKAGES } from "./helpers/packageRegistry.js";
13
+ import { getInstalledPackageConfigs } from "./helpers/packageRegistry.js";
14
+ import { ProjectManifest } from "./helpers/projectManifest.js";
16
15
  import { syncPackageDocs } from "./helpers/syncPackageDocs.js";
17
16
  async function main() {
18
17
  const runtime = getRuntime();
19
18
  console.log();
20
19
  intro(`Hi! 👋 (Running on ${runtime})`);
21
- updateProjectConfig(getProjectTasks());
22
- const installedPackages = getInstalledPackages();
20
+ const projectManifest = ProjectManifest.open(runtime);
21
+ projectManifest.updateTasks(getProjectTasks());
22
+ const installedPackages = projectManifest.getInstalledPackages();
23
23
  const options = PACKAGE_OPTIONS.map((opt) => ({
24
24
  ...opt,
25
25
  label: installedPackages.includes(opt.value)
@@ -71,15 +71,19 @@ async function main() {
71
71
  }
72
72
  }
73
73
  sInstall.stop("✅ Packages installed and documentation fetched.");
74
- updateProjectConfig(getProjectTasks());
75
- const supportedPackageNames = new Set(SUPPORTED_PACKAGES.map((pkg) => pkg.value));
76
- const finalInstalledPackages = getInstalledPackages().filter((pkg) => supportedPackageNames.has(pkg));
74
+ projectManifest.reload();
75
+ projectManifest.updateTasks(getProjectTasks());
76
+ const finalInstalledPackages = getInstalledPackageConfigs(projectManifest.getInstalledPackages()).map((pkg) => pkg.value);
77
77
  const docsMapping = await syncPackageDocs(finalInstalledPackages, packagesToInstall);
78
- await createFolderStructure(packagesToInstall);
78
+ createFolderStructure(finalInstalledPackages);
79
79
  ensureGitignore();
80
- await ensureEnvFile();
80
+ ensureEnvFile();
81
81
  await ensureReadme(runtime, finalInstalledPackages);
82
82
  await ensureAgents(docsMapping, runtime, finalInstalledPackages);
83
83
  outro("You are all set! 🙌");
84
84
  }
85
- main().catch(console.error);
85
+ main().catch((error) => {
86
+ const message = error instanceof Error ? error.message : String(error);
87
+ console.error(`❌ Error: ${message}`);
88
+ process.exitCode = 1;
89
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nshiab/setup-data-project",
3
- "version": "1.0.29",
3
+ "version": "1.0.31",
4
4
  "description": "Quickly kick off your data project using the simple-data-analysis and journalism libraries.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,2 +1,2 @@
1
- export declare function createFolderStructure(selectedPackages: string[]): Promise<string>;
1
+ export declare function createFolderStructure(selectedPackages: string[]): string;
2
2
  //# sourceMappingURL=createFolderStructure.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createFolderStructure.d.ts","sourceRoot":"","sources":["../../src/helpers/createFolderStructure.ts"],"names":[],"mappings":"AAKA,wBAAsB,qBAAqB,CAAC,gBAAgB,EAAE,MAAM,EAAE,mBA8CrE"}
1
+ {"version":3,"file":"createFolderStructure.d.ts","sourceRoot":"","sources":["../../src/helpers/createFolderStructure.ts"],"names":[],"mappings":"AAGA,wBAAgB,qBAAqB,CAAC,gBAAgB,EAAE,MAAM,EAAE,UA6C/D"}
@@ -3,9 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createFolderStructure = createFolderStructure;
4
4
  const node_fs_1 = require("node:fs");
5
5
  const node_path_1 = require("node:path");
6
- const prompts_1 = require("@clack/prompts");
7
- const handleFileConflict_js_1 = require("./handleFileConflict.js");
8
- async function createFolderStructure(selectedPackages) {
6
+ function createFolderStructure(selectedPackages) {
9
7
  const sdaFolder = "sda";
10
8
  const folders = ["data", "helpers", "output"];
11
9
  if (!(0, node_fs_1.existsSync)(sdaFolder)) {
@@ -37,9 +35,8 @@ await table.logTable();
37
35
  await sdb.done();
38
36
  `;
39
37
  }
40
- const status = await (0, handleFileConflict_js_1.handleFileConflict)(mainTsPath, mainTsContent);
41
- if (status === "updated") {
42
- prompts_1.log.info(`Updated ${mainTsPath}`);
38
+ if ((0, node_fs_1.lstatSync)(mainTsPath, { throwIfNoEntry: false }) === undefined) {
39
+ (0, node_fs_1.writeFileSync)(mainTsPath, mainTsContent);
43
40
  }
44
41
  return sdaFolder;
45
42
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ensureAgents.d.ts","sourceRoot":"","sources":["../../src/helpers/ensureAgents.ts"],"names":[],"mappings":"AAOA,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,OAAO,EAAE,MAAM,EACf,iBAAiB,GAAE,MAAM,EAA6B,QAkHvD"}
1
+ {"version":3,"file":"ensureAgents.d.ts","sourceRoot":"","sources":["../../src/helpers/ensureAgents.ts"],"names":[],"mappings":"AAOA,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,OAAO,EAAE,MAAM,EACf,iBAAiB,GAAE,MAAM,EAA6B,QAuHvD"}
@@ -7,6 +7,8 @@ const packageRegistry_js_1 = require("./packageRegistry.js");
7
7
  function ensureAgents(docsMapping, runtime, installedPackages = Object.keys(docsMapping)) {
8
8
  let journalismFunctions = "";
9
9
  let sdaClassesAndMethods = "";
10
+ let sdaDocsPath = "";
11
+ let sdaLibraryName = "";
10
12
  for (const [pkg, doc] of Object.entries(docsMapping)) {
11
13
  const pkgConfig = packageRegistry_js_1.SUPPORTED_PACKAGES.find((p) => p.value === pkg);
12
14
  const pkgType = pkgConfig?.type || "other";
@@ -24,6 +26,9 @@ function ensureAgents(docsMapping, runtime, installedPackages = Object.keys(docs
24
26
  .join("\n") + "\n";
25
27
  }
26
28
  else if (pkgType === "sda") {
29
+ const repoName = pkg.split("/")[1];
30
+ sdaDocsPath = `./docs/${repoName}.md`;
31
+ sdaLibraryName = pkgConfig?.label || repoName;
27
32
  sdaClassesAndMethods = doc
28
33
  .split("\n")
29
34
  .filter((line) => line.trim().startsWith("#"))
@@ -90,7 +95,7 @@ ${journalismFunctions}`;
90
95
  }
91
96
  if (sdaClassesAndMethods !== "") {
92
97
  content += `
93
- Here are the classes and their methods available in the "simple-data-analysis" library. If one of the classes or methods might be relevant, read the complete documentation at "./docs/simple-data-analysis.md" to properly use it. Remember that almost all methods are asynchronous, so you need to use \`await\` when calling them.
98
+ Here are the classes and their methods available in the "${sdaLibraryName}" library. If one of the classes or methods might be relevant, read the complete documentation at "${sdaDocsPath}" to properly use it. Remember that almost all methods are asynchronous, so you need to use \`await\` when calling them.
94
99
  ${sdaClassesAndMethods}`;
95
100
  }
96
101
  const status = (0, ensureManagedSection_js_1.ensureManagedSection)({
@@ -1,2 +1,2 @@
1
- export declare function ensureEnvFile(): Promise<void>;
1
+ export declare function ensureEnvFile(): void;
2
2
  //# sourceMappingURL=ensureEnvFile.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ensureEnvFile.d.ts","sourceRoot":"","sources":["../../src/helpers/ensureEnvFile.ts"],"names":[],"mappings":"AAGA,wBAAsB,aAAa,kBAKlC"}
1
+ {"version":3,"file":"ensureEnvFile.d.ts","sourceRoot":"","sources":["../../src/helpers/ensureEnvFile.ts"],"names":[],"mappings":"AAEA,wBAAgB,aAAa,SAI5B"}
@@ -1,11 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ensureEnvFile = ensureEnvFile;
4
- const prompts_1 = require("@clack/prompts");
5
- const handleFileConflict_js_1 = require("./handleFileConflict.js");
6
- async function ensureEnvFile() {
7
- const status = await (0, handleFileConflict_js_1.handleFileConflict)(".env", "");
8
- if (status === "updated") {
9
- prompts_1.log.info("Updated .env");
4
+ const node_fs_1 = require("node:fs");
5
+ function ensureEnvFile() {
6
+ if ((0, node_fs_1.lstatSync)(".env", { throwIfNoEntry: false }) === undefined) {
7
+ (0, node_fs_1.writeFileSync)(".env", "");
10
8
  }
11
9
  }
@@ -1,2 +1,3 @@
1
+ export declare const GITIGNORE_SENTINEL = "# Added by setup-data-project. Do not remove this line.";
1
2
  export declare function ensureGitignore(): void;
2
3
  //# sourceMappingURL=ensureGitignore.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ensureGitignore.d.ts","sourceRoot":"","sources":["../../src/helpers/ensureGitignore.ts"],"names":[],"mappings":"AAIA,wBAAgB,eAAe,SAqB9B"}
1
+ {"version":3,"file":"ensureGitignore.d.ts","sourceRoot":"","sources":["../../src/helpers/ensureGitignore.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,kBAAkB,4DAC4B,CAAC;AAE5D,wBAAgB,eAAe,SA4B9B"}
@@ -1,26 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GITIGNORE_SENTINEL = void 0;
3
4
  exports.ensureGitignore = ensureGitignore;
4
5
  const node_fs_1 = require("node:fs");
5
6
  const prompts_1 = require("@clack/prompts");
6
7
  const gitignoreEntries_js_1 = require("./gitignoreEntries.js");
8
+ exports.GITIGNORE_SENTINEL = "# Added by setup-data-project. Do not remove this line.";
7
9
  function ensureGitignore() {
8
10
  const path = ".gitignore";
9
- let content = "";
10
- let exists = false;
11
- if ((0, node_fs_1.existsSync)(path)) {
12
- content = (0, node_fs_1.readFileSync)(path, "utf-8");
13
- exists = true;
11
+ const stats = (0, node_fs_1.lstatSync)(path, { throwIfNoEntry: false });
12
+ if (stats?.isSymbolicLink()) {
13
+ return;
14
14
  }
15
- const lines = content.split("\n").map((l) => l.trim());
16
- const toAdd = gitignoreEntries_js_1.GITIGNORE_ENTRIES.filter((e) => !lines.includes(e));
17
- if (toAdd.length > 0) {
18
- const prefix = content.endsWith("\n") || content === "" ? "" : "\n";
19
- const header = "\n# Added by setup-data-project\n";
20
- const newContent = prefix + header + toAdd.join("\n") + "\n";
21
- (0, node_fs_1.writeFileSync)(path, content + newContent);
22
- if (exists) {
23
- prompts_1.log.info(`Updated ${path}`);
24
- }
15
+ const content = stats === undefined ? "" : (0, node_fs_1.readFileSync)(path, "utf-8");
16
+ const hasSentinel = content.split("\n").some((line) => line.trim() === exports.GITIGNORE_SENTINEL);
17
+ if (hasSentinel) {
18
+ return;
19
+ }
20
+ const separator = content === ""
21
+ ? ""
22
+ : content.endsWith("\n")
23
+ ? "\n"
24
+ : "\n\n";
25
+ const block = `${exports.GITIGNORE_SENTINEL}\n${gitignoreEntries_js_1.GITIGNORE_ENTRIES.join("\n")}\n`;
26
+ (0, node_fs_1.writeFileSync)(path, content + separator + block);
27
+ if (stats !== undefined) {
28
+ prompts_1.log.info(`Updated ${path}`);
25
29
  }
26
30
  }
@@ -0,0 +1,11 @@
1
+ type Runtime = "deno" | "node" | "bun";
2
+ export declare class ProjectManifest {
3
+ #private;
4
+ private constructor();
5
+ static open(runtime: Runtime): ProjectManifest;
6
+ reload(): void;
7
+ getInstalledPackages(): string[];
8
+ updateTasks(tasks: Record<string, string>): void;
9
+ }
10
+ export {};
11
+ //# sourceMappingURL=projectManifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectManifest.d.ts","sourceRoot":"","sources":["../../src/helpers/projectManifest.ts"],"names":[],"mappings":"AAEA,KAAK,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAGvC,qBAAa,eAAe;;IAM1B,OAAO;IAYP,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe;IA6B9C,MAAM,IAAI,IAAI;IAId,oBAAoB,IAAI,MAAM,EAAE;IAgBhC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;CAUjD"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
+ if (kind === "m") throw new TypeError("Private method is not writable");
4
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ };
8
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
+ };
13
+ var _ProjectManifest_path, _ProjectManifest_taskKey, _ProjectManifest_dependencyKeys, _ProjectManifest_config;
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.ProjectManifest = void 0;
16
+ const node_fs_1 = require("node:fs");
17
+ class ProjectManifest {
18
+ constructor(path, taskKey, dependencyKeys, config) {
19
+ _ProjectManifest_path.set(this, void 0);
20
+ _ProjectManifest_taskKey.set(this, void 0);
21
+ _ProjectManifest_dependencyKeys.set(this, void 0);
22
+ _ProjectManifest_config.set(this, void 0);
23
+ __classPrivateFieldSet(this, _ProjectManifest_path, path, "f");
24
+ __classPrivateFieldSet(this, _ProjectManifest_taskKey, taskKey, "f");
25
+ __classPrivateFieldSet(this, _ProjectManifest_dependencyKeys, dependencyKeys, "f");
26
+ __classPrivateFieldSet(this, _ProjectManifest_config, config, "f");
27
+ }
28
+ static open(runtime) {
29
+ if ((0, node_fs_1.existsSync)("deno.json")) {
30
+ return new ProjectManifest("deno.json", "tasks", ["imports"], readManifest("deno.json"));
31
+ }
32
+ if ((0, node_fs_1.existsSync)("package.json")) {
33
+ return new ProjectManifest("package.json", "scripts", ["dependencies", "devDependencies"], readManifest("package.json"));
34
+ }
35
+ return runtime === "deno"
36
+ ? new ProjectManifest("deno.json", "tasks", ["imports"], { tasks: {} })
37
+ : new ProjectManifest("package.json", "scripts", ["dependencies", "devDependencies"], { name: "data-project", type: "module", scripts: {} });
38
+ }
39
+ reload() {
40
+ __classPrivateFieldSet(this, _ProjectManifest_config, readManifest(__classPrivateFieldGet(this, _ProjectManifest_path, "f")), "f");
41
+ }
42
+ getInstalledPackages() {
43
+ const installed = [];
44
+ for (const key of __classPrivateFieldGet(this, _ProjectManifest_dependencyKeys, "f")) {
45
+ const dependencies = __classPrivateFieldGet(this, _ProjectManifest_config, "f")[key];
46
+ if (dependencies && typeof dependencies === "object" &&
47
+ !Array.isArray(dependencies)) {
48
+ installed.push(...Object.keys(dependencies));
49
+ }
50
+ }
51
+ return installed;
52
+ }
53
+ updateTasks(tasks) {
54
+ const currentTasks = __classPrivateFieldGet(this, _ProjectManifest_config, "f")[__classPrivateFieldGet(this, _ProjectManifest_taskKey, "f")];
55
+ const existingTasks = currentTasks && typeof currentTasks === "object" &&
56
+ !Array.isArray(currentTasks)
57
+ ? currentTasks
58
+ : {};
59
+ __classPrivateFieldGet(this, _ProjectManifest_config, "f")[__classPrivateFieldGet(this, _ProjectManifest_taskKey, "f")] = { ...existingTasks, ...tasks };
60
+ (0, node_fs_1.writeFileSync)(__classPrivateFieldGet(this, _ProjectManifest_path, "f"), JSON.stringify(__classPrivateFieldGet(this, _ProjectManifest_config, "f"), null, 2), "utf-8");
61
+ }
62
+ }
63
+ exports.ProjectManifest = ProjectManifest;
64
+ _ProjectManifest_path = new WeakMap(), _ProjectManifest_taskKey = new WeakMap(), _ProjectManifest_dependencyKeys = new WeakMap(), _ProjectManifest_config = new WeakMap();
65
+ function readManifest(path) {
66
+ try {
67
+ const parsed = JSON.parse((0, node_fs_1.readFileSync)(path, "utf-8"));
68
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
69
+ throw new SyntaxError("the root value must be a JSON object");
70
+ }
71
+ return parsed;
72
+ }
73
+ catch (error) {
74
+ const detail = error instanceof Error ? ` ${error.message}` : "";
75
+ throw new Error(`Failed to parse ${path}.${detail}`, { cause: error });
76
+ }
77
+ }
package/script/main.js CHANGED
@@ -7,9 +7,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
7
7
  const prompts_1 = require("@clack/prompts");
8
8
  const node_process_1 = __importDefault(require("node:process"));
9
9
  const getRuntime_js_1 = require("./helpers/getRuntime.js");
10
- const getInstalledPackages_js_1 = require("./helpers/getInstalledPackages.js");
11
10
  const packageOptions_js_1 = require("./helpers/packageOptions.js");
12
- const updateProjectConfig_js_1 = require("./helpers/updateProjectConfig.js");
13
11
  const ensureGitignore_js_1 = require("./helpers/ensureGitignore.js");
14
12
  const ensureReadme_js_1 = require("./helpers/ensureReadme.js");
15
13
  const installPackagesAndFetchDocs_js_1 = require("./helpers/installPackagesAndFetchDocs.js");
@@ -18,13 +16,15 @@ const createFolderStructure_js_1 = require("./helpers/createFolderStructure.js")
18
16
  const ensureEnvFile_js_1 = require("./helpers/ensureEnvFile.js");
19
17
  const ensureAgents_js_1 = require("./helpers/ensureAgents.js");
20
18
  const packageRegistry_js_1 = require("./helpers/packageRegistry.js");
19
+ const projectManifest_js_1 = require("./helpers/projectManifest.js");
21
20
  const syncPackageDocs_js_1 = require("./helpers/syncPackageDocs.js");
22
21
  async function main() {
23
22
  const runtime = (0, getRuntime_js_1.getRuntime)();
24
23
  console.log();
25
24
  (0, prompts_1.intro)(`Hi! 👋 (Running on ${runtime})`);
26
- (0, updateProjectConfig_js_1.updateProjectConfig)((0, getProjectTasks_js_1.getProjectTasks)());
27
- const installedPackages = (0, getInstalledPackages_js_1.getInstalledPackages)();
25
+ const projectManifest = projectManifest_js_1.ProjectManifest.open(runtime);
26
+ projectManifest.updateTasks((0, getProjectTasks_js_1.getProjectTasks)());
27
+ const installedPackages = projectManifest.getInstalledPackages();
28
28
  const options = packageOptions_js_1.PACKAGE_OPTIONS.map((opt) => ({
29
29
  ...opt,
30
30
  label: installedPackages.includes(opt.value)
@@ -76,15 +76,19 @@ async function main() {
76
76
  }
77
77
  }
78
78
  sInstall.stop("✅ Packages installed and documentation fetched.");
79
- (0, updateProjectConfig_js_1.updateProjectConfig)((0, getProjectTasks_js_1.getProjectTasks)());
80
- const supportedPackageNames = new Set(packageRegistry_js_1.SUPPORTED_PACKAGES.map((pkg) => pkg.value));
81
- const finalInstalledPackages = (0, getInstalledPackages_js_1.getInstalledPackages)().filter((pkg) => supportedPackageNames.has(pkg));
79
+ projectManifest.reload();
80
+ projectManifest.updateTasks((0, getProjectTasks_js_1.getProjectTasks)());
81
+ const finalInstalledPackages = (0, packageRegistry_js_1.getInstalledPackageConfigs)(projectManifest.getInstalledPackages()).map((pkg) => pkg.value);
82
82
  const docsMapping = await (0, syncPackageDocs_js_1.syncPackageDocs)(finalInstalledPackages, packagesToInstall);
83
- await (0, createFolderStructure_js_1.createFolderStructure)(packagesToInstall);
83
+ (0, createFolderStructure_js_1.createFolderStructure)(finalInstalledPackages);
84
84
  (0, ensureGitignore_js_1.ensureGitignore)();
85
- await (0, ensureEnvFile_js_1.ensureEnvFile)();
85
+ (0, ensureEnvFile_js_1.ensureEnvFile)();
86
86
  await (0, ensureReadme_js_1.ensureReadme)(runtime, finalInstalledPackages);
87
87
  await (0, ensureAgents_js_1.ensureAgents)(docsMapping, runtime, finalInstalledPackages);
88
88
  (0, prompts_1.outro)("You are all set! 🙌");
89
89
  }
90
- main().catch(console.error);
90
+ main().catch((error) => {
91
+ const message = error instanceof Error ? error.message : String(error);
92
+ console.error(`❌ Error: ${message}`);
93
+ node_process_1.default.exitCode = 1;
94
+ });
@@ -1,2 +0,0 @@
1
- export declare function getInstalledPackages(): string[];
2
- //# sourceMappingURL=getInstalledPackages.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getInstalledPackages.d.ts","sourceRoot":"","sources":["../../src/helpers/getInstalledPackages.ts"],"names":[],"mappings":"AAEA,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CA4B/C"}
@@ -1,29 +0,0 @@
1
- import { existsSync, readFileSync } from "node:fs";
2
- export function getInstalledPackages() {
3
- let configFile = "";
4
- let depKeys = [];
5
- if (existsSync("deno.json")) {
6
- configFile = "deno.json";
7
- depKeys = ["imports"];
8
- }
9
- else if (existsSync("package.json")) {
10
- configFile = "package.json";
11
- depKeys = ["dependencies", "devDependencies"];
12
- }
13
- if (configFile === "")
14
- return [];
15
- try {
16
- const content = readFileSync(configFile, "utf-8");
17
- const config = JSON.parse(content);
18
- const installed = [];
19
- for (const key of depKeys) {
20
- if (config[key]) {
21
- installed.push(...Object.keys(config[key]));
22
- }
23
- }
24
- return installed;
25
- }
26
- catch (_e) {
27
- return [];
28
- }
29
- }
@@ -1,5 +0,0 @@
1
- export declare const PROMPT_OVERRIDE: {
2
- select: (config: unknown) => Promise<string | symbol>;
3
- };
4
- export declare function handleFileConflict(path: string, newContent: string): Promise<"created" | "updated" | "skipped">;
5
- //# sourceMappingURL=handleFileConflict.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"handleFileConflict.d.ts","sourceRoot":"","sources":["../../src/helpers/handleFileConflict.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,EAAE;IAC5B,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;CAGvD,CAAC;AAEF,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC,CAoD5C"}
@@ -1,50 +0,0 @@
1
- import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
- import { isCancel, select } from "@clack/prompts";
3
- import process from "node:process";
4
- export const PROMPT_OVERRIDE = {
5
- select: select,
6
- };
7
- export async function handleFileConflict(path, newContent) {
8
- if (!existsSync(path)) {
9
- writeFileSync(path, newContent);
10
- return "created";
11
- }
12
- // Skip prompt in Deno tests if no override
13
- // @ts-ignore: Deno is not defined in type but present in runtime
14
- if (globalThis.Deno?.args.includes("--internal-test-mode") &&
15
- PROMPT_OVERRIDE.select === select) {
16
- return "skipped";
17
- }
18
- const action = (await PROMPT_OVERRIDE.select({
19
- message: `${path} already exists. What would you like to do?`,
20
- options: [
21
- { value: "skip", label: "Skip", hint: "Keep existing file" },
22
- {
23
- value: "overwrite",
24
- label: "Overwrite",
25
- hint: "Replace with new content",
26
- },
27
- { value: "append", label: "Append", hint: "Add to the end of the file" },
28
- ],
29
- }));
30
- if (isCancel(action)) {
31
- console.log("Operation cancelled.");
32
- process.exit(0);
33
- }
34
- if (action === "skip") {
35
- return "skipped";
36
- }
37
- if (action === "overwrite") {
38
- writeFileSync(path, newContent);
39
- return "updated";
40
- }
41
- if (action === "append") {
42
- const existingContent = readFileSync(path, "utf-8");
43
- const prefix = existingContent.endsWith("\n") || existingContent === ""
44
- ? ""
45
- : "\n";
46
- writeFileSync(path, existingContent + prefix + newContent);
47
- return "updated";
48
- }
49
- return "skipped";
50
- }
@@ -1,2 +0,0 @@
1
- export declare function updateProjectConfig(tasks: Record<string, string>): void;
2
- //# sourceMappingURL=updateProjectConfig.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"updateProjectConfig.d.ts","sourceRoot":"","sources":["../../src/helpers/updateProjectConfig.ts"],"names":[],"mappings":"AAGA,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QA8ChE"}
@@ -1,42 +0,0 @@
1
- import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
- import { getRuntime } from "./getRuntime.js";
3
- export function updateProjectConfig(tasks) {
4
- const runtime = getRuntime();
5
- let configFile = "package.json";
6
- let key = "scripts";
7
- if (existsSync("deno.json")) {
8
- configFile = "deno.json";
9
- key = "tasks";
10
- }
11
- else if (existsSync("package.json")) {
12
- configFile = "package.json";
13
- key = "scripts";
14
- }
15
- else if (runtime === "deno") {
16
- configFile = "deno.json";
17
- key = "tasks";
18
- writeFileSync(configFile, JSON.stringify({ [key]: {} }, null, 2));
19
- }
20
- else {
21
- configFile = "package.json";
22
- key = "scripts";
23
- writeFileSync(configFile, JSON.stringify({ name: "data-project", type: "module", [key]: {} }, null, 2));
24
- }
25
- try {
26
- const content = readFileSync(configFile, "utf-8");
27
- const config = JSON.parse(content);
28
- config[key] = { ...(config[key] || {}), ...tasks };
29
- writeFileSync(configFile, JSON.stringify(config, null, 2), "utf-8");
30
- }
31
- catch (e) {
32
- if (e instanceof SyntaxError) {
33
- console.error(`❌ Error: Failed to parse ${configFile} as JSON. Please check its validity.`);
34
- }
35
- else if (e instanceof Error) {
36
- console.error(`❌ Error: Could not update ${configFile}: ${e.message}`);
37
- }
38
- else {
39
- console.error(`❌ Error: An unexpected error occurred while updating ${configFile}.`);
40
- }
41
- }
42
- }
@@ -1,2 +0,0 @@
1
- export declare function getInstalledPackages(): string[];
2
- //# sourceMappingURL=getInstalledPackages.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getInstalledPackages.d.ts","sourceRoot":"","sources":["../../src/helpers/getInstalledPackages.ts"],"names":[],"mappings":"AAEA,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CA4B/C"}
@@ -1,32 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getInstalledPackages = getInstalledPackages;
4
- const node_fs_1 = require("node:fs");
5
- function getInstalledPackages() {
6
- let configFile = "";
7
- let depKeys = [];
8
- if ((0, node_fs_1.existsSync)("deno.json")) {
9
- configFile = "deno.json";
10
- depKeys = ["imports"];
11
- }
12
- else if ((0, node_fs_1.existsSync)("package.json")) {
13
- configFile = "package.json";
14
- depKeys = ["dependencies", "devDependencies"];
15
- }
16
- if (configFile === "")
17
- return [];
18
- try {
19
- const content = (0, node_fs_1.readFileSync)(configFile, "utf-8");
20
- const config = JSON.parse(content);
21
- const installed = [];
22
- for (const key of depKeys) {
23
- if (config[key]) {
24
- installed.push(...Object.keys(config[key]));
25
- }
26
- }
27
- return installed;
28
- }
29
- catch (_e) {
30
- return [];
31
- }
32
- }
@@ -1,5 +0,0 @@
1
- export declare const PROMPT_OVERRIDE: {
2
- select: (config: unknown) => Promise<string | symbol>;
3
- };
4
- export declare function handleFileConflict(path: string, newContent: string): Promise<"created" | "updated" | "skipped">;
5
- //# sourceMappingURL=handleFileConflict.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"handleFileConflict.d.ts","sourceRoot":"","sources":["../../src/helpers/handleFileConflict.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,EAAE;IAC5B,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;CAGvD,CAAC;AAEF,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC,CAoD5C"}
@@ -1,57 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.PROMPT_OVERRIDE = void 0;
7
- exports.handleFileConflict = handleFileConflict;
8
- const node_fs_1 = require("node:fs");
9
- const prompts_1 = require("@clack/prompts");
10
- const node_process_1 = __importDefault(require("node:process"));
11
- exports.PROMPT_OVERRIDE = {
12
- select: prompts_1.select,
13
- };
14
- async function handleFileConflict(path, newContent) {
15
- if (!(0, node_fs_1.existsSync)(path)) {
16
- (0, node_fs_1.writeFileSync)(path, newContent);
17
- return "created";
18
- }
19
- // Skip prompt in Deno tests if no override
20
- // @ts-ignore: Deno is not defined in type but present in runtime
21
- if (globalThis.Deno?.args.includes("--internal-test-mode") &&
22
- exports.PROMPT_OVERRIDE.select === prompts_1.select) {
23
- return "skipped";
24
- }
25
- const action = (await exports.PROMPT_OVERRIDE.select({
26
- message: `${path} already exists. What would you like to do?`,
27
- options: [
28
- { value: "skip", label: "Skip", hint: "Keep existing file" },
29
- {
30
- value: "overwrite",
31
- label: "Overwrite",
32
- hint: "Replace with new content",
33
- },
34
- { value: "append", label: "Append", hint: "Add to the end of the file" },
35
- ],
36
- }));
37
- if ((0, prompts_1.isCancel)(action)) {
38
- console.log("Operation cancelled.");
39
- node_process_1.default.exit(0);
40
- }
41
- if (action === "skip") {
42
- return "skipped";
43
- }
44
- if (action === "overwrite") {
45
- (0, node_fs_1.writeFileSync)(path, newContent);
46
- return "updated";
47
- }
48
- if (action === "append") {
49
- const existingContent = (0, node_fs_1.readFileSync)(path, "utf-8");
50
- const prefix = existingContent.endsWith("\n") || existingContent === ""
51
- ? ""
52
- : "\n";
53
- (0, node_fs_1.writeFileSync)(path, existingContent + prefix + newContent);
54
- return "updated";
55
- }
56
- return "skipped";
57
- }
@@ -1,2 +0,0 @@
1
- export declare function updateProjectConfig(tasks: Record<string, string>): void;
2
- //# sourceMappingURL=updateProjectConfig.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"updateProjectConfig.d.ts","sourceRoot":"","sources":["../../src/helpers/updateProjectConfig.ts"],"names":[],"mappings":"AAGA,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QA8ChE"}
@@ -1,45 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.updateProjectConfig = updateProjectConfig;
4
- const node_fs_1 = require("node:fs");
5
- const getRuntime_js_1 = require("./getRuntime.js");
6
- function updateProjectConfig(tasks) {
7
- const runtime = (0, getRuntime_js_1.getRuntime)();
8
- let configFile = "package.json";
9
- let key = "scripts";
10
- if ((0, node_fs_1.existsSync)("deno.json")) {
11
- configFile = "deno.json";
12
- key = "tasks";
13
- }
14
- else if ((0, node_fs_1.existsSync)("package.json")) {
15
- configFile = "package.json";
16
- key = "scripts";
17
- }
18
- else if (runtime === "deno") {
19
- configFile = "deno.json";
20
- key = "tasks";
21
- (0, node_fs_1.writeFileSync)(configFile, JSON.stringify({ [key]: {} }, null, 2));
22
- }
23
- else {
24
- configFile = "package.json";
25
- key = "scripts";
26
- (0, node_fs_1.writeFileSync)(configFile, JSON.stringify({ name: "data-project", type: "module", [key]: {} }, null, 2));
27
- }
28
- try {
29
- const content = (0, node_fs_1.readFileSync)(configFile, "utf-8");
30
- const config = JSON.parse(content);
31
- config[key] = { ...(config[key] || {}), ...tasks };
32
- (0, node_fs_1.writeFileSync)(configFile, JSON.stringify(config, null, 2), "utf-8");
33
- }
34
- catch (e) {
35
- if (e instanceof SyntaxError) {
36
- console.error(`❌ Error: Failed to parse ${configFile} as JSON. Please check its validity.`);
37
- }
38
- else if (e instanceof Error) {
39
- console.error(`❌ Error: Could not update ${configFile}: ${e.message}`);
40
- }
41
- else {
42
- console.error(`❌ Error: An unexpected error occurred while updating ${configFile}.`);
43
- }
44
- }
45
- }