@shipfox/api-definitions 2.0.0
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/.turbo/turbo-build.log +2 -0
- package/.turbo/turbo-type$colon$emit.log +1 -0
- package/.turbo/turbo-type.log +1 -0
- package/CHANGELOG.md +215 -0
- package/LICENSE +21 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +35 -0
- package/dist/config.js.map +1 -0
- package/dist/core/entities/index.d.ts +5 -0
- package/dist/core/entities/index.d.ts.map +1 -0
- package/dist/core/entities/index.js +6 -0
- package/dist/core/entities/index.js.map +1 -0
- package/dist/core/entities/integration-context.d.ts +11 -0
- package/dist/core/entities/integration-context.d.ts.map +1 -0
- package/dist/core/entities/integration-context.js +3 -0
- package/dist/core/entities/integration-context.js.map +1 -0
- package/dist/core/entities/sync-state.d.ts +19 -0
- package/dist/core/entities/sync-state.d.ts.map +1 -0
- package/dist/core/entities/sync-state.js +20 -0
- package/dist/core/entities/sync-state.js.map +1 -0
- package/dist/core/entities/workflow-definition.d.ts +35 -0
- package/dist/core/entities/workflow-definition.d.ts.map +1 -0
- package/dist/core/entities/workflow-definition.js +3 -0
- package/dist/core/entities/workflow-definition.js.map +1 -0
- package/dist/core/entities/workflow-model.d.ts +138 -0
- package/dist/core/entities/workflow-model.d.ts.map +1 -0
- package/dist/core/entities/workflow-model.js +3 -0
- package/dist/core/entities/workflow-model.js.map +1 -0
- package/dist/core/errors.d.ts +10 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +14 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/has-agent-step-integrations.d.ts +3 -0
- package/dist/core/has-agent-step-integrations.d.ts.map +1 -0
- package/dist/core/has-agent-step-integrations.js +5 -0
- package/dist/core/has-agent-step-integrations.js.map +1 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/parse-definition.d.ts +9 -0
- package/dist/core/parse-definition.d.ts.map +1 -0
- package/dist/core/parse-definition.js +17 -0
- package/dist/core/parse-definition.js.map +1 -0
- package/dist/core/sync-definitions.d.ts +44 -0
- package/dist/core/sync-definitions.d.ts.map +1 -0
- package/dist/core/sync-definitions.js +140 -0
- package/dist/core/sync-definitions.js.map +1 -0
- package/dist/core/validate-definition.d.ts +20 -0
- package/dist/core/validate-definition.d.ts.map +1 -0
- package/dist/core/validate-definition.js +61 -0
- package/dist/core/validate-definition.js.map +1 -0
- package/dist/core/workflow-model/constants.d.ts +2 -0
- package/dist/core/workflow-model/constants.d.ts.map +1 -0
- package/dist/core/workflow-model/constants.js +3 -0
- package/dist/core/workflow-model/constants.js.map +1 -0
- package/dist/core/workflow-model/cron-trigger.d.ts +16 -0
- package/dist/core/workflow-model/cron-trigger.d.ts.map +1 -0
- package/dist/core/workflow-model/cron-trigger.js +85 -0
- package/dist/core/workflow-model/cron-trigger.js.map +1 -0
- package/dist/core/workflow-model/index.d.ts +4 -0
- package/dist/core/workflow-model/index.d.ts.map +1 -0
- package/dist/core/workflow-model/index.js +5 -0
- package/dist/core/workflow-model/index.js.map +1 -0
- package/dist/core/workflow-model/invalid-workflow-model-error.d.ts +15 -0
- package/dist/core/workflow-model/invalid-workflow-model-error.d.ts.map +1 -0
- package/dist/core/workflow-model/invalid-workflow-model-error.js +9 -0
- package/dist/core/workflow-model/invalid-workflow-model-error.js.map +1 -0
- package/dist/core/workflow-model/map-job-ids.d.ts +4 -0
- package/dist/core/workflow-model/map-job-ids.d.ts.map +1 -0
- package/dist/core/workflow-model/map-job-ids.js +33 -0
- package/dist/core/workflow-model/map-job-ids.js.map +1 -0
- package/dist/core/workflow-model/normalize-agent-integrations.d.ts +12 -0
- package/dist/core/workflow-model/normalize-agent-integrations.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-agent-integrations.js +157 -0
- package/dist/core/workflow-model/normalize-agent-integrations.js.map +1 -0
- package/dist/core/workflow-model/normalize-dependencies.d.ts +6 -0
- package/dist/core/workflow-model/normalize-dependencies.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-dependencies.js +119 -0
- package/dist/core/workflow-model/normalize-dependencies.js.map +1 -0
- package/dist/core/workflow-model/normalize-env.d.ts +17 -0
- package/dist/core/workflow-model/normalize-env.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-env.js +40 -0
- package/dist/core/workflow-model/normalize-env.js.map +1 -0
- package/dist/core/workflow-model/normalize-if-condition.d.ts +14 -0
- package/dist/core/workflow-model/normalize-if-condition.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-if-condition.js +75 -0
- package/dist/core/workflow-model/normalize-if-condition.js.map +1 -0
- package/dist/core/workflow-model/normalize-job-checkout.d.ts +5 -0
- package/dist/core/workflow-model/normalize-job-checkout.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-job-checkout.js +16 -0
- package/dist/core/workflow-model/normalize-job-checkout.js.map +1 -0
- package/dist/core/workflow-model/normalize-job-listening.d.ts +10 -0
- package/dist/core/workflow-model/normalize-job-listening.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-job-listening.js +125 -0
- package/dist/core/workflow-model/normalize-job-listening.js.map +1 -0
- package/dist/core/workflow-model/normalize-job-success.d.ts +11 -0
- package/dist/core/workflow-model/normalize-job-success.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-job-success.js +23 -0
- package/dist/core/workflow-model/normalize-job-success.js.map +1 -0
- package/dist/core/workflow-model/normalize-jobs.d.ts +12 -0
- package/dist/core/workflow-model/normalize-jobs.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-jobs.js +935 -0
- package/dist/core/workflow-model/normalize-jobs.js.map +1 -0
- package/dist/core/workflow-model/normalize-needs.d.ts +2 -0
- package/dist/core/workflow-model/normalize-needs.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-needs.js +16 -0
- package/dist/core/workflow-model/normalize-needs.js.map +1 -0
- package/dist/core/workflow-model/normalize-step-gate.d.ts +15 -0
- package/dist/core/workflow-model/normalize-step-gate.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-step-gate.js +89 -0
- package/dist/core/workflow-model/normalize-step-gate.js.map +1 -0
- package/dist/core/workflow-model/normalize-step-outputs.d.ts +10 -0
- package/dist/core/workflow-model/normalize-step-outputs.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-step-outputs.js +32 -0
- package/dist/core/workflow-model/normalize-step-outputs.js.map +1 -0
- package/dist/core/workflow-model/normalize-triggers.d.ts +11 -0
- package/dist/core/workflow-model/normalize-triggers.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-triggers.js +128 -0
- package/dist/core/workflow-model/normalize-triggers.js.map +1 -0
- package/dist/core/workflow-model/normalize-workflow-document.d.ts +11 -0
- package/dist/core/workflow-model/normalize-workflow-document.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-workflow-document.js +43 -0
- package/dist/core/workflow-model/normalize-workflow-document.js.map +1 -0
- package/dist/core/workflow-model/parse-duration-ms.d.ts +11 -0
- package/dist/core/workflow-model/parse-duration-ms.d.ts.map +1 -0
- package/dist/core/workflow-model/parse-duration-ms.js +47 -0
- package/dist/core/workflow-model/parse-duration-ms.js.map +1 -0
- package/dist/core/workflow-model/parse-interpolation-field.d.ts +14 -0
- package/dist/core/workflow-model/parse-interpolation-field.d.ts.map +1 -0
- package/dist/core/workflow-model/parse-interpolation-field.js +377 -0
- package/dist/core/workflow-model/parse-interpolation-field.js.map +1 -0
- package/dist/core/workflow-model/stable-id.d.ts +2 -0
- package/dist/core/workflow-model/stable-id.d.ts.map +1 -0
- package/dist/core/workflow-model/stable-id.js +8 -0
- package/dist/core/workflow-model/stable-id.js.map +1 -0
- package/dist/core/workflow-model/validate-job-references.d.ts +10 -0
- package/dist/core/workflow-model/validate-job-references.d.ts.map +1 -0
- package/dist/core/workflow-model/validate-job-references.js +42 -0
- package/dist/core/workflow-model/validate-job-references.js.map +1 -0
- package/dist/core/workflow-model/validate-predicate-expression.d.ts +14 -0
- package/dist/core/workflow-model/validate-predicate-expression.d.ts.map +1 -0
- package/dist/core/workflow-model/validate-predicate-expression.js +273 -0
- package/dist/core/workflow-model/validate-predicate-expression.js.map +1 -0
- package/dist/core/workflow-model/validation-issue.d.ts +8 -0
- package/dist/core/workflow-model/validation-issue.d.ts.map +1 -0
- package/dist/core/workflow-model/validation-issue.js +17 -0
- package/dist/core/workflow-model/validation-issue.js.map +1 -0
- package/dist/core/workflow-model/workflow-field-label.d.ts +3 -0
- package/dist/core/workflow-model/workflow-field-label.d.ts.map +1 -0
- package/dist/core/workflow-model/workflow-field-label.js +47 -0
- package/dist/core/workflow-model/workflow-field-label.js.map +1 -0
- package/dist/core/workflow-yaml/index.d.ts +3 -0
- package/dist/core/workflow-yaml/index.d.ts.map +1 -0
- package/dist/core/workflow-yaml/index.js +4 -0
- package/dist/core/workflow-yaml/index.js.map +1 -0
- package/dist/core/workflow-yaml/invalid-workflow-yaml-error.d.ts +16 -0
- package/dist/core/workflow-yaml/invalid-workflow-yaml-error.d.ts.map +1 -0
- package/dist/core/workflow-yaml/invalid-workflow-yaml-error.js +12 -0
- package/dist/core/workflow-yaml/invalid-workflow-yaml-error.js.map +1 -0
- package/dist/core/workflow-yaml/parse-workflow-yaml.d.ts +9 -0
- package/dist/core/workflow-yaml/parse-workflow-yaml.d.ts.map +1 -0
- package/dist/core/workflow-yaml/parse-workflow-yaml.js +52 -0
- package/dist/core/workflow-yaml/parse-workflow-yaml.js.map +1 -0
- package/dist/core/workflow-yaml/source-locations.d.ts +3 -0
- package/dist/core/workflow-yaml/source-locations.d.ts.map +1 -0
- package/dist/core/workflow-yaml/source-locations.js +48 -0
- package/dist/core/workflow-yaml/source-locations.js.map +1 -0
- package/dist/db/db.d.ts +1277 -0
- package/dist/db/db.d.ts.map +1 -0
- package/dist/db/db.js +22 -0
- package/dist/db/db.js.map +1 -0
- package/dist/db/definition-triggers.d.ts +4 -0
- package/dist/db/definition-triggers.d.ts.map +1 -0
- package/dist/db/definition-triggers.js +17 -0
- package/dist/db/definition-triggers.js.map +1 -0
- package/dist/db/definitions.d.ts +63 -0
- package/dist/db/definitions.d.ts.map +1 -0
- package/dist/db/definitions.js +208 -0
- package/dist/db/definitions.js.map +1 -0
- package/dist/db/index.d.ts +8 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +10 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/schema/common.d.ts +2 -0
- package/dist/db/schema/common.d.ts.map +1 -0
- package/dist/db/schema/common.js +4 -0
- package/dist/db/schema/common.js.map +1 -0
- package/dist/db/schema/definitions.d.ts +237 -0
- package/dist/db/schema/definitions.d.ts.map +1 -0
- package/dist/db/schema/definitions.js +63 -0
- package/dist/db/schema/definitions.js.map +1 -0
- package/dist/db/schema/outbox.d.ts +195 -0
- package/dist/db/schema/outbox.d.ts.map +1 -0
- package/dist/db/schema/outbox.js +5 -0
- package/dist/db/schema/outbox.js.map +1 -0
- package/dist/db/schema/sync-states.d.ts +218 -0
- package/dist/db/schema/sync-states.d.ts.map +1 -0
- package/dist/db/schema/sync-states.js +68 -0
- package/dist/db/schema/sync-states.js.map +1 -0
- package/dist/db/sync-states.d.ts +21 -0
- package/dist/db/sync-states.d.ts.map +1 -0
- package/dist/db/sync-states.js +47 -0
- package/dist/db/sync-states.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +63 -0
- package/dist/index.js.map +1 -0
- package/dist/presentation/dto/definition.d.ts +6 -0
- package/dist/presentation/dto/definition.d.ts.map +1 -0
- package/dist/presentation/dto/definition.js +35 -0
- package/dist/presentation/dto/definition.js.map +1 -0
- package/dist/presentation/dto/index.d.ts +2 -0
- package/dist/presentation/dto/index.d.ts.map +1 -0
- package/dist/presentation/dto/index.js +3 -0
- package/dist/presentation/dto/index.js.map +1 -0
- package/dist/presentation/index.d.ts +2 -0
- package/dist/presentation/index.d.ts.map +1 -0
- package/dist/presentation/index.js +3 -0
- package/dist/presentation/index.js.map +1 -0
- package/dist/presentation/routes/create-definition.d.ts +9 -0
- package/dist/presentation/routes/create-definition.d.ts.map +1 -0
- package/dist/presentation/routes/create-definition.js +76 -0
- package/dist/presentation/routes/create-definition.js.map +1 -0
- package/dist/presentation/routes/get-definition.d.ts +2 -0
- package/dist/presentation/routes/get-definition.d.ts.map +1 -0
- package/dist/presentation/routes/get-definition.js +43 -0
- package/dist/presentation/routes/get-definition.js.map +1 -0
- package/dist/presentation/routes/index.d.ts +7 -0
- package/dist/presentation/routes/index.d.ts.map +1 -0
- package/dist/presentation/routes/index.js +22 -0
- package/dist/presentation/routes/index.js.map +1 -0
- package/dist/presentation/routes/list-definitions.d.ts +2 -0
- package/dist/presentation/routes/list-definitions.d.ts.map +1 -0
- package/dist/presentation/routes/list-definitions.js +56 -0
- package/dist/presentation/routes/list-definitions.js.map +1 -0
- package/dist/presentation/routes/validate-definition.d.ts +2 -0
- package/dist/presentation/routes/validate-definition.d.ts.map +1 -0
- package/dist/presentation/routes/validate-definition.js +43 -0
- package/dist/presentation/routes/validate-definition.js.map +1 -0
- package/dist/presentation/subscribers/index.d.ts +3 -0
- package/dist/presentation/subscribers/index.d.ts.map +1 -0
- package/dist/presentation/subscribers/index.js +4 -0
- package/dist/presentation/subscribers/index.js.map +1 -0
- package/dist/presentation/subscribers/on-project-source-bound.d.ts +3 -0
- package/dist/presentation/subscribers/on-project-source-bound.d.ts.map +1 -0
- package/dist/presentation/subscribers/on-project-source-bound.js +11 -0
- package/dist/presentation/subscribers/on-project-source-bound.js.map +1 -0
- package/dist/presentation/subscribers/on-project-source-commit-observed.d.ts +3 -0
- package/dist/presentation/subscribers/on-project-source-commit-observed.d.ts.map +1 -0
- package/dist/presentation/subscribers/on-project-source-commit-observed.js +13 -0
- package/dist/presentation/subscribers/on-project-source-commit-observed.js.map +1 -0
- package/dist/presentation/subscribers/start-definition-sync.d.ts +10 -0
- package/dist/presentation/subscribers/start-definition-sync.d.ts.map +1 -0
- package/dist/presentation/subscribers/start-definition-sync.js +26 -0
- package/dist/presentation/subscribers/start-definition-sync.js.map +1 -0
- package/dist/temporal/activities/index.d.ts +3 -0
- package/dist/temporal/activities/index.d.ts.map +1 -0
- package/dist/temporal/activities/index.js +3 -0
- package/dist/temporal/activities/index.js.map +1 -0
- package/dist/temporal/activities/sync-activities.d.ts +47 -0
- package/dist/temporal/activities/sync-activities.d.ts.map +1 -0
- package/dist/temporal/activities/sync-activities.js +128 -0
- package/dist/temporal/activities/sync-activities.js.map +1 -0
- package/dist/temporal/constants.d.ts +3 -0
- package/dist/temporal/constants.d.ts.map +1 -0
- package/dist/temporal/constants.js +4 -0
- package/dist/temporal/constants.js.map +1 -0
- package/dist/temporal/index.d.ts +3 -0
- package/dist/temporal/index.d.ts.map +1 -0
- package/dist/temporal/index.js +4 -0
- package/dist/temporal/index.js.map +1 -0
- package/dist/temporal/workflows/definition-sync.d.ts +20 -0
- package/dist/temporal/workflows/definition-sync.d.ts.map +1 -0
- package/dist/temporal/workflows/definition-sync.js +95 -0
- package/dist/temporal/workflows/definition-sync.js.map +1 -0
- package/dist/temporal/workflows/index.d.ts +2 -0
- package/dist/temporal/workflows/index.d.ts.map +1 -0
- package/dist/temporal/workflows/index.js +3 -0
- package/dist/temporal/workflows/index.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -0
- package/drizzle/0000_initial.sql +64 -0
- package/drizzle/0001_definition_list_pagination.sql +1 -0
- package/drizzle/meta/0000_snapshot.json +527 -0
- package/drizzle/meta/_journal.json +20 -0
- package/drizzle.config.ts +11 -0
- package/package.json +89 -0
- package/src/config.test.ts +23 -0
- package/src/config.ts +50 -0
- package/src/core/entities/index.ts +4 -0
- package/src/core/entities/integration-context.ts +21 -0
- package/src/core/entities/sync-state.ts +40 -0
- package/src/core/entities/workflow-definition.ts +38 -0
- package/src/core/entities/workflow-model.ts +162 -0
- package/src/core/errors.ts +21 -0
- package/src/core/has-agent-step-integrations.ts +7 -0
- package/src/core/index.ts +23 -0
- package/src/core/parse-definition.test.ts +200 -0
- package/src/core/parse-definition.ts +28 -0
- package/src/core/sync-definitions.test.ts +390 -0
- package/src/core/sync-definitions.ts +216 -0
- package/src/core/validate-definition.test.ts +152 -0
- package/src/core/validate-definition.ts +72 -0
- package/src/core/workflow-model/README.md +129 -0
- package/src/core/workflow-model/constants.ts +1 -0
- package/src/core/workflow-model/cron-trigger.test.ts +29 -0
- package/src/core/workflow-model/cron-trigger.ts +83 -0
- package/src/core/workflow-model/index.ts +9 -0
- package/src/core/workflow-model/invalid-workflow-model-error.ts +71 -0
- package/src/core/workflow-model/map-job-ids.ts +33 -0
- package/src/core/workflow-model/normalize-agent-integrations.ts +208 -0
- package/src/core/workflow-model/normalize-dependencies.ts +139 -0
- package/src/core/workflow-model/normalize-env.ts +48 -0
- package/src/core/workflow-model/normalize-if-condition.ts +126 -0
- package/src/core/workflow-model/normalize-job-checkout.ts +19 -0
- package/src/core/workflow-model/normalize-job-listening.ts +121 -0
- package/src/core/workflow-model/normalize-job-success.ts +28 -0
- package/src/core/workflow-model/normalize-jobs.ts +1010 -0
- package/src/core/workflow-model/normalize-needs.ts +12 -0
- package/src/core/workflow-model/normalize-step-gate.ts +90 -0
- package/src/core/workflow-model/normalize-step-outputs.ts +36 -0
- package/src/core/workflow-model/normalize-triggers.ts +130 -0
- package/src/core/workflow-model/normalize-workflow-document.test.ts +4463 -0
- package/src/core/workflow-model/normalize-workflow-document.ts +63 -0
- package/src/core/workflow-model/parse-duration-ms.ts +58 -0
- package/src/core/workflow-model/parse-interpolation-field.ts +566 -0
- package/src/core/workflow-model/stable-id.ts +12 -0
- package/src/core/workflow-model/validate-job-references.ts +54 -0
- package/src/core/workflow-model/validate-predicate-expression.test.ts +161 -0
- package/src/core/workflow-model/validate-predicate-expression.ts +406 -0
- package/src/core/workflow-model/validation-issue.ts +27 -0
- package/src/core/workflow-model/workflow-field-label.ts +50 -0
- package/src/core/workflow-yaml/README.md +77 -0
- package/src/core/workflow-yaml/index.ts +11 -0
- package/src/core/workflow-yaml/invalid-workflow-yaml-error.ts +23 -0
- package/src/core/workflow-yaml/parse-workflow-yaml.test.ts +71 -0
- package/src/core/workflow-yaml/parse-workflow-yaml.ts +74 -0
- package/src/core/workflow-yaml/source-locations.ts +62 -0
- package/src/db/db.ts +18 -0
- package/src/db/definition-triggers.test.ts +95 -0
- package/src/db/definition-triggers.ts +17 -0
- package/src/db/definitions.test.ts +1309 -0
- package/src/db/definitions.ts +357 -0
- package/src/db/index.ts +31 -0
- package/src/db/schema/common.ts +3 -0
- package/src/db/schema/definitions.test.ts +36 -0
- package/src/db/schema/definitions.ts +76 -0
- package/src/db/schema/outbox.ts +4 -0
- package/src/db/schema/sync-states.ts +79 -0
- package/src/db/sync-states.test.ts +90 -0
- package/src/db/sync-states.ts +86 -0
- package/src/index.ts +104 -0
- package/src/presentation/dto/definition.test.ts +59 -0
- package/src/presentation/dto/definition.ts +41 -0
- package/src/presentation/dto/index.ts +1 -0
- package/src/presentation/index.ts +1 -0
- package/src/presentation/routes/create-definition.test.ts +356 -0
- package/src/presentation/routes/create-definition.ts +101 -0
- package/src/presentation/routes/get-definition.test.ts +79 -0
- package/src/presentation/routes/get-definition.ts +37 -0
- package/src/presentation/routes/index.test.ts +41 -0
- package/src/presentation/routes/index.ts +28 -0
- package/src/presentation/routes/list-definitions.test.ts +195 -0
- package/src/presentation/routes/list-definitions.ts +49 -0
- package/src/presentation/routes/validate-definition.test.ts +63 -0
- package/src/presentation/routes/validate-definition.ts +46 -0
- package/src/presentation/subscribers/index.ts +2 -0
- package/src/presentation/subscribers/on-project-source-bound.test.ts +65 -0
- package/src/presentation/subscribers/on-project-source-bound.ts +11 -0
- package/src/presentation/subscribers/on-project-source-commit-observed.test.ts +56 -0
- package/src/presentation/subscribers/on-project-source-commit-observed.ts +15 -0
- package/src/presentation/subscribers/start-definition-sync.ts +38 -0
- package/src/temporal/activities/index.ts +10 -0
- package/src/temporal/activities/sync-activities.test.ts +337 -0
- package/src/temporal/activities/sync-activities.ts +206 -0
- package/src/temporal/constants.ts +2 -0
- package/src/temporal/index.ts +2 -0
- package/src/temporal/workflows/definition-sync.test.ts +59 -0
- package/src/temporal/workflows/definition-sync.ts +116 -0
- package/src/temporal/workflows/index.ts +1 -0
- package/test/env.ts +7 -0
- package/test/factories/definition.ts +66 -0
- package/test/fixtures/invalid-cycle.yml +13 -0
- package/test/fixtures/invalid-missing-name.yml +4 -0
- package/test/fixtures/invalid-yaml-syntax.yml +6 -0
- package/test/fixtures/valid-dag.yml +25 -0
- package/test/fixtures/valid-listening-job.yml +21 -0
- package/test/fixtures/valid-simple.yml +18 -0
- package/test/fixtures/workflow-yaml/invalid/invalid-yaml-syntax.yaml +6 -0
- package/test/fixtures/workflow-yaml/invalid/missing-step-run.yaml +5 -0
- package/test/fixtures/workflow-yaml/valid/simple-build.document.json +26 -0
- package/test/fixtures/workflow-yaml/valid/simple-build.yaml +14 -0
- package/test/globalSetup.ts +25 -0
- package/test/index.ts +1 -0
- package/test/setup.ts +17 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +3 -0
- package/tsconfig.test.json +8 -0
- package/vitest.config.ts +11 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { issue } from './validation-issue.js';
|
|
2
|
+
const UNIT_MS = {
|
|
3
|
+
ms: 1,
|
|
4
|
+
s: 1000,
|
|
5
|
+
m: 60 * 1000,
|
|
6
|
+
h: 60 * 60 * 1000,
|
|
7
|
+
d: 24 * 60 * 60 * 1000
|
|
8
|
+
};
|
|
9
|
+
const MIN_DURATION_MS = 1000;
|
|
10
|
+
const MAX_DURATION_MS = 24 * 60 * 60 * 1000;
|
|
11
|
+
const DURATION_PATTERN = /^(\d+)(ms|s|m|h|d)$/;
|
|
12
|
+
export function parseDurationMs(params) {
|
|
13
|
+
if (params.source === undefined) return undefined;
|
|
14
|
+
const match = DURATION_PATTERN.exec(params.source.trim());
|
|
15
|
+
if (!match) {
|
|
16
|
+
params.issues.push(issue({
|
|
17
|
+
code: 'invalid-duration',
|
|
18
|
+
message: 'Duration must be an integer followed by ms, s, m, h, or d.',
|
|
19
|
+
path: params.path,
|
|
20
|
+
details: {
|
|
21
|
+
source: params.source
|
|
22
|
+
}
|
|
23
|
+
}));
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
const value = Number(match[1]);
|
|
27
|
+
const unit = match[2];
|
|
28
|
+
const ms = value * UNIT_MS[unit];
|
|
29
|
+
const minMs = params.minMs ?? MIN_DURATION_MS;
|
|
30
|
+
const maxMs = params.maxMs ?? MAX_DURATION_MS;
|
|
31
|
+
if (!Number.isSafeInteger(ms) || ms < minMs || ms > maxMs) {
|
|
32
|
+
params.issues.push(issue({
|
|
33
|
+
code: params.outOfRangeCode ?? 'invalid-duration',
|
|
34
|
+
message: params.outOfRangeMessage ?? 'Duration must be between 1s and 24h.',
|
|
35
|
+
path: params.path,
|
|
36
|
+
details: {
|
|
37
|
+
source: params.source,
|
|
38
|
+
min_ms: minMs,
|
|
39
|
+
max_ms: maxMs
|
|
40
|
+
}
|
|
41
|
+
}));
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
return ms;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=parse-duration-ms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/core/workflow-model/parse-duration-ms.ts"],"sourcesContent":["import type {WorkflowModelValidationIssue} from './invalid-workflow-model-error.js';\nimport {issue} from './validation-issue.js';\n\nconst UNIT_MS = {\n ms: 1,\n s: 1000,\n m: 60 * 1000,\n h: 60 * 60 * 1000,\n d: 24 * 60 * 60 * 1000,\n} as const;\n\nconst MIN_DURATION_MS = 1000;\nconst MAX_DURATION_MS = 24 * 60 * 60 * 1000;\nconst DURATION_PATTERN = /^(\\d+)(ms|s|m|h|d)$/;\n\nexport function parseDurationMs(params: {\n source: string | undefined;\n path: Array<string | number>;\n issues: WorkflowModelValidationIssue[];\n minMs?: number | undefined;\n maxMs?: number | undefined;\n outOfRangeCode?: 'invalid-duration' | 'listening-timeout-exceeds-run-timeout' | undefined;\n outOfRangeMessage?: string | undefined;\n}): number | undefined {\n if (params.source === undefined) return undefined;\n\n const match = DURATION_PATTERN.exec(params.source.trim());\n if (!match) {\n params.issues.push(\n issue({\n code: 'invalid-duration',\n message: 'Duration must be an integer followed by ms, s, m, h, or d.',\n path: params.path,\n details: {source: params.source},\n }),\n );\n return undefined;\n }\n\n const value = Number(match[1]);\n const unit = match[2] as keyof typeof UNIT_MS;\n const ms = value * UNIT_MS[unit];\n const minMs = params.minMs ?? MIN_DURATION_MS;\n const maxMs = params.maxMs ?? MAX_DURATION_MS;\n if (!Number.isSafeInteger(ms) || ms < minMs || ms > maxMs) {\n params.issues.push(\n issue({\n code: params.outOfRangeCode ?? 'invalid-duration',\n message: params.outOfRangeMessage ?? 'Duration must be between 1s and 24h.',\n path: params.path,\n details: {source: params.source, min_ms: minMs, max_ms: maxMs},\n }),\n );\n return undefined;\n }\n\n return ms;\n}\n"],"names":["issue","UNIT_MS","ms","s","m","h","d","MIN_DURATION_MS","MAX_DURATION_MS","DURATION_PATTERN","parseDurationMs","params","source","undefined","match","exec","trim","issues","push","code","message","path","details","value","Number","unit","minMs","maxMs","isSafeInteger","outOfRangeCode","outOfRangeMessage","min_ms","max_ms"],"mappings":"AACA,SAAQA,KAAK,QAAO,wBAAwB;AAE5C,MAAMC,UAAU;IACdC,IAAI;IACJC,GAAG;IACHC,GAAG,KAAK;IACRC,GAAG,KAAK,KAAK;IACbC,GAAG,KAAK,KAAK,KAAK;AACpB;AAEA,MAAMC,kBAAkB;AACxB,MAAMC,kBAAkB,KAAK,KAAK,KAAK;AACvC,MAAMC,mBAAmB;AAEzB,OAAO,SAASC,gBAAgBC,MAQ/B;IACC,IAAIA,OAAOC,MAAM,KAAKC,WAAW,OAAOA;IAExC,MAAMC,QAAQL,iBAAiBM,IAAI,CAACJ,OAAOC,MAAM,CAACI,IAAI;IACtD,IAAI,CAACF,OAAO;QACVH,OAAOM,MAAM,CAACC,IAAI,CAChBlB,MAAM;YACJmB,MAAM;YACNC,SAAS;YACTC,MAAMV,OAAOU,IAAI;YACjBC,SAAS;gBAACV,QAAQD,OAAOC,MAAM;YAAA;QACjC;QAEF,OAAOC;IACT;IAEA,MAAMU,QAAQC,OAAOV,KAAK,CAAC,EAAE;IAC7B,MAAMW,OAAOX,KAAK,CAAC,EAAE;IACrB,MAAMZ,KAAKqB,QAAQtB,OAAO,CAACwB,KAAK;IAChC,MAAMC,QAAQf,OAAOe,KAAK,IAAInB;IAC9B,MAAMoB,QAAQhB,OAAOgB,KAAK,IAAInB;IAC9B,IAAI,CAACgB,OAAOI,aAAa,CAAC1B,OAAOA,KAAKwB,SAASxB,KAAKyB,OAAO;QACzDhB,OAAOM,MAAM,CAACC,IAAI,CAChBlB,MAAM;YACJmB,MAAMR,OAAOkB,cAAc,IAAI;YAC/BT,SAAST,OAAOmB,iBAAiB,IAAI;YACrCT,MAAMV,OAAOU,IAAI;YACjBC,SAAS;gBAACV,QAAQD,OAAOC,MAAM;gBAAEmB,QAAQL;gBAAOM,QAAQL;YAAK;QAC/D;QAEF,OAAOd;IACT;IAEA,OAAOX;AACT"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type AvailabilitySite, type ExpressionTypeEnvironment } from '@shipfox/expression';
|
|
2
|
+
import type { WorkflowFieldTemplate } from '../entities/workflow-model.js';
|
|
3
|
+
import type { WorkflowModelValidationIssue, WorkflowModelValidationIssuePathSegment } from './invalid-workflow-model-error.js';
|
|
4
|
+
export type StoredInterpolationField = 'run' | 'env.value' | 'agent.prompt' | 'agent.model' | 'agent.provider' | 'job.outputs' | 'job.name' | 'job.runner' | 'step.name' | 'step.feedback';
|
|
5
|
+
export declare function parseInterpolationField(params: {
|
|
6
|
+
field: StoredInterpolationField;
|
|
7
|
+
source: string;
|
|
8
|
+
path: readonly WorkflowModelValidationIssuePathSegment[];
|
|
9
|
+
issues: WorkflowModelValidationIssue[];
|
|
10
|
+
fillSite?: AvailabilitySite;
|
|
11
|
+
allowedJobReferences?: ReadonlySet<string>;
|
|
12
|
+
typeOverlay?: ExpressionTypeEnvironment | undefined;
|
|
13
|
+
}): WorkflowFieldTemplate | undefined;
|
|
14
|
+
//# sourceMappingURL=parse-interpolation-field.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-interpolation-field.d.ts","sourceRoot":"","sources":["../../../src/core/workflow-model/parse-interpolation-field.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,gBAAgB,EAGrB,KAAK,yBAAyB,EAqB/B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,+BAA+B,CAAC;AACzE,OAAO,KAAK,EACV,4BAA4B,EAE5B,uCAAuC,EACxC,MAAM,mCAAmC,CAAC;AAG3C,MAAM,MAAM,wBAAwB,GAChC,KAAK,GACL,WAAW,GACX,cAAc,GACd,aAAa,GACb,gBAAgB,GAChB,aAAa,GACb,UAAU,GACV,YAAY,GACZ,WAAW,GACX,eAAe,CAAC;AAEpB,wBAAgB,uBAAuB,CAAC,MAAM,EAAE;IAC9C,KAAK,EAAE,wBAAwB,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,SAAS,uCAAuC,EAAE,CAAC;IACzD,MAAM,EAAE,4BAA4B,EAAE,CAAC;IACvC,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,oBAAoB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3C,WAAW,CAAC,EAAE,yBAAyB,GAAG,SAAS,CAAC;CACrD,GAAG,qBAAqB,GAAG,SAAS,CAuBpC"}
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import { secretKeySchema, secretStoreSchema } from '@shipfox/api-secrets-dto';
|
|
2
|
+
import { analyzeContextKeyAccess, createWorkflowExpression, extractCelUntrustedPathAccesses, getWorkflowContextAvailability, getWorkflowContextDefinition, getWorkflowContextHost, getWorkflowContextTypeEnvironment, getWorkflowContextUntrustedPaths, InvalidWorkflowExpressionError, InvalidWorkflowTemplateError, parseWorkflowTemplate, planInterpolationField, unavailableRootsAt, workflowContextNames, workflowInterpolationFieldAcceptsContext, workflowInterpolationFieldAcceptsHost, workflowInterpolationFieldAcceptsTrustTier } from '@shipfox/expression';
|
|
3
|
+
import { validateDirectJobReferences } from './validate-job-references.js';
|
|
4
|
+
export function parseInterpolationField(params) {
|
|
5
|
+
const segments = parseTemplate(params);
|
|
6
|
+
if (segments === undefined) return undefined;
|
|
7
|
+
const expressionSegments = segments.filter(isExpressionSegment);
|
|
8
|
+
if (expressionSegments.length === 0) return undefined;
|
|
9
|
+
const checkedSegments = segments.map((segment)=>{
|
|
10
|
+
if (segment.kind === 'literal') return segment;
|
|
11
|
+
const validatedSegment = validateExpressionSegment({
|
|
12
|
+
...params,
|
|
13
|
+
segment
|
|
14
|
+
});
|
|
15
|
+
return validatedSegment ?? segment;
|
|
16
|
+
});
|
|
17
|
+
const plan = planInterpolationField({
|
|
18
|
+
field: params.field,
|
|
19
|
+
segments: checkedSegments
|
|
20
|
+
});
|
|
21
|
+
if (!plan.ok) {
|
|
22
|
+
params.issues.push(...plan.violations.map((violation)=>planViolationIssue(params, violation)));
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
return plan.plan.field.segments;
|
|
26
|
+
}
|
|
27
|
+
function parseTemplate(params) {
|
|
28
|
+
try {
|
|
29
|
+
return parseWorkflowTemplate(params.source);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
params.issues.push(issue({
|
|
32
|
+
code: 'invalid-interpolation-template',
|
|
33
|
+
message: `${fieldLabel(params.field)} must use valid $${'{{ }}'} interpolation syntax.`,
|
|
34
|
+
path: params.path,
|
|
35
|
+
details: {
|
|
36
|
+
field: params.field,
|
|
37
|
+
source: params.source,
|
|
38
|
+
reason: error instanceof InvalidWorkflowTemplateError ? error.reason : 'Template source did not parse.'
|
|
39
|
+
}
|
|
40
|
+
}));
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function validateExpressionSegment(params) {
|
|
45
|
+
const contextRoots = uniqueStrings(params.segment.contextRoots);
|
|
46
|
+
const knownRoots = contextRoots.filter(isWorkflowContextName);
|
|
47
|
+
const unknownRoots = contextRoots.filter((root)=>!isWorkflowContextName(root));
|
|
48
|
+
const rejectedRoots = knownRoots.filter((root)=>!workflowInterpolationFieldAcceptsContext(params.field, root));
|
|
49
|
+
if (rejectedRoots.length > 0) {
|
|
50
|
+
params.issues.push(untrustedContextIssue({
|
|
51
|
+
...params,
|
|
52
|
+
contextRoots,
|
|
53
|
+
rejectedRoots
|
|
54
|
+
}));
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
const rejectedHostRoots = knownRoots.filter((root)=>!workflowInterpolationFieldAcceptsHost(params.field, getWorkflowContextHost(root)));
|
|
58
|
+
if (rejectedHostRoots.length > 0) {
|
|
59
|
+
params.issues.push(runnerContextInFieldIssue({
|
|
60
|
+
...params,
|
|
61
|
+
contextRoots,
|
|
62
|
+
rejectedHostRoots
|
|
63
|
+
}));
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
const keyAccess = analyzeContextKeyAccess(params.segment.expression);
|
|
67
|
+
if (keyAccess.violations.length > 0) {
|
|
68
|
+
params.issues.push(...keyAccess.violations.map((violation)=>computedContextKeyIssue({
|
|
69
|
+
...params,
|
|
70
|
+
contextRoots,
|
|
71
|
+
root: violation.root,
|
|
72
|
+
expression: violation.source
|
|
73
|
+
})));
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
const invalidReferenceIssue = validateContextKeyReferences({
|
|
77
|
+
...params,
|
|
78
|
+
contextRoots,
|
|
79
|
+
references: keyAccess.references
|
|
80
|
+
});
|
|
81
|
+
if (invalidReferenceIssue !== undefined) {
|
|
82
|
+
params.issues.push(invalidReferenceIssue);
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
const invalidJobReferenceIssue = params.allowedJobReferences === undefined ? undefined : validateDirectJobReferences({
|
|
86
|
+
source: params.source,
|
|
87
|
+
expression: params.segment.expression,
|
|
88
|
+
field: params.field,
|
|
89
|
+
path: params.path,
|
|
90
|
+
allowedJobReferences: params.allowedJobReferences
|
|
91
|
+
});
|
|
92
|
+
if (invalidJobReferenceIssue !== undefined) {
|
|
93
|
+
params.issues.push(invalidJobReferenceIssue);
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
const rejectedPathRoots = findUntrustedPathRoots(params.segment, params.field, knownRoots);
|
|
97
|
+
if (rejectedPathRoots.length > 0) {
|
|
98
|
+
params.issues.push(untrustedContextIssue({
|
|
99
|
+
...params,
|
|
100
|
+
contextRoots,
|
|
101
|
+
rejectedRoots: rejectedPathRoots
|
|
102
|
+
}));
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
if (unknownRoots.length > 0) {
|
|
106
|
+
params.issues.push(issue({
|
|
107
|
+
code: 'unknown-interpolation-context',
|
|
108
|
+
message: `${fieldLabel(params.field)} interpolation references unknown context ${formatList(unknownRoots)}.`,
|
|
109
|
+
path: params.path,
|
|
110
|
+
details: {
|
|
111
|
+
field: params.field,
|
|
112
|
+
source: params.source,
|
|
113
|
+
expression: params.segment.expression.source,
|
|
114
|
+
contextRoots,
|
|
115
|
+
unknownRoots
|
|
116
|
+
}
|
|
117
|
+
}));
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
const fillSite = params.fillSite;
|
|
121
|
+
if (fillSite !== undefined) {
|
|
122
|
+
const serverRoots = knownRoots.filter((root)=>getWorkflowContextHost(root) === 'server');
|
|
123
|
+
const unavailableRoots = unavailableRootsAt(serverRoots, fillSite);
|
|
124
|
+
if (unavailableRoots.length > 0) {
|
|
125
|
+
params.issues.push(unavailableContextIssue({
|
|
126
|
+
...params,
|
|
127
|
+
contextRoots,
|
|
128
|
+
unavailableRoots,
|
|
129
|
+
fillSite
|
|
130
|
+
}));
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (params.typeOverlay === undefined && (knownRoots.length === 0 || knownRoots.some((root)=>hasSyntaxOnlyCheckMode(root)))) {
|
|
135
|
+
return params.segment;
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
return {
|
|
139
|
+
...params.segment,
|
|
140
|
+
expression: createWorkflowExpression({
|
|
141
|
+
source: params.segment.expression.source,
|
|
142
|
+
check: {
|
|
143
|
+
mode: 'typed',
|
|
144
|
+
// `undefined` preserves the legacy syntax-only path above. `{}` means
|
|
145
|
+
// callers intentionally requested typed checking with the standard roots.
|
|
146
|
+
typeEnvironment: mergeTypeEnvironments(knownRoots, params.typeOverlay)
|
|
147
|
+
}
|
|
148
|
+
})
|
|
149
|
+
};
|
|
150
|
+
} catch (error) {
|
|
151
|
+
params.issues.push(issue({
|
|
152
|
+
code: 'invalid-interpolation-expression',
|
|
153
|
+
message: `${fieldLabel(params.field)} interpolation expression did not type-check.`,
|
|
154
|
+
path: params.path,
|
|
155
|
+
details: {
|
|
156
|
+
field: params.field,
|
|
157
|
+
source: params.source,
|
|
158
|
+
expression: params.segment.expression.source,
|
|
159
|
+
contextRoots,
|
|
160
|
+
reason: error instanceof InvalidWorkflowExpressionError ? error.reason : 'Expression source did not type-check.'
|
|
161
|
+
}
|
|
162
|
+
}));
|
|
163
|
+
return undefined;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
function findUntrustedPathRoots(segment, field, knownRoots) {
|
|
167
|
+
if (!isTrustedOnlyField(field)) return [];
|
|
168
|
+
const untrustedPathsByRoot = new Map();
|
|
169
|
+
for (const root of knownRoots){
|
|
170
|
+
const paths = getWorkflowContextUntrustedPaths(root);
|
|
171
|
+
if (paths === undefined || paths.length === 0) continue;
|
|
172
|
+
untrustedPathsByRoot.set(root, paths);
|
|
173
|
+
}
|
|
174
|
+
if (knownRoots.includes('steps')) {
|
|
175
|
+
untrustedPathsByRoot.set('steps', [
|
|
176
|
+
...new Set([
|
|
177
|
+
...untrustedPathsByRoot.get('steps') ?? [],
|
|
178
|
+
'outputs'
|
|
179
|
+
])
|
|
180
|
+
]);
|
|
181
|
+
}
|
|
182
|
+
if (untrustedPathsByRoot.size === 0) return [];
|
|
183
|
+
return extractCelUntrustedPathAccesses({
|
|
184
|
+
source: segment.expression.source,
|
|
185
|
+
untrustedPathsByRoot
|
|
186
|
+
}).filter(isWorkflowContextName);
|
|
187
|
+
}
|
|
188
|
+
function isTrustedOnlyField(field) {
|
|
189
|
+
return !workflowInterpolationFieldAcceptsTrustTier(field, 'untrusted');
|
|
190
|
+
}
|
|
191
|
+
function untrustedContextIssue(params) {
|
|
192
|
+
return issue({
|
|
193
|
+
code: 'untrusted-context-in-field',
|
|
194
|
+
message: params.field === 'run' ? `Run command interpolation cannot use untrusted context ${formatList(params.rejectedRoots)}. Bind untrusted values to env and reference the shell variable from run instead.` : `${fieldLabel(params.field)} interpolation cannot use untrusted context ${formatList(params.rejectedRoots)}.`,
|
|
195
|
+
path: params.path,
|
|
196
|
+
details: {
|
|
197
|
+
field: params.field,
|
|
198
|
+
source: params.source,
|
|
199
|
+
contextRoots: params.contextRoots,
|
|
200
|
+
rejectedRoots: params.rejectedRoots
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
function runnerContextInFieldIssue(params) {
|
|
205
|
+
return issue({
|
|
206
|
+
code: 'runner-context-in-field',
|
|
207
|
+
message: `${fieldLabel(params.field)} interpolation cannot use runner context ${formatList(params.rejectedHostRoots)}. Bind secrets to a run-step env value instead.`,
|
|
208
|
+
path: params.path,
|
|
209
|
+
details: {
|
|
210
|
+
field: params.field,
|
|
211
|
+
source: params.source,
|
|
212
|
+
contextRoots: params.contextRoots,
|
|
213
|
+
rejectedRoots: params.rejectedHostRoots
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
function computedContextKeyIssue(params) {
|
|
218
|
+
return issue({
|
|
219
|
+
code: 'computed-context-key',
|
|
220
|
+
message: `${fieldLabel(params.field)} interpolation must reference ${params.root} with a literal dot key.`,
|
|
221
|
+
path: params.path,
|
|
222
|
+
details: {
|
|
223
|
+
field: params.field,
|
|
224
|
+
source: params.source,
|
|
225
|
+
expression: params.expression,
|
|
226
|
+
contextRoots: params.contextRoots,
|
|
227
|
+
root: params.root
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
function validateContextKeyReferences(params) {
|
|
232
|
+
for (const reference of params.references){
|
|
233
|
+
if (!secretKeySchema.safeParse(reference.key).success) {
|
|
234
|
+
return computedContextKeyIssue({
|
|
235
|
+
...params,
|
|
236
|
+
root: reference.root,
|
|
237
|
+
expression: params.segment.expression.source
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
if (reference.root !== 'secrets' || reference.store === undefined) continue;
|
|
241
|
+
if (secretStoreSchema.safeParse(reference.store).success) continue;
|
|
242
|
+
return issue({
|
|
243
|
+
code: 'unknown-secret-store',
|
|
244
|
+
message: `${fieldLabel(params.field)} interpolation references unknown secret store "${reference.store}".`,
|
|
245
|
+
path: params.path,
|
|
246
|
+
details: {
|
|
247
|
+
field: params.field,
|
|
248
|
+
source: params.source,
|
|
249
|
+
expression: params.segment.expression.source,
|
|
250
|
+
contextRoots: params.contextRoots,
|
|
251
|
+
store: reference.store
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
return undefined;
|
|
256
|
+
}
|
|
257
|
+
const availabilitySiteLabels = {
|
|
258
|
+
ingest: 'ingest',
|
|
259
|
+
'run-creation': 'run creation',
|
|
260
|
+
'execution-creation': 'execution creation',
|
|
261
|
+
'job-activation': 'job activation',
|
|
262
|
+
'step-dispatch': 'step dispatch',
|
|
263
|
+
'step-report': 'step reporting',
|
|
264
|
+
'execution-resolution': 'execution resolution',
|
|
265
|
+
'job-resolution': 'job resolution'
|
|
266
|
+
};
|
|
267
|
+
function unavailableContextIssue(params) {
|
|
268
|
+
return issue({
|
|
269
|
+
code: 'context-unavailable-at-fill-site',
|
|
270
|
+
message: `${fieldLabel(params.field)} interpolation references ${contextNoun(params.unavailableRoots)} ${formatList(params.unavailableRoots)} that ${availabilityVerb(params.unavailableRoots)} not available at ${describeAvailabilitySite(params.fillSite)}. ${params.unavailableRoots.map(unavailableRootAvailabilityMessage).join(' ')}`,
|
|
271
|
+
path: params.path,
|
|
272
|
+
details: {
|
|
273
|
+
field: params.field,
|
|
274
|
+
source: params.source,
|
|
275
|
+
expression: params.segment.expression.source,
|
|
276
|
+
contextRoots: params.contextRoots,
|
|
277
|
+
unavailableRoots: params.unavailableRoots,
|
|
278
|
+
fillSite: params.fillSite
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
function planViolationIssue(params, violation) {
|
|
283
|
+
if (violation.reason === 'computed-context-key') {
|
|
284
|
+
return issue({
|
|
285
|
+
code: 'computed-context-key',
|
|
286
|
+
message: `${fieldLabel(params.field)} interpolation must reference ${formatList(violation.contextRoots ?? [])} with a literal dot key.`,
|
|
287
|
+
path: params.path,
|
|
288
|
+
details: {
|
|
289
|
+
field: params.field,
|
|
290
|
+
source: params.source,
|
|
291
|
+
expression: violation.source,
|
|
292
|
+
contextRoots: violation.contextRoots
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
return issue({
|
|
297
|
+
code: 'runner-context-not-bare',
|
|
298
|
+
message: `${fieldLabel(params.field)} interpolation references runner context in a larger expression; ${violation.hint}.`,
|
|
299
|
+
path: params.path,
|
|
300
|
+
details: {
|
|
301
|
+
field: params.field,
|
|
302
|
+
source: params.source,
|
|
303
|
+
expression: violation.source,
|
|
304
|
+
runnerRoots: violation.runnerRoots ?? []
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
function contextNoun(roots) {
|
|
309
|
+
return roots.length === 1 ? 'context' : 'contexts';
|
|
310
|
+
}
|
|
311
|
+
function availabilityVerb(roots) {
|
|
312
|
+
return roots.length === 1 ? 'is' : 'are';
|
|
313
|
+
}
|
|
314
|
+
function unavailableRootAvailabilityMessage(root) {
|
|
315
|
+
const availability = getWorkflowContextAvailability(root);
|
|
316
|
+
if (availability === undefined) return `"${root}" is not available at any server site.`;
|
|
317
|
+
return `"${root}" becomes available at ${describeAvailabilitySite(availability)}.`;
|
|
318
|
+
}
|
|
319
|
+
function describeAvailabilitySite(site) {
|
|
320
|
+
return availabilitySiteLabels[site];
|
|
321
|
+
}
|
|
322
|
+
function hasSyntaxOnlyCheckMode(root) {
|
|
323
|
+
return getWorkflowContextDefinition(root).checkMode === 'syntax';
|
|
324
|
+
}
|
|
325
|
+
function mergeTypeEnvironments(roots, typeOverlay) {
|
|
326
|
+
const typeEnvironment = {};
|
|
327
|
+
for (const root of roots){
|
|
328
|
+
const overlayType = typeOverlay?.[root];
|
|
329
|
+
if (overlayType !== undefined) {
|
|
330
|
+
typeEnvironment[root] = overlayType;
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
const contextTypeEnvironment = getWorkflowContextTypeEnvironment(root);
|
|
334
|
+
if (contextTypeEnvironment === undefined) {
|
|
335
|
+
if (typeOverlay !== undefined) typeEnvironment[root] = {
|
|
336
|
+
kind: 'map'
|
|
337
|
+
};
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
Object.assign(typeEnvironment, contextTypeEnvironment);
|
|
341
|
+
}
|
|
342
|
+
return typeEnvironment;
|
|
343
|
+
}
|
|
344
|
+
function isExpressionSegment(segment) {
|
|
345
|
+
return segment.kind === 'expr';
|
|
346
|
+
}
|
|
347
|
+
function isWorkflowContextName(root) {
|
|
348
|
+
return workflowContextNames.includes(root);
|
|
349
|
+
}
|
|
350
|
+
function uniqueStrings(values) {
|
|
351
|
+
return [
|
|
352
|
+
...new Set(values)
|
|
353
|
+
];
|
|
354
|
+
}
|
|
355
|
+
function formatList(values) {
|
|
356
|
+
return values.map((value)=>`"${value}"`).join(', ');
|
|
357
|
+
}
|
|
358
|
+
function fieldLabel(field) {
|
|
359
|
+
return `Workflow ${field}`;
|
|
360
|
+
}
|
|
361
|
+
function issue(params) {
|
|
362
|
+
if (params.details === undefined) {
|
|
363
|
+
return {
|
|
364
|
+
code: params.code,
|
|
365
|
+
message: params.message,
|
|
366
|
+
path: params.path
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
return {
|
|
370
|
+
code: params.code,
|
|
371
|
+
message: params.message,
|
|
372
|
+
path: params.path,
|
|
373
|
+
details: params.details
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
//# sourceMappingURL=parse-interpolation-field.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/core/workflow-model/parse-interpolation-field.ts"],"sourcesContent":["import {secretKeySchema, secretStoreSchema} from '@shipfox/api-secrets-dto';\nimport {\n type AvailabilitySite,\n analyzeContextKeyAccess,\n createWorkflowExpression,\n type ExpressionTypeEnvironment,\n extractCelUntrustedPathAccesses,\n getWorkflowContextAvailability,\n getWorkflowContextDefinition,\n getWorkflowContextHost,\n getWorkflowContextTypeEnvironment,\n getWorkflowContextUntrustedPaths,\n InvalidWorkflowExpressionError,\n InvalidWorkflowTemplateError,\n type PlanViolation,\n parseWorkflowTemplate,\n planInterpolationField,\n unavailableRootsAt,\n type WorkflowContextName,\n type WorkflowInterpolationField,\n type WorkflowTemplateExprSegment,\n type WorkflowTemplateSegment,\n workflowContextNames,\n workflowInterpolationFieldAcceptsContext,\n workflowInterpolationFieldAcceptsHost,\n workflowInterpolationFieldAcceptsTrustTier,\n} from '@shipfox/expression';\nimport type {WorkflowFieldTemplate} from '../entities/workflow-model.js';\nimport type {\n WorkflowModelValidationIssue,\n WorkflowModelValidationIssueCode,\n WorkflowModelValidationIssuePathSegment,\n} from './invalid-workflow-model-error.js';\nimport {validateDirectJobReferences} from './validate-job-references.js';\n\nexport type StoredInterpolationField =\n | 'run'\n | 'env.value'\n | 'agent.prompt'\n | 'agent.model'\n | 'agent.provider'\n | 'job.outputs'\n | 'job.name'\n | 'job.runner'\n | 'step.name'\n | 'step.feedback';\n\nexport function parseInterpolationField(params: {\n field: StoredInterpolationField;\n source: string;\n path: readonly WorkflowModelValidationIssuePathSegment[];\n issues: WorkflowModelValidationIssue[];\n fillSite?: AvailabilitySite;\n allowedJobReferences?: ReadonlySet<string>;\n typeOverlay?: ExpressionTypeEnvironment | undefined;\n}): WorkflowFieldTemplate | undefined {\n const segments = parseTemplate(params);\n if (segments === undefined) return undefined;\n\n const expressionSegments = segments.filter(isExpressionSegment);\n if (expressionSegments.length === 0) return undefined;\n\n const checkedSegments = segments.map((segment) => {\n if (segment.kind === 'literal') return segment;\n\n const validatedSegment = validateExpressionSegment({...params, segment});\n return validatedSegment ?? segment;\n });\n\n const plan = planInterpolationField({field: params.field, segments: checkedSegments});\n if (!plan.ok) {\n params.issues.push(\n ...plan.violations.map((violation) => planViolationIssue(params, violation)),\n );\n return undefined;\n }\n\n return plan.plan.field.segments;\n}\n\nfunction parseTemplate(params: {\n field: WorkflowInterpolationField;\n source: string;\n path: readonly WorkflowModelValidationIssuePathSegment[];\n issues: WorkflowModelValidationIssue[];\n}): WorkflowTemplateSegment[] | undefined {\n try {\n return parseWorkflowTemplate(params.source);\n } catch (error) {\n params.issues.push(\n issue({\n code: 'invalid-interpolation-template',\n message: `${fieldLabel(params.field)} must use valid $${'{{ }}'} interpolation syntax.`,\n path: params.path,\n details: {\n field: params.field,\n source: params.source,\n reason:\n error instanceof InvalidWorkflowTemplateError\n ? error.reason\n : 'Template source did not parse.',\n },\n }),\n );\n return undefined;\n }\n}\n\nfunction validateExpressionSegment(params: {\n field: StoredInterpolationField;\n source: string;\n path: readonly WorkflowModelValidationIssuePathSegment[];\n issues: WorkflowModelValidationIssue[];\n segment: WorkflowTemplateExprSegment;\n fillSite?: AvailabilitySite;\n allowedJobReferences?: ReadonlySet<string>;\n typeOverlay?: ExpressionTypeEnvironment | undefined;\n}): WorkflowTemplateExprSegment | undefined {\n const contextRoots = uniqueStrings(params.segment.contextRoots);\n const knownRoots = contextRoots.filter(isWorkflowContextName);\n const unknownRoots = contextRoots.filter((root) => !isWorkflowContextName(root));\n\n const rejectedRoots = knownRoots.filter(\n (root) => !workflowInterpolationFieldAcceptsContext(params.field, root),\n );\n if (rejectedRoots.length > 0) {\n params.issues.push(untrustedContextIssue({...params, contextRoots, rejectedRoots}));\n return undefined;\n }\n\n const rejectedHostRoots = knownRoots.filter(\n (root) => !workflowInterpolationFieldAcceptsHost(params.field, getWorkflowContextHost(root)),\n );\n if (rejectedHostRoots.length > 0) {\n params.issues.push(runnerContextInFieldIssue({...params, contextRoots, rejectedHostRoots}));\n return undefined;\n }\n\n const keyAccess = analyzeContextKeyAccess(params.segment.expression);\n if (keyAccess.violations.length > 0) {\n params.issues.push(\n ...keyAccess.violations.map((violation) =>\n computedContextKeyIssue({\n ...params,\n contextRoots,\n root: violation.root,\n expression: violation.source,\n }),\n ),\n );\n return undefined;\n }\n\n const invalidReferenceIssue = validateContextKeyReferences({\n ...params,\n contextRoots,\n references: keyAccess.references,\n });\n if (invalidReferenceIssue !== undefined) {\n params.issues.push(invalidReferenceIssue);\n return undefined;\n }\n\n const invalidJobReferenceIssue =\n params.allowedJobReferences === undefined\n ? undefined\n : validateDirectJobReferences({\n source: params.source,\n expression: params.segment.expression,\n field: params.field,\n path: params.path,\n allowedJobReferences: params.allowedJobReferences,\n });\n if (invalidJobReferenceIssue !== undefined) {\n params.issues.push(invalidJobReferenceIssue);\n return undefined;\n }\n\n const rejectedPathRoots = findUntrustedPathRoots(params.segment, params.field, knownRoots);\n if (rejectedPathRoots.length > 0) {\n params.issues.push(\n untrustedContextIssue({...params, contextRoots, rejectedRoots: rejectedPathRoots}),\n );\n return undefined;\n }\n\n if (unknownRoots.length > 0) {\n params.issues.push(\n issue({\n code: 'unknown-interpolation-context',\n message: `${fieldLabel(params.field)} interpolation references unknown context ${formatList(\n unknownRoots,\n )}.`,\n path: params.path,\n details: {\n field: params.field,\n source: params.source,\n expression: params.segment.expression.source,\n contextRoots,\n unknownRoots,\n },\n }),\n );\n return undefined;\n }\n\n const fillSite = params.fillSite;\n if (fillSite !== undefined) {\n const serverRoots = knownRoots.filter((root) => getWorkflowContextHost(root) === 'server');\n const unavailableRoots = unavailableRootsAt(serverRoots, fillSite);\n if (unavailableRoots.length > 0) {\n params.issues.push(\n unavailableContextIssue({...params, contextRoots, unavailableRoots, fillSite}),\n );\n return undefined;\n }\n }\n\n if (\n params.typeOverlay === undefined &&\n (knownRoots.length === 0 || knownRoots.some((root) => hasSyntaxOnlyCheckMode(root)))\n ) {\n return params.segment;\n }\n\n try {\n return {\n ...params.segment,\n expression: createWorkflowExpression({\n source: params.segment.expression.source,\n check: {\n mode: 'typed',\n // `undefined` preserves the legacy syntax-only path above. `{}` means\n // callers intentionally requested typed checking with the standard roots.\n typeEnvironment: mergeTypeEnvironments(knownRoots, params.typeOverlay),\n },\n }),\n };\n } catch (error) {\n params.issues.push(\n issue({\n code: 'invalid-interpolation-expression',\n message: `${fieldLabel(params.field)} interpolation expression did not type-check.`,\n path: params.path,\n details: {\n field: params.field,\n source: params.source,\n expression: params.segment.expression.source,\n contextRoots,\n reason:\n error instanceof InvalidWorkflowExpressionError\n ? error.reason\n : 'Expression source did not type-check.',\n },\n }),\n );\n return undefined;\n }\n}\n\nfunction findUntrustedPathRoots(\n segment: WorkflowTemplateExprSegment,\n field: StoredInterpolationField,\n knownRoots: readonly WorkflowContextName[],\n): readonly WorkflowContextName[] {\n if (!isTrustedOnlyField(field)) return [];\n\n const untrustedPathsByRoot = new Map<string, readonly string[]>();\n for (const root of knownRoots) {\n const paths = getWorkflowContextUntrustedPaths(root);\n if (paths === undefined || paths.length === 0) continue;\n untrustedPathsByRoot.set(root, paths);\n }\n if (knownRoots.includes('steps')) {\n untrustedPathsByRoot.set('steps', [\n ...new Set([...(untrustedPathsByRoot.get('steps') ?? []), 'outputs']),\n ]);\n }\n if (untrustedPathsByRoot.size === 0) return [];\n\n return extractCelUntrustedPathAccesses({\n source: segment.expression.source,\n untrustedPathsByRoot,\n }).filter(isWorkflowContextName);\n}\n\nfunction isTrustedOnlyField(field: StoredInterpolationField): boolean {\n return !workflowInterpolationFieldAcceptsTrustTier(field, 'untrusted');\n}\n\nfunction untrustedContextIssue(params: {\n field: WorkflowInterpolationField;\n source: string;\n path: readonly WorkflowModelValidationIssuePathSegment[];\n contextRoots: readonly string[];\n rejectedRoots: readonly WorkflowContextName[];\n}): WorkflowModelValidationIssue {\n return issue({\n code: 'untrusted-context-in-field',\n message:\n params.field === 'run'\n ? `Run command interpolation cannot use untrusted context ${formatList(\n params.rejectedRoots,\n )}. Bind untrusted values to env and reference the shell variable from run instead.`\n : `${fieldLabel(params.field)} interpolation cannot use untrusted context ${formatList(\n params.rejectedRoots,\n )}.`,\n path: params.path,\n details: {\n field: params.field,\n source: params.source,\n contextRoots: params.contextRoots,\n rejectedRoots: params.rejectedRoots,\n },\n });\n}\n\nfunction runnerContextInFieldIssue(params: {\n field: WorkflowInterpolationField;\n source: string;\n path: readonly WorkflowModelValidationIssuePathSegment[];\n contextRoots: readonly string[];\n rejectedHostRoots: readonly WorkflowContextName[];\n}): WorkflowModelValidationIssue {\n return issue({\n code: 'runner-context-in-field',\n message: `${fieldLabel(params.field)} interpolation cannot use runner context ${formatList(\n params.rejectedHostRoots,\n )}. Bind secrets to a run-step env value instead.`,\n path: params.path,\n details: {\n field: params.field,\n source: params.source,\n contextRoots: params.contextRoots,\n rejectedRoots: params.rejectedHostRoots,\n },\n });\n}\n\nfunction computedContextKeyIssue(params: {\n field: WorkflowInterpolationField;\n source: string;\n path: readonly WorkflowModelValidationIssuePathSegment[];\n contextRoots: readonly string[];\n root: string;\n expression: string;\n}): WorkflowModelValidationIssue {\n return issue({\n code: 'computed-context-key',\n message: `${fieldLabel(params.field)} interpolation must reference ${params.root} with a literal dot key.`,\n path: params.path,\n details: {\n field: params.field,\n source: params.source,\n expression: params.expression,\n contextRoots: params.contextRoots,\n root: params.root,\n },\n });\n}\n\nfunction validateContextKeyReferences(params: {\n field: WorkflowInterpolationField;\n source: string;\n path: readonly WorkflowModelValidationIssuePathSegment[];\n contextRoots: readonly string[];\n segment: WorkflowTemplateExprSegment;\n references: ReturnType<typeof analyzeContextKeyAccess>['references'];\n}): WorkflowModelValidationIssue | undefined {\n for (const reference of params.references) {\n if (!secretKeySchema.safeParse(reference.key).success) {\n return computedContextKeyIssue({\n ...params,\n root: reference.root,\n expression: params.segment.expression.source,\n });\n }\n\n if (reference.root !== 'secrets' || reference.store === undefined) continue;\n if (secretStoreSchema.safeParse(reference.store).success) continue;\n\n return issue({\n code: 'unknown-secret-store',\n message: `${fieldLabel(params.field)} interpolation references unknown secret store \"${reference.store}\".`,\n path: params.path,\n details: {\n field: params.field,\n source: params.source,\n expression: params.segment.expression.source,\n contextRoots: params.contextRoots,\n store: reference.store,\n },\n });\n }\n\n return undefined;\n}\n\nconst availabilitySiteLabels = {\n ingest: 'ingest',\n 'run-creation': 'run creation',\n 'execution-creation': 'execution creation',\n 'job-activation': 'job activation',\n 'step-dispatch': 'step dispatch',\n 'step-report': 'step reporting',\n 'execution-resolution': 'execution resolution',\n 'job-resolution': 'job resolution',\n} as const satisfies Record<AvailabilitySite, string>;\n\nfunction unavailableContextIssue(params: {\n field: WorkflowInterpolationField;\n source: string;\n path: readonly WorkflowModelValidationIssuePathSegment[];\n segment: WorkflowTemplateExprSegment;\n contextRoots: readonly string[];\n unavailableRoots: readonly WorkflowContextName[];\n fillSite: AvailabilitySite;\n}): WorkflowModelValidationIssue {\n return issue({\n code: 'context-unavailable-at-fill-site',\n message: `${fieldLabel(params.field)} interpolation references ${contextNoun(\n params.unavailableRoots,\n )} ${formatList(params.unavailableRoots)} that ${availabilityVerb(\n params.unavailableRoots,\n )} not available at ${describeAvailabilitySite(params.fillSite)}. ${params.unavailableRoots\n .map(unavailableRootAvailabilityMessage)\n .join(' ')}`,\n path: params.path,\n details: {\n field: params.field,\n source: params.source,\n expression: params.segment.expression.source,\n contextRoots: params.contextRoots,\n unavailableRoots: params.unavailableRoots,\n fillSite: params.fillSite,\n },\n });\n}\n\nfunction planViolationIssue(\n params: {\n field: WorkflowInterpolationField;\n source: string;\n path: readonly WorkflowModelValidationIssuePathSegment[];\n },\n violation: PlanViolation,\n): WorkflowModelValidationIssue {\n if (violation.reason === 'computed-context-key') {\n return issue({\n code: 'computed-context-key',\n message: `${fieldLabel(params.field)} interpolation must reference ${formatList(\n violation.contextRoots ?? [],\n )} with a literal dot key.`,\n path: params.path,\n details: {\n field: params.field,\n source: params.source,\n expression: violation.source,\n contextRoots: violation.contextRoots,\n },\n });\n }\n\n return issue({\n code: 'runner-context-not-bare',\n message: `${fieldLabel(params.field)} interpolation references runner context in a larger expression; ${violation.hint}.`,\n path: params.path,\n details: {\n field: params.field,\n source: params.source,\n expression: violation.source,\n runnerRoots: violation.runnerRoots ?? [],\n },\n });\n}\n\nfunction contextNoun(roots: readonly WorkflowContextName[]): 'context' | 'contexts' {\n return roots.length === 1 ? 'context' : 'contexts';\n}\n\nfunction availabilityVerb(roots: readonly WorkflowContextName[]): 'is' | 'are' {\n return roots.length === 1 ? 'is' : 'are';\n}\n\nfunction unavailableRootAvailabilityMessage(root: WorkflowContextName): string {\n const availability = getWorkflowContextAvailability(root);\n if (availability === undefined) return `\"${root}\" is not available at any server site.`;\n return `\"${root}\" becomes available at ${describeAvailabilitySite(availability)}.`;\n}\n\nfunction describeAvailabilitySite(site: AvailabilitySite): string {\n return availabilitySiteLabels[site];\n}\n\nfunction hasSyntaxOnlyCheckMode(root: WorkflowContextName): boolean {\n return getWorkflowContextDefinition(root).checkMode === 'syntax';\n}\n\nfunction mergeTypeEnvironments(\n roots: readonly WorkflowContextName[],\n typeOverlay?: ExpressionTypeEnvironment,\n): ExpressionTypeEnvironment {\n const typeEnvironment: Record<string, ExpressionTypeEnvironment[string]> = {};\n\n for (const root of roots) {\n const overlayType = typeOverlay?.[root];\n if (overlayType !== undefined) {\n typeEnvironment[root] = overlayType;\n continue;\n }\n\n const contextTypeEnvironment = getWorkflowContextTypeEnvironment(root);\n if (contextTypeEnvironment === undefined) {\n if (typeOverlay !== undefined) typeEnvironment[root] = {kind: 'map'};\n continue;\n }\n\n Object.assign(typeEnvironment, contextTypeEnvironment);\n }\n\n return typeEnvironment;\n}\n\nfunction isExpressionSegment(\n segment: WorkflowTemplateSegment,\n): segment is WorkflowTemplateExprSegment {\n return segment.kind === 'expr';\n}\n\nfunction isWorkflowContextName(root: string): root is WorkflowContextName {\n return (workflowContextNames as readonly string[]).includes(root);\n}\n\nfunction uniqueStrings(values: readonly string[]): readonly string[] {\n return [...new Set(values)];\n}\n\nfunction formatList(values: readonly string[]): string {\n return values.map((value) => `\"${value}\"`).join(', ');\n}\n\nfunction fieldLabel(field: WorkflowInterpolationField): string {\n return `Workflow ${field}`;\n}\n\nfunction issue(params: {\n code: WorkflowModelValidationIssueCode;\n message: string;\n path: readonly WorkflowModelValidationIssuePathSegment[];\n details?: Readonly<Record<string, unknown>>;\n}): WorkflowModelValidationIssue {\n if (params.details === undefined) {\n return {\n code: params.code,\n message: params.message,\n path: params.path,\n };\n }\n\n return {\n code: params.code,\n message: params.message,\n path: params.path,\n details: params.details,\n };\n}\n"],"names":["secretKeySchema","secretStoreSchema","analyzeContextKeyAccess","createWorkflowExpression","extractCelUntrustedPathAccesses","getWorkflowContextAvailability","getWorkflowContextDefinition","getWorkflowContextHost","getWorkflowContextTypeEnvironment","getWorkflowContextUntrustedPaths","InvalidWorkflowExpressionError","InvalidWorkflowTemplateError","parseWorkflowTemplate","planInterpolationField","unavailableRootsAt","workflowContextNames","workflowInterpolationFieldAcceptsContext","workflowInterpolationFieldAcceptsHost","workflowInterpolationFieldAcceptsTrustTier","validateDirectJobReferences","parseInterpolationField","params","segments","parseTemplate","undefined","expressionSegments","filter","isExpressionSegment","length","checkedSegments","map","segment","kind","validatedSegment","validateExpressionSegment","plan","field","ok","issues","push","violations","violation","planViolationIssue","source","error","issue","code","message","fieldLabel","path","details","reason","contextRoots","uniqueStrings","knownRoots","isWorkflowContextName","unknownRoots","root","rejectedRoots","untrustedContextIssue","rejectedHostRoots","runnerContextInFieldIssue","keyAccess","expression","computedContextKeyIssue","invalidReferenceIssue","validateContextKeyReferences","references","invalidJobReferenceIssue","allowedJobReferences","rejectedPathRoots","findUntrustedPathRoots","formatList","fillSite","serverRoots","unavailableRoots","unavailableContextIssue","typeOverlay","some","hasSyntaxOnlyCheckMode","check","mode","typeEnvironment","mergeTypeEnvironments","isTrustedOnlyField","untrustedPathsByRoot","Map","paths","set","includes","Set","get","size","reference","safeParse","key","success","store","availabilitySiteLabels","ingest","contextNoun","availabilityVerb","describeAvailabilitySite","unavailableRootAvailabilityMessage","join","hint","runnerRoots","roots","availability","site","checkMode","overlayType","contextTypeEnvironment","Object","assign","values","value"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stable-id.d.ts","sourceRoot":"","sources":["../../../src/core/workflow-model/stable-id.ts"],"names":[],"mappings":"AAGA,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAQnD"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const nonStableIdPattern = /[^a-z0-9]+/g;
|
|
2
|
+
const edgeDashPattern = /^-+|-+$/g;
|
|
3
|
+
export function stableId(sourceName) {
|
|
4
|
+
const id = sourceName.trim().toLowerCase().replace(nonStableIdPattern, '-').replace(edgeDashPattern, '');
|
|
5
|
+
return id.length === 0 ? 'unnamed' : id;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
//# sourceMappingURL=stable-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/core/workflow-model/stable-id.ts"],"sourcesContent":["const nonStableIdPattern = /[^a-z0-9]+/g;\nconst edgeDashPattern = /^-+|-+$/g;\n\nexport function stableId(sourceName: string): string {\n const id = sourceName\n .trim()\n .toLowerCase()\n .replace(nonStableIdPattern, '-')\n .replace(edgeDashPattern, '');\n\n return id.length === 0 ? 'unnamed' : id;\n}\n"],"names":["nonStableIdPattern","edgeDashPattern","stableId","sourceName","id","trim","toLowerCase","replace","length"],"mappings":"AAAA,MAAMA,qBAAqB;AAC3B,MAAMC,kBAAkB;AAExB,OAAO,SAASC,SAASC,UAAkB;IACzC,MAAMC,KAAKD,WACRE,IAAI,GACJC,WAAW,GACXC,OAAO,CAACP,oBAAoB,KAC5BO,OAAO,CAACN,iBAAiB;IAE5B,OAAOG,GAAGI,MAAM,KAAK,IAAI,YAAYJ;AACvC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type WorkflowExpression, type WorkflowInterpolationField, type WorkflowPredicateField } from '@shipfox/expression';
|
|
2
|
+
import type { WorkflowModelValidationIssue, WorkflowModelValidationIssuePathSegment } from './invalid-workflow-model-error.js';
|
|
3
|
+
export declare function validateDirectJobReferences(params: {
|
|
4
|
+
source: string;
|
|
5
|
+
expression: WorkflowExpression;
|
|
6
|
+
field: WorkflowInterpolationField | WorkflowPredicateField;
|
|
7
|
+
path: readonly WorkflowModelValidationIssuePathSegment[];
|
|
8
|
+
allowedJobReferences: ReadonlySet<string>;
|
|
9
|
+
}): WorkflowModelValidationIssue | undefined;
|
|
10
|
+
//# sourceMappingURL=validate-job-references.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-job-references.d.ts","sourceRoot":"","sources":["../../../src/core/workflow-model/validate-job-references.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,EAC5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EACV,4BAA4B,EAC5B,uCAAuC,EACxC,MAAM,mCAAmC,CAAC;AAI3C,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,kBAAkB,CAAC;IAC/B,KAAK,EAAE,0BAA0B,GAAG,sBAAsB,CAAC;IAC3D,IAAI,EAAE,SAAS,uCAAuC,EAAE,CAAC;IACzD,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC3C,GAAG,4BAA4B,GAAG,SAAS,CAkC3C"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { analyzeContextRootKeyAccess } from '@shipfox/expression';
|
|
2
|
+
import { issue } from './validation-issue.js';
|
|
3
|
+
import { workflowFieldLabel } from './workflow-field-label.js';
|
|
4
|
+
export function validateDirectJobReferences(params) {
|
|
5
|
+
const access = analyzeContextRootKeyAccess(params.expression, [
|
|
6
|
+
'jobs'
|
|
7
|
+
]);
|
|
8
|
+
const [computed] = access.violations;
|
|
9
|
+
if (computed !== undefined) {
|
|
10
|
+
return issue({
|
|
11
|
+
code: 'computed-context-key',
|
|
12
|
+
message: `${workflowFieldLabel(params.field)} must reference jobs with a literal dot key.`,
|
|
13
|
+
path: params.path,
|
|
14
|
+
details: {
|
|
15
|
+
field: params.field,
|
|
16
|
+
source: params.source,
|
|
17
|
+
expression: computed.source,
|
|
18
|
+
contextRoots: [
|
|
19
|
+
'jobs'
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
const missing = access.references.find((reference)=>!params.allowedJobReferences.has(reference.key));
|
|
25
|
+
if (missing === undefined) return undefined;
|
|
26
|
+
return issue({
|
|
27
|
+
code: 'missing-job-needs-edge',
|
|
28
|
+
message: `${workflowFieldLabel(params.field)} references job "${missing.key}" without a direct needs edge.`,
|
|
29
|
+
path: params.path,
|
|
30
|
+
details: {
|
|
31
|
+
field: params.field,
|
|
32
|
+
source: params.source,
|
|
33
|
+
expression: params.expression.source,
|
|
34
|
+
job: missing.key,
|
|
35
|
+
allowedJobs: [
|
|
36
|
+
...params.allowedJobReferences
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
//# sourceMappingURL=validate-job-references.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/core/workflow-model/validate-job-references.ts"],"sourcesContent":["import {\n analyzeContextRootKeyAccess,\n type WorkflowExpression,\n type WorkflowInterpolationField,\n type WorkflowPredicateField,\n} from '@shipfox/expression';\nimport type {\n WorkflowModelValidationIssue,\n WorkflowModelValidationIssuePathSegment,\n} from './invalid-workflow-model-error.js';\nimport {issue} from './validation-issue.js';\nimport {workflowFieldLabel} from './workflow-field-label.js';\n\nexport function validateDirectJobReferences(params: {\n source: string;\n expression: WorkflowExpression;\n field: WorkflowInterpolationField | WorkflowPredicateField;\n path: readonly WorkflowModelValidationIssuePathSegment[];\n allowedJobReferences: ReadonlySet<string>;\n}): WorkflowModelValidationIssue | undefined {\n const access = analyzeContextRootKeyAccess(params.expression, ['jobs']);\n const [computed] = access.violations;\n if (computed !== undefined) {\n return issue({\n code: 'computed-context-key',\n message: `${workflowFieldLabel(params.field)} must reference jobs with a literal dot key.`,\n path: params.path,\n details: {\n field: params.field,\n source: params.source,\n expression: computed.source,\n contextRoots: ['jobs'],\n },\n });\n }\n\n const missing = access.references.find(\n (reference) => !params.allowedJobReferences.has(reference.key),\n );\n if (missing === undefined) return undefined;\n\n return issue({\n code: 'missing-job-needs-edge',\n message: `${workflowFieldLabel(params.field)} references job \"${missing.key}\" without a direct needs edge.`,\n path: params.path,\n details: {\n field: params.field,\n source: params.source,\n expression: params.expression.source,\n job: missing.key,\n allowedJobs: [...params.allowedJobReferences],\n },\n });\n}\n"],"names":["analyzeContextRootKeyAccess","issue","workflowFieldLabel","validateDirectJobReferences","params","access","expression","computed","violations","undefined","code","message","field","path","details","source","contextRoots","missing","references","find","reference","allowedJobReferences","has","key","job","allowedJobs"],"mappings":"AAAA,SACEA,2BAA2B,QAItB,sBAAsB;AAK7B,SAAQC,KAAK,QAAO,wBAAwB;AAC5C,SAAQC,kBAAkB,QAAO,4BAA4B;AAE7D,OAAO,SAASC,4BAA4BC,MAM3C;IACC,MAAMC,SAASL,4BAA4BI,OAAOE,UAAU,EAAE;QAAC;KAAO;IACtE,MAAM,CAACC,SAAS,GAAGF,OAAOG,UAAU;IACpC,IAAID,aAAaE,WAAW;QAC1B,OAAOR,MAAM;YACXS,MAAM;YACNC,SAAS,GAAGT,mBAAmBE,OAAOQ,KAAK,EAAE,4CAA4C,CAAC;YAC1FC,MAAMT,OAAOS,IAAI;YACjBC,SAAS;gBACPF,OAAOR,OAAOQ,KAAK;gBACnBG,QAAQX,OAAOW,MAAM;gBACrBT,YAAYC,SAASQ,MAAM;gBAC3BC,cAAc;oBAAC;iBAAO;YACxB;QACF;IACF;IAEA,MAAMC,UAAUZ,OAAOa,UAAU,CAACC,IAAI,CACpC,CAACC,YAAc,CAAChB,OAAOiB,oBAAoB,CAACC,GAAG,CAACF,UAAUG,GAAG;IAE/D,IAAIN,YAAYR,WAAW,OAAOA;IAElC,OAAOR,MAAM;QACXS,MAAM;QACNC,SAAS,GAAGT,mBAAmBE,OAAOQ,KAAK,EAAE,iBAAiB,EAAEK,QAAQM,GAAG,CAAC,8BAA8B,CAAC;QAC3GV,MAAMT,OAAOS,IAAI;QACjBC,SAAS;YACPF,OAAOR,OAAOQ,KAAK;YACnBG,QAAQX,OAAOW,MAAM;YACrBT,YAAYF,OAAOE,UAAU,CAACS,MAAM;YACpCS,KAAKP,QAAQM,GAAG;YAChBE,aAAa;mBAAIrB,OAAOiB,oBAAoB;aAAC;QAC/C;IACF;AACF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type AvailabilitySite, type ExpressionTypeEnvironment, type WorkflowExpression, type WorkflowPredicateField } from '@shipfox/expression';
|
|
2
|
+
import type { WorkflowModelValidationIssue, WorkflowModelValidationIssueCode, WorkflowModelValidationIssuePathSegment } from './invalid-workflow-model-error.js';
|
|
3
|
+
export declare function validatePredicateExpression(params: {
|
|
4
|
+
field: WorkflowPredicateField;
|
|
5
|
+
source: string;
|
|
6
|
+
site: AvailabilitySite;
|
|
7
|
+
path: readonly WorkflowModelValidationIssuePathSegment[];
|
|
8
|
+
invalidCode: WorkflowModelValidationIssueCode;
|
|
9
|
+
invalidMessage: string;
|
|
10
|
+
issues: WorkflowModelValidationIssue[];
|
|
11
|
+
allowedJobReferences?: ReadonlySet<string>;
|
|
12
|
+
typeOverlay?: ExpressionTypeEnvironment | undefined;
|
|
13
|
+
}): WorkflowExpression | undefined;
|
|
14
|
+
//# sourceMappingURL=validate-predicate-expression.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-predicate-expression.d.ts","sourceRoot":"","sources":["../../../src/core/workflow-model/validate-predicate-expression.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,gBAAgB,EAIrB,KAAK,yBAAyB,EAW9B,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAE5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EACV,4BAA4B,EAC5B,gCAAgC,EAChC,uCAAuC,EACxC,MAAM,mCAAmC,CAAC;AAK3C,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IAClD,KAAK,EAAE,sBAAsB,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,SAAS,uCAAuC,EAAE,CAAC;IACzD,WAAW,EAAE,gCAAgC,CAAC;IAC9C,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,4BAA4B,EAAE,CAAC;IACvC,oBAAoB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3C,WAAW,CAAC,EAAE,yBAAyB,GAAG,SAAS,CAAC;CACrD,GAAG,kBAAkB,GAAG,SAAS,CAqHjC"}
|