create-next-hydra 0.3.0 → 0.4.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.
Files changed (207) hide show
  1. package/README.md +126 -27
  2. package/dist/add-command.d.ts +11 -0
  3. package/dist/add-command.d.ts.map +1 -0
  4. package/dist/add-command.js +75 -0
  5. package/dist/addition.d.ts +67 -0
  6. package/dist/addition.d.ts.map +1 -0
  7. package/dist/addition.js +422 -0
  8. package/dist/application-git.d.ts +20 -0
  9. package/dist/application-git.d.ts.map +1 -0
  10. package/dist/application-git.js +57 -0
  11. package/dist/baseline.d.ts +22 -0
  12. package/dist/baseline.d.ts.map +1 -0
  13. package/dist/baseline.js +90 -0
  14. package/dist/cli.js +5 -18
  15. package/dist/commands.d.ts +22 -0
  16. package/dist/commands.d.ts.map +1 -0
  17. package/dist/commands.js +197 -0
  18. package/dist/composition-lint.d.ts +20 -0
  19. package/dist/composition-lint.d.ts.map +1 -0
  20. package/dist/composition-lint.js +288 -0
  21. package/dist/composition.d.ts +24 -0
  22. package/dist/composition.d.ts.map +1 -0
  23. package/dist/composition.js +420 -0
  24. package/dist/create-command.d.ts +21 -0
  25. package/dist/create-command.d.ts.map +1 -0
  26. package/dist/create-command.js +128 -0
  27. package/dist/demo-instrumentation.d.ts +5 -0
  28. package/dist/demo-instrumentation.d.ts.map +1 -0
  29. package/dist/demo-instrumentation.js +300 -0
  30. package/dist/environment.d.ts +7 -0
  31. package/dist/environment.d.ts.map +1 -0
  32. package/dist/environment.js +81 -0
  33. package/dist/errors.d.ts +156 -0
  34. package/dist/errors.d.ts.map +1 -0
  35. package/dist/errors.js +140 -0
  36. package/dist/file-policy.d.ts +6 -0
  37. package/dist/file-policy.d.ts.map +1 -0
  38. package/dist/file-policy.js +38 -0
  39. package/dist/files.d.ts +7 -0
  40. package/dist/files.d.ts.map +1 -0
  41. package/dist/files.js +66 -0
  42. package/dist/hosting.d.ts +5 -0
  43. package/dist/hosting.d.ts.map +1 -0
  44. package/dist/hosting.js +107 -0
  45. package/dist/index.d.ts +4 -6
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +17 -89
  48. package/dist/initialization.d.ts +14 -0
  49. package/dist/initialization.d.ts.map +1 -0
  50. package/dist/initialization.js +266 -0
  51. package/dist/lint-workspaces.d.ts +2 -0
  52. package/dist/lint-workspaces.d.ts.map +1 -0
  53. package/dist/lint-workspaces.js +62 -0
  54. package/dist/model.d.ts +143 -0
  55. package/dist/model.d.ts.map +1 -0
  56. package/dist/model.js +61 -0
  57. package/dist/package-catalog.d.ts +8 -0
  58. package/dist/package-catalog.d.ts.map +1 -0
  59. package/dist/package-catalog.js +61 -0
  60. package/dist/packages.d.ts +57 -0
  61. package/dist/packages.d.ts.map +1 -0
  62. package/dist/packages.js +237 -0
  63. package/dist/process-group.d.ts +5 -0
  64. package/dist/process-group.d.ts.map +1 -0
  65. package/dist/process-group.js +23 -0
  66. package/dist/reference-workspace-bindings.d.ts +38 -0
  67. package/dist/reference-workspace-bindings.d.ts.map +1 -0
  68. package/dist/reference-workspace-bindings.js +41 -0
  69. package/dist/reference-workspace.d.ts +6 -0
  70. package/dist/reference-workspace.d.ts.map +1 -0
  71. package/dist/reference-workspace.js +62 -0
  72. package/dist/registry.d.ts +187 -0
  73. package/dist/registry.d.ts.map +1 -0
  74. package/dist/registry.js +107 -0
  75. package/dist/runtime.d.ts +9 -0
  76. package/dist/runtime.d.ts.map +1 -0
  77. package/dist/runtime.js +22 -0
  78. package/dist/selection.d.ts +704 -0
  79. package/dist/selection.d.ts.map +1 -0
  80. package/dist/selection.js +424 -0
  81. package/dist/shadcn-protocol.d.ts +22 -0
  82. package/dist/shadcn-protocol.d.ts.map +1 -0
  83. package/dist/shadcn-protocol.js +13 -0
  84. package/dist/shadcn-worker.d.ts +2 -0
  85. package/dist/shadcn-worker.d.ts.map +1 -0
  86. package/dist/shadcn-worker.js +43 -0
  87. package/dist/shadcn.d.ts +22 -0
  88. package/dist/shadcn.d.ts.map +1 -0
  89. package/dist/shadcn.js +101 -0
  90. package/dist/source-changes.d.ts +55 -0
  91. package/dist/source-changes.d.ts.map +1 -0
  92. package/dist/source-changes.js +225 -0
  93. package/dist/source-inventory.d.ts +25 -0
  94. package/dist/source-inventory.d.ts.map +1 -0
  95. package/dist/source-inventory.js +212 -0
  96. package/dist/source-root.d.ts +4 -0
  97. package/dist/source-root.d.ts.map +1 -0
  98. package/dist/source-root.js +20 -0
  99. package/dist/staging.d.ts +19 -0
  100. package/dist/staging.d.ts.map +1 -0
  101. package/dist/staging.js +42 -0
  102. package/dist/tasks.d.ts +44 -0
  103. package/dist/tasks.d.ts.map +1 -0
  104. package/dist/tasks.js +137 -0
  105. package/dist/templates.d.ts +217 -0
  106. package/dist/templates.d.ts.map +1 -0
  107. package/dist/templates.js +161 -0
  108. package/dist/test-reference-workspace.d.ts +2 -0
  109. package/dist/test-reference-workspace.d.ts.map +1 -0
  110. package/dist/test-reference-workspace.js +6 -0
  111. package/dist/types.d.ts +2 -9
  112. package/dist/types.d.ts.map +1 -1
  113. package/dist/typescript-paths.d.ts +10 -0
  114. package/dist/typescript-paths.d.ts.map +1 -0
  115. package/dist/typescript-paths.js +52 -0
  116. package/dist/workspace-dependencies.d.ts +26 -0
  117. package/dist/workspace-dependencies.d.ts.map +1 -0
  118. package/dist/workspace-dependencies.js +478 -0
  119. package/dist/workspace-files.d.ts +24 -0
  120. package/dist/workspace-files.d.ts.map +1 -0
  121. package/dist/workspace-files.js +395 -0
  122. package/dist/workspace-lock.d.ts +12 -0
  123. package/dist/workspace-lock.d.ts.map +1 -0
  124. package/dist/workspace-lock.js +104 -0
  125. package/dist/workspace-snapshots.d.ts +24 -0
  126. package/dist/workspace-snapshots.d.ts.map +1 -0
  127. package/dist/workspace-snapshots.js +218 -0
  128. package/dist/workspace-sources.d.ts +27 -0
  129. package/dist/workspace-sources.d.ts.map +1 -0
  130. package/dist/workspace-sources.js +88 -0
  131. package/dist/workspace-state.d.ts +325 -0
  132. package/dist/workspace-state.d.ts.map +1 -0
  133. package/dist/workspace-state.js +571 -0
  134. package/dist/workspaces.d.ts +73 -0
  135. package/dist/workspaces.d.ts.map +1 -0
  136. package/dist/workspaces.js +396 -0
  137. package/package.json +25 -20
  138. package/schema/selection-definition.json +143 -4
  139. package/dist/clone.d.ts +0 -9
  140. package/dist/clone.d.ts.map +0 -1
  141. package/dist/clone.js +0 -19
  142. package/dist/composition/add.d.ts +0 -14
  143. package/dist/composition/add.d.ts.map +0 -1
  144. package/dist/composition/add.js +0 -484
  145. package/dist/composition/catalog.d.ts +0 -26
  146. package/dist/composition/catalog.d.ts.map +0 -1
  147. package/dist/composition/catalog.js +0 -317
  148. package/dist/composition/errors.d.ts +0 -5
  149. package/dist/composition/errors.d.ts.map +0 -1
  150. package/dist/composition/errors.js +0 -8
  151. package/dist/composition/format.d.ts +0 -6
  152. package/dist/composition/format.d.ts.map +0 -1
  153. package/dist/composition/format.js +0 -65
  154. package/dist/composition/install.d.ts +0 -16
  155. package/dist/composition/install.d.ts.map +0 -1
  156. package/dist/composition/install.js +0 -175
  157. package/dist/composition/packages.d.ts +0 -6
  158. package/dist/composition/packages.d.ts.map +0 -1
  159. package/dist/composition/packages.js +0 -55
  160. package/dist/composition/paths.d.ts +0 -4
  161. package/dist/composition/paths.d.ts.map +0 -1
  162. package/dist/composition/paths.js +0 -47
  163. package/dist/composition/planner.d.ts +0 -4
  164. package/dist/composition/planner.d.ts.map +0 -1
  165. package/dist/composition/planner.js +0 -366
  166. package/dist/composition/schema.d.ts +0 -294
  167. package/dist/composition/schema.d.ts.map +0 -1
  168. package/dist/composition/schema.js +0 -166
  169. package/dist/composition/types.d.ts +0 -111
  170. package/dist/composition/types.d.ts.map +0 -1
  171. package/dist/composition/types.js +0 -6
  172. package/dist/composition/typescript-paths.d.ts +0 -6
  173. package/dist/composition/typescript-paths.d.ts.map +0 -1
  174. package/dist/composition/typescript-paths.js +0 -157
  175. package/dist/composition/use.d.ts +0 -23
  176. package/dist/composition/use.d.ts.map +0 -1
  177. package/dist/composition/use.js +0 -187
  178. package/dist/composition/workspace.d.ts +0 -10
  179. package/dist/composition/workspace.d.ts.map +0 -1
  180. package/dist/composition/workspace.js +0 -210
  181. package/dist/constants.d.ts +0 -11
  182. package/dist/constants.d.ts.map +0 -1
  183. package/dist/constants.js +0 -39
  184. package/dist/fs-utils.d.ts +0 -9
  185. package/dist/fs-utils.d.ts.map +0 -1
  186. package/dist/fs-utils.js +0 -64
  187. package/dist/git.d.ts +0 -28
  188. package/dist/git.d.ts.map +0 -1
  189. package/dist/git.js +0 -107
  190. package/dist/instruction-renderer.d.ts +0 -17
  191. package/dist/instruction-renderer.d.ts.map +0 -1
  192. package/dist/instruction-renderer.js +0 -132
  193. package/dist/logger.d.ts +0 -13
  194. package/dist/logger.d.ts.map +0 -1
  195. package/dist/logger.js +0 -26
  196. package/dist/prompts.d.ts +0 -7
  197. package/dist/prompts.d.ts.map +0 -1
  198. package/dist/prompts.js +0 -54
  199. package/dist/sanitize.d.ts +0 -10
  200. package/dist/sanitize.d.ts.map +0 -1
  201. package/dist/sanitize.js +0 -110
  202. package/dist/scaffold.d.ts +0 -7
  203. package/dist/scaffold.d.ts.map +0 -1
  204. package/dist/scaffold.js +0 -330
  205. package/dist/version.d.ts +0 -2
  206. package/dist/version.d.ts.map +0 -1
  207. package/dist/version.js +0 -2
@@ -0,0 +1,300 @@
1
+ import { Array as EffectArray, Effect, Order } from "effect";
2
+ import ts from "typescript";
3
+ import { InvalidComposition } from "./errors.js";
4
+ export const demoArchitecturePackage = "@repo/demo-architecture";
5
+ function isDemoModule(value) {
6
+ return (value === demoArchitecturePackage ||
7
+ value.startsWith(`${demoArchitecturePackage}/`));
8
+ }
9
+ function importKind(moduleName) {
10
+ if (moduleName === `${demoArchitecturePackage}/boundary`) {
11
+ return "boundary";
12
+ }
13
+ if (moduleName === `${demoArchitecturePackage}/toolbar`) {
14
+ return "toolbar";
15
+ }
16
+ return undefined;
17
+ }
18
+ function metadataImportEdits(file, removed) {
19
+ const references = new Map();
20
+ const visit = (node) => {
21
+ if (ts.isImportDeclaration(node)) {
22
+ return;
23
+ }
24
+ if (ts.isIdentifier(node)) {
25
+ const matches = references.get(node.text) ?? [];
26
+ matches.push(node);
27
+ references.set(node.text, matches);
28
+ }
29
+ ts.forEachChild(node, visit);
30
+ };
31
+ visit(file);
32
+ const edits = [];
33
+ const printer = ts.createPrinter();
34
+ for (const statement of file.statements) {
35
+ if (!ts.isImportDeclaration(statement) ||
36
+ removed.some((edit) => edit.start === statement.getStart(file))) {
37
+ continue;
38
+ }
39
+ const clause = statement.importClause;
40
+ const bindings = clause?.namedBindings;
41
+ if (!(clause && bindings && ts.isNamedImports(bindings))) {
42
+ continue;
43
+ }
44
+ // Retain any binding referenced outside erased metadata. Unused imports
45
+ // that predate this transform are not part of annotation removal.
46
+ const retained = bindings.elements.filter((binding) => {
47
+ const uses = references.get(binding.name.text) ?? [];
48
+ return (uses.length === 0 ||
49
+ uses.some((use) => !removed.some((edit) => edit.start <= use.getStart(file) && use.end <= edit.end)));
50
+ });
51
+ if (retained.length === bindings.elements.length) {
52
+ continue;
53
+ }
54
+ let text = "";
55
+ if (clause.name || retained.length > 0) {
56
+ const updated = ts.factory.updateImportDeclaration(statement, statement.modifiers, ts.factory.updateImportClause(clause, clause.phaseModifier, clause.name, retained.length > 0
57
+ ? ts.factory.updateNamedImports(bindings, retained)
58
+ : undefined), statement.moduleSpecifier, statement.attributes);
59
+ text = printer.printNode(ts.EmitHint.Unspecified, updated, file);
60
+ }
61
+ edits.push({ end: statement.end, start: statement.getStart(file), text });
62
+ }
63
+ return edits;
64
+ }
65
+ const metadataProps = new Set([
66
+ "caching",
67
+ "cacheTags",
68
+ "composition",
69
+ "description",
70
+ "getCaching",
71
+ "getCacheLife",
72
+ "getCacheTags",
73
+ "name",
74
+ "streaming",
75
+ ]);
76
+ // Values describe the demo, never drive application work. Suppliers are lazy:
77
+ // their bodies run only in the demo runtime, so erasing them has no side effects.
78
+ function isMetadataValue(node) {
79
+ if (ts.isIdentifier(node) ||
80
+ ts.isLiteralExpression(node) ||
81
+ ts.isArrowFunction(node) ||
82
+ node.kind === ts.SyntaxKind.TrueKeyword ||
83
+ node.kind === ts.SyntaxKind.FalseKeyword ||
84
+ node.kind === ts.SyntaxKind.NullKeyword) {
85
+ return true;
86
+ }
87
+ if (ts.isParenthesizedExpression(node) ||
88
+ ts.isAsExpression(node) ||
89
+ ts.isNonNullExpression(node)) {
90
+ return isMetadataValue(node.expression);
91
+ }
92
+ if (ts.isPropertyAccessExpression(node)) {
93
+ return isMetadataValue(node.expression);
94
+ }
95
+ if (ts.isArrayLiteralExpression(node)) {
96
+ return node.elements.every(isMetadataValue);
97
+ }
98
+ if (ts.isConditionalExpression(node)) {
99
+ return (isMetadataValue(node.condition) &&
100
+ isMetadataValue(node.whenTrue) &&
101
+ isMetadataValue(node.whenFalse));
102
+ }
103
+ return false;
104
+ }
105
+ function validateMetadata(attributes) {
106
+ for (const property of attributes.properties) {
107
+ if (!ts.isJsxAttribute(property) ||
108
+ !ts.isIdentifier(property.name) ||
109
+ !metadataProps.has(property.name.text)) {
110
+ throw new Error("Only demo metadata props can be erased; move keys, refs, layout and spread props onto application elements.");
111
+ }
112
+ const value = property.initializer;
113
+ if (value &&
114
+ !ts.isStringLiteral(value) &&
115
+ (!ts.isJsxExpression(value) ||
116
+ !value.expression ||
117
+ !isMetadataValue(value.expression))) {
118
+ throw new Error("Metadata must be a value or lazy supplier, not an eager operation.");
119
+ }
120
+ }
121
+ }
122
+ // Only the explicit demo import contract is erasable. This is not dead-code
123
+ // elimination, and must never remove application cache or Suspense boundaries.
124
+ export const eraseDemoInstrumentation = (target, source) => Effect.try({
125
+ catch: (error) => new InvalidComposition({
126
+ message: `Cannot remove demo instrumentation from ${target}: ${error instanceof Error ? error.message : String(error)}`,
127
+ }),
128
+ try: () => {
129
+ if (!source.includes(demoArchitecturePackage)) {
130
+ return source;
131
+ }
132
+ const file = ts.createSourceFile(target, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
133
+ const diagnostics = ts.transpileModule(source, {
134
+ compilerOptions: {
135
+ jsx: ts.JsxEmit.Preserve,
136
+ target: ts.ScriptTarget.ESNext,
137
+ },
138
+ fileName: target,
139
+ reportDiagnostics: true,
140
+ }).diagnostics ?? [];
141
+ if (diagnostics.some((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error)) {
142
+ throw new Error("Invalid source syntax.");
143
+ }
144
+ const bindings = new Map();
145
+ const allowed = new Set();
146
+ const edits = [];
147
+ for (const statement of file.statements) {
148
+ if (!ts.isImportDeclaration(statement) ||
149
+ !ts.isStringLiteral(statement.moduleSpecifier)) {
150
+ continue;
151
+ }
152
+ const moduleName = statement.moduleSpecifier.text;
153
+ if (!isDemoModule(moduleName)) {
154
+ continue;
155
+ }
156
+ if (moduleName === `${demoArchitecturePackage}/styles.css` &&
157
+ !statement.importClause) {
158
+ allowed.add(statement.moduleSpecifier);
159
+ edits.push({
160
+ end: statement.end,
161
+ start: statement.getStart(file),
162
+ text: "",
163
+ });
164
+ continue;
165
+ }
166
+ const kind = importKind(moduleName);
167
+ const clause = statement.importClause;
168
+ if (!kind ||
169
+ !clause ||
170
+ clause.name ||
171
+ clause.phaseModifier === ts.SyntaxKind.TypeKeyword ||
172
+ !clause.namedBindings ||
173
+ !ts.isNamedImports(clause.namedBindings)) {
174
+ throw new Error("Use named imports from the demo boundary or toolbar module.");
175
+ }
176
+ for (const element of clause.namedBindings.elements) {
177
+ if (/^[a-z]/u.test(element.name.text)) {
178
+ throw new Error("Demo import aliases must use component names, not lowercase HTML tag names.");
179
+ }
180
+ const name = kind === "boundary"
181
+ ? "ArchitectureBoundary"
182
+ : "ArchitectureToolbar";
183
+ if ((element.propertyName ?? element.name).text !== name ||
184
+ element.isTypeOnly) {
185
+ throw new Error("Demo types and helpers must not enter application interfaces.");
186
+ }
187
+ bindings.set(element.name.text, kind);
188
+ allowed.add(element.name);
189
+ if (element.propertyName) {
190
+ allowed.add(element.propertyName);
191
+ }
192
+ }
193
+ allowed.add(statement.moduleSpecifier);
194
+ edits.push({
195
+ end: statement.end,
196
+ start: statement.getStart(file),
197
+ text: "",
198
+ });
199
+ }
200
+ const visit = (node, inJsxChildren = false, canSplice = false) => {
201
+ if (ts.isJsxElement(node) &&
202
+ ts.isIdentifier(node.openingElement.tagName) &&
203
+ bindings.get(node.openingElement.tagName.text) === "boundary") {
204
+ validateMetadata(node.openingElement.attributes);
205
+ allowed.add(node.openingElement.tagName);
206
+ allowed.add(node.closingElement.tagName);
207
+ const children = node.children.filter((child) => !(ts.isJsxText(child) &&
208
+ child.containsOnlyTriviaWhiteSpaces &&
209
+ /[\r\n]/u.test(child.text)));
210
+ const child = children.length === 1 ? children[0] : undefined;
211
+ const lastChild = children.at(-1);
212
+ const singleElement = child !== undefined &&
213
+ (ts.isJsxElement(child) ||
214
+ ts.isJsxSelfClosingElement(child) ||
215
+ ts.isJsxFragment(child));
216
+ const elementChildren = children.length > 0 &&
217
+ children.every((element) => ts.isJsxElement(element) ||
218
+ ts.isJsxSelfClosingElement(element) ||
219
+ ts.isJsxFragment(element));
220
+ // Keep text token boundaries and the single-child contract of custom
221
+ // components. Only element groups under intrinsic parents can flatten.
222
+ const splice = inJsxChildren && (singleElement || (canSplice && elementChildren));
223
+ // Parentheses preserve return/newline semantics when a single JSX
224
+ // child becomes an expression. JSX parents accept siblings directly.
225
+ let opening = "<>";
226
+ let closing = "</>";
227
+ if (splice) {
228
+ opening = "";
229
+ closing = "";
230
+ }
231
+ else if (singleElement && !inJsxChildren) {
232
+ opening = "(";
233
+ closing = ")";
234
+ }
235
+ edits.push({
236
+ end: splice && children[0] !== undefined
237
+ ? children[0].getStart(file)
238
+ : node.openingElement.end,
239
+ start: node.openingElement.getStart(file),
240
+ text: opening,
241
+ }, {
242
+ end: node.closingElement.end,
243
+ start: splice && lastChild !== undefined
244
+ ? lastChild.end
245
+ : node.closingElement.getStart(file),
246
+ text: closing,
247
+ });
248
+ for (const element of node.children) {
249
+ visit(element, splice || !singleElement, splice ? canSplice : !singleElement);
250
+ }
251
+ return;
252
+ }
253
+ if (ts.isJsxSelfClosingElement(node) &&
254
+ ts.isIdentifier(node.tagName) &&
255
+ bindings.get(node.tagName.text) === "toolbar") {
256
+ if (node.attributes.properties.length) {
257
+ throw new Error("The demo toolbar must not receive application props.");
258
+ }
259
+ allowed.add(node.tagName);
260
+ edits.push({
261
+ end: node.end,
262
+ start: node.getStart(file),
263
+ text: inJsxChildren ? "{null}" : "null",
264
+ });
265
+ }
266
+ ts.forEachChild(node, (child) => {
267
+ const childPosition = (ts.isJsxElement(node) || ts.isJsxFragment(node)) &&
268
+ node.children.some((element) => element === child);
269
+ const intrinsicParent = ts.isJsxFragment(node) ||
270
+ (ts.isJsxElement(node) &&
271
+ ts.isIdentifier(node.openingElement.tagName) &&
272
+ /^[a-z]/u.test(node.openingElement.tagName.text));
273
+ visit(child, childPosition, childPosition && intrinsicParent);
274
+ });
275
+ };
276
+ visit(file);
277
+ const check = (node) => {
278
+ if ((ts.isStringLiteralLike(node) || ts.isTemplateHead(node)) &&
279
+ isDemoModule(node.text) &&
280
+ !allowed.has(node)) {
281
+ throw new Error("Demo modules must use the supported static imports.");
282
+ }
283
+ if (ts.isIdentifier(node) &&
284
+ bindings.has(node.text) &&
285
+ !allowed.has(node)) {
286
+ throw new Error(`Unsupported use of demo import ${node.text}. Use an explicit JSX boundary.`);
287
+ }
288
+ ts.forEachChild(node, check);
289
+ };
290
+ check(file);
291
+ edits.push(...metadataImportEdits(file, edits));
292
+ let output = source;
293
+ const descendingPosition = Order.mapInput(Order.Number, (edit) => -edit.start);
294
+ for (const edit of EffectArray.sort(edits, descendingPosition)) {
295
+ output =
296
+ output.slice(0, edit.start) + edit.text + output.slice(edit.end);
297
+ }
298
+ return output;
299
+ },
300
+ });
@@ -0,0 +1,7 @@
1
+ import { Effect, FileSystem, Path } from "effect";
2
+ import { EnvironmentInitializationFailed, InvalidComposition } from "./errors.ts";
3
+ import type { PreparedFile } from "./model.ts";
4
+ import type { LocalEnvironmentFile } from "./source-inventory.ts";
5
+ export declare const planEnvironmentCopy: (destination: string, files: readonly PreparedFile[], local: readonly LocalEnvironmentFile[]) => Effect.Effect<LocalEnvironmentFile[], InvalidComposition | import("effect/PlatformError").PlatformError, FileSystem.FileSystem | Path.Path>;
6
+ export declare const copyEnvironment: (destination: string, inputs: readonly LocalEnvironmentFile[], initialize?: (<A, E, R>(target: string, write: Effect.Effect<A, E, R>) => Effect.Effect<A, E | import("./workspace-state.ts").WorkspaceStateError, R>) | undefined) => Effect.Effect<string[], EnvironmentInitializationFailed | import("./workspace-state.ts").WorkspaceStateError, FileSystem.FileSystem | Path.Path>;
7
+ //# sourceMappingURL=environment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAY,MAAM,QAAQ,CAAC;AAE5D,OAAO,EACL,+BAA+B,EAC/B,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAGrB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAGlE,eAAO,MAAM,mBAAmB,8OA6C/B,CAAC;AAEF,eAAO,MAAM,eAAe,wXA2D3B,CAAC"}
@@ -0,0 +1,81 @@
1
+ import { Effect, FileSystem, Path, Redacted } from "effect";
2
+ import { EnvironmentInitializationFailed, InvalidComposition, } from "./errors.js";
3
+ import { isEnvironmentFile } from "./file-policy.js";
4
+ import { relativeFile } from "./files.js";
5
+ export const planEnvironmentCopy = Effect.fn("Workspaces.planEnvironmentCopy")(function* (destination, files, local) {
6
+ const fs = yield* FileSystem.FileSystem;
7
+ const path = yield* Path.Path;
8
+ const directories = new Set(["."]);
9
+ for (const file of files) {
10
+ let directory = path.dirname(file.target);
11
+ while (directory !== ".") {
12
+ directories.add(directory);
13
+ directory = path.dirname(directory);
14
+ }
15
+ }
16
+ const pending = [];
17
+ for (const file of local) {
18
+ const target = yield* relativeFile(file.target);
19
+ if (!isEnvironmentFile(target)) {
20
+ return yield* new InvalidComposition({
21
+ message: `Not an environment file: ${target}`,
22
+ });
23
+ }
24
+ if (!directories.has(path.dirname(target))) {
25
+ continue;
26
+ }
27
+ const absolute = path.join(destination, target);
28
+ if (yield* fs.exists(absolute)) {
29
+ if ((yield* fs.stat(absolute)).type !== "File") {
30
+ return yield* new InvalidComposition({
31
+ message: `Environment target is not a file: ${file.target}`,
32
+ });
33
+ }
34
+ continue;
35
+ }
36
+ if ((yield* fs.stat(file.source)).type !== "File") {
37
+ return yield* new InvalidComposition({
38
+ message: `Environment source is not a file: ${file.target}`,
39
+ });
40
+ }
41
+ pending.push(file);
42
+ }
43
+ return pending;
44
+ });
45
+ export const copyEnvironment = Effect.fn("Workspaces.copyEnvironment")(function* (destination, inputs, initialize) {
46
+ const fs = yield* FileSystem.FileSystem;
47
+ const path = yield* Path.Path;
48
+ const created = [];
49
+ for (const file of inputs) {
50
+ const target = path.join(destination, file.target);
51
+ const copy = Effect.gen(function* () {
52
+ if (yield* fs.exists(target)) {
53
+ if ((yield* fs.stat(target)).type === "File") {
54
+ return;
55
+ }
56
+ return yield* new InvalidComposition({
57
+ message: `Environment target is not a file: ${file.target}`,
58
+ });
59
+ }
60
+ yield* fs.makeDirectory(path.dirname(target), { recursive: true });
61
+ const content = yield* fs.readFile(file.source);
62
+ const written = yield* fs
63
+ .writeFile(target, content, { flag: "wx", mode: 0o600 })
64
+ .pipe(Effect.as(true), Effect.catchIf((error) => error.reason._tag === "AlreadyExists", (error) => fs
65
+ .stat(target)
66
+ .pipe(Effect.flatMap((stat) => stat.type === "File"
67
+ ? Effect.succeed(false)
68
+ : Effect.fail(error)))));
69
+ if (written) {
70
+ created.push(file.target);
71
+ }
72
+ }).pipe(Effect.uninterruptible, Effect.mapError((error) => new EnvironmentInitializationFailed({
73
+ createdFiles: [...created],
74
+ diagnostic: Redacted.make(error),
75
+ directory: destination,
76
+ failedFile: file.target,
77
+ })));
78
+ yield* initialize ? initialize(file.target, copy) : copy;
79
+ }
80
+ return created;
81
+ });
@@ -0,0 +1,156 @@
1
+ import { Runtime, Schema } from "effect";
2
+ declare const ApplicationTaskFailed_base: Schema.Class<ApplicationTaskFailed, Schema.TaggedStruct<"ApplicationTaskFailed", {
3
+ readonly code: Schema.Int;
4
+ readonly directory: Schema.String;
5
+ }>, import("effect/Cause").YieldableError>;
6
+ export declare class ApplicationTaskFailed extends ApplicationTaskFailed_base {
7
+ get message(): string;
8
+ get [Runtime.errorExitCode](): number;
9
+ }
10
+ declare const IncompatibleSelection_base: Schema.Class<IncompatibleSelection, Schema.TaggedStruct<"IncompatibleSelection", {
11
+ readonly conflicts: Schema.$Array<Schema.String>;
12
+ readonly missing: Schema.$Array<Schema.String>;
13
+ readonly selection: Schema.String;
14
+ }>, import("effect/Cause").YieldableError>;
15
+ export declare class IncompatibleSelection extends IncompatibleSelection_base {
16
+ get message(): string;
17
+ }
18
+ declare const InvalidComposition_base: Schema.Class<InvalidComposition, Schema.TaggedStruct<"InvalidComposition", {
19
+ readonly message: Schema.String;
20
+ }>, import("effect/Cause").YieldableError>;
21
+ export declare class InvalidComposition extends InvalidComposition_base {
22
+ }
23
+ declare const SourceChanged_base: Schema.Class<SourceChanged, Schema.TaggedStruct<"SourceChanged", {
24
+ readonly paths: Schema.$Array<Schema.String>;
25
+ }>, import("effect/Cause").YieldableError>;
26
+ export declare class SourceChanged extends SourceChanged_base {
27
+ }
28
+ declare const SourceAcquisitionFailed_base: Schema.Class<SourceAcquisitionFailed, Schema.TaggedStruct<"SourceAcquisitionFailed", {
29
+ readonly diagnostic: Schema.Redacted<Schema.Unknown>;
30
+ readonly phase: Schema.String;
31
+ }>, import("effect/Cause").YieldableError>;
32
+ export declare class SourceAcquisitionFailed extends SourceAcquisitionFailed_base {
33
+ get message(): string;
34
+ }
35
+ declare const SourceStorageRetained_base: Schema.Class<SourceStorageRetained, Schema.TaggedStruct<"SourceStorageRetained", {
36
+ readonly directory: Schema.String;
37
+ }>, import("effect/Cause").YieldableError>;
38
+ export declare class SourceStorageRetained extends SourceStorageRetained_base {
39
+ }
40
+ declare const DestinationNotEmpty_base: Schema.Class<DestinationNotEmpty, Schema.TaggedStruct<"DestinationNotEmpty", {
41
+ readonly directory: Schema.String;
42
+ }>, import("effect/Cause").YieldableError>;
43
+ export declare class DestinationNotEmpty extends DestinationNotEmpty_base {
44
+ }
45
+ declare const RegistryFailure_base: Schema.Class<RegistryFailure, Schema.TaggedStruct<"RegistryFailure", {
46
+ readonly diagnostic: Schema.Redacted<Schema.String>;
47
+ readonly operation: Schema.String;
48
+ }>, import("effect/Cause").YieldableError>;
49
+ export declare class RegistryFailure extends RegistryFailure_base {
50
+ }
51
+ declare const StagingRetained_base: Schema.Class<StagingRetained, Schema.TaggedStruct<"StagingRetained", {
52
+ readonly directory: Schema.String;
53
+ }>, import("effect/Cause").YieldableError>;
54
+ export declare class StagingRetained extends StagingRetained_base {
55
+ }
56
+ declare const RegistryWorkerFailure_base: Schema.Class<RegistryWorkerFailure, Schema.TaggedStruct<"RegistryWorkerFailure", {
57
+ readonly phase: Schema.Literals<readonly ["launch", "exit", "protocol", "stop"]>;
58
+ }>, import("effect/Cause").YieldableError>;
59
+ export declare class RegistryWorkerFailure extends RegistryWorkerFailure_base {
60
+ }
61
+ declare const MaterializationFailed_base: Schema.Class<MaterializationFailed, Schema.TaggedStruct<"MaterializationFailed", {
62
+ readonly completedFiles: Schema.$Array<Schema.String>;
63
+ readonly diagnostic: Schema.Redacted<Schema.Unknown>;
64
+ readonly directory: Schema.String;
65
+ readonly failedFile: Schema.String;
66
+ }>, import("effect/Cause").YieldableError>;
67
+ export declare class MaterializationFailed extends MaterializationFailed_base {
68
+ }
69
+ declare const EnvironmentInitializationFailed_base: Schema.Class<EnvironmentInitializationFailed, Schema.TaggedStruct<"EnvironmentInitializationFailed", {
70
+ readonly createdFiles: Schema.$Array<Schema.String>;
71
+ readonly diagnostic: Schema.Redacted<Schema.Unknown>;
72
+ readonly directory: Schema.String;
73
+ readonly failedFile: Schema.String;
74
+ }>, import("effect/Cause").YieldableError>;
75
+ export declare class EnvironmentInitializationFailed extends EnvironmentInitializationFailed_base {
76
+ get message(): string;
77
+ }
78
+ declare const WorkspaceBusy_base: Schema.Class<WorkspaceBusy, Schema.TaggedStruct<"WorkspaceBusy", {
79
+ readonly directory: Schema.String;
80
+ }>, import("effect/Cause").YieldableError>;
81
+ export declare class WorkspaceBusy extends WorkspaceBusy_base {
82
+ get message(): string;
83
+ }
84
+ declare const WorkspaceLockAuthorizationRequired_base: Schema.Class<WorkspaceLockAuthorizationRequired, Schema.TaggedStruct<"WorkspaceLockAuthorizationRequired", {
85
+ readonly directory: Schema.String;
86
+ readonly reason: Schema.String;
87
+ readonly token: Schema.String;
88
+ }>, import("effect/Cause").YieldableError>;
89
+ export declare class WorkspaceLockAuthorizationRequired extends WorkspaceLockAuthorizationRequired_base {
90
+ get message(): string;
91
+ }
92
+ declare const WorkspaceLockChanged_base: Schema.Class<WorkspaceLockChanged, Schema.TaggedStruct<"WorkspaceLockChanged", {
93
+ readonly directory: Schema.String;
94
+ }>, import("effect/Cause").YieldableError>;
95
+ export declare class WorkspaceLockChanged extends WorkspaceLockChanged_base {
96
+ get message(): string;
97
+ }
98
+ declare const WorkspaceConflict_base: Schema.Class<WorkspaceConflict, Schema.TaggedStruct<"WorkspaceConflict", {
99
+ readonly paths: Schema.$Array<Schema.String>;
100
+ }>, import("effect/Cause").YieldableError>;
101
+ export declare class WorkspaceConflict extends WorkspaceConflict_base {
102
+ get message(): string;
103
+ }
104
+ declare const WorkspaceRecoveryRequired_base: Schema.Class<WorkspaceRecoveryRequired, Schema.TaggedStruct<"WorkspaceRecoveryRequired", {
105
+ readonly directory: Schema.String;
106
+ readonly paths: Schema.optionalKey<Schema.$Array<Schema.String>>;
107
+ }>, import("effect/Cause").YieldableError>;
108
+ export declare class WorkspaceRecoveryRequired extends WorkspaceRecoveryRequired_base {
109
+ get message(): string;
110
+ }
111
+ declare const WorkspaceStateInvalid_base: Schema.Class<WorkspaceStateInvalid, Schema.TaggedStruct<"WorkspaceStateInvalid", {
112
+ readonly directory: Schema.String;
113
+ }>, import("effect/Cause").YieldableError>;
114
+ export declare class WorkspaceStateInvalid extends WorkspaceStateInvalid_base {
115
+ get message(): string;
116
+ }
117
+ declare const WorkspaceNotCurrent_base: Schema.Class<WorkspaceNotCurrent, Schema.TaggedStruct<"WorkspaceNotCurrent", {
118
+ readonly directory: Schema.String;
119
+ }>, import("effect/Cause").YieldableError>;
120
+ export declare class WorkspaceNotCurrent extends WorkspaceNotCurrent_base {
121
+ get message(): string;
122
+ }
123
+ declare const WorkspaceBatchFailed_base: Schema.Class<WorkspaceBatchFailed, Schema.TaggedStruct<"WorkspaceBatchFailed", {
124
+ readonly names: Schema.$Array<Schema.String>;
125
+ }>, import("effect/Cause").YieldableError>;
126
+ export declare class WorkspaceBatchFailed extends WorkspaceBatchFailed_base {
127
+ get message(): string;
128
+ }
129
+ declare const SnapshotUnavailable_base: Schema.Class<SnapshotUnavailable, Schema.TaggedStruct<"SnapshotUnavailable", {
130
+ readonly directory: Schema.String;
131
+ }>, import("effect/Cause").YieldableError>;
132
+ export declare class SnapshotUnavailable extends SnapshotUnavailable_base {
133
+ get message(): string;
134
+ }
135
+ declare const WorkspaceUninitialized_base: Schema.Class<WorkspaceUninitialized, Schema.TaggedStruct<"WorkspaceUninitialized", {
136
+ readonly directory: Schema.String;
137
+ }>, import("effect/Cause").YieldableError>;
138
+ export declare class WorkspaceUninitialized extends WorkspaceUninitialized_base {
139
+ get message(): string;
140
+ }
141
+ declare const SnapshotFailed_base: Schema.Class<SnapshotFailed, Schema.TaggedStruct<"SnapshotFailed", {
142
+ readonly directory: Schema.String;
143
+ readonly operation: Schema.String;
144
+ }>, import("effect/Cause").YieldableError>;
145
+ export declare class SnapshotFailed extends SnapshotFailed_base {
146
+ get message(): string;
147
+ }
148
+ declare const DependencyInstallationFailed_base: Schema.Class<DependencyInstallationFailed, Schema.TaggedStruct<"DependencyInstallationFailed", {
149
+ readonly directory: Schema.String;
150
+ readonly phase: Schema.Literals<readonly ["launch", "exit", "stop", "inputs", "outputs", "version"]>;
151
+ }>, import("effect/Cause").YieldableError>;
152
+ export declare class DependencyInstallationFailed extends DependencyInstallationFailed_base {
153
+ get message(): string;
154
+ }
155
+ export {};
156
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;;;;;AAEzC,qBAAa,qBAAsB,SAAQ,0BAM1C;IACC,IAAI,OAAO,WAEV;IACD,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,WAE1B;CACF;;;;;;AAED,qBAAa,qBAAsB,SAAQ,0BAO1C;IACC,IAAI,OAAO,WASV;CACF;;;;AAED,qBAAa,kBAAmB,SAAQ,uBAGvC;CAAG;;;;AAEJ,qBAAa,aAAc,SAAQ,kBAGlC;CAAG;;;;;AAEJ,qBAAa,uBAAwB,SAAQ,4BAG5C;IACC,IAAI,OAAO,WAEV;CACF;;;;AACD,qBAAa,qBAAsB,SAAQ,0BAG1C;CAAG;;;;AAEJ,qBAAa,mBAAoB,SAAQ,wBAGxC;CAAG;;;;;AAEJ,qBAAa,eAAgB,SAAQ,oBAGpC;CAAG;;;;AAEJ,qBAAa,eAAgB,SAAQ,oBAGpC;CAAG;;;;AAEJ,qBAAa,qBAAsB,SAAQ,0BAG1C;CAAG;;;;;;;AAEJ,qBAAa,qBAAsB,SAAQ,0BAQ1C;CAAG;;;;;;;AAEJ,qBAAa,+BAAgC,SAAQ,oCAQpD;IACC,IAAI,OAAO,WAEV;CACF;;;;AAED,qBAAa,aAAc,SAAQ,kBAGlC;IACC,IAAI,OAAO,WAEV;CACF;;;;;;AAED,qBAAa,kCAAmC,SAAQ,uCAGvD;IACC,IAAI,OAAO,WAEV;CACF;;;;AAED,qBAAa,oBAAqB,SAAQ,yBAGzC;IACC,IAAI,OAAO,WAEV;CACF;;;;AAED,qBAAa,iBAAkB,SAAQ,sBAGtC;IACC,IAAI,OAAO,WAEV;CACF;;;;;AAED,qBAAa,yBAA0B,SAAQ,8BAM9C;IACC,IAAI,OAAO,WAKV;CACF;;;;AAED,qBAAa,qBAAsB,SAAQ,0BAG1C;IACC,IAAI,OAAO,WAEV;CACF;;;;AAED,qBAAa,mBAAoB,SAAQ,wBAGxC;IACC,IAAI,OAAO,WAEV;CACF;;;;AAED,qBAAa,oBAAqB,SAAQ,yBAGzC;IACC,IAAI,OAAO,WAEV;CACF;;;;AAED,qBAAa,mBAAoB,SAAQ,wBAGxC;IACC,IAAI,OAAO,WAEV;CACF;;;;AAED,qBAAa,sBAAuB,SAAQ,2BAG3C;IACC,IAAI,OAAO,WAEV;CACF;;;;;AAED,qBAAa,cAAe,SAAQ,mBAGnC;IACC,IAAI,OAAO,WAEV;CACF;;;;;AAED,qBAAa,4BAA6B,SAAQ,iCAajD;IACC,IAAI,OAAO,WAEV;CACF"}