@toolproof-npm/schema 0.1.44 → 0.1.45

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.
Files changed (28) hide show
  1. package/dist/_lib/test.js +38 -31
  2. package/dist/genesis/generated/resources/Genesis.json +742 -452
  3. package/dist/genesis/generated/schemas/Genesis.json +441 -166
  4. package/dist/genesis/generated/schemas/Job.json +26 -26
  5. package/dist/genesis/generated/schemas/ResourceFormat.json +9 -9
  6. package/dist/genesis/generated/schemas/ResourceType.json +317 -42
  7. package/dist/genesis/generated/schemas/StatefulStrategy.json +76 -76
  8. package/dist/genesis/generated/schemas/StatelessStrategy.json +40 -40
  9. package/dist/{_lib → genesis/generated}/types/Resource_Job.d.ts +16 -16
  10. package/dist/{_lib → genesis/generated}/types/Resource_ResourceFormat.d.ts +10 -10
  11. package/dist/{_lib → genesis/generated}/types/Resource_ResourceType.d.ts +15 -15
  12. package/dist/{_lib → genesis/generated}/types/Resource_StatelessStrategy.d.ts +16 -16
  13. package/dist/{_lib → genesis/generated}/types/types.d.ts +289 -261
  14. package/dist/genesis/resourceTypes/Genesis.json +530 -250
  15. package/dist/index.d.ts +6 -6
  16. package/dist/index.js +2 -2
  17. package/dist/scripts/_lib/config.js +2 -2
  18. package/dist/scripts/brandFactories.d.ts +37 -23
  19. package/dist/scripts/brandFactories.js +26 -29
  20. package/dist/scripts/extractSchemas.js +1 -1
  21. package/dist/scripts/generateResourceEnvelopes.js +6 -6
  22. package/dist/scripts/generateTypes.js +38 -26
  23. package/package.json +1 -1
  24. /package/dist/{_lib → genesis/generated}/types/Resource_Job.js +0 -0
  25. /package/dist/{_lib → genesis/generated}/types/Resource_ResourceFormat.js +0 -0
  26. /package/dist/{_lib → genesis/generated}/types/Resource_ResourceType.js +0 -0
  27. /package/dist/{_lib → genesis/generated}/types/Resource_StatelessStrategy.js +0 -0
  28. /package/dist/{_lib → genesis/generated}/types/types.js +0 -0
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  export { default as GenesisSchema } from './genesis/generated/schemas/Genesis.js';
2
2
  export { default as Genesis } from './genesis/resourceTypes/Genesis.js';
3
3
  export { default as JobSchema } from './genesis/generated/schemas/Job.js';
4
- export type { Resource_ResourceFormat as Resource_ResourceFormatJson } from './_lib/types/Resource_ResourceFormat.js';
5
- export type { Resource_ResourceType as Resource_ResourceTypeJson } from './_lib/types/Resource_ResourceType.js';
6
- export type { Resource_Job as Resource_JobJson } from './_lib/types/Resource_Job.js';
7
- export type { Documented as DocumentedJson, ResourceFormatId as ResourceFormatIdJson, ResourceFormat as ResourceFormatJson, ExtractionSchema as ExtractionSchemaJson, ExtractionSchemaValue as ExtractionSchemaValueJson, IdentityProp as IdentityPropJson, MeritProp as MeritPropJson, ResourceTypeId as ResourceTypeIdJson, ResourceType as ResourceTypeJson, ResourceRoleId as ResourceRoleIdJson, ResourceRoleValue as ResourceRoleValueJson, ExecutionId as ExecutionIdJson, Execution as ExecutionJson, ConditionalWrapper as ConditionalWrapperJson, RoleMap as RoleMapJson, RolesOuter as RolesOuterJson, RoleBindingMap as RoleBindingMapJson, RoleBindingsOuter as RoleBindingsOuterJson, ResourceId as ResourceIdJson, WorkStepId as WorkStepIdJson, BranchStepId as BranchStepIdJson, WhileStepId as WhileStepIdJson, ForStepId as ForStepIdJson, WorkStep as WorkStepJson, BranchStep as BranchStepJson, WhileStep as WhileStepJson, ForStep as ForStepJson, Step as StepJson, CreationContextValue as CreationContextValueJson, ResourceMissing as ResourceMissingJson, ResourcePotentialInput as ResourcePotentialInputJson, ResourcePotentialOutput as ResourcePotentialOutputJson, ResourceMetaBase as ResourceMetaJson, // ATTENTION: type not generated for ResourceMeta
8
- Resource as ResourceJson, StrategyState as StrategyStateJson, StrategyStateValue as StrategyStateValueJson, StatelessStrategyId as StatelessStrategyIdJson, StatelessStrategy as StatelessStrategyJson, StatefulStrategyId as StatefulStrategyIdJson, StatefulStrategy as StatefulStrategyJson, JobId as JobIdJson, Job as JobJson, JsonValue as JsonValueJson, } from './_lib/types/types.js';
9
- export { unsafeBrand, asResourceTypeId, asResourceRoleId, asExecutionId, asResourceId, asWorkStepId, asBranchStepId, asForStepId, asResourceFormatId, asWhileStepId, asStatelessStrategyId, asStatefulStrategyId, asResourceTypeIds, asResourceRoleIds, asExecutionIds, asResourceIds, asWorkStepIds, asBranchStepIds, asForStepIds, asResourceFormatIds, asWhileStepIds, asStatelessStrategyIds, asStatefulStrategyIds, } from './scripts/brandFactories.js';
4
+ export type { Resource_ResourceFormat as Resource_ResourceFormatJson } from './genesis/generated/types/Resource_ResourceFormat.js';
5
+ export type { Resource_ResourceType as Resource_ResourceTypeJson } from './genesis/generated/types/Resource_ResourceType.js';
6
+ export type { Resource_Job as Resource_JobJson } from './genesis/generated/types/Resource_Job.js';
7
+ export type { Documented as DocumentedJson, ResourceFormatIdentity as ResourceFormatIdentityJson, ResourceFormat as ResourceFormatJson, ExtractionSchema as ExtractionSchemaJson, IdentityProp as IdentityPropJson, MeritProp as MeritPropJson, ResourceTypeIdentity as ResourceTypeIdentityJson, ResourceType as ResourceTypeJson, ResourceRoleIdentity as ResourceRoleIdentityJson, ResourceRoleValue as ResourceRoleValueJson, ExecutionIdentity as ExecutionIdentityJson, Execution as ExecutionJson, Conditional as ConditionalJson, RoleMap as RoleMapJson, Roles as RolesJson, RoleBindingMap as RoleBindingMapJson, RoleBindings as RoleBindingsJson, ResourceIdentity as ResourceIdentityJson, WorkStepIdentity as WorkStepIdentityJson, BranchStepIdentity as BranchStepIdentityJson, WhileStepIdentity as WhileStepIdentityJson, ForStepIdentity as ForStepIdentityJson, WorkStep as WorkStepJson, BranchStep as BranchStepJson, WhileStep as WhileStepJson, ForStep as ForStepJson, Step as StepJson, CreationContext as CreationContextJson, ResourceMissing as ResourceMissingJson, ResourcePotentialInput as ResourcePotentialInputJson, ResourcePotentialOutput as ResourcePotentialOutputJson, ResourceMetaBase as ResourceMetaJson, // ATTENTION: type not generated for ResourceMeta
8
+ Resource as ResourceJson, StrategyState as StrategyStateJson, StatelessStrategyIdentity as StatelessStrategyIdentityJson, StatelessStrategy as StatelessStrategyJson, StatefulStrategyIdentity as StatefulStrategyIdentityJson, StatefulStrategy as StatefulStrategyJson, JobIdentity as JobIdentityJson, Job as JobJson, JsonData as JsonDataJson, } from './genesis/generated/types/types.js';
9
+ export { unsafeBrand, asResourceTypeIdentity, asResourceRoleIdentity, asExecutionIdentity, asResourceIdentity, asWorkStepIdentity, asBranchStepIdentity, asForStepIdentity, asResourceFormatIdentity, asWhileStepIdentity, asStatelessStrategyIdentity, asStatefulStrategyIdentity, asResourceTypeIdentities, asResourceRoleIdentities, asExecutionIdentities, asResourceIdentities, asWorkStepIdentities, asBranchStepIdentities, asForStepIdentities, asResourceFormatIdentities, asWhileStepIdentities, asStatelessStrategyIdentities, asStatefulStrategyIdentities, } from './scripts/brandFactories.js';
package/dist/index.js CHANGED
@@ -2,5 +2,5 @@
2
2
  export { default as GenesisSchema } from './genesis/generated/schemas/Genesis.js';
3
3
  export { default as Genesis } from './genesis/resourceTypes/Genesis.js';
4
4
  export { default as JobSchema } from './genesis/generated/schemas/Job.js';
5
- // Re-export brand factories so consumers can construct branded IDs at runtime.
6
- export { unsafeBrand, asResourceTypeId, asResourceRoleId, asExecutionId, asResourceId, asWorkStepId, asBranchStepId, asForStepId, asResourceFormatId, asWhileStepId, asStatelessStrategyId, asStatefulStrategyId, asResourceTypeIds, asResourceRoleIds, asExecutionIds, asResourceIds, asWorkStepIds, asBranchStepIds, asForStepIds, asResourceFormatIds, asWhileStepIds, asStatelessStrategyIds, asStatefulStrategyIds, } from './scripts/brandFactories.js';
5
+ // Re-export brand factories so consumers can construct branded identities at runtime.
6
+ export { unsafeBrand, asResourceTypeIdentity, asResourceRoleIdentity, asExecutionIdentity, asResourceIdentity, asWorkStepIdentity, asBranchStepIdentity, asForStepIdentity, asResourceFormatIdentity, asWhileStepIdentity, asStatelessStrategyIdentity, asStatefulStrategyIdentity, asResourceTypeIdentities, asResourceRoleIdentities, asExecutionIdentities, asResourceIdentities, asWorkStepIdentities, asBranchStepIdentities, asForStepIdentities, asResourceFormatIdentities, asWhileStepIdentities, asStatelessStrategyIdentities, asStatefulStrategyIdentities, } from './scripts/brandFactories.js';
@@ -21,8 +21,8 @@ export class SchemaConfig {
21
21
  this.sourceDir = getEnv('TP_SCHEMA_SOURCE_DIR', 'src/genesis/resourceTypes');
22
22
  this.sourceFile = getEnv('TP_SCHEMA_SOURCE_FILE', 'Genesis.json');
23
23
  this.outputDir = getEnv('TP_SCHEMA_OUTPUT_DIR', 'src/genesis/generated/schemas');
24
- this.typesSrcDir = getEnv('TP_SCHEMA_TYPES_SRC_DIR', 'src/_lib/types');
25
- this.typesDistDir = getEnv('TP_SCHEMA_TYPES_DIST_DIR', 'dist/_lib/types');
24
+ this.typesSrcDir = getEnv('TP_SCHEMA_TYPES_SRC_DIR', 'src/genesis/generated/types');
25
+ this.typesDistDir = getEnv('TP_SCHEMA_TYPES_DIST_DIR', 'dist/genesis/generated/types');
26
26
  this.baseUrl = getEnv('TP_SCHEMA_BASE_URL', 'https://schemas.toolproof.com');
27
27
  this.version = getEnv('TP_SCHEMA_VERSION', 'v0');
28
28
  }
@@ -1,25 +1,39 @@
1
- import type { ExecutionId, ResourceId, WorkStepId, BranchStepId, ForStepId, ResourceFormatId, ResourceTypeId, ResourceRoleId, WhileStepId, StatelessStrategyId, StatefulStrategyId } from "../_lib/types/types.js";
1
+ type Brand<K extends string> = string & {
2
+ readonly __brand: K;
3
+ };
4
+ export type ExecutionIdentity = Brand<'ExecutionIdentity'>;
5
+ export type ResourceIdentity = Brand<'ResourceIdentity'>;
6
+ export type WorkStepIdentity = Brand<'WorkStepIdentity'>;
7
+ export type BranchStepIdentity = Brand<'BranchStepIdentity'>;
8
+ export type ForStepIdentity = Brand<'ForStepIdentity'>;
9
+ export type WhileStepIdentity = Brand<'WhileStepIdentity'>;
10
+ export type ResourceFormatIdentity = Brand<'ResourceFormatIdentity'>;
11
+ export type ResourceTypeIdentity = Brand<'ResourceTypeIdentity'>;
12
+ export type ResourceRoleIdentity = Brand<'ResourceRoleIdentity'>;
13
+ export type StatelessStrategyIdentity = Brand<'StatelessStrategyIdentity'>;
14
+ export type StatefulStrategyIdentity = Brand<'StatefulStrategyIdentity'>;
2
15
  /** Generic unsafe brand helper when a bespoke factory is not available. */
3
16
  export declare function unsafeBrand<T extends string>(s: string): T;
4
- export declare const asResourceTypeId: (s: string) => string;
5
- export declare const asResourceRoleId: (s: string) => string;
6
- export declare const asExecutionId: (s: string) => string;
7
- export declare const asResourceId: (s: string) => string;
8
- export declare const asWorkStepId: (s: string) => string;
9
- export declare const asBranchStepId: (s: string) => string;
10
- export declare const asForStepId: (s: string) => string;
11
- export declare const asResourceFormatId: (s: string) => string;
12
- export declare const asWhileStepId: (s: string) => string;
13
- export declare const asStatelessStrategyId: (s: string) => string;
14
- export declare const asStatefulStrategyId: (s: string) => string;
15
- export declare const asResourceTypeIds: (xs: string[]) => ResourceTypeId[];
16
- export declare const asResourceRoleIds: (xs: string[]) => ResourceRoleId[];
17
- export declare const asExecutionIds: (xs: string[]) => ExecutionId[];
18
- export declare const asResourceIds: (xs: string[]) => ResourceId[];
19
- export declare const asWorkStepIds: (xs: string[]) => WorkStepId[];
20
- export declare const asBranchStepIds: (xs: string[]) => BranchStepId[];
21
- export declare const asForStepIds: (xs: string[]) => ForStepId[];
22
- export declare const asResourceFormatIds: (xs: string[]) => ResourceFormatId[];
23
- export declare const asWhileStepIds: (xs: string[]) => WhileStepId[];
24
- export declare const asStatelessStrategyIds: (xs: string[]) => StatelessStrategyId[];
25
- export declare const asStatefulStrategyIds: (xs: string[]) => StatefulStrategyId[];
17
+ export declare const asResourceTypeIdentity: (s: string) => ResourceTypeIdentity;
18
+ export declare const asResourceRoleIdentity: (s: string) => ResourceRoleIdentity;
19
+ export declare const asExecutionIdentity: (s: string) => ExecutionIdentity;
20
+ export declare const asResourceIdentity: (s: string) => ResourceIdentity;
21
+ export declare const asWorkStepIdentity: (s: string) => WorkStepIdentity;
22
+ export declare const asBranchStepIdentity: (s: string) => BranchStepIdentity;
23
+ export declare const asForStepIdentity: (s: string) => ForStepIdentity;
24
+ export declare const asResourceFormatIdentity: (s: string) => ResourceFormatIdentity;
25
+ export declare const asWhileStepIdentity: (s: string) => WhileStepIdentity;
26
+ export declare const asStatelessStrategyIdentity: (s: string) => StatelessStrategyIdentity;
27
+ export declare const asStatefulStrategyIdentity: (s: string) => StatefulStrategyIdentity;
28
+ export declare const asResourceTypeIdentities: (xs: string[]) => ResourceTypeIdentity[];
29
+ export declare const asResourceRoleIdentities: (xs: string[]) => ResourceRoleIdentity[];
30
+ export declare const asExecutionIdentities: (xs: string[]) => ExecutionIdentity[];
31
+ export declare const asResourceIdentities: (xs: string[]) => ResourceIdentity[];
32
+ export declare const asWorkStepIdentities: (xs: string[]) => WorkStepIdentity[];
33
+ export declare const asBranchStepIdentities: (xs: string[]) => BranchStepIdentity[];
34
+ export declare const asForStepIdentities: (xs: string[]) => ForStepIdentity[];
35
+ export declare const asResourceFormatIdentities: (xs: string[]) => ResourceFormatIdentity[];
36
+ export declare const asWhileStepIdentities: (xs: string[]) => WhileStepIdentity[];
37
+ export declare const asStatelessStrategyIdentities: (xs: string[]) => StatelessStrategyIdentity[];
38
+ export declare const asStatefulStrategyIdentities: (xs: string[]) => StatefulStrategyIdentity[];
39
+ export {};
@@ -1,6 +1,3 @@
1
- // Runtime factories for branded ID string types.
2
- // Note: The branded types are declared in src/types/types.d.ts by the generator.
3
- // We import them as type-only so there is no runtime dependency on the .d.ts file.
4
1
  // Optional runtime validation toggle. Off by default.
5
2
  // Enable by setting TP_BRAND_VALIDATE=1 (or NODE_ENV=development) when running.
6
3
  const shouldValidate = (typeof process !== "undefined" && !!process.env &&
@@ -19,31 +16,31 @@ export function unsafeBrand(s) {
19
16
  return s;
20
17
  }
21
18
  // Known patterns from schemas (when available)
22
- const RE_TYPE_ID = /^TYPE-.+$/;
23
- const RE_JOB_ID = /^JOB-.+$/;
24
- const RE_ROLE_ID = /^ROLE-.+$/;
25
- // Factories for each Id-like type
26
- export const asResourceTypeId = makeFactory("ResourceTypeId", RE_TYPE_ID);
27
- export const asResourceRoleId = makeFactory("ResourceRoleId", RE_ROLE_ID);
19
+ const RE_TYPE_IDENTITY = /^TYPE-.+$/;
20
+ const RE_JOB_IDENTITY = /^JOB-.+$/;
21
+ const RE_ROLE_IDENTITY = /^ROLE-.+$/;
22
+ // Factories for each Identity-like type
23
+ export const asResourceTypeIdentity = makeFactory("ResourceTypeIdentity", RE_TYPE_IDENTITY);
24
+ export const asResourceRoleIdentity = makeFactory("ResourceRoleIdentity", RE_ROLE_IDENTITY);
28
25
  // IDs without strict regex patterns in the current schemas: keep unchecked casts.
29
- export const asExecutionId = makeFactory("ExecutionId");
30
- export const asResourceId = makeFactory("ResourceId");
31
- export const asWorkStepId = makeFactory("WorkStepId");
32
- export const asBranchStepId = makeFactory("BranchStepId");
33
- export const asForStepId = makeFactory("ForStepId");
34
- export const asResourceFormatId = makeFactory("ResourceFormatId");
35
- export const asWhileStepId = makeFactory("WhileStepId");
36
- export const asStatelessStrategyId = makeFactory("StatelessStrategyId");
37
- export const asStatefulStrategyId = makeFactory("StatefulStrategyId");
26
+ export const asExecutionIdentity = makeFactory("ExecutionIdentity");
27
+ export const asResourceIdentity = makeFactory("ResourceIdentity");
28
+ export const asWorkStepIdentity = makeFactory("WorkStepIdentity");
29
+ export const asBranchStepIdentity = makeFactory("BranchStepIdentity");
30
+ export const asForStepIdentity = makeFactory("ForStepIdentity");
31
+ export const asResourceFormatIdentity = makeFactory("ResourceFormatIdentity");
32
+ export const asWhileStepIdentity = makeFactory("WhileStepIdentity");
33
+ export const asStatelessStrategyIdentity = makeFactory("StatelessStrategyIdentity");
34
+ export const asStatefulStrategyIdentity = makeFactory("StatefulStrategyIdentity");
38
35
  // Batch helpers
39
- export const asResourceTypeIds = (xs) => xs.map(asResourceTypeId);
40
- export const asResourceRoleIds = (xs) => xs.map(asResourceRoleId);
41
- export const asExecutionIds = (xs) => xs.map(asExecutionId);
42
- export const asResourceIds = (xs) => xs.map(asResourceId);
43
- export const asWorkStepIds = (xs) => xs.map(asWorkStepId);
44
- export const asBranchStepIds = (xs) => xs.map(asBranchStepId);
45
- export const asForStepIds = (xs) => xs.map(asForStepId);
46
- export const asResourceFormatIds = (xs) => xs.map(asResourceFormatId);
47
- export const asWhileStepIds = (xs) => xs.map(asWhileStepId);
48
- export const asStatelessStrategyIds = (xs) => xs.map(asStatelessStrategyId);
49
- export const asStatefulStrategyIds = (xs) => xs.map(asStatefulStrategyId);
36
+ export const asResourceTypeIdentities = (xs) => xs.map(asResourceTypeIdentity);
37
+ export const asResourceRoleIdentities = (xs) => xs.map(asResourceRoleIdentity);
38
+ export const asExecutionIdentities = (xs) => xs.map(asExecutionIdentity);
39
+ export const asResourceIdentities = (xs) => xs.map(asResourceIdentity);
40
+ export const asWorkStepIdentities = (xs) => xs.map(asWorkStepIdentity);
41
+ export const asBranchStepIdentities = (xs) => xs.map(asBranchStepIdentity);
42
+ export const asForStepIdentities = (xs) => xs.map(asForStepIdentity);
43
+ export const asResourceFormatIdentities = (xs) => xs.map(asResourceFormatIdentity);
44
+ export const asWhileStepIdentities = (xs) => xs.map(asWhileStepIdentity);
45
+ export const asStatelessStrategyIdentities = (xs) => xs.map(asStatelessStrategyIdentity);
46
+ export const asStatefulStrategyIdentities = (xs) => xs.map(asStatefulStrategyIdentity);
@@ -105,7 +105,7 @@ function unwrapTypes(node, topDefs, labelPath = [], visited = new Set()) {
105
105
  // Hoist inner $defs before stripping
106
106
  mergeDefs(topDefs, inner, labelPath.join("_"));
107
107
  // Return the inner schema itself, after also unwrapping any nested envelopes it may contain
108
- const unwrappedInner = unwrapTypes(inner, topDefs, labelPath.concat([String(env.id || "env")]), visited);
108
+ const unwrappedInner = unwrapTypes(inner, topDefs, labelPath.concat([String(env.identity || "env")]), visited);
109
109
  return unwrappedInner;
110
110
  }
111
111
  if (Array.isArray(node)) {
@@ -40,10 +40,10 @@ async function main() {
40
40
  // First entry is Genesis itself with empty extractedData
41
41
  resources['Genesis'] = {
42
42
  identity: 'RESOURCE-Genesis',
43
- resourceTypeId: 'TYPE-ResourceType',
43
+ resourceTypeRef: 'TYPE-ResourceType',
44
44
  creationContext: {
45
- resourceRoleId: 'ROLE-Genesis',
46
- executionId: 'EXECUTION-Genesis'
45
+ resourceRoleRef: 'ROLE-Genesis',
46
+ executionRef: 'EXECUTION-Genesis'
47
47
  },
48
48
  kind: 'materialized',
49
49
  timestamp: genesisTimestamp,
@@ -54,10 +54,10 @@ async function main() {
54
54
  const defValue = defs[defName];
55
55
  resources[defName] = {
56
56
  identity: `RESOURCE-${defName}`,
57
- resourceTypeId: 'TYPE-ResourceType',
57
+ resourceTypeRef: 'TYPE-ResourceType',
58
58
  creationContext: {
59
- resourceRoleId: 'ROLE-Genesis',
60
- executionId: `EXECUTION-${defName}`
59
+ resourceRoleRef: 'ROLE-Genesis',
60
+ executionRef: `EXECUTION-${defName}`
61
61
  },
62
62
  kind: 'materialized',
63
63
  timestamp: genesisTimestamp,
@@ -5,7 +5,7 @@ import { getConfig } from './_lib/config.js';
5
5
  const config = getConfig();
6
6
  const projectRoot = config.getRoot();
7
7
  const inputDir = config.getOutputDir();
8
- // We emit under src/_lib/types and dist/_lib/types
8
+ // We emit under src/genesis/generated/types and dist/genesis/generated/types
9
9
  const srcLibTypesDir = config.getTypesSrcDir();
10
10
  const srcLibOutputPath = config.getTypesSrcPath('types.d.ts');
11
11
  // Build an index of all schema files by their basename
@@ -25,8 +25,13 @@ function buildSchemaIndex(root) {
25
25
  stack.push(full);
26
26
  }
27
27
  else if (entry.isFile() && entry.name.endsWith('.json')) {
28
+ // Ignore temp files that can be left behind after crashes
28
29
  if (entry.name === '.combined-schema.json')
29
- continue; // ignore temp file
30
+ continue;
31
+ if (entry.name.startsWith('.normalized.'))
32
+ continue;
33
+ if (entry.name.startsWith('.'))
34
+ continue;
30
35
  const baseName = entry.name; // keep extension for direct mapping
31
36
  if (index.has(baseName)) {
32
37
  // Hard fail on collisions so they can be fixed explicitly
@@ -59,8 +64,13 @@ function listAllSchemaFiles(root) {
59
64
  stack.push(full);
60
65
  }
61
66
  else if (entry.isFile() && entry.name.endsWith('.json')) {
67
+ // Ignore temp files that can be left behind after crashes
62
68
  if (entry.name === '.combined-schema.json')
63
- continue; // ignore temp
69
+ continue;
70
+ if (entry.name.startsWith('.normalized.'))
71
+ continue;
72
+ if (entry.name.startsWith('.'))
73
+ continue;
64
74
  // produce path relative to root with posix separators
65
75
  const rel = path.relative(root, full).split(path.sep).join('/');
66
76
  files.push(rel);
@@ -71,7 +81,7 @@ function listAllSchemaFiles(root) {
71
81
  return files;
72
82
  }
73
83
  async function main() {
74
- // Ensure src/_lib/types exists (we no longer write to src/types to avoid duplication)
84
+ // Ensure types output folder exists
75
85
  fs.mkdirSync(srcLibTypesDir, { recursive: true });
76
86
  const parts = [];
77
87
  parts.push('// Auto-generated from JSON schemas. Do not edit.\n');
@@ -316,10 +326,9 @@ async function main() {
316
326
  if (!ts || !ts.trim()) {
317
327
  ts = '// (No concrete types emitted by generator)\nexport {}\n';
318
328
  }
319
- // Overlay Id aliases with template literal types inferred from Genesis.json patterns.
320
- // For each $defs entry ending with "Id" or specific key types that provide a `pattern`,
321
- // we derive a TS template literal. If no recognizable pattern exists,
322
- // we fall back to plain `string` (moving away from branded types).
329
+ // Overlay Identity/Ref aliases with template literal types inferred from Genesis.json patterns.
330
+ // For each $defs entry ending with "Identity" or "Ref", and that provides a `pattern`,
331
+ // derive a TS template literal; otherwise fall back to plain `string`.
323
332
  function deriveTemplateFromPattern(pattern) {
324
333
  // Common form: ^PREFIX-.+$ => PREFIX-${string}
325
334
  const m1 = /^\^([^$]+)\.\+\$/.exec(pattern);
@@ -339,7 +348,7 @@ async function main() {
339
348
  }
340
349
  return undefined;
341
350
  }
342
- function loadIdTemplates() {
351
+ function loadPatternTemplates() {
343
352
  const map = {};
344
353
  try {
345
354
  const genesisPath = path.join(inputDir, config.getSourceFile());
@@ -348,9 +357,10 @@ async function main() {
348
357
  const parsed = JSON.parse(raw);
349
358
  const defs = parsed?.$defs && typeof parsed.$defs === 'object' ? parsed.$defs : {};
350
359
  for (const [defName, defVal] of Object.entries(defs)) {
351
- // Process Id types
352
- const isIdType = /Id$/.test(defName);
353
- if (!isIdType)
360
+ // Process pattern-bearing string types.
361
+ // Supports "...Identity" / "...Ref" conventions.
362
+ const isPatternType = /(?:Identity|Ref)$/.test(defName);
363
+ if (!isPatternType)
354
364
  continue;
355
365
  const v = defVal;
356
366
  if (v && v.type === 'string' && typeof v.pattern === 'string') {
@@ -366,22 +376,25 @@ async function main() {
366
376
  }
367
377
  return map;
368
378
  }
369
- const idTemplates = loadIdTemplates();
370
- // Replace any exported Id aliases to use the inferred template literals where available.
379
+ const patternTemplates = loadPatternTemplates();
380
+ // Replace any exported Identity/Ref aliases to use the inferred template literals where available.
371
381
  // Handle both `= string;` and any pre-existing branded alias `= Branded<string, 'X'>;`.
372
- ts = ts.replace(/^(export\s+type\s+)([A-Za-z_][A-Za-z0-9_]*Id)(\s*=\s*)Branded<string,\s*'[^']+'>\s*;$/gm, (_m, p1, typeName, p3) => {
373
- const tmpl = idTemplates[typeName];
382
+ ts = ts.replace(/^(export\s+type\s+)([A-Za-z_][A-Za-z0-9_]*(?:Identity|Ref))(\s*=\s*)Branded<string,\s*'[^']+'>\s*;$/gm, (_m, p1, typeName, p3) => {
383
+ const tmpl = patternTemplates[typeName];
374
384
  return `${p1}${typeName}${p3}${tmpl ?? 'string'};`;
375
385
  });
376
- ts = ts.replace(/^(export\s+type\s+)([A-Za-z_][A-ZaZ0-9_]*Id)(\s*=\s*)string\s*;$/gm, (_m, p1, typeName, p3) => {
377
- const tmpl = idTemplates[typeName];
386
+ ts = ts.replace(/^(export\s+type\s+)([A-Za-z_][A-Za-z0-9_]*(?:Identity|Ref))(\s*=\s*)string\s*;$/gm, (_m, p1, typeName, p3) => {
387
+ const tmpl = patternTemplates[typeName];
378
388
  return `${p1}${typeName}${p3}${tmpl ?? 'string'};`;
379
389
  });
380
- // Post-process map-like interfaces to enforce key constraints via template literal Id types.
381
- // Replace index-signature interfaces with Record<IdType, ValueType> so object literal keys are checked.
382
- ts = ts.replace(/export interface RoleMap\s*{[^}]*}/g, 'export type RoleMap = Record<ResourceRoleId, ResourceRoleValue>;');
383
- ts = ts.replace(/export interface RoleBindingMap\s*{[^}]*}/g, 'export type RoleBindingMap = Record<ResourceRoleId, ResourceId>;');
384
- ts = ts.replace(/export interface StrategyState\s*\{[^}]*\{[^}]*\}[^}]*\}/gs, 'export type StrategyState = Record<ExecutionId, Record<ResourceRoleId, ResourcePotentialInput | ResourcePotentialOutput | Resource>>;');
390
+ // Post-process map-like interfaces to enforce key constraints via template literal Identity types.
391
+ // Replace index-signature interfaces with Record<KeyType, ValueType> so object literal keys are checked.
392
+ const resourceRoleKeyType = 'ResourceRoleIdentity';
393
+ const resourceKeyType = 'ResourceIdentity';
394
+ const executionKeyType = 'ExecutionIdentity';
395
+ ts = ts.replace(/export interface RoleMap\s*{[^}]*}/g, `export type RoleMap = Record<${resourceRoleKeyType}, ResourceRoleValue>;`);
396
+ ts = ts.replace(/export interface RoleBindingMap\s*{[^}]*}/g, `export type RoleBindingMap = Record<${resourceRoleKeyType}, ${resourceKeyType}>;`);
397
+ ts = ts.replace(/export interface StrategyState\s*\{[^}]*\{[^}]*\}[^}]*\}/gs, `export type StrategyState = Record<${executionKeyType}, Record<${resourceRoleKeyType}, ResourcePotentialInput | ResourcePotentialOutput | Resource>>;`);
385
398
  parts.push(ts);
386
399
  let output = parts.join('\n');
387
400
  // Final guard: strip any lingering `[k: string]: unknown;` that might have been
@@ -399,7 +412,7 @@ async function main() {
399
412
  if (!/\bexport\b|\bdeclare\s+module\b|\bdeclare\s+namespace\b/.test(output)) {
400
413
  output += '\nexport {}\n';
401
414
  }
402
- // Write only under src/_lib/types to avoid duplicate src/types folder
415
+ // Write only under configured types output folder
403
416
  try {
404
417
  fs.writeFileSync(srcLibOutputPath, output, 'utf8');
405
418
  console.log('Wrote', srcLibOutputPath);
@@ -408,7 +421,6 @@ async function main() {
408
421
  console.warn('Failed to write types to src/_lib:', e);
409
422
  }
410
423
  // Also write a copy into dist so consumers get the generated declarations
411
- // Write only to dist/_lib/types to keep the same path structure under dist
412
424
  const distLibTypesDir = config.getTypesDistDir();
413
425
  const distLibOutputPath = config.getTypesDistPath('types.d.ts');
414
426
  try {
@@ -420,7 +432,7 @@ async function main() {
420
432
  // If copying to dist fails, log but don't crash the generator.
421
433
  console.warn('Failed to write types to dist:', e);
422
434
  }
423
- // Ensure there is a runtime-resolvable module for './_lib/types/types.js'
435
+ // Ensure there is a runtime-resolvable module next to `types.d.ts`
424
436
  // Some consumers and TS NodeNext resolution expect a concrete .js next to .d.ts
425
437
  // The file is intentionally empty as all exports are types-only.
426
438
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toolproof-npm/schema",
3
- "version": "0.1.44",
3
+ "version": "0.1.45",
4
4
  "description": "JSON schemas and TypeScript types for ToolProof",
5
5
  "keywords": [
6
6
  "toolproof",
File without changes