@toolproof-npm/schema 0.1.34 → 0.1.35

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 (53) hide show
  1. package/dist/_lib/test.js +12 -12
  2. package/dist/_lib/types/Resource_Job.d.ts +55 -0
  3. package/dist/_lib/types/Resource_ResourceFormat.d.ts +40 -0
  4. package/dist/_lib/types/Resource_ResourceFormat.js +1 -0
  5. package/dist/_lib/types/Resource_ResourceType.d.ts +60 -0
  6. package/dist/_lib/types/Resource_ResourceType.js +1 -0
  7. package/dist/_lib/types/Resource_StatelessStrategy.d.ts +79 -0
  8. package/dist/_lib/types/Resource_StatelessStrategy.js +1 -0
  9. package/dist/_lib/types/types.d.ts +491 -353
  10. package/dist/genesis/generated/resources/Genesis.d.ts +2 -0
  11. package/dist/genesis/generated/resources/Genesis.js +2 -0
  12. package/dist/genesis/generated/resources/Genesis.json +2113 -0
  13. package/dist/{schemas → genesis/generated/schemas}/Genesis.json +266 -345
  14. package/dist/{schemas → genesis/generated/schemas}/Job.json +24 -26
  15. package/dist/genesis/generated/schemas/ResourceFormat.d.ts +2 -0
  16. package/dist/genesis/generated/schemas/ResourceFormat.js +2 -0
  17. package/dist/genesis/generated/schemas/ResourceFormat.json +74 -0
  18. package/dist/genesis/generated/schemas/ResourceType.d.ts +2 -0
  19. package/dist/genesis/generated/schemas/ResourceType.js +2 -0
  20. package/dist/genesis/generated/schemas/ResourceType.json +361 -0
  21. package/dist/genesis/generated/schemas/StatefulStrategy.d.ts +2 -0
  22. package/dist/genesis/generated/schemas/StatefulStrategy.js +2 -0
  23. package/dist/genesis/generated/schemas/StatefulStrategy.json +647 -0
  24. package/dist/genesis/generated/schemas/StatelessStrategy.d.ts +2 -0
  25. package/dist/genesis/generated/schemas/StatelessStrategy.js +2 -0
  26. package/dist/genesis/generated/schemas/StatelessStrategy.json +324 -0
  27. package/dist/genesis/resourceTypes/Genesis.d.ts +2 -0
  28. package/dist/genesis/resourceTypes/Genesis.js +2 -0
  29. package/dist/genesis/resourceTypes/Genesis.json +1523 -0
  30. package/dist/index.d.ts +8 -5
  31. package/dist/index.js +4 -3
  32. package/dist/scripts/_lib/config.d.ts +45 -0
  33. package/dist/scripts/_lib/config.js +109 -0
  34. package/dist/scripts/brandFactories.d.ts +5 -5
  35. package/dist/scripts/brandFactories.js +4 -5
  36. package/dist/scripts/extractSchemas.js +33 -8
  37. package/dist/scripts/extractSubschemaWithDefs.js +36 -7
  38. package/dist/scripts/generateResourceEnvelopes.js +77 -0
  39. package/dist/scripts/generateResourceTypeType.d.ts +1 -0
  40. package/dist/scripts/{generateResourceData.js → generateResourceTypeType.js} +21 -19
  41. package/dist/scripts/generateSchemaShims.d.ts +1 -0
  42. package/dist/scripts/generateSchemaShims.js +63 -0
  43. package/dist/scripts/generateTypes.js +116 -83
  44. package/dist/scripts/rewriteAnchors.d.ts +1 -0
  45. package/dist/scripts/rewriteAnchors.js +90 -0
  46. package/package.json +50 -52
  47. package/dist/_lib/types/ResourceData_Job.d.ts +0 -97
  48. /package/dist/_lib/types/{ResourceData_Job.js → Resource_Job.js} +0 -0
  49. /package/dist/{schemas → genesis/generated/schemas}/Genesis.d.ts +0 -0
  50. /package/dist/{schemas → genesis/generated/schemas}/Genesis.js +0 -0
  51. /package/dist/{schemas → genesis/generated/schemas}/Job.d.ts +0 -0
  52. /package/dist/{schemas → genesis/generated/schemas}/Job.js +0 -0
  53. /package/dist/scripts/{generateResourceData.d.ts → generateResourceEnvelopes.d.ts} +0 -0
package/dist/index.d.ts CHANGED
@@ -1,5 +1,8 @@
1
- export { default as GenesisSchema } from './schemas/Genesis.js';
2
- export { default as JobSchema } from './schemas/Job.js';
3
- export type { ResourceData_Job as ResourceData_JobJson } from './_lib/types/ResourceData_Job.js';
4
- export type { Identifiable as IdentifiableJson, Documented as DocumentedJson, IdentifiableDocumented as IdentifiableDocumentedJson, ResourceFormatId as ResourceFormatIdJson, ResourceFormatMeta as ResourceFormatMetaJson, ResourceFormatData as ResourceFormatDataJson, ExtractionSchema as ExtractionSchemaJson, ExtractionSchemaValue as ExtractionSchemaValueJson, IdentityProp as IdentityPropJson, MeritProp as MeritPropJson, ResourceTypeId as ResourceTypeIdJson, ResourceTypeMeta as ResourceTypeMetaJson, ResourceTypeData as ResourceTypeDataJson, 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, StepId as StepIdJson, Step as StepJson, ResourceSocket as ResourceSocketJson, ResourcePotentialInput as ResourcePotentialInputJson, ResourcePotentialOutput as ResourcePotentialOutputJson, ResourceRawMeta as ResourceRawMetaJson, ResourceMeta as ResourceMetaJson, ResourceData as ResourceDataJson, ResourceMap as ResourceMapJson, WorkflowId as WorkflowIdJson, Workflow as WorkflowJson, WorkflowSpecId as WorkflowSpecIdJson, WorkflowSpec as WorkflowSpecJson, Job as JobJson, JsonValue as JsonValueJson, } from './_lib/types/types.js';
5
- export { unsafeBrand, asResourceTypeId, asResourceRoleId, asExecutionId, asResourceId, asWorkStepId, asBranchStepId, asForStepId, asResourceFormatId, asWhileStepId, asWorkflowId, asWorkflowSpecId, asResourceTypeIds, asResourceRoleIds, asExecutionIds, asResourceIds, asWorkStepIds, asBranchStepIds, asForStepIds, asResourceFormatIds, asWhileStepIds, asWorkflowIds, asWorkflowSpecIds, } from './scripts/brandFactories.js';
1
+ export { default as GenesisSchema } from './genesis/generated/schemas/Genesis.js';
2
+ export { default as Genesis } from './genesis/resourceTypes/Genesis.js';
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, ResourceSocket as ResourceSocketJson, ResourcePotentialInput as ResourcePotentialInputJson, ResourcePotentialOutput as ResourcePotentialOutputJson, ResourceRawMeta as ResourceRawMetaJson, Resource as ResourceJson, StrategyState as StrategyStateJson, StrategyStateValue as StrategyStateValueJson, StatelessStrategy as StatelessStrategyIdJson, StatelessStrategy as StatelessStrategyJson, StatefulStrategyId as StatefulStrategyIdJson, StatefulStrategy as StatefulStrategyJson, Job as JobJson, JsonValue as JsonValueJson, } from './_lib/types/types.js';
8
+ 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';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // Re-export JSON schemas via .ts shims to avoid .json re-exports in declarations
2
- export { default as GenesisSchema } from './schemas/Genesis.js';
3
- export { default as JobSchema } from './schemas/Job.js';
2
+ export { default as GenesisSchema } from './genesis/generated/schemas/Genesis.js';
3
+ export { default as Genesis } from './genesis/resourceTypes/Genesis.js';
4
+ export { default as JobSchema } from './genesis/generated/schemas/Job.js';
4
5
  // Re-export brand factories so consumers can construct branded IDs at runtime.
5
- export { unsafeBrand, asResourceTypeId, asResourceRoleId, asExecutionId, asResourceId, asWorkStepId, asBranchStepId, asForStepId, asResourceFormatId, asWhileStepId, asWorkflowId, asWorkflowSpecId, asResourceTypeIds, asResourceRoleIds, asExecutionIds, asResourceIds, asWorkStepIds, asBranchStepIds, asForStepIds, asResourceFormatIds, asWhileStepIds, asWorkflowIds, asWorkflowSpecIds, } from './scripts/brandFactories.js';
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';
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Configuration for schema generation scripts
3
+ * All paths are configurable via environment variables
4
+ * Provides sensible defaults for standard project structure
5
+ */
6
+ /**
7
+ * Schema configuration with required environment variables
8
+ */
9
+ export declare class SchemaConfig {
10
+ private readonly root;
11
+ private readonly sourceDir;
12
+ private readonly sourceFile;
13
+ private readonly outputDir;
14
+ private readonly typesSrcDir;
15
+ private readonly typesDistDir;
16
+ private readonly baseUrl;
17
+ private readonly version;
18
+ constructor();
19
+ getRoot(): string;
20
+ getSourceDir(): string;
21
+ getSourceFile(): string;
22
+ getSourcePath(): string;
23
+ getOutputDir(): string;
24
+ getOutputPath(filename: string): string;
25
+ getTypesSrcDir(): string;
26
+ getTypesDistDir(): string;
27
+ getTypesSrcPath(filename: string): string;
28
+ getTypesDistPath(filename: string): string;
29
+ getBaseUrl(): string;
30
+ getVersion(): string;
31
+ getSchemaId(schemaName: string): string;
32
+ /**
33
+ * Check if a URL matches the configured schema base URL pattern
34
+ */
35
+ isSchemaUrl(url: string): boolean;
36
+ /**
37
+ * Extract schema name from URL (removes base URL and version prefix)
38
+ */
39
+ extractSchemaName(url: string): string;
40
+ }
41
+ /**
42
+ * Get the schema configuration singleton
43
+ * Throws error if required environment variables are not set
44
+ */
45
+ export declare function getConfig(): SchemaConfig;
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Configuration for schema generation scripts
3
+ * All paths are configurable via environment variables
4
+ * Provides sensible defaults for standard project structure
5
+ */
6
+ import path from 'path';
7
+ /**
8
+ * Get environment variable with optional default
9
+ */
10
+ function getEnv(name, defaultValue) {
11
+ const value = process.env[name];
12
+ return value || defaultValue;
13
+ }
14
+ /**
15
+ * Schema configuration with required environment variables
16
+ */
17
+ export class SchemaConfig {
18
+ constructor() {
19
+ // Environment variables with sensible defaults
20
+ this.root = getEnv('TP_SCHEMA_ROOT', process.cwd());
21
+ this.sourceDir = getEnv('TP_SCHEMA_SOURCE_DIR', 'src/genesis/resourceTypes');
22
+ this.sourceFile = getEnv('TP_SCHEMA_SOURCE_FILE', 'Genesis.json');
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');
26
+ this.baseUrl = getEnv('TP_SCHEMA_BASE_URL', 'https://schemas.toolproof.com');
27
+ this.version = getEnv('TP_SCHEMA_VERSION', 'v0');
28
+ }
29
+ // Path getters
30
+ getRoot() {
31
+ return this.root;
32
+ }
33
+ getSourceDir() {
34
+ return path.isAbsolute(this.sourceDir)
35
+ ? this.sourceDir
36
+ : path.join(this.root, this.sourceDir);
37
+ }
38
+ getSourceFile() {
39
+ return this.sourceFile;
40
+ }
41
+ getSourcePath() {
42
+ return path.join(this.getSourceDir(), this.sourceFile);
43
+ }
44
+ getOutputDir() {
45
+ return path.isAbsolute(this.outputDir)
46
+ ? this.outputDir
47
+ : path.join(this.root, this.outputDir);
48
+ }
49
+ getOutputPath(filename) {
50
+ return path.join(this.getOutputDir(), filename);
51
+ }
52
+ getTypesSrcDir() {
53
+ return path.isAbsolute(this.typesSrcDir)
54
+ ? this.typesSrcDir
55
+ : path.join(this.root, this.typesSrcDir);
56
+ }
57
+ getTypesDistDir() {
58
+ return path.isAbsolute(this.typesDistDir)
59
+ ? this.typesDistDir
60
+ : path.join(this.root, this.typesDistDir);
61
+ }
62
+ getTypesSrcPath(filename) {
63
+ return path.join(this.getTypesSrcDir(), filename);
64
+ }
65
+ getTypesDistPath(filename) {
66
+ return path.join(this.getTypesDistDir(), filename);
67
+ }
68
+ // Schema URL methods
69
+ getBaseUrl() {
70
+ return this.baseUrl;
71
+ }
72
+ getVersion() {
73
+ return this.version;
74
+ }
75
+ getSchemaId(schemaName) {
76
+ return `${this.baseUrl}/${this.version}/${schemaName}.json`;
77
+ }
78
+ /**
79
+ * Check if a URL matches the configured schema base URL pattern
80
+ */
81
+ isSchemaUrl(url) {
82
+ const baseUrlPattern = this.baseUrl.replace('https://', 'https?://');
83
+ return new RegExp(`^${baseUrlPattern}/`, 'i').test(url);
84
+ }
85
+ /**
86
+ * Extract schema name from URL (removes base URL and version prefix)
87
+ */
88
+ extractSchemaName(url) {
89
+ // Remove base URL
90
+ let name = url.replace(new RegExp(`^${this.baseUrl}/`, 'i'), '');
91
+ // Remove version prefix (v0/, v1/, etc.)
92
+ name = name.replace(/^v\d+\//, '');
93
+ // Remove .json extension
94
+ name = name.replace(/\.json$/, '');
95
+ return name;
96
+ }
97
+ }
98
+ // Singleton instance
99
+ let configInstance = null;
100
+ /**
101
+ * Get the schema configuration singleton
102
+ * Throws error if required environment variables are not set
103
+ */
104
+ export function getConfig() {
105
+ if (!configInstance) {
106
+ configInstance = new SchemaConfig();
107
+ }
108
+ return configInstance;
109
+ }
@@ -1,4 +1,4 @@
1
- import type { ExecutionId, ResourceId, WorkStepId, BranchStepId, ForStepId, ResourceFormatId, ResourceTypeId, ResourceRoleId, WhileStepId, WorkflowId, WorkflowSpecId } from "../_lib/types/types.js";
1
+ import type { ExecutionId, ResourceId, WorkStepId, BranchStepId, ForStepId, ResourceFormatId, ResourceTypeId, ResourceRoleId, WhileStepId, StatelessStrategyId, StatefulStrategyId } from "../_lib/types/types.js";
2
2
  /** Generic unsafe brand helper when a bespoke factory is not available. */
3
3
  export declare function unsafeBrand<T extends string>(s: string): T;
4
4
  export declare const asResourceTypeId: (s: string) => string;
@@ -10,8 +10,8 @@ export declare const asBranchStepId: (s: string) => string;
10
10
  export declare const asForStepId: (s: string) => string;
11
11
  export declare const asResourceFormatId: (s: string) => string;
12
12
  export declare const asWhileStepId: (s: string) => string;
13
- export declare const asWorkflowId: (s: string) => string;
14
- export declare const asWorkflowSpecId: (s: string) => string;
13
+ export declare const asStatelessStrategyId: (s: string) => string;
14
+ export declare const asStatefulStrategyId: (s: string) => string;
15
15
  export declare const asResourceTypeIds: (xs: string[]) => ResourceTypeId[];
16
16
  export declare const asResourceRoleIds: (xs: string[]) => ResourceRoleId[];
17
17
  export declare const asExecutionIds: (xs: string[]) => ExecutionId[];
@@ -21,5 +21,5 @@ export declare const asBranchStepIds: (xs: string[]) => BranchStepId[];
21
21
  export declare const asForStepIds: (xs: string[]) => ForStepId[];
22
22
  export declare const asResourceFormatIds: (xs: string[]) => ResourceFormatId[];
23
23
  export declare const asWhileStepIds: (xs: string[]) => WhileStepId[];
24
- export declare const asWorkflowIds: (xs: string[]) => WorkflowId[];
25
- export declare const asWorkflowSpecIds: (xs: string[]) => WorkflowSpecId[];
24
+ export declare const asStatelessStrategyIds: (xs: string[]) => StatelessStrategyId[];
25
+ export declare const asStatefulStrategyIds: (xs: string[]) => StatefulStrategyId[];
@@ -20,7 +20,6 @@ export function unsafeBrand(s) {
20
20
  }
21
21
  // Known patterns from schemas (when available)
22
22
  const RE_TYPE_ID = /^TYPE-.+$/;
23
- const RE_SIGNATURE_ID = /^SIGNATURE-.+$/;
24
23
  const RE_JOB_ID = /^JOB-.+$/;
25
24
  const RE_ROLE_ID = /^ROLE-.+$/;
26
25
  // Factories for each Id-like type
@@ -34,8 +33,8 @@ export const asBranchStepId = makeFactory("BranchStepId");
34
33
  export const asForStepId = makeFactory("ForStepId");
35
34
  export const asResourceFormatId = makeFactory("ResourceFormatId");
36
35
  export const asWhileStepId = makeFactory("WhileStepId");
37
- export const asWorkflowId = makeFactory("WorkflowId");
38
- export const asWorkflowSpecId = makeFactory("WorkflowSpecId");
36
+ export const asStatelessStrategyId = makeFactory("StatelessStrategyId");
37
+ export const asStatefulStrategyId = makeFactory("StatefulStrategyId");
39
38
  // Batch helpers
40
39
  export const asResourceTypeIds = (xs) => xs.map(asResourceTypeId);
41
40
  export const asResourceRoleIds = (xs) => xs.map(asResourceRoleId);
@@ -46,5 +45,5 @@ export const asBranchStepIds = (xs) => xs.map(asBranchStepId);
46
45
  export const asForStepIds = (xs) => xs.map(asForStepId);
47
46
  export const asResourceFormatIds = (xs) => xs.map(asResourceFormatId);
48
47
  export const asWhileStepIds = (xs) => xs.map(asWhileStepId);
49
- export const asWorkflowIds = (xs) => xs.map(asWorkflowId);
50
- export const asWorkflowSpecIds = (xs) => xs.map(asWorkflowSpecId);
48
+ export const asStatelessStrategyIds = (xs) => xs.map(asStatelessStrategyId);
49
+ export const asStatefulStrategyIds = (xs) => xs.map(asStatefulStrategyId);
@@ -1,7 +1,9 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
3
  import { fileURLToPath } from "url";
4
+ import { getConfig } from "./_lib/config.js";
4
5
  function parseArgs() {
6
+ const config = getConfig();
5
7
  const argv = process.argv.slice(2);
6
8
  let inPath = "";
7
9
  let outPath = "";
@@ -12,15 +14,28 @@ function parseArgs() {
12
14
  inPath = argv[++i];
13
15
  else if (a === "--out" && i + 1 < argv.length)
14
16
  outPath = argv[++i];
15
- else if (a === "--id" && i + 1 < argv.length)
16
- topLevelId = argv[++i];
17
+ else if (a === "--id" && i + 1 < argv.length) {
18
+ let v = argv[++i];
19
+ // Strip accidental surrounding quotes from PowerShell/cmd
20
+ if ((v.startsWith("'") && v.endsWith("'")) || (v.startsWith('"') && v.endsWith('"'))) {
21
+ v = v.slice(1, -1);
22
+ }
23
+ topLevelId = v;
24
+ }
25
+ }
26
+ // Use config defaults if not provided via CLI
27
+ if (!inPath) {
28
+ // Use normalized version with anchor refs rewritten to pointers
29
+ inPath = config.getSourcePath().replace('.json', '.normalized.json');
17
30
  }
18
- if (!inPath || !outPath) {
19
- console.error("Usage: node extractSchemas.js --in <Genesis.json> --out <flattened.json> [--id <schemaId>]");
20
- process.exit(1);
31
+ if (!outPath) {
32
+ outPath = config.getOutputPath(config.getSourceFile());
33
+ }
34
+ if (!topLevelId) {
35
+ topLevelId = config.getSchemaId('Genesis');
21
36
  }
22
37
  // Resolve to absolute paths from project root
23
- const cwd = process.cwd();
38
+ const cwd = config.getRoot();
24
39
  const wasInRelative = !path.isAbsolute(inPath);
25
40
  const wasOutRelative = !path.isAbsolute(outPath);
26
41
  if (wasInRelative)
@@ -48,7 +63,10 @@ function parseArgs() {
48
63
  // Heuristic: determine if a node is a Type envelope
49
64
  function isTypeEnvelope(node) {
50
65
  return (node && typeof node === "object" && !Array.isArray(node) &&
51
- typeof node.id === "string" && node.name && node.extractionSchema && typeof node.extractionSchema === "object");
66
+ // Treat any object that has an 'extractionSchema' AND 'identity' as a Type envelope
67
+ // This prevents false positives where 'extractionSchema' is just a regular schema property
68
+ node.extractionSchema && typeof node.extractionSchema === "object" &&
69
+ node.identity && typeof node.identity === "string");
52
70
  }
53
71
  // Merge $defs into target, without overwriting existing keys unless identical
54
72
  function mergeDefs(target, source, label) {
@@ -135,11 +153,18 @@ function main() {
135
153
  // If flattened is not an object (should be rare for a top-level schema), wrap it
136
154
  base = { const: flattened };
137
155
  }
156
+ // Assemble, but avoid duplicating $id: if the flattened base already has $id, prefer it.
138
157
  const output = {
139
158
  $schema: "https://json-schema.org/draft/2020-12/schema",
140
- ...(topLevelId ? { $id: topLevelId } : {}),
141
159
  ...base,
142
160
  };
161
+ if (topLevelId && !output.$id) {
162
+ output.$id = topLevelId;
163
+ }
164
+ // Enforce presence of $id: schema must declare an absolute identity.
165
+ if (!output.$id) {
166
+ throw new Error("Flattened schema must define $id. Provide it via CLI --id or include $id in the source extractionSchema.");
167
+ }
143
168
  // Merge collected defs into output.$defs, taking care not to clobber any existing
144
169
  if (!("$defs" in output))
145
170
  output.$defs = {};
@@ -1,5 +1,6 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
+ import { getConfig } from './_lib/config.js';
3
4
  /**
4
5
  * Generic extractor: given a subschema name that exists under Genesis.json $defs,
5
6
  * produce a standalone JSON Schema file that contains that subschema plus an inner $defs
@@ -10,18 +11,18 @@ import path from 'path';
10
11
  * Usage:
11
12
  * node ./dist/scripts/extractSubschemaWithDefs.js --name <DefName>
12
13
  *
13
- * Writes: src/schemas/<DefName>.json
14
+ * Writes: src/genesis/generated/schemas/<DefName>.json
14
15
  */
15
16
  async function main() {
17
+ const config = getConfig();
16
18
  const { name } = parseArgs(process.argv.slice(2));
17
19
  if (!name) {
18
20
  console.error('Missing --name <DefName> argument');
19
21
  process.exit(1);
20
22
  }
21
- const projectRoot = process.cwd();
22
- const schemasDir = path.join(projectRoot, 'src', 'schemas');
23
- const genesisPath = path.join(schemasDir, 'Genesis.json');
24
- const outPath = path.join(schemasDir, `${name}.json`);
23
+ const schemasDir = config.getOutputDir();
24
+ const genesisPath = path.join(schemasDir, config.getSourceFile());
25
+ const outPath = config.getOutputPath(`${name}.json`);
25
26
  if (!fs.existsSync(genesisPath)) {
26
27
  console.error(`Genesis.json not found at ${genesisPath}`);
27
28
  process.exit(1);
@@ -89,7 +90,7 @@ function deepClone(v) {
89
90
  }
90
91
  return v;
91
92
  }
92
- function extractLocalDefName(ref) {
93
+ function extractPointerDefName(ref) {
93
94
  // Accept refs like '#/$defs/Name' only (single-level under $defs)
94
95
  if (!ref || !ref.startsWith('#/'))
95
96
  return null;
@@ -102,6 +103,34 @@ function extractLocalDefName(ref) {
102
103
  const name = parts[1].replace(/~1/g, '/').replace(/~0/g, '~');
103
104
  return name;
104
105
  }
106
+ function resolveRefToDefName(ref, rootDefs) {
107
+ if (!ref)
108
+ return null;
109
+ // Case 1: JSON Pointer into $defs: '#/$defs/Name'
110
+ const byPointer = extractPointerDefName(ref);
111
+ if (byPointer)
112
+ return byPointer;
113
+ // Case 2: Anchor ref: '#Name' -> find a def whose extractionSchema.$anchor equals 'Name'
114
+ if (ref.startsWith('#') && !ref.startsWith('#/')) {
115
+ const anchor = ref.slice(1);
116
+ if (!anchor)
117
+ return null;
118
+ for (const [defName, defSchema] of Object.entries(rootDefs)) {
119
+ if (!defSchema || typeof defSchema !== 'object')
120
+ continue;
121
+ // Flattened Genesis has defs as the extraction schema itself (with $anchor at the top level).
122
+ // Unflattened may have { extractionSchema: { $anchor } } envelopes. Support both.
123
+ const topLevelAnchor = defSchema.$anchor;
124
+ const nested = defSchema.extractionSchema;
125
+ const nestedAnchor = nested && typeof nested === 'object' ? nested.$anchor : undefined;
126
+ const defAnchor = typeof topLevelAnchor === 'string' ? topLevelAnchor : (typeof nestedAnchor === 'string' ? nestedAnchor : undefined);
127
+ if (defAnchor === anchor) {
128
+ return defName;
129
+ }
130
+ }
131
+ }
132
+ return null;
133
+ }
105
134
  function collectLocalDefClosure(node, rootDefs) {
106
135
  const needed = new Set();
107
136
  const queue = [];
@@ -114,7 +143,7 @@ function collectLocalDefClosure(node, rootDefs) {
114
143
  if (!isObject(n))
115
144
  return;
116
145
  if (typeof n.$ref === 'string') {
117
- const name = extractLocalDefName(n.$ref);
146
+ const name = resolveRefToDefName(n.$ref, rootDefs);
118
147
  if (name && !needed.has(name)) {
119
148
  needed.add(name);
120
149
  queue.push(name);
@@ -0,0 +1,77 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { getConfig } from './_lib/config.js';
4
+ /**
5
+ * Generate Resource envelopes for all ResourceTypes defined in Genesis.json
6
+ *
7
+ * This script wraps each ResourceType definition (from $defs) with a Resource envelope
8
+ * that conforms to the Resource.extractionSchema pattern defined in Genesis.json.
9
+ *
10
+ * For the top-level Genesis ResourceType, extractedData is set to {} to avoid
11
+ * duplicating the entire $defs object.
12
+ *
13
+ * Resource identities follow the pattern RESOURCE-{Name} where Name is the key
14
+ * from the $defs object. Genesis itself uses RESOURCE-Genesis.
15
+ *
16
+ * Usage: node ./dist/scripts/generateResourceEnvelopes.js
17
+ */
18
+ async function main() {
19
+ const config = getConfig();
20
+ // Use normalized version with anchor refs rewritten to pointers
21
+ const genesisSourcePath = config.getSourcePath().replace('.json', '.normalized.json');
22
+ const outputPath = path.join(config.getRoot(), 'src', 'genesis', 'generated', 'resources', 'Genesis.json');
23
+ if (!fs.existsSync(genesisSourcePath)) {
24
+ console.error(`Genesis source file not found at ${genesisSourcePath}`);
25
+ process.exit(1);
26
+ }
27
+ const raw = fs.readFileSync(genesisSourcePath, 'utf-8');
28
+ const genesis = JSON.parse(raw);
29
+ // Validate that this is a ResourceType with extractionSchema
30
+ if (!genesis.extractionSchema || !genesis.extractionSchema.$defs) {
31
+ console.error('Genesis.json must have extractionSchema.$defs');
32
+ process.exit(1);
33
+ }
34
+ const defs = genesis.extractionSchema.$defs;
35
+ const defKeys = Object.keys(defs);
36
+ // Generate Resource envelopes
37
+ const resources = {};
38
+ // Genesis timestamp: 2025-11-30T00:00:00.000Z marks the genesis of ToolProof
39
+ const genesisTimestamp = '2025-11-30T00:00:00.000Z';
40
+ // First entry is Genesis itself with empty extractedData
41
+ resources['Genesis'] = {
42
+ identity: 'RESOURCE-Genesis',
43
+ resourceTypeId: 'TYPE-ResourceType',
44
+ creationContext: {
45
+ resourceRoleId: 'ROLE-Genesis',
46
+ executionId: 'EXECUTION-Genesis'
47
+ },
48
+ kind: 'materialized',
49
+ timestamp: genesisTimestamp,
50
+ extractedData: {}
51
+ };
52
+ // Generate resources for all other $defs
53
+ defKeys.forEach((defName) => {
54
+ const defValue = defs[defName];
55
+ resources[defName] = {
56
+ identity: `RESOURCE-${defName}`,
57
+ resourceTypeId: 'TYPE-ResourceType',
58
+ creationContext: {
59
+ resourceRoleId: 'ROLE-Genesis',
60
+ executionId: `EXECUTION-${defName}`
61
+ },
62
+ kind: 'materialized',
63
+ timestamp: genesisTimestamp,
64
+ extractedData: defValue
65
+ };
66
+ });
67
+ // Ensure output directory exists
68
+ const outputDir = path.dirname(outputPath);
69
+ fs.mkdirSync(outputDir, { recursive: true });
70
+ // Write the generated resources file
71
+ fs.writeFileSync(outputPath, JSON.stringify(resources, null, 4) + '\n', 'utf-8');
72
+ console.log(`Generated ${defKeys.length + 1} Resource envelopes -> ${outputPath}`);
73
+ }
74
+ main().catch((e) => {
75
+ console.error(e);
76
+ process.exit(1);
77
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -1,21 +1,23 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
  import { compileFromFile } from 'json-schema-to-typescript';
4
+ import { getConfig } from './_lib/config.js';
4
5
  /**
5
- * Generate a typed ResourceData variant where `extractedData` is typed to a specific schema
6
- * extracted under `src/schemas/<name>.json`.
6
+ * Generate a typed Resource variant where `extractedData` is typed to a specific schema
7
+ * extracted under the configured output directory.
7
8
  *
8
- * Usage: node ./dist/scripts/generateResourceData_js --name Job
9
+ * Usage: node ./dist/scripts/generateResourceTypeType.js --name Job
9
10
  */
10
11
  async function main() {
12
+ const config = getConfig();
11
13
  const { name } = parseArgs(process.argv.slice(2));
12
14
  if (!name) {
13
15
  console.error('Missing --name <SchemaBasename> argument');
14
16
  process.exit(1);
15
17
  }
16
- const projectRoot = process.cwd();
17
- const schemasDir = path.join(projectRoot, 'src', 'schemas');
18
- const inPath = path.join(schemasDir, `${name}.json`);
18
+ const projectRoot = config.getRoot();
19
+ const schemasDir = config.getOutputDir();
20
+ const inPath = config.getOutputPath(`${name}.json`);
19
21
  if (!fs.existsSync(inPath)) {
20
22
  console.error(`Schema file not found: ${inPath}`);
21
23
  process.exit(1);
@@ -38,21 +40,21 @@ async function main() {
38
40
  console.warn(`Warning: ExtractionSchema usually has type: 'object' but this schema has type: '${parsed.type}'. Proceeding.`);
39
41
  }
40
42
  // Ensure output folder exists
41
- const outDir = path.join(projectRoot, 'src', '_lib', 'types');
43
+ const outDir = config.getTypesSrcDir();
42
44
  fs.mkdirSync(outDir, { recursive: true });
43
- const outName = `ResourceData_${name}.d.ts`;
44
- const outPath = path.join(outDir, outName);
45
- const outJsName = `ResourceData_${name}.js`;
46
- const outJsPath = path.join(outDir, outJsName);
47
- // Build a composite schema in src/schemas so that local $ref paths are simple
48
- const schemasOutDir = path.join(projectRoot, 'src', 'schemas');
49
- const compositePath = path.join(schemasOutDir, `.composite.ResourceData_${name}.json`);
45
+ const outName = `Resource_${name}.d.ts`;
46
+ const outPath = config.getTypesSrcPath(outName);
47
+ const outJsName = `Resource_${name}.js`;
48
+ const outJsPath = config.getTypesSrcPath(outJsName);
49
+ // Build a composite schema in output directory so that local $ref paths are simple
50
+ const schemasOutDir = config.getOutputDir();
51
+ const compositePath = path.join(schemasOutDir, `.composite.Resource_${name}.json`);
50
52
  const compositeSchema = {
51
53
  $schema: 'https://json-schema.org/draft/2020-12/schema',
52
- title: `ResourceData_${name}`,
54
+ title: `Resource_${name}`,
53
55
  type: 'object',
54
56
  allOf: [
55
- { $ref: './Genesis.json#/$defs/ResourceMetaBase' },
57
+ { $ref: `./${config.getSourceFile()}#/$defs/ResourceMetaBase` },
56
58
  {
57
59
  type: 'object',
58
60
  required: ['extractedData'],
@@ -95,10 +97,10 @@ async function main() {
95
97
  console.log(`Wrote ${outJsPath}`);
96
98
  }
97
99
  // Also copy both files into dist so consumers can resolve the module and its types
98
- const distLibDir = path.join(projectRoot, 'dist', '_lib', 'types');
100
+ const distLibDir = config.getTypesDistDir();
99
101
  fs.mkdirSync(distLibDir, { recursive: true });
100
- const distDtsPath = path.join(distLibDir, outName);
101
- const distJsPath = path.join(distLibDir, outJsName);
102
+ const distDtsPath = config.getTypesDistPath(outName);
103
+ const distJsPath = config.getTypesDistPath(outJsName);
102
104
  fs.writeFileSync(distDtsPath, header + ts, 'utf8');
103
105
  fs.writeFileSync(distJsPath, 'export {}\n', 'utf8');
104
106
  console.log(`Wrote ${distDtsPath}`);
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,63 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { getConfig } from './_lib/config.js';
4
+ /**
5
+ * Generate TypeScript shim files for all JSON schemas and resources
6
+ *
7
+ * Creates .ts files that import and re-export .json files using
8
+ * the JSON import assertion syntax. This enables proper dependency resolution
9
+ * and type inference when importing schemas in TypeScript.
10
+ *
11
+ * Generates shims for:
12
+ * - src/genesis/generated/schemas/*.json (schema files)
13
+ * - src/genesis/generated/resources/*.json (resource envelope files)
14
+ *
15
+ * Usage: node ./dist/scripts/generateSchemaShims.js
16
+ */
17
+ async function main() {
18
+ const config = getConfig();
19
+ const schemasDir = config.getOutputDir();
20
+ const resourcesDir = path.join(path.dirname(schemasDir), 'resources');
21
+ // Process schemas directory
22
+ let totalCount = 0;
23
+ if (fs.existsSync(schemasDir)) {
24
+ const files = fs.readdirSync(schemasDir);
25
+ const jsonFiles = files.filter(f => f.endsWith('.json') && !f.startsWith('.'));
26
+ for (const jsonFile of jsonFiles) {
27
+ const baseName = path.basename(jsonFile, '.json');
28
+ const tsFile = `${baseName}.ts`;
29
+ const tsPath = path.join(schemasDir, tsFile);
30
+ const content = `import schema from './${jsonFile}' with { type: 'json' };\nexport default schema;\n`;
31
+ fs.writeFileSync(tsPath, content, 'utf-8');
32
+ console.log(`Generated ${tsFile}`);
33
+ totalCount++;
34
+ }
35
+ console.log(`Generated ${jsonFiles.length} TypeScript schema shims in ${schemasDir}`);
36
+ }
37
+ else {
38
+ console.warn(`Schemas directory not found at ${schemasDir}`);
39
+ }
40
+ // Process resources directory
41
+ if (fs.existsSync(resourcesDir)) {
42
+ const files = fs.readdirSync(resourcesDir);
43
+ const jsonFiles = files.filter(f => f.endsWith('.json') && !f.startsWith('.'));
44
+ for (const jsonFile of jsonFiles) {
45
+ const baseName = path.basename(jsonFile, '.json');
46
+ const tsFile = `${baseName}.ts`;
47
+ const tsPath = path.join(resourcesDir, tsFile);
48
+ const content = `import resources from './${jsonFile}' with { type: 'json' };\nexport default resources;\n`;
49
+ fs.writeFileSync(tsPath, content, 'utf-8');
50
+ console.log(`Generated ${tsFile}`);
51
+ totalCount++;
52
+ }
53
+ console.log(`Generated ${jsonFiles.length} TypeScript resource shims in ${resourcesDir}`);
54
+ }
55
+ else {
56
+ console.warn(`Resources directory not found at ${resourcesDir}`);
57
+ }
58
+ console.log(`Generated ${totalCount} total TypeScript shims`);
59
+ }
60
+ main().catch((e) => {
61
+ console.error(e);
62
+ process.exit(1);
63
+ });