@dreamboard-games/workspace-codegen 0.1.1 → 0.1.3

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.
@@ -2235,7 +2235,7 @@ function renderCardPropertiesSchemaByCardSetId(cardSets) {
2235
2235
  ` ${quote(cardSet.id)}: ${toPascalCase(cardSet.id)}CardPropertiesSchema,`,
2236
2236
  ];
2237
2237
  });
2238
- return `const cardPropertiesSchemaByCardSetId: Record<string, z.ZodTypeAny> = {\n${entries.join("\n")}\n};`;
2238
+ return `const cardPropertiesSchemaByCardSetId: Record<string, z.ZodType<unknown>> = {\n${entries.join("\n")}\n};`;
2239
2239
  }
2240
2240
  function renderObjectSchemaSection(typeName, schemaName, schema) {
2241
2241
  return renderBlocks([
@@ -2373,7 +2373,7 @@ function renderCardStateSchemaById(analysis) {
2373
2373
  return `z.object(
2374
2374
  Object.fromEntries(
2375
2375
  literals.cardIds.map((cardId) => [cardId, createCardStateSchema(cardId)]),
2376
- ) as Record<CardId, z.ZodTypeAny>,
2376
+ ) as Record<CardId, z.ZodType<unknown>>,
2377
2377
  )`;
2378
2378
  }
2379
2379
  function renderCardStateSchemaFactory(analysis) {
@@ -2459,8 +2459,17 @@ function renderGenericBoardStateSchema(board, runtimeBoardId) {
2459
2459
  : "ids.playerId.nullable().optional()"},
2460
2460
  templateId: z.string().nullable().optional(),
2461
2461
  fields: ${`${boardFieldsTypeName(board.board.id)}Schema`},
2462
+ // T220: per-board state.spaces is loose-keyed by string. The
2463
+ // canonical narrow id (\`ids.spaceId\`) is a Zod enum of EVERY
2464
+ // space id across every board, which makes a strict
2465
+ // \`z.record(enum, …)\` reject any board whose spaces are a
2466
+ // proper subset of that enum. Loose keying matches the JSON wire
2467
+ // shape (\`additionalProperties\`); the inner \`id: ids.spaceId\`
2468
+ // narrows the value's spaceId at parse time. A future per-board
2469
+ // branded-id refactor (option B) can re-tighten this without a
2470
+ // wire change.
2462
2471
  spaces: z.record(
2463
- ids.spaceId,
2472
+ z.string(),
2464
2473
  z.object({
2465
2474
  id: ids.spaceId,
2466
2475
  name: z.string().nullable().optional(),
@@ -2512,8 +2521,9 @@ function renderHexBoardStateSchema(board, runtimeBoardId) {
2512
2521
  : "ids.playerId.nullable().optional()"},
2513
2522
  templateId: z.string().nullable().optional(),
2514
2523
  fields: ${`${boardFieldsTypeName(board.board.id)}Schema`},
2524
+ // T220: see generic-board comment on the loose-keying choice.
2515
2525
  spaces: z.record(
2516
- ids.spaceId,
2526
+ z.string(),
2517
2527
  z.object({
2518
2528
  id: ids.spaceId,
2519
2529
  name: z.string().nullable().optional(),
@@ -2575,8 +2585,9 @@ function renderSquareBoardStateSchema(board, runtimeBoardId) {
2575
2585
  : "ids.playerId.nullable().optional()"},
2576
2586
  templateId: z.string().nullable().optional(),
2577
2587
  fields: ${`${boardFieldsTypeName(board.board.id)}Schema`},
2588
+ // T220: see generic-board comment on the loose-keying choice.
2578
2589
  spaces: z.record(
2579
- ids.spaceId,
2590
+ z.string(),
2580
2591
  z.object({
2581
2592
  id: ids.spaceId,
2582
2593
  name: z.string().nullable().optional(),
@@ -4160,7 +4171,11 @@ const runtimeGenericBoardStateSchema = z.object({
4160
4171
  playerId: ids.playerId.nullable().optional(),
4161
4172
  templateId: z.string().nullable().optional(),
4162
4173
  fields: unknownRecordSchema,
4163
- spaces: z.record(ids.spaceId, boardSpaceStateSchema),
4174
+ // T220: per-board state.spaces is loose-keyed by string. See the
4175
+ // codegen-template comment in renderGenericBoardStateSchema for
4176
+ // the rationale; the wire shape is unchanged (additionalProperties
4177
+ // JSON), and the inner id field narrows at parse time.
4178
+ spaces: z.record(z.string(), boardSpaceStateSchema),
4164
4179
  relations: z.array(boardRelationStateSchema),
4165
4180
  containers: z.record(ids.boardContainerId, boardContainerStateSchema),
4166
4181
  });
@@ -4190,7 +4205,8 @@ const squareVertexStateSchema = z.object({
4190
4205
  });
4191
4206
  const runtimeHexBoardStateSchema = runtimeGenericBoardStateSchema.extend({
4192
4207
  layout: z.literal("hex"),
4193
- spaces: z.record(ids.spaceId, hexSpaceStateSchema),
4208
+ // T220: loose-keyed by string — see comment above.
4209
+ spaces: z.record(z.string(), hexSpaceStateSchema),
4194
4210
  relations: z.array(boardRelationStateSchema),
4195
4211
  containers: z.object({}),
4196
4212
  orientation: z.enum(["pointy-top", "flat-top"]),
@@ -4199,7 +4215,8 @@ const runtimeHexBoardStateSchema = runtimeGenericBoardStateSchema.extend({
4199
4215
  });
4200
4216
  const runtimeSquareBoardStateSchema = runtimeGenericBoardStateSchema.extend({
4201
4217
  layout: z.literal("square"),
4202
- spaces: z.record(ids.spaceId, squareSpaceStateSchema),
4218
+ // T220: loose-keyed by string — see comment above.
4219
+ spaces: z.record(z.string(), squareSpaceStateSchema),
4203
4220
  relations: z.array(boardRelationStateSchema),
4204
4221
  containers: z.record(ids.boardContainerId, boardContainerStateSchema),
4205
4222
  edges: z.array(hexEdgeStateSchema),
@@ -4397,11 +4414,11 @@ export const schemas = {
4397
4414
  } as const;
4398
4415
 
4399
4416
  export function createGameStateSchema<
4400
- PhaseNameSchema extends z.ZodTypeAny,
4401
- PublicSchema extends z.ZodTypeAny,
4402
- PrivateSchema extends z.ZodTypeAny,
4403
- HiddenSchema extends z.ZodTypeAny,
4404
- PhasesSchema extends z.ZodTypeAny,
4417
+ PhaseNameSchema extends z.ZodType<unknown>,
4418
+ PublicSchema extends z.ZodType<unknown>,
4419
+ PrivateSchema extends z.ZodType<unknown>,
4420
+ HiddenSchema extends z.ZodType<unknown>,
4421
+ PhasesSchema extends z.ZodType<unknown>,
4405
4422
  >({
4406
4423
  phaseNameSchema,
4407
4424
  publicSchema,
@@ -4575,9 +4592,16 @@ function renderManifestRuntimeSource(legacySource) {
4575
4592
  return withoutLiterals
4576
4593
  .replace(generatedFileBanner, `${generatedFileBanner}\n// @ts-nocheck`)
4577
4594
  .replace(`} from "@dreamboard/app-sdk/reducer";\n\nconst unknownRecordSchema`, `} from "@dreamboard/app-sdk/reducer";\nimport { literals } from "./manifest-literals";\nimport type { PlayerId as PublicPlayerId, TableState as PublicTableState } from "./manifest-types";\n\nconst unknownRecordSchema`)
4595
+ .replaceAll("literals.playerIds as unknown as readonly PlayerId[]", "literals.playerIds")
4596
+ .replaceAll("cardId: cardIdSchema as unknown as z.ZodType<CardId>,", "cardId: assumeManifestSchema<CardId>(cardIdSchema),")
4597
+ .replaceAll("deckId: deckIdSchema as unknown as z.ZodType<DeckId>,", "deckId: assumeManifestSchema<DeckId>(deckIdSchema),")
4598
+ .replaceAll("handId: handIdSchema as unknown as z.ZodType<HandId>,", "handId: assumeManifestSchema<HandId>(handIdSchema),")
4599
+ .replace(/export const staticBoards = ([\s\S]*?) as const;\n\nconst baseInitialTable = /, "export const staticBoards = $1 as const satisfies StaticBoards<PublicTableState>;\n\nconst baseInitialTable = ")
4600
+ .replace(/const baseInitialTable = ([\s\S]*?) as const as unknown as TableState;\nconst baseDeckCardsByZoneId:/, "const baseInitialTable = cloneManifestDefault<PublicTableState>($1);\nconst baseDeckCardsByZoneId:")
4601
+ .replace("staticBoards: staticBoards as unknown as StaticBoards<TableState>,", "staticBoards,")
4578
4602
  .replace(`export const manifestContract: ReducerManifestContract<\n RuntimeTableRecord,`, `export const manifestContract: ReducerManifestContract<\n PublicTableState,`)
4579
4603
  .replace(`export const manifestContract: ReducerManifestContract<\n PublicTableState,\n string,\n PlayerId,`, `export const manifestContract: ReducerManifestContract<\n PublicTableState,\n string,\n PublicPlayerId,`)
4580
- .replace(`const playerIdSchema = markManifestScopedSchema(\n z\n .string()\n .min(1)\n .transform((value) => asPlayerId(value)),\n);`, `const playerIdSchema = markManifestScopedSchema(\n z\n .string()\n .min(1)\n .transform((value) => asPlayerId(value)),\n) as unknown as z.ZodType<PublicPlayerId>;`);
4604
+ .replace(`const playerIdSchema = markManifestScopedSchema(\n z\n .string()\n .min(1)\n .transform((value) => asPlayerId(value)),\n);`, `const playerIdSchema = assumeManifestSchema<PublicPlayerId>(\n markManifestScopedSchema(\n z\n .string()\n .min(1)\n .transform((value) => asPlayerId(value)),\n ),\n);`);
4581
4605
  }
4582
4606
  function renderCardSetTypeSections(analysis) {
4583
4607
  return analysis.cardSets