@stardeck-customer-apps/compose 0.9.0 → 0.10.0
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/SKILL.md +6 -0
- package/dist/cli.js +99 -134
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +261 -296
- package/dist/index.mjs +260 -296
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2027,6 +2027,7 @@ var require_semver2 = __commonJS({
|
|
|
2027
2027
|
// src/index.ts
|
|
2028
2028
|
var index_exports = {};
|
|
2029
2029
|
__export(index_exports, {
|
|
2030
|
+
BUILD_TSCONFIG_PATH: () => BUILD_TSCONFIG_PATH,
|
|
2030
2031
|
COMPOSE_INPUTS_PATH: () => COMPOSE_INPUTS_PATH,
|
|
2031
2032
|
assertSupportedTypescript: () => assertSupportedTypescript,
|
|
2032
2033
|
compose: () => compose,
|
|
@@ -2098,11 +2099,54 @@ function shellQuote(value) {
|
|
|
2098
2099
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
2099
2100
|
}
|
|
2100
2101
|
|
|
2101
|
-
// ../../packages/lib/src/shared/
|
|
2102
|
-
var
|
|
2102
|
+
// ../../packages/lib/src/shared/compose-inputs.ts
|
|
2103
|
+
var import_zod = require("zod");
|
|
2104
|
+
var COMPOSE_INPUTS_PATH = "apps/web/stardeck.compose.json";
|
|
2105
|
+
var composeInputsSchema = import_zod.z.strictObject({
|
|
2106
|
+
connectedStores: import_zod.z.array(
|
|
2107
|
+
import_zod.z.strictObject({
|
|
2108
|
+
storeId: import_zod.z.string().min(1),
|
|
2109
|
+
slug: import_zod.z.string().min(1),
|
|
2110
|
+
// A row with an empty binding key must not fail a deploy: the rail
|
|
2111
|
+
// treats falsy as "no binding key", so normalise rather than reject.
|
|
2112
|
+
bindingKey: import_zod.z.string().nullish().transform((value) => value || null),
|
|
2113
|
+
accessLevel: import_zod.z.enum(["read", "write", "admin"]),
|
|
2114
|
+
// Defaulted so a file written before the platform emitted store types
|
|
2115
|
+
// (database rows only) still parses. The platform starts writing
|
|
2116
|
+
// storage rows, with `type` set, once forks run a compose that reads it.
|
|
2117
|
+
type: import_zod.z.enum(["database", "storage"]).default("database")
|
|
2118
|
+
})
|
|
2119
|
+
).default([]),
|
|
2120
|
+
installs: import_zod.z.record(
|
|
2121
|
+
import_zod.z.string(),
|
|
2122
|
+
import_zod.z.strictObject({
|
|
2123
|
+
installedVersion: import_zod.z.string().min(1),
|
|
2124
|
+
datastoreBindings: import_zod.z.record(import_zod.z.string(), import_zod.z.string()).nullish()
|
|
2125
|
+
})
|
|
2126
|
+
).default({})
|
|
2127
|
+
});
|
|
2128
|
+
var STUB_IGNORE_PATH = "apps/web/src/app/.gitignore";
|
|
2129
|
+
var STUB_IGNORE_HEADER = "# Generated by stardeck-compose \u2014 Module-rail stubs are build outputs; do not edit or commit them.";
|
|
2130
|
+
function escapeStubIgnorePattern(pattern) {
|
|
2131
|
+
const escaped = pattern.replace(/[\\[\]*?]/g, (char) => `\\${char}`);
|
|
2132
|
+
return /^[#!]/.test(escaped) ? `\\${escaped}` : escaped;
|
|
2133
|
+
}
|
|
2134
|
+
function buildStubIgnore(artifactPaths) {
|
|
2135
|
+
const prefix = "apps/web/src/app/";
|
|
2136
|
+
const entries = artifactPaths.filter((artifact) => artifact.startsWith(prefix)).map((artifact) => escapeStubIgnorePattern(`/${artifact.slice(prefix.length)}`)).sort();
|
|
2137
|
+
return [STUB_IGNORE_HEADER, ...entries].join("\n") + "\n";
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2140
|
+
// ../../packages/lib/src/shared/module-enablement.ts
|
|
2141
|
+
function isModuleEnabledByList(raw, name, kindOf) {
|
|
2142
|
+
if (!raw) return true;
|
|
2143
|
+
const kind = kindOf(name);
|
|
2144
|
+
if (kind != null && kind !== "feature") return true;
|
|
2145
|
+
return raw.split(",").includes(name);
|
|
2146
|
+
}
|
|
2103
2147
|
|
|
2104
2148
|
// ../../packages/module-contract/src/module-manifest.ts
|
|
2105
|
-
var
|
|
2149
|
+
var import_zod2 = require("zod");
|
|
2106
2150
|
|
|
2107
2151
|
// ../../packages/module-contract/src/slug.ts
|
|
2108
2152
|
function validateSlug(slug) {
|
|
@@ -2137,13 +2181,13 @@ var ROUTE_GROUP_REGEX = /^\([a-z0-9-]+\)$/;
|
|
|
2137
2181
|
var ENDPOINT_STATIC_SEGMENT_REGEX = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
2138
2182
|
var ENDPOINT_PARAM_NAME_REGEX = /^[a-z][a-z0-9_-]*$/;
|
|
2139
2183
|
var ENDPOINT_METHODS = ["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"];
|
|
2140
|
-
var moduleNameSchema =
|
|
2184
|
+
var moduleNameSchema = import_zod2.z.string().max(40).regex(KEBAB_SLUG_REGEX, "must be a kebab-case slug (lowercase letters, digits, hyphens)");
|
|
2141
2185
|
function isValidModuleName(value) {
|
|
2142
2186
|
return moduleNameSchema.safeParse(value).success;
|
|
2143
2187
|
}
|
|
2144
|
-
var projectSlugSchema =
|
|
2145
|
-
var moduleKindSchema =
|
|
2146
|
-
var endpointMethodSchema =
|
|
2188
|
+
var projectSlugSchema = import_zod2.z.string().refine((value) => validateSlug(value).valid, "must be a valid project slug");
|
|
2189
|
+
var moduleKindSchema = import_zod2.z.enum(["feature", "library", "contract"]);
|
|
2190
|
+
var endpointMethodSchema = import_zod2.z.enum(ENDPOINT_METHODS);
|
|
2147
2191
|
function endpointPathValidationError(path4) {
|
|
2148
2192
|
if (!path4.startsWith("/api/")) {
|
|
2149
2193
|
return 'must begin with "/api/"';
|
|
@@ -2228,21 +2272,21 @@ function normalizeEndpointPathForCollision(path4) {
|
|
|
2228
2272
|
return segment;
|
|
2229
2273
|
}).join("/");
|
|
2230
2274
|
}
|
|
2231
|
-
var endpointPathSchema =
|
|
2275
|
+
var endpointPathSchema = import_zod2.z.string().superRefine((path4, ctx) => {
|
|
2232
2276
|
const error = endpointPathValidationError(path4);
|
|
2233
2277
|
if (error != null) {
|
|
2234
|
-
ctx.addIssue({ code:
|
|
2278
|
+
ctx.addIssue({ code: import_zod2.z.ZodIssueCode.custom, message: error });
|
|
2235
2279
|
}
|
|
2236
2280
|
});
|
|
2237
|
-
var endpointClaimSchema =
|
|
2281
|
+
var endpointClaimSchema = import_zod2.z.object({
|
|
2238
2282
|
path: endpointPathSchema,
|
|
2239
|
-
methods:
|
|
2283
|
+
methods: import_zod2.z.array(endpointMethodSchema).min(1, "methods must be non-empty").superRefine((methods, ctx) => {
|
|
2240
2284
|
const seen = /* @__PURE__ */ new Set();
|
|
2241
2285
|
for (let i = 0; i < methods.length; i += 1) {
|
|
2242
2286
|
const method = methods[i];
|
|
2243
2287
|
if (seen.has(method)) {
|
|
2244
2288
|
ctx.addIssue({
|
|
2245
|
-
code:
|
|
2289
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2246
2290
|
message: `duplicate method "${method}"`,
|
|
2247
2291
|
path: [i]
|
|
2248
2292
|
});
|
|
@@ -2279,14 +2323,14 @@ function mountSegmentValidationError(segment) {
|
|
|
2279
2323
|
}
|
|
2280
2324
|
return null;
|
|
2281
2325
|
}
|
|
2282
|
-
var mountSegmentSchema =
|
|
2326
|
+
var mountSegmentSchema = import_zod2.z.string().superRefine((segment, ctx) => {
|
|
2283
2327
|
const error = mountSegmentValidationError(segment);
|
|
2284
2328
|
if (error != null) {
|
|
2285
|
-
ctx.addIssue({ code:
|
|
2329
|
+
ctx.addIssue({ code: import_zod2.z.ZodIssueCode.custom, message: error });
|
|
2286
2330
|
}
|
|
2287
2331
|
});
|
|
2288
|
-
var mountSchema =
|
|
2289
|
-
group:
|
|
2332
|
+
var mountSchema = import_zod2.z.object({
|
|
2333
|
+
group: import_zod2.z.string().regex(ROUTE_GROUP_REGEX, 'must be a Next.js route group like "(admin)"'),
|
|
2290
2334
|
segment: mountSegmentSchema
|
|
2291
2335
|
}).strict();
|
|
2292
2336
|
function splitMountSegment(segment) {
|
|
@@ -2299,21 +2343,21 @@ function splitMountSegment(segment) {
|
|
|
2299
2343
|
}
|
|
2300
2344
|
return segment.split("/");
|
|
2301
2345
|
}
|
|
2302
|
-
var tableNameSchema =
|
|
2346
|
+
var tableNameSchema = import_zod2.z.string().regex(SNAKE_TABLE_REGEX, "must be snake_case");
|
|
2303
2347
|
var NPM_PACKAGE_NAME_REGEX = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;
|
|
2304
|
-
var npmPackageNameSchema =
|
|
2305
|
-
var descriptionSchema =
|
|
2306
|
-
var crossAppSchema =
|
|
2307
|
-
exposes:
|
|
2308
|
-
consumes:
|
|
2348
|
+
var npmPackageNameSchema = import_zod2.z.string().max(214).regex(NPM_PACKAGE_NAME_REGEX, "must be a valid npm package name");
|
|
2349
|
+
var descriptionSchema = import_zod2.z.string().max(200, "must be at most 200 characters").refine((value) => value.trim().length > 0, "must be non-empty after trimming");
|
|
2350
|
+
var crossAppSchema = import_zod2.z.object({
|
|
2351
|
+
exposes: import_zod2.z.array(import_zod2.z.unknown()).max(0, "must be empty until cross-app contracts are defined"),
|
|
2352
|
+
consumes: import_zod2.z.array(import_zod2.z.unknown()).max(0, "must be empty until cross-app contracts are defined")
|
|
2309
2353
|
}).strict();
|
|
2310
|
-
var enhancementWorkflowsSchema =
|
|
2311
|
-
var enhancementEndpointsSchema =
|
|
2312
|
-
var datastoreRequirementSchema =
|
|
2354
|
+
var enhancementWorkflowsSchema = import_zod2.z.record(moduleNameSchema, import_zod2.z.array(import_zod2.z.string().min(1))).default({});
|
|
2355
|
+
var enhancementEndpointsSchema = import_zod2.z.record(moduleNameSchema, import_zod2.z.array(endpointClaimSchema)).default({});
|
|
2356
|
+
var datastoreRequirementSchema = import_zod2.z.object({
|
|
2313
2357
|
/** Logical name, module-local, snake_case. Never a physical store key. */
|
|
2314
2358
|
id: tableNameSchema,
|
|
2315
2359
|
/** "app" = this project's app-local store; "org" = an org-level shared store. */
|
|
2316
|
-
scope:
|
|
2360
|
+
scope: import_zod2.z.enum(["app", "org"]).default("app"),
|
|
2317
2361
|
/**
|
|
2318
2362
|
* Which kind of connected store satisfies this requirement. A "database"
|
|
2319
2363
|
* requirement only ever binds to a database store and a "storage" one
|
|
@@ -2321,34 +2365,34 @@ var datastoreRequirementSchema = import_zod.z.object({
|
|
|
2321
2365
|
* rail never crosses the two. Defaults to "database", the only kind the
|
|
2322
2366
|
* rail resolved before this field existed.
|
|
2323
2367
|
*/
|
|
2324
|
-
type:
|
|
2368
|
+
type: import_zod2.z.enum(["database", "storage"]).default("database"),
|
|
2325
2369
|
/** true → install fails when no store resolves; false → binding omitted, module degrades. */
|
|
2326
|
-
required:
|
|
2370
|
+
required: import_zod2.z.boolean().default(true),
|
|
2327
2371
|
/** Checked against the connected store's accessLevel at install. */
|
|
2328
|
-
access:
|
|
2372
|
+
access: import_zod2.z.enum(["read", "write", "admin"]).default("write")
|
|
2329
2373
|
}).strict();
|
|
2330
|
-
var permissionClaimSchema =
|
|
2374
|
+
var permissionClaimSchema = import_zod2.z.object({
|
|
2331
2375
|
/**
|
|
2332
2376
|
* Lowercase resource:action with one colon and no underscores. This grammar
|
|
2333
2377
|
* is deliberately narrower than the platform permission tool's charset.
|
|
2334
2378
|
*/
|
|
2335
|
-
key:
|
|
2379
|
+
key: import_zod2.z.string().regex(/^[a-z0-9][a-z0-9-]*:[a-z0-9][a-z0-9-]*$/, "must be a lowercase resource:action key").max(100, "must be at most 100 characters (platform permission tool limit)"),
|
|
2336
2380
|
/** Human label for the deployment auth config row. */
|
|
2337
2381
|
description: descriptionSchema
|
|
2338
2382
|
}).strict();
|
|
2339
|
-
var seedBundleSchema =
|
|
2383
|
+
var seedBundleSchema = import_zod2.z.object({
|
|
2340
2384
|
table: tableNameSchema,
|
|
2341
2385
|
/** Columns forming the ON CONFLICT key — must appear in every row. */
|
|
2342
|
-
conflictTarget:
|
|
2386
|
+
conflictTarget: import_zod2.z.array(import_zod2.z.string().min(1)).min(1),
|
|
2343
2387
|
/** Scalar JSON values only (no nested objects/arrays). */
|
|
2344
|
-
rows:
|
|
2388
|
+
rows: import_zod2.z.array(import_zod2.z.record(import_zod2.z.string(), import_zod2.z.union([import_zod2.z.string(), import_zod2.z.number(), import_zod2.z.boolean(), import_zod2.z.null()]))).min(1)
|
|
2345
2389
|
}).strict().superRefine((bundle, ctx) => {
|
|
2346
2390
|
const rowKeys = bundle.rows.map((row) => Object.keys(row).sort().join("\0"));
|
|
2347
2391
|
const canonical = rowKeys[0];
|
|
2348
2392
|
for (let i = 1; i < rowKeys.length; i += 1) {
|
|
2349
2393
|
if (rowKeys[i] !== canonical) {
|
|
2350
2394
|
ctx.addIssue({
|
|
2351
|
-
code:
|
|
2395
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2352
2396
|
message: "all rows in a seed bundle must have identical key sets",
|
|
2353
2397
|
path: ["rows", i]
|
|
2354
2398
|
});
|
|
@@ -2360,7 +2404,7 @@ var seedBundleSchema = import_zod.z.object({
|
|
|
2360
2404
|
for (const col of bundle.conflictTarget) {
|
|
2361
2405
|
if (!keys.has(col)) {
|
|
2362
2406
|
ctx.addIssue({
|
|
2363
|
-
code:
|
|
2407
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2364
2408
|
message: `conflictTarget column "${col}" must be present in every row`,
|
|
2365
2409
|
path: ["rows", i]
|
|
2366
2410
|
});
|
|
@@ -2368,35 +2412,35 @@ var seedBundleSchema = import_zod.z.object({
|
|
|
2368
2412
|
}
|
|
2369
2413
|
}
|
|
2370
2414
|
});
|
|
2371
|
-
var moduleManifestSchema =
|
|
2415
|
+
var moduleManifestSchema = import_zod2.z.object({
|
|
2372
2416
|
name: moduleNameSchema,
|
|
2373
2417
|
kind: moduleKindSchema,
|
|
2374
2418
|
// Release versions are platform-owned in module_versions. Accept this
|
|
2375
2419
|
// legacy field while existing Module source ages out, but strip it from the
|
|
2376
2420
|
// parsed contract so no runtime can treat module.json as version authority.
|
|
2377
|
-
version:
|
|
2421
|
+
version: import_zod2.z.unknown().optional(),
|
|
2378
2422
|
home: projectSlugSchema,
|
|
2379
2423
|
/** Machine-checkable purpose line — required, ≤200 code units, non-blank when trimmed. */
|
|
2380
2424
|
description: descriptionSchema,
|
|
2381
|
-
uses:
|
|
2425
|
+
uses: import_zod2.z.array(moduleNameSchema).default([]),
|
|
2382
2426
|
/**
|
|
2383
2427
|
* Soft peers: this module ships `enhancements/<peer>/` directories that are
|
|
2384
2428
|
* composition-pruned — the installer includes them only when the peer is
|
|
2385
2429
|
* present, so the peer is NOT an install-time requirement. Disjoint from
|
|
2386
2430
|
* `uses`; entries may name modules absent from the composition.
|
|
2387
2431
|
*/
|
|
2388
|
-
enhancements:
|
|
2389
|
-
tables:
|
|
2390
|
-
mounts:
|
|
2391
|
-
integration:
|
|
2392
|
-
workflows:
|
|
2432
|
+
enhancements: import_zod2.z.array(moduleNameSchema).default([]),
|
|
2433
|
+
tables: import_zod2.z.array(tableNameSchema).default([]),
|
|
2434
|
+
mounts: import_zod2.z.array(mountSchema).default([]),
|
|
2435
|
+
integration: import_zod2.z.array(import_zod2.z.string()).default([]),
|
|
2436
|
+
workflows: import_zod2.z.array(import_zod2.z.string().min(1)).default([]),
|
|
2393
2437
|
/**
|
|
2394
2438
|
* Slice-scoped workflow names keyed by peer. Keys must be ⊆ `enhancements`;
|
|
2395
2439
|
* names must be unique across root `workflows` and every slice list.
|
|
2396
2440
|
*/
|
|
2397
2441
|
enhancementWorkflows: enhancementWorkflowsSchema,
|
|
2398
2442
|
/** Root API endpoint path claims. */
|
|
2399
|
-
endpoints:
|
|
2443
|
+
endpoints: import_zod2.z.array(endpointClaimSchema).default([]),
|
|
2400
2444
|
/**
|
|
2401
2445
|
* Slice-scoped endpoint claims keyed by peer. Keys must be ⊆ `enhancements`;
|
|
2402
2446
|
* normalized paths must be unique across root and every slice.
|
|
@@ -2412,38 +2456,38 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2412
2456
|
* to a physical connected store and generates module-datastores.gen.ts;
|
|
2413
2457
|
* unlike seeds, this field drives generated output.
|
|
2414
2458
|
*/
|
|
2415
|
-
datastores:
|
|
2459
|
+
datastores: import_zod2.z.array(datastoreRequirementSchema).optional(),
|
|
2416
2460
|
/**
|
|
2417
2461
|
* Keys this module's guards enforce. Install registers them in deployment
|
|
2418
2462
|
* auth config; registration only — declaring is never granting.
|
|
2419
2463
|
*/
|
|
2420
|
-
permissions:
|
|
2464
|
+
permissions: import_zod2.z.array(permissionClaimSchema).optional(),
|
|
2421
2465
|
/**
|
|
2422
2466
|
* Optional starter rows for tables this module owns. Replay is
|
|
2423
2467
|
* `INSERT ... ON CONFLICT (conflictTarget) DO NOTHING` — idempotent by
|
|
2424
2468
|
* construction; the rail (not this schema) performs the replay.
|
|
2425
2469
|
*/
|
|
2426
|
-
seeds:
|
|
2470
|
+
seeds: import_zod2.z.array(seedBundleSchema).optional(),
|
|
2427
2471
|
/** npm packages the source imports beyond the base app. Names only; the rail installs each at the home app's range. */
|
|
2428
|
-
packages:
|
|
2472
|
+
packages: import_zod2.z.array(npmPackageNameSchema).optional(),
|
|
2429
2473
|
/**
|
|
2430
2474
|
* UI-layer contract. `separable: true` asserts the Module's components/ and
|
|
2431
2475
|
* routes/ hold presentation only — the Blueprint's
|
|
2432
2476
|
* `module-boundaries/ui-layer` lint rule enforces it — so a fork may
|
|
2433
2477
|
* soft-eject them. See docs/module-ui-soft-eject-plan.md.
|
|
2434
2478
|
*/
|
|
2435
|
-
ui:
|
|
2479
|
+
ui: import_zod2.z.object({ separable: import_zod2.z.boolean() }).strict().optional()
|
|
2436
2480
|
}).strict().superRefine((manifest, ctx) => {
|
|
2437
2481
|
if (manifest.uses.includes(manifest.name)) {
|
|
2438
2482
|
ctx.addIssue({
|
|
2439
|
-
code:
|
|
2483
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2440
2484
|
message: "a module cannot list itself in uses",
|
|
2441
2485
|
path: ["uses"]
|
|
2442
2486
|
});
|
|
2443
2487
|
}
|
|
2444
2488
|
if (manifest.enhancements.includes(manifest.name)) {
|
|
2445
2489
|
ctx.addIssue({
|
|
2446
|
-
code:
|
|
2490
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2447
2491
|
message: "a module cannot list itself in enhancements",
|
|
2448
2492
|
path: ["enhancements"]
|
|
2449
2493
|
});
|
|
@@ -2451,7 +2495,7 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2451
2495
|
const hardAndSoft = manifest.enhancements.filter((peer) => manifest.uses.includes(peer));
|
|
2452
2496
|
if (hardAndSoft.length > 0) {
|
|
2453
2497
|
ctx.addIssue({
|
|
2454
|
-
code:
|
|
2498
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2455
2499
|
message: `uses and enhancements must be disjoint (a peer is either a hard dep or a soft one): ${hardAndSoft.join(", ")}`,
|
|
2456
2500
|
path: ["enhancements"]
|
|
2457
2501
|
});
|
|
@@ -2460,7 +2504,7 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2460
2504
|
for (const peer of Object.keys(manifest.enhancementWorkflows)) {
|
|
2461
2505
|
if (!enhancementPeers.has(peer)) {
|
|
2462
2506
|
ctx.addIssue({
|
|
2463
|
-
code:
|
|
2507
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2464
2508
|
message: `enhancementWorkflows key "${peer}" must be listed in enhancements`,
|
|
2465
2509
|
path: ["enhancementWorkflows", peer]
|
|
2466
2510
|
});
|
|
@@ -2469,7 +2513,7 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2469
2513
|
for (const peer of Object.keys(manifest.enhancementEndpoints)) {
|
|
2470
2514
|
if (!enhancementPeers.has(peer)) {
|
|
2471
2515
|
ctx.addIssue({
|
|
2472
|
-
code:
|
|
2516
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2473
2517
|
message: `enhancementEndpoints key "${peer}" must be listed in enhancements`,
|
|
2474
2518
|
path: ["enhancementEndpoints", peer]
|
|
2475
2519
|
});
|
|
@@ -2480,7 +2524,7 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2480
2524
|
const existing = seenWorkflows.get(name);
|
|
2481
2525
|
if (existing != null) {
|
|
2482
2526
|
ctx.addIssue({
|
|
2483
|
-
code:
|
|
2527
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2484
2528
|
message: `duplicate workflow name "${name}" (also at ${existing})`,
|
|
2485
2529
|
path: path4
|
|
2486
2530
|
});
|
|
@@ -2507,7 +2551,7 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2507
2551
|
const existing = seenEndpointKeys.get(key);
|
|
2508
2552
|
if (existing != null) {
|
|
2509
2553
|
ctx.addIssue({
|
|
2510
|
-
code:
|
|
2554
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2511
2555
|
message: `duplicate normalized endpoint path "${key}" (also at ${existing})`,
|
|
2512
2556
|
path: path4
|
|
2513
2557
|
});
|
|
@@ -2529,7 +2573,7 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2529
2573
|
const id = manifest.datastores[i].id;
|
|
2530
2574
|
if (seenDatastoreIds.has(id)) {
|
|
2531
2575
|
ctx.addIssue({
|
|
2532
|
-
code:
|
|
2576
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2533
2577
|
message: `duplicate datastore id "${id}"`,
|
|
2534
2578
|
path: ["datastores", i, "id"]
|
|
2535
2579
|
});
|
|
@@ -2544,7 +2588,7 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2544
2588
|
const key = manifest.permissions[i].key;
|
|
2545
2589
|
if (seenPermissionKeys.has(key)) {
|
|
2546
2590
|
ctx.addIssue({
|
|
2547
|
-
code:
|
|
2591
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2548
2592
|
message: `duplicate permission key "${key}"`,
|
|
2549
2593
|
path: ["permissions", i, "key"]
|
|
2550
2594
|
});
|
|
@@ -2556,35 +2600,35 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2556
2600
|
if (manifest.kind === "library") {
|
|
2557
2601
|
if (manifest.tables.length > 0) {
|
|
2558
2602
|
ctx.addIssue({
|
|
2559
|
-
code:
|
|
2603
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2560
2604
|
message: "library modules must not declare tables",
|
|
2561
2605
|
path: ["tables"]
|
|
2562
2606
|
});
|
|
2563
2607
|
}
|
|
2564
2608
|
if (manifest.mounts.length > 0) {
|
|
2565
2609
|
ctx.addIssue({
|
|
2566
|
-
code:
|
|
2610
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2567
2611
|
message: "library modules must not declare mounts",
|
|
2568
2612
|
path: ["mounts"]
|
|
2569
2613
|
});
|
|
2570
2614
|
}
|
|
2571
2615
|
if (manifest.seeds != null && manifest.seeds.length > 0) {
|
|
2572
2616
|
ctx.addIssue({
|
|
2573
|
-
code:
|
|
2617
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2574
2618
|
message: "library modules must not declare seeds",
|
|
2575
2619
|
path: ["seeds"]
|
|
2576
2620
|
});
|
|
2577
2621
|
}
|
|
2578
2622
|
if (manifest.datastores != null && manifest.datastores.length > 0) {
|
|
2579
2623
|
ctx.addIssue({
|
|
2580
|
-
code:
|
|
2624
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2581
2625
|
message: "library modules must not declare datastores",
|
|
2582
2626
|
path: ["datastores"]
|
|
2583
2627
|
});
|
|
2584
2628
|
}
|
|
2585
2629
|
if (manifest.permissions != null && manifest.permissions.length > 0) {
|
|
2586
2630
|
ctx.addIssue({
|
|
2587
|
-
code:
|
|
2631
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2588
2632
|
message: "library modules must not declare permissions",
|
|
2589
2633
|
path: ["permissions"]
|
|
2590
2634
|
});
|
|
@@ -2592,7 +2636,7 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2592
2636
|
}
|
|
2593
2637
|
if (manifest.kind === "contract" && manifest.mounts.length > 0) {
|
|
2594
2638
|
ctx.addIssue({
|
|
2595
|
-
code:
|
|
2639
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2596
2640
|
message: "contract modules must not declare mounts",
|
|
2597
2641
|
path: ["mounts"]
|
|
2598
2642
|
});
|
|
@@ -2603,7 +2647,7 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2603
2647
|
const bundle = manifest.seeds[i];
|
|
2604
2648
|
if (!ownedTables.has(bundle.table)) {
|
|
2605
2649
|
ctx.addIssue({
|
|
2606
|
-
code:
|
|
2650
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2607
2651
|
message: `seeds may only target tables listed in tables (got "${bundle.table}")`,
|
|
2608
2652
|
path: ["seeds", i, "table"]
|
|
2609
2653
|
});
|
|
@@ -2654,10 +2698,10 @@ var MANDATORY_MODULE_CHECK_DESCRIPTORS = Object.freeze([
|
|
|
2654
2698
|
]);
|
|
2655
2699
|
|
|
2656
2700
|
// ../../packages/module-contract/src/module-structure.ts
|
|
2657
|
-
var
|
|
2701
|
+
var import_zod4 = require("zod");
|
|
2658
2702
|
|
|
2659
2703
|
// ../../packages/module-contract/src/module-e2e-manifest.ts
|
|
2660
|
-
var
|
|
2704
|
+
var import_zod3 = require("zod");
|
|
2661
2705
|
function e2eSpecFileValidationError(file) {
|
|
2662
2706
|
if (file.length === 0) {
|
|
2663
2707
|
return "must be a non-empty relative path ending in .spec.ts";
|
|
@@ -2685,22 +2729,22 @@ function e2eSpecFileValidationError(file) {
|
|
|
2685
2729
|
}
|
|
2686
2730
|
return null;
|
|
2687
2731
|
}
|
|
2688
|
-
var e2eSpecFileSchema =
|
|
2732
|
+
var e2eSpecFileSchema = import_zod3.z.string().superRefine((file, ctx) => {
|
|
2689
2733
|
const error = e2eSpecFileValidationError(file);
|
|
2690
2734
|
if (error != null) {
|
|
2691
|
-
ctx.addIssue({ code:
|
|
2735
|
+
ctx.addIssue({ code: import_zod3.z.ZodIssueCode.custom, message: error });
|
|
2692
2736
|
}
|
|
2693
2737
|
});
|
|
2694
|
-
var e2eSpecSchema =
|
|
2738
|
+
var e2eSpecSchema = import_zod3.z.object({
|
|
2695
2739
|
file: e2eSpecFileSchema,
|
|
2696
|
-
requires:
|
|
2740
|
+
requires: import_zod3.z.array(moduleNameSchema).min(1, "requires must be non-empty")
|
|
2697
2741
|
}).strict().superRefine((spec, ctx) => {
|
|
2698
2742
|
const seen = /* @__PURE__ */ new Set();
|
|
2699
2743
|
for (let i = 0; i < spec.requires.length; i += 1) {
|
|
2700
2744
|
const name = spec.requires[i];
|
|
2701
2745
|
if (seen.has(name)) {
|
|
2702
2746
|
ctx.addIssue({
|
|
2703
|
-
code:
|
|
2747
|
+
code: import_zod3.z.ZodIssueCode.custom,
|
|
2704
2748
|
message: `duplicate requirement "${name}"`,
|
|
2705
2749
|
path: ["requires", i]
|
|
2706
2750
|
});
|
|
@@ -2709,15 +2753,15 @@ var e2eSpecSchema = import_zod2.z.object({
|
|
|
2709
2753
|
}
|
|
2710
2754
|
}
|
|
2711
2755
|
});
|
|
2712
|
-
var moduleE2eManifestSchema =
|
|
2713
|
-
specs:
|
|
2756
|
+
var moduleE2eManifestSchema = import_zod3.z.object({
|
|
2757
|
+
specs: import_zod3.z.array(e2eSpecSchema).min(1, "specs must contain at least one entry")
|
|
2714
2758
|
}).strict().superRefine((manifest, ctx) => {
|
|
2715
2759
|
const seenFiles = /* @__PURE__ */ new Set();
|
|
2716
2760
|
for (let i = 0; i < manifest.specs.length; i += 1) {
|
|
2717
2761
|
const file = manifest.specs[i].file;
|
|
2718
2762
|
if (seenFiles.has(file)) {
|
|
2719
2763
|
ctx.addIssue({
|
|
2720
|
-
code:
|
|
2764
|
+
code: import_zod3.z.ZodIssueCode.custom,
|
|
2721
2765
|
message: `duplicate file "${file}"`,
|
|
2722
2766
|
path: ["specs", i, "file"]
|
|
2723
2767
|
});
|
|
@@ -2959,7 +3003,7 @@ function compareCodeUnit(a, b) {
|
|
|
2959
3003
|
// ../../packages/module-contract/src/module-structure.ts
|
|
2960
3004
|
var MODULE_STRUCTURE_JSON_BYTE_CAP = 64 * 1024;
|
|
2961
3005
|
function uniqueSortedStringArray(label) {
|
|
2962
|
-
return
|
|
3006
|
+
return import_zod4.z.array(import_zod4.z.string()).superRefine((arr, ctx) => {
|
|
2963
3007
|
if (new Set(arr).size !== arr.length) {
|
|
2964
3008
|
ctx.addIssue({ code: "custom", message: `${label} must be unique` });
|
|
2965
3009
|
return;
|
|
@@ -2975,10 +3019,10 @@ function uniqueSortedStringArray(label) {
|
|
|
2975
3019
|
});
|
|
2976
3020
|
}
|
|
2977
3021
|
function contributionPermissionsSchema(label) {
|
|
2978
|
-
return
|
|
2979
|
-
|
|
2980
|
-
contributionId:
|
|
2981
|
-
permission:
|
|
3022
|
+
return import_zod4.z.array(
|
|
3023
|
+
import_zod4.z.object({
|
|
3024
|
+
contributionId: import_zod4.z.string().min(1),
|
|
3025
|
+
permission: import_zod4.z.string().min(1)
|
|
2982
3026
|
}).strict()
|
|
2983
3027
|
).superRefine((entries, ctx) => {
|
|
2984
3028
|
const keys = entries.map((entry) => `${entry.contributionId}\0${entry.permission}`);
|
|
@@ -2996,17 +3040,17 @@ function contributionPermissionsSchema(label) {
|
|
|
2996
3040
|
}
|
|
2997
3041
|
}).optional();
|
|
2998
3042
|
}
|
|
2999
|
-
var collectedFilePayloadSchema =
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3043
|
+
var collectedFilePayloadSchema = import_zod4.z.discriminatedUnion("status", [
|
|
3044
|
+
import_zod4.z.object({ status: import_zod4.z.literal("ok"), text: import_zod4.z.string() }).strict(),
|
|
3045
|
+
import_zod4.z.object({ status: import_zod4.z.literal("missing") }).strict(),
|
|
3046
|
+
import_zod4.z.object({ status: import_zod4.z.literal("too-large") }).strict(),
|
|
3047
|
+
import_zod4.z.object({ status: import_zod4.z.literal("unreadable") }).strict()
|
|
3004
3048
|
]);
|
|
3005
|
-
var collectedLocaleFileSchema =
|
|
3006
|
-
locale:
|
|
3049
|
+
var collectedLocaleFileSchema = import_zod4.z.object({
|
|
3050
|
+
locale: import_zod4.z.string().min(1),
|
|
3007
3051
|
payload: collectedFilePayloadSchema
|
|
3008
3052
|
}).strict();
|
|
3009
|
-
var collectedE2eFactsSchema =
|
|
3053
|
+
var collectedE2eFactsSchema = import_zod4.z.object({
|
|
3010
3054
|
manifest: collectedFilePayloadSchema,
|
|
3011
3055
|
specFiles: uniqueSortedStringArray("specFiles"),
|
|
3012
3056
|
escapingSymlinks: uniqueSortedStringArray("escapingSymlinks")
|
|
@@ -3028,20 +3072,20 @@ function validateRouteExportEvidenceCongruence(input) {
|
|
|
3028
3072
|
}
|
|
3029
3073
|
}
|
|
3030
3074
|
}
|
|
3031
|
-
var collectedEnhancementFactsSchema =
|
|
3032
|
-
peer:
|
|
3033
|
-
hasContributionsTs:
|
|
3075
|
+
var collectedEnhancementFactsSchema = import_zod4.z.object({
|
|
3076
|
+
peer: import_zod4.z.string().min(1),
|
|
3077
|
+
hasContributionsTs: import_zod4.z.boolean(),
|
|
3034
3078
|
contributionPermissions: contributionPermissionsSchema("enhancement contributionPermissions"),
|
|
3035
|
-
hasInitializeServerTs:
|
|
3079
|
+
hasInitializeServerTs: import_zod4.z.boolean(),
|
|
3036
3080
|
contributionsCollectionErrors: uniqueSortedStringArray(
|
|
3037
3081
|
"enhancement contributionsCollectionErrors"
|
|
3038
3082
|
),
|
|
3039
3083
|
initializeServerCollectionErrors: uniqueSortedStringArray(
|
|
3040
3084
|
"enhancement initializeServerCollectionErrors"
|
|
3041
3085
|
),
|
|
3042
|
-
hasRoutesDir:
|
|
3086
|
+
hasRoutesDir: import_zod4.z.boolean(),
|
|
3043
3087
|
routeCollectionErrors: uniqueSortedStringArray("enhancement routeCollectionErrors"),
|
|
3044
|
-
locales:
|
|
3088
|
+
locales: import_zod4.z.array(collectedLocaleFileSchema).superRefine((locales, ctx) => {
|
|
3045
3089
|
const names = locales.map((l) => l.locale);
|
|
3046
3090
|
if (new Set(names).size !== names.length) {
|
|
3047
3091
|
ctx.addIssue({ code: "custom", message: "enhancement locales must be unique by locale" });
|
|
@@ -3056,27 +3100,27 @@ var collectedEnhancementFactsSchema = import_zod3.z.object({
|
|
|
3056
3100
|
}),
|
|
3057
3101
|
e2e: collectedE2eFactsSchema.nullable()
|
|
3058
3102
|
}).strict();
|
|
3059
|
-
var moduleStructureFactsSchema =
|
|
3060
|
-
collected:
|
|
3061
|
-
dirName:
|
|
3062
|
-
hasIndexTs:
|
|
3063
|
-
hasContributionsTs:
|
|
3103
|
+
var moduleStructureFactsSchema = import_zod4.z.object({
|
|
3104
|
+
collected: import_zod4.z.literal(true),
|
|
3105
|
+
dirName: import_zod4.z.string().min(1),
|
|
3106
|
+
hasIndexTs: import_zod4.z.boolean(),
|
|
3107
|
+
hasContributionsTs: import_zod4.z.boolean(),
|
|
3064
3108
|
contributionPermissions: contributionPermissionsSchema("contributionPermissions"),
|
|
3065
|
-
hasSlotsTs:
|
|
3109
|
+
hasSlotsTs: import_zod4.z.boolean(),
|
|
3066
3110
|
contributionsCollectionErrors: uniqueSortedStringArray("contributionsCollectionErrors"),
|
|
3067
3111
|
slotsCollectionErrors: uniqueSortedStringArray("slotsCollectionErrors"),
|
|
3068
|
-
hasTestsDir:
|
|
3069
|
-
hasDatastoreDir:
|
|
3070
|
-
datastoreFileCount:
|
|
3071
|
-
hasServerIndexTs:
|
|
3072
|
-
hasOtherServerTs:
|
|
3073
|
-
hasE2eDir:
|
|
3074
|
-
hasRoutesDir:
|
|
3112
|
+
hasTestsDir: import_zod4.z.boolean(),
|
|
3113
|
+
hasDatastoreDir: import_zod4.z.boolean(),
|
|
3114
|
+
datastoreFileCount: import_zod4.z.number().int().nonnegative(),
|
|
3115
|
+
hasServerIndexTs: import_zod4.z.boolean(),
|
|
3116
|
+
hasOtherServerTs: import_zod4.z.boolean(),
|
|
3117
|
+
hasE2eDir: import_zod4.z.boolean(),
|
|
3118
|
+
hasRoutesDir: import_zod4.z.boolean(),
|
|
3075
3119
|
routeEntries: uniqueSortedStringArray("routeEntries"),
|
|
3076
|
-
routePageExports:
|
|
3077
|
-
|
|
3078
|
-
nextRelativePath:
|
|
3079
|
-
hasGenerateMetadata:
|
|
3120
|
+
routePageExports: import_zod4.z.array(
|
|
3121
|
+
import_zod4.z.object({
|
|
3122
|
+
nextRelativePath: import_zod4.z.string().min(1),
|
|
3123
|
+
hasGenerateMetadata: import_zod4.z.boolean()
|
|
3080
3124
|
}).strict()
|
|
3081
3125
|
).superRefine((entries, ctx) => {
|
|
3082
3126
|
const paths = entries.map((e) => e.nextRelativePath);
|
|
@@ -3098,7 +3142,7 @@ var moduleStructureFactsSchema = import_zod3.z.object({
|
|
|
3098
3142
|
}
|
|
3099
3143
|
}),
|
|
3100
3144
|
routeCollectionErrors: uniqueSortedStringArray("routeCollectionErrors"),
|
|
3101
|
-
rootLocales:
|
|
3145
|
+
rootLocales: import_zod4.z.array(collectedLocaleFileSchema).superRefine((locales, ctx) => {
|
|
3102
3146
|
const names = locales.map((l) => l.locale);
|
|
3103
3147
|
if (new Set(names).size !== names.length) {
|
|
3104
3148
|
ctx.addIssue({ code: "custom", message: "rootLocales must be unique by locale" });
|
|
@@ -3112,7 +3156,7 @@ var moduleStructureFactsSchema = import_zod3.z.object({
|
|
|
3112
3156
|
}
|
|
3113
3157
|
}),
|
|
3114
3158
|
rootE2e: collectedE2eFactsSchema.nullable(),
|
|
3115
|
-
enhancements:
|
|
3159
|
+
enhancements: import_zod4.z.array(collectedEnhancementFactsSchema).superRefine((enhancements, ctx) => {
|
|
3116
3160
|
const peers = enhancements.map((e) => e.peer);
|
|
3117
3161
|
if (new Set(peers).size !== peers.length) {
|
|
3118
3162
|
ctx.addIssue({ code: "custom", message: "enhancement peers must be unique" });
|
|
@@ -3133,10 +3177,10 @@ var moduleStructureFactsSchema = import_zod3.z.object({
|
|
|
3133
3177
|
onIssue: (message) => ctx.addIssue({ code: "custom", message })
|
|
3134
3178
|
});
|
|
3135
3179
|
});
|
|
3136
|
-
var moduleStructureCollectionSchema =
|
|
3180
|
+
var moduleStructureCollectionSchema = import_zod4.z.object({
|
|
3137
3181
|
homeLocales: uniqueSortedStringArray("homeLocales"),
|
|
3138
|
-
modules:
|
|
3139
|
-
truncated:
|
|
3182
|
+
modules: import_zod4.z.array(moduleStructureFactsSchema),
|
|
3183
|
+
truncated: import_zod4.z.boolean().optional(),
|
|
3140
3184
|
collectionErrors: uniqueSortedStringArray("collectionErrors").optional()
|
|
3141
3185
|
}).strict().superRefine((collection, ctx) => {
|
|
3142
3186
|
const dirs = collection.modules.map((m) => m.dirName);
|
|
@@ -3153,9 +3197,9 @@ var moduleStructureCollectionSchema = import_zod3.z.object({
|
|
|
3153
3197
|
});
|
|
3154
3198
|
|
|
3155
3199
|
// ../../packages/module-contract/src/locale.ts
|
|
3156
|
-
var
|
|
3200
|
+
var import_zod5 = require("zod");
|
|
3157
3201
|
var LOCALE_BASENAME_REGEX = /^[a-z]{2,3}(-[A-Za-z0-9]+)*$/;
|
|
3158
|
-
var localeBasenameSchema =
|
|
3202
|
+
var localeBasenameSchema = import_zod5.z.string().max(35).regex(LOCALE_BASENAME_REGEX, "must be a BCP47-like locale tag (e.g. en, th, en-US)");
|
|
3159
3203
|
function isValidLocaleBasename(value) {
|
|
3160
3204
|
return localeBasenameSchema.safeParse(value).success;
|
|
3161
3205
|
}
|
|
@@ -3558,43 +3602,43 @@ function formatRoutePageExportErrors(nextRelativePath, validation) {
|
|
|
3558
3602
|
var import_typescript2 = __toESM(require("typescript"), 1);
|
|
3559
3603
|
|
|
3560
3604
|
// ../../packages/module-contract/src/module-registry.ts
|
|
3561
|
-
var
|
|
3562
|
-
var projectSlugSchema2 =
|
|
3563
|
-
var registryEnhancementSchema =
|
|
3605
|
+
var import_zod6 = require("zod");
|
|
3606
|
+
var projectSlugSchema2 = import_zod6.z.string().refine((value) => validateSlug(value).valid, "must be a valid project slug");
|
|
3607
|
+
var registryEnhancementSchema = import_zod6.z.object({
|
|
3564
3608
|
peer: moduleNameSchema,
|
|
3565
|
-
active:
|
|
3609
|
+
active: import_zod6.z.boolean()
|
|
3566
3610
|
}).strict();
|
|
3567
|
-
var registryModuleSchema =
|
|
3611
|
+
var registryModuleSchema = import_zod6.z.object({
|
|
3568
3612
|
name: moduleNameSchema,
|
|
3569
3613
|
/** Installed version as recorded by the rail (non-empty string). */
|
|
3570
|
-
version:
|
|
3614
|
+
version: import_zod6.z.string().min(1),
|
|
3571
3615
|
home: projectSlugSchema2,
|
|
3572
3616
|
kind: moduleKindSchema,
|
|
3573
|
-
mounts:
|
|
3574
|
-
enhancements:
|
|
3617
|
+
mounts: import_zod6.z.array(mountSchema),
|
|
3618
|
+
enhancements: import_zod6.z.array(registryEnhancementSchema)
|
|
3575
3619
|
}).strict().superRefine((mod, ctx) => {
|
|
3576
3620
|
for (let i = 0; i < mod.enhancements.length; i += 1) {
|
|
3577
3621
|
if (mod.enhancements[i].peer === mod.name) {
|
|
3578
3622
|
ctx.addIssue({
|
|
3579
|
-
code:
|
|
3623
|
+
code: import_zod6.z.ZodIssueCode.custom,
|
|
3580
3624
|
message: "enhancement peer must not equal the module's own name",
|
|
3581
3625
|
path: ["enhancements", i, "peer"]
|
|
3582
3626
|
});
|
|
3583
3627
|
}
|
|
3584
3628
|
}
|
|
3585
3629
|
});
|
|
3586
|
-
var generatedModuleRegistrySchema =
|
|
3587
|
-
registryVersion:
|
|
3630
|
+
var generatedModuleRegistrySchema = import_zod6.z.object({
|
|
3631
|
+
registryVersion: import_zod6.z.literal(1),
|
|
3588
3632
|
/** Rail run id, or `"manual"` for fixtures. */
|
|
3589
|
-
generatedBy:
|
|
3590
|
-
modules:
|
|
3633
|
+
generatedBy: import_zod6.z.string().min(1),
|
|
3634
|
+
modules: import_zod6.z.array(registryModuleSchema)
|
|
3591
3635
|
}).strict().superRefine((registry, ctx) => {
|
|
3592
3636
|
const seen = /* @__PURE__ */ new Set();
|
|
3593
3637
|
for (let i = 0; i < registry.modules.length; i += 1) {
|
|
3594
3638
|
const name = registry.modules[i].name;
|
|
3595
3639
|
if (seen.has(name)) {
|
|
3596
3640
|
ctx.addIssue({
|
|
3597
|
-
code:
|
|
3641
|
+
code: import_zod6.z.ZodIssueCode.custom,
|
|
3598
3642
|
message: `duplicate module name "${name}"`,
|
|
3599
3643
|
path: ["modules", i, "name"]
|
|
3600
3644
|
});
|
|
@@ -3965,169 +4009,6 @@ function analyzeClientSafeEntryImports(sourceText, fileName) {
|
|
|
3965
4009
|
return analyzeClientSafeEntryImportsWithTs(import_typescript3.default, sourceText, fileName);
|
|
3966
4010
|
}
|
|
3967
4011
|
|
|
3968
|
-
// ../../packages/lib/src/shared/module-composition.ts
|
|
3969
|
-
var moduleRefSchema = import_zod6.z.object({
|
|
3970
|
-
homeProjectId: import_zod6.z.string().uuid(),
|
|
3971
|
-
moduleName: moduleNameSchema
|
|
3972
|
-
});
|
|
3973
|
-
var creationSourceBlankSchema = import_zod6.z.object({
|
|
3974
|
-
type: import_zod6.z.literal("blank")
|
|
3975
|
-
});
|
|
3976
|
-
var creationSourceBlueprintSchema = import_zod6.z.object({
|
|
3977
|
-
type: import_zod6.z.literal("blueprint"),
|
|
3978
|
-
/** Internal template/fork project id — keep template naming in identifiers. */
|
|
3979
|
-
blueprintProjectId: import_zod6.z.string().uuid(),
|
|
3980
|
-
/**
|
|
3981
|
-
* `null`/absent means every feature Module. `[]` is refused: the platform
|
|
3982
|
-
* serialises it to an empty `NEXT_PUBLIC_STARDECK_ENABLED_MODULES`, which the
|
|
3983
|
-
* enablement parser reads back as "all" (`module-enablement.ts`) — the
|
|
3984
|
-
* opposite of what an empty selection means.
|
|
3985
|
-
*/
|
|
3986
|
-
enabledModules: import_zod6.z.array(moduleNameSchema).min(1, "Enable at least one Module").max(100).nullable().optional()
|
|
3987
|
-
});
|
|
3988
|
-
var creationSourceModulesSchema = import_zod6.z.object({
|
|
3989
|
-
type: import_zod6.z.literal("modules"),
|
|
3990
|
-
requested: import_zod6.z.array(moduleRefSchema).min(1)
|
|
3991
|
-
});
|
|
3992
|
-
var creationSourceSchema = import_zod6.z.discriminatedUnion("type", [
|
|
3993
|
-
creationSourceBlankSchema,
|
|
3994
|
-
creationSourceBlueprintSchema,
|
|
3995
|
-
creationSourceModulesSchema
|
|
3996
|
-
]);
|
|
3997
|
-
var moduleCompositionStatusSchema = import_zod6.z.enum([
|
|
3998
|
-
"pending",
|
|
3999
|
-
"installing",
|
|
4000
|
-
"ready",
|
|
4001
|
-
"partial",
|
|
4002
|
-
"failed"
|
|
4003
|
-
]);
|
|
4004
|
-
var resolvedModuleSnapshotSchema = moduleRefSchema.extend({
|
|
4005
|
-
version: import_zod6.z.string().min(1),
|
|
4006
|
-
homeCommitSha: import_zod6.z.string().min(1)
|
|
4007
|
-
});
|
|
4008
|
-
var moduleInstallHandoffSchema = import_zod6.z.object({
|
|
4009
|
-
moduleName: import_zod6.z.string().min(1),
|
|
4010
|
-
homeProjectId: import_zod6.z.string().uuid(),
|
|
4011
|
-
installedVersion: import_zod6.z.string().min(1),
|
|
4012
|
-
baselineSha: import_zod6.z.string().min(1),
|
|
4013
|
-
mounts: import_zod6.z.array(
|
|
4014
|
-
import_zod6.z.object({
|
|
4015
|
-
group: import_zod6.z.string(),
|
|
4016
|
-
segment: import_zod6.z.string()
|
|
4017
|
-
})
|
|
4018
|
-
),
|
|
4019
|
-
integration: import_zod6.z.array(import_zod6.z.string()),
|
|
4020
|
-
workflows: import_zod6.z.array(import_zod6.z.string()),
|
|
4021
|
-
prunedEnhancements: import_zod6.z.array(import_zod6.z.string()),
|
|
4022
|
-
restoredEnhancements: import_zod6.z.array(import_zod6.z.string()).optional(),
|
|
4023
|
-
permissions: import_zod6.z.array(
|
|
4024
|
-
import_zod6.z.object({
|
|
4025
|
-
key: import_zod6.z.string().min(1),
|
|
4026
|
-
description: import_zod6.z.string().min(1)
|
|
4027
|
-
})
|
|
4028
|
-
).optional()
|
|
4029
|
-
});
|
|
4030
|
-
var moduleCompositionRunAttemptSchema = import_zod6.z.object({
|
|
4031
|
-
module: moduleRefSchema,
|
|
4032
|
-
runId: import_zod6.z.string().min(1),
|
|
4033
|
-
status: import_zod6.z.string().min(1),
|
|
4034
|
-
schemaApplied: import_zod6.z.boolean(),
|
|
4035
|
-
error: import_zod6.z.string().optional(),
|
|
4036
|
-
/** Prefer full ModuleInstallHandoff; identity fields optional for older rows. */
|
|
4037
|
-
handoff: moduleInstallHandoffSchema.partial({ moduleName: true, homeProjectId: true }).optional()
|
|
4038
|
-
});
|
|
4039
|
-
var initialModuleCompositionSchema = import_zod6.z.object({
|
|
4040
|
-
version: import_zod6.z.literal(1),
|
|
4041
|
-
status: moduleCompositionStatusSchema,
|
|
4042
|
-
requested: import_zod6.z.array(moduleRefSchema).min(1),
|
|
4043
|
-
resolved: import_zod6.z.array(resolvedModuleSnapshotSchema),
|
|
4044
|
-
installOrder: import_zod6.z.array(moduleRefSchema),
|
|
4045
|
-
runs: import_zod6.z.array(moduleCompositionRunAttemptSchema).default([]),
|
|
4046
|
-
/**
|
|
4047
|
-
* True when any failed/partial attempt applied schema before failing.
|
|
4048
|
-
* Never claim transactional rollback across git/schema.
|
|
4049
|
-
*/
|
|
4050
|
-
schemaApplied: import_zod6.z.boolean().default(false),
|
|
4051
|
-
/**
|
|
4052
|
-
* Present when retry would silently change pinned home SHAs — caller must
|
|
4053
|
-
* reconfirm the new plan rather than continue.
|
|
4054
|
-
*/
|
|
4055
|
-
reconfirmationRequired: import_zod6.z.object({
|
|
4056
|
-
reason: import_zod6.z.string(),
|
|
4057
|
-
previous: import_zod6.z.array(resolvedModuleSnapshotSchema),
|
|
4058
|
-
next: import_zod6.z.array(resolvedModuleSnapshotSchema)
|
|
4059
|
-
}).optional(),
|
|
4060
|
-
error: import_zod6.z.string().optional(),
|
|
4061
|
-
/**
|
|
4062
|
-
* First-turn system handoff lifecycle. Absent/`pending` means inject when
|
|
4063
|
-
* status is ready; `consumed` means a successful agent turn already used it.
|
|
4064
|
-
*/
|
|
4065
|
-
systemHandoffStatus: import_zod6.z.enum(["pending", "consumed"]).optional(),
|
|
4066
|
-
/**
|
|
4067
|
-
* CAS ownership token for concurrent retry attempts. Only the attempt that
|
|
4068
|
-
* currently owns this value may reset or compensate durable composition state.
|
|
4069
|
-
*/
|
|
4070
|
-
retryAttemptId: import_zod6.z.string().min(1).optional(),
|
|
4071
|
-
/**
|
|
4072
|
-
* When the current `installing` attempt was claimed. A setup run that dies
|
|
4073
|
-
* with its host (a killed Vercel instance) leaves the composition `installing`
|
|
4074
|
-
* forever, and the creating page's poll only stops on ready/partial/failed —
|
|
4075
|
-
* so staleness, not a queue's stall detector, is what settles it. Absent on
|
|
4076
|
-
* rows claimed before this field existed; treated as stale.
|
|
4077
|
-
*/
|
|
4078
|
-
attemptStartedAt: import_zod6.z.string().datetime().optional(),
|
|
4079
|
-
/** Outside-module files the agent changed during connection work. */
|
|
4080
|
-
integrationFiles: import_zod6.z.array(import_zod6.z.string()).optional(),
|
|
4081
|
-
verificationSummary: import_zod6.z.string().optional()
|
|
4082
|
-
});
|
|
4083
|
-
var MODULE_SETUP_ATTEMPT_STALE_MS = 10 * 60 * 1e3;
|
|
4084
|
-
|
|
4085
|
-
// ../../packages/lib/src/shared/compose-inputs.ts
|
|
4086
|
-
var import_zod7 = require("zod");
|
|
4087
|
-
var COMPOSE_INPUTS_PATH = "apps/web/stardeck.compose.json";
|
|
4088
|
-
var composeInputsSchema = import_zod7.z.strictObject({
|
|
4089
|
-
connectedStores: import_zod7.z.array(
|
|
4090
|
-
import_zod7.z.strictObject({
|
|
4091
|
-
storeId: import_zod7.z.string().min(1),
|
|
4092
|
-
slug: import_zod7.z.string().min(1),
|
|
4093
|
-
// A row with an empty binding key must not fail a deploy: the rail
|
|
4094
|
-
// treats falsy as "no binding key", so normalise rather than reject.
|
|
4095
|
-
bindingKey: import_zod7.z.string().nullish().transform((value) => value || null),
|
|
4096
|
-
accessLevel: import_zod7.z.enum(["read", "write", "admin"]),
|
|
4097
|
-
// Defaulted so a file written before the platform emitted store types
|
|
4098
|
-
// (database rows only) still parses. The platform starts writing
|
|
4099
|
-
// storage rows, with `type` set, once forks run a compose that reads it.
|
|
4100
|
-
type: import_zod7.z.enum(["database", "storage"]).default("database")
|
|
4101
|
-
})
|
|
4102
|
-
).default([]),
|
|
4103
|
-
installs: import_zod7.z.record(
|
|
4104
|
-
import_zod7.z.string(),
|
|
4105
|
-
import_zod7.z.strictObject({
|
|
4106
|
-
installedVersion: import_zod7.z.string().min(1),
|
|
4107
|
-
datastoreBindings: import_zod7.z.record(import_zod7.z.string(), import_zod7.z.string()).nullish()
|
|
4108
|
-
})
|
|
4109
|
-
).default({})
|
|
4110
|
-
});
|
|
4111
|
-
var STUB_IGNORE_PATH = "apps/web/src/app/.gitignore";
|
|
4112
|
-
var STUB_IGNORE_HEADER = "# Generated by stardeck-compose \u2014 Module-rail stubs are build outputs; do not edit or commit them.";
|
|
4113
|
-
function escapeStubIgnorePattern(pattern) {
|
|
4114
|
-
const escaped = pattern.replace(/[\\[\]*?]/g, (char) => `\\${char}`);
|
|
4115
|
-
return /^[#!]/.test(escaped) ? `\\${escaped}` : escaped;
|
|
4116
|
-
}
|
|
4117
|
-
function buildStubIgnore(artifactPaths) {
|
|
4118
|
-
const prefix = "apps/web/src/app/";
|
|
4119
|
-
const entries = artifactPaths.filter((artifact) => artifact.startsWith(prefix)).map((artifact) => escapeStubIgnorePattern(`/${artifact.slice(prefix.length)}`)).sort();
|
|
4120
|
-
return [STUB_IGNORE_HEADER, ...entries].join("\n") + "\n";
|
|
4121
|
-
}
|
|
4122
|
-
|
|
4123
|
-
// ../../packages/lib/src/shared/module-enablement.ts
|
|
4124
|
-
function isModuleEnabledByList(raw, name, kindOf) {
|
|
4125
|
-
if (!raw) return true;
|
|
4126
|
-
const kind = kindOf(name);
|
|
4127
|
-
if (kind != null && kind !== "feature") return true;
|
|
4128
|
-
return raw.split(",").includes(name);
|
|
4129
|
-
}
|
|
4130
|
-
|
|
4131
4012
|
// ../../packages/lib/src/shared/platform-owned-paths.ts
|
|
4132
4013
|
var APP_WEB_PREFIX = "apps/web/";
|
|
4133
4014
|
var MODULE_STUB_MARKER = "@stardeck-module-rail-generated";
|
|
@@ -6054,6 +5935,50 @@ function rejectPseudoModuleEntries(entries, parentDir, label) {
|
|
|
6054
5935
|
return dirs;
|
|
6055
5936
|
}
|
|
6056
5937
|
|
|
5938
|
+
// ../../packages/lib/src/shared/module-composition.ts
|
|
5939
|
+
var import_zod7 = require("zod");
|
|
5940
|
+
var creationSourceBlankSchema = import_zod7.z.object({
|
|
5941
|
+
type: import_zod7.z.literal("blank")
|
|
5942
|
+
});
|
|
5943
|
+
var creationSourceBlueprintSchema = import_zod7.z.object({
|
|
5944
|
+
type: import_zod7.z.literal("blueprint"),
|
|
5945
|
+
/** Internal template/fork project id — keep template naming in identifiers. */
|
|
5946
|
+
blueprintProjectId: import_zod7.z.string().uuid(),
|
|
5947
|
+
/**
|
|
5948
|
+
* `null`/absent means every feature Module. `[]` is refused: the platform
|
|
5949
|
+
* serialises it to an empty `NEXT_PUBLIC_STARDECK_ENABLED_MODULES`, which the
|
|
5950
|
+
* enablement parser reads back as "all" (`module-enablement.ts`) — the
|
|
5951
|
+
* opposite of what an empty selection means.
|
|
5952
|
+
*/
|
|
5953
|
+
enabledModules: import_zod7.z.array(moduleNameSchema).min(1, "Enable at least one Module").max(100).nullable().optional()
|
|
5954
|
+
});
|
|
5955
|
+
var creationSourceSchema = import_zod7.z.discriminatedUnion("type", [
|
|
5956
|
+
creationSourceBlankSchema,
|
|
5957
|
+
creationSourceBlueprintSchema
|
|
5958
|
+
]);
|
|
5959
|
+
var moduleInstallHandoffSchema = import_zod7.z.object({
|
|
5960
|
+
moduleName: import_zod7.z.string().min(1),
|
|
5961
|
+
homeProjectId: import_zod7.z.string().uuid(),
|
|
5962
|
+
installedVersion: import_zod7.z.string().min(1),
|
|
5963
|
+
baselineSha: import_zod7.z.string().min(1),
|
|
5964
|
+
mounts: import_zod7.z.array(
|
|
5965
|
+
import_zod7.z.object({
|
|
5966
|
+
group: import_zod7.z.string(),
|
|
5967
|
+
segment: import_zod7.z.string()
|
|
5968
|
+
})
|
|
5969
|
+
),
|
|
5970
|
+
integration: import_zod7.z.array(import_zod7.z.string()),
|
|
5971
|
+
workflows: import_zod7.z.array(import_zod7.z.string()),
|
|
5972
|
+
prunedEnhancements: import_zod7.z.array(import_zod7.z.string()),
|
|
5973
|
+
restoredEnhancements: import_zod7.z.array(import_zod7.z.string()).optional(),
|
|
5974
|
+
permissions: import_zod7.z.array(
|
|
5975
|
+
import_zod7.z.object({
|
|
5976
|
+
key: import_zod7.z.string().min(1),
|
|
5977
|
+
description: import_zod7.z.string().min(1)
|
|
5978
|
+
})
|
|
5979
|
+
).optional()
|
|
5980
|
+
});
|
|
5981
|
+
|
|
6057
5982
|
// ../../packages/lib/src/shared/schema-ops.ts
|
|
6058
5983
|
var import_zod8 = require("zod");
|
|
6059
5984
|
var columnSpecSchema = import_zod8.z.object({
|
|
@@ -7517,6 +7442,9 @@ async function reconcileCompositionArtifacts(context, options = {}) {
|
|
|
7517
7442
|
var HOME_I18N_SUBSTRATE_DIR = `${APP_PACKAGE_DIR}/src/lib/i18n/substrate`;
|
|
7518
7443
|
var HOME_I18N_MESSAGES_DIR = `${APP_PACKAGE_DIR}/src/lib/i18n/messages`;
|
|
7519
7444
|
|
|
7445
|
+
// src/index.ts
|
|
7446
|
+
var import_typescript6 = __toESM(require("typescript"));
|
|
7447
|
+
|
|
7520
7448
|
// src/module-boundaries.ts
|
|
7521
7449
|
var import_node_fs2 = __toESM(require("fs"));
|
|
7522
7450
|
var import_node_path2 = __toESM(require("path"));
|
|
@@ -7786,6 +7714,41 @@ function assertNoAppLayerImporters(cwd, excluded) {
|
|
|
7786
7714
|
);
|
|
7787
7715
|
}
|
|
7788
7716
|
}
|
|
7717
|
+
var TSCONFIG_PATH = "apps/web/tsconfig.json";
|
|
7718
|
+
var BUILD_TSCONFIG_PATH = "apps/web/tsconfig.build.gen.json";
|
|
7719
|
+
var BUILD_TSCONFIG_HEADER = "// Generated by stardeck-compose \u2014 the tsconfig `next build` type-checks. Do not edit or commit.";
|
|
7720
|
+
function writeBuildTsconfig(cwd, excluded) {
|
|
7721
|
+
const baseFile = import_node_path3.default.join(cwd, TSCONFIG_PATH);
|
|
7722
|
+
if (!import_node_fs3.default.existsSync(import_node_path3.default.join(cwd, MODULES_DIR2)) || !import_node_fs3.default.existsSync(baseFile)) return;
|
|
7723
|
+
const base = import_typescript6.default.readConfigFile(baseFile, import_typescript6.default.sys.readFile);
|
|
7724
|
+
if (base.error) {
|
|
7725
|
+
throw new Error(
|
|
7726
|
+
`[compose] cannot read ${TSCONFIG_PATH}: ${import_typescript6.default.flattenDiagnosticMessageText(base.error.messageText, "\n")}`
|
|
7727
|
+
);
|
|
7728
|
+
}
|
|
7729
|
+
const baseExclude = base.config?.exclude ?? ["node_modules"];
|
|
7730
|
+
const modulesDir = import_node_path3.default.posix.relative("apps/web", MODULES_DIR2);
|
|
7731
|
+
const config = {
|
|
7732
|
+
extends: "./tsconfig.json",
|
|
7733
|
+
exclude: [
|
|
7734
|
+
...baseExclude,
|
|
7735
|
+
...excluded.flatMap((name) => [
|
|
7736
|
+
`${modulesDir}/${name}`,
|
|
7737
|
+
`${modulesDir}/*/enhancements/${name}`
|
|
7738
|
+
])
|
|
7739
|
+
]
|
|
7740
|
+
};
|
|
7741
|
+
const content = `${BUILD_TSCONFIG_HEADER}
|
|
7742
|
+
${JSON.stringify(config, null, 2)}
|
|
7743
|
+
`;
|
|
7744
|
+
const file = import_node_path3.default.join(cwd, BUILD_TSCONFIG_PATH);
|
|
7745
|
+
if (!import_node_fs3.default.existsSync(file) || import_node_fs3.default.readFileSync(file, "utf8") !== content) {
|
|
7746
|
+
import_node_fs3.default.writeFileSync(file, content);
|
|
7747
|
+
}
|
|
7748
|
+
console.log(
|
|
7749
|
+
`[compose] ${BUILD_TSCONFIG_PATH} excludes ${excluded.length} Module(s): ${excluded.join(",") || "none"}`
|
|
7750
|
+
);
|
|
7751
|
+
}
|
|
7789
7752
|
function removeDir(absolute) {
|
|
7790
7753
|
if (!import_node_fs3.default.existsSync(absolute)) return false;
|
|
7791
7754
|
import_node_fs3.default.rmSync(absolute, { recursive: true, force: true });
|
|
@@ -7833,6 +7796,7 @@ async function compose(options) {
|
|
|
7833
7796
|
skipComposeInputs: true
|
|
7834
7797
|
});
|
|
7835
7798
|
const gitignoreEntries = options.enabled ? null : writeStubGitignore(options.cwd, result.artifactPaths);
|
|
7799
|
+
writeBuildTsconfig(options.cwd, result.excludedModules);
|
|
7836
7800
|
let pruned = 0;
|
|
7837
7801
|
if (options.prune) {
|
|
7838
7802
|
for (const name of result.excludedModules) {
|
|
@@ -7855,6 +7819,7 @@ async function compose(options) {
|
|
|
7855
7819
|
}
|
|
7856
7820
|
// Annotate the CommonJS export names for ESM import in node:
|
|
7857
7821
|
0 && (module.exports = {
|
|
7822
|
+
BUILD_TSCONFIG_PATH,
|
|
7858
7823
|
COMPOSE_INPUTS_PATH,
|
|
7859
7824
|
assertSupportedTypescript,
|
|
7860
7825
|
compose,
|