@starci/hfs 4.7.32 → 4.7.33
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/CHANGELOG.md +9 -0
- package/README.md +13 -6
- package/emit/contracts.mjs +4 -3
- package/emit/form-bounds-reader.ts.partial +58 -0
- package/emit/form-bounds.mjs +155 -0
- package/emit/graphql-input-bounds.mjs +97 -0
- package/emit/input-bounds.mjs +44 -0
- package/emit/operation-schemas.mjs +137 -0
- package/emit/operations-worker.mjs +2 -2
- package/emit/operations.mjs +52 -16
- package/emit/schema-worker.mjs +17 -4
- package/emit/type-schema.mjs +17 -5
- package/package.json +9 -2
- package/release/gate.mjs +18 -23
- package/release/index.mjs +1 -1
- package/release/push.mjs +4 -5
- package/runtime/engine/admission.mjs +331 -0
- package/runtime/engine/canonical-json.mjs +14 -0
- package/runtime/engine/db/blob.mjs +380 -0
- package/runtime/engine/db/event-compact.mjs +73 -0
- package/runtime/engine/db/ledger-open.mjs +38 -0
- package/runtime/engine/db/ledger-paths.mjs +87 -0
- package/runtime/engine/db/ledger.mjs +1068 -0
- package/runtime/engine/db/machine-connection.mjs +150 -0
- package/runtime/engine/db/machine-open.mjs +60 -0
- package/runtime/engine/db/machine-schema.mjs +105 -0
- package/runtime/engine/db/machine.mjs +1317 -0
- package/runtime/engine/db/provider-reservations.mjs +127 -0
- package/runtime/engine/db/provision-authority.mjs +76 -0
- package/runtime/engine/db/provision-lock.mjs +29 -0
- package/runtime/engine/db/provision-operations.mjs +146 -0
- package/runtime/engine/db/ref-value.mjs +67 -0
- package/runtime/engine/db/schema/machine.sql +920 -0
- package/runtime/engine/db/schema/runtime.sql +1113 -0
- package/runtime/engine/refuse.mjs +11 -0
- package/runtime/knowledge/hfs/canon-pins.yaml +65 -9
- package/runtime/knowledge/hfs/design-truths.yaml +149 -0
- package/runtime/knowledge/hfs/fe-stack.yaml +23 -5
- package/runtime/knowledge/hfs/rules.yaml +269 -48
- package/runtime/knowledge/hfs/slots.yaml +113 -53
- package/runtime/knowledge/patterns/be/api.yaml +46 -20
- package/runtime/knowledge/patterns/be/event-bus.yaml +19 -12
- package/runtime/knowledge/patterns/be/idempotency.yaml +265 -0
- package/runtime/knowledge/patterns/be/jobs.yaml +17 -12
- package/runtime/knowledge/patterns/be/projections.yaml +2 -2
- package/runtime/knowledge/patterns/be/queues.yaml +57 -22
- package/runtime/knowledge/patterns/be/reactors.yaml +1 -1
- package/runtime/knowledge/patterns/be/realtime.yaml +326 -27
- package/runtime/knowledge/patterns/be/saga.yaml +2 -2
- package/runtime/knowledge/sonar-gate.yaml +1 -1
- package/runtime/modules/kernel/command-policy.yaml +249 -0
- package/runtime/modules/kernel/failure-codes.yaml +211 -52
- package/runtime/modules/kernel/hook-input.yaml +6 -0
- package/runtime/modules/kernel/protected-zone.yaml +81 -0
- package/runtime/modules/kernel/removed-vocabulary.yaml +62 -0
- package/runtime/modules/kernel/roles.yaml +405 -0
- package/runtime/modules/models/registry.yaml +3 -1
- package/runtime/modules/models/runtimes.yaml +2 -0
- package/runtime/modules/schemas/application-stacks.schema.yaml +10 -2
- package/runtime/packages/cli/src/catalog.generated.mjs +46 -59
- package/runtime/packages/grammar/scripts/build-stamp.mjs +98 -0
- package/runtime/scripts/agent/codex-app-server.mjs +79 -0
- package/runtime/scripts/agent/codex-mirror-source.mjs +34 -0
- package/runtime/scripts/agent/host-agents.mjs +80 -0
- package/runtime/scripts/agent/launch-trust-policy.mjs +53 -0
- package/runtime/scripts/agent/trust-launch.mjs +191 -0
- package/runtime/scripts/agent/trust.mjs +523 -0
- package/runtime/scripts/api/fs/rename-over.mjs +21 -0
- package/runtime/scripts/api/fs/temp-path.mjs +8 -0
- package/runtime/scripts/api/fs/write-json-file.mjs +10 -0
- package/runtime/scripts/api/git/diff-names.mjs +8 -0
- package/runtime/scripts/api/git/head-time.mjs +10 -0
- package/runtime/scripts/api/git/index-lock.mjs +78 -0
- package/runtime/scripts/api/git/is-ancestor.mjs +5 -0
- package/runtime/scripts/api/git/log.mjs +5 -0
- package/runtime/scripts/api/git/merge-base-query.mjs +5 -0
- package/runtime/scripts/api/git/merge-tree.mjs +5 -0
- package/runtime/scripts/api/git/rev-list.mjs +5 -0
- package/runtime/scripts/api/git/rev-parse.mjs +13 -0
- package/runtime/scripts/api/git/status-query.mjs +5 -0
- package/runtime/scripts/api/git/worktree-list-query.mjs +5 -0
- package/runtime/scripts/api/node/spawn-node.mjs +6 -0
- package/runtime/scripts/api/npm/dist-tag.mjs +8 -0
- package/runtime/scripts/api/npm/lib.mjs +32 -0
- package/runtime/scripts/api/npm/pack-dry-run.mjs +9 -0
- package/runtime/scripts/api/npm/run-npm.mjs +6 -0
- package/runtime/scripts/api/npm/view.mjs +30 -0
- package/runtime/scripts/api/npm/whoami.mjs +8 -0
- package/runtime/scripts/api/process/hide-child-windows.mjs +31 -0
- package/runtime/scripts/api/process/kill-tree.mjs +22 -0
- package/runtime/scripts/api/process/lib.mjs +125 -0
- package/runtime/scripts/api/process/probe-guard-command.mjs +74 -0
- package/runtime/scripts/api/process/process-list.mjs +28 -0
- package/runtime/scripts/api/process/system-tool.mjs +37 -0
- package/runtime/scripts/gates/canon-digest.mjs +81 -0
- package/runtime/scripts/gates/canon-pins.mjs +16 -0
- package/runtime/scripts/gates/commit-proof.mjs +53 -0
- package/runtime/scripts/gates/gate-input.mjs +98 -0
- package/runtime/scripts/gates/gate.mjs +669 -0
- package/runtime/scripts/gates/grammar-dist.mjs +206 -0
- package/runtime/scripts/gates/runtime-package-selection.mjs +27 -0
- package/runtime/scripts/gates/test-world-run.mjs +254 -0
- package/runtime/scripts/gates/type-impact.mjs +277 -0
- package/runtime/scripts/gates/type-program.mjs +113 -0
- package/runtime/scripts/guards/assigned-command.mjs +12 -0
- package/runtime/scripts/guards/call-rights.mjs +47 -0
- package/runtime/scripts/guards/command-guard.mjs +468 -0
- package/runtime/scripts/guards/command-policy.mjs +342 -0
- package/runtime/scripts/guards/critic-reach.mjs +82 -0
- package/runtime/scripts/guards/deps-guard.mjs +150 -0
- package/runtime/scripts/guards/env-dump-verdict.mjs +89 -0
- package/runtime/scripts/guards/git-pathspec.mjs +225 -0
- package/runtime/scripts/guards/git-policy.mjs +355 -0
- package/runtime/scripts/guards/guards-root.mjs +27 -0
- package/runtime/scripts/guards/hook-install.mjs +343 -0
- package/runtime/scripts/guards/hook-io.mjs +76 -0
- package/runtime/scripts/guards/hook-verdict.mjs +12 -0
- package/runtime/scripts/guards/install-verdict.mjs +41 -0
- package/runtime/scripts/guards/kernel-seat.mjs +63 -0
- package/runtime/scripts/guards/launch-verdict.mjs +74 -0
- package/runtime/scripts/guards/op-starci.mjs +16 -0
- package/runtime/scripts/guards/op-write-scope.mjs +27 -0
- package/runtime/scripts/guards/orca-self-lifecycle.mjs +39 -0
- package/runtime/scripts/guards/process-kill-verdict.mjs +106 -0
- package/runtime/scripts/guards/protected-zone.mjs +56 -0
- package/runtime/scripts/guards/refusals.mjs +27 -0
- package/runtime/scripts/guards/release-definition.mjs +185 -0
- package/runtime/scripts/guards/release-push-gate.mjs +72 -0
- package/runtime/scripts/guards/release-record.mjs +58 -0
- package/runtime/scripts/guards/release-suite-mode.mjs +15 -0
- package/runtime/scripts/guards/rights.mjs +268 -0
- package/runtime/scripts/guards/seat-tools.mjs +47 -0
- package/runtime/scripts/guards/shell-commands.mjs +328 -0
- package/runtime/scripts/guards/supervisor-seat.mjs +80 -0
- package/runtime/scripts/guards/verdict-process.mjs +81 -0
- package/runtime/scripts/hfs/architecture/dead-exports.mjs +10 -10
- package/runtime/scripts/hfs/architecture/function-spec-providers.mjs +1 -1
- package/runtime/scripts/hfs/architecture/operation-contract-roots.mjs +53 -0
- package/runtime/scripts/hfs/architecture/reachability.mjs +1 -1
- package/runtime/scripts/hfs/architecture/sql-owner.mjs +17 -6
- package/runtime/scripts/hfs/architecture/sql-token-forms.mjs +105 -0
- package/runtime/scripts/hfs/architecture/sql-tokens.mjs +38 -52
- package/runtime/scripts/hfs/architecture/supabase-keys.mjs +261 -0
- package/runtime/scripts/hfs/architecture/transport-owner.mjs +49 -3
- package/runtime/scripts/hfs/architecture/typescript.mjs +1 -1
- package/runtime/scripts/hfs/check.mjs +6 -4
- package/runtime/scripts/hfs/coverage-scope.mjs +28 -1
- package/runtime/scripts/hfs/db-restamp-verb.mjs +54 -14
- package/runtime/scripts/hfs/declaration-shape.mjs +4 -4
- package/runtime/scripts/hfs/declaration-slots.mjs +14 -3
- package/runtime/scripts/hfs/manifest-shape.mjs +10 -6
- package/runtime/scripts/hfs/rule-params-shape.mjs +18 -6
- package/runtime/scripts/hfs/rules/a15-findings.mjs +4 -1
- package/runtime/scripts/hfs/rules/bypass-markers.mjs +22 -7
- package/runtime/scripts/hfs/rules/database-migrations.mjs +69 -14
- package/runtime/scripts/hfs/rules/database-queue-sources.mjs +9 -7
- package/runtime/scripts/hfs/rules/database-queues.mjs +68 -18
- package/runtime/scripts/hfs/rules/edition.mjs +56 -12
- package/runtime/scripts/hfs/rules/fe-contract-documents.mjs +1 -10
- package/runtime/scripts/hfs/rules/fe-stack.mjs +12 -7
- package/runtime/scripts/hfs/rules/lite-proof-lane.mjs +1 -1
- package/runtime/scripts/hfs/rules/stacks-lite-backing.mjs +75 -9
- package/runtime/scripts/hfs/rules/stacks-runtime.mjs +1 -1
- package/runtime/scripts/hfs/rules/stacks-swarm.mjs +15 -4
- package/runtime/scripts/hfs/rules/text-integrity.mjs +73 -0
- package/runtime/scripts/hfs/runtime-rules/hook-shape.mjs +74 -0
- package/runtime/scripts/hfs/runtime-rules/release-notes.mjs +44 -0
- package/runtime/scripts/hfs/sealed-members.mjs +3 -3
- package/runtime/scripts/hfs/slot-side-problems.mjs +3 -3
- package/runtime/scripts/hfs/slots.mjs +2 -1
- package/runtime/scripts/hfs/stack-deploy-config.mjs +22 -5
- package/runtime/scripts/hfs/stacks-gate.mjs +28 -7
- package/runtime/scripts/hfs/view.mjs +2 -1
- package/runtime/scripts/lib/app-data.mjs +11 -0
- package/runtime/scripts/lib/bypass-markers.mjs +272 -75
- package/runtime/scripts/lib/check-format.mjs +7 -0
- package/runtime/scripts/lib/cli-arg.mjs +120 -0
- package/runtime/scripts/lib/css-rules.mjs +220 -0
- package/runtime/scripts/lib/dom-tree.mjs +4 -0
- package/runtime/scripts/lib/escape.mjs +16 -0
- package/runtime/scripts/lib/event-items.mjs +22 -0
- package/runtime/scripts/lib/failure-code-template-errors.mjs +161 -0
- package/runtime/scripts/lib/git-dir.mjs +120 -0
- package/runtime/scripts/lib/grammar-vendor-parity.mjs +377 -0
- package/runtime/scripts/lib/guard-command.mjs +24 -0
- package/runtime/scripts/lib/hook-limits.mjs +5 -0
- package/runtime/scripts/lib/interrupt-cleanup.mjs +38 -0
- package/runtime/scripts/lib/js-lex.mjs +200 -0
- package/runtime/scripts/lib/json-formats.mjs +0 -1
- package/runtime/scripts/lib/language.mjs +94 -1
- package/runtime/scripts/lib/loosening-budgets.mjs +44 -0
- package/runtime/scripts/lib/loosening-config.mjs +361 -0
- package/runtime/scripts/lib/loosening-state.mjs +223 -0
- package/runtime/scripts/lib/menu-parts.mjs +11 -0
- package/runtime/scripts/lib/normalize.mjs +25 -0
- package/runtime/scripts/lib/op-gate.mjs +15 -0
- package/runtime/scripts/lib/redact.mjs +208 -0
- package/runtime/scripts/lib/runtime-location.mjs +21 -0
- package/runtime/scripts/lib/runtime-package-inventory.mjs +21 -0
- package/runtime/scripts/lib/runtime-package-manifests.mjs +84 -0
- package/runtime/scripts/lib/runtime-publication-tags.mjs +99 -0
- package/runtime/scripts/lib/seat-env.mjs +43 -0
- package/runtime/scripts/lib/secret-patterns.mjs +58 -9
- package/runtime/scripts/lib/shell-source.mjs +4 -0
- package/runtime/scripts/lib/source-phrases.mjs +34 -0
- package/runtime/scripts/lib/sqlite.mjs +21 -0
- package/runtime/scripts/lib/swarm-stack.mjs +2 -1
- package/runtime/scripts/lib/tar-files.mjs +39 -0
- package/runtime/scripts/lib/ts-analysis.mjs +10 -0
- package/runtime/scripts/lib/worktree-exclude.mjs +35 -0
- package/runtime/scripts/lib/worktree-record.mjs +14 -0
- package/runtime/scripts/machine/artifact-hold.mjs +52 -0
- package/runtime/scripts/machine/ask-receipts.mjs +113 -0
- package/runtime/scripts/machine/evidence-store.mjs +223 -0
- package/runtime/scripts/machine/home.mjs +216 -0
- package/runtime/scripts/machine/host-lock.mjs +184 -0
- package/runtime/scripts/machine/lock-recovery.mjs +55 -0
- package/runtime/scripts/machine/roles-contract.mjs +90 -0
- package/runtime/scripts/machine/runtime-change.mjs +20 -0
- package/runtime/scripts/machine/workflow-tree.mjs +122 -0
- package/runtime/scripts/reconciler/checklist-items.mjs +7 -0
- package/runtime/scripts/reconciler/guard-row.mjs +25 -0
- package/runtime/scripts/work/asset-slot.mjs +284 -0
- package/runtime/scripts/work/brand/brand-colour.mjs +125 -0
- package/runtime/scripts/work/brand/brand-tokens.mjs +167 -0
- package/runtime/scripts/work/brand/brand-value-source.mjs +106 -0
- package/runtime/scripts/work/brand/brand.mjs +892 -0
- package/runtime/scripts/work/draw/draw-dna-anatomy.mjs +60 -0
- package/runtime/scripts/work/draw/draw-dna-findings.mjs +256 -0
- package/runtime/scripts/work/draw/draw-dna-selector.mjs +38 -0
- package/runtime/scripts/work/draw/draw-dna.mjs +483 -0
- package/runtime/scripts/work/draw/draw-layer.mjs +305 -0
- package/runtime/scripts/work/draw/draw-rationale-page.mjs +237 -0
- package/runtime/scripts/work/draw/draw-rationale-ref.mjs +14 -0
- package/runtime/scripts/work/draw/draw-rationale.mjs +353 -0
- package/runtime/scripts/work/draw/draw-source.mjs +412 -0
- package/runtime/scripts/work/draw/draw-taste.mjs +278 -0
- package/runtime/scripts/work/draw/draw-typecheck.mjs +72 -0
- package/runtime/scripts/work/draw/rationale-findings.mjs +205 -0
- package/runtime/scripts/work/draw-grammar.mjs +175 -0
- package/runtime/scripts/work/draw-render-page.mjs +188 -0
- package/runtime/scripts/work/draw-render.mjs +626 -0
- package/runtime/scripts/work/grammar-proposal.mjs +279 -0
- package/runtime/scripts/work/png.mjs +237 -0
- package/runtime/scripts/work/render-tools.mjs +64 -0
- package/runtime/scripts/work/work-io.mjs +119 -0
- package/scaffold/add-inbox-lite.mjs +2 -2
- package/scaffold/add-plan.mjs +40 -13
- package/scaffold/add-queue-lite.mjs +372 -0
- package/scaffold/add.mjs +5 -2
- package/scaffold/app.mjs +1 -2
- package/scaffold/edition-gate.mjs +11 -7
- package/scaffold/lite-exports.mjs +10 -0
- package/scaffold/pattern-file-slots.mjs +33 -0
- package/scaffold/test-world.mjs +1 -1
- package/scaffold/yaml-block-edit.mjs +117 -0
- package/src/main.mjs +5 -4
- package/stack/deploy.mjs +7 -3
- package/stack/post-deploy.mjs +48 -0
- package/sync/index.mjs +10 -0
- package/templates/app/ci-workflows/github/workflows/stack-deploy.yml +1 -1
- package/templates/app/ci-workflows-lite/github/workflows/stack-deploy.yml +1 -1
- package/templates/app/codegen-graphql.mjs.partial +59 -12
- package/templates/app/hooks/husky/pre-commit +2 -2
- package/templates/app/hooks/husky/pre-push +10 -3
- package/templates/app/package-scripts/redis-dev.json +3 -0
- package/templates/app/package-scripts-lite/package.json +1 -0
- package/templates/app/skeleton/.starcistacks/application-stacks.yaml +36 -8
- package/templates/app/skeleton/.starcistacks/dev/README.md +1 -1
- package/templates/app/skeleton/.starcistacks/production/README.md +10 -9
- package/templates/app/skeleton/.starcistacks/production/infra/swarm/postgres-init.sh +21 -0
- package/templates/app/skeleton/.starcistacks/production/infra/swarm/recovery/restore-proof.md +1 -1
- package/templates/app/skeleton/.starcistacks/production/infra/swarm/releases/images.lock.yaml +1 -0
- package/templates/app/skeleton/.starcistacks/production/infra/swarm/stack.yaml +47 -5
- package/templates/app/skeleton/.starcistacks/production/runtime/env/KEYS.md +5 -3
- package/templates/app/skeleton/README.md +2 -0
- package/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml +5 -0
- package/templates/app/skeleton-lite/.starcistacks/dev/README.md +2 -2
- package/templates/app/skeleton-lite/.starcistacks/production/README.md +1 -1
- package/templates/app/skeleton-lite/README.md +1 -1
- package/templates/be/inbox/platform/client-operation-outcomes.sql.tpl +18 -0
- package/templates/be/inbox/platform/event-bus/errors/event-bus.error.ts.tpl +16 -0
- package/templates/be/inbox/platform/event-bus/event-bus.contracts.ts.tpl +10 -0
- package/templates/be/inbox/platform/event-bus/event-bus.port.ts.tpl +1 -1
- package/templates/be/inbox/platform/event-bus/event-bus.service.spec.ts.tpl +15 -3
- package/templates/be/inbox/platform/event-bus/event-bus.service.ts.tpl +11 -3
- package/templates/be/inbox/platform/event-bus/index.ts.tpl +2 -0
- package/templates/be/inbox/platform/event-bus/messages/event-bus.messages.ts.tpl +7 -0
- package/templates/be/inbox/platform/event-bus/persistence/event-bus.sql.ts.tpl +2 -2
- package/templates/be/inbox/platform/idempotency/errors/idempotency.error.ts.tpl +19 -0
- package/templates/be/inbox/platform/idempotency/index.ts.tpl +2 -0
- package/templates/be/inbox/platform/idempotency/messages/idempotency.messages.ts.tpl +13 -0
- package/templates/be/inbox/platform/inbox/client-operation.policy.spec.ts.tpl +32 -0
- package/templates/be/inbox/platform/inbox/client-operation.policy.ts.tpl +17 -0
- package/templates/be/inbox/platform/inbox/errors/inbox.error.ts.tpl +22 -0
- package/templates/be/inbox/platform/inbox/inbox.port.ts.tpl +21 -0
- package/templates/be/inbox/platform/inbox/inbox.service.spec.ts.tpl +334 -11
- package/templates/be/inbox/platform/inbox/inbox.service.ts.tpl +55 -4
- package/templates/be/inbox/platform/inbox/index.ts.tpl +2 -0
- package/templates/be/inbox/platform/inbox/messages/inbox.messages.ts.tpl +15 -0
- package/templates/be/inbox/platform/inbox/persistence/inbox.rows.ts.tpl +33 -0
- package/templates/be/inbox/platform/inbox/persistence/inbox.sql.ts.tpl +26 -0
- package/templates/be/inbox/platform/inbox/request-fingerprint.policy.spec.ts.tpl +76 -0
- package/templates/be/inbox/platform/inbox/request-fingerprint.policy.ts.tpl +36 -0
- package/templates/be/inbox/platform/migration.sql.tpl +1 -0
- package/templates/be/inbox/service.spec.ts.tpl +4 -4
- package/templates/be/inbox/service.ts.tpl +3 -1
- package/templates/be/inbox/webhook-door.spec.ts.tpl +3 -2
- package/templates/be/inbox/webhook-door.ts.tpl +3 -2
- package/templates/be/patterns/event-bus/platform/errors/event-bus.error.ts.tpl +3 -0
- package/templates/be/patterns/event-bus/platform/event-bus.contracts.ts.tpl +10 -0
- package/templates/be/patterns/event-bus/platform/event-bus.port.ts.tpl +2 -2
- package/templates/be/patterns/event-bus/platform/event-bus.service.spec.ts.tpl +16 -3
- package/templates/be/patterns/event-bus/platform/event-bus.service.ts.tpl +11 -3
- package/templates/be/patterns/event-bus/platform/event-envelope.policy.spec.ts.tpl +139 -50
- package/templates/be/patterns/event-bus/platform/event-envelope.policy.ts.tpl +25 -2
- package/templates/be/patterns/event-bus/platform/event-relay.service.spec.ts.tpl +139 -78
- package/templates/be/patterns/event-bus/platform/event-relay.service.ts.tpl +10 -6
- package/templates/be/patterns/event-bus/platform/event-runner.service.spec.ts.tpl +262 -159
- package/templates/be/patterns/event-bus/platform/event-runner.service.ts.tpl +32 -5
- package/templates/be/patterns/event-bus/platform/messages/event-bus.messages.ts.tpl +2 -0
- package/templates/be/patterns/event-bus/platform/persistence/entities/event-outbox.entity.ts.tpl +5 -1
- package/templates/be/patterns/event-bus/platform/persistence/event-bus.rows.ts.tpl +2 -0
- package/templates/be/patterns/event-bus/platform/persistence/event-bus.sql.ts.tpl +4 -4
- package/templates/be/patterns/event-bus/platform/persistence/migrations/1789800009000-create-event-outbox.ts.tpl +1 -0
- package/templates/be/patterns/idempotency/platform/idempotency/errors/idempotency.error.ts.tpl +19 -0
- package/templates/be/patterns/idempotency/platform/idempotency/index.ts.tpl +2 -0
- package/templates/be/patterns/idempotency/platform/idempotency/messages/idempotency.messages.ts.tpl +13 -0
- package/templates/be/patterns/idempotency/platform/inbox/client-operation.policy.spec.ts.tpl +32 -0
- package/templates/be/patterns/idempotency/platform/inbox/client-operation.policy.ts.tpl +17 -0
- package/templates/be/patterns/idempotency/platform/inbox/client-outcome-backfill.client.spec.ts.tpl +66 -0
- package/templates/be/patterns/idempotency/platform/inbox/client-outcome-backfill.client.ts.tpl +24 -0
- package/templates/be/patterns/idempotency/platform/inbox/delivery-claim-backfill.client.spec.ts.tpl +60 -0
- package/templates/be/patterns/idempotency/platform/inbox/delivery-claim-backfill.client.ts.tpl +12 -0
- package/templates/be/patterns/idempotency/platform/inbox/delivery-claim-release.client.spec.ts.tpl +49 -0
- package/templates/be/patterns/idempotency/platform/inbox/delivery-claim-release.client.ts.tpl +12 -0
- package/templates/be/patterns/idempotency/platform/inbox/effectful.decorators.ts.tpl +7 -0
- package/templates/be/patterns/idempotency/platform/inbox/errors/inbox.error.ts.tpl +22 -0
- package/templates/be/patterns/idempotency/platform/inbox/inbox.decorators.ts.tpl +17 -0
- package/templates/be/patterns/idempotency/platform/inbox/inbox.module-definition.ts.tpl +7 -0
- package/templates/be/patterns/idempotency/platform/inbox/inbox.module.ts.tpl +28 -0
- package/templates/be/patterns/idempotency/platform/inbox/inbox.options.ts.tpl +7 -0
- package/templates/be/patterns/idempotency/platform/inbox/inbox.port.ts.tpl +44 -0
- package/templates/be/patterns/idempotency/platform/inbox/inbox.service.spec.ts.tpl +388 -0
- package/templates/be/patterns/idempotency/platform/inbox/inbox.service.ts.tpl +77 -0
- package/templates/be/patterns/idempotency/platform/inbox/index.ts.tpl +10 -0
- package/templates/be/patterns/idempotency/platform/inbox/messages/inbox.messages.ts.tpl +15 -0
- package/templates/be/patterns/idempotency/platform/inbox/persistence/connection.ts.tpl +9 -0
- package/templates/be/patterns/idempotency/platform/inbox/persistence/entities/inbox-claim.entity.ts.tpl +25 -0
- package/templates/be/patterns/idempotency/platform/inbox/persistence/inbox.rows.ts.tpl +33 -0
- package/templates/be/patterns/idempotency/platform/inbox/persistence/inbox.sql.ts.tpl +39 -0
- package/templates/be/patterns/idempotency/platform/inbox/persistence/migrations/1789800005000-create-inbox-claims.ts.tpl +21 -0
- package/templates/be/patterns/idempotency/platform/inbox/persistence/migrations/1792800000000-client-operation-outcomes.ts.tpl +21 -0
- package/templates/be/patterns/idempotency/platform/inbox/request-fingerprint.policy.spec.ts.tpl +76 -0
- package/templates/be/patterns/idempotency/platform/inbox/request-fingerprint.policy.ts.tpl +36 -0
- package/templates/be/patterns/jobs/platform/fenced.processor.spec.ts.tpl +1 -0
- package/templates/be/patterns/jobs/platform/job-claim.service.spec.ts.tpl +4 -3
- package/templates/be/patterns/jobs/platform/job-claim.service.ts.tpl +2 -0
- package/templates/be/patterns/jobs/platform/job-runner.service.spec.ts.tpl +20 -2
- package/templates/be/patterns/jobs/platform/job-runner.service.ts.tpl +1 -0
- package/templates/be/patterns/jobs/platform/jobs.contracts.ts.tpl +4 -0
- package/templates/be/patterns/jobs/platform-lite/jobs.index.ts.tpl +10 -0
- package/templates/be/patterns/jobs/platform-lite/jobs.sql.tpl +44 -0
- package/templates/be/patterns/jobs/platform-lite/persistence.jobs.sql.ts.tpl +33 -0
- package/templates/be/patterns/queues/platform/bullmq-queue-transport.client.spec.ts.tpl +203 -18
- package/templates/be/patterns/queues/platform/bullmq-queue-transport.client.ts.tpl +78 -22
- package/templates/be/patterns/queues/platform/errors/queue.error.ts.tpl +19 -0
- package/templates/be/patterns/queues/platform/messages/queue.messages.ts.tpl +13 -0
- package/templates/be/patterns/queues/platform/persistence.migration.ts.tpl +1 -0
- package/templates/be/patterns/queues/platform/persistence.queue-outbox.entity.ts.tpl +4 -0
- package/templates/be/patterns/queues/platform/persistence.queue.rows.ts.tpl +2 -0
- package/templates/be/patterns/queues/platform/persistence.queue.sql.ts.tpl +4 -4
- package/templates/be/patterns/queues/platform/queue-outbox.service.spec.ts.tpl +14 -2
- package/templates/be/patterns/queues/platform/queue-outbox.service.ts.tpl +5 -2
- package/templates/be/patterns/queues/platform/queue-relay.service.spec.ts.tpl +72 -74
- package/templates/be/patterns/queues/platform/queue-relay.service.ts.tpl +1 -1
- package/templates/be/patterns/queues/platform/queue-transport.port.ts.tpl +23 -8
- package/templates/be/patterns/queues/platform/queue-worker.service.spec.ts.tpl +29 -8
- package/templates/be/patterns/queues/platform/queue-worker.service.ts.tpl +7 -3
- package/templates/be/patterns/queues/platform/queue.contracts.ts.tpl +5 -0
- package/templates/be/patterns/queues/platform/queue.index.ts.tpl +2 -0
- package/templates/be/patterns/queues/platform/queue.log-events.ts.tpl +4 -0
- package/templates/be/patterns/queues/platform/queue.module.ts.tpl +2 -1
- package/templates/be/patterns/queues/platform/queue.port.ts.tpl +1 -1
- package/templates/be/patterns/queues/platform-lite/bullmq-queue-transport.client.spec.ts.tpl +417 -0
- package/templates/be/patterns/queues/platform-lite/bullmq-queue-transport.client.ts.tpl +172 -0
- package/templates/be/patterns/queues/platform-lite/persistence.queue.sql.ts.tpl +12 -0
- package/templates/be/patterns/queues/platform-lite/queue-outbox.sql.tpl +32 -0
- package/templates/be/patterns/queues/platform-lite/queue-relay.service.spec.ts.tpl +148 -0
- package/templates/be/patterns/queues/platform-lite/queue-relay.service.ts.tpl +51 -0
- package/templates/be/patterns/queues/platform-lite/queue-transport.port.ts.tpl +163 -0
- package/templates/be/patterns/queues/platform-lite/queue.config.ts.tpl +17 -0
- package/templates/be/patterns/queues/platform-lite/queue.error.ts.tpl +25 -0
- package/templates/be/patterns/queues/platform-lite/queue.index.ts.tpl +8 -0
- package/templates/be/patterns/queues/platform-lite/queue.messages.ts.tpl +21 -0
- package/templates/be/patterns/queues/platform-lite/queue.module.ts.tpl +74 -0
- package/templates/be/patterns/queues/platform-lite/queue.options.ts.tpl +38 -0
- package/templates/be/patterns/queues/queue.queue.ts.tpl +2 -2
- package/templates/be/patterns/reactors/application.contracts.ts.tpl +2 -0
- package/templates/be/patterns/reactors/consumer.ts.tpl +5 -1
- package/templates/be/platform/graphql/graphql.contracts.ts +2 -1
- package/templates/be/platform/graphql/localize-errors.mapper.spec.ts +1 -1
- package/templates/be/skeleton/apps/__app__/src/compose/platform.ts +6 -1
- package/templates/be/skeleton/apps/__app__/src/main.ts +7 -4
- package/templates/be/skeleton/apps/cli/src/compose/platform.ts +4 -0
- package/templates/be/skeleton/apps/cli/src/main.ts +7 -4
- package/templates/be/skeleton/src/modules/platform/database/index.ts +1 -1
- package/templates/be/skeleton/src/modules/platform/http/errors/http.error.ts +22 -0
- package/templates/be/skeleton/src/modules/platform/http/fetch-http-client.client.spec.ts +235 -0
- package/templates/be/skeleton/src/modules/platform/http/fetch-http-client.client.ts +85 -0
- package/templates/be/skeleton/src/modules/platform/http/graphql-call.mapper.spec.ts +92 -0
- package/templates/be/skeleton/src/modules/platform/http/graphql-call.mapper.ts +52 -0
- package/templates/be/skeleton/src/modules/platform/http/http.decorators.ts +9 -0
- package/templates/be/skeleton/src/modules/platform/http/http.module-definition.ts +7 -0
- package/templates/be/skeleton/src/modules/platform/http/http.module.ts +19 -0
- package/templates/be/skeleton/src/modules/platform/http/http.options.ts +2 -0
- package/templates/be/skeleton/src/modules/platform/http/http.port.ts +40 -0
- package/templates/be/skeleton/src/modules/platform/http/index.ts +7 -0
- package/templates/be/skeleton/src/modules/platform/http/messages/http.messages.ts +15 -0
- package/templates/be/skeleton/src/modules/platform/ids/ids.decorators.ts +9 -0
- package/templates/be/skeleton/src/modules/platform/ids/ids.module-definition.ts +7 -0
- package/templates/be/skeleton/src/modules/platform/ids/ids.module.ts +19 -0
- package/templates/be/skeleton/src/modules/platform/ids/ids.options.ts +2 -0
- package/templates/be/skeleton/src/modules/platform/ids/ids.port.ts +5 -0
- package/templates/be/skeleton/src/modules/platform/ids/index.ts +4 -0
- package/templates/be/skeleton/src/modules/platform/ids/system-ids.service.spec.ts +15 -0
- package/templates/be/skeleton/src/modules/platform/ids/system-ids.service.ts +10 -0
- package/templates/be/skeleton/src/modules/platform/logging/correlation-request.policy.spec.ts +59 -0
- package/templates/be/skeleton/src/modules/platform/logging/correlation-request.policy.ts +21 -0
- package/templates/be/skeleton/src/modules/platform/logging/correlation.contracts.ts +16 -0
- package/templates/be/skeleton/src/modules/platform/logging/correlation.policy.spec.ts +150 -0
- package/templates/be/skeleton/src/modules/platform/logging/correlation.policy.ts +42 -0
- package/templates/be/skeleton/src/modules/platform/logging/correlation.port.ts +15 -0
- package/templates/be/skeleton/src/modules/platform/logging/correlation.service.spec.ts +23 -0
- package/templates/be/skeleton/src/modules/platform/logging/correlation.service.ts +28 -0
- package/templates/be/skeleton/src/modules/platform/logging/index.ts +14 -1
- package/templates/be/skeleton/src/modules/platform/logging/json-logger.service.spec.ts +39 -6
- package/templates/be/skeleton/src/modules/platform/logging/json-logger.service.ts +15 -3
- package/templates/be/skeleton/src/modules/platform/logging/logging.decorators.ts +17 -2
- package/templates/be/skeleton/src/modules/platform/logging/logging.log-events.ts +13 -1
- package/templates/be/skeleton/src/modules/platform/logging/logging.module.ts +13 -3
- package/templates/be/skeleton/src/modules/platform/logging/nest-logger.service.spec.ts +69 -0
- package/templates/be/skeleton/src/modules/platform/logging/nest-logger.service.ts +48 -0
- package/templates/be/skeleton/src/modules/platform/primitives/index.ts +1 -0
- package/templates/be/skeleton/src/modules/platform/primitives/record.policy.spec.ts +12 -0
- package/templates/be/skeleton/src/modules/platform/primitives/record.policy.ts +3 -0
- package/templates/be/skeleton-lite/apps/api/src/compose/platform.ts +6 -1
- package/templates/be/skeleton-lite/apps/cli/src/compose/platform.ts +4 -0
- package/templates/be/skeleton-lite/src/modules/platform/database/index.ts +1 -0
- package/templates/be/skeleton-lite/src/modules/platform/logging/index.ts +14 -1
- package/templates/be/skeleton-lite/src/modules/platform/logging/logging.log-events.ts +12 -0
- package/templates/be/skeleton-lite/src/modules/platform/primitives/index.ts +2 -0
- package/templates/be/test-world/world/test-apps.options.ts.tpl +2 -0
- package/templates/be/test-world/world/test-world.config.ts.tpl +1 -0
- package/upgrade/check.mjs +12 -135
- package/upgrade/file-state.mjs +1 -16
- package/upgrade/index.mjs +34 -361
- package/runtime/scripts/lib/check-code-loosening.mjs +0 -128
- package/runtime/scripts/lib/gate-loosening.mjs +0 -292
- package/templates/app/upgrade-full/.starcistacks/application-stacks.yaml +0 -89
- package/templates/app/upgrade-full/.starcistacks/dev/README.md +0 -16
- package/templates/app/upgrade-full/.starcistacks/dev/infra/compose/api.yaml +0 -13
- package/templates/app/upgrade-full/.starcistacks/dev/infra/compose/compose.yaml +0 -3
- package/templates/app/upgrade-full/.starcistacks/dev/infra/compose/postgres.yaml +0 -12
- package/templates/app/upgrade-full/.starcistacks/dev/infra/metadata.json +0 -7
- package/templates/be/skeleton-lite/apps/api/src/main.ts +0 -26
- package/templates/be/upgrade-full/apps/cli/src/app.module.ts +0 -12
- package/templates/be/upgrade-full/apps/cli/src/cli.env.ts +0 -7
- package/templates/be/upgrade-full/apps/cli/src/compose/cli.ts +0 -5
- package/templates/be/upgrade-full/apps/cli/src/compose/platform.ts +0 -9
- package/templates/be/upgrade-full/apps/cli/src/main.ts +0 -29
- package/templates/be/upgrade-full/src/features/cli/cli.module.ts +0 -7
- package/templates/be/upgrade-full/src/features/cli/migrate/subs/run.cli.ts +0 -23
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
// gate-loosening.mjs — what "loosens a gate" means, mechanically (modules/kernel/gate-loosening.yaml), over the unified diff of one change.
|
|
2
|
-
// A loosening is one of:
|
|
3
|
-
// check-removed a list item removed from a gate file and not added back in the same file (an item that carries an id is the
|
|
4
|
-
// same item while an added item carries that id: a row whose fields change stays a check)
|
|
5
|
-
// check-narrowed an enforcer row `{kind, id, editions}` that keeps its kind and id but now runs in fewer editions (a lost restriction or
|
|
6
|
-
// a superset of editions is a widening, never a loosening)
|
|
7
|
-
// threshold-lowered a number of a gate file moved the loose way: a floor lowered, a ceiling raised
|
|
8
|
-
// allowlist-added a list item added to an allowlist file
|
|
9
|
-
// spec-deleted a spec file deleted in a change that also changes product code
|
|
10
|
-
// assertion-weakened a spec that loses more assertions than it gains in a change that also changes product code
|
|
11
|
-
// spec-skipped a skip marker added to a spec in a change that also changes product code
|
|
12
|
-
// bypass-added, check-weakened, scope-widened (and check-removed over code): the code of a check is a gate too. A check script, rule module,
|
|
13
|
-
// canon template, lint package, workflow or hook (modules/kernel/gate-loosening.yaml checkCode) that gains a bypass marker,
|
|
14
|
-
// loses enforcement lines or ban-list rows, or gains an exemption is judged by scripts/lib/check-code-loosening.mjs
|
|
15
|
-
// A change that renames paths (a git rename, `git diff -M`) may MOVE the entries that name them: a removed line and an added line of the
|
|
16
|
-
// same file that are equal once every renamed prefix of the removed line is rewritten to its new name are one entry moved, not a check
|
|
17
|
-
// removed and an exception added (renamedPrefixesOf, movedLinesOf). A moved entry that also changes in any other way (a widened glob, an
|
|
18
|
-
// extra path) is still judged as a removal and an addition.
|
|
19
|
-
// The finding id is `<kind>:<file>:<detail>`. A loosening is always red (owner ruling loosening-always-red, 2026-10-22): there is no
|
|
20
|
-
// approval that lets one through, so a change that loosens a gate is fixed by restoring the gate (looseningStep).
|
|
21
|
-
// Only what a release shipped can be loosened (loosensReleased): a check, a spec or an assertion added after the release and folded
|
|
22
|
-
// away before the next one never was a gate of a release.
|
|
23
|
-
import { byCodeUnit } from './list.mjs';
|
|
24
|
-
import { checkCodeFindings, isCheckCode } from './check-code-loosening.mjs';
|
|
25
|
-
|
|
26
|
-
const LIST_ITEM = /^\s*-\s+\S/;
|
|
27
|
-
const NUMBER_LINE = /^\s*(?:-\s+)?([A-Za-z][\w.-]*):\s*(-?\d+(?:\.\d+)?)\s*(?:#.*)?$/;
|
|
28
|
-
/** A line of a JSON or JavaScript config as the YAML number line above reads it: no quotes around the key, no trailing comma or line comment. */
|
|
29
|
-
function plainNumberLine(line) {
|
|
30
|
-
const comment = line.indexOf('//');
|
|
31
|
-
const code = (comment < 0 ? line : line.slice(0, comment)).trimEnd();
|
|
32
|
-
return (code.endsWith(',') ? code.slice(0, -1) : code).replace(/^(\s*(?:-\s+)?)["']([^"']+)["']:/, '$1$2:');
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const concatenates = (line) => typeof line === 'string' && line.trimEnd().endsWith('+');
|
|
36
|
-
|
|
37
|
-
/** Records one changed line of `current`; returns the removed text (the next line's `above`), or null. */
|
|
38
|
-
function recordLine(current, line, section, above) {
|
|
39
|
-
if (line.startsWith('deleted file mode')) { current.deleted = true; return null; }
|
|
40
|
-
if (line.startsWith('+') && !line.startsWith('+++')) {
|
|
41
|
-
const text = line.slice(1);
|
|
42
|
-
current.added.push(text);
|
|
43
|
-
current.under.set(text, [...(current.under.get(text) ?? []), section]);
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
if (!line.startsWith('-') || line.startsWith('---')) return null;
|
|
47
|
-
const text = line.slice(1);
|
|
48
|
-
current.removed.push(text);
|
|
49
|
-
if (concatenates(above) || concatenates(text)) current.operands.add(text);
|
|
50
|
-
return text;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* The files of a unified diff: [{file, deleted, added[], removed[], under}] (changed lines without their marker). `under` maps an added line to the
|
|
55
|
-
* hunk headers it was added under (git prints the nearest line above the hunk that starts a word, so the key a YAML list item sits in).
|
|
56
|
-
* `operands` holds the removed lines that are an operand of a string concatenation: a line that ends in `+`, or one whose removed line just
|
|
57
|
-
* above it in the same hunk ends in `+` (a message being printed, never a row of a ban list).
|
|
58
|
-
*/
|
|
59
|
-
export function parseDiff(text) {
|
|
60
|
-
const files = [];
|
|
61
|
-
let current = null;
|
|
62
|
-
let section = '';
|
|
63
|
-
let above = null;
|
|
64
|
-
for (const line of String(text ?? '').split(/\r?\n/)) {
|
|
65
|
-
const header = /^diff --git a\/(.+?) b\/(.+)$/.exec(line);
|
|
66
|
-
if (header) { current = { file: header[2], deleted: false, added: [], removed: [], operands: new Set(), under: new Map() }; files.push(current); above = null; continue; }
|
|
67
|
-
if (!current) continue;
|
|
68
|
-
const hunk = /^@@ .*? @@ ?(.*)$/.exec(line);
|
|
69
|
-
if (hunk) { section = hunk[1]; above = null; continue; }
|
|
70
|
-
above = recordLine(current, line, section, above);
|
|
71
|
-
}
|
|
72
|
-
return files;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/** The rename lines `R<score> <old> <new>` (tab separated) of `git diff --name-status -M`: [{from, to}]. */
|
|
76
|
-
const renamesOf = (nameStatus) => String(nameStatus ?? '').split(/\r?\n/).map((line) => line.split('\t'))
|
|
77
|
-
.filter((fields) => /^R\d*$/.test(fields[0] ?? '') && fields.length === 3).map(([, from, to]) => ({ from, to }));
|
|
78
|
-
|
|
79
|
-
/** The moved prefix of one renamed file: its old and new path without the trailing segments they share. */
|
|
80
|
-
function movedPrefixOf({ from, to }) {
|
|
81
|
-
const before = from.split('/');
|
|
82
|
-
const after = to.split('/');
|
|
83
|
-
while (before.length > 1 && after.length > 1 && before.at(-1) === after.at(-1)) { before.pop(); after.pop(); }
|
|
84
|
-
return { from: before.join('/'), to: after.join('/') };
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* The path prefixes a change renamed, from its `git diff --name-status -M` output: [{from, to}], longest `from` first. A prefix is kept only
|
|
89
|
-
* when every renamed file under it moved to the same new prefix; an old prefix that went two ways names no single move and is dropped.
|
|
90
|
-
*/
|
|
91
|
-
export function renamedPrefixesOf(nameStatus) {
|
|
92
|
-
const targets = new Map();
|
|
93
|
-
for (const { from, to } of renamesOf(nameStatus).map(movedPrefixOf)) {
|
|
94
|
-
if (from === to) continue;
|
|
95
|
-
if (!targets.has(from)) targets.set(from, new Set());
|
|
96
|
-
targets.get(from).add(to);
|
|
97
|
-
}
|
|
98
|
-
return [...targets].filter(([, to]) => to.size === 1).map(([from, to]) => ({ from, to: [...to][0] }))
|
|
99
|
-
.sort((a, b) => b.from.length - a.from.length || byCodeUnit(a.from, b.from));
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const escapeRegExp = (text) => text.replace(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
|
|
103
|
-
|
|
104
|
-
/** `line` with every renamed prefix rewritten to its new name; a prefix matches only as a whole path (not inside a longer name). */
|
|
105
|
-
function renamedLine(line, prefixes) {
|
|
106
|
-
return prefixes.reduce((text, { from, to }) => text.replace(new RegExp(String.raw`(?<![\w./-])${escapeRegExp(from)}(?![\w.-])`, 'g'), to), line);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* One file of a change without its moved entries: each removed line whose renamed form is exactly an added line is paired with it, and
|
|
111
|
-
* both are left out. A line the rename does not touch is never paired, so an entry merely removed or added stays.
|
|
112
|
-
*/
|
|
113
|
-
export function movedLinesOf(entry, prefixes) {
|
|
114
|
-
if (!prefixes.length) return entry;
|
|
115
|
-
const unpaired = new Map();
|
|
116
|
-
for (const line of entry.added) unpaired.set(line, (unpaired.get(line) ?? 0) + 1);
|
|
117
|
-
const paired = new Map();
|
|
118
|
-
const removed = entry.removed.filter((line) => {
|
|
119
|
-
const moved = renamedLine(line, prefixes);
|
|
120
|
-
if (moved === line || (unpaired.get(moved) ?? 0) <= 0) return true;
|
|
121
|
-
unpaired.set(moved, unpaired.get(moved) - 1);
|
|
122
|
-
paired.set(moved, (paired.get(moved) ?? 0) + 1);
|
|
123
|
-
return false;
|
|
124
|
-
});
|
|
125
|
-
const added = entry.added.filter((line) => {
|
|
126
|
-
if ((paired.get(line) ?? 0) <= 0) return true;
|
|
127
|
-
paired.set(line, paired.get(line) - 1);
|
|
128
|
-
return false;
|
|
129
|
-
});
|
|
130
|
-
return { ...entry, added, removed };
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const keyWords = (key) => key.replace(/([a-z])([A-Z])/g, '$1 $2').toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
|
|
134
|
-
const trimmed = (line) => line.trim();
|
|
135
|
-
const clip = (text) => (text.length > 90 ? `${text.slice(0, 89)}…` : text);
|
|
136
|
-
|
|
137
|
-
/** What makes a list item the same item: its id when it carries one, else its text. */
|
|
138
|
-
function identityOf(line) {
|
|
139
|
-
const item = trimmed(line).slice(1).trimStart();
|
|
140
|
-
const body = (item.startsWith('{') ? item.slice(1) : item).trimStart();
|
|
141
|
-
if (!body.startsWith('id:')) return trimmed(line);
|
|
142
|
-
const id = body.slice(3).trimStart().split(/[,}\s]/)[0];
|
|
143
|
-
return id ? `id:${id}` : trimmed(line);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/** Splits `a: 1, b: [x, y]` at the commas outside square brackets. */
|
|
147
|
-
function splitTopLevel(text) {
|
|
148
|
-
const parts = [];
|
|
149
|
-
let depth = 0;
|
|
150
|
-
let from = 0;
|
|
151
|
-
for (let at = 0; at < text.length; at += 1) {
|
|
152
|
-
if (text[at] === '[') depth += 1;
|
|
153
|
-
else if (text[at] === ']') depth -= 1;
|
|
154
|
-
else if (text[at] === ',' && depth === 0) { parts.push(text.slice(from, at)); from = at + 1; }
|
|
155
|
-
}
|
|
156
|
-
parts.push(text.slice(from));
|
|
157
|
-
return parts;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/** The flow-mapping enforcer row `- {kind: k, id: i, editions: [a, b]}`: {kind, id, editions} (editions null = every edition), or null. */
|
|
161
|
-
function flowRow(line) {
|
|
162
|
-
const text = line.trim();
|
|
163
|
-
if (!text.startsWith('-')) return null;
|
|
164
|
-
const open = text.indexOf('{');
|
|
165
|
-
const close = text.lastIndexOf('}');
|
|
166
|
-
if (open < 1 || close < open || text.slice(1, open).trim() !== '') return null;
|
|
167
|
-
const fields = new Map();
|
|
168
|
-
for (const part of splitTopLevel(text.slice(open + 1, close))) {
|
|
169
|
-
const at = part.indexOf(':');
|
|
170
|
-
if (at > 0) fields.set(part.slice(0, at).trim(), part.slice(at + 1).trim());
|
|
171
|
-
}
|
|
172
|
-
if (!fields.has('kind') || !fields.has('id')) return null;
|
|
173
|
-
const editions = fields.get('editions');
|
|
174
|
-
const list = editions === undefined ? null : editions.replace('[', '').replace(']', '').split(',').map((value) => value.trim()).filter(Boolean);
|
|
175
|
-
return { kind: fields.get('kind'), id: fields.get('id'), editions: list };
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/** Whether row `after` still runs everywhere row `before` ran: a lost restriction or a superset of editions widens, a subset narrows. */
|
|
179
|
-
const coversEditions = (before, after) => after.editions === null || (before.editions !== null && before.editions.every((edition) => after.editions.includes(edition)));
|
|
180
|
-
|
|
181
|
-
/** The removed list items of a gate file that no added line restores; an enforcer row that keeps its kind and id may only widen its editions. */
|
|
182
|
-
function checksRemoved(entry) {
|
|
183
|
-
const back = new Map();
|
|
184
|
-
for (const line of entry.added.filter((value) => LIST_ITEM.test(value))) back.set(identityOf(line), (back.get(identityOf(line)) ?? 0) + 1);
|
|
185
|
-
const addedRows = entry.added.map(flowRow).filter(Boolean);
|
|
186
|
-
return entry.removed.filter((value) => LIST_ITEM.test(value)).flatMap((value) => {
|
|
187
|
-
const row = flowRow(value);
|
|
188
|
-
if (row) {
|
|
189
|
-
const same = addedRows.filter((candidate) => candidate.kind === row.kind && candidate.id === row.id);
|
|
190
|
-
if (same.length) {
|
|
191
|
-
if (same.some((candidate) => coversEditions(row, candidate))) return [];
|
|
192
|
-
return [{ kind: 'check-narrowed', file: entry.file, detail: clip(trimmed(value)) }];
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
const left = back.get(identityOf(value)) ?? 0;
|
|
196
|
-
if (left > 0) { back.set(identityOf(value), left - 1); return []; }
|
|
197
|
-
return [{ kind: 'check-removed', file: entry.file, detail: clip(trimmed(value)) }];
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
const numbersOf = (lines) => lines.map((line) => NUMBER_LINE.exec(plainNumberLine(line))).filter(Boolean).map((match) => ({ key: match[1], value: Number(match[2]) }));
|
|
202
|
-
|
|
203
|
-
/** The thresholds of a gate file moved the loose way. */
|
|
204
|
-
function thresholdsLowered(entry, rules) {
|
|
205
|
-
const added = numbersOf(entry.added);
|
|
206
|
-
return numbersOf(entry.removed).flatMap((before) => {
|
|
207
|
-
const after = added.find((candidate) => candidate.key === before.key);
|
|
208
|
-
if (!after || after.value === before.value) return [];
|
|
209
|
-
const words = keyWords(before.key);
|
|
210
|
-
const lowered = words.some((word) => rules.thresholds.floors.includes(word)) && after.value < before.value;
|
|
211
|
-
const raised = words.some((word) => rules.thresholds.ceilings.includes(word)) && after.value > before.value;
|
|
212
|
-
return lowered || raised ? [{ kind: 'threshold-lowered', file: entry.file, detail: `${before.key} ${before.value} -> ${after.value}` }] : [];
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
const SPEC_NAME = /\.spec\.[cm]?[jt]sx?$/;
|
|
217
|
-
const isSpec = (file, rules) => rules.specRoots.some((root) => file.startsWith(root)) && SPEC_NAME.test(file);
|
|
218
|
-
const countOf = (lines, markers) => lines.filter((line) => markers.some((marker) => line.includes(marker))).length;
|
|
219
|
-
|
|
220
|
-
const baseName = (file) => file.slice(file.lastIndexOf('/') + 1);
|
|
221
|
-
|
|
222
|
-
/** Whether a spec of the same name is written elsewhere in the change: a moved spec is not a deleted one. */
|
|
223
|
-
const movedSpec = (entry, files, rules) => files.some((other) => other !== entry && !other.deleted && isSpec(other.file, rules) && baseName(other.file) === baseName(entry.file));
|
|
224
|
-
|
|
225
|
-
/** The spec findings of one file of a change that also changes product code. */
|
|
226
|
-
function specFindings(entry, files, rules) {
|
|
227
|
-
if (entry.deleted) return movedSpec(entry, files, rules) ? [] : [{ kind: 'spec-deleted', file: entry.file, detail: 'deleted' }];
|
|
228
|
-
const weaker = countOf(entry.removed, rules.assertionMarkers) - countOf(entry.added, rules.assertionMarkers);
|
|
229
|
-
const skipped = countOf(entry.added, rules.skipMarkers) - countOf(entry.removed, rules.skipMarkers);
|
|
230
|
-
return [...(weaker > 0 ? [{ kind: 'assertion-weakened', file: entry.file, detail: `${weaker} assertion(s) fewer` }] : []),
|
|
231
|
-
...(skipped > 0 ? [{ kind: 'spec-skipped', file: entry.file, detail: `${skipped} skip marker(s) added` }] : [])];
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
const changesProduct = (files, rules) => files.some((entry) => !isSpec(entry.file, rules) && rules.productPrefixes.some((prefix) => entry.file.startsWith(prefix)));
|
|
235
|
-
|
|
236
|
-
/** The findings of one file that is a gate file (its lists and numbers) or the code of a check (its numbers; its bypasses are checkCodeFindings'). */
|
|
237
|
-
function gateFindings(entry, rules) {
|
|
238
|
-
if (rules.gateFiles.includes(entry.file)) return [...checksRemoved(entry), ...thresholdsLowered(entry, rules)];
|
|
239
|
-
return isCheckCode(entry.file, rules) ? thresholdsLowered(entry, rules) : [];
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Every loosening of the change `diffText`, sorted: [{id, kind, file, detail}]. `rules` is modules/kernel/gate-loosening.yaml; `renamed`
|
|
244
|
-
* is the change's renamed prefixes (renamedPrefixesOf), whose moved entries are no loosening.
|
|
245
|
-
*/
|
|
246
|
-
export function looseningsOf(diffText, rules, { renamed = [] } = {}) {
|
|
247
|
-
const files = parseDiff(diffText).map((entry) => movedLinesOf(entry, renamed));
|
|
248
|
-
const product = changesProduct(files, rules);
|
|
249
|
-
const found = files.flatMap((entry) => [
|
|
250
|
-
...gateFindings(entry, rules),
|
|
251
|
-
...(rules.allowlistFiles.includes(entry.file) ? entry.added.filter((value) => LIST_ITEM.test(value)).map((value) => ({ kind: 'allowlist-added', file: entry.file, detail: clip(trimmed(value)) })) : []),
|
|
252
|
-
...(product && isSpec(entry.file, rules) ? specFindings(entry, files, rules) : []),
|
|
253
|
-
]).concat(checkCodeFindings(files, rules));
|
|
254
|
-
return found.map((finding) => ({ ...finding, id: `${finding.kind}:${finding.file}:${finding.detail}` })).sort((a, b) => byCodeUnit(a.id, b.id));
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/** One finding as the land gate and the self-check print it. */
|
|
258
|
-
export const looseningLine = (finding) => `${finding.kind} ${finding.file}: ${finding.detail}`;
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* The land gate's step for a change that loosens a gate: always red, with the way out that exists, restoring the gate. There is no
|
|
262
|
-
* approval: a loosening never lands (owner ruling loosening-always-red).
|
|
263
|
-
*/
|
|
264
|
-
export const looseningStep = (findings) => ({
|
|
265
|
-
name: 'gate-loosening', ok: false, findings, output: findings.map(looseningLine).join('\n'),
|
|
266
|
-
hint: 'a change that loosens a gate never lands (owner ruling loosening-always-red): restore every gate listed above',
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
const assertionsIn = (text, markers) => String(text ?? '').split('\n').filter((line) => markers.some((marker) => line.includes(marker))).length;
|
|
270
|
-
|
|
271
|
-
/** The detail of a check-removed finding without its clipping mark: the start of the removed line. */
|
|
272
|
-
const shownDetail = (detail) => (detail.endsWith('…') ? detail.slice(0, -1) : detail);
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Whether `finding` loosens the state released at `base`, read through `read(rev, file)` (text, or null when the revision holds no such
|
|
276
|
-
* file); `rules` gives the assertion markers. A finding stays only when
|
|
277
|
-
* bypass-added the added line is still in the file at HEAD (a bypass folded away before the next release never shipped)
|
|
278
|
-
* check-removed the removed list item is an item of that gate file at the release commit
|
|
279
|
-
* spec-deleted the spec exists at the release commit
|
|
280
|
-
* spec-skipped the spec exists at the release commit
|
|
281
|
-
* assertion-weakened the spec exists at the release commit and holds fewer assertion lines now than it held there
|
|
282
|
-
* (every other kind loosens whenever its file existed at the release).
|
|
283
|
-
*/
|
|
284
|
-
export function loosensReleased(finding, { base, read, rules }) {
|
|
285
|
-
// A bypass is judged by whether it still stands: one added and folded away before the next release never shipped.
|
|
286
|
-
if (finding.kind === 'bypass-added') return String(read('HEAD', finding.file) ?? '').split('\n').some((line) => line.trim() === finding.text);
|
|
287
|
-
const before = read(base, finding.file);
|
|
288
|
-
if (before === null) return false;
|
|
289
|
-
if (finding.kind === 'check-removed') return before.split('\n').some((line) => line.trim().startsWith(shownDetail(finding.detail)));
|
|
290
|
-
if (finding.kind !== 'assertion-weakened') return true;
|
|
291
|
-
return assertionsIn(read('HEAD', finding.file), rules.assertionMarkers) < assertionsIn(before, rules.assertionMarkers);
|
|
292
|
-
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
schema: starci/application-stacks@1
|
|
2
|
-
# To render README badges, declare ci.github: {repository: owner/repo, defaultBranch: main}.
|
|
3
|
-
# A GitHub package.json repository URL also enables the managed block.
|
|
4
|
-
sources:
|
|
5
|
-
- repository: "{{project}}"
|
|
6
|
-
components:
|
|
7
|
-
supabase-postgres:
|
|
8
|
-
image: postgres:16@sha256:1a6ab3f5345eb6dbe04a1349529caabdb0ab09293a09590fad07b2246bfa4b54
|
|
9
|
-
role: stateful
|
|
10
|
-
compose: infra/compose/postgres.yaml
|
|
11
|
-
purpose: The pinned PostgreSQL-compatible database behind the Supabase project.
|
|
12
|
-
required: true
|
|
13
|
-
api:
|
|
14
|
-
image: "{{project}}/api:0.0.0"
|
|
15
|
-
role: service
|
|
16
|
-
compose: infra/compose/api.yaml
|
|
17
|
-
purpose: The Nest API that owns privileged and cross-tenant operations.
|
|
18
|
-
required: true
|
|
19
|
-
environments:
|
|
20
|
-
dev:
|
|
21
|
-
status: supported
|
|
22
|
-
runtime: docker-compose
|
|
23
|
-
composeFiles:
|
|
24
|
-
- infra/compose/compose.yaml
|
|
25
|
-
components:
|
|
26
|
-
supabase-postgres: { port: 5432 }
|
|
27
|
-
api: { port: 3001 }
|
|
28
|
-
runbook: README.md
|
|
29
|
-
secrets: []
|
|
30
|
-
k8s:
|
|
31
|
-
status: deferred
|
|
32
|
-
reason: The upgrade establishes the full local stack first; deployment topology is selected separately.
|
|
33
|
-
ci:
|
|
34
|
-
secrets:
|
|
35
|
-
- {name: SONAR_TOKEN, scope: repository, purpose: Sonar analysis token provisioned for this app}
|
|
36
|
-
- {name: SOPS_AGE_KEY, scope: repository, purpose: Decrypt app members during deployment, optional: true}
|
|
37
|
-
- {name: VPS_SSH_KEY, scope: repository, purpose: Deployment SSH key, optional: true}
|
|
38
|
-
- {name: VPS_KNOWN_HOSTS, scope: repository, purpose: Pinned deployment SSH host keys, optional: true}
|
|
39
|
-
vars:
|
|
40
|
-
- {name: SONAR_HOST_URL, scope: repository, value: "https://sonar.{{project}}.example.invalid", purpose: Documentation endpoint to replace with this app's public Sonar host}
|
|
41
|
-
- {name: VPS_HOST, scope: repository, value: 203.0.113.10, purpose: Documentation deployment address to replace before use, optional: true}
|
|
42
|
-
- {name: VPS_USER, scope: repository, value: deploy, purpose: Documentation deployment user to replace before use, optional: true}
|
|
43
|
-
services:
|
|
44
|
-
sonar:
|
|
45
|
-
provider: sonarqube
|
|
46
|
-
mode: disabled
|
|
47
|
-
reason: Enable the repository's Sonar service when a host and project token are provisioned.
|
|
48
|
-
qualityGate: starci-quality
|
|
49
|
-
credentials: []
|
|
50
|
-
projects: [{repository: "{{project}}", key: "{{project}}"}]
|
|
51
|
-
ci: {wiring: required, workflow: .github/workflows/ci.yml, token: SONAR_TOKEN, hostVar: SONAR_HOST_URL}
|
|
52
|
-
ownerAction: none
|
|
53
|
-
codecov:
|
|
54
|
-
provider: codecov
|
|
55
|
-
mode: hosted
|
|
56
|
-
purpose: Report application coverage through GitHub OIDC.
|
|
57
|
-
auth: oidc
|
|
58
|
-
target: 100
|
|
59
|
-
components: auto
|
|
60
|
-
required: true
|
|
61
|
-
ci: {wiring: required, workflow: .github/workflows/ci.yml}
|
|
62
|
-
ownerAction: none
|
|
63
|
-
dependabot:
|
|
64
|
-
provider: github
|
|
65
|
-
mode: hosted
|
|
66
|
-
purpose: Keep application dependencies and workflow actions current.
|
|
67
|
-
ecosystems: [npm, docker, github-actions]
|
|
68
|
-
schedule: {interval: weekly}
|
|
69
|
-
groups: {minorPatch: grouped, major: per-package}
|
|
70
|
-
ignore: ['@starci/*']
|
|
71
|
-
security: immediate
|
|
72
|
-
ownerAction: none
|
|
73
|
-
audit:
|
|
74
|
-
provider: npm
|
|
75
|
-
mode: local
|
|
76
|
-
purpose: Refuse high severity production dependency vulnerabilities.
|
|
77
|
-
level: high
|
|
78
|
-
omitDev: true
|
|
79
|
-
in: [release-gate, ci]
|
|
80
|
-
ownerAction: none
|
|
81
|
-
container-registry:
|
|
82
|
-
provider: ghcr
|
|
83
|
-
mode: hosted
|
|
84
|
-
purpose: Publish this app's deployment images with the workflow GitHub token.
|
|
85
|
-
host: {public: https://ghcr.io}
|
|
86
|
-
auth: github-token
|
|
87
|
-
projects: [{repository: "{{project}}", key: "{{project}}"}]
|
|
88
|
-
ci: {wiring: required}
|
|
89
|
-
ownerAction: none
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# Development stack
|
|
2
|
-
|
|
3
|
-
The app services may run in a local Docker Swarm; local Supabase is started separately with its CLI and supplies the database and broker. The tracked model contains no self-hosted database.
|
|
4
|
-
Starter release images and external secrets must be prepared before starting the container model. Replace its starter `SUPABASE_URL` with the local Supabase endpoint reachable from the Swarm node, and seal that local database connection and integration credential; a container cannot use the host's loopback address without owner-configured networking. Local source development remains available through the app scripts.
|
|
5
|
-
|
|
6
|
-
| Command | Operation |
|
|
7
|
-
| --- | --- |
|
|
8
|
-
| prepare | Run `npm run db:start` at the app root; obtain the local Supabase connection and Auth configuration. An owner who chooses local Swarm initializes it, labels its node `{{project}}=dev` and provisions the ingress volumes. Create the external development secrets named in the model from real sealed members. |
|
|
9
|
-
| doctor | From this directory, run `docker stack config -c infra/swarm/stack.yaml`. Confirm image, secret and local Supabase availability. |
|
|
10
|
-
| up | Run `docker stack deploy -c infra/swarm/stack.yaml {{project}}-dev` from this directory after preparation. |
|
|
11
|
-
| status | Run `docker stack services {{project}}-dev`. |
|
|
12
|
-
| logs | Run `docker service logs {{project}}-dev_api`; never print mounted credentials. |
|
|
13
|
-
| down | Run `docker stack rm {{project}}-dev`. |
|
|
14
|
-
| verification | Confirm the API `/health/live` and `/health/ready` endpoints, then run `npm run lint` from the app root. |
|
|
15
|
-
|
|
16
|
-
Keep real sealed members under `.starcistacks/dev/secrets/*.enc`, add them to the manifest after sealing and inventory their key names in the environment record. The scaffold creates no fake secret or successful proof.
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
services:
|
|
2
|
-
api:
|
|
3
|
-
image: "{{project}}/api:0.0.0"
|
|
4
|
-
build:
|
|
5
|
-
context: ../../../..
|
|
6
|
-
dockerfile: be/apps/api/Dockerfile
|
|
7
|
-
environment:
|
|
8
|
-
PRIMARY_DB_URL: postgres://postgres@supabase-postgres:5432/postgres
|
|
9
|
-
ports:
|
|
10
|
-
- "3001:3000"
|
|
11
|
-
depends_on:
|
|
12
|
-
supabase-postgres:
|
|
13
|
-
condition: service_healthy
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
services:
|
|
2
|
-
supabase-postgres:
|
|
3
|
-
image: postgres:16@sha256:1a6ab3f5345eb6dbe04a1349529caabdb0ab09293a09590fad07b2246bfa4b54
|
|
4
|
-
environment:
|
|
5
|
-
POSTGRES_HOST_AUTH_METHOD: trust
|
|
6
|
-
ports:
|
|
7
|
-
- "5432:5432"
|
|
8
|
-
healthcheck:
|
|
9
|
-
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
|
10
|
-
interval: 5s
|
|
11
|
-
timeout: 5s
|
|
12
|
-
retries: 12
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { NestFactory } from "@nestjs/core"
|
|
2
|
-
import { SystemClockService } from "@modules/platform/clock"
|
|
3
|
-
import { EnvSource } from "@modules/platform/config"
|
|
4
|
-
import { applyHttpSecurity } from "@modules/platform/http-security"
|
|
5
|
-
import { createJsonLogger, LoggingLogEvent } from "@modules/platform/logging"
|
|
6
|
-
import { readApiEnv } from "./api.env"
|
|
7
|
-
import { AppModule } from "./app.module"
|
|
8
|
-
|
|
9
|
-
/** Reads the environment once, composes the API from parsed options and serves until a shutdown signal. */
|
|
10
|
-
const bootstrap = async (): Promise<void> => {
|
|
11
|
-
const env = EnvSource.fromProcess()
|
|
12
|
-
const options = readApiEnv(env)
|
|
13
|
-
const app = await NestFactory.create(AppModule.register(options), { rawBody: true })
|
|
14
|
-
applyHttpSecurity(app, options.httpSecurity, { trustProxy: 1 })
|
|
15
|
-
app.enableShutdownHooks()
|
|
16
|
-
await app.listen(options.server.port)
|
|
17
|
-
createJsonLogger(new SystemClockService()).info(LoggingLogEvent.ServerStarted, {
|
|
18
|
-
service: "api",
|
|
19
|
-
port: options.server.port,
|
|
20
|
-
})
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
bootstrap().catch((error: unknown) => {
|
|
24
|
-
createJsonLogger(new SystemClockService()).error(LoggingLogEvent.StartupFailed, error, { service: "api" })
|
|
25
|
-
process.exitCode = 1
|
|
26
|
-
})
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Module } from "@nestjs/common";
|
|
2
|
-
import { cliModules } from "./compose/cli";
|
|
3
|
-
import { platformModules } from "./compose/platform";
|
|
4
|
-
|
|
5
|
-
@Module({
|
|
6
|
-
imports: [
|
|
7
|
-
...platformModules(),
|
|
8
|
-
...cliModules(),
|
|
9
|
-
],
|
|
10
|
-
})
|
|
11
|
-
/** The cli composition root; database schema changes remain delegated to the Supabase CLI. */
|
|
12
|
-
export class AppModule {}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { EnvSource } from "@modules/platform/config"
|
|
2
|
-
|
|
3
|
-
/** This command app delegates migration configuration to the managed Supabase CLI. */
|
|
4
|
-
export interface CliEnv {}
|
|
5
|
-
|
|
6
|
-
/** Keeps the command app's environment boundary explicit while no command needs app configuration. */
|
|
7
|
-
export const readCliEnv = (_env: EnvSource): CliEnv => ({})
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { DynamicModule } from "@nestjs/common"
|
|
2
|
-
import { ClockModule } from "@modules/platform/clock"
|
|
3
|
-
import { LoggingModule } from "@modules/platform/logging"
|
|
4
|
-
|
|
5
|
-
/** The shared clock and logger; migrations retain their Supabase CLI authority. */
|
|
6
|
-
export const platformModules = (): Array<DynamicModule> => [
|
|
7
|
-
ClockModule.register({ isGlobal: true }),
|
|
8
|
-
LoggingModule.register({ isGlobal: true }),
|
|
9
|
-
]
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import "reflect-metadata";
|
|
2
|
-
import { CommandFactory } from "nest-commander";
|
|
3
|
-
import { SystemClockService } from "@modules/platform/clock";
|
|
4
|
-
import { EnvSource } from "@modules/platform/config";
|
|
5
|
-
import { createJsonLogger, LoggingLogEvent } from "@modules/platform/logging";
|
|
6
|
-
import { AppModule } from "./app.module";
|
|
7
|
-
import { readCliEnv } from "./cli.env";
|
|
8
|
-
|
|
9
|
-
/** The one-off command app. Its migrate command delegates schema authority to the Supabase CLI. */
|
|
10
|
-
async function bootstrap(): Promise<void> {
|
|
11
|
-
readCliEnv(EnvSource.fromProcess());
|
|
12
|
-
const logger = createJsonLogger(new SystemClockService());
|
|
13
|
-
await CommandFactory.run(AppModule, {
|
|
14
|
-
logger: false,
|
|
15
|
-
errorHandler: (error: Error) => {
|
|
16
|
-
logger.error(LoggingLogEvent.StartupFailed, error, { service: "cli" });
|
|
17
|
-
process.exit(1);
|
|
18
|
-
},
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
bootstrap().catch((error: unknown) => {
|
|
23
|
-
createJsonLogger(new SystemClockService()).error(
|
|
24
|
-
LoggingLogEvent.StartupFailed,
|
|
25
|
-
error,
|
|
26
|
-
{ service: "cli" },
|
|
27
|
-
);
|
|
28
|
-
process.exit(1);
|
|
29
|
-
});
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { Module } from "@nestjs/common";
|
|
2
|
-
import { ConfigurableModuleClass } from "./cli.module-definition";
|
|
3
|
-
import { MigrateModule } from "./migrate/migrate.module";
|
|
4
|
-
|
|
5
|
-
@Module({ imports: [MigrateModule.register({})] })
|
|
6
|
-
/** The cli feature root of the upgraded app. */
|
|
7
|
-
export class CliModule extends ConfigurableModuleClass {}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { spawnSync } from "node:child_process";
|
|
2
|
-
import { CommandRunner, SubCommand } from "nest-commander";
|
|
3
|
-
|
|
4
|
-
@SubCommand({
|
|
5
|
-
name: "run",
|
|
6
|
-
description: "Apply the Supabase migrations",
|
|
7
|
-
})
|
|
8
|
-
/** `cli migrate run`: delegates the schema authority under supabase/migrations to the Supabase CLI. */
|
|
9
|
-
export class RunCli extends CommandRunner {
|
|
10
|
-
/** Runs the installed Supabase CLI in the app root and preserves its exit result. */
|
|
11
|
-
async run(): Promise<void> {
|
|
12
|
-
const command = process.platform === "win32" ? "supabase.cmd" : "supabase";
|
|
13
|
-
const result = spawnSync(command, ["db", "push"], {
|
|
14
|
-
cwd: process.cwd(),
|
|
15
|
-
stdio: "inherit",
|
|
16
|
-
});
|
|
17
|
-
if (result.error !== undefined) throw result.error;
|
|
18
|
-
if (result.status !== 0)
|
|
19
|
-
throw new Error(
|
|
20
|
-
`supabase db push exited ${result.status ?? "without a status"}`,
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
}
|