@ingestron/cli 0.0.0-stage → 1.0.0

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 (175) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +4 -0
  3. package/README.md +44 -2
  4. package/dist/args.d.ts +105 -0
  5. package/dist/args.d.ts.map +1 -0
  6. package/dist/args.js +161 -0
  7. package/dist/args.js.map +1 -0
  8. package/dist/ask.d.ts +5 -0
  9. package/dist/ask.d.ts.map +1 -0
  10. package/dist/ask.js +17 -0
  11. package/dist/ask.js.map +1 -0
  12. package/dist/compare.d.ts +13 -0
  13. package/dist/compare.d.ts.map +1 -0
  14. package/dist/compare.js +90 -0
  15. package/dist/compare.js.map +1 -0
  16. package/dist/environments.d.ts +6 -0
  17. package/dist/environments.d.ts.map +1 -0
  18. package/dist/environments.js +25 -0
  19. package/dist/environments.js.map +1 -0
  20. package/dist/generate.d.ts +16 -0
  21. package/dist/generate.d.ts.map +1 -0
  22. package/dist/generate.js +118 -0
  23. package/dist/generate.js.map +1 -0
  24. package/dist/index.d.ts +21 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +46 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/init-choice.d.ts +10 -0
  29. package/dist/init-choice.d.ts.map +1 -0
  30. package/dist/init-choice.js +36 -0
  31. package/dist/init-choice.js.map +1 -0
  32. package/dist/init-preflight.d.ts +4 -0
  33. package/dist/init-preflight.d.ts.map +1 -0
  34. package/dist/init-preflight.js +18 -0
  35. package/dist/init-preflight.js.map +1 -0
  36. package/dist/init.d.ts +5 -0
  37. package/dist/init.d.ts.map +1 -0
  38. package/dist/init.js +136 -0
  39. package/dist/init.js.map +1 -0
  40. package/dist/io.d.ts +8 -0
  41. package/dist/io.d.ts.map +1 -0
  42. package/dist/io.js +3 -0
  43. package/dist/io.js.map +1 -0
  44. package/dist/main.d.ts +3 -0
  45. package/dist/main.d.ts.map +1 -0
  46. package/dist/main.js +11 -0
  47. package/dist/main.js.map +1 -0
  48. package/dist/outputs.d.ts +12 -0
  49. package/dist/outputs.d.ts.map +1 -0
  50. package/dist/outputs.js +53 -0
  51. package/dist/outputs.js.map +1 -0
  52. package/dist/packs.d.ts +4 -0
  53. package/dist/packs.d.ts.map +1 -0
  54. package/dist/packs.js +5 -0
  55. package/dist/packs.js.map +1 -0
  56. package/dist/project-choices.d.ts +27 -0
  57. package/dist/project-choices.d.ts.map +1 -0
  58. package/dist/project-choices.js +44 -0
  59. package/dist/project-choices.js.map +1 -0
  60. package/dist/project-questions.d.ts +5 -0
  61. package/dist/project-questions.d.ts.map +1 -0
  62. package/dist/project-questions.js +43 -0
  63. package/dist/project-questions.js.map +1 -0
  64. package/dist/project-recipes.d.ts +14 -0
  65. package/dist/project-recipes.d.ts.map +1 -0
  66. package/dist/project-recipes.js +115 -0
  67. package/dist/project-recipes.js.map +1 -0
  68. package/dist/request.d.ts +13 -0
  69. package/dist/request.d.ts.map +1 -0
  70. package/dist/request.js +110 -0
  71. package/dist/request.js.map +1 -0
  72. package/dist/sample-contract.d.ts +11 -0
  73. package/dist/sample-contract.d.ts.map +1 -0
  74. package/dist/sample-contract.js +91 -0
  75. package/dist/sample-contract.js.map +1 -0
  76. package/dist/sample-read.d.ts +8 -0
  77. package/dist/sample-read.d.ts.map +1 -0
  78. package/dist/sample-read.js +89 -0
  79. package/dist/sample-read.js.map +1 -0
  80. package/dist/samples.d.ts +33 -0
  81. package/dist/samples.d.ts.map +1 -0
  82. package/dist/samples.js +108 -0
  83. package/dist/samples.js.map +1 -0
  84. package/dist/scaffold.d.ts +34 -0
  85. package/dist/scaffold.d.ts.map +1 -0
  86. package/dist/scaffold.js +106 -0
  87. package/dist/scaffold.js.map +1 -0
  88. package/dist/schemas.d.ts +5 -0
  89. package/dist/schemas.d.ts.map +1 -0
  90. package/dist/schemas.js +39 -0
  91. package/dist/schemas.js.map +1 -0
  92. package/dist/sources.d.ts +17 -0
  93. package/dist/sources.d.ts.map +1 -0
  94. package/dist/sources.js +103 -0
  95. package/dist/sources.js.map +1 -0
  96. package/dist/templates.d.ts +64 -0
  97. package/dist/templates.d.ts.map +1 -0
  98. package/dist/templates.js +88 -0
  99. package/dist/templates.js.map +1 -0
  100. package/package.json +68 -3
  101. package/project-templates/kafka/README.md +12 -0
  102. package/project-templates/kafka/connections/events.yaml +8 -0
  103. package/project-templates/kafka/contracts/page_views.yaml +13 -0
  104. package/project-templates/kafka/contracts/purchases.yaml +13 -0
  105. package/project-templates/kafka/flows/events.yaml +10 -0
  106. package/project-templates/kafka/project.yaml +10 -0
  107. package/project-templates/kafka/standard.yaml +4 -0
  108. package/project-templates/kafka/template.yaml +3 -0
  109. package/project-templates/minimal/README.md +10 -0
  110. package/project-templates/minimal/connections/shop.yaml +7 -0
  111. package/project-templates/minimal/contracts/orders.yaml +14 -0
  112. package/project-templates/minimal/flows/orders.yaml +6 -0
  113. package/project-templates/minimal/project.yaml +11 -0
  114. package/project-templates/minimal/standard.yaml +4 -0
  115. package/project-templates/minimal/template.yaml +7 -0
  116. package/project-templates/private-files/README.md +29 -0
  117. package/project-templates/private-files/connections/share.yaml +10 -0
  118. package/project-templates/private-files/contracts/sales.yaml +14 -0
  119. package/project-templates/private-files/contracts/stock.yaml +14 -0
  120. package/project-templates/private-files/flows/stores.yaml +9 -0
  121. package/project-templates/private-files/platform.yaml +11 -0
  122. package/project-templates/private-files/project.yaml +19 -0
  123. package/project-templates/private-files/standard.yaml +11 -0
  124. package/project-templates/private-files/template.yaml +10 -0
  125. package/project-templates/private-sql-server/README.md +25 -0
  126. package/project-templates/private-sql-server/connections/erp.yaml +10 -0
  127. package/project-templates/private-sql-server/contracts/customers.yaml +14 -0
  128. package/project-templates/private-sql-server/contracts/invoices.yaml +15 -0
  129. package/project-templates/private-sql-server/flows/erp.yaml +13 -0
  130. package/project-templates/private-sql-server/platform.yaml +11 -0
  131. package/project-templates/private-sql-server/project.yaml +19 -0
  132. package/project-templates/private-sql-server/standard.yaml +17 -0
  133. package/project-templates/private-sql-server/template.yaml +10 -0
  134. package/project-templates/pyspark/README.md +12 -0
  135. package/project-templates/pyspark/connections/billing.yaml +7 -0
  136. package/project-templates/pyspark/contracts/invoices.yaml +16 -0
  137. package/project-templates/pyspark/contracts/monthly_revenue.yaml +14 -0
  138. package/project-templates/pyspark/flows/billing.yaml +6 -0
  139. package/project-templates/pyspark/project.yaml +11 -0
  140. package/project-templates/pyspark/standard.yaml +4 -0
  141. package/project-templates/pyspark/template.yaml +3 -0
  142. package/project-templates/pyspark/transforms/monthly_revenue.py +10 -0
  143. package/project-templates/pyspark/transforms/monthly_revenue.yaml +10 -0
  144. package/project-templates/retail/README.md +22 -0
  145. package/project-templates/retail/connections/shop.yaml +8 -0
  146. package/project-templates/retail/contracts/customers.yaml +12 -0
  147. package/project-templates/retail/contracts/daily_sales.yaml +19 -0
  148. package/project-templates/retail/contracts/orders.yaml +16 -0
  149. package/project-templates/retail/flows/shop.yaml +18 -0
  150. package/project-templates/retail/platform.yaml +21 -0
  151. package/project-templates/retail/project.yaml +18 -0
  152. package/project-templates/retail/standard.yaml +15 -0
  153. package/project-templates/retail/template.yaml +10 -0
  154. package/project-templates/retail/transforms/daily_sales.sql +7 -0
  155. package/project-templates/retail/transforms/daily_sales.yaml +7 -0
  156. package/project-templates/salesforce/README.md +6 -0
  157. package/project-templates/salesforce/connections/salesforce.yaml +7 -0
  158. package/project-templates/salesforce/contracts/accounts.yaml +13 -0
  159. package/project-templates/salesforce/contracts/opportunities.yaml +14 -0
  160. package/project-templates/salesforce/flows/salesforce.yaml +7 -0
  161. package/project-templates/salesforce/project.yaml +9 -0
  162. package/project-templates/salesforce/standard.yaml +4 -0
  163. package/project-templates/salesforce/template.yaml +3 -0
  164. package/project-templates/sql-server/README.md +17 -0
  165. package/project-templates/sql-server/connections/erp.yaml +8 -0
  166. package/project-templates/sql-server/contracts/customer_balances.yaml +13 -0
  167. package/project-templates/sql-server/contracts/customers.yaml +13 -0
  168. package/project-templates/sql-server/contracts/invoices.yaml +14 -0
  169. package/project-templates/sql-server/flows/erp.yaml +13 -0
  170. package/project-templates/sql-server/platform.yaml +6 -0
  171. package/project-templates/sql-server/project.yaml +13 -0
  172. package/project-templates/sql-server/standard.yaml +9 -0
  173. package/project-templates/sql-server/template.yaml +3 -0
  174. package/project-templates/sql-server/transforms/customer_balances.sql +5 -0
  175. package/project-templates/sql-server/transforms/customer_balances.yaml +6 -0
@@ -0,0 +1,90 @@
1
+ // ingestron compare: what differs between two environments once the
2
+ // definitions are resolved: the platform, the names, and each table's methods
3
+ // and settings. Secrets are never shown. The editor's command shows the same.
4
+ import { resolve } from "node:path";
5
+ import { formatDiagnostics, nodeFiles } from "@ingestron/config";
6
+ import { resolveDefinitions } from "@ingestron/definitions";
7
+ import { environmentsToGenerate } from "./environments.js";
8
+ import { packs } from "./packs.js";
9
+ /** Prints the comparison of the two environments given, else the project's first two. */
10
+ export function compare(options, io) {
11
+ const definitions = resolve(io.cwd, options.definitions);
12
+ const [a, b, ...more] = environmentsToGenerate(definitions, options.environments);
13
+ if (!a || !b || (more.length > 0 && options.environments.length > 0)) {
14
+ io.write("compare needs two environments: name them with --env, or declare two in project.yaml.\n");
15
+ return 2;
16
+ }
17
+ const text = compareEnvironments(nodeFiles(definitions), a, b);
18
+ io.write(text);
19
+ return text.includes("the definitions have problems") ? 1 : 0;
20
+ }
21
+ /**
22
+ * The differences between two environments as Markdown, grouped by platform,
23
+ * names and table; a note with the problems when either does not resolve.
24
+ * @example
25
+ * console.log(compareEnvironments(nodeFiles("definitions"), "dev", "prod"));
26
+ */
27
+ export function compareEnvironments(files, a, b) {
28
+ const left = resolveDefinitions(files, { packs, environment: a, envvars: {} });
29
+ const right = resolveDefinitions(files, { packs, environment: b, envvars: {} });
30
+ for (const [name, result] of [
31
+ [a, left],
32
+ [b, right],
33
+ ])
34
+ if (!result.model)
35
+ return `# ${a} ↔ ${b}\n\n${name}: the definitions have problems\n\n${formatDiagnostics(result.diagnostics)}\n`;
36
+ const before = sectionsOf(left.model);
37
+ const after = sectionsOf(right.model);
38
+ const groups = [...new Set([...Object.keys(before), ...Object.keys(after)])].flatMap((section) => {
39
+ const lines = differences(before[section] ?? {}, after[section] ?? {});
40
+ return lines.length > 0 ? [`## ${section}\n\n${lines.join("\n")}`] : [];
41
+ });
42
+ const title = `# ${a} ↔ ${b}: ${left.model.project.id}`;
43
+ return `${[title, ...(groups.length > 0 ? groups : ["No differences."])].join("\n\n")}\n`;
44
+ }
45
+ function sectionsOf(model) {
46
+ return {
47
+ Platform: flat(model.platform),
48
+ Names: flat(model.names),
49
+ ...Object.fromEntries(model.tables.map((table) => [`Table ${table.name}`, tableFacts(table)])),
50
+ };
51
+ }
52
+ function tableFacts(table) {
53
+ const step = (found) => found && { method: found.method, settings: found.settings };
54
+ return {
55
+ "full name": Object.values(table.fullName).join("."),
56
+ ...flat({
57
+ ingest: table.ingest && {
58
+ ...step(table.ingest),
59
+ object: table.ingest.object,
60
+ connection: {
61
+ connectivity: table.ingest.connection.connectivity,
62
+ settings: table.ingest.connection.settings,
63
+ },
64
+ },
65
+ transform: step(table.transform),
66
+ store: step(table.store),
67
+ }),
68
+ expectations: table.expectations.map((item) => `${item.name}: ${item.action}`),
69
+ };
70
+ }
71
+ /** Every leaf by its dotted path; lists and secrets are leaves. */
72
+ function flat(value, prefix = "") {
73
+ const secret = typeof value === "object" && value !== null && "$secret" in value;
74
+ if (secret)
75
+ return { [prefix]: "a secret" };
76
+ if (typeof value !== "object" || value === null || Array.isArray(value))
77
+ return value === undefined ? {} : { [prefix]: value };
78
+ return Object.assign({}, ...Object.entries(value).map(([key, item]) => flat(item, prefix ? `${prefix}.${key}` : key)));
79
+ }
80
+ function differences(before, after) {
81
+ return [...new Set([...Object.keys(before), ...Object.keys(after)])]
82
+ .filter((key) => JSON.stringify(before[key]) !== JSON.stringify(after[key]))
83
+ .map((key) => `- \`${key}\`: ${shown(before[key])} → ${shown(after[key])}`);
84
+ }
85
+ function shown(value) {
86
+ if (value === undefined)
87
+ return "not set";
88
+ return `\`${typeof value === "string" ? value : JSON.stringify(value)}\``;
89
+ }
90
+ //# sourceMappingURL=compare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.js","sourceRoot":"","sources":["../src/compare.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * The environments to generate: the requested ones, else every environment
3
+ * in project.yaml, else one unnamed environment (`undefined`).
4
+ */
5
+ export declare function environmentsToGenerate(definitions: string, requested: string[]): (string | undefined)[];
6
+ //# sourceMappingURL=environments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environments.d.ts","sourceRoot":"","sources":["../src/environments.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EAAE,GAClB,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAcxB"}
@@ -0,0 +1,25 @@
1
+ // The environments declared in project.yaml.
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { parse } from "yaml";
5
+ /**
6
+ * The environments to generate: the requested ones, else every environment
7
+ * in project.yaml, else one unnamed environment (`undefined`).
8
+ */
9
+ export function environmentsToGenerate(definitions, requested) {
10
+ if (requested.length > 0)
11
+ return requested;
12
+ const manifest = join(definitions, "project.yaml");
13
+ if (!existsSync(manifest))
14
+ return [undefined];
15
+ try {
16
+ const data = parse(readFileSync(manifest, "utf8"));
17
+ const names = Object.keys(data?.environments ?? {});
18
+ return names.length > 0 ? names : [undefined];
19
+ }
20
+ catch {
21
+ // Loading reports the problem with its location.
22
+ return [undefined];
23
+ }
24
+ }
25
+ //# sourceMappingURL=environments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environments.js","sourceRoot":"","sources":["../src/environments.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAE7B;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,WAAmB,EACnB,SAAmB;IAEnB,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IACnD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC9C,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAEhD,CAAC;QACF,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,IAAI,EAAE,CAAC,CAAC;QACpD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,iDAAiD;QACjD,OAAO,CAAC,SAAS,CAAC,CAAC;IACrB,CAAC;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { type ResolvedModel } from "@ingestron/definitions";
2
+ import type { Options } from "./args.js";
3
+ import type { Io } from "./io.js";
4
+ /** Runs plan, apply or check for each environment. Returns the exit code. */
5
+ export declare function generate(options: Options, io: Io): number;
6
+ /**
7
+ * The files each pack the standard names generates for one environment. The
8
+ * label is the output sub-folder: `<environment>`, or `<environment>/<pack>`
9
+ * with several packs.
10
+ */
11
+ export declare function generatedOutputs(model: ResolvedModel, environment: string): {
12
+ pack: string;
13
+ label: string;
14
+ files: Record<string, string>;
15
+ }[];
16
+ //# sourceMappingURL=generate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAGA,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAW7E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAYlC,6EAA6E;AAC7E,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,GAAG,MAAM,CAsBzD;AAyDD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,aAAa,EACpB,WAAW,EAAE,MAAM,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,EAAE,CAOlE"}
@@ -0,0 +1,118 @@
1
+ // plan, apply and check: definitions → files → the output folder.
2
+ import { join, relative, resolve, sep } from "node:path";
3
+ import { formatDiagnostics } from "@ingestron/config";
4
+ import { loadDefinitions } from "@ingestron/definitions";
5
+ import { applyPlan, formatPlan, manifestFile, nodeFolder, planGeneration, } from "@ingestron/generate";
6
+ import { packs } from "./packs.js";
7
+ import { environmentsToGenerate } from "./environments.js";
8
+ import { extraFiles, generatedFolders } from "./outputs.js";
9
+ /** Runs plan, apply or check for each environment. Returns the exit code. */
10
+ export function generate(options, io) {
11
+ const definitions = resolve(io.cwd, options.definitions);
12
+ const planned = [];
13
+ const unresolved = [];
14
+ for (const environment of environmentsToGenerate(definitions, options.environments)) {
15
+ const outputs = planEnvironment(options, io, definitions, environment);
16
+ if (!outputs)
17
+ unresolved.push(environment ?? "default");
18
+ planned.push(...(outputs ?? []));
19
+ }
20
+ const roots = planned.map((item) => item.root);
21
+ const done = planned.filter((item) => finish(options, io, item, roots)).map(({ name }) => name);
22
+ const notDone = [
23
+ ...planned.filter(({ name }) => !done.includes(name)).map(({ name }) => name),
24
+ ...unresolved,
25
+ ];
26
+ const retired = retiredFolders(options, resolve(io.cwd, options.out), roots, unresolved);
27
+ for (const folder of retired)
28
+ io.write(`${relative(io.cwd, folder)}: no longer generated. Delete the folder, or delete its ${manifestFile} to keep it as your own.\n`);
29
+ if (options.command === "apply")
30
+ summarise(io, done, notDone);
31
+ return notDone.length > 0 || (options.command === "check" && retired.length > 0) ? 1 : 0;
32
+ }
33
+ /** After apply, when some output folders were written and others not, says which. */
34
+ function summarise(io, done, notDone) {
35
+ if (done.length > 0 && notDone.length > 0)
36
+ io.write(`Applied: ${done.join(", ")}. Not applied: ${notDone.join(", ")}.\n`);
37
+ }
38
+ /**
39
+ * Folders under the output folder that hold a manifest but that the
40
+ * definitions no longer generate. With --env, only those environments'
41
+ * folders are looked at; nor are those of an environment that failed to load.
42
+ */
43
+ function retiredFolders(options, out, current, unresolved) {
44
+ const within = (folder, root) => folder === root || folder.startsWith(root + sep);
45
+ const looked = options.environments.length > 0
46
+ ? options.environments.map((environment) => join(out, environment))
47
+ : [out];
48
+ const skipped = unresolved.map((environment) => join(out, environment));
49
+ return looked
50
+ .flatMap(generatedFolders)
51
+ .filter((folder) => !current.includes(folder))
52
+ .filter((folder) => !skipped.some((root) => within(folder, root)));
53
+ }
54
+ /**
55
+ * One plan per pack the standard names. With one pack the output folder is
56
+ * `<out>/<environment>`; with several, each pack gets `<out>/<environment>/<pack>`.
57
+ */
58
+ function planEnvironment(options, io, definitions, environment) {
59
+ const name = environment ?? "default";
60
+ const result = loadDefinitions(definitions, { packs, environment, envvars: process.env });
61
+ if (!result.model) {
62
+ io.write(`${name}: the definitions have problems\n${formatDiagnostics(result.diagnostics)}\n`);
63
+ return undefined;
64
+ }
65
+ if (result.diagnostics.length > 0)
66
+ io.write(`${name}: warnings\n${formatDiagnostics(result.diagnostics)}\n`);
67
+ return generatedOutputs(result.model, name).map(({ label, files }) => {
68
+ const output = resolve(io.cwd, options.out, label);
69
+ const folder = nodeFolder(output);
70
+ const plan = planGeneration(folder, files);
71
+ return { name: label, folder, plan, root: output, output: relative(io.cwd, output) };
72
+ });
73
+ }
74
+ /**
75
+ * The files each pack the standard names generates for one environment. The
76
+ * label is the output sub-folder: `<environment>`, or `<environment>/<pack>`
77
+ * with several packs.
78
+ */
79
+ export function generatedOutputs(model, environment) {
80
+ const used = packs.filter((pack) => model.standard.packs.includes(`${pack.id}@${pack.version}`));
81
+ return used.map((pack) => ({
82
+ pack: pack.id,
83
+ label: used.length > 1 ? `${environment}/${pack.id}` : environment,
84
+ files: pack.build(model),
85
+ }));
86
+ }
87
+ /**
88
+ * Prints the plan and, for apply, writes it. True when this output folder
89
+ * succeeded. check also fails on files in the folder that were not
90
+ * generated, unless --allow-extra; `roots` are every output folder, so one
91
+ * inside another is not counted as extra.
92
+ */
93
+ function finish(options, io, planned, roots) {
94
+ const { name, folder, plan, output } = planned;
95
+ if (options.command === "check")
96
+ return check(options, io, planned, roots);
97
+ io.write(`${name} → ${output}\n`);
98
+ io.write(`${formatPlan(plan, { diffs: options.diffs })}\n`);
99
+ if (options.command === "plan" || !plan.clean)
100
+ return plan.clean;
101
+ if (plan.upToDate)
102
+ return true;
103
+ const result = applyPlan(folder, plan);
104
+ io.write(result.ok ? "Applied.\n" : `${result.problems.map((problem) => problem.message).join("\n")}\n`);
105
+ return result.ok;
106
+ }
107
+ /** check for one output folder: up to date, and nothing in it that was not generated. */
108
+ function check(options, io, { name, plan, root }, roots) {
109
+ const known = new Set(plan.changes.map((change) => change.path));
110
+ const extra = options.allowExtra ? [] : extraFiles(root, known, roots);
111
+ io.write(plan.upToDate ? `${name}: up to date\n` : `${name}: not up to date\n${formatPlan(plan)}\n`);
112
+ for (const path of extra)
113
+ io.write(`${name}: not generated ${path}\n`);
114
+ if (extra.length > 0)
115
+ io.write("Move files that were not generated out of the output folder, or check with --allow-extra.\n");
116
+ return plan.upToDate && extra.length === 0;
117
+ }
118
+ //# sourceMappingURL=generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export { commands, flags } from "./args.js";
2
+ import type { Io } from "./io.js";
3
+ export type { Io } from "./io.js";
4
+ export { packs } from "./packs.js";
5
+ export { nameProblem, projectId } from "./scaffold.js";
6
+ export { generatedOutputs } from "./generate.js";
7
+ export { platformRequest } from "./request.js";
8
+ export { compareEnvironments } from "./compare.js";
9
+ export { contractFromSample } from "./sample-contract.js";
10
+ export { listSamples, readSample, sampleFacts, templatesFolder, type Sample, type SampleFacts, } from "./samples.js";
11
+ export { projectSources, projectRoutes, type ProjectSource, type ProjectRoute, } from "./project-choices.js";
12
+ export { projectRecipe, type ProjectRecipe } from "./project-recipes.js";
13
+ export { builtInTemplates, parseTemplate, templateSchema, type Template } from "./templates.js";
14
+ /**
15
+ * Runs `ingestron` with `args` and returns the exit code: 0 success, 1
16
+ * problems in the definitions or the output folder, 2 a usage mistake.
17
+ * @example
18
+ * process.exitCode = run(process.argv.slice(2), { cwd: process.cwd(), write: (text) => process.stdout.write(text) });
19
+ */
20
+ export declare function run(args: string[], io: Io): number;
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAG5C,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAMlC,YAAY,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EACL,WAAW,EACX,UAAU,EACV,WAAW,EACX,eAAe,EACf,KAAK,MAAM,EACX,KAAK,WAAW,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,cAAc,EAAE,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAEhG;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,MAAM,CAelD"}
package/dist/index.js ADDED
@@ -0,0 +1,46 @@
1
+ // Public API of @ingestron/cli: run the command line in-process.
2
+ import { readArgs, usage } from "./args.js";
3
+ export { commands, flags } from "./args.js";
4
+ import { generate } from "./generate.js";
5
+ import { init } from "./init.js";
6
+ import { compare } from "./compare.js";
7
+ import { request } from "./request.js";
8
+ import { draftContract } from "./sample-contract.js";
9
+ import { writeSchemas } from "./schemas.js";
10
+ export { packs } from "./packs.js";
11
+ export { nameProblem, projectId } from "./scaffold.js";
12
+ export { generatedOutputs } from "./generate.js";
13
+ export { platformRequest } from "./request.js";
14
+ export { compareEnvironments } from "./compare.js";
15
+ export { contractFromSample } from "./sample-contract.js";
16
+ export { listSamples, readSample, sampleFacts, templatesFolder, } from "./samples.js";
17
+ export { projectSources, projectRoutes, } from "./project-choices.js";
18
+ export { projectRecipe } from "./project-recipes.js";
19
+ export { builtInTemplates, parseTemplate, templateSchema } from "./templates.js";
20
+ /**
21
+ * Runs `ingestron` with `args` and returns the exit code: 0 success, 1
22
+ * problems in the definitions or the output folder, 2 a usage mistake.
23
+ * @example
24
+ * process.exitCode = run(process.argv.slice(2), { cwd: process.cwd(), write: (text) => process.stdout.write(text) });
25
+ */
26
+ export function run(args, io) {
27
+ const options = readArgs(args);
28
+ if (options === "help") {
29
+ io.write(usage);
30
+ return 0;
31
+ }
32
+ if ("mistake" in options) {
33
+ io.write(`${options.mistake}\n\n${usage}`);
34
+ return 2;
35
+ }
36
+ if (options.command === "init")
37
+ return init(options, io);
38
+ if (options.command === "request")
39
+ return request(options, io);
40
+ if (options.command === "compare")
41
+ return compare(options, io);
42
+ if (options.command === "contract")
43
+ return draftContract(options, io);
44
+ return options.command === "schemas" ? writeSchemas(options, io) : generate(options, io);
45
+ }
46
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EACL,WAAW,EACX,UAAU,EACV,WAAW,EACX,eAAe,GAGhB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,aAAa,GAGd,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAsB,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,cAAc,EAAiB,MAAM,gBAAgB,CAAC;AAEhG;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CAAC,IAAc,EAAE,EAAM;IACxC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACvB,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAChB,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,SAAS,IAAI,OAAO,EAAE,CAAC;QACzB,EAAE,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,OAAO,OAAO,KAAK,EAAE,CAAC,CAAC;QAC3C,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACzD,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC/D,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC/D,IAAI,OAAO,CAAC,OAAO,KAAK,UAAU;QAAE,OAAO,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACtE,OAAO,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAC3F,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { Options } from "./args.js";
2
+ /** The existing init question contract. */
3
+ export type Ask = (question: string, flag: string, fallback: string, check?: (answer: string) => string | undefined) => string;
4
+ /** Select a connector, reachable network and compatible ingestion route. */
5
+ export declare function chooseProject(flags: Options["init"], ask: Ask): {
6
+ done: () => void;
7
+ template: import("./templates.js").Template;
8
+ files: Record<string, import("./scaffold.js").Content>;
9
+ };
10
+ //# sourceMappingURL=init-choice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-choice.d.ts","sourceRoot":"","sources":["../src/init-choice.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,2CAA2C;AAC3C,MAAM,MAAM,GAAG,GAAG,CAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,KAC3C,MAAM,CAAC;AACZ,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG;;;;EAsC7D"}
@@ -0,0 +1,36 @@
1
+ import { projectRoutes, projectSources } from "./project-choices.js";
2
+ import { projectRecipe } from "./project-recipes.js";
3
+ /** Select a connector, reachable network and compatible ingestion route. */
4
+ export function chooseProject(flags, ask) {
5
+ const sources = projectSources();
6
+ let connector = flags.connector;
7
+ if (!connector) {
8
+ const categories = [...new Set(sources.map((source) => source.category))];
9
+ const category = choose("Source category", categories, "Files and storage", "--connector", ask);
10
+ connector = choose("Connector", sources.filter((source) => source.category === category).map((source) => source.id), category === "Files and storage" ? "files" : "", "--connector", ask);
11
+ }
12
+ if (!sources.some((source) => source.id === connector))
13
+ throw new Error(`Unknown connector "${connector}".`);
14
+ const available = projectRoutes(connector);
15
+ const networks = [...new Set(available.flatMap((route) => route.connectivity))];
16
+ const preferred = available.some((route) => route.via === "databricks")
17
+ ? connector === "sqlserver"
18
+ ? "workspace"
19
+ : "public"
20
+ : "private";
21
+ const connectivity = flags.connectivity ?? choose("Connectivity", networks, preferred, "--connectivity", ask);
22
+ const routes = projectRoutes(connector, connectivity);
23
+ if (!routes.length)
24
+ throw new Error(`No route for ${connector} with ${connectivity} connectivity.`);
25
+ const via = flags.via ??
26
+ choose(`Route (${routes.map((route) => `${route.via}: ${route.title}, ${route.maturity}`).join("; ")})`, routes.map((route) => route.via), routes[0].via, "--via", ask);
27
+ return { ...projectRecipe(connector, via, connectivity), done: () => { } };
28
+ }
29
+ function choose(title, values, fallback, flag, ask) {
30
+ if (values.length === 1)
31
+ return values[0];
32
+ const normalise = (answer) => /^\d+$/.test(answer) ? (values[Number(answer) - 1] ?? answer) : answer;
33
+ const prompt = `${title}:\n${values.map((value, index) => ` ${index + 1}. ${value}`).join("\n")}\nChoice [${fallback || values[0]}]: `;
34
+ return normalise(ask(prompt, flag, fallback || values[0], (answer) => values.includes(normalise(answer)) ? undefined : `Choose one of: ${values.join(", ")}.`));
35
+ }
36
+ //# sourceMappingURL=init-choice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-choice.js","sourceRoot":"","sources":["../src/init-choice.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Content } from "./scaffold.js";
2
+ /** All requested environments must resolve, including the selected standard. */
3
+ export declare function projectProblem(files: Record<string, Content>): string | undefined;
4
+ //# sourceMappingURL=init-preflight.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-preflight.d.ts","sourceRoot":"","sources":["../src/init-preflight.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS,CAYjF"}
@@ -0,0 +1,18 @@
1
+ // Validate the composed project before the scaffold writer creates any files.
2
+ import { memoryFiles, formatDiagnostics } from "@ingestron/config";
3
+ import { resolveDefinitions } from "@ingestron/definitions";
4
+ import { parse } from "yaml";
5
+ import { packs } from "./packs.js";
6
+ /** All requested environments must resolve, including the selected standard. */
7
+ export function projectProblem(files) {
8
+ const source = memoryFiles(Object.fromEntries(Object.entries(files).map(([path, content]) => [path, content.toString()])));
9
+ const project = parse(String(files["project.yaml"]));
10
+ const names = Object.keys(project.environments ?? {});
11
+ for (const environment of names.length ? names : [undefined]) {
12
+ const result = resolveDefinitions(source, { packs, environment });
13
+ if (!result.model)
14
+ return `Project is not compatible in ${environment}; nothing written.\n${formatDiagnostics(result.diagnostics)}`;
15
+ }
16
+ return undefined;
17
+ }
18
+ //# sourceMappingURL=init-preflight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-preflight.js","sourceRoot":"","sources":["../src/init-preflight.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,gFAAgF;AAChF,MAAM,UAAU,cAAc,CAAC,KAA8B;IAC3D,MAAM,MAAM,GAAG,WAAW,CACxB,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAC/F,CAAC;IACF,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAA8B,CAAC;IAClF,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;IACtD,KAAK,MAAM,WAAW,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7D,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QAClE,IAAI,CAAC,MAAM,CAAC,KAAK;YACf,OAAO,gCAAgC,WAAW,uBAAuB,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;IACrH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
package/dist/init.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import type { Options } from "./args.js";
2
+ import type { Io } from "./io.js";
3
+ /** Creates the project and shows its plan. Returns the exit code. */
4
+ export declare function init(options: Options, io: Io): number;
5
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKzC,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAalC,qEAAqE;AACrE,wBAAgB,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,GAAG,MAAM,CAmBrD"}
package/dist/init.js ADDED
@@ -0,0 +1,136 @@
1
+ // ingestron init: a new project from a connection or explicit template. Every answer comes from a
2
+ // flag, else the default with --yes, else a question; without a terminal a
3
+ // missing answer is an error that names the flag, never a wait.
4
+ import { readFileSync } from "node:fs";
5
+ import { basename, join, relative, resolve } from "node:path";
6
+ import { parse } from "yaml";
7
+ import { chooseProject } from "./init-choice.js";
8
+ import { projectProblem } from "./init-preflight.js";
9
+ import { generate } from "./generate.js";
10
+ import { nameProblem, projectId, scaffoldFiles, writeScaffold } from "./scaffold.js";
11
+ import { standardSource, templateSource } from "./sources.js";
12
+ import {} from "./templates.js";
13
+ /** Creates the project and shows its plan. Returns the exit code. */
14
+ export function init(options, io) {
15
+ const cleanups = [];
16
+ try {
17
+ checkFlags(options);
18
+ const ask = asker(options, io);
19
+ const target = resolve(io.cwd, options.init.folder);
20
+ const source = options
21
+ .init.template
22
+ ? templateSource(options.init.template, io.cwd)
23
+ : chooseProject(options.init, ask);
24
+ cleanups.push(source.done);
25
+ const answers = gather(options, io, ask, source.template, target, cleanups);
26
+ return create(options, io, target, source.template, answers, source.files);
27
+ }
28
+ catch (error) {
29
+ io.write(`${error instanceof Error ? error.message : String(error)}\n`);
30
+ return 1;
31
+ }
32
+ finally {
33
+ for (const cleanup of cleanups)
34
+ cleanup();
35
+ }
36
+ }
37
+ function gather(options, io, ask, template, target, cleanups) {
38
+ const { init: flags } = options;
39
+ const suggested = projectId(basename(target));
40
+ const name = flags.name ??
41
+ ask(`Project name [${suggested}]: `, "--name", suggested, (answer) => nameProblem(answer, "project"));
42
+ const known = (flags.template ? templateEnvironments(template) : ["dev", "prod"]).join(", ");
43
+ const environments = options.environments.length > 0
44
+ ? options.environments
45
+ : list(ask(`Environments [${known}]: `, "--env", known, environmentsProblem));
46
+ // Optional: keeping the template's standard needs no answer.
47
+ const standard = flags.standard ??
48
+ (io.ask && !flags.yes
49
+ ? ask("Standard: a path or Git URL, or Enter to keep the supplied default: ", "--standard", "")
50
+ : "");
51
+ const answers = { name, environments, values: {} };
52
+ if (standard) {
53
+ const found = standardSource(standard, io.cwd);
54
+ cleanups.push(found.done);
55
+ answers.standard = { file: found.file, source: found.source };
56
+ }
57
+ answers.values = values(flags.set, template, ask);
58
+ return answers;
59
+ }
60
+ function values(set, template, ask) {
61
+ const asked = template.questions.map((question) => question.value);
62
+ const unknown = Object.keys(set).find((key) => !asked.includes(key));
63
+ if (unknown)
64
+ throw new Error(`The template asks no "${unknown}". It asks: ${asked.join(", ") || "nothing"}.`);
65
+ return Object.fromEntries(template.questions.map((question) => [
66
+ question.value,
67
+ set[question.value] ??
68
+ ask(`${question.ask} [${question.default}]: `, `--set ${question.value}=…`, question.default),
69
+ ]));
70
+ }
71
+ /** The answer from the terminal, else the default with --yes, else an error naming the flag. */
72
+ function asker(options, io) {
73
+ return (question, flag, fallback, check) => {
74
+ if (options.init.yes)
75
+ return fallback;
76
+ if (!io.ask)
77
+ throw new Error(`Missing ${flag}. Pass it, or --yes to take the defaults.`);
78
+ let prompt = question;
79
+ for (;;) {
80
+ const answer = io.ask(prompt)?.trim() || fallback;
81
+ const problem = check?.(answer);
82
+ if (!problem)
83
+ return answer;
84
+ prompt = `${problem}\n${question}`;
85
+ }
86
+ };
87
+ }
88
+ /** Writes the project, unless a file is in the way, then shows its plan. */
89
+ function create(options, io, target, template, answers, prepared) {
90
+ const files = scaffoldFiles(template, answers, prepared);
91
+ const problem = projectProblem(files);
92
+ if (problem)
93
+ throw new Error(problem);
94
+ const result = writeScaffold(target, files);
95
+ const shown = relative(io.cwd, target) || ".";
96
+ if ("clashes" in result) {
97
+ const listed = result.clashes.map((path) => ` ${path}\n`).join("");
98
+ io.write(`Nothing written: these files already exist in ${shown}:\n${listed}`);
99
+ return 1;
100
+ }
101
+ io.write(`Created ${shown} from ${options.init.template ? "the template " : ""}${template.name} (${result.written.length} files).\n\n`);
102
+ const plan = {
103
+ command: "plan",
104
+ environments: [],
105
+ definitions: target,
106
+ out: join(target, "build"),
107
+ diffs: false,
108
+ };
109
+ return generate({ ...options, ...plan }, io);
110
+ }
111
+ /** Names given as flags are checked before anything else happens. */
112
+ function checkFlags(options) {
113
+ if (options.init.template &&
114
+ (options.init.connector || options.init.via || options.init.connectivity))
115
+ throw new Error("Choose connection options or --template, not both.");
116
+ const problem = (options.init.name !== undefined ? nameProblem(options.init.name, "project") : undefined) ??
117
+ options.environments.map((name) => nameProblem(name, "environment")).find(Boolean);
118
+ if (problem)
119
+ throw new Error(problem);
120
+ }
121
+ function environmentsProblem(answer) {
122
+ return list(answer)
123
+ .map((name) => nameProblem(name, "environment"))
124
+ .find(Boolean);
125
+ }
126
+ function templateEnvironments(template) {
127
+ const project = parse(readFileSync(join(template.folder, "project.yaml"), "utf8"));
128
+ return Object.keys(project.environments ?? { dev: {} });
129
+ }
130
+ function list(text) {
131
+ return text
132
+ .split(",")
133
+ .map((item) => item.trim())
134
+ .filter(Boolean);
135
+ }
136
+ //# sourceMappingURL=init.js.map