@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.
- package/dist/_lib/test.js +12 -12
- package/dist/_lib/types/Resource_Job.d.ts +55 -0
- package/dist/_lib/types/Resource_ResourceFormat.d.ts +40 -0
- package/dist/_lib/types/Resource_ResourceFormat.js +1 -0
- package/dist/_lib/types/Resource_ResourceType.d.ts +60 -0
- package/dist/_lib/types/Resource_ResourceType.js +1 -0
- package/dist/_lib/types/Resource_StatelessStrategy.d.ts +79 -0
- package/dist/_lib/types/Resource_StatelessStrategy.js +1 -0
- package/dist/_lib/types/types.d.ts +491 -353
- package/dist/genesis/generated/resources/Genesis.d.ts +2 -0
- package/dist/genesis/generated/resources/Genesis.js +2 -0
- package/dist/genesis/generated/resources/Genesis.json +2113 -0
- package/dist/{schemas → genesis/generated/schemas}/Genesis.json +266 -345
- package/dist/{schemas → genesis/generated/schemas}/Job.json +24 -26
- package/dist/genesis/generated/schemas/ResourceFormat.d.ts +2 -0
- package/dist/genesis/generated/schemas/ResourceFormat.js +2 -0
- package/dist/genesis/generated/schemas/ResourceFormat.json +74 -0
- package/dist/genesis/generated/schemas/ResourceType.d.ts +2 -0
- package/dist/genesis/generated/schemas/ResourceType.js +2 -0
- package/dist/genesis/generated/schemas/ResourceType.json +361 -0
- package/dist/genesis/generated/schemas/StatefulStrategy.d.ts +2 -0
- package/dist/genesis/generated/schemas/StatefulStrategy.js +2 -0
- package/dist/genesis/generated/schemas/StatefulStrategy.json +647 -0
- package/dist/genesis/generated/schemas/StatelessStrategy.d.ts +2 -0
- package/dist/genesis/generated/schemas/StatelessStrategy.js +2 -0
- package/dist/genesis/generated/schemas/StatelessStrategy.json +324 -0
- package/dist/genesis/resourceTypes/Genesis.d.ts +2 -0
- package/dist/genesis/resourceTypes/Genesis.js +2 -0
- package/dist/genesis/resourceTypes/Genesis.json +1523 -0
- package/dist/index.d.ts +8 -5
- package/dist/index.js +4 -3
- package/dist/scripts/_lib/config.d.ts +45 -0
- package/dist/scripts/_lib/config.js +109 -0
- package/dist/scripts/brandFactories.d.ts +5 -5
- package/dist/scripts/brandFactories.js +4 -5
- package/dist/scripts/extractSchemas.js +33 -8
- package/dist/scripts/extractSubschemaWithDefs.js +36 -7
- package/dist/scripts/generateResourceEnvelopes.js +77 -0
- package/dist/scripts/generateResourceTypeType.d.ts +1 -0
- package/dist/scripts/{generateResourceData.js → generateResourceTypeType.js} +21 -19
- package/dist/scripts/generateSchemaShims.d.ts +1 -0
- package/dist/scripts/generateSchemaShims.js +63 -0
- package/dist/scripts/generateTypes.js +116 -83
- package/dist/scripts/rewriteAnchors.d.ts +1 -0
- package/dist/scripts/rewriteAnchors.js +90 -0
- package/package.json +50 -52
- package/dist/_lib/types/ResourceData_Job.d.ts +0 -97
- /package/dist/_lib/types/{ResourceData_Job.js → Resource_Job.js} +0 -0
- /package/dist/{schemas → genesis/generated/schemas}/Genesis.d.ts +0 -0
- /package/dist/{schemas → genesis/generated/schemas}/Genesis.js +0 -0
- /package/dist/{schemas → genesis/generated/schemas}/Job.d.ts +0 -0
- /package/dist/{schemas → genesis/generated/schemas}/Job.js +0 -0
- /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
|
|
3
|
-
export
|
|
4
|
-
export type {
|
|
5
|
-
export {
|
|
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
|
|
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,
|
|
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,
|
|
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
|
|
14
|
-
export declare const
|
|
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
|
|
25
|
-
export declare const
|
|
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
|
|
38
|
-
export const
|
|
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
|
|
50
|
-
export const
|
|
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
|
-
|
|
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 (!
|
|
19
|
-
|
|
20
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
|
22
|
-
const
|
|
23
|
-
const
|
|
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
|
|
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 =
|
|
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
|
|
6
|
-
* extracted under
|
|
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/
|
|
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 =
|
|
17
|
-
const schemasDir =
|
|
18
|
-
const inPath =
|
|
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 =
|
|
43
|
+
const outDir = config.getTypesSrcDir();
|
|
42
44
|
fs.mkdirSync(outDir, { recursive: true });
|
|
43
|
-
const outName = `
|
|
44
|
-
const outPath =
|
|
45
|
-
const outJsName = `
|
|
46
|
-
const outJsPath =
|
|
47
|
-
// Build a composite schema in
|
|
48
|
-
const schemasOutDir =
|
|
49
|
-
const compositePath = path.join(schemasOutDir, `.composite.
|
|
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: `
|
|
54
|
+
title: `Resource_${name}`,
|
|
53
55
|
type: 'object',
|
|
54
56
|
allOf: [
|
|
55
|
-
{ $ref:
|
|
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 =
|
|
100
|
+
const distLibDir = config.getTypesDistDir();
|
|
99
101
|
fs.mkdirSync(distLibDir, { recursive: true });
|
|
100
|
-
const distDtsPath =
|
|
101
|
-
const distJsPath =
|
|
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
|
+
});
|