@stardeck-customer-apps/compose 0.9.0 → 0.11.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 +9 -1
- package/dist/cli.js +109 -135
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +270 -296
- package/dist/index.mjs +269 -296
- package/package.json +3 -5
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,44 @@ 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(),
|
|
2480
|
+
/**
|
|
2481
|
+
* `false` keeps a feature Module off in a new Blueprint fork unless the
|
|
2482
|
+
* creator ticks it: the fork picker leaves it unchecked and "every Module"
|
|
2483
|
+
* is written out without it. Omitted means on. Library Modules are always on.
|
|
2484
|
+
*/
|
|
2485
|
+
defaultEnabled: import_zod2.z.boolean().optional()
|
|
2436
2486
|
}).strict().superRefine((manifest, ctx) => {
|
|
2437
2487
|
if (manifest.uses.includes(manifest.name)) {
|
|
2438
2488
|
ctx.addIssue({
|
|
2439
|
-
code:
|
|
2489
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2440
2490
|
message: "a module cannot list itself in uses",
|
|
2441
2491
|
path: ["uses"]
|
|
2442
2492
|
});
|
|
2443
2493
|
}
|
|
2444
2494
|
if (manifest.enhancements.includes(manifest.name)) {
|
|
2445
2495
|
ctx.addIssue({
|
|
2446
|
-
code:
|
|
2496
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2447
2497
|
message: "a module cannot list itself in enhancements",
|
|
2448
2498
|
path: ["enhancements"]
|
|
2449
2499
|
});
|
|
@@ -2451,7 +2501,7 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2451
2501
|
const hardAndSoft = manifest.enhancements.filter((peer) => manifest.uses.includes(peer));
|
|
2452
2502
|
if (hardAndSoft.length > 0) {
|
|
2453
2503
|
ctx.addIssue({
|
|
2454
|
-
code:
|
|
2504
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2455
2505
|
message: `uses and enhancements must be disjoint (a peer is either a hard dep or a soft one): ${hardAndSoft.join(", ")}`,
|
|
2456
2506
|
path: ["enhancements"]
|
|
2457
2507
|
});
|
|
@@ -2460,7 +2510,7 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2460
2510
|
for (const peer of Object.keys(manifest.enhancementWorkflows)) {
|
|
2461
2511
|
if (!enhancementPeers.has(peer)) {
|
|
2462
2512
|
ctx.addIssue({
|
|
2463
|
-
code:
|
|
2513
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2464
2514
|
message: `enhancementWorkflows key "${peer}" must be listed in enhancements`,
|
|
2465
2515
|
path: ["enhancementWorkflows", peer]
|
|
2466
2516
|
});
|
|
@@ -2469,7 +2519,7 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2469
2519
|
for (const peer of Object.keys(manifest.enhancementEndpoints)) {
|
|
2470
2520
|
if (!enhancementPeers.has(peer)) {
|
|
2471
2521
|
ctx.addIssue({
|
|
2472
|
-
code:
|
|
2522
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2473
2523
|
message: `enhancementEndpoints key "${peer}" must be listed in enhancements`,
|
|
2474
2524
|
path: ["enhancementEndpoints", peer]
|
|
2475
2525
|
});
|
|
@@ -2480,7 +2530,7 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2480
2530
|
const existing = seenWorkflows.get(name);
|
|
2481
2531
|
if (existing != null) {
|
|
2482
2532
|
ctx.addIssue({
|
|
2483
|
-
code:
|
|
2533
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2484
2534
|
message: `duplicate workflow name "${name}" (also at ${existing})`,
|
|
2485
2535
|
path: path4
|
|
2486
2536
|
});
|
|
@@ -2507,7 +2557,7 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2507
2557
|
const existing = seenEndpointKeys.get(key);
|
|
2508
2558
|
if (existing != null) {
|
|
2509
2559
|
ctx.addIssue({
|
|
2510
|
-
code:
|
|
2560
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2511
2561
|
message: `duplicate normalized endpoint path "${key}" (also at ${existing})`,
|
|
2512
2562
|
path: path4
|
|
2513
2563
|
});
|
|
@@ -2529,7 +2579,7 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2529
2579
|
const id = manifest.datastores[i].id;
|
|
2530
2580
|
if (seenDatastoreIds.has(id)) {
|
|
2531
2581
|
ctx.addIssue({
|
|
2532
|
-
code:
|
|
2582
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2533
2583
|
message: `duplicate datastore id "${id}"`,
|
|
2534
2584
|
path: ["datastores", i, "id"]
|
|
2535
2585
|
});
|
|
@@ -2544,7 +2594,7 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2544
2594
|
const key = manifest.permissions[i].key;
|
|
2545
2595
|
if (seenPermissionKeys.has(key)) {
|
|
2546
2596
|
ctx.addIssue({
|
|
2547
|
-
code:
|
|
2597
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2548
2598
|
message: `duplicate permission key "${key}"`,
|
|
2549
2599
|
path: ["permissions", i, "key"]
|
|
2550
2600
|
});
|
|
@@ -2556,35 +2606,35 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2556
2606
|
if (manifest.kind === "library") {
|
|
2557
2607
|
if (manifest.tables.length > 0) {
|
|
2558
2608
|
ctx.addIssue({
|
|
2559
|
-
code:
|
|
2609
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2560
2610
|
message: "library modules must not declare tables",
|
|
2561
2611
|
path: ["tables"]
|
|
2562
2612
|
});
|
|
2563
2613
|
}
|
|
2564
2614
|
if (manifest.mounts.length > 0) {
|
|
2565
2615
|
ctx.addIssue({
|
|
2566
|
-
code:
|
|
2616
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2567
2617
|
message: "library modules must not declare mounts",
|
|
2568
2618
|
path: ["mounts"]
|
|
2569
2619
|
});
|
|
2570
2620
|
}
|
|
2571
2621
|
if (manifest.seeds != null && manifest.seeds.length > 0) {
|
|
2572
2622
|
ctx.addIssue({
|
|
2573
|
-
code:
|
|
2623
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2574
2624
|
message: "library modules must not declare seeds",
|
|
2575
2625
|
path: ["seeds"]
|
|
2576
2626
|
});
|
|
2577
2627
|
}
|
|
2578
2628
|
if (manifest.datastores != null && manifest.datastores.length > 0) {
|
|
2579
2629
|
ctx.addIssue({
|
|
2580
|
-
code:
|
|
2630
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2581
2631
|
message: "library modules must not declare datastores",
|
|
2582
2632
|
path: ["datastores"]
|
|
2583
2633
|
});
|
|
2584
2634
|
}
|
|
2585
2635
|
if (manifest.permissions != null && manifest.permissions.length > 0) {
|
|
2586
2636
|
ctx.addIssue({
|
|
2587
|
-
code:
|
|
2637
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2588
2638
|
message: "library modules must not declare permissions",
|
|
2589
2639
|
path: ["permissions"]
|
|
2590
2640
|
});
|
|
@@ -2592,7 +2642,7 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2592
2642
|
}
|
|
2593
2643
|
if (manifest.kind === "contract" && manifest.mounts.length > 0) {
|
|
2594
2644
|
ctx.addIssue({
|
|
2595
|
-
code:
|
|
2645
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2596
2646
|
message: "contract modules must not declare mounts",
|
|
2597
2647
|
path: ["mounts"]
|
|
2598
2648
|
});
|
|
@@ -2603,7 +2653,7 @@ var moduleManifestSchema = import_zod.z.object({
|
|
|
2603
2653
|
const bundle = manifest.seeds[i];
|
|
2604
2654
|
if (!ownedTables.has(bundle.table)) {
|
|
2605
2655
|
ctx.addIssue({
|
|
2606
|
-
code:
|
|
2656
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
2607
2657
|
message: `seeds may only target tables listed in tables (got "${bundle.table}")`,
|
|
2608
2658
|
path: ["seeds", i, "table"]
|
|
2609
2659
|
});
|
|
@@ -2654,10 +2704,10 @@ var MANDATORY_MODULE_CHECK_DESCRIPTORS = Object.freeze([
|
|
|
2654
2704
|
]);
|
|
2655
2705
|
|
|
2656
2706
|
// ../../packages/module-contract/src/module-structure.ts
|
|
2657
|
-
var
|
|
2707
|
+
var import_zod4 = require("zod");
|
|
2658
2708
|
|
|
2659
2709
|
// ../../packages/module-contract/src/module-e2e-manifest.ts
|
|
2660
|
-
var
|
|
2710
|
+
var import_zod3 = require("zod");
|
|
2661
2711
|
function e2eSpecFileValidationError(file) {
|
|
2662
2712
|
if (file.length === 0) {
|
|
2663
2713
|
return "must be a non-empty relative path ending in .spec.ts";
|
|
@@ -2685,22 +2735,22 @@ function e2eSpecFileValidationError(file) {
|
|
|
2685
2735
|
}
|
|
2686
2736
|
return null;
|
|
2687
2737
|
}
|
|
2688
|
-
var e2eSpecFileSchema =
|
|
2738
|
+
var e2eSpecFileSchema = import_zod3.z.string().superRefine((file, ctx) => {
|
|
2689
2739
|
const error = e2eSpecFileValidationError(file);
|
|
2690
2740
|
if (error != null) {
|
|
2691
|
-
ctx.addIssue({ code:
|
|
2741
|
+
ctx.addIssue({ code: import_zod3.z.ZodIssueCode.custom, message: error });
|
|
2692
2742
|
}
|
|
2693
2743
|
});
|
|
2694
|
-
var e2eSpecSchema =
|
|
2744
|
+
var e2eSpecSchema = import_zod3.z.object({
|
|
2695
2745
|
file: e2eSpecFileSchema,
|
|
2696
|
-
requires:
|
|
2746
|
+
requires: import_zod3.z.array(moduleNameSchema).min(1, "requires must be non-empty")
|
|
2697
2747
|
}).strict().superRefine((spec, ctx) => {
|
|
2698
2748
|
const seen = /* @__PURE__ */ new Set();
|
|
2699
2749
|
for (let i = 0; i < spec.requires.length; i += 1) {
|
|
2700
2750
|
const name = spec.requires[i];
|
|
2701
2751
|
if (seen.has(name)) {
|
|
2702
2752
|
ctx.addIssue({
|
|
2703
|
-
code:
|
|
2753
|
+
code: import_zod3.z.ZodIssueCode.custom,
|
|
2704
2754
|
message: `duplicate requirement "${name}"`,
|
|
2705
2755
|
path: ["requires", i]
|
|
2706
2756
|
});
|
|
@@ -2709,15 +2759,15 @@ var e2eSpecSchema = import_zod2.z.object({
|
|
|
2709
2759
|
}
|
|
2710
2760
|
}
|
|
2711
2761
|
});
|
|
2712
|
-
var moduleE2eManifestSchema =
|
|
2713
|
-
specs:
|
|
2762
|
+
var moduleE2eManifestSchema = import_zod3.z.object({
|
|
2763
|
+
specs: import_zod3.z.array(e2eSpecSchema).min(1, "specs must contain at least one entry")
|
|
2714
2764
|
}).strict().superRefine((manifest, ctx) => {
|
|
2715
2765
|
const seenFiles = /* @__PURE__ */ new Set();
|
|
2716
2766
|
for (let i = 0; i < manifest.specs.length; i += 1) {
|
|
2717
2767
|
const file = manifest.specs[i].file;
|
|
2718
2768
|
if (seenFiles.has(file)) {
|
|
2719
2769
|
ctx.addIssue({
|
|
2720
|
-
code:
|
|
2770
|
+
code: import_zod3.z.ZodIssueCode.custom,
|
|
2721
2771
|
message: `duplicate file "${file}"`,
|
|
2722
2772
|
path: ["specs", i, "file"]
|
|
2723
2773
|
});
|
|
@@ -2959,7 +3009,7 @@ function compareCodeUnit(a, b) {
|
|
|
2959
3009
|
// ../../packages/module-contract/src/module-structure.ts
|
|
2960
3010
|
var MODULE_STRUCTURE_JSON_BYTE_CAP = 64 * 1024;
|
|
2961
3011
|
function uniqueSortedStringArray(label) {
|
|
2962
|
-
return
|
|
3012
|
+
return import_zod4.z.array(import_zod4.z.string()).superRefine((arr, ctx) => {
|
|
2963
3013
|
if (new Set(arr).size !== arr.length) {
|
|
2964
3014
|
ctx.addIssue({ code: "custom", message: `${label} must be unique` });
|
|
2965
3015
|
return;
|
|
@@ -2975,10 +3025,10 @@ function uniqueSortedStringArray(label) {
|
|
|
2975
3025
|
});
|
|
2976
3026
|
}
|
|
2977
3027
|
function contributionPermissionsSchema(label) {
|
|
2978
|
-
return
|
|
2979
|
-
|
|
2980
|
-
contributionId:
|
|
2981
|
-
permission:
|
|
3028
|
+
return import_zod4.z.array(
|
|
3029
|
+
import_zod4.z.object({
|
|
3030
|
+
contributionId: import_zod4.z.string().min(1),
|
|
3031
|
+
permission: import_zod4.z.string().min(1)
|
|
2982
3032
|
}).strict()
|
|
2983
3033
|
).superRefine((entries, ctx) => {
|
|
2984
3034
|
const keys = entries.map((entry) => `${entry.contributionId}\0${entry.permission}`);
|
|
@@ -2996,17 +3046,17 @@ function contributionPermissionsSchema(label) {
|
|
|
2996
3046
|
}
|
|
2997
3047
|
}).optional();
|
|
2998
3048
|
}
|
|
2999
|
-
var collectedFilePayloadSchema =
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3049
|
+
var collectedFilePayloadSchema = import_zod4.z.discriminatedUnion("status", [
|
|
3050
|
+
import_zod4.z.object({ status: import_zod4.z.literal("ok"), text: import_zod4.z.string() }).strict(),
|
|
3051
|
+
import_zod4.z.object({ status: import_zod4.z.literal("missing") }).strict(),
|
|
3052
|
+
import_zod4.z.object({ status: import_zod4.z.literal("too-large") }).strict(),
|
|
3053
|
+
import_zod4.z.object({ status: import_zod4.z.literal("unreadable") }).strict()
|
|
3004
3054
|
]);
|
|
3005
|
-
var collectedLocaleFileSchema =
|
|
3006
|
-
locale:
|
|
3055
|
+
var collectedLocaleFileSchema = import_zod4.z.object({
|
|
3056
|
+
locale: import_zod4.z.string().min(1),
|
|
3007
3057
|
payload: collectedFilePayloadSchema
|
|
3008
3058
|
}).strict();
|
|
3009
|
-
var collectedE2eFactsSchema =
|
|
3059
|
+
var collectedE2eFactsSchema = import_zod4.z.object({
|
|
3010
3060
|
manifest: collectedFilePayloadSchema,
|
|
3011
3061
|
specFiles: uniqueSortedStringArray("specFiles"),
|
|
3012
3062
|
escapingSymlinks: uniqueSortedStringArray("escapingSymlinks")
|
|
@@ -3028,20 +3078,20 @@ function validateRouteExportEvidenceCongruence(input) {
|
|
|
3028
3078
|
}
|
|
3029
3079
|
}
|
|
3030
3080
|
}
|
|
3031
|
-
var collectedEnhancementFactsSchema =
|
|
3032
|
-
peer:
|
|
3033
|
-
hasContributionsTs:
|
|
3081
|
+
var collectedEnhancementFactsSchema = import_zod4.z.object({
|
|
3082
|
+
peer: import_zod4.z.string().min(1),
|
|
3083
|
+
hasContributionsTs: import_zod4.z.boolean(),
|
|
3034
3084
|
contributionPermissions: contributionPermissionsSchema("enhancement contributionPermissions"),
|
|
3035
|
-
hasInitializeServerTs:
|
|
3085
|
+
hasInitializeServerTs: import_zod4.z.boolean(),
|
|
3036
3086
|
contributionsCollectionErrors: uniqueSortedStringArray(
|
|
3037
3087
|
"enhancement contributionsCollectionErrors"
|
|
3038
3088
|
),
|
|
3039
3089
|
initializeServerCollectionErrors: uniqueSortedStringArray(
|
|
3040
3090
|
"enhancement initializeServerCollectionErrors"
|
|
3041
3091
|
),
|
|
3042
|
-
hasRoutesDir:
|
|
3092
|
+
hasRoutesDir: import_zod4.z.boolean(),
|
|
3043
3093
|
routeCollectionErrors: uniqueSortedStringArray("enhancement routeCollectionErrors"),
|
|
3044
|
-
locales:
|
|
3094
|
+
locales: import_zod4.z.array(collectedLocaleFileSchema).superRefine((locales, ctx) => {
|
|
3045
3095
|
const names = locales.map((l) => l.locale);
|
|
3046
3096
|
if (new Set(names).size !== names.length) {
|
|
3047
3097
|
ctx.addIssue({ code: "custom", message: "enhancement locales must be unique by locale" });
|
|
@@ -3056,27 +3106,27 @@ var collectedEnhancementFactsSchema = import_zod3.z.object({
|
|
|
3056
3106
|
}),
|
|
3057
3107
|
e2e: collectedE2eFactsSchema.nullable()
|
|
3058
3108
|
}).strict();
|
|
3059
|
-
var moduleStructureFactsSchema =
|
|
3060
|
-
collected:
|
|
3061
|
-
dirName:
|
|
3062
|
-
hasIndexTs:
|
|
3063
|
-
hasContributionsTs:
|
|
3109
|
+
var moduleStructureFactsSchema = import_zod4.z.object({
|
|
3110
|
+
collected: import_zod4.z.literal(true),
|
|
3111
|
+
dirName: import_zod4.z.string().min(1),
|
|
3112
|
+
hasIndexTs: import_zod4.z.boolean(),
|
|
3113
|
+
hasContributionsTs: import_zod4.z.boolean(),
|
|
3064
3114
|
contributionPermissions: contributionPermissionsSchema("contributionPermissions"),
|
|
3065
|
-
hasSlotsTs:
|
|
3115
|
+
hasSlotsTs: import_zod4.z.boolean(),
|
|
3066
3116
|
contributionsCollectionErrors: uniqueSortedStringArray("contributionsCollectionErrors"),
|
|
3067
3117
|
slotsCollectionErrors: uniqueSortedStringArray("slotsCollectionErrors"),
|
|
3068
|
-
hasTestsDir:
|
|
3069
|
-
hasDatastoreDir:
|
|
3070
|
-
datastoreFileCount:
|
|
3071
|
-
hasServerIndexTs:
|
|
3072
|
-
hasOtherServerTs:
|
|
3073
|
-
hasE2eDir:
|
|
3074
|
-
hasRoutesDir:
|
|
3118
|
+
hasTestsDir: import_zod4.z.boolean(),
|
|
3119
|
+
hasDatastoreDir: import_zod4.z.boolean(),
|
|
3120
|
+
datastoreFileCount: import_zod4.z.number().int().nonnegative(),
|
|
3121
|
+
hasServerIndexTs: import_zod4.z.boolean(),
|
|
3122
|
+
hasOtherServerTs: import_zod4.z.boolean(),
|
|
3123
|
+
hasE2eDir: import_zod4.z.boolean(),
|
|
3124
|
+
hasRoutesDir: import_zod4.z.boolean(),
|
|
3075
3125
|
routeEntries: uniqueSortedStringArray("routeEntries"),
|
|
3076
|
-
routePageExports:
|
|
3077
|
-
|
|
3078
|
-
nextRelativePath:
|
|
3079
|
-
hasGenerateMetadata:
|
|
3126
|
+
routePageExports: import_zod4.z.array(
|
|
3127
|
+
import_zod4.z.object({
|
|
3128
|
+
nextRelativePath: import_zod4.z.string().min(1),
|
|
3129
|
+
hasGenerateMetadata: import_zod4.z.boolean()
|
|
3080
3130
|
}).strict()
|
|
3081
3131
|
).superRefine((entries, ctx) => {
|
|
3082
3132
|
const paths = entries.map((e) => e.nextRelativePath);
|
|
@@ -3098,7 +3148,7 @@ var moduleStructureFactsSchema = import_zod3.z.object({
|
|
|
3098
3148
|
}
|
|
3099
3149
|
}),
|
|
3100
3150
|
routeCollectionErrors: uniqueSortedStringArray("routeCollectionErrors"),
|
|
3101
|
-
rootLocales:
|
|
3151
|
+
rootLocales: import_zod4.z.array(collectedLocaleFileSchema).superRefine((locales, ctx) => {
|
|
3102
3152
|
const names = locales.map((l) => l.locale);
|
|
3103
3153
|
if (new Set(names).size !== names.length) {
|
|
3104
3154
|
ctx.addIssue({ code: "custom", message: "rootLocales must be unique by locale" });
|
|
@@ -3112,7 +3162,7 @@ var moduleStructureFactsSchema = import_zod3.z.object({
|
|
|
3112
3162
|
}
|
|
3113
3163
|
}),
|
|
3114
3164
|
rootE2e: collectedE2eFactsSchema.nullable(),
|
|
3115
|
-
enhancements:
|
|
3165
|
+
enhancements: import_zod4.z.array(collectedEnhancementFactsSchema).superRefine((enhancements, ctx) => {
|
|
3116
3166
|
const peers = enhancements.map((e) => e.peer);
|
|
3117
3167
|
if (new Set(peers).size !== peers.length) {
|
|
3118
3168
|
ctx.addIssue({ code: "custom", message: "enhancement peers must be unique" });
|
|
@@ -3133,10 +3183,10 @@ var moduleStructureFactsSchema = import_zod3.z.object({
|
|
|
3133
3183
|
onIssue: (message) => ctx.addIssue({ code: "custom", message })
|
|
3134
3184
|
});
|
|
3135
3185
|
});
|
|
3136
|
-
var moduleStructureCollectionSchema =
|
|
3186
|
+
var moduleStructureCollectionSchema = import_zod4.z.object({
|
|
3137
3187
|
homeLocales: uniqueSortedStringArray("homeLocales"),
|
|
3138
|
-
modules:
|
|
3139
|
-
truncated:
|
|
3188
|
+
modules: import_zod4.z.array(moduleStructureFactsSchema),
|
|
3189
|
+
truncated: import_zod4.z.boolean().optional(),
|
|
3140
3190
|
collectionErrors: uniqueSortedStringArray("collectionErrors").optional()
|
|
3141
3191
|
}).strict().superRefine((collection, ctx) => {
|
|
3142
3192
|
const dirs = collection.modules.map((m) => m.dirName);
|
|
@@ -3153,9 +3203,9 @@ var moduleStructureCollectionSchema = import_zod3.z.object({
|
|
|
3153
3203
|
});
|
|
3154
3204
|
|
|
3155
3205
|
// ../../packages/module-contract/src/locale.ts
|
|
3156
|
-
var
|
|
3206
|
+
var import_zod5 = require("zod");
|
|
3157
3207
|
var LOCALE_BASENAME_REGEX = /^[a-z]{2,3}(-[A-Za-z0-9]+)*$/;
|
|
3158
|
-
var localeBasenameSchema =
|
|
3208
|
+
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
3209
|
function isValidLocaleBasename(value) {
|
|
3160
3210
|
return localeBasenameSchema.safeParse(value).success;
|
|
3161
3211
|
}
|
|
@@ -3558,43 +3608,43 @@ function formatRoutePageExportErrors(nextRelativePath, validation) {
|
|
|
3558
3608
|
var import_typescript2 = __toESM(require("typescript"), 1);
|
|
3559
3609
|
|
|
3560
3610
|
// ../../packages/module-contract/src/module-registry.ts
|
|
3561
|
-
var
|
|
3562
|
-
var projectSlugSchema2 =
|
|
3563
|
-
var registryEnhancementSchema =
|
|
3611
|
+
var import_zod6 = require("zod");
|
|
3612
|
+
var projectSlugSchema2 = import_zod6.z.string().refine((value) => validateSlug(value).valid, "must be a valid project slug");
|
|
3613
|
+
var registryEnhancementSchema = import_zod6.z.object({
|
|
3564
3614
|
peer: moduleNameSchema,
|
|
3565
|
-
active:
|
|
3615
|
+
active: import_zod6.z.boolean()
|
|
3566
3616
|
}).strict();
|
|
3567
|
-
var registryModuleSchema =
|
|
3617
|
+
var registryModuleSchema = import_zod6.z.object({
|
|
3568
3618
|
name: moduleNameSchema,
|
|
3569
3619
|
/** Installed version as recorded by the rail (non-empty string). */
|
|
3570
|
-
version:
|
|
3620
|
+
version: import_zod6.z.string().min(1),
|
|
3571
3621
|
home: projectSlugSchema2,
|
|
3572
3622
|
kind: moduleKindSchema,
|
|
3573
|
-
mounts:
|
|
3574
|
-
enhancements:
|
|
3623
|
+
mounts: import_zod6.z.array(mountSchema),
|
|
3624
|
+
enhancements: import_zod6.z.array(registryEnhancementSchema)
|
|
3575
3625
|
}).strict().superRefine((mod, ctx) => {
|
|
3576
3626
|
for (let i = 0; i < mod.enhancements.length; i += 1) {
|
|
3577
3627
|
if (mod.enhancements[i].peer === mod.name) {
|
|
3578
3628
|
ctx.addIssue({
|
|
3579
|
-
code:
|
|
3629
|
+
code: import_zod6.z.ZodIssueCode.custom,
|
|
3580
3630
|
message: "enhancement peer must not equal the module's own name",
|
|
3581
3631
|
path: ["enhancements", i, "peer"]
|
|
3582
3632
|
});
|
|
3583
3633
|
}
|
|
3584
3634
|
}
|
|
3585
3635
|
});
|
|
3586
|
-
var generatedModuleRegistrySchema =
|
|
3587
|
-
registryVersion:
|
|
3636
|
+
var generatedModuleRegistrySchema = import_zod6.z.object({
|
|
3637
|
+
registryVersion: import_zod6.z.literal(1),
|
|
3588
3638
|
/** Rail run id, or `"manual"` for fixtures. */
|
|
3589
|
-
generatedBy:
|
|
3590
|
-
modules:
|
|
3639
|
+
generatedBy: import_zod6.z.string().min(1),
|
|
3640
|
+
modules: import_zod6.z.array(registryModuleSchema)
|
|
3591
3641
|
}).strict().superRefine((registry, ctx) => {
|
|
3592
3642
|
const seen = /* @__PURE__ */ new Set();
|
|
3593
3643
|
for (let i = 0; i < registry.modules.length; i += 1) {
|
|
3594
3644
|
const name = registry.modules[i].name;
|
|
3595
3645
|
if (seen.has(name)) {
|
|
3596
3646
|
ctx.addIssue({
|
|
3597
|
-
code:
|
|
3647
|
+
code: import_zod6.z.ZodIssueCode.custom,
|
|
3598
3648
|
message: `duplicate module name "${name}"`,
|
|
3599
3649
|
path: ["modules", i, "name"]
|
|
3600
3650
|
});
|
|
@@ -3965,171 +4015,9 @@ function analyzeClientSafeEntryImports(sourceText, fileName) {
|
|
|
3965
4015
|
return analyzeClientSafeEntryImportsWithTs(import_typescript3.default, sourceText, fileName);
|
|
3966
4016
|
}
|
|
3967
4017
|
|
|
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
4018
|
// ../../packages/lib/src/shared/platform-owned-paths.ts
|
|
4132
4019
|
var APP_WEB_PREFIX = "apps/web/";
|
|
4020
|
+
var BLUEPRINT_LINT_MARKER = `${APP_WEB_PREFIX}eslint-rules/module-boundaries.mjs`;
|
|
4133
4021
|
var MODULE_STUB_MARKER = "@stardeck-module-rail-generated";
|
|
4134
4022
|
var ENABLED_MODULES_ENV = "NEXT_PUBLIC_STARDECK_ENABLED_MODULES";
|
|
4135
4023
|
var HEADLESS_MOUNTS_ENV = "NEXT_PUBLIC_STARDECK_HEADLESS_MOUNTS";
|
|
@@ -6054,6 +5942,52 @@ function rejectPseudoModuleEntries(entries, parentDir, label) {
|
|
|
6054
5942
|
return dirs;
|
|
6055
5943
|
}
|
|
6056
5944
|
|
|
5945
|
+
// ../../packages/lib/src/shared/module-composition.ts
|
|
5946
|
+
var import_zod7 = require("zod");
|
|
5947
|
+
var creationSourceBlankSchema = import_zod7.z.object({
|
|
5948
|
+
type: import_zod7.z.literal("blank")
|
|
5949
|
+
});
|
|
5950
|
+
var creationSourceBlueprintSchema = import_zod7.z.object({
|
|
5951
|
+
type: import_zod7.z.literal("blueprint"),
|
|
5952
|
+
/** Internal template/fork project id — keep template naming in identifiers. */
|
|
5953
|
+
blueprintProjectId: import_zod7.z.string().uuid(),
|
|
5954
|
+
/**
|
|
5955
|
+
* `null`/absent means every feature Module: the platform stores that as the
|
|
5956
|
+
* explicit list of feature Modules in the published Blueprint version the fork
|
|
5957
|
+
* is cut from, so a Module a later Blueprint update adds arrives off. `[]` is
|
|
5958
|
+
* refused: the platform serialises it to an empty
|
|
5959
|
+
* `NEXT_PUBLIC_STARDECK_ENABLED_MODULES`, which the enablement parser reads
|
|
5960
|
+
* back as "all" (`module-enablement.ts`) — the opposite of an empty selection.
|
|
5961
|
+
*/
|
|
5962
|
+
enabledModules: import_zod7.z.array(moduleNameSchema).min(1, "Enable at least one Module").max(100).nullable().optional()
|
|
5963
|
+
});
|
|
5964
|
+
var creationSourceSchema = import_zod7.z.discriminatedUnion("type", [
|
|
5965
|
+
creationSourceBlankSchema,
|
|
5966
|
+
creationSourceBlueprintSchema
|
|
5967
|
+
]);
|
|
5968
|
+
var moduleInstallHandoffSchema = import_zod7.z.object({
|
|
5969
|
+
moduleName: import_zod7.z.string().min(1),
|
|
5970
|
+
homeProjectId: import_zod7.z.string().uuid(),
|
|
5971
|
+
installedVersion: import_zod7.z.string().min(1),
|
|
5972
|
+
baselineSha: import_zod7.z.string().min(1),
|
|
5973
|
+
mounts: import_zod7.z.array(
|
|
5974
|
+
import_zod7.z.object({
|
|
5975
|
+
group: import_zod7.z.string(),
|
|
5976
|
+
segment: import_zod7.z.string()
|
|
5977
|
+
})
|
|
5978
|
+
),
|
|
5979
|
+
integration: import_zod7.z.array(import_zod7.z.string()),
|
|
5980
|
+
workflows: import_zod7.z.array(import_zod7.z.string()),
|
|
5981
|
+
prunedEnhancements: import_zod7.z.array(import_zod7.z.string()),
|
|
5982
|
+
restoredEnhancements: import_zod7.z.array(import_zod7.z.string()).optional(),
|
|
5983
|
+
permissions: import_zod7.z.array(
|
|
5984
|
+
import_zod7.z.object({
|
|
5985
|
+
key: import_zod7.z.string().min(1),
|
|
5986
|
+
description: import_zod7.z.string().min(1)
|
|
5987
|
+
})
|
|
5988
|
+
).optional()
|
|
5989
|
+
});
|
|
5990
|
+
|
|
6057
5991
|
// ../../packages/lib/src/shared/schema-ops.ts
|
|
6058
5992
|
var import_zod8 = require("zod");
|
|
6059
5993
|
var columnSpecSchema = import_zod8.z.object({
|
|
@@ -7517,6 +7451,9 @@ async function reconcileCompositionArtifacts(context, options = {}) {
|
|
|
7517
7451
|
var HOME_I18N_SUBSTRATE_DIR = `${APP_PACKAGE_DIR}/src/lib/i18n/substrate`;
|
|
7518
7452
|
var HOME_I18N_MESSAGES_DIR = `${APP_PACKAGE_DIR}/src/lib/i18n/messages`;
|
|
7519
7453
|
|
|
7454
|
+
// src/index.ts
|
|
7455
|
+
var import_typescript6 = __toESM(require("typescript"));
|
|
7456
|
+
|
|
7520
7457
|
// src/module-boundaries.ts
|
|
7521
7458
|
var import_node_fs2 = __toESM(require("fs"));
|
|
7522
7459
|
var import_node_path2 = __toESM(require("path"));
|
|
@@ -7786,6 +7723,41 @@ function assertNoAppLayerImporters(cwd, excluded) {
|
|
|
7786
7723
|
);
|
|
7787
7724
|
}
|
|
7788
7725
|
}
|
|
7726
|
+
var TSCONFIG_PATH = "apps/web/tsconfig.json";
|
|
7727
|
+
var BUILD_TSCONFIG_PATH = "apps/web/tsconfig.build.gen.json";
|
|
7728
|
+
var BUILD_TSCONFIG_HEADER = "// Generated by stardeck-compose \u2014 the tsconfig `next build` type-checks. Do not edit or commit.";
|
|
7729
|
+
function writeBuildTsconfig(cwd, excluded) {
|
|
7730
|
+
const baseFile = import_node_path3.default.join(cwd, TSCONFIG_PATH);
|
|
7731
|
+
if (!import_node_fs3.default.existsSync(import_node_path3.default.join(cwd, MODULES_DIR2)) || !import_node_fs3.default.existsSync(baseFile)) return;
|
|
7732
|
+
const base = import_typescript6.default.readConfigFile(baseFile, import_typescript6.default.sys.readFile);
|
|
7733
|
+
if (base.error) {
|
|
7734
|
+
throw new Error(
|
|
7735
|
+
`[compose] cannot read ${TSCONFIG_PATH}: ${import_typescript6.default.flattenDiagnosticMessageText(base.error.messageText, "\n")}`
|
|
7736
|
+
);
|
|
7737
|
+
}
|
|
7738
|
+
const baseExclude = base.config?.exclude ?? ["node_modules"];
|
|
7739
|
+
const modulesDir = import_node_path3.default.posix.relative("apps/web", MODULES_DIR2);
|
|
7740
|
+
const config = {
|
|
7741
|
+
extends: "./tsconfig.json",
|
|
7742
|
+
exclude: [
|
|
7743
|
+
...baseExclude,
|
|
7744
|
+
...excluded.flatMap((name) => [
|
|
7745
|
+
`${modulesDir}/${name}`,
|
|
7746
|
+
`${modulesDir}/*/enhancements/${name}`
|
|
7747
|
+
])
|
|
7748
|
+
]
|
|
7749
|
+
};
|
|
7750
|
+
const content = `${BUILD_TSCONFIG_HEADER}
|
|
7751
|
+
${JSON.stringify(config, null, 2)}
|
|
7752
|
+
`;
|
|
7753
|
+
const file = import_node_path3.default.join(cwd, BUILD_TSCONFIG_PATH);
|
|
7754
|
+
if (!import_node_fs3.default.existsSync(file) || import_node_fs3.default.readFileSync(file, "utf8") !== content) {
|
|
7755
|
+
import_node_fs3.default.writeFileSync(file, content);
|
|
7756
|
+
}
|
|
7757
|
+
console.log(
|
|
7758
|
+
`[compose] ${BUILD_TSCONFIG_PATH} excludes ${excluded.length} Module(s): ${excluded.join(",") || "none"}`
|
|
7759
|
+
);
|
|
7760
|
+
}
|
|
7789
7761
|
function removeDir(absolute) {
|
|
7790
7762
|
if (!import_node_fs3.default.existsSync(absolute)) return false;
|
|
7791
7763
|
import_node_fs3.default.rmSync(absolute, { recursive: true, force: true });
|
|
@@ -7833,6 +7805,7 @@ async function compose(options) {
|
|
|
7833
7805
|
skipComposeInputs: true
|
|
7834
7806
|
});
|
|
7835
7807
|
const gitignoreEntries = options.enabled ? null : writeStubGitignore(options.cwd, result.artifactPaths);
|
|
7808
|
+
writeBuildTsconfig(options.cwd, result.excludedModules);
|
|
7836
7809
|
let pruned = 0;
|
|
7837
7810
|
if (options.prune) {
|
|
7838
7811
|
for (const name of result.excludedModules) {
|
|
@@ -7855,6 +7828,7 @@ async function compose(options) {
|
|
|
7855
7828
|
}
|
|
7856
7829
|
// Annotate the CommonJS export names for ESM import in node:
|
|
7857
7830
|
0 && (module.exports = {
|
|
7831
|
+
BUILD_TSCONFIG_PATH,
|
|
7858
7832
|
COMPOSE_INPUTS_PATH,
|
|
7859
7833
|
assertSupportedTypescript,
|
|
7860
7834
|
compose,
|