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.
@@ -493,7 +493,10 @@
493
493
  "encrypted": false,
494
494
  "computed": false,
495
495
  "options": null,
496
- "bounds": null,
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": null,
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.149",
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.165.0",
34
- "@cosmicdrift/kumiko-framework": "0.165.0",
35
- "@cosmicdrift/kumiko-server-runtime": "0.165.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
+ });