@toolproof-npm/shared 0.1.113 → 0.1.115

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.
@@ -2,7 +2,7 @@ import type { ResourceJson, ResourceRoleIdentityJson, ResourceRoleValueJson, Res
2
2
  import { CONSTANTS } from '../constants.js';
3
3
  export type BucketConst = typeof CONSTANTS.STORAGE.BUCKETS.tp_resources;
4
4
  export type CollectionConst = keyof typeof CONSTANTS.STORAGE.COLLECTIONS;
5
- export type TerminalConst = keyof typeof CONSTANTS.TERMINALS;
5
+ export type IdentityPrefix = keyof typeof CONSTANTS.IDENTITY_PREFIXES;
6
6
  export type StepConst = keyof typeof CONSTANTS.STEPS;
7
7
  export type Role = {
8
8
  identity: ResourceRoleIdentityJson;
@@ -1,5 +1,5 @@
1
1
  import { CONSTANTS } from '@toolproof-npm/shared/constants';
2
- import { getNewIdentity } from '@toolproof-npm/shared/server';
2
+ import { getNewIdentity, getNewStepIdentity, getExecutionRefFromWorkStepIdentity } from '@toolproof-npm/shared/server';
3
3
  function assertNonEmpty(arr, msg) {
4
4
  if (arr.length === 0)
5
5
  throw new Error(msg);
@@ -7,24 +7,24 @@ function assertNonEmpty(arr, msg) {
7
7
  const mintNewRoleBindingMap = async (existingMap) => {
8
8
  const newMap = {};
9
9
  await Promise.all(Object.keys(existingMap).map(async (resourceRoleRef) => {
10
- const resourceId = await getNewIdentity(CONSTANTS.TERMINALS.resource);
10
+ const resourceId = await getNewIdentity(CONSTANTS.IDENTITY_PREFIXES.resource);
11
11
  newMap[resourceRoleRef] = resourceId;
12
12
  }));
13
13
  return newMap;
14
14
  };
15
15
  // DOC: Helper function to construct an Execution object from a job
16
16
  const createExecutionFromJob = async (job, executionRef) => {
17
- const execIdentity = executionRef ?? await getNewIdentity(CONSTANTS.TERMINALS.execution);
17
+ const execIdentity = executionRef ?? await getNewIdentity(CONSTANTS.IDENTITY_PREFIXES.execution);
18
18
  const inputBindingMap = {};
19
19
  const inputs = job.roles.inputMap;
20
20
  await Promise.all(Object.keys(inputs).map(async (resourceRoleRef) => {
21
- const resourceId = await getNewIdentity(CONSTANTS.TERMINALS.resource);
21
+ const resourceId = await getNewIdentity(CONSTANTS.IDENTITY_PREFIXES.resource);
22
22
  inputBindingMap[resourceRoleRef] = resourceId;
23
23
  }));
24
24
  const outputBindingMap = {};
25
25
  const outputs = job.roles.outputMap;
26
26
  await Promise.all(Object.keys(outputs).map(async (resourceRoleRef) => {
27
- const resourceId = await getNewIdentity(CONSTANTS.TERMINALS.resource);
27
+ const resourceId = await getNewIdentity(CONSTANTS.IDENTITY_PREFIXES.resource);
28
28
  outputBindingMap[resourceRoleRef] = resourceId;
29
29
  }));
30
30
  return {
@@ -38,8 +38,8 @@ const createExecutionFromJob = async (job, executionRef) => {
38
38
  };
39
39
  // DOC: Helper function to construct a WorkStep object from an jobMetaJson (does not append to statelessStrategy.steps)
40
40
  export const createWorkStepFromJob = async (job) => {
41
- const workStepIdentity = await getNewIdentity(CONSTANTS.STEPS.work);
42
- const executionRef = workStepIdentity.replace(CONSTANTS.STEPS.work.toUpperCase(), 'execution'.toUpperCase()); // ATTENTION: use function
41
+ const workStepIdentity = await getNewStepIdentity(CONSTANTS.STEPS.work);
42
+ const executionRef = getExecutionRefFromWorkStepIdentity(workStepIdentity);
43
43
  const execution = await createExecutionFromJob(job, executionRef);
44
44
  const newWorkStep = {
45
45
  identity: workStepIdentity,
@@ -56,8 +56,8 @@ export const createLoopStepFromJob = async (whatJob, whenJob, kind) => {
56
56
  const whenWorkStep = await createWorkStepFromJob(whenJob);
57
57
  // Generate loop step identity based on kind
58
58
  const stepIdentity = (kind === 'for'
59
- ? await getNewIdentity(CONSTANTS.STEPS.for)
60
- : await getNewIdentity(CONSTANTS.STEPS.while));
59
+ ? await getNewStepIdentity(CONSTANTS.STEPS.for)
60
+ : await getNewStepIdentity(CONSTANTS.STEPS.while));
61
61
  // Assemble the loop step
62
62
  return {
63
63
  identity: stepIdentity,
@@ -71,7 +71,7 @@ export const createLoopStepFromJob = async (whatJob, whenJob, kind) => {
71
71
  // DOC: Helper function to construct a BranchStep from an array of job pairs
72
72
  export const createBranchStepFromJobPairs = async (cases) => {
73
73
  // Generate branch step identity
74
- const branchStepIdentity = await getNewIdentity(CONSTANTS.STEPS.branch);
74
+ const branchStepIdentity = await getNewStepIdentity(CONSTANTS.STEPS.branch);
75
75
  // Create WorkSteps for each case (what and when pair)
76
76
  const casesWithWorkSteps = await Promise.all(cases.map(async ({ whatJob, whenJob }) => {
77
77
  const whatWorkStep = await createWorkStepFromJob(whatJob);
@@ -95,11 +95,11 @@ export const createBranchStepFromJobPairs = async (cases) => {
95
95
  // DOC: Helper function to clone a ForStep with new identities for steps and executions, preserving job references and bindings
96
96
  export const cloneForStep = async (forStep) => {
97
97
  // Generate new ForStep identity
98
- const newForStepIdentity = await getNewIdentity(CONSTANTS.STEPS.for);
98
+ const newForStepIdentity = await getNewStepIdentity(CONSTANTS.STEPS.for);
99
99
  // Clone the "what" WorkStep
100
100
  const originalWhatWorkStep = forStep.case.what;
101
- const newWhatWorkStepIdentity = await getNewIdentity(CONSTANTS.STEPS.work);
102
- const newWhatExecutionIdentity = newWhatWorkStepIdentity.replace(CONSTANTS.STEPS.work.toUpperCase(), 'execution'.toUpperCase());
101
+ const newWhatWorkStepIdentity = await getNewStepIdentity(CONSTANTS.STEPS.work);
102
+ const newWhatExecutionIdentity = getExecutionRefFromWorkStepIdentity(newWhatWorkStepIdentity);
103
103
  const newWhatExecution = {
104
104
  identity: newWhatExecutionIdentity,
105
105
  jobRef: originalWhatWorkStep.execution.jobRef,
@@ -115,8 +115,8 @@ export const cloneForStep = async (forStep) => {
115
115
  };
116
116
  // Clone the "when" WorkStep
117
117
  const originalWhenWorkStep = forStep.case.when;
118
- const newWhenWorkStepIdentity = await getNewIdentity(CONSTANTS.STEPS.work);
119
- const newWhenExecutionIdentity = newWhenWorkStepIdentity.replace(CONSTANTS.STEPS.work.toUpperCase(), 'execution'.toUpperCase());
118
+ const newWhenWorkStepIdentity = await getNewStepIdentity(CONSTANTS.STEPS.work);
119
+ const newWhenExecutionIdentity = getExecutionRefFromWorkStepIdentity(newWhenWorkStepIdentity);
120
120
  const newWhenExecution = {
121
121
  identity: newWhenExecutionIdentity,
122
122
  jobRef: originalWhenWorkStep.execution.jobRef,
@@ -143,11 +143,11 @@ export const cloneForStep = async (forStep) => {
143
143
  // DOC: Helper function to clone a WhileStep with new identities for steps and executions, preserving job references and bindings
144
144
  export const cloneWhileStep = async (whileStep) => {
145
145
  // Generate new WhileStep identity
146
- const newWhileStepIdentity = await getNewIdentity(CONSTANTS.STEPS.while);
146
+ const newWhileStepIdentity = await getNewStepIdentity(CONSTANTS.STEPS.while);
147
147
  // Clone the "what" WorkStep
148
148
  const originalWhatWorkStep = whileStep.case.what;
149
- const newWhatWorkStepIdentity = await getNewIdentity(CONSTANTS.STEPS.work);
150
- const newWhatExecutionIdentity = newWhatWorkStepIdentity.replace(CONSTANTS.STEPS.work.toUpperCase(), 'execution'.toUpperCase());
149
+ const newWhatWorkStepIdentity = await getNewStepIdentity(CONSTANTS.STEPS.work);
150
+ const newWhatExecutionIdentity = getExecutionRefFromWorkStepIdentity(newWhatWorkStepIdentity);
151
151
  const newWhatExecution = {
152
152
  identity: newWhatExecutionIdentity,
153
153
  jobRef: originalWhatWorkStep.execution.jobRef,
@@ -163,8 +163,8 @@ export const cloneWhileStep = async (whileStep) => {
163
163
  };
164
164
  // Clone the "when" WorkStep
165
165
  const originalWhenWorkStep = whileStep.case.when;
166
- const newWhenWorkStepIdentity = await getNewIdentity(CONSTANTS.STEPS.work);
167
- const newWhenExecutionIdentity = newWhenWorkStepIdentity.replace(CONSTANTS.STEPS.work.toUpperCase(), 'execution'.toUpperCase());
166
+ const newWhenWorkStepIdentity = await getNewStepIdentity(CONSTANTS.STEPS.work);
167
+ const newWhenExecutionIdentity = getExecutionRefFromWorkStepIdentity(newWhenWorkStepIdentity);
168
168
  const newWhenExecution = {
169
169
  identity: newWhenExecutionIdentity,
170
170
  jobRef: originalWhenWorkStep.execution.jobRef,
@@ -191,7 +191,7 @@ export const cloneWhileStep = async (whileStep) => {
191
191
  // DOC: Helper function to clone a BranchStep with a new identity, optionally overriding its cases.
192
192
  // Note: We intentionally do NOT clone executions/steps here because BranchStep (Option A) does not repeat cases.
193
193
  export const cloneBranchStep = async (branchStep, casesOverride) => {
194
- const newBranchStepIdentity = await getNewIdentity(CONSTANTS.STEPS.branch);
194
+ const newBranchStepIdentity = await getNewStepIdentity(CONSTANTS.STEPS.branch);
195
195
  const cases = casesOverride ?? branchStep.cases;
196
196
  const priorCanonical = branchStep.canonicalWhatExecutionRef;
197
197
  const canonicalStillExists = priorCanonical
@@ -1,6 +1,6 @@
1
1
  import type { ExecutionJson, StatefulStrategyJson, StrategyRunJson, StrategyRunStatusJson, StrategyStateJson } from '@toolproof-npm/schema';
2
- import type { TerminalConst } from '../types.js';
3
- export type GetNewIdentity = (identifiable: TerminalConst) => string | Promise<string>;
2
+ import type { IdentityPrefix } from '../types.js';
3
+ export type GetNewIdentity = (identifiable: IdentityPrefix) => string | Promise<string>;
4
4
  export declare function normalizeExecutionInputBindingMap(execution: ExecutionJson, strategyState: StrategyStateJson): ExecutionJson;
5
5
  export declare function createStrategyRun(statefulStrategy: StatefulStrategyJson, opts?: {
6
6
  getNewIdentity: GetNewIdentity;
@@ -172,14 +172,14 @@ export async function createStrategyRun(statefulStrategy, opts) {
172
172
  // Normalize roleBindings.inputBindingMap to reflect the identities present in strategyState.
173
173
  // This is intentionally a pure transformation (no mutation of the provided statefulStrategy object graph).
174
174
  const normalizedStatefulStrategy = normalizeStatefulStrategyInputBindingMaps(statefulStrategy);
175
- const strategyRunIdentity = (await opts.getNewIdentity(CONSTANTS.TERMINALS.strategy_run));
175
+ const strategyRunIdentity = (await opts.getNewIdentity(CONSTANTS.IDENTITY_PREFIXES.strategy_run));
176
176
  const steps = normalizedStatefulStrategy.statelessStrategy?.steps ?? [];
177
177
  const strategyState = (normalizedStatefulStrategy.strategyState ?? {});
178
178
  // Algorithm to find what steps can run in parallel
179
179
  const threadStepsGroups = getIndependentThreads(steps, strategyState);
180
180
  const strategyThreadMap = {};
181
181
  for (const group of threadStepsGroups) {
182
- const threadIdentity = await opts.getNewIdentity(CONSTANTS.TERMINALS.strategy_thread);
182
+ const threadIdentity = await opts.getNewIdentity(CONSTANTS.IDENTITY_PREFIXES.strategy_thread);
183
183
  strategyThreadMap[threadIdentity] = group;
184
184
  }
185
185
  return {
@@ -15,7 +15,7 @@ export declare const CONSTANTS: {
15
15
  readonly members: "members";
16
16
  };
17
17
  };
18
- readonly TERMINALS: {
18
+ readonly IDENTITY_PREFIXES: {
19
19
  readonly format: "format";
20
20
  readonly type: "type";
21
21
  readonly role: "role";
@@ -33,6 +33,18 @@ export declare const CONSTANTS: {
33
33
  readonly while: "while";
34
34
  readonly for: "for";
35
35
  };
36
+ readonly STEP_IDENTITY_PREFIXES: {
37
+ readonly workstep: "workstep";
38
+ readonly branchstep: "branchstep";
39
+ readonly forstep: "forstep";
40
+ readonly whilestep: "whilestep";
41
+ };
42
+ readonly STEP_IDENTITY_PREFIX_BY_KIND: {
43
+ readonly work: "workstep";
44
+ readonly branch: "branchstep";
45
+ readonly for: "forstep";
46
+ readonly while: "whilestep";
47
+ };
36
48
  readonly ENGINE: {
37
49
  readonly GraphRunStrategy: "GraphRunStrategy";
38
50
  };
package/dist/constants.js CHANGED
@@ -15,7 +15,7 @@ export const CONSTANTS = {
15
15
  members: 'members',
16
16
  },
17
17
  },
18
- TERMINALS: {
18
+ IDENTITY_PREFIXES: {
19
19
  format: 'format',
20
20
  type: 'type',
21
21
  role: 'role',
@@ -33,6 +33,18 @@ export const CONSTANTS = {
33
33
  while: 'while',
34
34
  for: 'for',
35
35
  },
36
+ STEP_IDENTITY_PREFIXES: {
37
+ workstep: 'workstep',
38
+ branchstep: 'branchstep',
39
+ forstep: 'forstep',
40
+ whilestep: 'whilestep',
41
+ },
42
+ STEP_IDENTITY_PREFIX_BY_KIND: {
43
+ work: 'workstep',
44
+ branch: 'branchstep',
45
+ for: 'forstep',
46
+ while: 'whilestep',
47
+ },
36
48
  ENGINE: {
37
49
  GraphRunStrategy: 'GraphRunStrategy',
38
50
  },
@@ -1,5 +1,17 @@
1
- import type { ResourceTypeIdentityJson } from '@toolproof-npm/schema';
2
- import type { StepConst, ResourceMap, TerminalConst } from './_lib/types.js';
3
- export declare function getNewIdentity(identifiable: TerminalConst | StepConst): string;
1
+ import type { BranchStepIdentityJson, ExecutionIdentityJson, ForStepIdentityJson, IdentityByPrefix, ResourceTypeIdentityJson, WhileStepIdentityJson, WorkStepIdentityJson } from '@toolproof-npm/schema';
2
+ import type { ResourceMap, IdentityPrefix } from './_lib/types.js';
3
+ import { CONSTANTS } from './constants.js';
4
+ type StripTrailingS<S extends string> = S extends `${infer Rest}S` ? Rest : S;
5
+ type IdentityPrefixFor<T extends string> = StripTrailingS<Uppercase<T>>;
6
+ export type StepKind = keyof typeof CONSTANTS.STEPS;
7
+ export type StepIdentityPrefix = (typeof CONSTANTS.STEP_IDENTITY_PREFIX_BY_KIND)[StepKind];
8
+ type StepIdentityForPrefix<P extends StepIdentityPrefix> = P extends 'workstep' ? WorkStepIdentityJson : P extends 'branchstep' ? BranchStepIdentityJson : P extends 'forstep' ? ForStepIdentityJson : P extends 'whilestep' ? WhileStepIdentityJson : never;
9
+ type AnyIdentityPrefix = IdentityPrefix | StepIdentityPrefix;
10
+ export type NewIdentity<T extends AnyIdentityPrefix = AnyIdentityPrefix> = T extends keyof IdentityByPrefix ? IdentityByPrefix[T] : T extends StepIdentityPrefix ? StepIdentityForPrefix<T> : `${IdentityPrefixFor<T>}-${string}`;
11
+ export declare function getNewIdentity<T extends AnyIdentityPrefix>(identifiable: T): NewIdentity<T>;
12
+ export declare function getNewStepIdentityPrefix<K extends StepKind>(kind: K): (typeof CONSTANTS.STEP_IDENTITY_PREFIX_BY_KIND)[K];
13
+ export declare function getNewStepIdentity<K extends StepKind>(kind: K): Promise<StepIdentityForPrefix<(typeof CONSTANTS.STEP_IDENTITY_PREFIX_BY_KIND)[K]>>;
14
+ export declare function getExecutionRefFromWorkStepIdentity(workStepIdentity: WorkStepIdentityJson): ExecutionIdentityJson;
4
15
  export declare function listResources(// ATTENTION: must clean up
5
16
  resourceTypeRefs: ResourceTypeIdentityJson[]): Promise<ResourceMap>;
17
+ export {};
@@ -5,7 +5,17 @@ export function getNewIdentity(identifiable) {
5
5
  const normalized = base.endsWith('S') ? base.slice(0, -1) : base;
6
6
  const prefix = normalized + '-';
7
7
  const docRef = dbAdmin.collection(CONSTANTS.STORAGE.COLLECTIONS.resources).doc(identifiable).collection(CONSTANTS.STORAGE.COLLECTIONS.members).doc();
8
- return prefix + docRef.id;
8
+ return (prefix + docRef.id);
9
+ }
10
+ export function getNewStepIdentityPrefix(kind) {
11
+ return CONSTANTS.STEP_IDENTITY_PREFIX_BY_KIND[kind];
12
+ }
13
+ export async function getNewStepIdentity(kind) {
14
+ const prefix = getNewStepIdentityPrefix(kind);
15
+ return getNewIdentity(prefix);
16
+ }
17
+ export function getExecutionRefFromWorkStepIdentity(workStepIdentity) {
18
+ return workStepIdentity.replace('WORKSTEP', 'EXECUTION');
9
19
  }
10
20
  export async function listResources(// ATTENTION: must clean up
11
21
  resourceTypeRefs) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toolproof-npm/shared",
3
- "version": "0.1.113",
3
+ "version": "0.1.115",
4
4
  "description": "Core library utilities for ToolProof",
5
5
  "keywords": [
6
6
  "toolproof",
@@ -56,7 +56,7 @@
56
56
  "typescript": "^5.9.3"
57
57
  },
58
58
  "dependencies": {
59
- "@toolproof-npm/schema": "^0.1.76",
59
+ "@toolproof-npm/schema": "^0.1.77",
60
60
  "firebase-admin": "^13.6.0"
61
61
  },
62
62
  "scripts": {