@intentius/chant 0.1.4 → 0.1.6
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/bin/chant +1 -10
- package/package.json +4 -5
- package/src/attrref.test.ts +1 -1
- package/src/bench.test.ts +1 -1
- package/src/build.test.ts +3 -5
- package/src/builder.test.ts +1 -1
- package/src/cli/commands/__fixtures__/init-lexicon-output/justfile +8 -8
- package/src/cli/commands/__fixtures__/init-lexicon-output/package.json +4 -4
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/codegen/generate-cli.ts +1 -1
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/plugin.ts +3 -3
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/validate-cli.ts +1 -1
- package/src/cli/commands/__snapshots__/init-lexicon.test.ts.snap +7 -7
- package/src/cli/commands/build.test.ts +1 -1
- package/src/cli/commands/diff.test.ts +1 -1
- package/src/cli/commands/doctor.test.ts +1 -1
- package/src/cli/commands/doctor.ts +7 -7
- package/src/cli/commands/import.test.ts +1 -1
- package/src/cli/commands/init-lexicon/templates/codegen.ts +1 -1
- package/src/cli/commands/init-lexicon/templates/plugin.ts +3 -3
- package/src/cli/commands/init-lexicon/templates/project.ts +13 -13
- package/src/cli/commands/init-lexicon/templates/tests.ts +4 -4
- package/src/cli/commands/init-lexicon.test.ts +2 -2
- package/src/cli/commands/init-lexicon.ts +1 -1
- package/src/cli/commands/init.test.ts +1 -1
- package/src/cli/commands/init.ts +1 -2
- package/src/cli/commands/lint.test.ts +3 -3
- package/src/cli/commands/list.test.ts +2 -2
- package/src/cli/commands/onboard.test.ts +33 -33
- package/src/cli/commands/onboard.ts +13 -13
- package/src/cli/commands/update.test.ts +1 -1
- package/src/cli/conflict-check.test.ts +7 -2
- package/src/cli/format.test.ts +1 -1
- package/src/cli/lsp/server.test.ts +8 -4
- package/src/cli/main.test.ts +1 -1
- package/src/cli/main.ts +6 -5
- package/src/cli/mcp/server.test.ts +1 -1
- package/src/cli/plugins.test.ts +1 -1
- package/src/cli/reporters/stylish.test.ts +1 -1
- package/src/cli/watch.test.ts +1 -1
- package/src/codegen/docs-interpolation.test.ts +3 -3
- package/src/codegen/docs-rules.test.ts +1 -1
- package/src/codegen/docs.ts +1 -1
- package/src/codegen/fetch.test.ts +1 -1
- package/src/codegen/generate-registry.test.ts +1 -1
- package/src/codegen/generate-runtime-index.test.ts +1 -1
- package/src/codegen/generate-typescript.test.ts +1 -1
- package/src/codegen/generate.test.ts +1 -1
- package/src/codegen/json-patch.test.ts +1 -1
- package/src/codegen/json-schema.test.ts +1 -1
- package/src/codegen/topo-sort.test.ts +1 -1
- package/src/codegen/typecheck.test.ts +1 -1
- package/src/codegen/typecheck.ts +18 -5
- package/src/codegen/validate.test.ts +1 -1
- package/src/composite.test.ts +17 -16
- package/src/composite.ts +5 -4
- package/src/config.test.ts +3 -3
- package/src/config.ts +0 -4
- package/src/declarable.test.ts +1 -1
- package/src/detectLexicon.test.ts +1 -1
- package/src/discovery/cache.test.ts +1 -1
- package/src/discovery/collect.test.ts +1 -1
- package/src/discovery/cycles.test.ts +1 -1
- package/src/discovery/files.test.ts +1 -1
- package/src/discovery/graph.test.ts +1 -1
- package/src/discovery/import.test.ts +4 -3
- package/src/discovery/index.test.ts +1 -1
- package/src/discovery/resolve.test.ts +1 -1
- package/src/errors.test.ts +1 -1
- package/src/import/base-parser.test.ts +1 -1
- package/src/import/ir-utils.test.ts +1 -1
- package/src/index.ts +4 -0
- package/src/intrinsic-interpolation.test.ts +1 -1
- package/src/intrinsic.test.ts +1 -1
- package/src/lexicon-integrity.test.ts +2 -2
- package/src/lexicon-manifest.test.ts +1 -1
- package/src/lexicon-output.test.ts +1 -1
- package/src/lexicon-schema.test.ts +1 -1
- package/src/lint/config-overrides.test.ts +2 -2
- package/src/lint/config.test.ts +2 -2
- package/src/lint/config.ts +1 -1
- package/src/lint/declarative.test.ts +1 -1
- package/src/lint/discover.test.ts +1 -1
- package/src/lint/discover.ts +10 -0
- package/src/lint/engine.test.ts +1 -1
- package/src/lint/named-checks.test.ts +1 -1
- package/src/lint/parser.test.ts +2 -2
- package/src/lint/post-synth.test.ts +1 -1
- package/src/lint/rule-loader.test.ts +2 -2
- package/src/lint/rule-options.test.ts +2 -2
- package/src/lint/rule-registry.test.ts +1 -1
- package/src/lint/rule.test.ts +1 -1
- package/src/lint/rules/cor017-composite-name-match.test.ts +1 -1
- package/src/lint/rules/cor018-composite-prefer-lexicon-type.test.ts +1 -1
- package/src/lint/rules/declarable-naming-convention.test.ts +1 -1
- package/src/lint/rules/evl001-non-literal-expression.test.ts +1 -1
- package/src/lint/rules/evl002-control-flow-resource.test.ts +1 -1
- package/src/lint/rules/evl003-dynamic-property-access.test.ts +1 -1
- package/src/lint/rules/evl004-spread-non-const.test.ts +1 -1
- package/src/lint/rules/evl005-resource-block-body.test.ts +1 -1
- package/src/lint/rules/evl007-invalid-siblings.test.ts +1 -1
- package/src/lint/rules/evl009-composite-no-constant.test.ts +1 -1
- package/src/lint/rules/evl010-composite-no-transform.test.ts +1 -1
- package/src/lint/rules/export-required.test.ts +1 -1
- package/src/lint/rules/file-declarable-limit.test.ts +1 -1
- package/src/lint/rules/flat-declarations.test.ts +1 -1
- package/src/lint/rules/no-cyclic-declarable-ref.test.ts +1 -1
- package/src/lint/rules/no-redundant-type-import.test.ts +1 -1
- package/src/lint/rules/no-redundant-value-cast.test.ts +1 -1
- package/src/lint/rules/no-string-ref.test.ts +1 -1
- package/src/lint/rules/no-unused-declarable-import.test.ts +1 -1
- package/src/lint/rules/no-unused-declarable.test.ts +1 -1
- package/src/lint/rules/single-concern-file.test.ts +1 -1
- package/src/lint/selectors.test.ts +1 -1
- package/src/op/builders.ts +96 -0
- package/src/op/index.ts +4 -0
- package/src/op/op.test.ts +199 -0
- package/src/op/resource.ts +8 -0
- package/src/op/types.ts +66 -0
- package/src/project-validation.test.ts +2 -2
- package/src/pseudo-parameter.test.ts +1 -1
- package/src/resource-attributes.test.ts +2 -2
- package/src/runtime-adapter.ts +13 -68
- package/src/serializer-walker.test.ts +2 -1
- package/src/sort.test.ts +1 -1
- package/src/stack-output.ts +2 -2
- package/src/toml.test.ts +2 -2
- package/src/types.test.ts +1 -1
- package/src/utils.test.ts +1 -1
- package/src/utils.ts +2 -2
- package/src/validation.test.ts +1 -1
- package/src/yaml.test.ts +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect, beforeEach, afterEach } from "
|
|
1
|
+
import { describe, test, expect, beforeEach, afterEach } from "vitest";
|
|
2
2
|
import { mkdirSync, writeFileSync, readFileSync, rmSync } from "fs";
|
|
3
3
|
import { join } from "path";
|
|
4
4
|
import { tmpdir } from "os";
|
|
@@ -64,32 +64,32 @@ jobs:
|
|
|
64
64
|
steps:
|
|
65
65
|
- name: Generate lexicon artifacts
|
|
66
66
|
run: |
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
npm run --prefix lexicons/aws prepack
|
|
68
|
+
npm run --prefix lexicons/gitlab prepack
|
|
69
|
+
npm run --prefix lexicons/k8s prepack
|
|
70
70
|
- name: Run tests
|
|
71
|
-
run:
|
|
71
|
+
run: npx vitest run
|
|
72
72
|
|
|
73
73
|
test:
|
|
74
74
|
steps:
|
|
75
75
|
- name: Generate lexicon artifacts
|
|
76
76
|
run: |
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
npm run --prefix lexicons/aws prepack
|
|
78
|
+
npm run --prefix lexicons/gitlab prepack
|
|
79
|
+
npm run --prefix lexicons/k8s prepack
|
|
80
80
|
- name: Run tests
|
|
81
|
-
run:
|
|
81
|
+
run: npx vitest run
|
|
82
82
|
|
|
83
83
|
validate:
|
|
84
84
|
steps:
|
|
85
85
|
- name: Generate and validate AWS lexicon
|
|
86
|
-
run:
|
|
86
|
+
run: npm run --prefix lexicons/aws prepack
|
|
87
87
|
|
|
88
88
|
- name: Generate and validate GitLab lexicon
|
|
89
|
-
run:
|
|
89
|
+
run: npm run --prefix lexicons/gitlab prepack
|
|
90
90
|
|
|
91
91
|
- name: Generate and validate K8s lexicon
|
|
92
|
-
run:
|
|
92
|
+
run: npm run --prefix lexicons/k8s prepack
|
|
93
93
|
`;
|
|
94
94
|
|
|
95
95
|
test("inserts prepack line in multi-line blocks", () => {
|
|
@@ -105,7 +105,7 @@ jobs:
|
|
|
105
105
|
for (let i = 0; i <= lines.length; i++) {
|
|
106
106
|
const isPrepack =
|
|
107
107
|
i < lines.length &&
|
|
108
|
-
lines[i].includes("
|
|
108
|
+
lines[i].includes("npm run --prefix lexicons/") &&
|
|
109
109
|
lines[i].includes("prepack");
|
|
110
110
|
if (isPrepack && groupStart === -1) {
|
|
111
111
|
groupStart = i;
|
|
@@ -155,13 +155,13 @@ jobs:
|
|
|
155
155
|
const block = [
|
|
156
156
|
"",
|
|
157
157
|
" - name: Generate and validate Terraform lexicon",
|
|
158
|
-
" run:
|
|
158
|
+
" run: npm run --prefix lexicons/terraform prepack",
|
|
159
159
|
];
|
|
160
160
|
lines.splice(lastValidateRunIdx + 1, 0, ...block);
|
|
161
161
|
const result = lines.join("\n");
|
|
162
162
|
|
|
163
163
|
expect(result).toContain("Generate and validate Terraform lexicon");
|
|
164
|
-
expect(result).toContain("
|
|
164
|
+
expect(result).toContain("npm run --prefix lexicons/terraform prepack");
|
|
165
165
|
});
|
|
166
166
|
});
|
|
167
167
|
|
|
@@ -175,20 +175,20 @@ on:
|
|
|
175
175
|
jobs:
|
|
176
176
|
test:
|
|
177
177
|
steps:
|
|
178
|
-
- run:
|
|
179
|
-
- run:
|
|
180
|
-
- run:
|
|
181
|
-
- run:
|
|
178
|
+
- run: npm run --prefix lexicons/aws prepack
|
|
179
|
+
- run: npm run --prefix lexicons/gitlab prepack
|
|
180
|
+
- run: npm run --prefix lexicons/k8s prepack
|
|
181
|
+
- run: npx vitest run
|
|
182
182
|
|
|
183
183
|
publish:
|
|
184
184
|
steps:
|
|
185
185
|
- name: Publish @intentius/chant-lexicon-aws
|
|
186
186
|
working-directory: lexicons/aws
|
|
187
|
-
run:
|
|
187
|
+
run: npm publish --access public
|
|
188
188
|
|
|
189
189
|
- name: Publish @intentius/chant-lexicon-k8s
|
|
190
190
|
working-directory: lexicons/k8s
|
|
191
|
-
run:
|
|
191
|
+
run: npm publish --access public
|
|
192
192
|
`;
|
|
193
193
|
|
|
194
194
|
test("adds prepack line in test job", () => {
|
|
@@ -199,10 +199,10 @@ jobs:
|
|
|
199
199
|
// Find contiguous prepack group in test job
|
|
200
200
|
const insertAfter: number[] = [];
|
|
201
201
|
for (let i = 0; i < lines.length; i++) {
|
|
202
|
-
if (!lines[i].includes("
|
|
202
|
+
if (!lines[i].includes("npm run --prefix lexicons/") || !lines[i].includes("prepack")) continue;
|
|
203
203
|
const nextIsAlsoPrepack =
|
|
204
204
|
i + 1 < lines.length &&
|
|
205
|
-
lines[i + 1].includes("
|
|
205
|
+
lines[i + 1].includes("npm run --prefix lexicons/") &&
|
|
206
206
|
lines[i + 1].includes("prepack");
|
|
207
207
|
if (!nextIsAlsoPrepack) insertAfter.push(i);
|
|
208
208
|
}
|
|
@@ -224,7 +224,7 @@ jobs:
|
|
|
224
224
|
|
|
225
225
|
let lastPublishRunIdx = -1;
|
|
226
226
|
for (let i = 0; i < lines.length; i++) {
|
|
227
|
-
if (lines[i].includes("
|
|
227
|
+
if (lines[i].includes("npm publish --access public")) {
|
|
228
228
|
lastPublishRunIdx = i;
|
|
229
229
|
}
|
|
230
230
|
}
|
|
@@ -235,7 +235,7 @@ jobs:
|
|
|
235
235
|
"",
|
|
236
236
|
" - name: Publish @intentius/chant-lexicon-terraform",
|
|
237
237
|
" working-directory: lexicons/terraform",
|
|
238
|
-
" run:
|
|
238
|
+
" run: npm publish --access public",
|
|
239
239
|
];
|
|
240
240
|
lines.splice(lastPublishRunIdx + 1, 0, ...block);
|
|
241
241
|
const result = lines.join("\n");
|
|
@@ -248,13 +248,13 @@ jobs:
|
|
|
248
248
|
// ── Dockerfile ──────────────────────────────────────────
|
|
249
249
|
|
|
250
250
|
describe("Dockerfile patching", () => {
|
|
251
|
-
const dockerContent = `FROM
|
|
251
|
+
const dockerContent = `FROM node:22-slim
|
|
252
252
|
WORKDIR /app
|
|
253
253
|
COPY . .
|
|
254
|
-
RUN
|
|
255
|
-
RUN
|
|
256
|
-
RUN
|
|
257
|
-
RUN
|
|
254
|
+
RUN npm install
|
|
255
|
+
RUN npm run --prefix lexicons/aws prepack
|
|
256
|
+
RUN npm run --prefix lexicons/gitlab prepack
|
|
257
|
+
RUN npm run --prefix lexicons/k8s prepack
|
|
258
258
|
COPY test/integration.sh /app/test/integration.sh
|
|
259
259
|
`;
|
|
260
260
|
|
|
@@ -265,7 +265,7 @@ COPY test/integration.sh /app/test/integration.sh
|
|
|
265
265
|
|
|
266
266
|
let lastIdx = -1;
|
|
267
267
|
for (let i = 0; i < lines.length; i++) {
|
|
268
|
-
if (lines[i].includes("
|
|
268
|
+
if (lines[i].includes("npm run --prefix lexicons/") && lines[i].includes("prepack")) {
|
|
269
269
|
lastIdx = i;
|
|
270
270
|
}
|
|
271
271
|
}
|
|
@@ -276,7 +276,7 @@ COPY test/integration.sh /app/test/integration.sh
|
|
|
276
276
|
lines.splice(lastIdx + 1, 0, newLine);
|
|
277
277
|
const result = lines.join("\n");
|
|
278
278
|
|
|
279
|
-
expect(result).toContain("RUN
|
|
279
|
+
expect(result).toContain("RUN npm run --prefix lexicons/terraform prepack");
|
|
280
280
|
// Should come after k8s line
|
|
281
281
|
const k8sIdx = result.indexOf("lexicons/k8s prepack");
|
|
282
282
|
const tfIdx = result.indexOf("lexicons/terraform prepack");
|
|
@@ -284,7 +284,7 @@ COPY test/integration.sh /app/test/integration.sh
|
|
|
284
284
|
});
|
|
285
285
|
|
|
286
286
|
test("does not add duplicate", () => {
|
|
287
|
-
const withTerraform = dockerContent + "RUN
|
|
287
|
+
const withTerraform = dockerContent + "RUN npm run --prefix lexicons/terraform prepack\n";
|
|
288
288
|
writeFileSync(join(root, "test/Dockerfile.smoke"), withTerraform);
|
|
289
289
|
const content = readFileSync(join(root, "test/Dockerfile.smoke"), "utf-8");
|
|
290
290
|
|
|
@@ -64,7 +64,7 @@ function insertPrepackInContiguousGroups(lines: string[], name: string): boolean
|
|
|
64
64
|
for (let i = 0; i <= lines.length; i++) {
|
|
65
65
|
const isPrepack =
|
|
66
66
|
i < lines.length &&
|
|
67
|
-
lines[i].includes("
|
|
67
|
+
lines[i].includes("npm run --prefix lexicons/") &&
|
|
68
68
|
lines[i].includes("prepack");
|
|
69
69
|
if (isPrepack && groupStart === -1) {
|
|
70
70
|
groupStart = i;
|
|
@@ -97,10 +97,10 @@ function insertPrepackAfterEach(lines: string[], name: string): boolean {
|
|
|
97
97
|
|
|
98
98
|
const insertAfter: number[] = [];
|
|
99
99
|
for (let i = 0; i < lines.length; i++) {
|
|
100
|
-
if (!lines[i].includes("
|
|
100
|
+
if (!lines[i].includes("npm run --prefix lexicons/") || !lines[i].includes("prepack")) continue;
|
|
101
101
|
const nextIsAlsoPrepack =
|
|
102
102
|
i + 1 < lines.length &&
|
|
103
|
-
lines[i + 1].includes("
|
|
103
|
+
lines[i + 1].includes("npm run --prefix lexicons/") &&
|
|
104
104
|
lines[i + 1].includes("prepack");
|
|
105
105
|
if (!nextIsAlsoPrepack) {
|
|
106
106
|
insertAfter.push(i);
|
|
@@ -122,8 +122,8 @@ function insertPrepackAfterEach(lines: string[], name: string): boolean {
|
|
|
122
122
|
* and add a new validate step.
|
|
123
123
|
*
|
|
124
124
|
* The file has two patterns:
|
|
125
|
-
* 1. Multi-line blocks (check + test jobs): `run: |\n
|
|
126
|
-
* 2. Standalone steps (validate job): `- name: Generate and validate ...\n run:
|
|
125
|
+
* 1. Multi-line blocks (check + test jobs): `run: |\n npm run --prefix lexicons/aws prepack\n ...`
|
|
126
|
+
* 2. Standalone steps (validate job): `- name: Generate and validate ...\n run: npm run --prefix ...`
|
|
127
127
|
*
|
|
128
128
|
* We only insert into pattern 1 (contiguous groups) and separately add a new pattern 2 step.
|
|
129
129
|
*/
|
|
@@ -160,7 +160,7 @@ function patchCiWorkflow(root: string, name: string): { patched: boolean; reason
|
|
|
160
160
|
const block = [
|
|
161
161
|
"",
|
|
162
162
|
` - name: ${validateStepName}`,
|
|
163
|
-
` run:
|
|
163
|
+
` run: npm run --prefix lexicons/${name} prepack`,
|
|
164
164
|
];
|
|
165
165
|
lines.splice(lastValidateRunIdx + 1, 0, ...block);
|
|
166
166
|
}
|
|
@@ -190,7 +190,7 @@ function patchPublishWorkflow(root: string, name: string): { patched: boolean; r
|
|
|
190
190
|
// Add publish step after the last existing publish step
|
|
191
191
|
let lastPublishRunIdx = -1;
|
|
192
192
|
for (let i = 0; i < lines.length; i++) {
|
|
193
|
-
if (lines[i].includes("
|
|
193
|
+
if (lines[i].includes("npm publish --access public")) {
|
|
194
194
|
lastPublishRunIdx = i;
|
|
195
195
|
}
|
|
196
196
|
}
|
|
@@ -200,7 +200,7 @@ function patchPublishWorkflow(root: string, name: string): { patched: boolean; r
|
|
|
200
200
|
"",
|
|
201
201
|
` - name: Publish @intentius/chant-lexicon-${name}`,
|
|
202
202
|
` working-directory: lexicons/${name}`,
|
|
203
|
-
" run:
|
|
203
|
+
" run: npm publish --access public",
|
|
204
204
|
];
|
|
205
205
|
lines.splice(lastPublishRunIdx + 1, 0, ...block);
|
|
206
206
|
}
|
|
@@ -251,15 +251,15 @@ export function onboardCommand(options: OnboardOptions): OnboardResult {
|
|
|
251
251
|
|
|
252
252
|
// 4. Dockerfiles
|
|
253
253
|
const dockerBun = join(root, "test/Dockerfile.smoke");
|
|
254
|
-
const
|
|
254
|
+
const dockerNpm = join(root, "test/Dockerfile.smoke-npm");
|
|
255
255
|
|
|
256
256
|
const db = patchDockerfile(dockerBun, options.name);
|
|
257
257
|
if (db.patched) patched.push("Dockerfile.smoke (prepack)");
|
|
258
258
|
else skipped.push(`Dockerfile.smoke: ${db.reason}`);
|
|
259
259
|
|
|
260
|
-
const dn = patchDockerfile(
|
|
261
|
-
if (dn.patched) patched.push("Dockerfile.smoke-
|
|
262
|
-
else skipped.push(`Dockerfile.smoke-
|
|
260
|
+
const dn = patchDockerfile(dockerNpm, options.name);
|
|
261
|
+
if (dn.patched) patched.push("Dockerfile.smoke-npm (prepack)");
|
|
262
|
+
else skipped.push(`Dockerfile.smoke-npm: ${dn.reason}`);
|
|
263
263
|
|
|
264
264
|
return { success: true, patched, skipped };
|
|
265
265
|
}
|
|
@@ -293,7 +293,7 @@ export async function printOnboardResult(result: OnboardResult, name: string): P
|
|
|
293
293
|
console.log(` 1. Create an example: lexicons/${name}/examples/<example-name>/`);
|
|
294
294
|
console.log(` (must depend on @intentius/chant-lexicon-${name} for workspace resolution)`);
|
|
295
295
|
console.log(` 2. Add smoke tests to test/integration.sh`);
|
|
296
|
-
console.log(` 3. Run:
|
|
296
|
+
console.log(` 3. Run: npm install (to update workspace links)`);
|
|
297
297
|
console.log(` 4. First npm publish: tag with v<version> and push`);
|
|
298
298
|
console.log(` 5. Run: chant dev check-lexicon lexicons/${name} (to see completeness status)`);
|
|
299
299
|
console.log(formatWarning({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import { updateCommand } from "./update";
|
|
3
3
|
import { withTestDir } from "@intentius/chant-test-utils";
|
|
4
4
|
import { writeFileSync, mkdirSync, existsSync, readFileSync } from "fs";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { describe, test, expect } from "
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
2
|
import { checkConflicts } from "./conflict-check";
|
|
3
3
|
import type { LexiconPlugin } from "../lexicon";
|
|
4
4
|
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5
6
|
const mockSerializer = { name: "test", serialize: () => ({}) } as any;
|
|
6
7
|
|
|
7
8
|
const noopAsync = async () => {};
|
|
@@ -31,6 +32,7 @@ function makePlugin(
|
|
|
31
32
|
category: "correctness" as const,
|
|
32
33
|
check: () => [],
|
|
33
34
|
}));
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
34
36
|
(plugin as any).lintRules = () => rules;
|
|
35
37
|
}
|
|
36
38
|
|
|
@@ -40,6 +42,7 @@ function makePlugin(
|
|
|
40
42
|
description: "",
|
|
41
43
|
content: "",
|
|
42
44
|
}));
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
43
46
|
(plugin as any).skills = () => skills;
|
|
44
47
|
}
|
|
45
48
|
|
|
@@ -50,6 +53,7 @@ function makePlugin(
|
|
|
50
53
|
inputSchema: { type: "object" as const, properties: {} },
|
|
51
54
|
handler: async () => "",
|
|
52
55
|
}));
|
|
56
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
53
57
|
(plugin as any).mcpTools = () => tools;
|
|
54
58
|
}
|
|
55
59
|
|
|
@@ -60,6 +64,7 @@ function makePlugin(
|
|
|
60
64
|
description: "",
|
|
61
65
|
handler: async () => "",
|
|
62
66
|
}));
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
63
68
|
(plugin as any).mcpResources = () => resources;
|
|
64
69
|
}
|
|
65
70
|
|
|
@@ -261,7 +266,7 @@ describe("skill naming consistency", () => {
|
|
|
261
266
|
test("all skill names match chant-{lexicon}(-{topic})* pattern", async () => {
|
|
262
267
|
const { readdirSync, readFileSync } = await import("fs");
|
|
263
268
|
const { join } = await import("path");
|
|
264
|
-
const lexiconsDir = join(import.meta.
|
|
269
|
+
const lexiconsDir = join(import.meta.dirname, "../../../../lexicons");
|
|
265
270
|
const lexiconNames = readdirSync(lexiconsDir, { withFileTypes: true })
|
|
266
271
|
.filter((d) => d.isDirectory())
|
|
267
272
|
.map((d) => d.name);
|
package/src/cli/format.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect, beforeEach } from "
|
|
1
|
+
import { describe, test, expect, beforeEach, vi } from "vitest";
|
|
2
2
|
import { LspServer } from "./server";
|
|
3
3
|
import { computeCapabilities } from "./capabilities";
|
|
4
4
|
import { toLspDiagnostics } from "./diagnostics";
|
|
@@ -217,12 +217,16 @@ describe("LspServer", () => {
|
|
|
217
217
|
method: "textDocument/didOpen",
|
|
218
218
|
params: { textDocument: { uri: "file:///a.ts", text: "const x = 1;" } },
|
|
219
219
|
});
|
|
220
|
-
//
|
|
221
|
-
await
|
|
220
|
+
// Wait for async diagnostics to emit (dynamic import may take longer in Node.js)
|
|
221
|
+
await vi.waitFor(() => {
|
|
222
|
+
const diagNotif = server.sentNotifications.find(
|
|
223
|
+
(n) => n.method === "textDocument/publishDiagnostics",
|
|
224
|
+
);
|
|
225
|
+
expect(diagNotif).toBeDefined();
|
|
226
|
+
}, { timeout: 2000 });
|
|
222
227
|
const diagNotif = server.sentNotifications.find(
|
|
223
228
|
(n) => n.method === "textDocument/publishDiagnostics",
|
|
224
229
|
);
|
|
225
|
-
expect(diagNotif).toBeDefined();
|
|
226
230
|
expect(diagNotif!.params.uri).toBe("file:///a.ts");
|
|
227
231
|
});
|
|
228
232
|
});
|
package/src/cli/main.test.ts
CHANGED
package/src/cli/main.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
2
|
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { formatSuccess, formatError } from "./format";
|
|
@@ -234,10 +234,10 @@ async function main(): Promise<void> {
|
|
|
234
234
|
// Initialize runtime adapter early — before plugins or commands run
|
|
235
235
|
const projectPath0 = resolve(args.path === "." ? "." : args.path);
|
|
236
236
|
try {
|
|
237
|
-
|
|
238
|
-
initRuntime(
|
|
237
|
+
await loadChantConfig(projectPath0);
|
|
238
|
+
initRuntime();
|
|
239
239
|
} catch {
|
|
240
|
-
// Config may not exist yet (e.g. `chant init`)
|
|
240
|
+
// Config may not exist yet (e.g. `chant init`)
|
|
241
241
|
initRuntime();
|
|
242
242
|
}
|
|
243
243
|
|
|
@@ -263,7 +263,8 @@ async function main(): Promise<void> {
|
|
|
263
263
|
}
|
|
264
264
|
|
|
265
265
|
// Only run main when executed directly, not when imported
|
|
266
|
-
|
|
266
|
+
const isMain = import.meta.url === `file://${process.argv[1]}`;
|
|
267
|
+
if (isMain) {
|
|
267
268
|
main().catch((err) => {
|
|
268
269
|
const verbose = process.argv.includes("--verbose") || process.argv.includes("-v");
|
|
269
270
|
if (verbose && err instanceof Error && err.stack) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect, beforeEach, afterEach } from "
|
|
1
|
+
import { describe, test, expect, beforeEach, afterEach } from "vitest";
|
|
2
2
|
import { McpServer } from "./server";
|
|
3
3
|
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
4
4
|
import { join } from "node:path";
|
package/src/cli/plugins.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect, beforeEach, afterEach } from "
|
|
1
|
+
import { describe, test, expect, beforeEach, afterEach } from "vitest";
|
|
2
2
|
import { formatStylish, formatSummary, formatJson, formatSarif } from "./stylish";
|
|
3
3
|
import type { LintDiagnostic, LintRule } from "../../lint/rule";
|
|
4
4
|
|
package/src/cli/watch.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, test, expect, beforeAll, afterAll } from "
|
|
1
|
+
import { describe, test, expect, beforeAll, afterAll } from "vitest";
|
|
2
2
|
import { mkdtempSync, writeFileSync, mkdirSync, rmSync } from "fs";
|
|
3
3
|
import { join } from "path";
|
|
4
4
|
import { tmpdir } from "os";
|
|
@@ -29,8 +29,8 @@ describe("expandFileMarkers", () => {
|
|
|
29
29
|
expect(result).toContain('```typescript title="example.ts"');
|
|
30
30
|
expect(result).toContain('import { Bucket } from "@intentius/chant-lexicon-aws";');
|
|
31
31
|
expect(result).toContain("```");
|
|
32
|
-
expect(result
|
|
33
|
-
expect(result
|
|
32
|
+
expect(result.startsWith("Before\n\n")).toBe(true);
|
|
33
|
+
expect(result.endsWith("\n\nAfter")).toBe(true);
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
test("expands line range", () => {
|
package/src/codegen/docs.ts
CHANGED
|
@@ -148,7 +148,7 @@ export function writeDocsPages(result: DocsResult, outDir: string): void {
|
|
|
148
148
|
*
|
|
149
149
|
* Writes: package.json, astro.config.mjs, tsconfig.json, and all content
|
|
150
150
|
* pages under src/content/docs/. The resulting directory can be built with
|
|
151
|
-
* `
|
|
151
|
+
* `npm install && npm run build`.
|
|
152
152
|
*/
|
|
153
153
|
export function writeDocsSite(config: DocsConfig, result: DocsResult): void {
|
|
154
154
|
const outDir = config.outDir;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, expect, test } from "
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
2
|
import { buildRegistry, serializeRegistry, type RegistryResource, type RegistryConfig } from "./generate-registry";
|
|
3
3
|
import { NamingStrategy, type NamingInput, type NamingConfig } from "./naming";
|
|
4
4
|
|
package/src/codegen/typecheck.ts
CHANGED
|
@@ -4,8 +4,20 @@
|
|
|
4
4
|
import { writeFileSync, mkdirSync, rmSync } from "fs";
|
|
5
5
|
import { join } from "path";
|
|
6
6
|
import { tmpdir } from "os";
|
|
7
|
+
import { createRequire } from "module";
|
|
7
8
|
import { getRuntime } from "../runtime-adapter";
|
|
8
9
|
|
|
10
|
+
// Resolve tsc binary path — works regardless of cwd when spawning.
|
|
11
|
+
function resolveTsc(): string {
|
|
12
|
+
try {
|
|
13
|
+
const req = createRequire(import.meta.url);
|
|
14
|
+
const tscPkg = req.resolve("typescript/bin/tsc");
|
|
15
|
+
return tscPkg;
|
|
16
|
+
} catch {
|
|
17
|
+
return "tsc";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
9
21
|
/**
|
|
10
22
|
* Minimal TypeScript lib stub — declares just enough built-in types for
|
|
11
23
|
* validating generated .d.ts files without needing the full standard library.
|
|
@@ -94,12 +106,13 @@ export async function typecheckDTS(content: string): Promise<TypeCheckResult> {
|
|
|
94
106
|
};
|
|
95
107
|
writeFileSync(join(dir, "tsconfig.json"), JSON.stringify(tsconfig, null, 2));
|
|
96
108
|
|
|
97
|
-
// Run tsc
|
|
109
|
+
// Run tsc using absolute path to avoid npx/cwd resolution issues
|
|
98
110
|
const rt = getRuntime();
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
111
|
+
const tscBin = resolveTsc();
|
|
112
|
+
const cmd = tscBin === "tsc"
|
|
113
|
+
? [rt.commands.exec, "tsc", "--noEmit", "--project", "tsconfig.json"]
|
|
114
|
+
: [rt.commands.runner, tscBin, "--noEmit", "--project", "tsconfig.json"];
|
|
115
|
+
const { stdout, stderr, exitCode } = await rt.spawn(cmd, { cwd: dir });
|
|
103
116
|
|
|
104
117
|
// Parse diagnostics from stdout (tsc writes errors to stdout)
|
|
105
118
|
const output = stdout + stderr;
|