@askrjs/cli 0.0.20 → 0.0.22
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/dist/analyze.js +1 -1
- package/dist/cli.js +1 -1
- package/dist/create.js +1 -1
- package/dist/generate.js +3 -2
- package/dist/{guardrails-L60OAzIp.js → guardrails-BVxzrcBX.js} +1 -1
- package/dist/openapi.js +2 -1
- package/dist/{registry-BVliEbUv.js → registry-BmGIkoO0.js} +2 -1
- package/dist/{runner-CYvonJ0C.js → runner-D2iNzz9g.js} +72 -6
- package/dist/{runner-DzWc9R4G.js → runner-N2qHCBar.js} +3 -3
- package/dist/{skills-CSGdAZHN.js → skills-C72Z3-Cr.js} +2 -2
- package/dist/skills.js +1 -1
- package/dist/ssg.js +18 -2
- package/dist/templates/full-stack/package.json +4 -3
- package/dist/templates/spa/package.json +4 -3
- package/dist/templates/spa/tests/app.test.tsx +1 -1
- package/dist/templates/spa/tests/components/shared.test.tsx +1 -1
- package/dist/templates/spa/tests/resources.test.ts +2 -2
- package/dist/templates/ssg/package.json +4 -3
- package/dist/templates/ssg/tests/app.test.tsx +1 -1
- package/dist/templates/ssg/tests/components/counter.test.tsx +1 -1
- package/dist/templates/ssg/tests/resources.test.ts +1 -1
- package/dist/templates/ssg/tests/ssg-config.test.ts +1 -1
- package/dist/templates/ssr/package.json +4 -3
- package/dist/templates/ssr/tests/app.test.tsx +1 -1
- package/dist/templates/ssr/tests/components/counter.test.tsx +1 -1
- package/dist/templates/ssr/tests/resources.test.ts +1 -1
- package/dist/templates/startkit/package.json +4 -3
- package/dist/templates/startkit/tests/app.test.tsx +3 -3
- package/dist/update.js +1 -1
- package/package.json +23 -21
package/dist/analyze.js
CHANGED
|
@@ -71,7 +71,7 @@ async function runAnalyzeCli(args = process.argv.slice(2), io = console, runtime
|
|
|
71
71
|
io.log(helpText.trimEnd());
|
|
72
72
|
return 0;
|
|
73
73
|
}
|
|
74
|
-
const report = await (runtime.analyze ?? (await import("./runner-
|
|
74
|
+
const report = await (runtime.analyze ?? (await import("./runner-D2iNzz9g.js")).runAnalysis)({
|
|
75
75
|
cwd: parsed.cwd,
|
|
76
76
|
workspacePatterns: parsed.workspacePatterns,
|
|
77
77
|
check: parsed.check
|
package/dist/cli.js
CHANGED
|
@@ -96,7 +96,7 @@ async function runCli(args = process.argv.slice(2), io = console) {
|
|
|
96
96
|
return runAnalyzeCli(args.slice(1), io);
|
|
97
97
|
}
|
|
98
98
|
if (command === "check" || command === "doctor" || command === "repair") {
|
|
99
|
-
const { runGuardrailCli } = await import("./guardrails-
|
|
99
|
+
const { runGuardrailCli } = await import("./guardrails-BVxzrcBX.js");
|
|
100
100
|
return runGuardrailCli(command, args.slice(1), io);
|
|
101
101
|
}
|
|
102
102
|
if (command === "generate") {
|
package/dist/create.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { t as isDirectExecution } from "./is-direct-execution-Cdlr-ZUl.js";
|
|
3
|
-
import { n as installBundledSkills } from "./skills-
|
|
3
|
+
import { n as installBundledSkills } from "./skills-C72Z3-Cr.js";
|
|
4
4
|
import { n as publishStagedDirectory, t as createSiblingStage } from "./directory-swap-DWoHtx7C.js";
|
|
5
5
|
import fs from "node:fs/promises";
|
|
6
6
|
import path from "node:path";
|
package/dist/generate.js
CHANGED
|
@@ -419,7 +419,7 @@ async function loadOpenApi(input, options = {}) {
|
|
|
419
419
|
return parsed.origin;
|
|
420
420
|
})),
|
|
421
421
|
allowPrivateHosts: options.allowPrivateHosts ?? false,
|
|
422
|
-
maxBytes: positiveOption("maxBytes", options.maxBytes ??
|
|
422
|
+
maxBytes: positiveOption("maxBytes", options.maxBytes ?? 5242880),
|
|
423
423
|
maxDepth: positiveOption("maxDepth", options.maxDepth ?? 32),
|
|
424
424
|
maxRedirects: positiveOption("maxRedirects", options.maxRedirects ?? 5),
|
|
425
425
|
timeoutMs: positiveOption("timeoutMs", options.timeoutMs ?? 1e4),
|
|
@@ -604,7 +604,8 @@ async function writeGenerated(directory, files, check) {
|
|
|
604
604
|
async function generate(input, output, check = false, loadOptions = {}) {
|
|
605
605
|
if (!/^https?:\/\//.test(input)) {
|
|
606
606
|
const resolvedInput = resolve(input);
|
|
607
|
-
const
|
|
607
|
+
const resolvedOutput = resolve(output);
|
|
608
|
+
const inputWithinOutput = relative(resolvedOutput, resolvedInput);
|
|
608
609
|
if (!inputWithinOutput.startsWith("..") && !isAbsolute(inputWithinOutput)) throw new GenerationError("Generated output must not contain its OpenAPI input document");
|
|
609
610
|
}
|
|
610
611
|
const files = generateFiles(await loadOpenApi(input, loadOptions));
|
|
@@ -98,7 +98,7 @@ async function runGuardrailCli(command, args = process.argv.slice(2), io = conso
|
|
|
98
98
|
cwd: parsed.cwd,
|
|
99
99
|
workspacePatterns: parsed.workspacePatterns
|
|
100
100
|
};
|
|
101
|
-
const { runCheck, runDoctor, runRepair } = await import("./runner-
|
|
101
|
+
const { runCheck, runDoctor, runRepair } = await import("./runner-N2qHCBar.js");
|
|
102
102
|
const report = command === "doctor" ? await runDoctor(options, runtime) : command === "repair" ? await runRepair(options) : await runCheck(options, runtime);
|
|
103
103
|
if (parsed.json) io.log(JSON.stringify(report));
|
|
104
104
|
else if (report.command === "doctor") printDoctor(report, io);
|
package/dist/openapi.js
CHANGED
|
@@ -61,7 +61,8 @@ function exporterFrom(moduleValue) {
|
|
|
61
61
|
function serializeOpenApi(document) {
|
|
62
62
|
return `${dump(document, {
|
|
63
63
|
lineWidth: -1,
|
|
64
|
-
noRefs: true
|
|
64
|
+
noRefs: true,
|
|
65
|
+
quoteStyle: "double"
|
|
65
66
|
}).replace(/\n+$/, "")}\n`;
|
|
66
67
|
}
|
|
67
68
|
function validateOpenApiDocument(document) {
|
|
@@ -16,8 +16,9 @@ function executionEnvironment(env) {
|
|
|
16
16
|
async function loadNpmConfiguration(root, env = process.env) {
|
|
17
17
|
const effectiveEnvironment = executionEnvironment(env);
|
|
18
18
|
const { definitions, flatten, shorthands } = npmDefinitions;
|
|
19
|
+
const npmPath = path.dirname(fileURLToPath(import.meta.resolve("@npmcli/config/package.json")));
|
|
19
20
|
const configuration = new Config({
|
|
20
|
-
npmPath
|
|
21
|
+
npmPath,
|
|
21
22
|
definitions,
|
|
22
23
|
flatten,
|
|
23
24
|
shorthands,
|
|
@@ -413,15 +413,47 @@ function collectStateBindings(sourceFile, bindings) {
|
|
|
413
413
|
owners
|
|
414
414
|
};
|
|
415
415
|
}
|
|
416
|
-
function
|
|
416
|
+
function isCallableJsxProp(node, checker) {
|
|
417
|
+
const expression = node.parent;
|
|
418
|
+
if (!ts.isJsxExpression(expression) || !expression.expression) return false;
|
|
419
|
+
const attribute = expression.parent;
|
|
420
|
+
if (!ts.isJsxAttribute(attribute)) return false;
|
|
421
|
+
const opening = attribute.parent.parent;
|
|
422
|
+
if (!ts.isJsxOpeningLikeElement(opening)) return false;
|
|
423
|
+
const attributeName = ts.isIdentifier(attribute.name) ? attribute.name.text : ts.isJsxNamespacedName(attribute.name) && ts.isIdentifier(attribute.name.name) ? attribute.name.name.text : null;
|
|
424
|
+
if (!attributeName) return false;
|
|
425
|
+
let expected = checker.getContextualType(expression.expression);
|
|
426
|
+
if (!expected || expected.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) {
|
|
427
|
+
const tagType = checker.getTypeAtLocation(opening.tagName);
|
|
428
|
+
for (const signature of tagType.getCallSignatures()) {
|
|
429
|
+
const propsParameter = signature.parameters[0];
|
|
430
|
+
if (!propsParameter) continue;
|
|
431
|
+
const prop = checker.getTypeOfSymbolAtLocation(propsParameter, opening.tagName).getProperty(attributeName);
|
|
432
|
+
if (!prop) continue;
|
|
433
|
+
expected = checker.getTypeOfSymbolAtLocation(prop, attribute);
|
|
434
|
+
if (expected.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) continue;
|
|
435
|
+
if (expected.getCallSignatures().length > 0 || expected.isUnion()) break;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
if (!expected || expected.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) return false;
|
|
439
|
+
const hasCallableSignature = (type) => type.isUnion() ? type.types.some((member) => hasCallableSignature(member)) : type.getCallSignatures().length > 0;
|
|
440
|
+
return hasCallableSignature(expected);
|
|
441
|
+
}
|
|
442
|
+
function identifierIsReadAsValue(node, checker) {
|
|
417
443
|
const parent = node.parent;
|
|
418
444
|
if (ts.isCallExpression(parent) && parent.expression === node) return false;
|
|
419
|
-
if (ts.isPropertyAccessExpression(parent)
|
|
445
|
+
if (ts.isPropertyAccessExpression(parent)) {
|
|
446
|
+
if (parent.expression === node || parent.name === node) return false;
|
|
447
|
+
}
|
|
448
|
+
if (ts.isElementAccessExpression(parent) && parent.expression === node) return false;
|
|
420
449
|
if (ts.isVariableDeclaration(parent) && parent.name === node) return false;
|
|
421
450
|
if (ts.isBindingElement(parent) && parent.name === node) return false;
|
|
422
|
-
if (ts.isImportSpecifier(parent) || ts.isImportClause(parent) || ts.isNamespaceImport(parent)) return false;
|
|
423
|
-
if (ts.
|
|
424
|
-
|
|
451
|
+
if (ts.isImportSpecifier(parent) || ts.isImportClause(parent) || ts.isNamespaceImport(parent) || ts.isParameter(parent) && parent.name === node || ts.isPropertyDeclaration(parent) && parent.name === node || ts.isPropertySignature(parent) && parent.name === node || ts.isMethodDeclaration(parent) && parent.name === node || ts.isMethodSignature(parent) && parent.name === node || ts.isExportSpecifier(parent) && (parent.name === node || parent.propertyName === node) || ts.isTypeQueryNode(parent) && parent.exprName === node) return false;
|
|
452
|
+
if (ts.isJsxAttribute(parent) && parent.name === node) return false;
|
|
453
|
+
if (isCallableJsxProp(node, checker)) return false;
|
|
454
|
+
if (ts.isPropertyAssignment(parent) && parent.name === node) return false;
|
|
455
|
+
if (ts.isShorthandPropertyAssignment(parent)) return true;
|
|
456
|
+
return true;
|
|
425
457
|
}
|
|
426
458
|
const stateAccessRule = {
|
|
427
459
|
id: "askr/state-access",
|
|
@@ -434,7 +466,7 @@ const stateAccessRule = {
|
|
|
434
466
|
const state = collectStateBindings(sourceFile, sourceBindings(sourceFile));
|
|
435
467
|
visit(sourceFile, (node) => {
|
|
436
468
|
if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && state.setters.has(node.expression.text) && node.arguments.length === 0) diagnostics.push(diagnostic(context, node.expression, this, `State setter '${node.expression.text}' is called without a value or updater.`, "Pass the next value or a functional updater."));
|
|
437
|
-
else if (ts.isIdentifier(node) && state.getters.has(node.text) && identifierIsReadAsValue(node)) diagnostics.push(diagnostic(context, node, this, `State getter '${node.text}' is used as a value instead of being called.`, `Read it with ${node.text}().`));
|
|
469
|
+
else if (ts.isIdentifier(node) && state.getters.has(node.text) && identifierIsReadAsValue(node, context.checker)) diagnostics.push(diagnostic(context, node, this, `State getter '${node.text}' is used as a value instead of being called.`, `Read it with ${node.text}().`));
|
|
438
470
|
});
|
|
439
471
|
}
|
|
440
472
|
return diagnostics;
|
|
@@ -525,6 +557,32 @@ const stableDependenciesRule = {
|
|
|
525
557
|
function jsxAttributes(node) {
|
|
526
558
|
return new Map(node.attributes.properties.flatMap((attribute) => ts.isJsxAttribute(attribute) && ts.isIdentifier(attribute.name) ? [[attribute.name.text, attribute]] : []));
|
|
527
559
|
}
|
|
560
|
+
function staticallyNonFunction(expression, checker) {
|
|
561
|
+
if (ts.isArrowFunction(expression) || ts.isFunctionExpression(expression) || ts.isClassExpression(expression)) return false;
|
|
562
|
+
if (ts.isStringLiteral(expression) || ts.isNumericLiteral(expression) || expression.kind === ts.SyntaxKind.TrueKeyword || expression.kind === ts.SyntaxKind.FalseKeyword || expression.kind === ts.SyntaxKind.NullKeyword || ts.isObjectLiteralExpression(expression) || ts.isArrayLiteralExpression(expression)) return true;
|
|
563
|
+
const type = checker.getTypeAtLocation(expression);
|
|
564
|
+
if (type.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Never)) return false;
|
|
565
|
+
if (type.isUnion()) return type.types.every((member) => staticallyNonFunctionType(member));
|
|
566
|
+
return staticallyNonFunctionType(type);
|
|
567
|
+
}
|
|
568
|
+
function staticallyNonFunctionType(type) {
|
|
569
|
+
if (type.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Never)) return false;
|
|
570
|
+
if (type.isUnion()) return type.types.some((member) => !(member.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined | ts.TypeFlags.VoidLike)) && staticallyNonFunctionType(member));
|
|
571
|
+
return type.getCallSignatures().length === 0;
|
|
572
|
+
}
|
|
573
|
+
function staticallyNotTrue(expression, checker) {
|
|
574
|
+
if (expression.kind === ts.SyntaxKind.TrueKeyword) return false;
|
|
575
|
+
if (ts.isStringLiteral(expression) || ts.isNumericLiteral(expression) || expression.kind === ts.SyntaxKind.FalseKeyword || expression.kind === ts.SyntaxKind.NullKeyword || ts.isObjectLiteralExpression(expression) || ts.isArrayLiteralExpression(expression)) return true;
|
|
576
|
+
const type = checker.getTypeAtLocation(expression);
|
|
577
|
+
if (type.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Never)) return false;
|
|
578
|
+
return staticallyNotTrueType(type, checker);
|
|
579
|
+
}
|
|
580
|
+
function staticallyNotTrueType(type, checker) {
|
|
581
|
+
if (type.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Never)) return false;
|
|
582
|
+
if (type.isUnion()) return type.types.every((member) => staticallyNotTrueType(member, checker));
|
|
583
|
+
if (type.flags & ts.TypeFlags.BooleanLike) return (type.flags & ts.TypeFlags.BooleanLiteral) !== 0 && type === checker.getFalseType();
|
|
584
|
+
return true;
|
|
585
|
+
}
|
|
528
586
|
const forContractRule = {
|
|
529
587
|
id: "askr/for-contract",
|
|
530
588
|
category: "correctness",
|
|
@@ -543,6 +601,14 @@ const forContractRule = {
|
|
|
543
601
|
const byIndex = attributes.get("byIndex");
|
|
544
602
|
if (!by && !byIndex) diagnostics.push(diagnostic(context, node.tagName, this, "<For> requires a stable by function or explicit byIndex.", "Prefer by={(item) => item.id}; use byIndex only for positional lists."));
|
|
545
603
|
else if (by && byIndex) diagnostics.push(diagnostic(context, byIndex, this, "<For> accepts either by or byIndex, not both.", "Remove one key strategy."));
|
|
604
|
+
if (by) {
|
|
605
|
+
const expression = by.initializer && ts.isJsxExpression(by.initializer) ? by.initializer.expression : void 0;
|
|
606
|
+
if (!expression || staticallyNonFunction(expression, context.checker)) diagnostics.push(diagnostic(context, by, this, "<For> by must be a function.", "Pass by={(item) => item.id} or use byIndex for positional lists."));
|
|
607
|
+
}
|
|
608
|
+
if (byIndex?.initializer) {
|
|
609
|
+
const expression = ts.isJsxExpression(byIndex.initializer) ? byIndex.initializer.expression : void 0;
|
|
610
|
+
if (!expression || staticallyNotTrue(expression, context.checker)) diagnostics.push(diagnostic(context, byIndex, this, "<For> byIndex must be true.", "Use bare byIndex or byIndex={true} for positional lists."));
|
|
611
|
+
}
|
|
546
612
|
const element = ts.isJsxOpeningElement(node) && ts.isJsxElement(node.parent) ? node.parent : null;
|
|
547
613
|
if (ts.isJsxSelfClosingElement(node) || element && element.children.every((child) => ts.isJsxText(child) && child.text.trim().length === 0)) diagnostics.push(diagnostic(context, node.tagName, this, "<For> is missing its item renderer child.", "Provide a function child such as {(item) => <Row item={item} />}."));
|
|
548
614
|
});
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { t as inspectBundledSkills } from "./skills-
|
|
1
|
+
import { t as inspectBundledSkills } from "./skills-C72Z3-Cr.js";
|
|
2
2
|
import { discoverWorkspaceProject } from "./discovery-DUDrZCIC.js";
|
|
3
|
-
import { analysisHasBlockingFindings, runAnalysis } from "./runner-
|
|
3
|
+
import { analysisHasBlockingFindings, runAnalysis } from "./runner-D2iNzz9g.js";
|
|
4
4
|
import fs from "node:fs/promises";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { spawn } from "node:child_process";
|
|
7
7
|
import semver from "semver";
|
|
8
8
|
//#region src/guardrails/runner.ts
|
|
9
|
-
const SUPPORTED_NODE_RANGE = "
|
|
9
|
+
const SUPPORTED_NODE_RANGE = ">=24.0.0";
|
|
10
10
|
const VALIDATION_SCRIPTS = [
|
|
11
11
|
"lint",
|
|
12
12
|
"typecheck",
|
|
@@ -316,8 +316,8 @@ async function pathExists$1(filePath) {
|
|
|
316
316
|
return Boolean(await fs.stat(filePath).catch(() => null));
|
|
317
317
|
}
|
|
318
318
|
const MAX_REVIEW_FILES = 1e4;
|
|
319
|
-
const MAX_REVIEW_FILE_BYTES =
|
|
320
|
-
const MAX_REVIEW_TOTAL_BYTES =
|
|
319
|
+
const MAX_REVIEW_FILE_BYTES = 2097152;
|
|
320
|
+
const MAX_REVIEW_TOTAL_BYTES = 20971520;
|
|
321
321
|
function shouldReadFile(filePath) {
|
|
322
322
|
return TEXT_FILE_EXTENSIONS.has(path.extname(filePath).toLowerCase());
|
|
323
323
|
}
|
package/dist/skills.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { i as syncBundledSkills, n as installBundledSkills, r as runSkillsCli, t as inspectBundledSkills } from "./skills-
|
|
2
|
+
import { i as syncBundledSkills, n as installBundledSkills, r as runSkillsCli, t as inspectBundledSkills } from "./skills-C72Z3-Cr.js";
|
|
3
3
|
export { inspectBundledSkills, installBundledSkills, runSkillsCli, syncBundledSkills };
|
package/dist/ssg.js
CHANGED
|
@@ -23,7 +23,7 @@ const changeFrequencies = /* @__PURE__ */ new Set([
|
|
|
23
23
|
"never"
|
|
24
24
|
]);
|
|
25
25
|
const MAX_URLS_PER_SITEMAP = 5e4;
|
|
26
|
-
const MAX_SITEMAP_BYTES =
|
|
26
|
+
const MAX_SITEMAP_BYTES = 52428800;
|
|
27
27
|
const MANIFEST_PATH = ".askr/sitemap-manifest.json";
|
|
28
28
|
function escapeXml(value) {
|
|
29
29
|
return value.replace(/[&<>"']/g, (character) => {
|
|
@@ -486,12 +486,27 @@ async function writeSsgOutputReport(outputDir, routes, inspections, config = {})
|
|
|
486
486
|
}
|
|
487
487
|
assets.sort((left, right) => left.path.localeCompare(right.path));
|
|
488
488
|
const assetMap = new Map(assets.map((asset) => [asset.path, asset]));
|
|
489
|
+
const missingReferences = /* @__PURE__ */ new Set();
|
|
489
490
|
const outputRoutes = [];
|
|
490
491
|
for (const route of [...routes].sort((left, right) => left.path.localeCompare(right.path))) {
|
|
491
492
|
const inspection = inspections.get(route.path);
|
|
492
493
|
if (!inspection) continue;
|
|
493
494
|
const html = inspection.html;
|
|
494
|
-
const referenced = (references, type) =>
|
|
495
|
+
const referenced = (references, type) => {
|
|
496
|
+
const resolved = [];
|
|
497
|
+
for (const reference of references) {
|
|
498
|
+
const localPath = localReference(reference, inspection.filePath);
|
|
499
|
+
if (!localPath) continue;
|
|
500
|
+
const asset = assetMap.get(localPath);
|
|
501
|
+
if (!asset) {
|
|
502
|
+
missingReferences.add(`route ${route.path} references missing ${type} asset ${localPath}`);
|
|
503
|
+
continue;
|
|
504
|
+
}
|
|
505
|
+
if (asset.type !== type) continue;
|
|
506
|
+
resolved.push(asset);
|
|
507
|
+
}
|
|
508
|
+
return resolved.sort((left, right) => left.path.localeCompare(right.path));
|
|
509
|
+
};
|
|
495
510
|
outputRoutes.push({
|
|
496
511
|
route: route.path,
|
|
497
512
|
filePath: inspection.filePath,
|
|
@@ -506,6 +521,7 @@ async function writeSsgOutputReport(outputDir, routes, inspections, config = {})
|
|
|
506
521
|
}
|
|
507
522
|
});
|
|
508
523
|
}
|
|
524
|
+
if (missingReferences.size > 0) throw new Error(`SSG output contains missing local assets:\n${[...missingReferences].sort().map((item) => `- ${item}`).join("\n")}`);
|
|
509
525
|
const total = (type) => assets.filter((asset) => asset.type === type).reduce((sum, asset) => ({
|
|
510
526
|
raw: sum.raw + asset.raw,
|
|
511
527
|
gzip: sum.gzip + asset.gzip
|
|
@@ -30,11 +30,12 @@
|
|
|
30
30
|
"@askrjs/vite": ">=0.0.6 <0.1.0",
|
|
31
31
|
"@types/node": "^20.19.0",
|
|
32
32
|
"jsdom": "^29.1.1",
|
|
33
|
-
"typescript": "^
|
|
33
|
+
"typescript": "^7.0.2",
|
|
34
34
|
"vite-plus": "^0.2.4",
|
|
35
35
|
"vitest": "^4.1.10"
|
|
36
36
|
},
|
|
37
37
|
"engines": {
|
|
38
|
-
"node": "
|
|
39
|
-
}
|
|
38
|
+
"node": ">=24.0.0"
|
|
39
|
+
},
|
|
40
|
+
"packageManager": "npm@12.0.1"
|
|
40
41
|
}
|
|
@@ -26,10 +26,11 @@
|
|
|
26
26
|
"@askrjs/vite": ">=0.0.6 <0.1.0",
|
|
27
27
|
"@types/node": "^20.19.0",
|
|
28
28
|
"jsdom": "^29.1.1",
|
|
29
|
-
"typescript": "^
|
|
29
|
+
"typescript": "^7.0.2",
|
|
30
30
|
"vite-plus": "^0.2.4"
|
|
31
31
|
},
|
|
32
32
|
"engines": {
|
|
33
|
-
"node": "
|
|
34
|
-
}
|
|
33
|
+
"node": ">=24.0.0"
|
|
34
|
+
},
|
|
35
|
+
"packageManager": "npm@12.0.1"
|
|
35
36
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vite-plus/test';
|
|
2
2
|
|
|
3
3
|
describe('SPA template structure', () => {
|
|
4
|
-
it('
|
|
4
|
+
it('should document the route-first shell and theme layers the app should keep', () => {
|
|
5
5
|
const structure = [
|
|
6
6
|
'src/main.tsx',
|
|
7
7
|
'src/pages/_routes.tsx',
|
|
@@ -3,7 +3,7 @@ import MetricCard from '../../src/components/shared/metric-card';
|
|
|
3
3
|
import StatusBadge from '../../src/components/shared/status-badge';
|
|
4
4
|
|
|
5
5
|
describe('shared app components', () => {
|
|
6
|
-
it('
|
|
6
|
+
it('should export small app-local wrappers around theme primitives', () => {
|
|
7
7
|
expect(MetricCard).toBeDefined();
|
|
8
8
|
expect(StatusBadge).toBeDefined();
|
|
9
9
|
expect(typeof MetricCard).toBe('function');
|
|
@@ -3,7 +3,7 @@ import { getOperationsSnapshot } from '../src/adapters/operations-client';
|
|
|
3
3
|
import { loadOperations } from '../src/features/operations/operations.query';
|
|
4
4
|
|
|
5
5
|
describe('operations data flow', () => {
|
|
6
|
-
it('
|
|
6
|
+
it('should load the dashboard snapshot through the feature query boundary', async () => {
|
|
7
7
|
const snapshot = await loadOperations({});
|
|
8
8
|
|
|
9
9
|
expect(snapshot.metrics.length).toBeGreaterThan(0);
|
|
@@ -11,7 +11,7 @@ describe('operations data flow', () => {
|
|
|
11
11
|
expect(snapshot.lastEventId).toMatch(/^evt_/);
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
-
it('
|
|
14
|
+
it('should keep cancellation owned by the adapter', async () => {
|
|
15
15
|
const controller = new AbortController();
|
|
16
16
|
const request = getOperationsSnapshot({ signal: controller.signal });
|
|
17
17
|
|
|
@@ -27,10 +27,11 @@
|
|
|
27
27
|
"@askrjs/vite": ">=0.0.6 <0.1.0",
|
|
28
28
|
"@types/node": "^20.19.0",
|
|
29
29
|
"jsdom": "^29.1.1",
|
|
30
|
-
"typescript": "^
|
|
30
|
+
"typescript": "^7.0.2",
|
|
31
31
|
"vite-plus": "^0.2.4"
|
|
32
32
|
},
|
|
33
33
|
"engines": {
|
|
34
|
-
"node": "
|
|
35
|
-
}
|
|
34
|
+
"node": ">=24.0.0"
|
|
35
|
+
},
|
|
36
|
+
"packageManager": "npm@12.0.1"
|
|
36
37
|
}
|
|
@@ -2,7 +2,7 @@ import { describe, expect, it } from 'vite-plus/test';
|
|
|
2
2
|
import { navItems } from '../src/app';
|
|
3
3
|
|
|
4
4
|
describe('App shell', () => {
|
|
5
|
-
it('
|
|
5
|
+
it('should expose the workflow-focused navigation order', () => {
|
|
6
6
|
expect(navItems.map((item) => item.label)).toEqual([
|
|
7
7
|
'Home',
|
|
8
8
|
'Workflow',
|
|
@@ -3,7 +3,7 @@ import { renderToString } from '@askrjs/askr/ssr';
|
|
|
3
3
|
import Counter from '../../src/components/counter';
|
|
4
4
|
|
|
5
5
|
describe('Counter', () => {
|
|
6
|
-
it('
|
|
6
|
+
it('should render the initial hydration check view', () => {
|
|
7
7
|
const html = renderToString(() => <Counter />);
|
|
8
8
|
|
|
9
9
|
expect(html).toContain('Hydration check');
|
|
@@ -2,7 +2,7 @@ import { describe, it, expect } from 'vite-plus/test';
|
|
|
2
2
|
import { fetchUser } from '../src/resources/user';
|
|
3
3
|
|
|
4
4
|
describe('Resources', () => {
|
|
5
|
-
it('
|
|
5
|
+
it('should create a resource for fetching user data', () => {
|
|
6
6
|
// Resources are called during component render
|
|
7
7
|
// Here we just verify the function is defined
|
|
8
8
|
expect(fetchUser).toBeDefined();
|
|
@@ -2,7 +2,7 @@ import { describe, expect, it } from 'vite-plus/test';
|
|
|
2
2
|
import { staticConfig } from '../ssg.config';
|
|
3
3
|
|
|
4
4
|
describe('SSG config', () => {
|
|
5
|
-
it('
|
|
5
|
+
it('should keep the sample route tree explicit', () => {
|
|
6
6
|
expect(
|
|
7
7
|
staticConfig.registry.manifest.records.map((route) => route.path).sort()
|
|
8
8
|
).toEqual(['/', '/content', '/preview', '/workflow'].sort());
|
|
@@ -26,10 +26,11 @@
|
|
|
26
26
|
"@types/node": "^20.19.0",
|
|
27
27
|
"jsdom": "^29.1.1",
|
|
28
28
|
"tsx": "^4.23.1",
|
|
29
|
-
"typescript": "^
|
|
29
|
+
"typescript": "^7.0.2",
|
|
30
30
|
"vite-plus": "^0.2.4"
|
|
31
31
|
},
|
|
32
32
|
"engines": {
|
|
33
|
-
"node": "
|
|
34
|
-
}
|
|
33
|
+
"node": ">=24.0.0"
|
|
34
|
+
},
|
|
35
|
+
"packageManager": "npm@12.0.1"
|
|
35
36
|
}
|
|
@@ -3,7 +3,7 @@ import { renderToString } from '@askrjs/askr/ssr';
|
|
|
3
3
|
import Counter from '../../src/components/counter';
|
|
4
4
|
|
|
5
5
|
describe('Counter', () => {
|
|
6
|
-
it('
|
|
6
|
+
it('should render its initial state during SSR', () => {
|
|
7
7
|
const html = renderToString(() => <Counter />);
|
|
8
8
|
|
|
9
9
|
expect(html).toContain('counter-value');
|
|
@@ -2,7 +2,7 @@ import { describe, it, expect } from 'vite-plus/test';
|
|
|
2
2
|
import { fetchUser } from '../src/resources/user';
|
|
3
3
|
|
|
4
4
|
describe('SSR Resources', () => {
|
|
5
|
-
it('
|
|
5
|
+
it('should create a resource for fetching user data', () => {
|
|
6
6
|
// Resources are called during component render
|
|
7
7
|
// Here we just verify the function is defined
|
|
8
8
|
expect(fetchUser).toBeDefined();
|
|
@@ -27,10 +27,11 @@
|
|
|
27
27
|
"@askrjs/vite": ">=0.0.6 <0.1.0",
|
|
28
28
|
"@types/node": "^20.19.0",
|
|
29
29
|
"jsdom": "^29.1.1",
|
|
30
|
-
"typescript": "^
|
|
30
|
+
"typescript": "^7.0.2",
|
|
31
31
|
"vite-plus": "^0.2.4"
|
|
32
32
|
},
|
|
33
33
|
"engines": {
|
|
34
|
-
"node": "
|
|
35
|
-
}
|
|
34
|
+
"node": ">=24.0.0"
|
|
35
|
+
},
|
|
36
|
+
"packageManager": "npm@12.0.1"
|
|
36
37
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vite-plus/test';
|
|
2
2
|
|
|
3
3
|
describe('App Component', () => {
|
|
4
|
-
it('
|
|
4
|
+
it('should expose the current starter route set', () => {
|
|
5
5
|
const routes = [
|
|
6
6
|
'/',
|
|
7
7
|
'/login',
|
|
@@ -16,14 +16,14 @@ describe('App Component', () => {
|
|
|
16
16
|
expect(routes).toContain('/login');
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
-
it('
|
|
19
|
+
it('should use the updated primary nav labels', () => {
|
|
20
20
|
const navLabels = ['Dashboard', 'Accounts', 'Settings'];
|
|
21
21
|
|
|
22
22
|
expect(navLabels).toContain('Accounts');
|
|
23
23
|
expect(navLabels).toContain('Settings');
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
it('
|
|
26
|
+
it('should document the starter appearance presets', () => {
|
|
27
27
|
const appearanceModes = ['Default', 'Harbor', 'Ink'];
|
|
28
28
|
|
|
29
29
|
expect(appearanceModes).toContain('Harbor');
|
package/dist/update.js
CHANGED
|
@@ -193,7 +193,7 @@ function collectEdits(decisions) {
|
|
|
193
193
|
}] : []));
|
|
194
194
|
}
|
|
195
195
|
async function defaultRegistry(root, packageNames, requirements) {
|
|
196
|
-
const { fetchPackuments, loadNpmConfiguration } = await import("./registry-
|
|
196
|
+
const { fetchPackuments, loadNpmConfiguration } = await import("./registry-BmGIkoO0.js");
|
|
197
197
|
return fetchPackuments(packageNames, await loadNpmConfiguration(root), { requirements });
|
|
198
198
|
}
|
|
199
199
|
async function runDependencyCli(command, args, io = console, runtime = {}) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askrjs/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.22",
|
|
4
4
|
"description": "Unified CLI for the Askr platform",
|
|
5
5
|
"homepage": "https://github.com/askrjs/askr-cli#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -41,11 +41,11 @@
|
|
|
41
41
|
"fmt": "vp fmt .",
|
|
42
42
|
"lint": "vp lint src tests benchmarks vite.config.ts vitest.config.ts vitest.bench.config.ts",
|
|
43
43
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
44
|
-
"test:changelog": "
|
|
45
|
-
"test:peer-floor": "
|
|
44
|
+
"test:changelog": "vp test run -c vitest.config.ts tests/changelog.test.ts",
|
|
45
|
+
"test:peer-floor": "vp test run -c vitest.integration.config.ts tests/integration/peer-floor.test.ts",
|
|
46
46
|
"test:publint": "publint",
|
|
47
47
|
"pack:check": "npm pack --ignore-scripts --dry-run --json",
|
|
48
|
-
"test:templates": "
|
|
48
|
+
"test:templates": "vp test run -c vitest.integration.config.ts tests/integration/packed-templates.test.ts",
|
|
49
49
|
"bench": "npm run build --silent && npm run bench:analyze && node --import tsx benchmarks/cli.mjs --gate",
|
|
50
50
|
"bench:analyze": "vp test bench --run -c vitest.bench.config.ts",
|
|
51
51
|
"bench:json": "npm run build --silent && node --import tsx benchmarks/cli.mjs --gate --json",
|
|
@@ -55,32 +55,33 @@
|
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"@npmcli/config": "^11.0.1",
|
|
58
|
-
"js-yaml": "^5.2.
|
|
58
|
+
"js-yaml": "^5.2.3",
|
|
59
59
|
"minimatch": "^10.2.6",
|
|
60
60
|
"npm-registry-fetch": "^20.0.1",
|
|
61
61
|
"parse5": "^8.0.1",
|
|
62
62
|
"semver": "^7.8.5",
|
|
63
|
-
"tsx": "^4.23.
|
|
64
|
-
"typescript": "
|
|
63
|
+
"tsx": "^4.23.11",
|
|
64
|
+
"typescript": "npm:@typescript/typescript6@^6.0.2"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
|
-
"@askrjs/askr": ">=0.0.
|
|
68
|
-
"@askrjs/charts": ">=0.1.
|
|
69
|
-
"@askrjs/logos": ">=0.0.
|
|
70
|
-
"@askrjs/lucide": ">=0.0.
|
|
71
|
-
"@askrjs/themes": ">=0.0.
|
|
72
|
-
"@askrjs/ui": ">=0.0.
|
|
73
|
-
"@askrjs/vite": ">=0.0.
|
|
67
|
+
"@askrjs/askr": ">=0.0.89 <0.1.0",
|
|
68
|
+
"@askrjs/charts": ">=0.1.6 <0.2.0",
|
|
69
|
+
"@askrjs/logos": ">=0.0.7 <0.1.0",
|
|
70
|
+
"@askrjs/lucide": ">=0.0.9 <0.1.0",
|
|
71
|
+
"@askrjs/themes": ">=0.0.24 <0.1.0",
|
|
72
|
+
"@askrjs/ui": ">=0.0.27 <0.1.0",
|
|
73
|
+
"@askrjs/vite": ">=0.0.13 <0.1.0",
|
|
74
74
|
"@types/js-yaml": "^4.0.9",
|
|
75
|
-
"@types/node": "^26.
|
|
76
|
-
"@types/semver": "^7.
|
|
75
|
+
"@types/node": "^26.2.0",
|
|
76
|
+
"@types/semver": "^7.8.0",
|
|
77
|
+
"@typescript/native": "npm:typescript@^7.0.2",
|
|
77
78
|
"@vitest/coverage-v8": "^4.1.10",
|
|
78
|
-
"publint": "^0.3.
|
|
79
|
-
"vite-plus": "0.2.
|
|
79
|
+
"publint": "^0.3.23",
|
|
80
|
+
"vite-plus": "0.2.8",
|
|
80
81
|
"vitest": "^4.1.10"
|
|
81
82
|
},
|
|
82
83
|
"peerDependencies": {
|
|
83
|
-
"@askrjs/askr": ">=0.0.
|
|
84
|
+
"@askrjs/askr": ">=0.0.89 <0.1.0"
|
|
84
85
|
},
|
|
85
86
|
"peerDependenciesMeta": {
|
|
86
87
|
"@askrjs/askr": {
|
|
@@ -88,6 +89,7 @@
|
|
|
88
89
|
}
|
|
89
90
|
},
|
|
90
91
|
"engines": {
|
|
91
|
-
"node": "
|
|
92
|
-
}
|
|
92
|
+
"node": ">=24.0.0"
|
|
93
|
+
},
|
|
94
|
+
"packageManager": "npm@12.0.1"
|
|
93
95
|
}
|