@hydranium/cli 1.0.0-next.10
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/LICENSE +21 -0
- package/README.md +240 -0
- package/heap-analysis/analyze-heap.mjs +798 -0
- package/heap-analysis/heap/core/aggregate.mjs +152 -0
- package/heap-analysis/heap/core/bucket-label.mjs +23 -0
- package/heap-analysis/heap/core/cutpoints.mjs +51 -0
- package/heap-analysis/heap/core/diff.mjs +56 -0
- package/heap-analysis/heap/core/format.mjs +47 -0
- package/heap-analysis/heap/core/holders.mjs +80 -0
- package/heap-analysis/heap/core/load.mjs +46 -0
- package/heap-analysis/heap/core/report.mjs +68 -0
- package/heap-analysis/heap/core/strings.mjs +80 -0
- package/heap-analysis/heap/langium/concepts.mjs +230 -0
- package/heap-analysis/heap/langium/glsp.classifier.mjs +80 -0
- package/heap-analysis/heap/langium/langium.classifier.mjs +203 -0
- package/heap-analysis/heap/renderer/renderer.mjs +122 -0
- package/lib/cli-version.d.ts +21 -0
- package/lib/cli-version.d.ts.map +1 -0
- package/lib/cli-version.js +30 -0
- package/lib/cli-version.js.map +1 -0
- package/lib/cli.d.ts +11 -0
- package/lib/cli.d.ts.map +1 -0
- package/lib/cli.js +135 -0
- package/lib/cli.js.map +1 -0
- package/lib/commands/analyze-heap-args.d.ts +46 -0
- package/lib/commands/analyze-heap-args.d.ts.map +1 -0
- package/lib/commands/analyze-heap-args.js +174 -0
- package/lib/commands/analyze-heap-args.js.map +1 -0
- package/lib/commands/analyze-heap.d.ts +37 -0
- package/lib/commands/analyze-heap.d.ts.map +1 -0
- package/lib/commands/analyze-heap.js +63 -0
- package/lib/commands/analyze-heap.js.map +1 -0
- package/lib/commands/ast-ground-truth-args.d.ts +23 -0
- package/lib/commands/ast-ground-truth-args.d.ts.map +1 -0
- package/lib/commands/ast-ground-truth-args.js +47 -0
- package/lib/commands/ast-ground-truth-args.js.map +1 -0
- package/lib/commands/ast-ground-truth-driver.d.ts +10 -0
- package/lib/commands/ast-ground-truth-driver.d.ts.map +1 -0
- package/lib/commands/ast-ground-truth-driver.js +72 -0
- package/lib/commands/ast-ground-truth-driver.js.map +1 -0
- package/lib/commands/ast-ground-truth.d.ts +31 -0
- package/lib/commands/ast-ground-truth.d.ts.map +1 -0
- package/lib/commands/ast-ground-truth.js +36 -0
- package/lib/commands/ast-ground-truth.js.map +1 -0
- package/lib/commands/generate-transfer-model-args.d.ts +38 -0
- package/lib/commands/generate-transfer-model-args.d.ts.map +1 -0
- package/lib/commands/generate-transfer-model-args.js +183 -0
- package/lib/commands/generate-transfer-model-args.js.map +1 -0
- package/lib/commands/generate-transfer-model-config.d.ts +32 -0
- package/lib/commands/generate-transfer-model-config.d.ts.map +1 -0
- package/lib/commands/generate-transfer-model-config.js +122 -0
- package/lib/commands/generate-transfer-model-config.js.map +1 -0
- package/lib/commands/generate-transfer-model.d.ts +110 -0
- package/lib/commands/generate-transfer-model.d.ts.map +1 -0
- package/lib/commands/generate-transfer-model.js +587 -0
- package/lib/commands/generate-transfer-model.js.map +1 -0
- package/lib/commands/harness-args.d.ts +198 -0
- package/lib/commands/harness-args.d.ts.map +1 -0
- package/lib/commands/harness-args.js +339 -0
- package/lib/commands/harness-args.js.map +1 -0
- package/lib/commands/headless-harness.d.ts +97 -0
- package/lib/commands/headless-harness.d.ts.map +1 -0
- package/lib/commands/headless-harness.js +121 -0
- package/lib/commands/headless-harness.js.map +1 -0
- package/lib/commands/init-args.d.ts +81 -0
- package/lib/commands/init-args.d.ts.map +1 -0
- package/lib/commands/init-args.js +250 -0
- package/lib/commands/init-args.js.map +1 -0
- package/lib/commands/init-prompt.d.ts +66 -0
- package/lib/commands/init-prompt.d.ts.map +1 -0
- package/lib/commands/init-prompt.js +71 -0
- package/lib/commands/init-prompt.js.map +1 -0
- package/lib/commands/init-templates.d.ts +42 -0
- package/lib/commands/init-templates.d.ts.map +1 -0
- package/lib/commands/init-templates.js +1902 -0
- package/lib/commands/init-templates.js.map +1 -0
- package/lib/commands/init-wizard.d.ts +65 -0
- package/lib/commands/init-wizard.d.ts.map +1 -0
- package/lib/commands/init-wizard.js +302 -0
- package/lib/commands/init-wizard.js.map +1 -0
- package/lib/commands/init-workspace.d.ts +168 -0
- package/lib/commands/init-workspace.d.ts.map +1 -0
- package/lib/commands/init-workspace.js +372 -0
- package/lib/commands/init-workspace.js.map +1 -0
- package/lib/commands/init.d.ts +273 -0
- package/lib/commands/init.d.ts.map +1 -0
- package/lib/commands/init.js +303 -0
- package/lib/commands/init.js.map +1 -0
- package/lib/commands/lint-grammar-args.d.ts +23 -0
- package/lib/commands/lint-grammar-args.d.ts.map +1 -0
- package/lib/commands/lint-grammar-args.js +63 -0
- package/lib/commands/lint-grammar-args.js.map +1 -0
- package/lib/commands/lint-grammar-driver.d.ts +10 -0
- package/lib/commands/lint-grammar-driver.d.ts.map +1 -0
- package/lib/commands/lint-grammar-driver.js +72 -0
- package/lib/commands/lint-grammar-driver.js.map +1 -0
- package/lib/commands/lint-grammar-report.d.ts +24 -0
- package/lib/commands/lint-grammar-report.d.ts.map +1 -0
- package/lib/commands/lint-grammar-report.js +65 -0
- package/lib/commands/lint-grammar-report.js.map +1 -0
- package/lib/commands/lint-grammar.d.ts +33 -0
- package/lib/commands/lint-grammar.d.ts.map +1 -0
- package/lib/commands/lint-grammar.js +42 -0
- package/lib/commands/lint-grammar.js.map +1 -0
- package/lib/commands/measure-memory-args.d.ts +23 -0
- package/lib/commands/measure-memory-args.d.ts.map +1 -0
- package/lib/commands/measure-memory-args.js +106 -0
- package/lib/commands/measure-memory-args.js.map +1 -0
- package/lib/commands/measure-memory-driver.d.ts +10 -0
- package/lib/commands/measure-memory-driver.d.ts.map +1 -0
- package/lib/commands/measure-memory-driver.js +110 -0
- package/lib/commands/measure-memory-driver.js.map +1 -0
- package/lib/commands/measure-memory.d.ts +68 -0
- package/lib/commands/measure-memory.d.ts.map +1 -0
- package/lib/commands/measure-memory.js +100 -0
- package/lib/commands/measure-memory.js.map +1 -0
- package/lib/commands/model-docs-args.d.ts +23 -0
- package/lib/commands/model-docs-args.d.ts.map +1 -0
- package/lib/commands/model-docs-args.js +53 -0
- package/lib/commands/model-docs-args.js.map +1 -0
- package/lib/commands/model-docs-driver.d.ts +10 -0
- package/lib/commands/model-docs-driver.d.ts.map +1 -0
- package/lib/commands/model-docs-driver.js +61 -0
- package/lib/commands/model-docs-driver.js.map +1 -0
- package/lib/commands/model-docs-report.d.ts +18 -0
- package/lib/commands/model-docs-report.d.ts.map +1 -0
- package/lib/commands/model-docs-report.js +123 -0
- package/lib/commands/model-docs-report.js.map +1 -0
- package/lib/commands/model-docs.d.ts +30 -0
- package/lib/commands/model-docs.d.ts.map +1 -0
- package/lib/commands/model-docs.js +37 -0
- package/lib/commands/model-docs.js.map +1 -0
- package/lib/commands/projects-args.d.ts +25 -0
- package/lib/commands/projects-args.d.ts.map +1 -0
- package/lib/commands/projects-args.js +49 -0
- package/lib/commands/projects-args.js.map +1 -0
- package/lib/commands/projects.d.ts +45 -0
- package/lib/commands/projects.d.ts.map +1 -0
- package/lib/commands/projects.js +39 -0
- package/lib/commands/projects.js.map +1 -0
- package/lib/commands/query-args.d.ts +25 -0
- package/lib/commands/query-args.d.ts.map +1 -0
- package/lib/commands/query-args.js +46 -0
- package/lib/commands/query-args.js.map +1 -0
- package/lib/commands/query.d.ts +32 -0
- package/lib/commands/query.d.ts.map +1 -0
- package/lib/commands/query.js +29 -0
- package/lib/commands/query.js.map +1 -0
- package/lib/commands/reflect-args.d.ts +23 -0
- package/lib/commands/reflect-args.d.ts.map +1 -0
- package/lib/commands/reflect-args.js +59 -0
- package/lib/commands/reflect-args.js.map +1 -0
- package/lib/commands/reflect-driver.d.ts +10 -0
- package/lib/commands/reflect-driver.d.ts.map +1 -0
- package/lib/commands/reflect-driver.js +66 -0
- package/lib/commands/reflect-driver.js.map +1 -0
- package/lib/commands/reflect-report.d.ts +20 -0
- package/lib/commands/reflect-report.d.ts.map +1 -0
- package/lib/commands/reflect-report.js +127 -0
- package/lib/commands/reflect-report.js.map +1 -0
- package/lib/commands/reflect.d.ts +30 -0
- package/lib/commands/reflect.d.ts.map +1 -0
- package/lib/commands/reflect.js +38 -0
- package/lib/commands/reflect.js.map +1 -0
- package/lib/commands/save-args.d.ts +26 -0
- package/lib/commands/save-args.d.ts.map +1 -0
- package/lib/commands/save-args.js +59 -0
- package/lib/commands/save-args.js.map +1 -0
- package/lib/commands/save.d.ts +38 -0
- package/lib/commands/save.d.ts.map +1 -0
- package/lib/commands/save.js +48 -0
- package/lib/commands/save.js.map +1 -0
- package/lib/commands/validate-args.d.ts +23 -0
- package/lib/commands/validate-args.d.ts.map +1 -0
- package/lib/commands/validate-args.js +60 -0
- package/lib/commands/validate-args.js.map +1 -0
- package/lib/commands/validate-driver.d.ts +10 -0
- package/lib/commands/validate-driver.d.ts.map +1 -0
- package/lib/commands/validate-driver.js +72 -0
- package/lib/commands/validate-driver.js.map +1 -0
- package/lib/commands/validate-report.d.ts +30 -0
- package/lib/commands/validate-report.d.ts.map +1 -0
- package/lib/commands/validate-report.js +87 -0
- package/lib/commands/validate-report.js.map +1 -0
- package/lib/commands/validate.d.ts +34 -0
- package/lib/commands/validate.d.ts.map +1 -0
- package/lib/commands/validate.js +41 -0
- package/lib/commands/validate.js.map +1 -0
- package/lib/commands/watch-args.d.ts +26 -0
- package/lib/commands/watch-args.d.ts.map +1 -0
- package/lib/commands/watch-args.js +59 -0
- package/lib/commands/watch-args.js.map +1 -0
- package/lib/commands/watch.d.ts +75 -0
- package/lib/commands/watch.d.ts.map +1 -0
- package/lib/commands/watch.js +112 -0
- package/lib/commands/watch.js.map +1 -0
- package/lib/index.d.ts +16 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +16 -0
- package/lib/index.js.map +1 -0
- package/lib/log-level.d.ts +39 -0
- package/lib/log-level.d.ts.map +1 -0
- package/lib/log-level.js +47 -0
- package/lib/log-level.js.map +1 -0
- package/lib/package-name.d.ts +33 -0
- package/lib/package-name.d.ts.map +1 -0
- package/lib/package-name.js +37 -0
- package/lib/package-name.js.map +1 -0
- package/lib/spawn-data-server.d.ts +102 -0
- package/lib/spawn-data-server.d.ts.map +1 -0
- package/lib/spawn-data-server.js +154 -0
- package/lib/spawn-data-server.js.map +1 -0
- package/lib/testing/echo-server.d.ts +11 -0
- package/lib/testing/echo-server.d.ts.map +1 -0
- package/lib/testing/echo-server.js +79 -0
- package/lib/testing/echo-server.js.map +1 -0
- package/package.json +105 -0
- package/src/cli-version.ts +32 -0
- package/src/cli.ts +139 -0
- package/src/commands/analyze-heap-args.ts +184 -0
- package/src/commands/analyze-heap.ts +76 -0
- package/src/commands/ast-ground-truth-args.ts +63 -0
- package/src/commands/ast-ground-truth-driver.ts +81 -0
- package/src/commands/ast-ground-truth.ts +49 -0
- package/src/commands/generate-transfer-model-args.ts +203 -0
- package/src/commands/generate-transfer-model-config.ts +128 -0
- package/src/commands/generate-transfer-model.ts +716 -0
- package/src/commands/harness-args.ts +429 -0
- package/src/commands/headless-harness.ts +165 -0
- package/src/commands/init-args.ts +273 -0
- package/src/commands/init-prompt.ts +149 -0
- package/src/commands/init-templates.ts +2037 -0
- package/src/commands/init-wizard.ts +378 -0
- package/src/commands/init-workspace.ts +442 -0
- package/src/commands/init.ts +554 -0
- package/src/commands/lint-grammar-args.ts +79 -0
- package/src/commands/lint-grammar-driver.ts +83 -0
- package/src/commands/lint-grammar-report.ts +74 -0
- package/src/commands/lint-grammar.ts +57 -0
- package/src/commands/measure-memory-args.ts +123 -0
- package/src/commands/measure-memory-driver.ts +128 -0
- package/src/commands/measure-memory.ts +143 -0
- package/src/commands/model-docs-args.ts +69 -0
- package/src/commands/model-docs-driver.ts +68 -0
- package/src/commands/model-docs-report.ts +133 -0
- package/src/commands/model-docs.ts +48 -0
- package/src/commands/projects-args.ts +62 -0
- package/src/commands/projects.ts +76 -0
- package/src/commands/query-args.ts +61 -0
- package/src/commands/query.ts +58 -0
- package/src/commands/reflect-args.ts +75 -0
- package/src/commands/reflect-driver.ts +76 -0
- package/src/commands/reflect-report.ts +138 -0
- package/src/commands/reflect.ts +51 -0
- package/src/commands/save-args.ts +74 -0
- package/src/commands/save.ts +84 -0
- package/src/commands/validate-args.ts +76 -0
- package/src/commands/validate-driver.ts +84 -0
- package/src/commands/validate-report.ts +95 -0
- package/src/commands/validate.ts +58 -0
- package/src/commands/watch-args.ts +74 -0
- package/src/commands/watch.ts +185 -0
- package/src/index.ts +16 -0
- package/src/log-level.ts +49 -0
- package/src/package-name.ts +39 -0
- package/src/spawn-data-server.ts +247 -0
- package/src/testing/echo-server.ts +93 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 CrossBreeze, EclipseSource and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the MIT License which is available in the project root.
|
|
6
|
+
*
|
|
7
|
+
* SPDX-License-Identifier: MIT
|
|
8
|
+
********************************************************************************/
|
|
9
|
+
/**
|
|
10
|
+
* Workspace detection for `init --monorepo`.
|
|
11
|
+
*
|
|
12
|
+
* Split from `init.ts` because the rules here are the only part of `init` that
|
|
13
|
+
* reads files it does not write, and because the reliable/unreliable line runs
|
|
14
|
+
* straight through them: the root and the base tsconfig are *detected*, the
|
|
15
|
+
* package scope is *guessed from siblings* and the `private` flag is not
|
|
16
|
+
* derivable at all. Keeping them in one module makes that distinction reviewable
|
|
17
|
+
* rather than scattered across the scaffolder.
|
|
18
|
+
*
|
|
19
|
+
* Everything is expressed over {@link WorkspaceProbe} rather than `node:fs`, so
|
|
20
|
+
* the rules are testable against an in-memory tree instead of a temp directory.
|
|
21
|
+
*/
|
|
22
|
+
import * as fs from 'node:fs';
|
|
23
|
+
import * as path from 'node:path';
|
|
24
|
+
/** True for a JSON object — the shape `package.json` and `tsconfig.json` parse to. */
|
|
25
|
+
function isJsonObject(value) {
|
|
26
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Strip the two things `tsc` accepts in a config that `JSON.parse` rejects:
|
|
30
|
+
* comments, and a trailing comma before a closing brace or bracket.
|
|
31
|
+
*
|
|
32
|
+
* Written as a scanner rather than a regex because both constructs are legal
|
|
33
|
+
* INSIDE a string — `"https://example.com"` holds a `//`, and a description can
|
|
34
|
+
* end in a comma — so a pattern that ignores string state corrupts the very
|
|
35
|
+
* configs it is meant to rescue. Without this, a base config with a single
|
|
36
|
+
* comment reads as "no compilerOptions here" and the scaffold silently emits no
|
|
37
|
+
* `extends` at all, which is the worst failure shape available: quietly wrong
|
|
38
|
+
* rather than loudly broken.
|
|
39
|
+
*/
|
|
40
|
+
export function stripJsonComments(text) {
|
|
41
|
+
const characters = [...text];
|
|
42
|
+
const output = [];
|
|
43
|
+
const commaIndices = [];
|
|
44
|
+
let inString = false;
|
|
45
|
+
let escaped = false;
|
|
46
|
+
for (let index = 0; index < characters.length; index += 1) {
|
|
47
|
+
const character = characters[index];
|
|
48
|
+
const next = characters[index + 1];
|
|
49
|
+
if (inString) {
|
|
50
|
+
output.push(character);
|
|
51
|
+
if (escaped) {
|
|
52
|
+
escaped = false;
|
|
53
|
+
}
|
|
54
|
+
else if (character === '\\') {
|
|
55
|
+
escaped = true;
|
|
56
|
+
}
|
|
57
|
+
else if (character === '"') {
|
|
58
|
+
inString = false;
|
|
59
|
+
}
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (character === '"') {
|
|
63
|
+
inString = true;
|
|
64
|
+
output.push(character);
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (character === '/' && next === '/') {
|
|
68
|
+
while (index < characters.length && characters[index] !== '\n') {
|
|
69
|
+
index += 1;
|
|
70
|
+
}
|
|
71
|
+
output.push('\n');
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (character === '/' && next === '*') {
|
|
75
|
+
index += 2;
|
|
76
|
+
while (index < characters.length && !(characters[index] === '*' && characters[index + 1] === '/')) {
|
|
77
|
+
index += 1;
|
|
78
|
+
}
|
|
79
|
+
index += 1;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (character === ',') {
|
|
83
|
+
commaIndices.push(output.length);
|
|
84
|
+
}
|
|
85
|
+
output.push(character);
|
|
86
|
+
}
|
|
87
|
+
// A comma is trailing only if the next thing that is not whitespace closes
|
|
88
|
+
// the object or array. Resolved after the scan, so the lookahead sees text
|
|
89
|
+
// with the comments already gone.
|
|
90
|
+
for (const commaIndex of commaIndices) {
|
|
91
|
+
let lookahead = commaIndex + 1;
|
|
92
|
+
while (lookahead < output.length && /\s/.test(output[lookahead])) {
|
|
93
|
+
lookahead += 1;
|
|
94
|
+
}
|
|
95
|
+
if (output[lookahead] === '}' || output[lookahead] === ']') {
|
|
96
|
+
output[commaIndex] = '';
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return output.join('');
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* The real-filesystem probe.
|
|
103
|
+
*
|
|
104
|
+
* Every read is best-effort: detection runs over directories the user may not
|
|
105
|
+
* own, so an unreadable or malformed file degrades to "not found" rather than
|
|
106
|
+
* aborting a scaffold.
|
|
107
|
+
*/
|
|
108
|
+
export function createNodeWorkspaceProbe() {
|
|
109
|
+
const listEntries = (absolutePath, wantDirectory) => {
|
|
110
|
+
try {
|
|
111
|
+
return fs
|
|
112
|
+
.readdirSync(absolutePath, { withFileTypes: true })
|
|
113
|
+
.filter(entry => entry.isDirectory() === wantDirectory)
|
|
114
|
+
.map(entry => entry.name);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
return {
|
|
121
|
+
readJson: absolutePath => {
|
|
122
|
+
try {
|
|
123
|
+
return JSON.parse(stripJsonComments(fs.readFileSync(absolutePath, 'utf-8')));
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
listDirectories: absolutePath => listEntries(absolutePath, true),
|
|
130
|
+
listFiles: absolutePath => listEntries(absolutePath, false),
|
|
131
|
+
readText: absolutePath => {
|
|
132
|
+
try {
|
|
133
|
+
return fs.readFileSync(absolutePath, 'utf-8');
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* The nearest ancestor of `targetDir` whose `package.json` declares
|
|
143
|
+
* `workspaces`.
|
|
144
|
+
*
|
|
145
|
+
* Nearest rather than outermost: nested workspaces are legal, and the inner one
|
|
146
|
+
* is the manifest that would actually claim the new package.
|
|
147
|
+
*/
|
|
148
|
+
export function findWorkspaceRoot(targetDir, probe) {
|
|
149
|
+
let current = path.resolve(targetDir);
|
|
150
|
+
for (;;) {
|
|
151
|
+
const manifest = probe.readJson(path.join(current, 'package.json'));
|
|
152
|
+
if (isJsonObject(manifest) && Array.isArray(manifest.workspaces)) {
|
|
153
|
+
return current;
|
|
154
|
+
}
|
|
155
|
+
const parent = path.dirname(current);
|
|
156
|
+
if (parent === current) {
|
|
157
|
+
return undefined;
|
|
158
|
+
}
|
|
159
|
+
current = parent;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/** The `workspaces` globs of a detected root, as strings. */
|
|
163
|
+
function readWorkspaces(rootDir, probe) {
|
|
164
|
+
const manifest = probe.readJson(path.join(rootDir, 'package.json'));
|
|
165
|
+
if (!isJsonObject(manifest) || !Array.isArray(manifest.workspaces)) {
|
|
166
|
+
return [];
|
|
167
|
+
}
|
|
168
|
+
return manifest.workspaces.filter((entry) => typeof entry === 'string');
|
|
169
|
+
}
|
|
170
|
+
/** Match one path segment against a glob segment, where `*` stands for "any run of non-separator". */
|
|
171
|
+
function segmentMatches(glob, segment) {
|
|
172
|
+
const source = glob.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '[^/]*');
|
|
173
|
+
return new RegExp(`^${source}$`).test(segment);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* True when a `workspaces` glob covers a repo-relative path.
|
|
177
|
+
*
|
|
178
|
+
* `**` is treated as covering any run of segments. Deliberately no glob
|
|
179
|
+
* dependency: npm's own set is small, and a wrong answer here only costs a
|
|
180
|
+
* printed hint that turns out to be unnecessary.
|
|
181
|
+
*/
|
|
182
|
+
export function workspaceGlobCovers(glob, relativePath) {
|
|
183
|
+
const globSegments = glob.split('/').filter(segment => segment.length > 0);
|
|
184
|
+
const pathSegments = relativePath.split('/').filter(segment => segment.length > 0);
|
|
185
|
+
const matches = (globIndex, pathIndex) => {
|
|
186
|
+
if (globIndex === globSegments.length) {
|
|
187
|
+
return pathIndex === pathSegments.length;
|
|
188
|
+
}
|
|
189
|
+
if (globSegments[globIndex] === '**') {
|
|
190
|
+
for (let skip = pathIndex; skip <= pathSegments.length; skip += 1) {
|
|
191
|
+
if (matches(globIndex + 1, skip)) {
|
|
192
|
+
return true;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
return (pathIndex < pathSegments.length &&
|
|
198
|
+
segmentMatches(globSegments[globIndex], pathSegments[pathIndex]) &&
|
|
199
|
+
matches(globIndex + 1, pathIndex + 1));
|
|
200
|
+
};
|
|
201
|
+
return matches(0, 0);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Expand a `workspaces` glob to the directories it currently names.
|
|
205
|
+
*
|
|
206
|
+
* `**` is not expanded — it returns nothing rather than walking an unbounded
|
|
207
|
+
* tree, because the only caller is scope inference, which a partial sample
|
|
208
|
+
* answers just as well.
|
|
209
|
+
*/
|
|
210
|
+
function expandWorkspaceGlob(rootDir, glob, probe) {
|
|
211
|
+
const segments = glob.split('/').filter(segment => segment.length > 0);
|
|
212
|
+
let directories = [rootDir];
|
|
213
|
+
for (const segment of segments) {
|
|
214
|
+
if (segment === '**') {
|
|
215
|
+
return [];
|
|
216
|
+
}
|
|
217
|
+
if (!segment.includes('*')) {
|
|
218
|
+
directories = directories.map(directory => path.join(directory, segment));
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
directories = directories.flatMap(directory => probe
|
|
222
|
+
.listDirectories(directory)
|
|
223
|
+
.filter(name => segmentMatches(segment, name))
|
|
224
|
+
.map(name => path.join(directory, name)));
|
|
225
|
+
}
|
|
226
|
+
return directories;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* The npm scope the existing workspace members agree on.
|
|
230
|
+
*
|
|
231
|
+
* Guessed from siblings and NOT from the root manifest, which in a framework
|
|
232
|
+
* repo is routinely named for the repo rather than the scope it publishes under
|
|
233
|
+
* — so reading it would confidently produce the wrong answer. Requires a
|
|
234
|
+
* unanimous scope: a split verdict is exactly the case where a prompt should
|
|
235
|
+
* ask rather than a heuristic should pick.
|
|
236
|
+
*/
|
|
237
|
+
export function inferPackageScope(rootDir, workspaces, probe) {
|
|
238
|
+
const scopes = new Set();
|
|
239
|
+
for (const glob of workspaces) {
|
|
240
|
+
for (const directory of expandWorkspaceGlob(rootDir, glob, probe)) {
|
|
241
|
+
const manifest = probe.readJson(path.join(directory, 'package.json'));
|
|
242
|
+
if (!isJsonObject(manifest) || typeof manifest.name !== 'string') {
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
const scope = manifest.name.startsWith('@') ? manifest.name.split('/')[0] : '';
|
|
246
|
+
scopes.add(scope);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
scopes.delete('');
|
|
250
|
+
return scopes.size === 1 ? [...scopes][0] : undefined;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* The root tsconfig that actually carries `compilerOptions`.
|
|
254
|
+
*
|
|
255
|
+
* `tsconfig.json` at a monorepo root is very often a *solution* file — `files:
|
|
256
|
+
* []` plus `references` — so extending it inherits nothing and silently drops
|
|
257
|
+
* every compiler setting the package meant to pick up. Hence the search is by
|
|
258
|
+
* content, preferring the conventional `tsconfig.base.json` name only as a
|
|
259
|
+
* tie-break, never as the test.
|
|
260
|
+
*/
|
|
261
|
+
export function findBaseTsconfig(rootDir, probe) {
|
|
262
|
+
const present = probe.listFiles(rootDir).filter(name => /^tsconfig(\..+)?\.json$/.test(name));
|
|
263
|
+
const preferred = ['tsconfig.base.json', 'tsconfig.json'];
|
|
264
|
+
const candidates = [...preferred.filter(name => present.includes(name)), ...present.filter(name => !preferred.includes(name)).sort()];
|
|
265
|
+
for (const file of candidates) {
|
|
266
|
+
const parsed = probe.readJson(path.join(rootDir, file));
|
|
267
|
+
if (isJsonObject(parsed) && isJsonObject(parsed.compilerOptions) && Object.keys(parsed.compilerOptions).length > 0) {
|
|
268
|
+
return { file, compilerOptions: parsed.compilerOptions };
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return undefined;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* The repo's prettier `printWidth`, so the emitted sources wrap where the repo
|
|
275
|
+
* wraps instead of at the scaffold's own default.
|
|
276
|
+
*
|
|
277
|
+
* **Why this is worth detecting at all.** There is no width that is stable for
|
|
278
|
+
* an unknown repo — 80 (prettier's own default), 100, 120 and 140 each produce
|
|
279
|
+
* different wrapping — so emitted code that "passes a formatter check as-is" is
|
|
280
|
+
* only ever true relative to a config. Matching the one we can see is the
|
|
281
|
+
* closest thing available.
|
|
282
|
+
*
|
|
283
|
+
* **A regex over the file, deliberately, and only for the module forms.** The
|
|
284
|
+
* JSON forms are parsed properly; `.prettierrc.js` and `prettier.config.mjs` are
|
|
285
|
+
* executable modules that no scaffold should evaluate, and skipping them would
|
|
286
|
+
* miss the configs most repos actually use. The pattern takes the FIRST
|
|
287
|
+
* `printWidth`, which is the top-level one in every config laid out
|
|
288
|
+
* conventionally — an `overrides` entry appearing before it would win, and that
|
|
289
|
+
* is the known limit.
|
|
290
|
+
*
|
|
291
|
+
* Getting it wrong costs exactly what getting it absent costs today: the
|
|
292
|
+
* adopter's formatter rewraps on first commit. So a heuristic that is usually
|
|
293
|
+
* right strictly improves on no detection, and can break nothing.
|
|
294
|
+
*/
|
|
295
|
+
export function findPrettierPrintWidth(rootDir, probe) {
|
|
296
|
+
const manifest = probe.readJson(path.join(rootDir, 'package.json'));
|
|
297
|
+
if (isJsonObject(manifest) && isJsonObject(manifest.prettier) && typeof manifest.prettier.printWidth === 'number') {
|
|
298
|
+
return manifest.prettier.printWidth;
|
|
299
|
+
}
|
|
300
|
+
const present = probe.listFiles(rootDir);
|
|
301
|
+
for (const file of present.filter(name => name === '.prettierrc' || name === '.prettierrc.json')) {
|
|
302
|
+
const parsed = probe.readJson(path.join(rootDir, file));
|
|
303
|
+
if (isJsonObject(parsed) && typeof parsed.printWidth === 'number') {
|
|
304
|
+
return parsed.printWidth;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
for (const file of present.filter(name => /^(\.prettierrc\.[cm]?[jt]s|prettier\.config\.[cm]?[jt]s)$/.test(name))) {
|
|
308
|
+
const width = /\bprintWidth\s*:\s*(\d+)/.exec(probe.readText(path.join(rootDir, file)) ?? '');
|
|
309
|
+
if (width) {
|
|
310
|
+
return Number(width[1]);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return undefined;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* The root eslint config's filename, when the repo has one.
|
|
317
|
+
*
|
|
318
|
+
* Read to decide whether the scaffold emits a `lint` script. The failure it
|
|
319
|
+
* prevents is silent in the direction that matters: a task runner runs a script
|
|
320
|
+
* only where one is declared, so a package without `lint` is SKIPPED rather than
|
|
321
|
+
* reported, and the absence reads as a clean lint. Emitting the script into a
|
|
322
|
+
* repo whose lint invocation differs costs one visible line to edit.
|
|
323
|
+
*
|
|
324
|
+
* Both config generations, because detecting a repo that has not migrated off
|
|
325
|
+
* `.eslintrc` is free and the question asked here — does this repo lint? — is
|
|
326
|
+
* the same either way.
|
|
327
|
+
*/
|
|
328
|
+
export function findEslintConfig(rootDir, probe) {
|
|
329
|
+
return probe.listFiles(rootDir).find(name => /^eslint\.config\.[cm]?[jt]s$/.test(name) || /^\.eslintrc(\..+)?$/.test(name));
|
|
330
|
+
}
|
|
331
|
+
/** POSIX-style relative path, which is what both `extends` and `--prefix` want on every platform. */
|
|
332
|
+
function posixRelative(from, to) {
|
|
333
|
+
return path.relative(from, to).split(path.sep).join('/');
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Detect the workspace `targetDir` would join. `undefined` when no ancestor
|
|
337
|
+
* declares `workspaces`, which is the standalone case and not an error here —
|
|
338
|
+
* `runInit` decides whether that is fatal.
|
|
339
|
+
*
|
|
340
|
+
* The target is resolved against the process's working directory, so a relative
|
|
341
|
+
* one is relative to where the command was RUN, not to anything the scaffolder
|
|
342
|
+
* picks. That matters because the two are routinely different directories.
|
|
343
|
+
*/
|
|
344
|
+
export function detectWorkspace(targetDir, probe) {
|
|
345
|
+
const absoluteTarget = path.resolve(targetDir);
|
|
346
|
+
const rootDir = findWorkspaceRoot(absoluteTarget, probe);
|
|
347
|
+
if (rootDir === undefined) {
|
|
348
|
+
return undefined;
|
|
349
|
+
}
|
|
350
|
+
const workspaces = readWorkspaces(rootDir, probe);
|
|
351
|
+
const targetPath = posixRelative(rootDir, absoluteTarget);
|
|
352
|
+
// The target IS the workspace root — `init .` at the top of a monorepo, or a
|
|
353
|
+
// target that resolved to the cwd because it was empty. There is no member to
|
|
354
|
+
// place, so reporting a placement here describes a scaffold that cannot
|
|
355
|
+
// happen and names a directory the user never asked for.
|
|
356
|
+
if (targetPath === '') {
|
|
357
|
+
return undefined;
|
|
358
|
+
}
|
|
359
|
+
const base = findBaseTsconfig(rootDir, probe);
|
|
360
|
+
return {
|
|
361
|
+
rootDir,
|
|
362
|
+
workspaces,
|
|
363
|
+
targetPath,
|
|
364
|
+
coveredBy: workspaces.find(glob => workspaceGlobCovers(glob, targetPath)),
|
|
365
|
+
scope: inferPackageScope(rootDir, workspaces, probe),
|
|
366
|
+
baseTsconfig: base && posixRelative(absoluteTarget, path.join(rootDir, base.file)),
|
|
367
|
+
baseCompilerOptions: base?.compilerOptions,
|
|
368
|
+
printWidth: findPrettierPrintWidth(rootDir, probe),
|
|
369
|
+
eslintConfig: findEslintConfig(rootDir, probe)
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
//# sourceMappingURL=init-workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-workspace.js","sourceRoot":"","sources":["../../src/commands/init-workspace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 CrossBreeze, EclipseSource and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the MIT License which is available in the project root.
|
|
6
|
+
*
|
|
7
|
+
* SPDX-License-Identifier: MIT
|
|
8
|
+
********************************************************************************/
|
|
9
|
+
import { type JsonValue, type WorkspaceProbe } from './init-workspace.js';
|
|
10
|
+
/**
|
|
11
|
+
* The protocol heads a scaffold can start, in composition order.
|
|
12
|
+
*
|
|
13
|
+
* `lsp` is mandatory rather than optional: it owns the workspace, the build
|
|
14
|
+
* pipeline and the shared service tier every other head reads through, so a
|
|
15
|
+
* project without it has nothing for `data` or `glsp` to serve.
|
|
16
|
+
*/
|
|
17
|
+
export declare const INIT_HEADS: readonly ["lsp", "data", "glsp"];
|
|
18
|
+
/** One protocol head — see {@link INIT_HEADS}. */
|
|
19
|
+
export type InitHead = (typeof INIT_HEADS)[number];
|
|
20
|
+
/** The heads a scaffold emits when `--heads` is not given. */
|
|
21
|
+
export declare const DEFAULT_INIT_HEADS: readonly InitHead[];
|
|
22
|
+
/** True for a string naming one of {@link INIT_HEADS}. */
|
|
23
|
+
export declare function isInitHead(value: string): value is InitHead;
|
|
24
|
+
/**
|
|
25
|
+
* One grammar as the command line collected it, before any derivation.
|
|
26
|
+
*
|
|
27
|
+
* Everything but {@link name} is optional: the derivation rules produce a usable
|
|
28
|
+
* routing key and extension from the project and grammar names alone. An
|
|
29
|
+
* override is for the case derivation cannot reach — a file extension that is
|
|
30
|
+
* not the kebab grammar name.
|
|
31
|
+
*/
|
|
32
|
+
export interface InitGrammarSpec {
|
|
33
|
+
/** PascalCase grammar name — the `grammar X` declaration. */
|
|
34
|
+
readonly name: string;
|
|
35
|
+
/**
|
|
36
|
+
* File extensions, leading dot optional. Defaults to the kebab grammar id.
|
|
37
|
+
*
|
|
38
|
+
* A list rather than a single value because `langium-config.json`'s
|
|
39
|
+
* `fileExtensions` is a list: one language may answer for several suffixes.
|
|
40
|
+
*/
|
|
41
|
+
readonly extensions?: readonly string[];
|
|
42
|
+
/** Override the derived routing key. */
|
|
43
|
+
readonly languageId?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Scaffold a GLSP diagram for this grammar. Requires the `glsp` head.
|
|
46
|
+
*
|
|
47
|
+
* Per grammar rather than per project because
|
|
48
|
+
* `AbstractHydraniumGlspDiagramModule.declareLanguage()` returns ONE grammar's
|
|
49
|
+
* `LanguageMetaData` — a diagram type has exactly one grammar, and a grammar
|
|
50
|
+
* with no diagram sitting on the same server is the normal case.
|
|
51
|
+
*/
|
|
52
|
+
readonly diagram?: boolean;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The resolved names of ONE grammar — the per-language tier.
|
|
56
|
+
*
|
|
57
|
+
* Everything here gains a sibling per additional grammar, which is what
|
|
58
|
+
* separates it from {@link InitComposition}'s project-level fields. The
|
|
59
|
+
* generated-symbol split is the reason the tiers cannot be collapsed:
|
|
60
|
+
* `langium-cli` emits `<grammar>GeneratedModule` and `<grammar>LanguageMetaData`
|
|
61
|
+
* per grammar, but `<projectName>AstReflection` and
|
|
62
|
+
* `<projectName>GeneratedSharedModule` once per project.
|
|
63
|
+
*/
|
|
64
|
+
export interface InitGrammarNames {
|
|
65
|
+
/** PascalCase grammar name — the `grammar X` declaration. */
|
|
66
|
+
readonly grammar: string;
|
|
67
|
+
/** Kebab grammar id — names the `.langium` file. */
|
|
68
|
+
readonly grammarId: string;
|
|
69
|
+
/**
|
|
70
|
+
* Kebab routing key — the `langium-config.json` entry id.
|
|
71
|
+
*
|
|
72
|
+
* Qualified as `<projectId>-<grammarId>` whenever the grammar is separately
|
|
73
|
+
* named or the project holds more than one, because a second grammar needs a
|
|
74
|
+
* second id and retro-fitting the suffix later renames a routing key every
|
|
75
|
+
* host has already bound.
|
|
76
|
+
*/
|
|
77
|
+
readonly languageId: string;
|
|
78
|
+
/** File extensions without leading dots. At least one. */
|
|
79
|
+
readonly extensions: readonly string[];
|
|
80
|
+
/**
|
|
81
|
+
* The grammar's entry rule, always `<Grammar>Model`.
|
|
82
|
+
*
|
|
83
|
+
* **Derived rather than fixed, because one `langium-cli` run over N grammars
|
|
84
|
+
* emits ONE combined `ast.ts` sharing one reflection.** Two grammars both
|
|
85
|
+
* declaring `entry Model:` would put the same interface name in that module
|
|
86
|
+
* twice.
|
|
87
|
+
*/
|
|
88
|
+
readonly entryRule: string;
|
|
89
|
+
/**
|
|
90
|
+
* The starter node rule, always `<Grammar>Node`.
|
|
91
|
+
*
|
|
92
|
+
* **`Node` and not `Element`:** the transfer-model generator emits
|
|
93
|
+
* `export interface <projectName>Element` as the base type every rule
|
|
94
|
+
* extends, so a rule named `<Grammar>Element` would collide with it in the
|
|
95
|
+
* single-grammar case — the same interface declared twice, the second
|
|
96
|
+
* extending itself.
|
|
97
|
+
*/
|
|
98
|
+
readonly nodeRule: string;
|
|
99
|
+
/** Whether a GLSP diagram is scaffolded for this grammar. */
|
|
100
|
+
readonly diagram: boolean;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Where a scaffold sits inside an existing npm workspace.
|
|
104
|
+
*
|
|
105
|
+
* Detected rather than asked, because both members are things a wrong answer
|
|
106
|
+
* makes actively broken rather than merely unidiomatic: a `--prefix` that names
|
|
107
|
+
* the wrong directory runs the wrong package's scripts, and an `extends` that
|
|
108
|
+
* points at a *solution* tsconfig (`files: []` plus `references`, which is what
|
|
109
|
+
* a monorepo root usually has) inherits no compiler options at all.
|
|
110
|
+
*/
|
|
111
|
+
export interface InitWorkspacePlacement {
|
|
112
|
+
/** POSIX path of the target relative to the workspace root, e.g. `packages/foo`. */
|
|
113
|
+
readonly targetPath: string;
|
|
114
|
+
/** Relative specifier of the tsconfig carrying `compilerOptions`, e.g. `../../tsconfig.base.json`. */
|
|
115
|
+
readonly baseTsconfig?: string;
|
|
116
|
+
/** That tsconfig's `compilerOptions`, so the emitted one can omit what it would inherit unchanged. */
|
|
117
|
+
readonly baseCompilerOptions?: Readonly<Record<string, JsonValue>>;
|
|
118
|
+
/** The workspace's prettier `printWidth`, so emitted sources wrap where the repo wraps. */
|
|
119
|
+
readonly printWidth?: number;
|
|
120
|
+
/** Filename of the workspace's eslint config; its presence is what makes the scaffold emit a `lint` script. */
|
|
121
|
+
readonly eslintConfig?: string;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* How the emitted `package.json` presents itself.
|
|
125
|
+
*
|
|
126
|
+
* Separate from {@link InitWorkspacePlacement} because the two answer to
|
|
127
|
+
* different authorities: the placement is *detected* from the surrounding tree,
|
|
128
|
+
* while the scope and the publishability are **intent** and are never inferred —
|
|
129
|
+
* a repo's root manifest is routinely named for the repo rather than for the
|
|
130
|
+
* scope it publishes under, so guessing would confidently produce the wrong
|
|
131
|
+
* package name. The wizard offers a sibling-derived default; the flags decide.
|
|
132
|
+
*
|
|
133
|
+
* This is the one place the two polarities meet: every option surface upstream
|
|
134
|
+
* carries `public`, because a flag names a DEVIATION from the default, while
|
|
135
|
+
* this type carries `private`, because that is the manifest key the template
|
|
136
|
+
* substitutes.
|
|
137
|
+
*/
|
|
138
|
+
export interface InitPackaging {
|
|
139
|
+
/** npm scope for the package name, e.g. `@acme`. Absent leaves it unscoped. */
|
|
140
|
+
readonly scope?: string;
|
|
141
|
+
/** Emit `"private": true` — a package npm refuses to publish. */
|
|
142
|
+
readonly private: boolean;
|
|
143
|
+
/** The workspace the package joins. Absent for a standalone project. */
|
|
144
|
+
readonly workspace?: InitWorkspacePlacement;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* A standalone, unscoped, unpublishable package — what `init` emits without the
|
|
148
|
+
* packaging flags.
|
|
149
|
+
*
|
|
150
|
+
* `private` defaults to TRUE because the manifest also declares `license:
|
|
151
|
+
* "UNLICENSED"`, and a package that grants no rights while being publishable to
|
|
152
|
+
* a public registry asserts two contradictory things about itself. npm pairs
|
|
153
|
+
* those two keys for exactly this reason. The scaffold cannot pick a licence for
|
|
154
|
+
* a stranger's project, so it withholds publication instead of granting rights
|
|
155
|
+
* nobody chose; `--public` is the opt-out for a project that has picked one.
|
|
156
|
+
*/
|
|
157
|
+
export declare const STANDALONE_PACKAGING: InitPackaging;
|
|
158
|
+
/**
|
|
159
|
+
* The full scaffold description: one project tier, N grammar tiers. Templates
|
|
160
|
+
* read this and are rendered per tier.
|
|
161
|
+
*/
|
|
162
|
+
export interface InitComposition {
|
|
163
|
+
/** PascalCase project name — the Langium `projectName`. */
|
|
164
|
+
readonly name: string;
|
|
165
|
+
/**
|
|
166
|
+
* Kebab project id, always derived from {@link name} and never from a
|
|
167
|
+
* language id. Names what a second grammar must not rename: the package and
|
|
168
|
+
* `bin` key, the DI module file, and the data-server port command (there is
|
|
169
|
+
* one data server per project, not one per language).
|
|
170
|
+
*/
|
|
171
|
+
readonly projectId: string;
|
|
172
|
+
/** The protocol heads to start, always including `lsp`. */
|
|
173
|
+
readonly heads: readonly InitHead[];
|
|
174
|
+
/** The grammars, in the order given. The first is the configuration root. */
|
|
175
|
+
readonly grammars: readonly InitGrammarNames[];
|
|
176
|
+
/** How the emitted `package.json` presents itself, and where it sits. */
|
|
177
|
+
readonly packaging: InitPackaging;
|
|
178
|
+
/**
|
|
179
|
+
* The framework version every emitted `@hydranium/*` pin is derived from —
|
|
180
|
+
* the scaffolding CLI's own, since the scope is versioned as one line.
|
|
181
|
+
*
|
|
182
|
+
* Carried on the composition rather than read where the templates render, so
|
|
183
|
+
* {@link planInitFiles} stays pure over its input. That is what lets a golden
|
|
184
|
+
* pin the emitted shape at a fixed token without pinning the number, which
|
|
185
|
+
* would otherwise turn every release into a red suite.
|
|
186
|
+
*/
|
|
187
|
+
readonly frameworkVersion: string;
|
|
188
|
+
}
|
|
189
|
+
/** One file the scaffold writes: relative path + fully-substituted content. */
|
|
190
|
+
export interface InitFile {
|
|
191
|
+
path: string;
|
|
192
|
+
content: string;
|
|
193
|
+
}
|
|
194
|
+
/** Options for the {@link runInit} subcommand. */
|
|
195
|
+
export interface InitCommandOptions {
|
|
196
|
+
/** Target directory to scaffold into. */
|
|
197
|
+
readonly targetDir: string;
|
|
198
|
+
/** PascalCase project name (drives the services + shared generated module names). */
|
|
199
|
+
readonly name: string;
|
|
200
|
+
/**
|
|
201
|
+
* The grammars to scaffold, in order. Defaults to a single grammar named
|
|
202
|
+
* after the project, which is the single-language starter shape.
|
|
203
|
+
*/
|
|
204
|
+
readonly grammars?: readonly InitGrammarSpec[];
|
|
205
|
+
/** The protocol heads to start. Defaults to {@link DEFAULT_INIT_HEADS}. */
|
|
206
|
+
readonly heads?: readonly InitHead[];
|
|
207
|
+
/** Scaffold into a non-empty directory anyway. */
|
|
208
|
+
readonly force?: boolean;
|
|
209
|
+
/**
|
|
210
|
+
* Scaffold a member of the surrounding npm workspace: extend its base
|
|
211
|
+
* tsconfig, leave `.gitignore` to the root, and address the package by
|
|
212
|
+
* `--prefix` in the scripts it prints back at itself. Errors when no ancestor
|
|
213
|
+
* declares `workspaces`, rather than silently degrading to a standalone
|
|
214
|
+
* project the caller did not ask for.
|
|
215
|
+
*/
|
|
216
|
+
readonly monorepo?: boolean;
|
|
217
|
+
/** npm scope for the package name, e.g. `@acme`. */
|
|
218
|
+
readonly scope?: string;
|
|
219
|
+
/** Omit `"private": true`, leaving the package publishable. */
|
|
220
|
+
readonly public?: boolean;
|
|
221
|
+
/** Output sink. Default: `process.stdout.write`. Tests inject a capturing stub. */
|
|
222
|
+
readonly write?: (line: string) => void;
|
|
223
|
+
/** Filesystem port for workspace detection. Default: the real filesystem. */
|
|
224
|
+
readonly probe?: WorkspaceProbe;
|
|
225
|
+
/** Test-only: capture the planned files instead of writing to disk. */
|
|
226
|
+
readonly __writeFilesForTest?: (targetDir: string, files: readonly InitFile[]) => void;
|
|
227
|
+
}
|
|
228
|
+
/** Kebab-case a PascalCase/camelCase name. */
|
|
229
|
+
export declare function kebab(name: string): string;
|
|
230
|
+
/**
|
|
231
|
+
* Derive the whole scaffold description from `--name` plus the collected
|
|
232
|
+
* grammars. Throws on a name that is not a valid PascalCase identifier — both
|
|
233
|
+
* project and grammar names become prefixes of generated TypeScript symbols.
|
|
234
|
+
*
|
|
235
|
+
* With no grammars given, one is synthesised from the project name, which is
|
|
236
|
+
* the single-language starter shape.
|
|
237
|
+
*/
|
|
238
|
+
export declare function resolveInitComposition(name: string, grammars?: readonly InitGrammarSpec[], heads?: readonly InitHead[], packaging?: InitPackaging): InitComposition;
|
|
239
|
+
/**
|
|
240
|
+
* Plan the files a scaffold emits — every template rendered for this
|
|
241
|
+
* composition. Pure over its input → unit-testable without touching disk;
|
|
242
|
+
* {@link runInit} is the thin IO wrapper.
|
|
243
|
+
*/
|
|
244
|
+
export declare function planInitFiles(composition: InitComposition): InitFile[];
|
|
245
|
+
/** True when `dir` exists and contains at least one entry. */
|
|
246
|
+
export declare function isNonEmptyDir(dir: string): boolean;
|
|
247
|
+
/** The packaging flags, plus the workspace they were given in. */
|
|
248
|
+
export interface InitPackagingOptions {
|
|
249
|
+
readonly monorepo?: boolean;
|
|
250
|
+
readonly scope?: string;
|
|
251
|
+
readonly public?: boolean;
|
|
252
|
+
readonly probe?: WorkspaceProbe;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Resolve the packaging tier for a target directory, running workspace
|
|
256
|
+
* detection when `--monorepo` asked for it.
|
|
257
|
+
*
|
|
258
|
+
* Exported because the `init`-provenance gate re-runs the reference example's
|
|
259
|
+
* recorded invocation and must reach the same composition `runInit` would: a
|
|
260
|
+
* second copy of these rules there would drift from these, and the gate exists
|
|
261
|
+
* precisely to catch drift.
|
|
262
|
+
*/
|
|
263
|
+
export declare function resolveInitPackaging(targetDir: string, options: InitPackagingOptions): InitPackaging;
|
|
264
|
+
/**
|
|
265
|
+
* Scaffold a new Hydranium language project end-to-end: one starter grammar per
|
|
266
|
+
* `--grammar`, `create<Name>Services` DI wiring, a launcher for each head in
|
|
267
|
+
* `--heads`, `langium-config.json`, `package.json`, and scripts. Does NOT run `npm install`
|
|
268
|
+
* or `langium generate` — those are printed as next steps, so the command stays
|
|
269
|
+
* offline and side-effect-free beyond the files it writes. Refuses a non-empty
|
|
270
|
+
* target directory unless `force`.
|
|
271
|
+
*/
|
|
272
|
+
export declare function runInit(options: InitCommandOptions): void;
|
|
273
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|