create-geonosis 2.13.0 → 3.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.
- package/CHANGELOG.md +23 -0
- package/bin/create-geonosis.mjs +1 -1
- package/dist/adopt.js +144 -0
- package/dist/answers.d.ts +42 -0
- package/dist/answers.js +111 -0
- package/dist/check.d.ts +24 -0
- package/dist/check.js +62 -0
- package/dist/composition.d.ts +46 -0
- package/dist/composition.js +137 -0
- package/dist/corpus.d.ts +16 -0
- package/dist/corpus.js +46 -0
- package/dist/create-geonosis-cli.js +41 -229
- package/dist/files.d.ts +18 -0
- package/dist/files.js +497 -0
- package/dist/floor-versions.d.ts +29 -0
- package/dist/floor-versions.js +35 -0
- package/dist/index.d.ts +7 -170
- package/dist/index.js +16 -19
- package/dist/layout.d.ts +18 -0
- package/dist/layout.js +164 -0
- package/dist/scaffold.d.ts +36 -0
- package/dist/scaffold.js +173 -0
- package/package.json +5 -4
- package/dist/chunk-LUUI74BB.js +0 -1224
|
@@ -1,199 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BACKENDS,
|
|
3
|
-
DOMAIN_NAMES,
|
|
4
|
-
MEDUSA_RANGE,
|
|
5
|
-
PLATFORM_FILE,
|
|
6
|
-
UIS,
|
|
7
|
-
checkScaffold,
|
|
8
|
-
describeDrift,
|
|
9
|
-
finish,
|
|
10
|
-
parseAnswers,
|
|
11
|
-
parseArgs,
|
|
12
|
-
scopeOf,
|
|
13
|
-
wantsInstall,
|
|
14
|
-
writeScaffold
|
|
15
|
-
} from "./chunk-LUUI74BB.js";
|
|
16
|
-
|
|
17
|
-
// src/create-geonosis-cli.ts
|
|
18
|
-
import { existsSync as existsSync2 } from "fs";
|
|
19
|
-
|
|
20
|
-
// src/adopt.ts
|
|
21
|
-
import { existsSync, readdirSync, readFileSync } from "fs";
|
|
22
|
-
import { basename, join, resolve } from "path";
|
|
23
|
-
import { countersFor, rulesFor, runtimeOf, tiersFor } from "@geonosis/cli";
|
|
24
|
-
var ADOPT_USAGE = "create-geonosis --plan <dir> [--presets <a,b>] [--runtime pnpm|bun] [--backend medusa|sagaflow-cf|none] [--ui tiered-shadcn|atoms-only|none] \u2014 what adopting this repo would take, computed off the tree. Writes nothing.";
|
|
25
|
-
var LOCKFILES = ["bun.lock", "bun.lockb", "pnpm-lock.yaml"];
|
|
26
|
-
var MEDUSA = "@medusajs/";
|
|
27
|
-
var WORKERS = ["wrangler", "@cloudflare/workers-types", "sagaflow-js"];
|
|
28
|
-
var readJson = (at) => {
|
|
29
|
-
if (!existsSync(at)) return void 0;
|
|
30
|
-
try {
|
|
31
|
-
return JSON.parse(readFileSync(at, "utf8"));
|
|
32
|
-
} catch {
|
|
33
|
-
return void 0;
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
var manifestsIn = (dir) => {
|
|
37
|
-
const found = [readJson(join(dir, "package.json"))];
|
|
38
|
-
for (const group of ["apps", "packages"]) {
|
|
39
|
-
const at = join(dir, group);
|
|
40
|
-
if (!existsSync(at)) continue;
|
|
41
|
-
for (const entry of readdirSync(at, { withFileTypes: true })) {
|
|
42
|
-
if (entry.isDirectory()) found.push(readJson(join(at, entry.name, "package.json")));
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return found.filter((one) => one !== void 0);
|
|
46
|
-
};
|
|
47
|
-
var dependencyNames = (manifests) => manifests.flatMap((one) => [
|
|
48
|
-
...Object.keys(one.dependencies ?? {}),
|
|
49
|
-
...Object.keys(one.devDependencies ?? {})
|
|
50
|
-
]);
|
|
51
|
-
var backendOf = (manifests) => {
|
|
52
|
-
const names = dependencyNames(manifests);
|
|
53
|
-
if (names.some((one) => one.startsWith(MEDUSA))) return "medusa";
|
|
54
|
-
if (names.some((one) => WORKERS.includes(one))) return "sagaflow-cf";
|
|
55
|
-
return "none";
|
|
56
|
-
};
|
|
57
|
-
var chosen = (flag, given, allowed) => {
|
|
58
|
-
if (given === void 0) return void 0;
|
|
59
|
-
if (!allowed.includes(given)) {
|
|
60
|
-
throw new Error(`${flag} "${given}" is not one of ${allowed.join(", ")}`);
|
|
61
|
-
}
|
|
62
|
-
return given;
|
|
63
|
-
};
|
|
64
|
-
var uiOf = (dir, given) => {
|
|
65
|
-
if (given !== void 0) return given;
|
|
66
|
-
if (!existsSync(join(dir, "packages/ui"))) return "none";
|
|
67
|
-
throw new Error(
|
|
68
|
-
`${dir} has a packages/ui and no --ui was given \u2014 the tier decides which rules the plan proposes, and a directory listing cannot say which tier it is. Name --ui ${UIS.join("|")}.`
|
|
69
|
-
);
|
|
70
|
-
};
|
|
71
|
-
var doorFor = (block) => `@geonosis/${block}`;
|
|
72
|
-
var KIT_OWNED_BLOCKS = ["ledger", "review", "testbed", "verify", "walk"];
|
|
73
|
-
var planAdoption = ({ backend, dir, presets, runtime, ui }) => {
|
|
74
|
-
const at = resolve(dir);
|
|
75
|
-
if (!existsSync(at))
|
|
76
|
-
throw new Error(`${at} is not there \u2014 --plan reads a repo, it never makes one`);
|
|
77
|
-
const manifests = manifestsIn(at);
|
|
78
|
-
const chosenRuntime = chosen("--runtime", runtime, ["bun", "pnpm"]) ?? runtimeOf(at);
|
|
79
|
-
if (chosenRuntime === void 0) {
|
|
80
|
-
throw new Error(
|
|
81
|
-
`${at} has none of ${LOCKFILES.join(", ")}, so nothing there says which package manager it runs \u2014 name --runtime pnpm|bun.`
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
const answers = {
|
|
85
|
-
backend: chosen("--backend", backend, BACKENDS) ?? backendOf(manifests),
|
|
86
|
-
dir: at,
|
|
87
|
-
domains: [],
|
|
88
|
-
name: basename(at),
|
|
89
|
-
runtime: chosenRuntime,
|
|
90
|
-
scope: scopeOf(basename(at)),
|
|
91
|
-
ui: uiOf(at, chosen("--ui", ui, UIS))
|
|
92
|
-
};
|
|
93
|
-
const drift = checkScaffold(answers);
|
|
94
|
-
const enabled = new Set(
|
|
95
|
-
Object.keys(
|
|
96
|
-
readJson(join(at, ".oxlintrc.json"))?.rules ?? {}
|
|
97
|
-
)
|
|
98
|
-
);
|
|
99
|
-
const config = readJson(join(at, "geonosis.json")) ?? {};
|
|
100
|
-
const declaredTiers = config["verify"] ?? {};
|
|
101
|
-
const declaredCounters = new Set(
|
|
102
|
-
(readJson(
|
|
103
|
-
join(at, "geonosis.ratchet.json")
|
|
104
|
-
)?.counters ?? []).map((one) => one.key ?? one.counter ?? "")
|
|
105
|
-
);
|
|
106
|
-
const declaredPackages = new Set(dependencyNames(manifests));
|
|
107
|
-
const { unanswered } = rulesFor(presets);
|
|
108
|
-
const tiers = tiersFor({
|
|
109
|
-
rules: {},
|
|
110
|
-
runtime: chosenRuntime,
|
|
111
|
-
scripts: Object.keys(
|
|
112
|
-
readJson(join(at, "package.json"))?.scripts ?? {}
|
|
113
|
-
)
|
|
114
|
-
});
|
|
115
|
-
return {
|
|
116
|
-
backend: answers.backend,
|
|
117
|
-
counters: countersFor(chosenRuntime, "LAW.md").map((one) => {
|
|
118
|
-
const key = typeof one["key"] === "string" ? one["key"] : String(one["counter"]);
|
|
119
|
-
return { declared: declaredCounters.has(key), key };
|
|
120
|
-
}),
|
|
121
|
-
dir: at,
|
|
122
|
-
doors: KIT_OWNED_BLOCKS.map((block) => ({
|
|
123
|
-
block,
|
|
124
|
-
declared: declaredPackages.has(doorFor(block)),
|
|
125
|
-
package: doorFor(block)
|
|
126
|
-
})),
|
|
127
|
-
files: drift.filter((one) => one.kind === "missing"),
|
|
128
|
-
keys: drift.filter((one) => one.kind === "key"),
|
|
129
|
-
presets: presets.map((name) => {
|
|
130
|
-
const brings = Object.keys(rulesFor([name]).rules);
|
|
131
|
-
return {
|
|
132
|
-
brings: brings.length,
|
|
133
|
-
enabled: brings.filter((id) => enabled.has(id)),
|
|
134
|
-
name
|
|
135
|
-
};
|
|
136
|
-
}),
|
|
137
|
-
runtime: chosenRuntime,
|
|
138
|
-
tiers: Object.entries(tiers).map(([name, steps]) => ({
|
|
139
|
-
declared: Object.hasOwn(declaredTiers, name),
|
|
140
|
-
name,
|
|
141
|
-
steps
|
|
142
|
-
})),
|
|
143
|
-
ui: answers.ui,
|
|
144
|
-
unanswered,
|
|
145
|
-
unreadable: drift.filter((one) => one.kind === "unreadable")
|
|
146
|
-
};
|
|
147
|
-
};
|
|
148
|
-
var section = (title, lines) => lines.length === 0 ? [`${title} \u2014 none`, ""] : [`${title} (${lines.length})`, ...lines, ""];
|
|
149
|
-
var formatPlan = (plan) => [
|
|
150
|
-
`adoption plan for ${plan.dir}`,
|
|
151
|
-
` runtime ${plan.runtime} \xB7 backend ${plan.backend} \xB7 ui ${plan.ui}`,
|
|
152
|
-
"",
|
|
153
|
-
...section(
|
|
154
|
-
"FILES the scaffold writes and this repo has none of",
|
|
155
|
-
plan.files.map((one) => ` ${one.file}`)
|
|
156
|
-
),
|
|
157
|
-
...section(
|
|
158
|
-
"KEYS the scaffold declares inside a file this repo has",
|
|
159
|
-
plan.keys.map((one) => ` ${one.file} \u2192 ${one.at}`)
|
|
160
|
-
),
|
|
161
|
-
...section(
|
|
162
|
-
"RULES the presets bring",
|
|
163
|
-
plan.presets.map(
|
|
164
|
-
(one) => ` ${one.name}: ${one.brings} rules, ${one.enabled.length} already enabled here`
|
|
165
|
-
)
|
|
166
|
-
),
|
|
167
|
-
...section(
|
|
168
|
-
"RULES left out until somebody answers their option",
|
|
169
|
-
plan.unanswered.map(([rule, option]) => ` ${rule} needs \`${option}\``)
|
|
170
|
-
),
|
|
171
|
-
...section(
|
|
172
|
-
"COUNTERS the ratchet would run",
|
|
173
|
-
plan.counters.map((one) => ` ${one.key}${one.declared ? " \u2014 declared" : ""}`)
|
|
174
|
-
),
|
|
175
|
-
...section(
|
|
176
|
-
"TIERS",
|
|
177
|
-
plan.tiers.map((one) => ` ${one.name}${one.declared ? " \u2014 declared" : ""}`)
|
|
178
|
-
),
|
|
179
|
-
...section(
|
|
180
|
-
"DOORS a block needs declared",
|
|
181
|
-
plan.doors.map(
|
|
182
|
-
(one) => ` ${one.package} for "${one.block}"${one.declared ? " \u2014 declared" : ""}`
|
|
183
|
-
)
|
|
184
|
-
),
|
|
185
|
-
...plan.unreadable.length === 0 ? [] : section(
|
|
186
|
-
"FILES this check could not read as JSON",
|
|
187
|
-
plan.unreadable.map((one) => ` ${one.file}`)
|
|
188
|
-
)
|
|
189
|
-
].join("\n");
|
|
190
|
-
|
|
191
1
|
// src/create-geonosis-cli.ts
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { ADOPT_USAGE, formatPlan, planAdoption } from "./adopt.js";
|
|
4
|
+
import { MEDUSA_RANGE, parseAnswers, parseArgs, wantsInstall } from "./answers.js";
|
|
5
|
+
import { checkScaffold, describeDrift } from "./check.js";
|
|
6
|
+
import { DOMAIN_NAMES, PLATFORM_FILE } from "./composition.js";
|
|
7
|
+
import { finish, writeScaffold } from "./scaffold.js";
|
|
192
8
|
var USAGE = `create-geonosis <dir> --runtime pnpm|bun --backend medusa|sagaflow-cf|none --ui tiered-shadcn|atoms-only|none
|
|
193
9
|
[--medusa <range>]
|
|
194
10
|
[--domains <a,b>] [--brand <name>] [--themekit <name>] [--marketplace <path>] [--kit <path>] [--no-install]
|
|
195
11
|
[--check]
|
|
196
|
-
create-geonosis --plan <dir> [--presets <a,b>] [--runtime
|
|
12
|
+
create-geonosis --plan <dir> [--presets <a,b>] [--runtime …] [--backend …] [--ui …]
|
|
197
13
|
|
|
198
14
|
Writes a repo that passes its own gates on day one: a workspace with one catalog of shared versions,
|
|
199
15
|
an exports map and no barrel in every package, typecheck + lint + test scripts in every workspace,
|
|
@@ -204,7 +20,7 @@ skills lock, and a reach corpus in this repo's own vocabulary so the doctor can
|
|
|
204
20
|
There is no default for --runtime, --backend or --ui. Each one decides the shape of the tree, and a
|
|
205
21
|
default borrowed from another repo would be that repo's stack hardcoded into this one.
|
|
206
22
|
|
|
207
|
-
--domains the domains this repo composes
|
|
23
|
+
--domains the domains this repo composes — ${DOMAIN_NAMES.join(", ")}. Each one writes its
|
|
208
24
|
store into the app's ${PLATFORM_FILE}: the composition root, in two lifetimes, with
|
|
209
25
|
the tenant session opened before any store is built. A name nothing ships is refused.
|
|
210
26
|
--medusa <range>
|
|
@@ -221,19 +37,19 @@ default borrowed from another repo would be that repo's stack hardcoded into thi
|
|
|
221
37
|
preset brings against the ones already enabled, the rules left out until somebody
|
|
222
38
|
answers their option, the counters, the tiers and the doors a block needs
|
|
223
39
|
declared. The runtime and the backend are read off the lockfile and the manifests;
|
|
224
|
-
a flag overrides one. Exit 0
|
|
40
|
+
a flag overrides one. Exit 0 — it is a report.
|
|
225
41
|
--check say what an EXISTING repo is missing of what the scaffold writes today, and WRITE
|
|
226
42
|
NOTHING. Files it has never had, and keys inside the JSON it has. Contents and
|
|
227
43
|
values are never compared: a repo that has been worked in has rewritten them, and
|
|
228
44
|
it was entitled to. Exit 1 when anything drifted.
|
|
229
45
|
|
|
230
|
-
Exit: 0 written (or, under --check, no drift)
|
|
231
|
-
answer that is not one) or drift found
|
|
46
|
+
Exit: 0 written (or, under --check, no drift) · 1 refused (a directory with something in it, an
|
|
47
|
+
answer that is not one) or drift found · 2 a run that could not be made at all.`;
|
|
232
48
|
var CONFIG_SHAPE = `create-geonosis reads no configuration file.
|
|
233
49
|
|
|
234
50
|
It WRITES them: geonosis.json, .oxlintrc.json, geonosis.ratchet.json and gate-baseline.json, from
|
|
235
51
|
the answers given on the command line. Every answer is a flag, and there is no default for the three
|
|
236
|
-
that decide the shape of the tree
|
|
52
|
+
that decide the shape of the tree — see create-geonosis --help.
|
|
237
53
|
|
|
238
54
|
For the shape of what it wrote, ask the bin that reads it: geonosis-<tool> --print-config-shape.`;
|
|
239
55
|
var main = () => {
|
|
@@ -250,61 +66,57 @@ var main = () => {
|
|
|
250
66
|
}
|
|
251
67
|
if (argv.includes("--plan")) {
|
|
252
68
|
const { dir, flags } = parseArgs(argv);
|
|
253
|
-
if (dir ===
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
)}
|
|
264
|
-
`
|
|
265
|
-
);
|
|
69
|
+
if (dir === undefined)
|
|
70
|
+
throw new Error(`--plan needs a directory — ${ADOPT_USAGE}`);
|
|
71
|
+
process.stdout.write(`${formatPlan(planAdoption({
|
|
72
|
+
...flags["--backend"] === undefined ? {} : { backend: flags["--backend"] },
|
|
73
|
+
dir,
|
|
74
|
+
presets: (flags["--presets"] ?? "frontend,tooling").split(",").map((one) => one.trim()).filter((one) => one !== ""),
|
|
75
|
+
...flags["--runtime"] === undefined ? {} : { runtime: flags["--runtime"] },
|
|
76
|
+
...flags["--ui"] === undefined ? {} : { ui: flags["--ui"] }
|
|
77
|
+
}))}
|
|
78
|
+
`);
|
|
266
79
|
return 0;
|
|
267
80
|
}
|
|
268
81
|
const answers = parseAnswers(argv, process.cwd());
|
|
269
82
|
if (argv.includes("--check")) {
|
|
270
|
-
if (!
|
|
271
|
-
throw new Error(`${answers.dir} is not there
|
|
83
|
+
if (!existsSync(answers.dir)) {
|
|
84
|
+
throw new Error(`${answers.dir} is not there — --check reads a repo, it never makes one`);
|
|
272
85
|
}
|
|
273
86
|
const drift = checkScaffold(answers);
|
|
274
87
|
if (drift.length === 0) {
|
|
275
|
-
process.stdout.write(`create-geonosis --check ${answers.dir}
|
|
88
|
+
process.stdout.write(`create-geonosis --check ${answers.dir} — no drift
|
|
276
89
|
`);
|
|
277
90
|
return 0;
|
|
278
91
|
}
|
|
279
|
-
for (const line of describeDrift(drift))
|
|
92
|
+
for (const line of describeDrift(drift))
|
|
93
|
+
process.stderr.write(` ${line}
|
|
94
|
+
`);
|
|
95
|
+
process.stderr.write(`create-geonosis --check ${answers.dir} — ${drift.length} drift, nothing written
|
|
280
96
|
`);
|
|
281
|
-
process.stderr.write(
|
|
282
|
-
`create-geonosis --check ${answers.dir} \u2014 ${drift.length} drift, nothing written
|
|
283
|
-
`
|
|
284
|
-
);
|
|
285
97
|
return 1;
|
|
286
98
|
}
|
|
287
99
|
const written = writeScaffold(answers);
|
|
288
|
-
process.stdout.write(`create-geonosis
|
|
100
|
+
process.stdout.write(`create-geonosis — ${written.length} file(s) into ${answers.dir}
|
|
289
101
|
`);
|
|
290
102
|
const install = wantsInstall(argv);
|
|
291
103
|
for (const step of finish({ answers, install })) {
|
|
292
104
|
process.stdout.write(` ${step.code === 0 ? "ok " : "FAIL"} ${step.what}
|
|
293
105
|
`);
|
|
294
|
-
if (step.code !== 0)
|
|
106
|
+
if (step.code !== 0)
|
|
107
|
+
process.stdout.write(`${step.output}
|
|
295
108
|
`);
|
|
296
109
|
}
|
|
297
110
|
if (!install) {
|
|
298
|
-
process.stdout.write(
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
);
|
|
111
|
+
process.stdout.write([
|
|
112
|
+
"",
|
|
113
|
+
" Nothing was installed, so the edges table has not reached the gates yet. Run:",
|
|
114
|
+
` cd ${answers.dir} && ${answers.runtime} install`,
|
|
115
|
+
" geonosis sync --target turbo --into turbo.json",
|
|
116
|
+
" geonosis sync --target layer-walls --into .oxlintrc.json",
|
|
117
|
+
""
|
|
118
|
+
].join(`
|
|
119
|
+
`));
|
|
308
120
|
}
|
|
309
121
|
return 0;
|
|
310
122
|
};
|
package/dist/files.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Answers } from './answers.js';
|
|
2
|
+
declare const presetsFor: (answers: Answers) => string[];
|
|
3
|
+
/** The kit a scaffolded repo runs on, at the version this scaffold was published at. */
|
|
4
|
+
export declare const kitDependencies: (answers: Answers) => Record<string, string>;
|
|
5
|
+
/**
|
|
6
|
+
* The two files the edges table generates, named once. `scaffold` runs them when it makes the tree
|
|
7
|
+
* and the `sync:graph` script runs them when the table changes; a second spelling of the pair is a
|
|
8
|
+
* second answer to where the graph comes from.
|
|
9
|
+
*/
|
|
10
|
+
export declare const GRAPH_SYNCS: {
|
|
11
|
+
target: string;
|
|
12
|
+
write: string;
|
|
13
|
+
}[];
|
|
14
|
+
/** What the root can be asked to run — and therefore what a verify tier may name (`tiersFor`). */
|
|
15
|
+
export declare const HOOK_INSTALLER = "scripts/install-hooks.mjs";
|
|
16
|
+
export declare const filesFor: (answers: Answers) => Record<string, string>;
|
|
17
|
+
export declare const presetsChosenBy: typeof presetsFor;
|
|
18
|
+
export {};
|