@starci/hfs 4.0.8 → 4.0.9
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 +81 -39
- package/emit/contracts.mjs +56 -9
- package/emit/db-types.mjs +169 -0
- package/emit/events.mjs +41 -0
- package/emit/operations-worker.mjs +1 -1
- package/emit/operations.mjs +2 -2
- package/emit/schema-worker.mjs +1 -1
- package/lint/bound-sys.cjs +50 -0
- package/lint/run.mjs +53 -19
- package/package.json +14 -9
- package/report/sonar.mjs +8 -8
- package/runtime/engine/config.mjs +494 -0
- package/runtime/engine/invalid-config.mjs +15 -0
- package/runtime/engine/orca-config.mjs +27 -0
- package/runtime/knowledge/hfs/canon-pins.yaml +160 -29
- package/runtime/knowledge/hfs/peer-integrations.yaml +2 -2
- package/runtime/knowledge/hfs/rules.yaml +2059 -0
- package/runtime/knowledge/hfs/slots.yaml +912 -120
- package/runtime/knowledge/patterns/be/api.yaml +369 -0
- package/runtime/knowledge/patterns/be/cli.yaml +297 -0
- package/runtime/knowledge/patterns/be/domain.yaml +113 -0
- package/runtime/knowledge/patterns/be/event-bus.yaml +285 -0
- package/runtime/knowledge/patterns/be/jobs.yaml +261 -0
- package/runtime/knowledge/patterns/be/projections.yaml +178 -0
- package/runtime/knowledge/patterns/be/queues.yaml +236 -0
- package/runtime/knowledge/patterns/be/reactors.yaml +140 -0
- package/runtime/knowledge/patterns/be/realtime.yaml +222 -0
- package/runtime/knowledge/patterns/be/saga.yaml +248 -0
- package/runtime/knowledge/patterns/be/webhooks.yaml +221 -0
- package/runtime/knowledge/patterns/fe/folder.yaml +131 -25
- package/runtime/knowledge/sonar-gate.yaml +52 -18
- package/runtime/modules/kernel/failure-codes.yaml +571 -51
- package/runtime/modules/models/registry.yaml +591 -0
- package/runtime/modules/models/runtimes.yaml +701 -0
- package/runtime/scripts/api/fs/forbidden-root.mjs +51 -0
- package/runtime/scripts/api/fs/is-link-like.mjs +25 -0
- package/runtime/scripts/api/fs/lib.mjs +10 -2
- package/runtime/scripts/api/fs/safe-remove.mjs +12 -132
- package/runtime/scripts/api/git/config-get.mjs +10 -0
- package/runtime/scripts/api/git/diff.mjs +5 -0
- package/runtime/scripts/api/git/lib.mjs +16 -26
- package/runtime/scripts/api/git/log.mjs +5 -0
- package/runtime/scripts/api/git/ls-files.mjs +6 -0
- package/runtime/scripts/api/git/ls-tree.mjs +5 -0
- package/runtime/scripts/api/git/merge-base.mjs +9 -0
- package/runtime/scripts/api/git/remote.mjs +5 -0
- package/runtime/scripts/api/git/rev-parse-query.mjs +5 -0
- package/runtime/scripts/api/git/show.mjs +6 -0
- package/runtime/scripts/api/sops/decrypt.mjs +9 -5
- package/runtime/scripts/api/sops/lib.mjs +35 -0
- package/runtime/scripts/api/sops/seal.mjs +18 -0
- package/runtime/scripts/hfs/architecture/ast-walks.mjs +220 -0
- package/runtime/scripts/hfs/architecture/backend.mjs +16 -23
- package/runtime/scripts/hfs/architecture/background-unowned.mjs +16 -34
- package/runtime/scripts/hfs/architecture/client-reaches-server.mjs +3 -1
- package/runtime/scripts/hfs/architecture/clones.mjs +4 -4
- package/runtime/scripts/hfs/architecture/config.mjs +9 -6
- package/runtime/scripts/hfs/architecture/connection-map.mjs +20 -8
- package/runtime/scripts/hfs/architecture/context-coupling.mjs +88 -0
- package/runtime/scripts/hfs/architecture/context-map.mjs +237 -0
- package/runtime/scripts/hfs/architecture/context-owner.mjs +82 -0
- package/runtime/scripts/hfs/architecture/context-platform-tables.mjs +47 -0
- package/runtime/scripts/hfs/architecture/context-transaction.mjs +60 -0
- package/runtime/scripts/hfs/architecture/contract-fixture-guard.mjs +4 -10
- package/runtime/scripts/hfs/architecture/contracts.mjs +33 -162
- package/runtime/scripts/hfs/architecture/dead-exports.mjs +58 -29
- package/runtime/scripts/hfs/architecture/doc-language.mjs +1 -1
- package/runtime/scripts/hfs/architecture/entrypoint.mjs +2 -1
- package/runtime/scripts/hfs/architecture/fe-slot-allows.mjs +1 -1
- package/runtime/scripts/hfs/architecture/feature-shape.mjs +5 -2
- package/runtime/scripts/hfs/architecture/framework-pinned.mjs +1 -1
- package/runtime/scripts/hfs/architecture/frontend.mjs +17 -43
- package/runtime/scripts/hfs/architecture/hfs.mjs +24 -39
- package/runtime/scripts/hfs/architecture/i18n-keys.mjs +1 -1
- package/runtime/scripts/hfs/architecture/index.mjs +17 -4
- package/runtime/scripts/hfs/architecture/machine-ast.mjs +44 -11
- package/runtime/scripts/hfs/architecture/managed-scripts.mjs +27 -0
- package/runtime/scripts/hfs/architecture/module-per-transport.mjs +30 -6
- package/runtime/scripts/hfs/architecture/next-data.mjs +22 -63
- package/runtime/scripts/hfs/architecture/owners.mjs +35 -15
- package/runtime/scripts/hfs/architecture/register-once.mjs +2 -1
- package/runtime/scripts/hfs/architecture/registration.mjs +23 -81
- package/runtime/scripts/hfs/architecture/required-files.mjs +20 -12
- package/runtime/scripts/hfs/architecture/schema-owner.mjs +17 -114
- package/runtime/scripts/hfs/architecture/server-action.mjs +24 -0
- package/runtime/scripts/hfs/architecture/side-boundary.mjs +16 -0
- package/runtime/scripts/hfs/architecture/source-names.mjs +27 -147
- package/runtime/scripts/hfs/architecture/sql-owner.mjs +59 -18
- package/runtime/scripts/hfs/architecture/sql-returning.mjs +64 -0
- package/runtime/scripts/hfs/architecture/supabase-ast.mjs +111 -0
- package/runtime/scripts/hfs/architecture/supabase-be.mjs +131 -0
- package/runtime/scripts/hfs/architecture/supabase-tables.mjs +42 -0
- package/runtime/scripts/hfs/architecture/supabase.mjs +434 -0
- package/runtime/scripts/hfs/architecture/surface.mjs +9 -3
- package/runtime/scripts/hfs/architecture/test-world-files.mjs +9 -19
- package/runtime/scripts/hfs/architecture/tiers.mjs +47 -5
- package/runtime/scripts/hfs/architecture/transport-owner.mjs +3 -3
- package/runtime/scripts/hfs/architecture/typescript.mjs +12 -26
- package/runtime/scripts/hfs/architecture.mjs +4 -4
- package/runtime/scripts/hfs/check.mjs +75 -72
- package/runtime/scripts/hfs/coverage-scope.mjs +162 -0
- package/runtime/scripts/hfs/declaration-shape.mjs +62 -0
- package/runtime/scripts/hfs/declaration-slots.mjs +75 -0
- package/runtime/scripts/hfs/edition-slots.mjs +66 -0
- package/runtime/scripts/hfs/manifest-shape.mjs +109 -32
- package/runtime/scripts/hfs/param-names.mjs +18 -0
- package/runtime/scripts/hfs/path-findings.mjs +1 -1
- package/runtime/scripts/hfs/repo-identity.mjs +9 -6
- package/runtime/scripts/hfs/rule-params-shape.mjs +50 -0
- package/runtime/scripts/hfs/rules/app-root.mjs +51 -0
- package/runtime/scripts/hfs/rules/cli.mjs +37 -0
- package/runtime/scripts/hfs/rules/contract-compat.mjs +71 -0
- package/runtime/scripts/hfs/rules/contract.mjs +10 -9
- package/runtime/scripts/hfs/rules/database-config.mjs +102 -0
- package/runtime/scripts/hfs/rules/database-constants.mjs +13 -0
- package/runtime/scripts/hfs/rules/database-migrations.mjs +111 -0
- package/runtime/scripts/hfs/rules/database-plpgsql.mjs +233 -0
- package/runtime/scripts/hfs/rules/database-sql.mjs +336 -0
- package/runtime/scripts/hfs/rules/database.mjs +68 -0
- package/runtime/scripts/hfs/rules/deps.mjs +1 -1
- package/runtime/scripts/hfs/rules/docker.mjs +259 -0
- package/runtime/scripts/hfs/rules/edition.mjs +111 -0
- package/runtime/scripts/hfs/rules/event-bus.mjs +153 -0
- package/runtime/scripts/hfs/rules/fe-contract-documents.mjs +1 -1
- package/runtime/scripts/hfs/rules/fe-no-tests.mjs +6 -5
- package/runtime/scripts/hfs/rules/frontend-tree.mjs +9 -9
- package/runtime/scripts/hfs/rules/integration-specs.mjs +3 -6
- package/runtime/scripts/hfs/rules/kinds.mjs +84 -0
- package/runtime/scripts/hfs/rules/lint-suppression.mjs +1 -1
- package/runtime/scripts/hfs/rules/monorepo.mjs +179 -0
- package/runtime/scripts/hfs/rules/peer-integrations.mjs +3 -3
- package/runtime/scripts/hfs/rules/pipeline.mjs +11 -21
- package/runtime/scripts/hfs/rules/proof-commands.mjs +2 -2
- package/runtime/scripts/hfs/rules/read.mjs +1 -1
- package/runtime/scripts/hfs/rules/repo-local-checks.mjs +2 -2
- package/runtime/scripts/hfs/rules/saga.mjs +170 -0
- package/runtime/scripts/hfs/rules/secrets.mjs +3 -3
- package/runtime/scripts/hfs/rules/services.mjs +220 -0
- package/runtime/scripts/hfs/rules/spec-placement.mjs +1 -1
- package/runtime/scripts/hfs/rules/stacks.mjs +3 -3
- package/runtime/scripts/hfs/rules/supabase-secrets.mjs +89 -0
- package/runtime/scripts/hfs/rules/test-topology.mjs +2 -2
- package/runtime/scripts/hfs/secret.mjs +175 -0
- package/runtime/scripts/hfs/slots.mjs +78 -108
- package/runtime/scripts/hfs/sql/pg-parse.mjs +46 -0
- package/runtime/scripts/hfs/test-world-slot.mjs +6 -0
- package/runtime/scripts/hfs/tree.mjs +5 -4
- package/runtime/scripts/hfs/typescript-programs.mjs +0 -5
- package/runtime/scripts/hfs/view.mjs +3 -2
- package/runtime/scripts/lib/dockerfile.mjs +124 -0
- package/runtime/scripts/lib/env.mjs +10 -0
- package/runtime/scripts/lib/event-contract.mjs +103 -0
- package/runtime/scripts/lib/git.mjs +36 -0
- package/runtime/scripts/lib/graphql-contract.mjs +1 -1
- package/runtime/scripts/lib/i18n.mjs +86 -0
- package/runtime/scripts/lib/json.mjs +13 -3
- package/runtime/scripts/lib/language.mjs +24 -5
- package/runtime/scripts/lib/list.mjs +20 -0
- package/runtime/scripts/lib/package-at.mjs +37 -0
- package/runtime/scripts/lib/path-key.mjs +57 -2
- package/runtime/scripts/lib/read-text.mjs +34 -0
- package/runtime/scripts/lib/regex.mjs +4 -0
- package/runtime/scripts/lib/same-text.mjs +5 -0
- package/runtime/scripts/lib/secret-patterns.mjs +4 -3
- package/runtime/scripts/lib/sleep-sync.mjs +2 -1
- package/runtime/scripts/lib/sops-envelope.mjs +58 -0
- package/runtime/scripts/lib/stack-services.mjs +7 -31
- package/runtime/scripts/lib/ts-ast.mjs +35 -0
- package/runtime/scripts/lib/walk.mjs +4 -3
- package/scaffold/add-app.mjs +174 -0
- package/scaffold/add-cli-lite.mjs +257 -0
- package/scaffold/add-inbox-lite.mjs +314 -0
- package/scaffold/add-table.mjs +344 -0
- package/scaffold/add.mjs +299 -0
- package/scaffold/app.mjs +358 -69
- package/scaffold/edition-gate.mjs +25 -0
- package/scaffold/image.mjs +19 -0
- package/scaffold/lite-exports.mjs +186 -0
- package/scaffold/service.mjs +32 -26
- package/scaffold/supabase-ports.mjs +26 -0
- package/src/main.mjs +327 -0
- package/sync/cli.mjs +6 -9
- package/sync/format.mjs +1 -1
- package/sync/hygiene.mjs +10 -10
- package/sync/index.mjs +167 -104
- package/sync/managed.mjs +19 -11
- package/sync/sonar-key.mjs +5 -0
- package/templates/app/ci-workflows/github/workflows/ci.yml +14 -14
- package/templates/app/ci-workflows/github/workflows/images.yml +37 -0
- package/templates/app/ci-workflows/sonar-steps.yml +9 -0
- package/templates/app/ci-workflows-lite/github/workflows/ci.yml +66 -0
- package/templates/app/ci-workflows-lite/github/workflows/db-deploy.yml +31 -0
- package/templates/app/ci-workflows-lite/github/workflows/images.yml +37 -0
- package/templates/app/codegen-lite/scripts/codegen.mjs +32 -0
- package/templates/app/docker-ignore/dockerignore +50 -0
- package/templates/app/gitignore-lite +35 -0
- package/templates/app/hooks/husky/pre-commit +3 -8
- package/templates/app/hooks/husky/pre-push +45 -6
- package/templates/app/package-scripts/core.json +8 -0
- package/templates/app/package-scripts/package.json +3 -10
- package/templates/app/package-scripts-lite/package.json +15 -0
- package/templates/app/quality-config/codecov.yml +15 -3
- package/templates/app/quality-config/sonar-base.properties +4 -0
- package/templates/app/quality-config/sonar-project.properties +1 -4
- package/templates/app/quality-config-lite/sonar-project.properties +5 -0
- package/templates/app/skeleton/.starcistacks/dev/seeds/primary-notes.sql +5 -0
- package/templates/app/skeleton/.starciwork/features/system-health/index.yaml +4 -0
- package/templates/app/skeleton/.starciwork/{features/index.yaml → index.yaml} +2 -2
- package/templates/app/skeleton/README.md +7 -5
- package/templates/app/skeleton-lite/.sops.yaml +3 -0
- package/templates/app/skeleton-lite/.starcistacks/dev/environment.json +5 -0
- package/templates/app/skeleton-lite/.starcistacks/dev/secrets/.gitkeep +1 -0
- package/templates/app/skeleton-lite/.starciwork/shell/index.yaml +55 -0
- package/templates/app/skeleton-lite/README.md +40 -0
- package/templates/app/skeleton-lite/supabase/config.toml +41 -0
- package/templates/app/skeleton-lite/supabase/migrations/__timestamp___baseline.sql +56 -0
- package/templates/app/skeleton-lite/supabase/seed.sql +0 -0
- package/templates/app/task-graph/turbo.json +23 -0
- package/templates/app/tool-config-lite/prettierignore +2 -0
- package/templates/app/tool-config-lite/prettierrc +1 -0
- package/templates/app/upgrade-full/.starcistacks/application-stacks.yaml +38 -0
- package/templates/app/upgrade-full/.starcistacks/dev/README.md +10 -0
- package/templates/app/upgrade-full/.starcistacks/dev/infra/compose/api.yaml +13 -0
- package/templates/app/upgrade-full/.starcistacks/dev/infra/compose/compose.yaml +3 -0
- package/templates/app/upgrade-full/.starcistacks/dev/infra/compose/postgres.yaml +12 -0
- package/templates/app/upgrade-full/.starcistacks/dev/infra/metadata.json +7 -0
- package/templates/be/common/main-listen.ts.partial +14 -0
- package/templates/be/common/sql-ident.ts.partial +7 -0
- package/templates/be/common/sql-tag.ts.partial +5 -0
- package/templates/be/image/api/Dockerfile +38 -0
- package/templates/be/image/cli/Dockerfile +38 -0
- package/templates/be/image/worker/Dockerfile +36 -0
- package/templates/be/inbox/database-client.ts.tpl +50 -0
- package/templates/be/inbox/index.ts.tpl +2 -0
- package/templates/be/inbox/migration.sql.tpl +29 -0
- package/templates/be/inbox/module-definition.ts.tpl +6 -0
- package/templates/be/inbox/module.ts.tpl +14 -0
- package/templates/be/inbox/options.ts.tpl +2 -0
- package/templates/be/inbox/service.ts.tpl +33 -0
- package/templates/be/inbox/sql.ts.tpl +16 -0
- package/templates/be/inbox/webhook-door.ts.tpl +36 -0
- package/templates/be/patterns/api/application.command.http.ts.tpl +10 -0
- package/templates/be/patterns/api/application.command.ts.tpl +10 -0
- package/templates/be/patterns/api/application.contracts.ts.tpl +11 -0
- package/templates/be/patterns/api/application.handler.http.ts.tpl +22 -0
- package/templates/be/patterns/api/application.handler.ts.tpl +22 -0
- package/templates/be/patterns/api/feature.index.http.ts.tpl +1 -0
- package/templates/be/patterns/api/feature.index.ts.tpl +1 -0
- package/templates/be/patterns/api/feature.module.ts.tpl +6 -0
- package/templates/be/patterns/api/graphql.input.ts.tpl +13 -0
- package/templates/be/patterns/api/graphql.mapper.ts.tpl +9 -0
- package/templates/be/patterns/api/graphql.module.ts.tpl +7 -0
- package/templates/be/patterns/api/graphql.resolver.ts.tpl +27 -0
- package/templates/be/patterns/api/graphql.type.ts.tpl +9 -0
- package/templates/be/patterns/api/http.controller.ts.tpl +27 -0
- package/templates/be/patterns/api/http.mapper.ts.tpl +9 -0
- package/templates/be/patterns/api/http.module.ts.tpl +7 -0
- package/templates/be/patterns/api/http.request.ts.tpl +10 -0
- package/templates/be/patterns/api/http.response.ts.tpl +5 -0
- package/templates/be/patterns/cli/group.cli.spec.ts.tpl +15 -0
- package/templates/be/patterns/cli/group.cli.ts.tpl +11 -0
- package/templates/be/patterns/cli/group.module.ts.tpl +7 -0
- package/templates/be/patterns/cli/sub.run.cli.spec.ts.tpl +17 -0
- package/templates/be/patterns/cli/sub.run.cli.ts.tpl +15 -0
- package/templates/be/patterns/event-bus/platform/errors/event-bus.error.ts.tpl +22 -0
- package/templates/be/patterns/event-bus/platform/event-bus.config.ts.tpl +19 -0
- package/templates/be/patterns/event-bus/platform/event-bus.contracts.ts.tpl +58 -0
- package/templates/be/patterns/event-bus/platform/event-bus.decorators.ts.tpl +46 -0
- package/templates/be/patterns/event-bus/platform/event-bus.log-events.ts.tpl +12 -0
- package/templates/be/patterns/event-bus/platform/event-bus.module-definition.ts.tpl +10 -0
- package/templates/be/patterns/event-bus/platform/event-bus.module.ts.tpl +52 -0
- package/templates/be/patterns/event-bus/platform/event-bus.options.ts.tpl +19 -0
- package/templates/be/patterns/event-bus/platform/event-bus.port.ts.tpl +28 -0
- package/templates/be/patterns/event-bus/platform/event-bus.service.spec.ts.tpl +165 -0
- package/templates/be/patterns/event-bus/platform/event-bus.service.ts.tpl +93 -0
- package/templates/be/patterns/event-bus/platform/event-envelope.policy.spec.ts.tpl +90 -0
- package/templates/be/patterns/event-bus/platform/event-envelope.policy.ts.tpl +58 -0
- package/templates/be/patterns/event-bus/platform/event-relay.service.spec.ts.tpl +136 -0
- package/templates/be/patterns/event-bus/platform/event-relay.service.ts.tpl +56 -0
- package/templates/be/patterns/event-bus/platform/event-runner.service.spec.ts.tpl +272 -0
- package/templates/be/patterns/event-bus/platform/event-runner.service.ts.tpl +128 -0
- package/templates/be/patterns/event-bus/platform/event-transport.port.ts.tpl +180 -0
- package/templates/be/patterns/event-bus/platform/event.policy.spec.ts.tpl +67 -0
- package/templates/be/patterns/event-bus/platform/event.policy.ts.tpl +38 -0
- package/templates/be/patterns/event-bus/platform/index.ts.tpl +11 -0
- package/templates/be/patterns/event-bus/platform/kafka-event-transport.client.spec.ts.tpl +348 -0
- package/templates/be/patterns/event-bus/platform/kafka-event-transport.client.ts.tpl +241 -0
- package/templates/be/patterns/event-bus/platform/messages/event-bus.messages.ts.tpl +15 -0
- package/templates/be/patterns/event-bus/platform/persistence/connection.ts.tpl +8 -0
- package/templates/be/patterns/event-bus/platform/persistence/entities/event-outbox.entity.ts.tpl +37 -0
- package/templates/be/patterns/event-bus/platform/persistence/event-bus.rows.ts.tpl +11 -0
- package/templates/be/patterns/event-bus/platform/persistence/event-bus.sql.ts.tpl +12 -0
- package/templates/be/patterns/event-bus/platform/persistence/migrations/1789800009000-create-event-outbox.ts.tpl +26 -0
- package/templates/be/patterns/jobs/job.index.ts.tpl +1 -0
- package/templates/be/patterns/jobs/job.module.ts.tpl +6 -0
- package/templates/be/patterns/jobs/job.processor.ts.tpl +20 -0
- package/templates/be/patterns/jobs/job.queue.module.ts.tpl +20 -0
- package/templates/be/patterns/jobs/job.step.ts.tpl +19 -0
- package/templates/be/patterns/jobs/platform/fenced.processor.spec.ts.tpl +31 -0
- package/templates/be/patterns/jobs/platform/fenced.processor.ts.tpl +13 -0
- package/templates/be/patterns/jobs/platform/job-claim.service.spec.ts.tpl +150 -0
- package/templates/be/patterns/jobs/platform/job-claim.service.ts.tpl +100 -0
- package/templates/be/patterns/jobs/platform/job-runner.service.spec.ts.tpl +138 -0
- package/templates/be/patterns/jobs/platform/job-runner.service.ts.tpl +69 -0
- package/templates/be/patterns/jobs/platform/jobs.config.ts.tpl +11 -0
- package/templates/be/patterns/jobs/platform/jobs.contracts.ts.tpl +62 -0
- package/templates/be/patterns/jobs/platform/jobs.decorators.ts.tpl +31 -0
- package/templates/be/patterns/jobs/platform/jobs.error.ts.tpl +22 -0
- package/templates/be/patterns/jobs/platform/jobs.index.ts.tpl +11 -0
- package/templates/be/patterns/jobs/platform/jobs.log-events.ts.tpl +9 -0
- package/templates/be/patterns/jobs/platform/jobs.messages.ts.tpl +15 -0
- package/templates/be/patterns/jobs/platform/jobs.module-definition.ts.tpl +10 -0
- package/templates/be/patterns/jobs/platform/jobs.module.ts.tpl +32 -0
- package/templates/be/patterns/jobs/platform/jobs.options.ts.tpl +11 -0
- package/templates/be/patterns/jobs/platform/jobs.port.ts.tpl +36 -0
- package/templates/be/patterns/jobs/platform/persistence.connection.ts.tpl +8 -0
- package/templates/be/patterns/jobs/platform/persistence.job.entity.ts.tpl +53 -0
- package/templates/be/patterns/jobs/platform/persistence.jobs.rows.ts.tpl +13 -0
- package/templates/be/patterns/jobs/platform/persistence.jobs.sql.ts.tpl +33 -0
- package/templates/be/patterns/jobs/platform/persistence.migration.ts.tpl +29 -0
- package/templates/be/patterns/outbox/platform/index.ts.tpl +2 -0
- package/templates/be/patterns/outbox/platform/outbox-relay.policy.spec.ts.tpl +96 -0
- package/templates/be/patterns/outbox/platform/outbox-relay.policy.ts.tpl +78 -0
- package/templates/be/patterns/outbox/platform/outbox.log-events.ts.tpl +5 -0
- package/templates/be/patterns/projections/migration.ts.tpl +18 -0
- package/templates/be/patterns/projections/persistence.connection.ts.tpl +8 -0
- package/templates/be/patterns/projections/projection.entity.ts.tpl +9 -0
- package/templates/be/patterns/projections/projection.index.ts.tpl +3 -0
- package/templates/be/patterns/projections/projection.module-definition.ts.tpl +7 -0
- package/templates/be/patterns/projections/projection.module.ts.tpl +18 -0
- package/templates/be/patterns/projections/projection.options.ts.tpl +2 -0
- package/templates/be/patterns/projections/projection.projection.spec.ts.tpl +55 -0
- package/templates/be/patterns/projections/projection.projection.ts.tpl +21 -0
- package/templates/be/patterns/queues/platform/bullmq-queue-transport.client.spec.ts.tpl +142 -0
- package/templates/be/patterns/queues/platform/bullmq-queue-transport.client.ts.tpl +81 -0
- package/templates/be/patterns/queues/platform/persistence.connection.ts.tpl +8 -0
- package/templates/be/patterns/queues/platform/persistence.migration.ts.tpl +25 -0
- package/templates/be/patterns/queues/platform/persistence.queue-outbox.entity.ts.tpl +25 -0
- package/templates/be/patterns/queues/platform/persistence.queue.rows.ts.tpl +9 -0
- package/templates/be/patterns/queues/platform/persistence.queue.sql.ts.tpl +12 -0
- package/templates/be/patterns/queues/platform/queue-outbox.service.spec.ts.tpl +48 -0
- package/templates/be/patterns/queues/platform/queue-outbox.service.ts.tpl +17 -0
- package/templates/be/patterns/queues/platform/queue-relay.service.spec.ts.tpl +128 -0
- package/templates/be/patterns/queues/platform/queue-relay.service.ts.tpl +48 -0
- package/templates/be/patterns/queues/platform/queue-transport.port.ts.tpl +115 -0
- package/templates/be/patterns/queues/platform/queue-worker.service.spec.ts.tpl +91 -0
- package/templates/be/patterns/queues/platform/queue-worker.service.ts.tpl +45 -0
- package/templates/be/patterns/queues/platform/queue.config.ts.tpl +15 -0
- package/templates/be/patterns/queues/platform/queue.contracts.ts.tpl +31 -0
- package/templates/be/patterns/queues/platform/queue.decorators.ts.tpl +45 -0
- package/templates/be/patterns/queues/platform/queue.index.ts.tpl +7 -0
- package/templates/be/patterns/queues/platform/queue.log-events.ts.tpl +5 -0
- package/templates/be/patterns/queues/platform/queue.module-definition.ts.tpl +10 -0
- package/templates/be/patterns/queues/platform/queue.module.ts.tpl +62 -0
- package/templates/be/patterns/queues/platform/queue.options.ts.tpl +22 -0
- package/templates/be/patterns/queues/platform/queue.policy.spec.ts.tpl +19 -0
- package/templates/be/patterns/queues/platform/queue.policy.ts.tpl +11 -0
- package/templates/be/patterns/queues/platform/queue.port.ts.tpl +14 -0
- package/templates/be/patterns/queues/queue.index.ts.tpl +3 -0
- package/templates/be/patterns/queues/queue.module.ts.tpl +6 -0
- package/templates/be/patterns/queues/queue.queue.ts.tpl +23 -0
- package/templates/be/patterns/reactors/application.command.ts.tpl +10 -0
- package/templates/be/patterns/reactors/application.contracts.ts.tpl +12 -0
- package/templates/be/patterns/reactors/application.handler.ts.tpl +22 -0
- package/templates/be/patterns/reactors/consumer.ts.tpl +19 -0
- package/templates/be/patterns/reactors/message.module.ts.tpl +20 -0
- package/templates/be/patterns/reactors/reactor.index.ts.tpl +1 -0
- package/templates/be/patterns/reactors/reactor.module.ts.tpl +6 -0
- package/templates/be/patterns/realtime/channel.graphql.module.ts.tpl +6 -0
- package/templates/be/patterns/realtime/channel.index.ts.tpl +1 -0
- package/templates/be/patterns/realtime/channel.input.ts.tpl +12 -0
- package/templates/be/patterns/realtime/channel.subscription.spec.ts.tpl +51 -0
- package/templates/be/patterns/realtime/channel.subscription.ts.tpl +32 -0
- package/templates/be/patterns/realtime/channel.type.ts.tpl +9 -0
- package/templates/be/patterns/saga/saga.compensate.command.ts.tpl +11 -0
- package/templates/be/patterns/saga/saga.compensate.contracts.ts.tpl +7 -0
- package/templates/be/patterns/saga/saga.compensate.handler.ts.tpl +22 -0
- package/templates/be/patterns/saga/saga.compensation.ts.tpl +21 -0
- package/templates/be/patterns/saga/saga.complete.command.ts.tpl +11 -0
- package/templates/be/patterns/saga/saga.complete.contracts.ts.tpl +7 -0
- package/templates/be/patterns/saga/saga.complete.handler.ts.tpl +22 -0
- package/templates/be/patterns/saga/saga.done.consumer.ts.tpl +21 -0
- package/templates/be/patterns/saga/saga.failed.consumer.ts.tpl +21 -0
- package/templates/be/patterns/saga/saga.index.ts.tpl +1 -0
- package/templates/be/patterns/saga/saga.message.module.ts.tpl +23 -0
- package/templates/be/patterns/saga/saga.module.ts.tpl +20 -0
- package/templates/be/patterns/saga/saga.service.spec.ts.tpl +70 -0
- package/templates/be/patterns/saga/saga.service.ts.tpl +44 -0
- package/templates/be/patterns/saga/saga.state.ts.tpl +14 -0
- package/templates/be/patterns/saga/saga.step.ts.tpl +11 -0
- package/templates/be/patterns/saga/saga.undo.command.ts.tpl +10 -0
- package/templates/be/patterns/saga/saga.undo.contracts.ts.tpl +5 -0
- package/templates/be/patterns/saga/saga.undo.handler.ts.tpl +21 -0
- package/templates/be/patterns/webhooks/webhook.door.spec.ts.tpl +72 -0
- package/templates/be/patterns/webhooks/webhook.door.ts.tpl +36 -0
- package/templates/be/patterns/webhooks/webhook.http.module.ts.tpl +6 -0
- package/templates/be/patterns/webhooks/webhook.index.ts.tpl +1 -0
- package/templates/be/patterns/webhooks/webhook.request.ts.tpl +9 -0
- package/templates/be/skeleton/apps/__app__/src/__app__.options.ts +3 -0
- package/templates/be/skeleton/apps/__app__/src/app.module.ts +15 -2
- package/templates/be/skeleton/apps/__app__/src/main.ts +7 -15
- package/templates/be/skeleton/apps/cli/src/app.module.ts +30 -0
- package/templates/be/skeleton/apps/cli/src/cli.options.ts +22 -0
- package/templates/be/skeleton/apps/cli/src/main.ts +24 -0
- package/templates/be/skeleton/src/features/cli/cli.module.ts +7 -0
- package/templates/be/skeleton/src/features/cli/index.ts +1 -0
- package/templates/be/skeleton/src/features/cli/migrate/migrate.cli.spec.ts +17 -0
- package/templates/be/skeleton/src/features/cli/migrate/migrate.cli.ts +15 -0
- package/templates/be/skeleton/src/features/cli/migrate/migrate.module.ts +7 -0
- package/templates/be/skeleton/src/features/cli/migrate/subs/run.cli.spec.ts +17 -0
- package/templates/be/skeleton/src/features/cli/migrate/subs/run.cli.ts +18 -0
- package/templates/be/skeleton/src/features/cli/seed/seed.cli.spec.ts +17 -0
- package/templates/be/skeleton/src/features/cli/seed/seed.cli.ts +15 -0
- package/templates/be/skeleton/src/features/cli/seed/seed.module.ts +7 -0
- package/templates/be/skeleton/src/features/cli/seed/subs/run.cli.spec.ts +33 -0
- package/templates/be/skeleton/src/features/cli/seed/subs/run.cli.ts +34 -0
- package/templates/be/skeleton/src/modules/domain/identity/admission.policy.spec.ts +13 -0
- package/templates/be/skeleton/src/modules/domain/identity/auth.guard.spec.ts +40 -0
- package/templates/be/skeleton/src/modules/domain/identity/messages/identity.messages.ts +1 -1
- package/templates/be/skeleton/src/modules/domain/note/errors/note.error.ts +16 -0
- package/templates/be/skeleton/src/modules/domain/note/index.ts +3 -0
- package/templates/be/skeleton/src/modules/domain/note/note.contracts.ts +19 -0
- package/templates/be/skeleton/src/modules/domain/note/note.decorators.ts +9 -0
- package/templates/be/skeleton/src/modules/domain/note/note.module-definition.ts +7 -0
- package/templates/be/skeleton/src/modules/domain/note/note.module.ts +19 -0
- package/templates/be/skeleton/src/modules/domain/note/note.options.ts +2 -0
- package/templates/be/skeleton/src/modules/domain/note/note.service.spec.ts +76 -0
- package/templates/be/skeleton/src/modules/domain/note/note.service.ts +37 -0
- package/templates/be/skeleton/src/modules/domain/note/persistence/connection.ts +8 -0
- package/templates/be/skeleton/src/modules/domain/note/persistence/entities/note.entity.ts +17 -0
- package/templates/be/skeleton/src/modules/domain/note/persistence/migrations/1790000000000-init-note.ts +22 -0
- package/templates/be/skeleton/src/modules/domain/note/persistence/note.rows.ts +17 -0
- package/templates/be/skeleton/src/modules/domain/note/persistence/note.sql.ts +4 -0
- package/templates/be/skeleton/src/modules/platform/config/env-source.config.ts +20 -0
- package/templates/be/skeleton/src/modules/platform/config/index.ts +1 -1
- package/templates/be/skeleton/src/modules/platform/cqrs/cqrs.contracts.ts +18 -0
- package/templates/be/skeleton/src/modules/platform/database/connection-source.client.spec.ts +41 -0
- package/templates/be/skeleton/src/modules/platform/database/connection-source.client.ts +17 -0
- package/templates/be/skeleton/src/modules/platform/database/database.module-definition.ts +13 -0
- package/templates/be/skeleton/src/modules/platform/database/database.module.ts +77 -0
- package/templates/be/skeleton/src/modules/platform/database/database.options.ts +30 -0
- package/templates/be/skeleton/src/modules/platform/database/database.port.ts +65 -0
- package/templates/be/skeleton/src/modules/platform/database/database.sql.ts +47 -0
- package/templates/be/skeleton/src/modules/platform/database/errors/database.error.ts +16 -0
- package/templates/be/skeleton/src/modules/platform/database/index.ts +9 -0
- package/templates/be/skeleton/src/modules/platform/database/migrate-connections.client.ts +30 -0
- package/templates/be/skeleton/src/modules/platform/database/migration-runner.service.spec.ts +84 -0
- package/templates/be/skeleton/src/modules/platform/database/migration-runner.service.ts +23 -0
- package/templates/be/skeleton/src/modules/platform/database/primary.config.ts +9 -0
- package/templates/be/skeleton/src/modules/platform/database/primary.connection.ts +2 -0
- package/templates/be/skeleton/src/modules/platform/database/primary.decorators.ts +10 -0
- package/templates/be/skeleton/src/modules/platform/database/seed-connections.client.spec.ts +108 -0
- package/templates/be/skeleton/src/modules/platform/database/seed-connections.client.ts +75 -0
- package/templates/be/skeleton/src/modules/platform/database/seed-runner.service.spec.ts +88 -0
- package/templates/be/skeleton/src/modules/platform/database/seed-runner.service.ts +29 -0
- package/templates/be/skeleton/src/modules/platform/errors/errors.filter.spec.ts +48 -0
- package/templates/be/skeleton/src/modules/platform/errors/messages/errors.messages.ts +1 -1
- package/templates/be/skeleton/src/modules/platform/http-security/errors/http-security.error.ts +12 -0
- package/templates/be/skeleton/src/modules/platform/http-security/execution-request.mapper.spec.ts +16 -0
- package/templates/be/skeleton/src/modules/platform/http-security/http-security.config.ts +8 -1
- package/templates/be/skeleton/src/modules/platform/http-security/http-security.decorators.ts +8 -0
- package/templates/be/skeleton/src/modules/platform/http-security/http-security.module.ts +14 -1
- package/templates/be/skeleton/src/modules/platform/http-security/http-security.options.ts +12 -0
- package/templates/be/skeleton/src/modules/platform/http-security/messages/http-security.messages.ts +10 -2
- package/templates/be/skeleton/src/modules/platform/http-security/origin.guard.spec.ts +63 -0
- package/templates/be/skeleton/src/modules/platform/http-security/rate-limit.guard.spec.ts +108 -0
- package/templates/be/skeleton/src/modules/platform/http-security/request-validation.service.spec.ts +39 -0
- package/templates/be/skeleton/src/modules/platform/http-security/request-validation.service.ts +25 -0
- package/templates/be/skeleton/src/modules/platform/http-security/webhook-signature.service.spec.ts +172 -0
- package/templates/be/skeleton/src/modules/platform/http-security/webhook-signature.service.ts +66 -0
- package/templates/be/skeleton/src/modules/platform/logging/logging.log-events.ts +3 -1
- package/templates/be/skeleton/src/modules/platform/primitives/outcome.mapper.spec.ts +52 -0
- package/templates/be/skeleton-lite/apps/api/Dockerfile +37 -0
- package/templates/be/skeleton-lite/apps/api/src/api.options.ts +16 -0
- package/templates/be/skeleton-lite/apps/api/src/app.module.ts +81 -0
- package/templates/be/skeleton-lite/apps/api/src/main.ts +34 -0
- package/templates/be/skeleton-lite/src/modules/domain/identity/admission.policy.ts +14 -0
- package/templates/be/skeleton-lite/src/modules/domain/identity/auth.guard.ts +50 -0
- package/templates/be/skeleton-lite/src/modules/domain/identity/identity.contracts.ts +26 -0
- package/templates/be/skeleton-lite/src/modules/domain/identity/identity.decorators.ts +19 -0
- package/templates/be/skeleton-lite/src/modules/domain/identity/identity.module.ts +26 -0
- package/templates/be/skeleton-lite/src/modules/domain/identity/identity.options.ts +7 -0
- package/templates/be/skeleton-lite/src/modules/domain/identity/index.ts +6 -0
- package/templates/be/skeleton-lite/src/modules/integrations/supabase/errors/supabase.error.ts +19 -0
- package/templates/be/skeleton-lite/src/modules/integrations/supabase/index.ts +10 -0
- package/templates/be/skeleton-lite/src/modules/integrations/supabase/supabase.client.ts +24 -0
- package/templates/be/skeleton-lite/src/modules/integrations/supabase/supabase.config.ts +8 -0
- package/templates/be/skeleton-lite/src/modules/integrations/supabase/supabase.decorators.ts +17 -0
- package/templates/be/skeleton-lite/src/modules/integrations/supabase/supabase.jwks.ts +32 -0
- package/templates/be/skeleton-lite/src/modules/integrations/supabase/supabase.options.ts +24 -0
- package/templates/be/skeleton-lite/src/modules/platform/cqrs/index.ts +4 -0
- package/templates/be/skeleton-lite/src/modules/platform/database/database.module.ts +54 -0
- package/templates/be/skeleton-lite/src/modules/platform/database/database.options.ts +23 -0
- package/templates/be/skeleton-lite/src/modules/platform/database/database.port.ts +10 -0
- package/templates/be/skeleton-lite/src/modules/platform/database/database.sql.ts +49 -0
- package/templates/be/skeleton-lite/src/modules/platform/database/index.ts +4 -0
- package/templates/be/skeleton-lite/src/modules/platform/database/migration-runner.service.ts +21 -0
- package/templates/be/skeleton-lite/src/modules/platform/database/primary.config.ts +11 -0
- package/templates/be/skeleton-lite/src/modules/platform/database/seed-runner.service.ts +28 -0
- package/templates/be/skeleton-lite/src/modules/platform/http-security/http-security.module.ts +25 -0
- package/templates/be/skeleton-lite/src/modules/platform/http-security/index.ts +9 -0
- package/templates/be/skeleton-lite/src/modules/platform/i18n/index.ts +4 -0
- package/templates/be/skeleton-lite/src/modules/platform/logging/index.ts +5 -0
- package/templates/be/table/error.ts.tpl +16 -0
- package/templates/be/table/index.ts.tpl +2 -0
- package/templates/be/table/migration.sql.tpl +51 -0
- package/templates/be/table/module-definition.ts.tpl +7 -0
- package/templates/be/table/module.ts.tpl +14 -0
- package/templates/be/table/options.ts.tpl +2 -0
- package/templates/be/table/rows.ts.tpl +4 -0
- package/templates/be/table/service.ts.tpl +23 -0
- package/templates/be/table/sql.ts.tpl +4 -0
- package/templates/be/tool-config/jest.config.js +3 -1
- package/templates/be/upgrade-full/apps/cli/src/app.module.ts +14 -0
- package/templates/be/upgrade-full/apps/cli/src/main.ts +26 -0
- package/templates/be/upgrade-full/src/features/cli/cli.module.ts +6 -0
- package/templates/be/upgrade-full/src/features/cli/migrate/subs/run.cli.ts +23 -0
- package/templates/common/gitignore.base +1 -2
- package/templates/fe/app/package.json.tpl +1 -0
- package/templates/fe/app/tsconfig.json +12 -0
- package/templates/fe/common/app-layout.tsx.partial +8 -0
- package/templates/fe/common/site-shell.tsx.partial +9 -0
- package/templates/fe/image/next/Dockerfile +42 -0
- package/templates/fe/skeleton/apps/app/next.config.ts +23 -0
- package/templates/fe/skeleton/apps/app/postcss.config.mjs +7 -0
- package/templates/fe/skeleton/apps/{__app__ → app}/src/app/[locale]/error.tsx +2 -2
- package/templates/fe/skeleton/apps/app/src/app/[locale]/layout.tsx +22 -0
- package/templates/fe/skeleton/apps/{__app__ → app}/src/app/[locale]/loading.tsx +2 -2
- package/templates/fe/skeleton/apps/{__app__ → app}/src/app/[locale]/not-found.tsx +2 -2
- package/templates/fe/skeleton/apps/app/src/app/[locale]/page.tsx +9 -0
- package/templates/fe/skeleton/apps/{__app__ → app}/src/app/global-error.tsx +2 -2
- package/templates/fe/skeleton/apps/app/src/app/globals.css +10 -0
- package/templates/fe/skeleton/apps/app/src/features/layouts/AppLayout/index.tsx +18 -0
- package/templates/fe/skeleton/apps/app/src/features/pages/AppErrorPage/component.tsx +19 -0
- package/templates/fe/skeleton/apps/app/src/features/pages/AppErrorPage/index.tsx +11 -0
- package/templates/fe/skeleton/apps/app/src/features/pages/AppGlobalErrorPage/index.tsx +16 -0
- package/templates/fe/skeleton/apps/app/src/features/pages/AppHomePage/component.tsx +10 -0
- package/templates/fe/skeleton/apps/app/src/features/pages/AppHomePage/index.tsx +15 -0
- package/templates/fe/skeleton/apps/app/src/features/pages/AppLoadingPage/index.tsx +8 -0
- package/templates/fe/skeleton/apps/app/src/features/pages/AppNotFoundPage/index.tsx +9 -0
- package/templates/fe/skeleton/apps/app/src/modules/i18n/index.ts +4 -0
- package/templates/fe/skeleton/apps/app/src/modules/i18n/messages/vi.json +28 -0
- package/templates/fe/skeleton/apps/app/src/modules/i18n/request.ts +4 -0
- package/templates/fe/skeleton/apps/app/src/modules/routes/index.ts +4 -0
- package/templates/fe/skeleton/apps/app/src/proxy.ts +1 -0
- package/templates/fe/skeleton/apps/{__app__ → landing}/next.config.ts +4 -2
- package/templates/fe/skeleton/apps/landing/postcss.config.mjs +7 -0
- package/templates/fe/skeleton/apps/landing/src/app/[locale]/error.tsx +10 -0
- package/templates/fe/skeleton/apps/landing/src/app/[locale]/layout.tsx +22 -0
- package/templates/fe/skeleton/apps/landing/src/app/[locale]/loading.tsx +6 -0
- package/templates/fe/skeleton/apps/landing/src/app/[locale]/not-found.tsx +6 -0
- package/templates/fe/skeleton/apps/landing/src/app/[locale]/page.tsx +9 -0
- package/templates/fe/skeleton/apps/landing/src/app/global-error.tsx +10 -0
- package/templates/fe/skeleton/apps/landing/src/app/globals.css +10 -0
- package/templates/fe/skeleton/apps/landing/src/features/layouts/LandingLayout/index.tsx +24 -0
- package/templates/fe/skeleton/apps/landing/src/features/pages/LandingErrorPage/component.tsx +18 -0
- package/templates/fe/skeleton/apps/landing/src/features/pages/LandingErrorPage/index.tsx +11 -0
- package/templates/fe/skeleton/apps/landing/src/features/pages/LandingGlobalErrorPage/index.tsx +16 -0
- package/templates/fe/skeleton/apps/landing/src/features/pages/LandingLoadingPage/index.tsx +8 -0
- package/templates/fe/skeleton/apps/landing/src/features/pages/LandingNotFoundPage/index.tsx +9 -0
- package/templates/fe/skeleton/apps/landing/src/features/pages/LandingPage/component.tsx +24 -0
- package/templates/fe/skeleton/apps/landing/src/features/pages/LandingPage/index.tsx +16 -0
- package/templates/fe/skeleton/apps/landing/src/modules/config/index.ts +12 -0
- package/templates/fe/skeleton/apps/landing/src/modules/i18n/index.ts +7 -0
- package/templates/fe/skeleton/apps/landing/src/modules/i18n/messages/vi.json +31 -0
- package/templates/fe/skeleton/apps/landing/src/modules/i18n/request.ts +4 -0
- package/templates/fe/skeleton/apps/landing/src/modules/routes/index.ts +4 -0
- package/templates/fe/skeleton/apps/landing/src/proxy.ts +1 -0
- package/templates/fe/skeleton/packages/__project__-i18n/src/index.ts +49 -0
- package/templates/fe/skeleton/packages/__project__-i18n/src/proxy.ts +24 -0
- package/templates/fe/skeleton/packages/__project__-i18n/src/routing.ts +20 -0
- package/templates/fe/skeleton/packages/__project__-ui/src/branches/Providers/index.tsx +23 -0
- package/templates/fe/skeleton/packages/__project__-ui/src/composites/ErrorNotice/index.tsx +14 -0
- package/templates/fe/skeleton/packages/__project__-ui/src/composites/GlobalErrorNotice/index.tsx +25 -0
- package/templates/fe/skeleton/packages/__project__-ui/src/composites/LoadingNotice/index.tsx +9 -0
- package/templates/fe/skeleton/packages/__project__-ui/src/composites/LocaleShell/index.tsx +21 -0
- package/templates/fe/skeleton/packages/__project__-ui/src/composites/NotFoundNotice/index.tsx +19 -0
- package/templates/fe/skeleton/packages/__project__-ui/src/composites/SiteShell/classNames.ts +4 -0
- package/templates/fe/skeleton/packages/__project__-ui/src/composites/SiteShell/index.tsx +19 -0
- package/templates/fe/skeleton/packages/__project__-ui/src/index.ts +6 -0
- package/templates/fe/skeleton-lite/apps/web/next.config.ts +22 -0
- package/templates/fe/skeleton-lite/apps/web/src/app/[locale]/error.tsx +10 -0
- package/templates/fe/skeleton-lite/apps/web/src/app/[locale]/layout.tsx +37 -0
- package/templates/fe/skeleton-lite/apps/web/src/app/[locale]/loading.tsx +6 -0
- package/templates/fe/skeleton-lite/apps/web/src/app/[locale]/not-found.tsx +6 -0
- package/templates/fe/skeleton-lite/apps/web/src/app/[locale]/page.tsx +9 -0
- package/templates/fe/skeleton-lite/apps/web/src/app/[locale]/providers.tsx +26 -0
- package/templates/fe/skeleton-lite/apps/web/src/app/auth/callback/route.ts +24 -0
- package/templates/fe/skeleton-lite/apps/web/src/app/global-error.tsx +10 -0
- package/templates/fe/{skeleton/apps/__app__ → skeleton-lite/apps/web}/src/app/globals.css +1 -1
- package/templates/fe/skeleton-lite/apps/web/src/app/health/live/route.ts +5 -0
- package/templates/fe/skeleton-lite/apps/web/src/components/blocks/SignInForm/component.tsx +29 -0
- package/templates/fe/skeleton-lite/apps/web/src/components/blocks/SignInForm/index.tsx +41 -0
- package/templates/fe/skeleton-lite/apps/web/src/components/blocks/SignOutButton/component.tsx +17 -0
- package/templates/fe/skeleton-lite/apps/web/src/components/blocks/SignOutButton/index.tsx +38 -0
- package/templates/fe/skeleton-lite/apps/web/src/components/composites/ErrorNotice/index.tsx +13 -0
- package/templates/fe/skeleton-lite/apps/web/src/components/composites/GlobalErrorNotice/index.tsx +24 -0
- package/templates/fe/skeleton-lite/apps/web/src/components/composites/LoadingNotice/index.tsx +7 -0
- package/templates/fe/skeleton-lite/apps/web/src/components/composites/NotFoundNotice/index.tsx +18 -0
- package/templates/fe/skeleton-lite/apps/web/src/components/composites/SiteShell/classNames.ts +4 -0
- package/templates/fe/skeleton-lite/apps/web/src/components/composites/SiteShell/index.tsx +13 -0
- package/templates/fe/skeleton-lite/apps/web/src/features/layouts/AppLayout/index.tsx +31 -0
- package/templates/fe/skeleton-lite/apps/web/src/features/pages/AppErrorPage/component.tsx +12 -0
- package/templates/fe/skeleton-lite/apps/web/src/features/pages/AppErrorPage/index.tsx +10 -0
- package/templates/fe/skeleton-lite/apps/web/src/features/pages/AppGlobalErrorPage/index.tsx +15 -0
- package/templates/fe/skeleton-lite/apps/web/src/features/pages/AppHomePage/component.tsx +14 -0
- package/templates/fe/skeleton-lite/apps/web/src/features/pages/AppHomePage/index.tsx +30 -0
- package/templates/fe/skeleton-lite/apps/web/src/features/pages/AppLoadingPage/index.tsx +8 -0
- package/templates/fe/skeleton-lite/apps/web/src/features/pages/AppNotFoundPage/index.tsx +9 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/brand/brand.css +20 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/brand/index.ts +2 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/config/index.ts +20 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/db/auth/read-session.ts +25 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/db/auth/write-sign-in.ts +25 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/db/auth/write-sign-out.ts +17 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/db/browser.ts +14 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/db/index.ts +3 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/db/outcome.ts +59 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/db/principal.ts +29 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/db/server.ts +70 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/db/validation/validation.mapper.ts +50 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/i18n/index.ts +8 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/i18n/messages/vi.json +48 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/i18n/request.ts +16 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/i18n/routing.ts +14 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/routes/index.ts +7 -0
- package/templates/fe/skeleton-lite/apps/web/src/modules/routes/safe-next-path.ts +26 -0
- package/templates/fe/skeleton-lite/apps/web/src/proxy.ts +43 -0
- package/templates/fe/table/read.ts.tpl +16 -0
- package/templates/fe/table/write.ts.tpl +16 -0
- package/upgrade/check.mjs +137 -0
- package/upgrade/index.mjs +524 -0
- package/bin/hfs.mjs +0 -233
- package/runtime/scripts/api/fs/rmdir-link.mjs +0 -12
- package/runtime/scripts/lib/test-secrets.mjs +0 -116
- package/templates/fe/skeleton/apps/__app__/src/app/[locale]/layout.tsx +0 -20
- package/templates/fe/skeleton/apps/__app__/src/app/[locale]/page.tsx +0 -9
- package/templates/fe/skeleton/apps/__app__/src/components/composites/FailureScreen/index.tsx +0 -28
- package/templates/fe/skeleton/apps/__app__/src/features/layouts/LocaleShell/index.tsx +0 -35
- package/templates/fe/skeleton/apps/__app__/src/features/pages/ErrorPage/component.tsx +0 -19
- package/templates/fe/skeleton/apps/__app__/src/features/pages/ErrorPage/index.tsx +0 -11
- package/templates/fe/skeleton/apps/__app__/src/features/pages/GlobalErrorPage/component.tsx +0 -24
- package/templates/fe/skeleton/apps/__app__/src/features/pages/GlobalErrorPage/index.tsx +0 -14
- package/templates/fe/skeleton/apps/__app__/src/features/pages/HomePage/component.tsx +0 -21
- package/templates/fe/skeleton/apps/__app__/src/features/pages/HomePage/index.tsx +0 -15
- package/templates/fe/skeleton/apps/__app__/src/features/pages/LoadingPage/component.tsx +0 -23
- package/templates/fe/skeleton/apps/__app__/src/features/pages/LoadingPage/index.tsx +0 -8
- package/templates/fe/skeleton/apps/__app__/src/features/pages/NotFoundPage/component.tsx +0 -28
- package/templates/fe/skeleton/apps/__app__/src/features/pages/NotFoundPage/index.tsx +0 -8
- package/templates/fe/skeleton/apps/__app__/src/modules/i18n/config.ts +0 -8
- package/templates/fe/skeleton/apps/__app__/src/modules/i18n/index.ts +0 -2
- package/templates/fe/skeleton/apps/__app__/src/modules/i18n/messages/vi.json +0 -25
- package/templates/fe/skeleton/apps/__app__/src/modules/i18n/request.ts +0 -19
- package/templates/fe/skeleton/apps/__app__/src/modules/i18n/routing.ts +0 -9
- package/templates/fe/skeleton/apps/__app__/src/modules/routes/index.ts +0 -4
- package/templates/fe/skeleton/apps/__app__/src/proxy.ts +0 -10
- /package/templates/be/skeleton/src/features/{system-health → api/system-health}/application/check-liveness.contracts.ts +0 -0
- /package/templates/be/skeleton/src/features/{system-health → api/system-health}/application/check-liveness.handler.ts +0 -0
- /package/templates/be/skeleton/src/features/{system-health → api/system-health}/application/check-liveness.query.ts +0 -0
- /package/templates/be/skeleton/src/features/{system-health → api/system-health}/index.ts +0 -0
- /package/templates/be/skeleton/src/features/{system-health → api/system-health}/system-health.module.ts +0 -0
- /package/templates/be/skeleton/src/features/{system-health → api/system-health}/transport/http/live.controller.ts +0 -0
- /package/templates/be/skeleton/src/features/{system-health → api/system-health}/transport/http/system-health-http.module.ts +0 -0
- /package/templates/fe/skeleton/apps/{__app__ → app}/src/app/health/live/route.ts +0 -0
- /package/templates/fe/skeleton/apps/{__app__ → app}/src/modules/config/index.ts +0 -0
- /package/templates/fe/{skeleton/apps/__app__ → skeleton-lite/apps/web}/postcss.config.mjs +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// The child process of `
|
|
1
|
+
// The child process of `starci app emit` for the operations of one app.
|
|
2
2
|
// Prints the OpenAPI 3.1 document of the app's typed operation table on stdout; exit 3 when the app has no `apps/<app>/src/operations.ts`.
|
|
3
3
|
// Loads the repository's own typescript (resolved from the repository, never from hfs). Nothing of the repository is executed.
|
|
4
4
|
import { createRequire } from 'node:module';
|
package/emit/operations.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The versioned operations of an api app, read from its typed operation table and printed as OpenAPI 3.1.
|
|
3
3
|
*
|
|
4
|
-
* The table is the canon's one declaration of an app's operation surface (knowledge/patterns/be/
|
|
4
|
+
* The table is the canon's one declaration of an app's operation surface (knowledge/patterns/be/api.yaml, BE-OPERATIONS-1):
|
|
5
5
|
* `apps/<app>/src/operations.ts` exports `OPERATIONS`, made by `defineOperations({ "<id>@<version>": operation<Input, Output,
|
|
6
6
|
* RefusalCode>("query" | "mutation") })`. The types come from the TypeScript checker; nothing is executed. An input, an output or a
|
|
7
7
|
* refusal set the checker cannot express (`any`, `unknown`, `Record<string, unknown>`, an unbound generic, `string` as a refusal code)
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
import { createSchemaBuilder, stable } from './type-schema.mjs';
|
|
15
15
|
|
|
16
16
|
/** The export of `apps/<app>/src/operations.ts` that holds the table. */
|
|
17
|
-
|
|
17
|
+
const OPERATIONS_EXPORT = 'OPERATIONS';
|
|
18
18
|
|
|
19
19
|
/** The repository-relative path of an app's operation table. */
|
|
20
20
|
export const operationsPath = (app) => `apps/${app}/src/operations.ts`;
|
package/emit/schema-worker.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// The child process of `
|
|
1
|
+
// The child process of `starci app emit` for one app.
|
|
2
2
|
// Prints the schema the app serves on stdout; exit 3 when the app's module graph has no GraphQL server.
|
|
3
3
|
// Loads the repository's own typescript, @nestjs/* and graphql (resolved from the repository, never from hfs).
|
|
4
4
|
//
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// bound-sys.cjs - the typed ESLint run never reads types from above the app root.
|
|
2
|
+
//
|
|
3
|
+
// `starci app lint` starts ESLint with `node --require <this file>` and STARCI_LINT_BOUND set to the app root. typescript-eslint's
|
|
4
|
+
// projectService builds its server host from `tsserver.sys` (typescript/lib/tsserverlibrary) and exposes no host through
|
|
5
|
+
// parserOptions, so without a bound a typed rule reads types from an enclosing repository's node_modules and judges the app
|
|
6
|
+
// greener than its own install allows. Here `sys` of the app's own TypeScript is patched, in place and before ESLint loads
|
|
7
|
+
// the parser, to answer only for paths inside the app root and TypeScript's own lib directory (the same bound the gate's
|
|
8
|
+
// tsc programs use, scripts/gates/gate.mjs boundedSys). realpath is the identity, so an install junctioned inside the app
|
|
9
|
+
// stays inside it. Nothing is patched when STARCI_LINT_BOUND is unset or TypeScript is not installed (nothing typed runs).
|
|
10
|
+
'use strict'
|
|
11
|
+
const path = require('node:path')
|
|
12
|
+
const { createRequire } = require('node:module')
|
|
13
|
+
|
|
14
|
+
const key = (p) => path.resolve(String(p)).replace(/\\/g, '/').replace(/\/+$/, '').toLowerCase()
|
|
15
|
+
|
|
16
|
+
/** Patch `sys` (the TypeScript system object) so it answers only for paths inside `bound` and `libDir`. Returns `sys`. */
|
|
17
|
+
function bindSys(sys, bound, libDir) {
|
|
18
|
+
const roots = [key(bound), key(libDir)]
|
|
19
|
+
const inside = (p) => {
|
|
20
|
+
const k = key(p)
|
|
21
|
+
return roots.some((root) => k === root || k.startsWith(`${root}/`))
|
|
22
|
+
}
|
|
23
|
+
const base = { ...sys }
|
|
24
|
+
return Object.assign(sys, {
|
|
25
|
+
fileExists: (p) => inside(p) && base.fileExists(p),
|
|
26
|
+
directoryExists: (p) => inside(p) && base.directoryExists(p),
|
|
27
|
+
readFile: (p, encoding) => (inside(p) ? base.readFile(p, encoding) : undefined),
|
|
28
|
+
getDirectories: (p) => (inside(p) ? base.getDirectories(p) : []),
|
|
29
|
+
readDirectory: (dir, ext, exclude, include, depth) => (inside(dir) ? base.readDirectory(dir, ext, exclude, include, depth).filter(inside) : []),
|
|
30
|
+
realpath: (p) => p,
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Bind the `sys` of every TypeScript entry the typed lint loads, resolved from `from` (a side folder of the app). */
|
|
35
|
+
function bindTypeScript(bound, from) {
|
|
36
|
+
const require_ = createRequire(path.join(from, 'package.json'))
|
|
37
|
+
const bound_ = [];
|
|
38
|
+
for (const entry of ['typescript/lib/tsserverlibrary', 'typescript']) {
|
|
39
|
+
let ts
|
|
40
|
+
try { ts = require_(entry) } catch { continue }
|
|
41
|
+
if (!ts?.sys || bound_.includes(ts.sys)) continue
|
|
42
|
+
bindSys(ts.sys, bound, path.dirname(ts.getDefaultLibFilePath({})))
|
|
43
|
+
bound_.push(ts.sys)
|
|
44
|
+
}
|
|
45
|
+
return bound_.length
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (process.env.STARCI_LINT_BOUND) bindTypeScript(process.env.STARCI_LINT_BOUND, process.cwd())
|
|
49
|
+
|
|
50
|
+
module.exports = { bindSys, bindTypeScript }
|
package/lint/run.mjs
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
|
-
//
|
|
1
|
+
// starci app lint - the ONE lint entry and the ONE report of a StarCi app.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
3
|
+
// starci app lint [--cwd <dir>] [--changed <file>...] [--workspace <dir>] [--fix] [--format text|json] [--sonar <file>]
|
|
4
4
|
//
|
|
5
5
|
// It runs at the app root (the folder of hfs.json), over the app (or over the app-relative files named by --changed):
|
|
6
6
|
// 1. ESLint once per side, from the side folder, through the app's own install and that side's eslint.config.mjs (be/ the be canon,
|
|
7
7
|
// fe/ the fe canon: the per-file rules and the project-graph rules of the architecture machine, findings on the line of the
|
|
8
8
|
// offending TypeScript file); each side lints only its own files, so the be rules never see fe/ and the fe rules never see be/;
|
|
9
|
-
// 2. `
|
|
9
|
+
// 2. `starci app check` for what has no TypeScript file to sit on (the tree, managed files, pins, CI, contracts, docs, .starciwork), root and sides;
|
|
10
10
|
// 3. stylelint over the fe side's stylesheets (sync STYLE_GLOB), from fe/ with its stylelint.config.mjs.
|
|
11
11
|
// Their findings become one list of one shape (`starci/lint@1`), every path app-relative. `--format json` prints that report on stdout;
|
|
12
12
|
// `--sonar <file>` writes the same findings as THE Sonar Generic Issue Import file (engine ids starci-hfs, eslint, stylelint in one
|
|
13
13
|
// document); the exit code is the land-gate input: 0 no finding, 1 at least one, 2 a tool could not run (never a pass).
|
|
14
14
|
// --changed restricts ESLint and stylelint to the listed files and keeps of the app findings only those on a listed file or on no file.
|
|
15
|
+
// --workspace scopes the same lint to one npm workspace of the fe side (fe/apps/<app> or fe/packages/<pkg>, app-relative): ESLint and
|
|
16
|
+
// stylelint over that folder only, and of the app findings only those inside it. It is the `lint` script of every fe workspace (the
|
|
17
|
+
// turbo `lint` task); the root `npm run lint` stays the whole app. There is no second linter: a workspace lint is this lint, scoped.
|
|
15
18
|
import fs from 'node:fs';
|
|
16
19
|
import path from 'node:path';
|
|
17
20
|
import { createRequire } from 'node:module';
|
|
18
21
|
import { spawnSync } from 'node:child_process';
|
|
22
|
+
import { fileURLToPath } from 'node:url';
|
|
19
23
|
import { linterReport, mergeReports, sonarReport, sourceRootsOf } from '../report/sonar.mjs';
|
|
20
24
|
import { SIDES, appRelativeMessages, loadSlotManifest, readRepoDeclaration } from '../runtime/scripts/hfs/slots.mjs';
|
|
21
25
|
import { STYLE_GLOB } from '../sync/index.mjs';
|
|
@@ -25,27 +29,43 @@ export const LINT_SCHEMA = 'starci/lint@1';
|
|
|
25
29
|
const STYLE_SIDE = 'fe';
|
|
26
30
|
const CODE_PREFIX = /^\[([A-Z][A-Z0-9_]+)\] /;
|
|
27
31
|
const posix = (file) => String(file).replace(/\\/g, '/').replace(/^\.\//, '');
|
|
32
|
+
/** An npm workspace of the fe side, app-relative: one folder below fe/apps or fe/packages (the root package.json workspaces). */
|
|
33
|
+
const WORKSPACE = /^fe\/(?:apps|packages)\/[a-z0-9][a-z0-9-]*$/;
|
|
28
34
|
|
|
29
|
-
/** The
|
|
35
|
+
/** The app-relative workspace of `opts.workspace` (already app-relative), or a refusal when it is not one folder of fe/apps or fe/packages. */
|
|
36
|
+
export function workspaceOf(workspace) {
|
|
37
|
+
const rel = posix(workspace).replace(/\/+$/, '');
|
|
38
|
+
if (!WORKSPACE.test(rel)) throw new Error(`--workspace ${workspace} is not an fe workspace (fe/apps/<app> or fe/packages/<pkg>, from the app root)`);
|
|
39
|
+
return rel;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** The flags of `starci app lint`; `--changed` takes every argument up to the next flag, and a repeated `--changed` adds to the list (the
|
|
43
|
+
* catalog's list flag, `--changed a --changed b`, as the CLI dispatcher passes it through). */
|
|
30
44
|
export function parseLintArgs(argv) {
|
|
31
|
-
const opts = { changed: null, fix: false, format: 'text',
|
|
45
|
+
const opts = { changed: null, fix: false, format: 'text', sonar: undefined, workspace: undefined };
|
|
32
46
|
for (let i = 0; i < argv.length; i += 1) {
|
|
33
47
|
const arg = argv[i];
|
|
34
48
|
if (arg === '--changed') {
|
|
35
|
-
opts.changed
|
|
49
|
+
opts.changed ??= [];
|
|
36
50
|
while (i + 1 < argv.length && !argv[i + 1].startsWith('--')) opts.changed.push(posix(argv[++i]));
|
|
37
51
|
} else if (arg === '--fix') opts.fix = true;
|
|
38
|
-
else if (
|
|
52
|
+
else if (arg === '--json') opts.format = 'json';
|
|
53
|
+
else if (['--format', '--sonar', '--workspace'].includes(arg)) {
|
|
39
54
|
if (argv[i + 1] === undefined) throw new Error(`${arg} needs a value`);
|
|
40
55
|
opts[arg.slice(2)] = argv[++i];
|
|
41
56
|
} else throw new Error(`unknown argument ${arg}`);
|
|
42
57
|
}
|
|
43
58
|
if (!['text', 'json'].includes(opts.format)) throw new Error('--format is text or json');
|
|
59
|
+
if (opts.workspace !== undefined && opts.changed !== null) throw new Error('--workspace and --changed do not combine: a workspace lint judges the whole workspace');
|
|
44
60
|
return opts;
|
|
45
61
|
}
|
|
46
62
|
|
|
63
|
+
/** The typed ESLint run reads nothing above the app root: its TypeScript `sys` is bound by this preload (3.3, bound-sys.cjs). */
|
|
64
|
+
export const BOUND_ENV = 'STARCI_LINT_BOUND';
|
|
65
|
+
export const linterBoundArgs = () => ['--require', fileURLToPath(new URL('./bound-sys.cjs', import.meta.url))];
|
|
66
|
+
|
|
47
67
|
/** A linter's json results through the app's own install, run from `cwd` (a side folder): `{ results }` or `{ error }`. */
|
|
48
|
-
function runLinter({ cwd, pkg, bin, args }) {
|
|
68
|
+
function runLinter({ cwd, pkg, bin, args, bound = null }) {
|
|
49
69
|
let entry;
|
|
50
70
|
try {
|
|
51
71
|
const manifest = createRequire(path.join(cwd, 'package.json')).resolve(`${pkg}/package.json`);
|
|
@@ -54,7 +74,7 @@ function runLinter({ cwd, pkg, bin, args }) {
|
|
|
54
74
|
} catch {
|
|
55
75
|
return { error: `${pkg} is not installed for ${cwd}` };
|
|
56
76
|
}
|
|
57
|
-
const run = spawnSync(process.execPath, [entry, ...args], { cwd, encoding: 'utf8', maxBuffer: 512 * 1024 * 1024 });
|
|
77
|
+
const run = spawnSync(process.execPath, [...(bound ? linterBoundArgs() : []), entry, ...args], { cwd, encoding: 'utf8', maxBuffer: 512 * 1024 * 1024, ...(bound ? { env: { ...process.env, [BOUND_ENV]: bound } } : {}) });
|
|
58
78
|
// The linters exit 1 when they found something; no json at all means they could not run. ESLint prints its report on stdout,
|
|
59
79
|
// stylelint (16 and later) its formatter output on stderr.
|
|
60
80
|
let results;
|
|
@@ -79,27 +99,38 @@ const byLocation = (a, b) => `${a.path ?? ''}:${String(a.line ?? 0).padStart(7,
|
|
|
79
99
|
const onSide = (changed, side) => changed.filter((file) => file.startsWith(`${side}/`)).map((file) => file.slice(side.length + 1));
|
|
80
100
|
|
|
81
101
|
/**
|
|
82
|
-
* Run the whole lint of the app at `repoRoot`. `hfsCheck(repoRoot)` returns the `
|
|
102
|
+
* Run the whole lint of the app at `repoRoot`. `hfsCheck(repoRoot)` returns the `starci app check` result (`{ findings, tracked }`); the CLI
|
|
83
103
|
* injects it. Returns `{ report, sonar, exit }`; `sonar` is the merged Generic Issue Import document.
|
|
84
104
|
*/
|
|
85
105
|
export async function lintRepository({ repoRoot, opts, hfsCheck, trackedFiles = () => [] }) {
|
|
86
106
|
const changed = opts.changed === null ? null : new Set(opts.changed);
|
|
87
|
-
const existing = changed ? [...changed].filter((file) => fs.existsSync(path.join(repoRoot, file))) : [];
|
|
88
107
|
const errors = [];
|
|
108
|
+
let workspace = null;
|
|
109
|
+
if (opts.workspace !== undefined) {
|
|
110
|
+
try { workspace = workspaceOf(opts.workspace); } catch (error) { errors.push(String(error?.message ?? error)); }
|
|
111
|
+
}
|
|
112
|
+
/** Whether an app-relative path lies inside the scoped workspace. */
|
|
113
|
+
const inWorkspace = (file) => posix(file).startsWith(`${workspace}/`);
|
|
114
|
+
const existing = changed ? [...changed].filter((file) => fs.existsSync(path.join(repoRoot, file))) : [];
|
|
89
115
|
const findings = [];
|
|
90
116
|
const raw = { eslint: [], stylelint: [] };
|
|
91
117
|
const engines = {};
|
|
92
118
|
|
|
93
119
|
let app = null;
|
|
94
|
-
try { app = readRepoDeclaration(loadSlotManifest(), repoRoot); } catch (error) { errors.push(`
|
|
95
|
-
if (app && !app.sides) { errors.push(`${repoRoot} is the ${app.side} side of an app;
|
|
120
|
+
try { app = readRepoDeclaration(loadSlotManifest(), repoRoot); } catch (error) { errors.push(`starci app lint runs at the app root: ${String(error?.message ?? error)}`); }
|
|
121
|
+
if (app && !app.sides) { errors.push(`${repoRoot} is the ${app.side} side of an app; starci app lint runs at the app root, the folder of hfs.json`); app = null; }
|
|
122
|
+
if (opts.workspace !== undefined && workspace === null) app = null;
|
|
123
|
+
if (workspace !== null && !fs.existsSync(path.join(repoRoot, workspace, 'package.json'))) { errors.push(`--workspace ${workspace} holds no package.json; it is not a workspace of this app`); app = null; }
|
|
124
|
+
/** The workspace folder relative to the fe side folder (apps/<app> or packages/<pkg>). */
|
|
125
|
+
const onFe = workspace === null ? null : workspace.slice(STYLE_SIDE.length + 1);
|
|
96
126
|
|
|
97
127
|
// 1. ESLint, once per side, from the side folder with that side's config.
|
|
98
128
|
engines.eslint = { sides: {} };
|
|
99
129
|
for (const side of app ? SIDES : []) {
|
|
130
|
+
if (workspace !== null && side !== STYLE_SIDE) { engines.eslint.sides[side] = { files: 0, skipped: `outside --workspace ${workspace}` }; continue; }
|
|
100
131
|
const sources = onSide(existing, side).filter((file) => /\.(?:[cm]?[jt]sx?)$/.test(file));
|
|
101
132
|
if (changed !== null && !sources.length) { engines.eslint.sides[side] = { files: 0, skipped: 'no changed source file' }; continue; }
|
|
102
|
-
const linted = runLinter({ cwd: path.join(repoRoot, side), pkg: 'eslint', bin: 'eslint', args: ['--format', 'json', ...(opts.fix ? ['--fix'] : []), ...(changed ? sources : ['.'])] });
|
|
133
|
+
const linted = runLinter({ cwd: path.join(repoRoot, side), pkg: 'eslint', bin: 'eslint', args: ['--format', 'json', ...(opts.fix ? ['--fix'] : []), ...(changed ? sources : [onFe ?? '.'])], bound: repoRoot });
|
|
103
134
|
if (linted.error) errors.push(linted.error);
|
|
104
135
|
else {
|
|
105
136
|
// The side canon names side-relative paths in its messages; the report names every path from the app root.
|
|
@@ -115,7 +146,7 @@ export async function lintRepository({ repoRoot, opts, hfsCheck, trackedFiles =
|
|
|
115
146
|
if (app) {
|
|
116
147
|
const styles = onSide(existing, STYLE_SIDE).filter((file) => file.endsWith('.css'));
|
|
117
148
|
if (changed === null || styles.length) {
|
|
118
|
-
const linted = runLinter({ cwd: path.join(repoRoot, STYLE_SIDE), pkg: 'stylelint', bin: 'stylelint', args: [...(changed ? styles : [STYLE_GLOB]), '--formatter', 'json', ...(opts.fix ? ['--fix'] : [])] });
|
|
149
|
+
const linted = runLinter({ cwd: path.join(repoRoot, STYLE_SIDE), pkg: 'stylelint', bin: 'stylelint', args: [...(changed ? styles : [onFe ? `${onFe}/src/**/*.css` : STYLE_GLOB]), '--formatter', 'json', ...(opts.fix ? ['--fix'] : [])] });
|
|
119
150
|
if (linted.error) errors.push(linted.error);
|
|
120
151
|
else {
|
|
121
152
|
const appRelative = appRelativeMessages(STYLE_SIDE, path.join(repoRoot, STYLE_SIDE));
|
|
@@ -130,10 +161,13 @@ export async function lintRepository({ repoRoot, opts, hfsCheck, trackedFiles =
|
|
|
130
161
|
// 2. The app check: root and sides.
|
|
131
162
|
let checked = { findings: [] };
|
|
132
163
|
if (app) {
|
|
133
|
-
try { checked = await hfsCheck(repoRoot); } catch (error) { errors.push(`
|
|
164
|
+
try { checked = await hfsCheck(repoRoot); } catch (error) { errors.push(`starci app check could not run: ${String(error?.message ?? error)}`); }
|
|
134
165
|
}
|
|
135
166
|
const repoErrors = checked.findings.filter((finding) => finding.level === 'error');
|
|
136
|
-
|
|
167
|
+
// A workspace lint keeps only the app findings inside the workspace; the rest belong to the root lint of the whole app.
|
|
168
|
+
const kept = workspace !== null
|
|
169
|
+
? repoErrors.filter((finding) => finding.path && inWorkspace(finding.path))
|
|
170
|
+
: changed === null ? repoErrors : repoErrors.filter((finding) => !finding.path || changed.has(posix(finding.path)));
|
|
137
171
|
for (const finding of kept) {
|
|
138
172
|
findings.push({ engine: 'hfs', rule: finding.code, code: finding.code, severity: 'error', path: finding.path ? posix(finding.path) : null, line: finding.line ?? null, column: finding.column ?? null, message: finding.message, titleVi: finding.titleVi, nextStepVi: finding.nextStepVi });
|
|
139
173
|
}
|
|
@@ -149,7 +183,7 @@ export async function lintRepository({ repoRoot, opts, hfsCheck, trackedFiles =
|
|
|
149
183
|
linterReport('eslint', raw.eslint, { root: repoRoot, sourceRoots, tracked }),
|
|
150
184
|
linterReport('stylelint', raw.stylelint, { root: repoRoot, sourceRoots, tracked }),
|
|
151
185
|
]);
|
|
152
|
-
const report = { schema: LINT_SCHEMA, ok: findings.length === 0 && errors.length === 0, repoRoot, changed: changed ? [...changed].sort() : null, counts: { error: findings.length }, engines, errors, findings };
|
|
186
|
+
const report = { schema: LINT_SCHEMA, ok: findings.length === 0 && errors.length === 0, repoRoot, changed: changed ? [...changed].sort() : null, workspace, counts: { error: findings.length }, engines, errors, findings };
|
|
153
187
|
return { report, sonar, exit: errors.length ? 2 : findings.length ? 1 : 0 };
|
|
154
188
|
}
|
|
155
189
|
|
|
@@ -157,5 +191,5 @@ export function printLintText(report, out) {
|
|
|
157
191
|
for (const f of report.findings) out(`${f.path ?? '-'}${f.line ? `:${f.line}${f.column ? `:${f.column}` : ''}` : ''} ${f.engine}/${f.rule} ${f.message}\n`);
|
|
158
192
|
for (const e of report.errors) out(`ERROR ${e}\n`);
|
|
159
193
|
const per = Object.keys(report.engines).map((engine) => `${engine} ${report.findings.filter((f) => f.engine === engine).length}`).join(', ');
|
|
160
|
-
out(`\
|
|
194
|
+
out(`\nstarci app lint: ${report.counts.error} finding${report.counts.error === 1 ? '' : 's'} (${per})${report.errors.length ? `, ${report.errors.length} tool error${report.errors.length === 1 ? '' : 's'}` : ''}\n`);
|
|
161
195
|
}
|
package/package.json
CHANGED
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@starci/hfs",
|
|
3
|
-
"version": "4.0.
|
|
4
|
-
"description": "The
|
|
3
|
+
"version": "4.0.9",
|
|
4
|
+
"description": "The StarCi app command implementation for scaffolding, linting, checking and synchronizing one product repository.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|
|
7
7
|
"private": false,
|
|
8
|
-
"bin": {
|
|
9
|
-
"hfs": "./bin/hfs.mjs"
|
|
10
|
-
},
|
|
11
8
|
"exports": {
|
|
9
|
+
".": "./src/main.mjs",
|
|
12
10
|
"./package.json": "./package.json",
|
|
13
11
|
"./runtime/*": "./runtime/*"
|
|
14
12
|
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"libpg-query": "18.1.5",
|
|
15
|
+
"smol-toml": "1.9.0"
|
|
16
|
+
},
|
|
15
17
|
"files": [
|
|
16
|
-
"
|
|
18
|
+
"src/main.mjs",
|
|
17
19
|
"emit/**",
|
|
18
20
|
"lint/**",
|
|
19
21
|
"scaffold/**",
|
|
20
22
|
"report/**",
|
|
21
23
|
"runtime/**",
|
|
22
24
|
"sync/**",
|
|
25
|
+
"upgrade/**",
|
|
23
26
|
"templates/**",
|
|
24
27
|
"README.md",
|
|
25
28
|
"CHANGELOG.md"
|
|
@@ -31,8 +34,10 @@
|
|
|
31
34
|
"access": "public"
|
|
32
35
|
},
|
|
33
36
|
"scripts": {
|
|
34
|
-
"sync": "node scripts/sync-runtime.mjs",
|
|
35
|
-
"sync:check": "node scripts/sync-runtime.mjs --check",
|
|
36
|
-
"
|
|
37
|
+
"sync": "node ../../scripts/hfs/sync-runtime.mjs",
|
|
38
|
+
"sync:check": "node ../../scripts/hfs/sync-runtime.mjs --check",
|
|
39
|
+
"prepack": "node prep-runtime.mjs",
|
|
40
|
+
"pretest": "node prep-runtime.mjs",
|
|
41
|
+
"test": "node --test \"src/*.spec.mjs\""
|
|
37
42
|
}
|
|
38
43
|
}
|
package/report/sonar.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
// Sonar documents of the ONE lint entry `
|
|
1
|
+
// Sonar documents of the ONE lint entry `starci app lint`: the building blocks that turn the
|
|
2
2
|
// findings of the StarCi canon into a Sonar Generic Issue Import document (SonarQube 10.3+ format: `{ rules, issues }`).
|
|
3
|
-
// sonarReport(findings) the repository findings of `
|
|
3
|
+
// sonarReport(findings) the repository findings of `starci app check`, engineId `starci-hfs`, rule id = the finding code
|
|
4
4
|
// linterReport(kind, results) a linter's own json output (`eslint -f json`, `stylelint --formatter json`), engineId `eslint` / `stylelint`,
|
|
5
5
|
// rule id = the linter's rule. Sonar's own ESLint import (sonar.eslint.reportPaths) is not used: it drops an
|
|
6
6
|
// issue on a file outside sonar.sources, and a stylelint result has no native import at all.
|
|
7
|
-
// mergeReports(reports) the documents of one `
|
|
7
|
+
// mergeReports(reports) the documents of one `starci app lint` run as ONE file
|
|
8
8
|
// One placement rule for every engine: Sonar imports an issue only on a file it indexes (a tracked source or stylesheet under
|
|
9
9
|
// sonar.sources). A finding on any other path (hfs.json, a workflow, a package under an unindexed root, e2e/, a directory) is filed
|
|
10
10
|
// on the first source file of sonar.sources and its message names the real path, so no finding is dropped.
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
import fs from 'node:fs';
|
|
14
14
|
import path from 'node:path';
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
const HFS_ENGINE = 'starci-hfs';
|
|
17
|
+
const ESLINT_ENGINE = 'eslint';
|
|
18
|
+
const STYLELINT_ENGINE = 'stylelint';
|
|
19
19
|
/** Every imported issue is a maintainability defect of the highest impact: the gate holds the count at zero. */
|
|
20
20
|
const IMPACT = Object.freeze([Object.freeze({ softwareQuality: 'MAINTAINABILITY', severity: 'HIGH' })]);
|
|
21
21
|
const CLEAN_CODE_ATTRIBUTE = 'CONVENTIONAL';
|
|
@@ -39,7 +39,7 @@ function document(rules, issues) {
|
|
|
39
39
|
return { rules: [...rules.values()].filter((rule) => used.has(rule.id)).sort((a, b) => cmp(a.id, b.id)), issues: sorted };
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
/** One document of several (the starci-hfs, eslint and stylelint documents of one
|
|
42
|
+
/** One document of several (the starci-hfs, eslint and stylelint documents of one app lint): rules by id, issues in the one sort order. */
|
|
43
43
|
export function mergeReports(reports) {
|
|
44
44
|
const rules = new Map(reports.flatMap((report) => report.rules).map((rule) => [rule.id, rule]));
|
|
45
45
|
return document(rules, reports.flatMap((report) => report.issues));
|
|
@@ -86,7 +86,7 @@ export function sonarReport(findings, { sourceRoots = [], tracked = [] } = {}) {
|
|
|
86
86
|
for (const finding of findings) {
|
|
87
87
|
if (finding.level !== 'error') continue;
|
|
88
88
|
if (!rules.has(finding.code)) {
|
|
89
|
-
rules.set(finding.code, ruleOf(finding.code, HFS_ENGINE, finding.title ?? finding.code, `${finding.title ?? finding.code}. ${finding.titleVi}: ${finding.whyVi}
|
|
89
|
+
rules.set(finding.code, ruleOf(finding.code, HFS_ENGINE, finding.title ?? finding.code, `${finding.title ?? finding.code}. ${finding.titleVi}: ${finding.whyVi} C\u00e1ch s\u1eeda: ${finding.nextStepVi}`));
|
|
90
90
|
}
|
|
91
91
|
const primaryLocation = place(finding.path ? posix(finding.path) : null, finding.message, finding.line);
|
|
92
92
|
if (primaryLocation === null) continue;
|