create-next-hydra 0.3.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +126 -27
- package/dist/add-command.d.ts +11 -0
- package/dist/add-command.d.ts.map +1 -0
- package/dist/add-command.js +75 -0
- package/dist/addition.d.ts +67 -0
- package/dist/addition.d.ts.map +1 -0
- package/dist/addition.js +422 -0
- package/dist/application-git.d.ts +20 -0
- package/dist/application-git.d.ts.map +1 -0
- package/dist/application-git.js +57 -0
- package/dist/baseline.d.ts +22 -0
- package/dist/baseline.d.ts.map +1 -0
- package/dist/baseline.js +90 -0
- package/dist/cli.js +5 -18
- package/dist/commands.d.ts +22 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +197 -0
- package/dist/composition-lint.d.ts +20 -0
- package/dist/composition-lint.d.ts.map +1 -0
- package/dist/composition-lint.js +288 -0
- package/dist/composition.d.ts +24 -0
- package/dist/composition.d.ts.map +1 -0
- package/dist/composition.js +420 -0
- package/dist/create-command.d.ts +21 -0
- package/dist/create-command.d.ts.map +1 -0
- package/dist/create-command.js +128 -0
- package/dist/demo-instrumentation.d.ts +5 -0
- package/dist/demo-instrumentation.d.ts.map +1 -0
- package/dist/demo-instrumentation.js +300 -0
- package/dist/environment.d.ts +7 -0
- package/dist/environment.d.ts.map +1 -0
- package/dist/environment.js +81 -0
- package/dist/errors.d.ts +156 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +140 -0
- package/dist/file-policy.d.ts +6 -0
- package/dist/file-policy.d.ts.map +1 -0
- package/dist/file-policy.js +38 -0
- package/dist/files.d.ts +7 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +66 -0
- package/dist/hosting.d.ts +5 -0
- package/dist/hosting.d.ts.map +1 -0
- package/dist/hosting.js +107 -0
- package/dist/index.d.ts +4 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -89
- package/dist/initialization.d.ts +14 -0
- package/dist/initialization.d.ts.map +1 -0
- package/dist/initialization.js +266 -0
- package/dist/lint-workspaces.d.ts +2 -0
- package/dist/lint-workspaces.d.ts.map +1 -0
- package/dist/lint-workspaces.js +62 -0
- package/dist/model.d.ts +143 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +61 -0
- package/dist/package-catalog.d.ts +8 -0
- package/dist/package-catalog.d.ts.map +1 -0
- package/dist/package-catalog.js +61 -0
- package/dist/packages.d.ts +57 -0
- package/dist/packages.d.ts.map +1 -0
- package/dist/packages.js +237 -0
- package/dist/process-group.d.ts +5 -0
- package/dist/process-group.d.ts.map +1 -0
- package/dist/process-group.js +23 -0
- package/dist/reference-workspace-bindings.d.ts +38 -0
- package/dist/reference-workspace-bindings.d.ts.map +1 -0
- package/dist/reference-workspace-bindings.js +41 -0
- package/dist/reference-workspace.d.ts +6 -0
- package/dist/reference-workspace.d.ts.map +1 -0
- package/dist/reference-workspace.js +62 -0
- package/dist/registry.d.ts +187 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +107 -0
- package/dist/runtime.d.ts +9 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +22 -0
- package/dist/selection.d.ts +704 -0
- package/dist/selection.d.ts.map +1 -0
- package/dist/selection.js +424 -0
- package/dist/shadcn-protocol.d.ts +22 -0
- package/dist/shadcn-protocol.d.ts.map +1 -0
- package/dist/shadcn-protocol.js +13 -0
- package/dist/shadcn-worker.d.ts +2 -0
- package/dist/shadcn-worker.d.ts.map +1 -0
- package/dist/shadcn-worker.js +43 -0
- package/dist/shadcn.d.ts +22 -0
- package/dist/shadcn.d.ts.map +1 -0
- package/dist/shadcn.js +101 -0
- package/dist/source-changes.d.ts +55 -0
- package/dist/source-changes.d.ts.map +1 -0
- package/dist/source-changes.js +225 -0
- package/dist/source-inventory.d.ts +25 -0
- package/dist/source-inventory.d.ts.map +1 -0
- package/dist/source-inventory.js +212 -0
- package/dist/source-root.d.ts +4 -0
- package/dist/source-root.d.ts.map +1 -0
- package/dist/source-root.js +20 -0
- package/dist/staging.d.ts +19 -0
- package/dist/staging.d.ts.map +1 -0
- package/dist/staging.js +42 -0
- package/dist/tasks.d.ts +44 -0
- package/dist/tasks.d.ts.map +1 -0
- package/dist/tasks.js +137 -0
- package/dist/templates.d.ts +217 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/templates.js +161 -0
- package/dist/test-reference-workspace.d.ts +2 -0
- package/dist/test-reference-workspace.d.ts.map +1 -0
- package/dist/test-reference-workspace.js +6 -0
- package/dist/types.d.ts +2 -9
- package/dist/types.d.ts.map +1 -1
- package/dist/typescript-paths.d.ts +10 -0
- package/dist/typescript-paths.d.ts.map +1 -0
- package/dist/typescript-paths.js +52 -0
- package/dist/workspace-dependencies.d.ts +26 -0
- package/dist/workspace-dependencies.d.ts.map +1 -0
- package/dist/workspace-dependencies.js +478 -0
- package/dist/workspace-files.d.ts +24 -0
- package/dist/workspace-files.d.ts.map +1 -0
- package/dist/workspace-files.js +395 -0
- package/dist/workspace-lock.d.ts +12 -0
- package/dist/workspace-lock.d.ts.map +1 -0
- package/dist/workspace-lock.js +104 -0
- package/dist/workspace-snapshots.d.ts +24 -0
- package/dist/workspace-snapshots.d.ts.map +1 -0
- package/dist/workspace-snapshots.js +218 -0
- package/dist/workspace-sources.d.ts +27 -0
- package/dist/workspace-sources.d.ts.map +1 -0
- package/dist/workspace-sources.js +88 -0
- package/dist/workspace-state.d.ts +325 -0
- package/dist/workspace-state.d.ts.map +1 -0
- package/dist/workspace-state.js +571 -0
- package/dist/workspaces.d.ts +73 -0
- package/dist/workspaces.d.ts.map +1 -0
- package/dist/workspaces.js +396 -0
- package/package.json +27 -20
- package/schema/selection-definition.json +143 -4
- package/dist/clone.d.ts +0 -9
- package/dist/clone.d.ts.map +0 -1
- package/dist/clone.js +0 -19
- package/dist/composition/add.d.ts +0 -14
- package/dist/composition/add.d.ts.map +0 -1
- package/dist/composition/add.js +0 -484
- package/dist/composition/catalog.d.ts +0 -26
- package/dist/composition/catalog.d.ts.map +0 -1
- package/dist/composition/catalog.js +0 -317
- package/dist/composition/errors.d.ts +0 -5
- package/dist/composition/errors.d.ts.map +0 -1
- package/dist/composition/errors.js +0 -8
- package/dist/composition/format.d.ts +0 -6
- package/dist/composition/format.d.ts.map +0 -1
- package/dist/composition/format.js +0 -65
- package/dist/composition/install.d.ts +0 -16
- package/dist/composition/install.d.ts.map +0 -1
- package/dist/composition/install.js +0 -175
- package/dist/composition/packages.d.ts +0 -6
- package/dist/composition/packages.d.ts.map +0 -1
- package/dist/composition/packages.js +0 -55
- package/dist/composition/paths.d.ts +0 -4
- package/dist/composition/paths.d.ts.map +0 -1
- package/dist/composition/paths.js +0 -47
- package/dist/composition/planner.d.ts +0 -4
- package/dist/composition/planner.d.ts.map +0 -1
- package/dist/composition/planner.js +0 -366
- package/dist/composition/schema.d.ts +0 -294
- package/dist/composition/schema.d.ts.map +0 -1
- package/dist/composition/schema.js +0 -166
- package/dist/composition/types.d.ts +0 -111
- package/dist/composition/types.d.ts.map +0 -1
- package/dist/composition/types.js +0 -6
- package/dist/composition/typescript-paths.d.ts +0 -6
- package/dist/composition/typescript-paths.d.ts.map +0 -1
- package/dist/composition/typescript-paths.js +0 -157
- package/dist/composition/use.d.ts +0 -23
- package/dist/composition/use.d.ts.map +0 -1
- package/dist/composition/use.js +0 -187
- package/dist/composition/workspace.d.ts +0 -10
- package/dist/composition/workspace.d.ts.map +0 -1
- package/dist/composition/workspace.js +0 -210
- package/dist/constants.d.ts +0 -11
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js +0 -39
- package/dist/fs-utils.d.ts +0 -9
- package/dist/fs-utils.d.ts.map +0 -1
- package/dist/fs-utils.js +0 -64
- package/dist/git.d.ts +0 -28
- package/dist/git.d.ts.map +0 -1
- package/dist/git.js +0 -107
- package/dist/instruction-renderer.d.ts +0 -17
- package/dist/instruction-renderer.d.ts.map +0 -1
- package/dist/instruction-renderer.js +0 -132
- package/dist/logger.d.ts +0 -13
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -26
- package/dist/prompts.d.ts +0 -7
- package/dist/prompts.d.ts.map +0 -1
- package/dist/prompts.js +0 -54
- package/dist/sanitize.d.ts +0 -10
- package/dist/sanitize.d.ts.map +0 -1
- package/dist/sanitize.js +0 -110
- package/dist/scaffold.d.ts +0 -7
- package/dist/scaffold.d.ts.map +0 -1
- package/dist/scaffold.js +0 -330
- package/dist/version.d.ts +0 -2
- package/dist/version.d.ts.map +0 -1
- package/dist/version.js +0 -2
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { Effect, FileSystem, Path } from "effect";
|
|
2
|
+
import { DestinationNotEmpty, InvalidComposition, SourceChanged, } from "./errors.js";
|
|
3
|
+
import { cacheDirectories, isEnvironmentFile } from "./file-policy.js";
|
|
4
|
+
import { relativeFile } from "./files.js";
|
|
5
|
+
// A wildcard represents exactly one directory, never a recursive file pattern.
|
|
6
|
+
// Ownership and initial Git visibility are derived from the same declaration.
|
|
7
|
+
const settings = [
|
|
8
|
+
{
|
|
9
|
+
directory: [],
|
|
10
|
+
files: {
|
|
11
|
+
".gitignore": "ignore",
|
|
12
|
+
"README.md": "readme",
|
|
13
|
+
"next-hydra.json": "definition",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
directory: ["apps", "*"],
|
|
18
|
+
files: { ".gitignore": "ignore", "vercel.json": "deployment" },
|
|
19
|
+
},
|
|
20
|
+
];
|
|
21
|
+
export function workspaceSetting(target) {
|
|
22
|
+
const parts = target.split("/");
|
|
23
|
+
const name = parts.pop();
|
|
24
|
+
if (!name) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
const group = settings.find(({ directory }) => directory.length === parts.length &&
|
|
28
|
+
directory.every((segment, index) => segment === "*" ? Boolean(parts[index]) : segment === parts[index]));
|
|
29
|
+
return group && Object.hasOwn(group.files, name)
|
|
30
|
+
? group.files[name]
|
|
31
|
+
: undefined;
|
|
32
|
+
}
|
|
33
|
+
export const validatePreservedFiles = Effect.fn("Workspaces.validatePreservedFiles")(function* (targets) {
|
|
34
|
+
const unique = new Set(targets);
|
|
35
|
+
for (const target of targets) {
|
|
36
|
+
const normalized = yield* relativeFile(target);
|
|
37
|
+
const parts = target.split("/");
|
|
38
|
+
if (normalized !== target ||
|
|
39
|
+
/[*?\[\]{}!\r\n]/u.test(target) ||
|
|
40
|
+
target.startsWith(".workspace-composition") ||
|
|
41
|
+
workspaceSetting(target) !== undefined ||
|
|
42
|
+
isEnvironmentFile(target) ||
|
|
43
|
+
parts.some((part) => cacheDirectories.has(part)) ||
|
|
44
|
+
parts.some((_, index) => {
|
|
45
|
+
const ancestor = parts.slice(0, index).join("/");
|
|
46
|
+
return (unique.has(ancestor) ||
|
|
47
|
+
workspaceSetting(ancestor) !== undefined ||
|
|
48
|
+
isEnvironmentFile(ancestor));
|
|
49
|
+
})) {
|
|
50
|
+
return yield* new InvalidComposition({
|
|
51
|
+
message: `Expected an exact application file in preserve: ${target}`,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (unique.size !== targets.length) {
|
|
56
|
+
return yield* new InvalidComposition({
|
|
57
|
+
message: "Preserve paths must be unique",
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
function namedIgnoreRules(preserve) {
|
|
62
|
+
const rules = new Set([
|
|
63
|
+
"# Commit workspace settings and generated Turbo config; Compose owns the materialized application.",
|
|
64
|
+
"/*",
|
|
65
|
+
]);
|
|
66
|
+
const allow = new Set(["!/turbo.json"]);
|
|
67
|
+
for (const { directory, files } of settings) {
|
|
68
|
+
let prefix = "/";
|
|
69
|
+
for (const segment of directory) {
|
|
70
|
+
prefix += `${segment}/`;
|
|
71
|
+
rules.add(`!${prefix}`);
|
|
72
|
+
rules.add(`${prefix}*`);
|
|
73
|
+
}
|
|
74
|
+
for (const name of Object.keys(files)) {
|
|
75
|
+
allow.add(`!${prefix}${name}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
for (const target of preserve) {
|
|
79
|
+
const parts = target.split("/");
|
|
80
|
+
for (let end = 1; end < parts.length; end += 1) {
|
|
81
|
+
const prefix = `/${parts.slice(0, end).join("/")}/`;
|
|
82
|
+
rules.add(`!${prefix}`);
|
|
83
|
+
rules.add(`${prefix}*`);
|
|
84
|
+
}
|
|
85
|
+
allow.add(`!/${target}`);
|
|
86
|
+
}
|
|
87
|
+
return `${[...rules, ...allow].join("\n")}\n`;
|
|
88
|
+
}
|
|
89
|
+
export const namedInitializationFiles = Effect.fn("Workspaces.namedInitializationFiles")(function* (files, preserved, preserve = []) {
|
|
90
|
+
const targets = new Set(files.map((file) => file.target));
|
|
91
|
+
for (const target of preserved) {
|
|
92
|
+
if (workspaceSetting(target) === "deployment" &&
|
|
93
|
+
!targets.has(`${target.slice(0, target.lastIndexOf("/"))}/package.json`)) {
|
|
94
|
+
return yield* new InvalidComposition({
|
|
95
|
+
message: `Deployment settings target an unselected application: ${target}`,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const output = [];
|
|
100
|
+
for (const file of files) {
|
|
101
|
+
const parts = file.target.split("/");
|
|
102
|
+
if (parts[0]?.startsWith(".workspace-composition")) {
|
|
103
|
+
return yield* new InvalidComposition({
|
|
104
|
+
message: `Composition cannot own workspace state: ${file.target}`,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
if (parts.some((part) => cacheDirectories.has(part))) {
|
|
108
|
+
return yield* new InvalidComposition({
|
|
109
|
+
message: `Composition cannot own cache paths: ${file.target}`,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
for (let end = 1; end < parts.length; end += 1) {
|
|
113
|
+
const ancestor = parts.slice(0, end).join("/");
|
|
114
|
+
if (workspaceSetting(ancestor) || isEnvironmentFile(ancestor)) {
|
|
115
|
+
return yield* new InvalidComposition({
|
|
116
|
+
message: `Composition cannot write below workspace settings: ${file.target}`,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const setting = workspaceSetting(file.target);
|
|
121
|
+
if (setting === "ignore" || setting === "deployment") {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (setting !== undefined) {
|
|
125
|
+
return yield* new InvalidComposition({
|
|
126
|
+
message: `Composition cannot own workspace settings: ${file.target}`,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
output.push(file);
|
|
130
|
+
}
|
|
131
|
+
if (!preserved.has(".gitignore")) {
|
|
132
|
+
output.push({
|
|
133
|
+
content: new TextEncoder().encode(namedIgnoreRules(preserve)),
|
|
134
|
+
mode: 0o644,
|
|
135
|
+
origin: { kind: "policy", policy: "application-ignore", sources: [] },
|
|
136
|
+
target: ".gitignore",
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return output;
|
|
140
|
+
});
|
|
141
|
+
export const listUnregisteredFiles = Effect.fn("Workspaces.listUnregisteredFiles")(function* (destination, owned) {
|
|
142
|
+
const fs = yield* FileSystem.FileSystem;
|
|
143
|
+
const path = yield* Path.Path;
|
|
144
|
+
const unexpected = [];
|
|
145
|
+
if (!(yield* fs.exists(destination))) {
|
|
146
|
+
return unexpected;
|
|
147
|
+
}
|
|
148
|
+
if ((yield* fs.stat(destination)).type !== "Directory") {
|
|
149
|
+
return yield* new DestinationNotEmpty({ directory: destination });
|
|
150
|
+
}
|
|
151
|
+
const pending = [""];
|
|
152
|
+
while (pending.length) {
|
|
153
|
+
const directory = pending.pop();
|
|
154
|
+
if (directory === undefined) {
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
for (const name of yield* fs.readDirectory(path.join(destination, directory))) {
|
|
158
|
+
const target = directory ? `${directory}/${name}` : name;
|
|
159
|
+
const stat = yield* fs.stat(path.join(destination, target));
|
|
160
|
+
if (target === ".git") {
|
|
161
|
+
unexpected.push(target);
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (([
|
|
165
|
+
".workspace-composition.lock",
|
|
166
|
+
".workspace-composition.recovery",
|
|
167
|
+
].includes(target) &&
|
|
168
|
+
stat.type === "Directory") ||
|
|
169
|
+
(target === ".workspace-composition.json" && stat.type === "File")) {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
if (owned.has(target)) {
|
|
173
|
+
if (stat.type !== "File") {
|
|
174
|
+
unexpected.push(target);
|
|
175
|
+
}
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
if (cacheDirectories.has(name)) {
|
|
179
|
+
if (stat.type !== "Directory") {
|
|
180
|
+
unexpected.push(target);
|
|
181
|
+
}
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
if (workspaceSetting(target) || isEnvironmentFile(target)) {
|
|
185
|
+
if (stat.type !== "File") {
|
|
186
|
+
unexpected.push(target);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
else if (stat.type === "Directory") {
|
|
190
|
+
pending.push(target);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
unexpected.push(target);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return unexpected;
|
|
198
|
+
});
|
|
199
|
+
const settingDirectories = Effect.fn("Workspaces.settingDirectories")(function* (destination, pattern) {
|
|
200
|
+
const fs = yield* FileSystem.FileSystem;
|
|
201
|
+
const path = yield* Path.Path;
|
|
202
|
+
let directories = [""];
|
|
203
|
+
for (const segment of pattern) {
|
|
204
|
+
const next = [];
|
|
205
|
+
for (const directory of directories) {
|
|
206
|
+
const names = segment === "*"
|
|
207
|
+
? yield* fs.readDirectory(path.join(destination, directory))
|
|
208
|
+
: [segment];
|
|
209
|
+
for (const name of names) {
|
|
210
|
+
const target = directory ? `${directory}/${name}` : name;
|
|
211
|
+
const absolute = path.join(destination, target);
|
|
212
|
+
if ((yield* fs.exists(absolute)) &&
|
|
213
|
+
(yield* fs.stat(absolute)).type === "Directory") {
|
|
214
|
+
next.push(target);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
directories = next;
|
|
219
|
+
}
|
|
220
|
+
return directories;
|
|
221
|
+
});
|
|
222
|
+
export const inspectInitialization = Effect.fn("Workspaces.inspectInitialization")(function* (destination, definition) {
|
|
223
|
+
const fs = yield* FileSystem.FileSystem;
|
|
224
|
+
const path = yield* Path.Path;
|
|
225
|
+
const preserved = new Set();
|
|
226
|
+
if (!(yield* fs.exists(destination))) {
|
|
227
|
+
if (definition !== undefined) {
|
|
228
|
+
return yield* new SourceChanged({ paths: ["next-hydra.json"] });
|
|
229
|
+
}
|
|
230
|
+
return preserved;
|
|
231
|
+
}
|
|
232
|
+
if ((yield* fs.stat(destination)).type !== "Directory") {
|
|
233
|
+
return yield* new DestinationNotEmpty({ directory: destination });
|
|
234
|
+
}
|
|
235
|
+
if (definition === undefined) {
|
|
236
|
+
if ((yield* fs.readDirectory(destination)).length) {
|
|
237
|
+
return yield* new DestinationNotEmpty({ directory: destination });
|
|
238
|
+
}
|
|
239
|
+
return preserved;
|
|
240
|
+
}
|
|
241
|
+
if (yield* fs.exists(path.join(destination, ".git"))) {
|
|
242
|
+
return yield* new DestinationNotEmpty({ directory: destination });
|
|
243
|
+
}
|
|
244
|
+
// Probe declared settings directly; unrelated output need not be readable.
|
|
245
|
+
// WorkspaceFiles separately verifies owned files and publication targets.
|
|
246
|
+
for (const group of settings) {
|
|
247
|
+
for (const directory of yield* settingDirectories(destination, group.directory)) {
|
|
248
|
+
for (const name of Object.keys(group.files)) {
|
|
249
|
+
const target = directory ? `${directory}/${name}` : name;
|
|
250
|
+
const absolute = path.join(destination, target);
|
|
251
|
+
if (!(yield* fs.exists(absolute))) {
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
if ((yield* fs.stat(absolute)).type !== "File") {
|
|
255
|
+
return yield* new DestinationNotEmpty({ directory: destination });
|
|
256
|
+
}
|
|
257
|
+
preserved.add(target);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if ((yield* fs.readFileString(path.join(destination, "next-hydra.json"))) !==
|
|
262
|
+
definition) {
|
|
263
|
+
return yield* new SourceChanged({ paths: ["next-hydra.json"] });
|
|
264
|
+
}
|
|
265
|
+
return preserved;
|
|
266
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lint-workspaces.d.ts","sourceRoot":"","sources":["../src/lint-workspaces.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { NodeRuntime } from "@effect/platform-node";
|
|
2
|
+
import { Console, Effect, Path, Schema } from "effect";
|
|
3
|
+
import { affectedLintWorkspaces, executeLintCommand, lintCompositions, } from "./composition-lint.js";
|
|
4
|
+
import { InvalidComposition } from "./errors.js";
|
|
5
|
+
import { runtime } from "./runtime.js";
|
|
6
|
+
import { findSourceRoot } from "./source-root.js";
|
|
7
|
+
const program = Effect.gen(function* () {
|
|
8
|
+
const root = yield* findSourceRoot(process.cwd());
|
|
9
|
+
const path = yield* Path.Path;
|
|
10
|
+
const args = process.argv.slice(2);
|
|
11
|
+
const selections = args.filter((arg) => arg === "--source" || arg.startsWith("--workspace="));
|
|
12
|
+
const positional = args.filter((arg) => !arg.startsWith("--"));
|
|
13
|
+
const revisions = args.filter((arg) => arg.startsWith("--changed-from="));
|
|
14
|
+
const invalid = args.filter((arg) => arg.startsWith("--") &&
|
|
15
|
+
!["--staged", "--list", ...selections, ...revisions].includes(arg));
|
|
16
|
+
if (invalid.length > 0 ||
|
|
17
|
+
selections.length > 1 ||
|
|
18
|
+
selections.includes("--workspace=") ||
|
|
19
|
+
revisions.length > 1 ||
|
|
20
|
+
(revisions.length > 0 &&
|
|
21
|
+
(args.includes("--staged") || positional.length > 0)) ||
|
|
22
|
+
revisions.some((arg) => !/^[a-f\d]{40,64}$/u.test(arg.slice("--changed-from=".length))) ||
|
|
23
|
+
(args.includes("--list") &&
|
|
24
|
+
(selections.length > 0 || args.includes("--staged"))) ||
|
|
25
|
+
(args.includes("--staged") && positional.length > 0)) {
|
|
26
|
+
return yield* new InvalidComposition({
|
|
27
|
+
message: "Usage: lint-workspaces.js [--source | --workspace=<name>] [--staged | --changed-from=<commit-sha> | files...] or --list [--changed-from=<commit-sha> | files...]",
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
const [selection] = selections;
|
|
31
|
+
let scope = { kind: "all" };
|
|
32
|
+
if (selection === "--source") {
|
|
33
|
+
scope = { kind: "source" };
|
|
34
|
+
}
|
|
35
|
+
else if (selection !== undefined) {
|
|
36
|
+
scope = { kind: "workspace", name: selection.slice("--workspace=".length) };
|
|
37
|
+
}
|
|
38
|
+
const staged = args.includes("--staged");
|
|
39
|
+
const revision = revisions[0]?.slice("--changed-from=".length);
|
|
40
|
+
const files = staged || revision !== undefined
|
|
41
|
+
? (yield* executeLintCommand(root, "git", [
|
|
42
|
+
"diff",
|
|
43
|
+
...(staged ? ["--cached"] : []),
|
|
44
|
+
...(args.includes("--list") ? ["--no-renames"] : []),
|
|
45
|
+
"--name-only",
|
|
46
|
+
args.includes("--list")
|
|
47
|
+
? "--diff-filter=ACMRD"
|
|
48
|
+
: "--diff-filter=ACMR",
|
|
49
|
+
"-z",
|
|
50
|
+
...(revision === undefined ? [] : [revision, "HEAD", "--"]),
|
|
51
|
+
]))
|
|
52
|
+
.split("\0")
|
|
53
|
+
.filter(Boolean)
|
|
54
|
+
: positional.map((file) => path.relative(root, path.resolve(file)));
|
|
55
|
+
if (args.includes("--list")) {
|
|
56
|
+
const names = yield* affectedLintWorkspaces(root, revision !== undefined || positional.length > 0 ? files : undefined);
|
|
57
|
+
yield* Console.log(yield* Schema.encodeEffect(Schema.fromJsonString(Schema.Array(Schema.String)))(names));
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
yield* lintCompositions(root, staged || revision !== undefined || files.length > 0 ? files : undefined, scope);
|
|
61
|
+
});
|
|
62
|
+
NodeRuntime.runMain(program.pipe(Effect.provide(runtime)));
|
package/dist/model.d.ts
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
export declare const Selection: Schema.Struct<{
|
|
3
|
+
readonly addOns: Schema.withDecodingDefaultKey<Schema.$Array<Schema.NonEmptyString>, never>;
|
|
4
|
+
readonly providers: Schema.withDecodingDefaultKey<Schema.Struct<{
|
|
5
|
+
readonly auth: Schema.optionalKey<Schema.NonEmptyString>;
|
|
6
|
+
readonly cms: Schema.optionalKey<Schema.NonEmptyString>;
|
|
7
|
+
readonly commerce: Schema.optionalKey<Schema.NonEmptyString>;
|
|
8
|
+
readonly search: Schema.optionalKey<Schema.NonEmptyString>;
|
|
9
|
+
}>, never>;
|
|
10
|
+
}>;
|
|
11
|
+
export type Selection = typeof Selection.Type;
|
|
12
|
+
export declare const SelectionRequest: Schema.Union<readonly [Schema.Struct<{
|
|
13
|
+
readonly addOns: Schema.withDecodingDefaultKey<Schema.$Array<Schema.NonEmptyString>, never>;
|
|
14
|
+
readonly providers: Schema.withDecodingDefaultKey<Schema.Struct<{
|
|
15
|
+
readonly auth: Schema.optionalKey<Schema.NonEmptyString>;
|
|
16
|
+
readonly cms: Schema.optionalKey<Schema.NonEmptyString>;
|
|
17
|
+
readonly commerce: Schema.optionalKey<Schema.NonEmptyString>;
|
|
18
|
+
readonly search: Schema.optionalKey<Schema.NonEmptyString>;
|
|
19
|
+
}>, never>;
|
|
20
|
+
}>, Schema.Struct<{
|
|
21
|
+
readonly addOns: Schema.withDecodingDefaultKey<Schema.$Array<Schema.NonEmptyString>, never>;
|
|
22
|
+
readonly preset: Schema.NonEmptyString;
|
|
23
|
+
}>]>;
|
|
24
|
+
export type SelectionRequest = typeof SelectionRequest.Type;
|
|
25
|
+
export declare const DevelopmentPort: Schema.Finite;
|
|
26
|
+
export declare const WorkspaceDefinition: Schema.Struct<{
|
|
27
|
+
readonly demo: Schema.optionalKey<Schema.Struct<{
|
|
28
|
+
readonly architecture: Schema.Boolean;
|
|
29
|
+
}>>;
|
|
30
|
+
readonly development: Schema.optionalKey<Schema.Struct<{
|
|
31
|
+
readonly port: Schema.optionalKey<Schema.Finite>;
|
|
32
|
+
}>>;
|
|
33
|
+
readonly preserve: Schema.withDecodingDefaultKey<Schema.$Array<Schema.NonEmptyString>, never>;
|
|
34
|
+
readonly addOns: Schema.withDecodingDefaultKey<Schema.$Array<Schema.NonEmptyString>, never>;
|
|
35
|
+
readonly providers: Schema.withDecodingDefaultKey<Schema.Struct<{
|
|
36
|
+
readonly auth: Schema.optionalKey<Schema.NonEmptyString>;
|
|
37
|
+
readonly cms: Schema.optionalKey<Schema.NonEmptyString>;
|
|
38
|
+
readonly commerce: Schema.optionalKey<Schema.NonEmptyString>;
|
|
39
|
+
readonly search: Schema.optionalKey<Schema.NonEmptyString>;
|
|
40
|
+
}>, never>;
|
|
41
|
+
}>;
|
|
42
|
+
export interface PreparedFile {
|
|
43
|
+
readonly target: string;
|
|
44
|
+
readonly content: Uint8Array;
|
|
45
|
+
readonly mode: number;
|
|
46
|
+
}
|
|
47
|
+
export interface PreparedWorkspace {
|
|
48
|
+
readonly files: readonly (PreparedFile & {
|
|
49
|
+
readonly origin: FileOrigin;
|
|
50
|
+
})[];
|
|
51
|
+
readonly instructions: readonly RegistryInstruction[];
|
|
52
|
+
readonly inputs: SourceInputs;
|
|
53
|
+
}
|
|
54
|
+
export interface RegistryInstruction {
|
|
55
|
+
readonly item: string;
|
|
56
|
+
readonly text: string;
|
|
57
|
+
}
|
|
58
|
+
export interface SourceInputs {
|
|
59
|
+
readonly files: readonly string[];
|
|
60
|
+
readonly packagePatterns: readonly string[];
|
|
61
|
+
readonly packages: readonly string[];
|
|
62
|
+
readonly excluded: readonly string[];
|
|
63
|
+
}
|
|
64
|
+
export declare const FileOrigin: Schema.Union<readonly [Schema.Struct<{
|
|
65
|
+
readonly kind: Schema.Literal<"registry">;
|
|
66
|
+
readonly owner: Schema.String;
|
|
67
|
+
readonly transforms: Schema.optionalKey<Schema.$Array<Schema.Literal<"remove-demo-architecture">>>;
|
|
68
|
+
}>, Schema.Struct<{
|
|
69
|
+
readonly kind: Schema.Literal<"workspace-setting">;
|
|
70
|
+
readonly source: Schema.String;
|
|
71
|
+
}>, Schema.Struct<{
|
|
72
|
+
readonly kind: Schema.Literal<"source">;
|
|
73
|
+
readonly transforms: Schema.optionalKey<Schema.$Array<Schema.Literal<"remove-demo-architecture">>>;
|
|
74
|
+
readonly owner: Schema.NullOr<Schema.String>;
|
|
75
|
+
readonly source: Schema.String;
|
|
76
|
+
}>, Schema.Struct<{
|
|
77
|
+
readonly bindings: Schema.$Array<Schema.Struct<{
|
|
78
|
+
readonly owner: Schema.String;
|
|
79
|
+
readonly as: Schema.optionalKey<Schema.String>;
|
|
80
|
+
readonly export: Schema.String;
|
|
81
|
+
readonly module: Schema.NonEmptyString;
|
|
82
|
+
readonly order: Schema.optionalKey<Schema.Int>;
|
|
83
|
+
readonly slot: Schema.NonEmptyString;
|
|
84
|
+
readonly target: Schema.NonEmptyString;
|
|
85
|
+
}>>;
|
|
86
|
+
readonly kind: Schema.Literal<"template">;
|
|
87
|
+
readonly transforms: Schema.optionalKey<Schema.$Array<Schema.Literal<"remove-demo-architecture">>>;
|
|
88
|
+
readonly owner: Schema.String;
|
|
89
|
+
readonly source: Schema.String;
|
|
90
|
+
}>, Schema.Struct<{
|
|
91
|
+
readonly kind: Schema.Literal<"policy">;
|
|
92
|
+
readonly policy: Schema.Literals<readonly ["application-manifest", "workspace-settings", "lockfile-seed", "application-tasks", "application-ignore"]>;
|
|
93
|
+
readonly sources: Schema.$Array<Schema.String>;
|
|
94
|
+
}>]>;
|
|
95
|
+
export type FileOrigin = typeof FileOrigin.Type;
|
|
96
|
+
export interface FileExplanation {
|
|
97
|
+
readonly target: string;
|
|
98
|
+
readonly origin: FileOrigin;
|
|
99
|
+
}
|
|
100
|
+
export interface ExplanationReport {
|
|
101
|
+
readonly sourceRoot: string;
|
|
102
|
+
readonly destination: string;
|
|
103
|
+
readonly files: readonly FileExplanation[];
|
|
104
|
+
}
|
|
105
|
+
export interface MaterializationReport {
|
|
106
|
+
readonly instructions: readonly RegistryInstruction[];
|
|
107
|
+
readonly origins: readonly FileExplanation[];
|
|
108
|
+
readonly git?: {
|
|
109
|
+
readonly initialized: boolean;
|
|
110
|
+
readonly committed: boolean;
|
|
111
|
+
readonly warning?: string;
|
|
112
|
+
};
|
|
113
|
+
readonly recoveryEvidence?: string | null;
|
|
114
|
+
readonly environmentFilesCreated: readonly string[];
|
|
115
|
+
readonly destination: string;
|
|
116
|
+
readonly files: readonly string[];
|
|
117
|
+
readonly removedFiles: readonly string[];
|
|
118
|
+
readonly dependencies: "pending" | "current";
|
|
119
|
+
readonly dependencyReasons: readonly string[];
|
|
120
|
+
}
|
|
121
|
+
export interface FileChange {
|
|
122
|
+
readonly target: string;
|
|
123
|
+
readonly kind: "create" | "update" | "remove" | "record" | "conflict" | "unregistered" | "setting";
|
|
124
|
+
}
|
|
125
|
+
export interface CheckReport {
|
|
126
|
+
readonly destination: string;
|
|
127
|
+
readonly initialized: boolean;
|
|
128
|
+
readonly ready: boolean;
|
|
129
|
+
readonly changes: readonly FileChange[];
|
|
130
|
+
}
|
|
131
|
+
export interface DiffReport {
|
|
132
|
+
readonly origins: readonly FileExplanation[];
|
|
133
|
+
readonly snapshot: string;
|
|
134
|
+
readonly incomplete: boolean;
|
|
135
|
+
readonly patch: string;
|
|
136
|
+
readonly changes: readonly {
|
|
137
|
+
readonly target: string;
|
|
138
|
+
readonly status: string;
|
|
139
|
+
}[];
|
|
140
|
+
readonly unregisteredFiles: readonly string[];
|
|
141
|
+
readonly conflicts: readonly string[];
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
|
package/dist/model.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import { Binding } from "./templates.js";
|
|
3
|
+
export const Selection = Schema.Struct({
|
|
4
|
+
addOns: Schema.Array(Schema.NonEmptyString).pipe(Schema.withDecodingDefaultKey(Effect.succeed([]))),
|
|
5
|
+
providers: Schema.Struct({
|
|
6
|
+
auth: Schema.optionalKey(Schema.NonEmptyString),
|
|
7
|
+
cms: Schema.optionalKey(Schema.NonEmptyString),
|
|
8
|
+
commerce: Schema.optionalKey(Schema.NonEmptyString),
|
|
9
|
+
search: Schema.optionalKey(Schema.NonEmptyString),
|
|
10
|
+
}).pipe(Schema.withDecodingDefaultKey(Effect.succeed({}))),
|
|
11
|
+
});
|
|
12
|
+
export const SelectionRequest = Schema.Union([
|
|
13
|
+
Selection,
|
|
14
|
+
Schema.Struct({
|
|
15
|
+
addOns: Selection.fields.addOns,
|
|
16
|
+
preset: Schema.NonEmptyString,
|
|
17
|
+
}),
|
|
18
|
+
]);
|
|
19
|
+
export const DevelopmentPort = Schema.Finite.check(Schema.isInt(), Schema.isBetween({ maximum: 65_533, minimum: 1024 }));
|
|
20
|
+
export const WorkspaceDefinition = Schema.Struct({
|
|
21
|
+
...Selection.fields,
|
|
22
|
+
demo: Schema.optionalKey(Schema.Struct({ architecture: Schema.Boolean })),
|
|
23
|
+
development: Schema.optionalKey(Schema.Struct({ port: Schema.optionalKey(DevelopmentPort) })),
|
|
24
|
+
preserve: Schema.Array(Schema.NonEmptyString).pipe(Schema.withDecodingDefaultKey(Effect.succeed([]))),
|
|
25
|
+
});
|
|
26
|
+
const SourceTransforms = Schema.optionalKey(Schema.Array(Schema.Literal("remove-demo-architecture")));
|
|
27
|
+
export const FileOrigin = Schema.Union([
|
|
28
|
+
Schema.Struct({
|
|
29
|
+
kind: Schema.Literal("registry"),
|
|
30
|
+
owner: Schema.String,
|
|
31
|
+
transforms: SourceTransforms,
|
|
32
|
+
}),
|
|
33
|
+
Schema.Struct({
|
|
34
|
+
kind: Schema.Literal("workspace-setting"),
|
|
35
|
+
source: Schema.String,
|
|
36
|
+
}),
|
|
37
|
+
Schema.Struct({
|
|
38
|
+
kind: Schema.Literal("source"),
|
|
39
|
+
transforms: SourceTransforms,
|
|
40
|
+
owner: Schema.NullOr(Schema.String),
|
|
41
|
+
source: Schema.String,
|
|
42
|
+
}),
|
|
43
|
+
Schema.Struct({
|
|
44
|
+
bindings: Schema.Array(Schema.Struct({ ...Binding.fields, owner: Schema.String })),
|
|
45
|
+
kind: Schema.Literal("template"),
|
|
46
|
+
transforms: SourceTransforms,
|
|
47
|
+
owner: Schema.String,
|
|
48
|
+
source: Schema.String,
|
|
49
|
+
}),
|
|
50
|
+
Schema.Struct({
|
|
51
|
+
kind: Schema.Literal("policy"),
|
|
52
|
+
policy: Schema.Literals([
|
|
53
|
+
"application-manifest",
|
|
54
|
+
"workspace-settings",
|
|
55
|
+
"lockfile-seed",
|
|
56
|
+
"application-tasks",
|
|
57
|
+
"application-ignore",
|
|
58
|
+
]),
|
|
59
|
+
sources: Schema.Array(Schema.String),
|
|
60
|
+
}),
|
|
61
|
+
]);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function packageManifestMatcher(sourcePatterns: readonly string[]): (file: string) => boolean;
|
|
2
|
+
export declare function applicationPackagePatterns(sourcePatterns: readonly string[], targets: ReadonlySet<string>): readonly string[];
|
|
3
|
+
export declare function packageCatalog(files: readonly string[], sourcePatterns: readonly string[]): {
|
|
4
|
+
manifests: string[];
|
|
5
|
+
matchesManifest: (file: string) => boolean;
|
|
6
|
+
patterns: readonly string[];
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=package-catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-catalog.d.ts","sourceRoot":"","sources":["../src/package-catalog.ts"],"names":[],"mappings":"AAuBA,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,SAAS,MAAM,EAAE,GAChC,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAgB3B;AAED,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,SAAS,MAAM,EAAE,EACjC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,GAC3B,SAAS,MAAM,EAAE,CAyBnB;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,cAAc,EAAE,SAAS,MAAM,EAAE;;4BAlDzB,MAAM,KAAK,OAAO;;EA2D3B"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { isCanonicalSource } from "./file-policy.js";
|
|
3
|
+
function normalizePackagePatterns(patterns) {
|
|
4
|
+
return patterns.map((input) => {
|
|
5
|
+
const excluded = input.startsWith("!");
|
|
6
|
+
let pattern = excluded ? input.slice(1) : input;
|
|
7
|
+
while (pattern.startsWith("./")) {
|
|
8
|
+
pattern = pattern.slice(2);
|
|
9
|
+
}
|
|
10
|
+
while (pattern.endsWith("/")) {
|
|
11
|
+
pattern = pattern.slice(0, -1);
|
|
12
|
+
}
|
|
13
|
+
return excluded ? `!${pattern}` : pattern;
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
// pnpm declarations describe discovery, not selection. Registry ownership still
|
|
17
|
+
// determines which discovered packages may enter a particular composition.
|
|
18
|
+
// Effect Path has no glob matcher; Node's pure POSIX matcher needs no filesystem access.
|
|
19
|
+
export function packageManifestMatcher(sourcePatterns) {
|
|
20
|
+
const patterns = normalizePackagePatterns(sourcePatterns);
|
|
21
|
+
const included = patterns.filter((pattern) => !pattern.startsWith("!"));
|
|
22
|
+
const excluded = patterns
|
|
23
|
+
.filter((pattern) => pattern.startsWith("!"))
|
|
24
|
+
.map((pattern) => pattern.slice(1));
|
|
25
|
+
return (file) => {
|
|
26
|
+
if (!file.endsWith("/package.json") || !isCanonicalSource(file)) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
const directory = file.slice(0, -"/package.json".length);
|
|
30
|
+
return (included.some((pattern) => path.posix.matchesGlob(directory, pattern)) &&
|
|
31
|
+
!excluded.some((pattern) => path.posix.matchesGlob(directory, pattern)));
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export function applicationPackagePatterns(sourcePatterns, targets) {
|
|
35
|
+
const patterns = [
|
|
36
|
+
"apps/*",
|
|
37
|
+
"packages/*",
|
|
38
|
+
...(targets.has("tests/e2e/package.json") ? ["tests/*"] : []),
|
|
39
|
+
];
|
|
40
|
+
const directories = [...targets]
|
|
41
|
+
.filter((target) => target.endsWith("/package.json"))
|
|
42
|
+
.map((target) => target.slice(0, -"/package.json".length));
|
|
43
|
+
// Keep customary locations open for new application code, and retain source
|
|
44
|
+
// declarations needed by selected packages in other or nested locations.
|
|
45
|
+
for (const pattern of normalizePackagePatterns(sourcePatterns)) {
|
|
46
|
+
if (pattern.startsWith("!") ||
|
|
47
|
+
directories.some((directory) => !patterns.some((existing) => path.posix.matchesGlob(directory, existing)) && path.posix.matchesGlob(directory, pattern))) {
|
|
48
|
+
patterns.push(pattern);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return patterns;
|
|
52
|
+
}
|
|
53
|
+
export function packageCatalog(files, sourcePatterns) {
|
|
54
|
+
const patterns = normalizePackagePatterns(sourcePatterns);
|
|
55
|
+
const matchesManifest = packageManifestMatcher(patterns);
|
|
56
|
+
return {
|
|
57
|
+
manifests: files.filter(matchesManifest),
|
|
58
|
+
matchesManifest,
|
|
59
|
+
patterns,
|
|
60
|
+
};
|
|
61
|
+
}
|