@toolproof-npm/shared 0.1.76 → 0.1.77
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/types.d.ts +19 -0
- package/dist/_lib/types.js +1 -0
- package/dist/_lib/utils/resourceCreation.d.ts +112 -0
- package/dist/_lib/utils/resourceCreation.js +146 -0
- package/dist/_lib/utils/utils.d.ts +24 -0
- package/dist/_lib/utils/utils.js +58 -0
- package/dist/firebaseAdminHelpers.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ExecutionIdentityJson, ResourceIdentityJson, ResourceJson, ResourceRoleIdentityJson, ResourceRoleValueJson, ResourceTypeIdentityJson } from '@toolproof-npm/schema';
|
|
2
|
+
import { CONSTANTS } from '../constants.js';
|
|
3
|
+
export type BucketConst = typeof CONSTANTS.STORAGE.BUCKETS.tp_resources;
|
|
4
|
+
export type CollectionConst = keyof typeof CONSTANTS.STORAGE.COLLECTIONS;
|
|
5
|
+
export type TerminalConst = keyof typeof CONSTANTS.TERMINALS;
|
|
6
|
+
export type StepConst = keyof typeof CONSTANTS.STEPS;
|
|
7
|
+
export type Role = {
|
|
8
|
+
identity: ResourceRoleIdentityJson;
|
|
9
|
+
} & ResourceRoleValueJson;
|
|
10
|
+
export type ResourceMap = Record<ResourceTypeIdentityJson, ResourceJson[]>;
|
|
11
|
+
export type PartialResourceMeta = {
|
|
12
|
+
identity: ResourceIdentityJson;
|
|
13
|
+
resourceTypeRef: ResourceTypeIdentityJson;
|
|
14
|
+
creationContext: {
|
|
15
|
+
resourceRoleRef: ResourceRoleIdentityJson;
|
|
16
|
+
executionRef: ExecutionIdentityJson;
|
|
17
|
+
};
|
|
18
|
+
timestamp?: string;
|
|
19
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { ResourceTypeIdentityJson, ResourceJson, ResourcePotentialOutputJson, JsonDataJson } from '@toolproof-npm/schema';
|
|
2
|
+
/**
|
|
3
|
+
* Generates SHA-256 hash of content
|
|
4
|
+
* @param content The content to hash
|
|
5
|
+
* @returns The SHA-256 hash as hex string
|
|
6
|
+
*/
|
|
7
|
+
export declare function generateContentHash(content: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Generates a content-addressed path for a resource
|
|
10
|
+
* @param resourceTypeRef The resource type reference
|
|
11
|
+
* @param content The content to hash
|
|
12
|
+
* @returns The path in format: {resourceTypeRef}/{contentHash}
|
|
13
|
+
*/
|
|
14
|
+
export declare function generateContentAddressedPath(resourceTypeRef: ResourceTypeIdentityJson, content: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Options for creating a materialized resource from a potential-output
|
|
17
|
+
* Provide either 'path' OR 'content' (which generates a hash-based path)
|
|
18
|
+
*/
|
|
19
|
+
export type CreateMaterializedResourceOptions = Pick<ResourceJson, 'extractedData'> & {
|
|
20
|
+
/** Explicit path (if provided, content is ignored) */
|
|
21
|
+
path?: string;
|
|
22
|
+
/** Content to hash for generating path (used if path not provided) */
|
|
23
|
+
content?: string;
|
|
24
|
+
/** Optional timestamp (defaults to current ISO timestamp) */
|
|
25
|
+
timestamp?: string;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Options for creating a materialized resource from scratch
|
|
29
|
+
* Provide either 'path' OR 'content' (which generates a hash-based path)
|
|
30
|
+
* Omits 'kind' (always set to 'materialized') and makes 'timestamp' optional
|
|
31
|
+
*/
|
|
32
|
+
export type CreateMaterializedResourceFromScratchOptions = Omit<ResourceJson, 'kind' | 'timestamp' | 'path'> & {
|
|
33
|
+
/** Explicit path (if provided, content is ignored) */
|
|
34
|
+
path?: string;
|
|
35
|
+
/** Content to hash for generating path (used if path not provided) */
|
|
36
|
+
content?: string;
|
|
37
|
+
/** Optional timestamp (defaults to current ISO timestamp) */
|
|
38
|
+
timestamp?: string;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Creates a materialized resource from a potential-output resource.
|
|
42
|
+
* Handles timestamp generation, extractedData normalization, path generation, and structural conversion.
|
|
43
|
+
*
|
|
44
|
+
* @param potentialOutput The potential-output resource to materialize
|
|
45
|
+
* @param options Configuration for the materialized resource
|
|
46
|
+
* @returns A fully materialized ResourceJson
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* // With explicit path
|
|
51
|
+
* const materialized = createMaterializedResource(potentialOutput, {
|
|
52
|
+
* path: 'TYPE-Natural/abc123...',
|
|
53
|
+
* extractedData: { identity: 42 },
|
|
54
|
+
* timestamp: '2025-01-03T12:00:00.000Z'
|
|
55
|
+
* });
|
|
56
|
+
*
|
|
57
|
+
* // With content (generates hash-based path)
|
|
58
|
+
* const materialized = createMaterializedResource(potentialOutput, {
|
|
59
|
+
* content: '{"identity": 42}',
|
|
60
|
+
* extractedData: { identity: 42 }
|
|
61
|
+
* });
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare function createMaterializedResource(potentialOutput: ResourcePotentialOutputJson, options: CreateMaterializedResourceOptions): ResourceJson;
|
|
65
|
+
/**
|
|
66
|
+
* Normalizes extractedData to ensure consistent structure with an identity field.
|
|
67
|
+
* Handles various input formats:
|
|
68
|
+
* - Primitives (numbers, strings): wrapped in { identity: value }
|
|
69
|
+
* - Objects with identity: preserved
|
|
70
|
+
* - Objects without identity: identity extracted from first suitable field
|
|
71
|
+
*
|
|
72
|
+
* @param data The raw extracted data
|
|
73
|
+
* @returns Normalized extractedData with identity field
|
|
74
|
+
*/
|
|
75
|
+
export declare function normalizeExtractedData(data: JsonDataJson): JsonDataJson;
|
|
76
|
+
/**
|
|
77
|
+
* Creates a materialized resource from scratch (for manual resource creation).
|
|
78
|
+
* Handles timestamp generation, extractedData normalization, path generation, and structural validation.
|
|
79
|
+
* Use this when creating resources manually without a potential-output template.
|
|
80
|
+
*
|
|
81
|
+
* @param options All required fields for creating a materialized resource
|
|
82
|
+
* @returns A fully materialized ResourceJson
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* // With explicit path
|
|
87
|
+
* const materialized = createMaterializedResourceFromScratch({
|
|
88
|
+
* identity: 'RESOURCE-abc123',
|
|
89
|
+
* resourceTypeRef: 'TYPE-Natural',
|
|
90
|
+
* creationContext: {
|
|
91
|
+
* resourceRoleRef: 'ROLE-Manual',
|
|
92
|
+
* executionRef: 'EXECUTION-Genesis'
|
|
93
|
+
* },
|
|
94
|
+
* path: 'TYPE-Natural/def456...',
|
|
95
|
+
* extractedData: { identity: 42 },
|
|
96
|
+
* timestamp: '2025-01-03T12:00:00.000Z'
|
|
97
|
+
* });
|
|
98
|
+
*
|
|
99
|
+
* // With content (generates hash-based path)
|
|
100
|
+
* const materialized = createMaterializedResourceFromScratch({
|
|
101
|
+
* identity: 'RESOURCE-abc123',
|
|
102
|
+
* resourceTypeRef: 'TYPE-Natural',
|
|
103
|
+
* creationContext: {
|
|
104
|
+
* resourceRoleRef: 'ROLE-Manual',
|
|
105
|
+
* executionRef: 'EXECUTION-Genesis'
|
|
106
|
+
* },
|
|
107
|
+
* content: '{"identity": 42}',
|
|
108
|
+
* extractedData: { identity: 42 }
|
|
109
|
+
* });
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
export declare function createMaterializedResourceFromScratch(options: CreateMaterializedResourceFromScratchOptions): ResourceJson;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { createHash } from 'crypto';
|
|
2
|
+
/**
|
|
3
|
+
* Generates SHA-256 hash of content
|
|
4
|
+
* @param content The content to hash
|
|
5
|
+
* @returns The SHA-256 hash as hex string
|
|
6
|
+
*/
|
|
7
|
+
export function generateContentHash(content) {
|
|
8
|
+
return createHash('sha256').update(content).digest('hex');
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Generates a content-addressed path for a resource
|
|
12
|
+
* @param resourceTypeRef The resource type reference
|
|
13
|
+
* @param content The content to hash
|
|
14
|
+
* @returns The path in format: {resourceTypeRef}/{contentHash}
|
|
15
|
+
*/
|
|
16
|
+
export function generateContentAddressedPath(resourceTypeRef, content) {
|
|
17
|
+
const contentHash = generateContentHash(content);
|
|
18
|
+
return `${resourceTypeRef}/${contentHash}`;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Creates a materialized resource from a potential-output resource.
|
|
22
|
+
* Handles timestamp generation, extractedData normalization, path generation, and structural conversion.
|
|
23
|
+
*
|
|
24
|
+
* @param potentialOutput The potential-output resource to materialize
|
|
25
|
+
* @param options Configuration for the materialized resource
|
|
26
|
+
* @returns A fully materialized ResourceJson
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* // With explicit path
|
|
31
|
+
* const materialized = createMaterializedResource(potentialOutput, {
|
|
32
|
+
* path: 'TYPE-Natural/abc123...',
|
|
33
|
+
* extractedData: { identity: 42 },
|
|
34
|
+
* timestamp: '2025-01-03T12:00:00.000Z'
|
|
35
|
+
* });
|
|
36
|
+
*
|
|
37
|
+
* // With content (generates hash-based path)
|
|
38
|
+
* const materialized = createMaterializedResource(potentialOutput, {
|
|
39
|
+
* content: '{"identity": 42}',
|
|
40
|
+
* extractedData: { identity: 42 }
|
|
41
|
+
* });
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export function createMaterializedResource(potentialOutput, options) {
|
|
45
|
+
const { path, content, extractedData, timestamp } = options;
|
|
46
|
+
// Determine path: use explicit path or generate from content
|
|
47
|
+
const finalPath = path ?? (content ? generateContentAddressedPath(potentialOutput.resourceTypeRef, content) : '');
|
|
48
|
+
if (!finalPath) {
|
|
49
|
+
throw new Error('Either path or content must be provided');
|
|
50
|
+
}
|
|
51
|
+
// Normalize extractedData to ensure it has an identity field
|
|
52
|
+
const normalizedExtractedData = normalizeExtractedData(extractedData);
|
|
53
|
+
return {
|
|
54
|
+
identity: potentialOutput.identity,
|
|
55
|
+
resourceTypeRef: potentialOutput.resourceTypeRef,
|
|
56
|
+
creationContext: potentialOutput.creationContext,
|
|
57
|
+
kind: 'materialized',
|
|
58
|
+
path: finalPath,
|
|
59
|
+
timestamp: timestamp ?? new Date().toISOString(),
|
|
60
|
+
extractedData: normalizedExtractedData,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Normalizes extractedData to ensure consistent structure with an identity field.
|
|
65
|
+
* Handles various input formats:
|
|
66
|
+
* - Primitives (numbers, strings): wrapped in { identity: value }
|
|
67
|
+
* - Objects with identity: preserved
|
|
68
|
+
* - Objects without identity: identity extracted from first suitable field
|
|
69
|
+
*
|
|
70
|
+
* @param data The raw extracted data
|
|
71
|
+
* @returns Normalized extractedData with identity field
|
|
72
|
+
*/
|
|
73
|
+
export function normalizeExtractedData(data) {
|
|
74
|
+
// If data is a primitive, wrap it
|
|
75
|
+
if (typeof data !== 'object' || data === null) {
|
|
76
|
+
return { identity: data };
|
|
77
|
+
}
|
|
78
|
+
// If data is an object
|
|
79
|
+
const dataObj = data;
|
|
80
|
+
// If it already has an identity field, preserve everything
|
|
81
|
+
if ('identity' in dataObj) {
|
|
82
|
+
return data;
|
|
83
|
+
}
|
|
84
|
+
// Otherwise, try to extract an identity value from common patterns
|
|
85
|
+
// This handles cases where the data might have a value field or similar
|
|
86
|
+
const identityValue = dataObj.value ?? dataObj.id ?? dataObj.result ?? 0;
|
|
87
|
+
return {
|
|
88
|
+
identity: identityValue,
|
|
89
|
+
...dataObj,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Creates a materialized resource from scratch (for manual resource creation).
|
|
94
|
+
* Handles timestamp generation, extractedData normalization, path generation, and structural validation.
|
|
95
|
+
* Use this when creating resources manually without a potential-output template.
|
|
96
|
+
*
|
|
97
|
+
* @param options All required fields for creating a materialized resource
|
|
98
|
+
* @returns A fully materialized ResourceJson
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* // With explicit path
|
|
103
|
+
* const materialized = createMaterializedResourceFromScratch({
|
|
104
|
+
* identity: 'RESOURCE-abc123',
|
|
105
|
+
* resourceTypeRef: 'TYPE-Natural',
|
|
106
|
+
* creationContext: {
|
|
107
|
+
* resourceRoleRef: 'ROLE-Manual',
|
|
108
|
+
* executionRef: 'EXECUTION-Genesis'
|
|
109
|
+
* },
|
|
110
|
+
* path: 'TYPE-Natural/def456...',
|
|
111
|
+
* extractedData: { identity: 42 },
|
|
112
|
+
* timestamp: '2025-01-03T12:00:00.000Z'
|
|
113
|
+
* });
|
|
114
|
+
*
|
|
115
|
+
* // With content (generates hash-based path)
|
|
116
|
+
* const materialized = createMaterializedResourceFromScratch({
|
|
117
|
+
* identity: 'RESOURCE-abc123',
|
|
118
|
+
* resourceTypeRef: 'TYPE-Natural',
|
|
119
|
+
* creationContext: {
|
|
120
|
+
* resourceRoleRef: 'ROLE-Manual',
|
|
121
|
+
* executionRef: 'EXECUTION-Genesis'
|
|
122
|
+
* },
|
|
123
|
+
* content: '{"identity": 42}',
|
|
124
|
+
* extractedData: { identity: 42 }
|
|
125
|
+
* });
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
export function createMaterializedResourceFromScratch(options) {
|
|
129
|
+
const { identity, resourceTypeRef, creationContext, path, content, extractedData, timestamp } = options;
|
|
130
|
+
// Determine path: use explicit path or generate from content
|
|
131
|
+
const finalPath = path ?? (content ? generateContentAddressedPath(resourceTypeRef, content) : '');
|
|
132
|
+
if (!finalPath) {
|
|
133
|
+
throw new Error('Either path or content must be provided');
|
|
134
|
+
}
|
|
135
|
+
// Normalize extractedData to ensure it has an identity field
|
|
136
|
+
const normalizedExtractedData = normalizeExtractedData(extractedData);
|
|
137
|
+
return {
|
|
138
|
+
identity,
|
|
139
|
+
resourceTypeRef,
|
|
140
|
+
creationContext,
|
|
141
|
+
kind: 'materialized',
|
|
142
|
+
path: finalPath,
|
|
143
|
+
timestamp: timestamp ?? new Date().toISOString(),
|
|
144
|
+
extractedData: normalizedExtractedData,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ResourceIdentityJson, ResourceTypeIdentityJson, ResourceJson, ResourceMissingJson, JobJson, ResourcePotentialOutputJson, StrategyStateJson, CreationContextJson } from '@toolproof-npm/schema';
|
|
2
|
+
import type { ResourceMap } from '../types.js';
|
|
3
|
+
export declare function extractResourcesByType(resourceMap: ResourceMap, resourceTypeRef: ResourceTypeIdentityJson): Record<ResourceIdentityJson, ResourceJson>;
|
|
4
|
+
export declare function extractJobMap(resourceMap: ResourceMap): Map<`JOB-${string}`, JobJson>;
|
|
5
|
+
export type ResolveResult = {
|
|
6
|
+
status: 'materialized';
|
|
7
|
+
entry: ResourceJson;
|
|
8
|
+
path: CreationContextJson[];
|
|
9
|
+
} | {
|
|
10
|
+
status: 'missing';
|
|
11
|
+
entry: ResourceMissingJson;
|
|
12
|
+
path: CreationContextJson[];
|
|
13
|
+
} | {
|
|
14
|
+
status: 'blocked-output';
|
|
15
|
+
entry: ResourcePotentialOutputJson;
|
|
16
|
+
path: CreationContextJson[];
|
|
17
|
+
} | {
|
|
18
|
+
status: 'unresolved';
|
|
19
|
+
reason: 'missing-entry' | 'cycle' | 'depth-exceeded';
|
|
20
|
+
path: CreationContextJson[];
|
|
21
|
+
};
|
|
22
|
+
export declare function resolveResourceChain(strategyState: StrategyStateJson, start: CreationContextJson, opts?: {
|
|
23
|
+
maxDepth?: number;
|
|
24
|
+
}): ResolveResult;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export function extractResourcesByType(resourceMap, resourceTypeRef) {
|
|
2
|
+
const resources = resourceMap[resourceTypeRef] ?? [];
|
|
3
|
+
const result = {};
|
|
4
|
+
for (const resource of resources) {
|
|
5
|
+
result[resource.identity] = resource;
|
|
6
|
+
}
|
|
7
|
+
return result;
|
|
8
|
+
}
|
|
9
|
+
export function extractJobMap(resourceMap) {
|
|
10
|
+
const resourceJobMap = extractResourcesByType(resourceMap, 'TYPE-Job');
|
|
11
|
+
const jobMap = new Map();
|
|
12
|
+
Object.values(resourceJobMap).forEach((resource) => {
|
|
13
|
+
if (resource.extractedData?.identity) {
|
|
14
|
+
jobMap.set(resource.extractedData.identity, resource.extractedData); // ATTENTION: why do we need type assertion here?
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
return jobMap;
|
|
18
|
+
}
|
|
19
|
+
export function resolveResourceChain(strategyState, start, opts) {
|
|
20
|
+
const maxDepth = opts?.maxDepth ?? 50;
|
|
21
|
+
const visited = new Set();
|
|
22
|
+
const path = [];
|
|
23
|
+
let current = start;
|
|
24
|
+
for (let depth = 0; depth <= maxDepth; depth++) {
|
|
25
|
+
path.push(current);
|
|
26
|
+
const visitKey = `${current.executionRef}::${current.resourceRoleRef}`;
|
|
27
|
+
if (visited.has(visitKey)) {
|
|
28
|
+
return { status: 'unresolved', reason: 'cycle', path };
|
|
29
|
+
}
|
|
30
|
+
visited.add(visitKey);
|
|
31
|
+
const bucket = strategyState[current.executionRef];
|
|
32
|
+
if (!bucket)
|
|
33
|
+
return { status: 'unresolved', reason: 'missing-entry', path };
|
|
34
|
+
const entry = bucket[current.resourceRoleRef];
|
|
35
|
+
if (!entry)
|
|
36
|
+
return { status: 'unresolved', reason: 'missing-entry', path };
|
|
37
|
+
if (entry.kind === 'materialized') {
|
|
38
|
+
return { status: 'materialized', entry: entry, path };
|
|
39
|
+
}
|
|
40
|
+
if (entry.kind === 'missing') {
|
|
41
|
+
return { status: 'missing', entry: entry, path };
|
|
42
|
+
}
|
|
43
|
+
if (entry.kind === 'potential-output') {
|
|
44
|
+
return { status: 'blocked-output', entry: entry, path };
|
|
45
|
+
}
|
|
46
|
+
// potential-input: follow ref backwards
|
|
47
|
+
if (entry.kind === 'potential-input') {
|
|
48
|
+
const rpi = entry.creationContext;
|
|
49
|
+
if (!rpi)
|
|
50
|
+
return { status: 'unresolved', reason: 'missing-entry', path };
|
|
51
|
+
current = rpi;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
// Unknown case
|
|
55
|
+
return { status: 'unresolved', reason: 'missing-entry', path };
|
|
56
|
+
}
|
|
57
|
+
return { status: 'unresolved', reason: 'depth-exceeded', path };
|
|
58
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ResourceTypeIdentityJson } from '@toolproof-npm/schema';
|
|
2
|
-
import type { StepConst, ResourceMap, TerminalConst } from './types.
|
|
2
|
+
import type { StepConst, ResourceMap, TerminalConst } from './_lib/types.js';
|
|
3
3
|
export declare function getNewIdentity(identifiable: TerminalConst | StepConst): string;
|
|
4
4
|
export declare function listResources(// ATTENTION: must clean up
|
|
5
5
|
resourceTypeRefs: ResourceTypeIdentityJson[]): Promise<ResourceMap>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * as CONSTANTS from './constants.js';
|
|
2
|
-
export * as TYPES from './types.js';
|
|
3
|
-
export * as UTILS from './utils.js';
|
|
2
|
+
export * as TYPES from './_lib/types.js';
|
|
3
|
+
export * as UTILS from './_lib/utils/utils.js';
|
|
4
4
|
export * from './firebaseAdminHelpers.js';
|
|
5
5
|
export * from './firebaseAdminInit.js';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * as CONSTANTS from './constants.js';
|
|
2
|
-
export * as TYPES from './types.js';
|
|
3
|
-
export * as UTILS from './utils.js';
|
|
2
|
+
export * as TYPES from './_lib/types.js';
|
|
3
|
+
export * as UTILS from './_lib/utils/utils.js';
|
|
4
4
|
export * from './firebaseAdminHelpers.js';
|
|
5
5
|
export * from './firebaseAdminInit.js';
|