create-kumiko-app 0.4.149 → 0.4.150
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/feature-manifest.json
CHANGED
|
@@ -493,7 +493,10 @@
|
|
|
493
493
|
"encrypted": false,
|
|
494
494
|
"computed": false,
|
|
495
495
|
"options": null,
|
|
496
|
-
"bounds":
|
|
496
|
+
"bounds": {
|
|
497
|
+
"min": 1,
|
|
498
|
+
"max": 500
|
|
499
|
+
},
|
|
497
500
|
"pattern": null,
|
|
498
501
|
"writeRoles": [
|
|
499
502
|
"TenantAdmin",
|
|
@@ -515,7 +518,9 @@
|
|
|
515
518
|
"computed": false,
|
|
516
519
|
"options": null,
|
|
517
520
|
"bounds": null,
|
|
518
|
-
"pattern":
|
|
521
|
+
"pattern": {
|
|
522
|
+
"regex": "^[a-z]{3}(\\+[a-z]{3})*$"
|
|
523
|
+
},
|
|
519
524
|
"writeRoles": [
|
|
520
525
|
"TenantAdmin",
|
|
521
526
|
"SystemAdmin"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-kumiko-app",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.150",
|
|
4
4
|
"description": "`bun create kumiko-app <name>` — scaffold a new Kumiko app with an interactive feature picker.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
"vendor:manifest": "bun run scripts/vendor-manifest.ts"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@cosmicdrift/kumiko-dev-server": "0.
|
|
34
|
-
"@cosmicdrift/kumiko-framework": "0.
|
|
35
|
-
"@cosmicdrift/kumiko-server-runtime": "0.
|
|
33
|
+
"@cosmicdrift/kumiko-dev-server": "1.0.0",
|
|
34
|
+
"@cosmicdrift/kumiko-framework": "1.0.0",
|
|
35
|
+
"@cosmicdrift/kumiko-server-runtime": "1.0.0",
|
|
36
36
|
"@inquirer/core": "^10.0.0",
|
|
37
37
|
"@inquirer/prompts": "^7.4.0"
|
|
38
38
|
},
|
|
@@ -30,7 +30,10 @@ describe("create-kumiko-app CLI", () => {
|
|
|
30
30
|
expect(code).toBe(0);
|
|
31
31
|
// Onboarding regression gate: the scaffold step is the first thing a new
|
|
32
32
|
// user waits on. Generous ceiling so slow CI runners pass — what we catch
|
|
33
|
-
// is an order-of-magnitude blowup, not seconds.
|
|
33
|
+
// is an order-of-magnitude blowup, not seconds. Needs an explicit test
|
|
34
|
+
// timeout above the 30s ceiling: bun's default (5s) would fail a slow-
|
|
35
|
+
// but-fine CI run on its own timeout before this assertion ever gets to
|
|
36
|
+
// fire, making the "ceiling" the opposite of what the comment claims.
|
|
34
37
|
expect(scaffoldMs, `scaffold took ${Math.round(scaffoldMs)}ms (ceiling 30s)`).toBeLessThan(
|
|
35
38
|
30_000,
|
|
36
39
|
);
|
|
@@ -67,7 +70,7 @@ describe("create-kumiko-app CLI", () => {
|
|
|
67
70
|
|
|
68
71
|
// Setup-impact preview lands before the scaffold actually runs.
|
|
69
72
|
expect(out).toMatch(/→ Scaffolding \d+ features? into \.\/demo-app\//);
|
|
70
|
-
});
|
|
73
|
+
}, 35_000);
|
|
71
74
|
|
|
72
75
|
test("--print-manifest emits JSON, no name needed", async () => {
|
|
73
76
|
const code = await runCreate({
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// Guards against #1425/1: callExpression (rendered into generated
|
|
2
|
+
// run-config.ts) and callArgs (used at runtime by instantiateScaffoldFeatures)
|
|
3
|
+
// encode the same call twice by hand. If someone edits one without the
|
|
4
|
+
// other, the boot test validates a different feature config than what
|
|
5
|
+
// actually gets scaffolded. This derives the expected callExpression from
|
|
6
|
+
// exportName + callArgs for every entry and diffs it against the literal.
|
|
7
|
+
|
|
8
|
+
import { describe, expect, test } from "bun:test";
|
|
9
|
+
import { FEATURE_CONSTRUCTORS } from "../feature-constructors";
|
|
10
|
+
|
|
11
|
+
function expectedCallExpression(
|
|
12
|
+
exportName: string,
|
|
13
|
+
callArgs: readonly unknown[] | undefined,
|
|
14
|
+
): string {
|
|
15
|
+
if (callArgs === undefined) {
|
|
16
|
+
// Ambiguous by callArgs alone: could be a zero-arg factory (`fn()`) or a
|
|
17
|
+
// bare object export (`fn`). Disambiguate the same way the runtime does
|
|
18
|
+
// (scaffold-app.ts's instantiateScaffoldFeatures): trust the "()" the
|
|
19
|
+
// literal itself carries, then only check the exportName prefix matches.
|
|
20
|
+
return exportName;
|
|
21
|
+
}
|
|
22
|
+
const args = callArgs.map((a) => JSON.stringify(a)).join(", ");
|
|
23
|
+
return `${exportName}(${args})`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
describe("FEATURE_CONSTRUCTORS callExpression/callArgs consistency", () => {
|
|
27
|
+
for (const [name, entry] of Object.entries(FEATURE_CONSTRUCTORS)) {
|
|
28
|
+
test(`${name}: callExpression matches exportName + callArgs`, () => {
|
|
29
|
+
if (entry.callArgs !== undefined) {
|
|
30
|
+
// callExpression is hand-formatted TS source (`{ scopes: {} }`), not
|
|
31
|
+
// JSON (`{"scopes":{}}`) — compare with whitespace stripped so both
|
|
32
|
+
// are checked against the same underlying arg values.
|
|
33
|
+
const normalize = (s: string) => s.replace(/[\s"]+/g, "");
|
|
34
|
+
expect(normalize(entry.callExpression)).toBe(
|
|
35
|
+
normalize(expectedCallExpression(entry.exportName, entry.callArgs)),
|
|
36
|
+
);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
// No callArgs: either `exportName()` (zero-arg factory) or bare
|
|
40
|
+
// `exportName` (object export) — both are legal, but the export name
|
|
41
|
+
// itself must be the prefix either way.
|
|
42
|
+
expect(
|
|
43
|
+
entry.callExpression === entry.exportName ||
|
|
44
|
+
entry.callExpression === `${entry.exportName}()`,
|
|
45
|
+
).toBe(true);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
});
|