@tailor-platform/sdk 2.33.0 → 2.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +84 -0
- package/dist/ai/index.d.mts +1 -3
- package/dist/{application-Bet1K5C4.mjs → application-Bj2MtL-d.mjs} +1 -1
- package/dist/application-DIsQSnj3.mjs +207 -0
- package/dist/application-DIsQSnj3.mjs.map +1 -0
- package/dist/cli/cache/bundle-cache.d.mts +1 -0
- package/dist/cli/commands/api/api-call.d.mts +1 -3
- package/dist/cli/commands/deploy/aigateway.d.mts +1 -0
- package/dist/cli/commands/deploy/app-id-lock.d.mts +1 -3
- package/dist/cli/commands/deploy/application.d.mts +1 -0
- package/dist/cli/commands/deploy/auth.d.mts +1 -0
- package/dist/cli/commands/deploy/config-id-injector.d.mts +1 -3
- package/dist/cli/commands/deploy/confirm.d.mts +1 -0
- package/dist/cli/commands/deploy/deploy.d.mts +4 -3
- package/dist/cli/commands/deploy/executor.d.mts +1 -0
- package/dist/cli/commands/deploy/function-registry-types.d.mts +1 -3
- package/dist/cli/commands/deploy/function-registry.d.mts +1 -0
- package/dist/cli/commands/deploy/idp.d.mts +1 -0
- package/dist/cli/commands/deploy/owned-resource.d.mts +3 -0
- package/dist/cli/commands/deploy/resolver.d.mts +1 -0
- package/dist/cli/commands/deploy/secret-manager.d.mts +1 -0
- package/dist/cli/commands/deploy/staticwebsite.d.mts +1 -0
- package/dist/cli/commands/deploy/tailordb/migration-validation.d.mts +1 -2
- package/dist/cli/commands/deploy/tailordb/plan.d.mts +1 -0
- package/dist/cli/commands/deploy/workflow-execution-policy.d.mts +2 -1
- package/dist/cli/commands/deploy/workflow.d.mts +1 -0
- package/dist/cli/commands/executor/get.d.mts +0 -2
- package/dist/cli/commands/executor/jobs.d.mts +0 -2
- package/dist/cli/commands/executor/list.d.mts +1 -3
- package/dist/cli/commands/executor/transform.d.mts +1 -3
- package/dist/cli/commands/executor/trigger.d.mts +0 -2
- package/dist/cli/commands/executor/webhook.d.mts +1 -3
- package/dist/cli/commands/function/get.d.mts +0 -2
- package/dist/cli/commands/function/list.d.mts +0 -2
- package/dist/cli/commands/function/transform.d.mts +1 -3
- package/dist/cli/commands/generate/options.d.mts +1 -3
- package/dist/cli/commands/generate/seed/bundler.d.mts +1 -3
- package/dist/cli/commands/generate/service.d.mts +1 -3
- package/dist/cli/commands/machineuser/list.d.mts +1 -3
- package/dist/cli/commands/machineuser/token.d.mts +1 -3
- package/dist/cli/commands/oauth2client/get.d.mts +1 -3
- package/dist/cli/commands/oauth2client/list.d.mts +1 -3
- package/dist/cli/commands/oauth2client/transform.d.mts +1 -3
- package/dist/cli/commands/organization/folder/create.d.mts +0 -2
- package/dist/cli/commands/organization/folder/delete.d.mts +0 -2
- package/dist/cli/commands/organization/folder/get.d.mts +0 -2
- package/dist/cli/commands/organization/folder/list.d.mts +0 -2
- package/dist/cli/commands/organization/folder/update.d.mts +0 -2
- package/dist/cli/commands/organization/get.d.mts +0 -2
- package/dist/cli/commands/organization/list.d.mts +1 -3
- package/dist/cli/commands/organization/transform.d.mts +1 -3
- package/dist/cli/commands/organization/tree.d.mts +0 -2
- package/dist/cli/commands/organization/update.d.mts +0 -2
- package/dist/cli/commands/remove.d.mts +1 -3
- package/dist/cli/commands/show.d.mts +0 -2
- package/dist/cli/commands/staticwebsite/deploy.d.mts +1 -3
- package/dist/cli/commands/tailordb/migrate/bundler.d.mts +1 -3
- package/dist/cli/commands/tailordb/migrate/config.d.mts +1 -3
- package/dist/cli/commands/tailordb/migrate/diff-calculator.d.mts +0 -2
- package/dist/cli/commands/tailordb/migrate/generate.d.mts +2 -4
- package/dist/cli/commands/tailordb/migrate/rename-detection.d.mts +1 -3
- package/dist/cli/commands/tailordb/migrate/snapshot-comparison.d.mts +1 -3
- package/dist/cli/commands/tailordb/migrate/snapshot-files.d.mts +1 -3
- package/dist/cli/commands/tailordb/migrate/snapshot-local.d.mts +1 -3
- package/dist/cli/commands/tailordb/migrate/snapshot-migrations.d.mts +1 -3
- package/dist/cli/commands/tailordb/migrate/snapshot-types.d.mts +0 -2
- package/dist/cli/commands/tailordb/migrate/types.d.mts +1 -3
- package/dist/cli/commands/tailordb/truncate.d.mts +1 -3
- package/dist/cli/commands/workflow/executions.d.mts +0 -2
- package/dist/cli/commands/workflow/get.d.mts +0 -2
- package/dist/cli/commands/workflow/list.d.mts +1 -3
- package/dist/cli/commands/workflow/resume.d.mts +1 -3
- package/dist/cli/commands/workflow/start.d.mts +0 -2
- package/dist/cli/commands/workflow/status.d.mts +1 -3
- package/dist/cli/commands/workflow/transform.d.mts +1 -3
- package/dist/cli/commands/workflow/wait.d.mts +1 -3
- package/dist/cli/commands/workflow/waiter.d.mts +1 -3
- package/dist/cli/commands/workspace/app/health.d.mts +0 -2
- package/dist/cli/commands/workspace/app/list.d.mts +0 -2
- package/dist/cli/commands/workspace/app/transform.d.mts +1 -3
- package/dist/cli/commands/workspace/create.d.mts +0 -2
- package/dist/cli/commands/workspace/delete.d.mts +0 -2
- package/dist/cli/commands/workspace/expiry.d.mts +1 -3
- package/dist/cli/commands/workspace/get.d.mts +0 -2
- package/dist/cli/commands/workspace/list.d.mts +1 -3
- package/dist/cli/commands/workspace/restore.d.mts +0 -2
- package/dist/cli/commands/workspace/transform.d.mts +1 -3
- package/dist/cli/commands/workspace/user/invite.d.mts +0 -2
- package/dist/cli/commands/workspace/user/list.d.mts +0 -2
- package/dist/cli/commands/workspace/user/remove.d.mts +0 -2
- package/dist/cli/commands/workspace/user/transform.d.mts +1 -3
- package/dist/cli/commands/workspace/user/update.d.mts +0 -2
- package/dist/cli/lib.d.mts +1 -1
- package/dist/cli/lib.mjs +1 -1
- package/dist/cli/lib.mjs.map +1 -1
- package/dist/cli/main.d.mts +1 -3
- package/dist/cli/main.mjs +55 -51
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/query/index.d.mts +0 -2
- package/dist/cli/services/application.d.mts +6 -4
- package/dist/cli/services/executor/service.d.mts +2 -2
- package/dist/cli/services/function-bundle.d.mts +8 -0
- package/dist/cli/services/http-adapter/bundler.d.mts +7 -1
- package/dist/cli/services/resolver/service.d.mts +2 -2
- package/dist/cli/services/workflow/bundler.d.mts +2 -3
- package/dist/cli/shared/args.d.mts +0 -2
- package/dist/cli/shared/beta.d.mts +1 -3
- package/dist/cli/shared/client.d.mts +4 -3
- package/dist/cli/shared/command.d.mts +2 -4
- package/dist/cli/shared/config-loader.d.mts +2 -4
- package/dist/cli/shared/config.d.mts +1 -3
- package/dist/cli/shared/context.d.mts +0 -2
- package/dist/cli/shared/error-diagnostics.d.mts +1 -3
- package/dist/cli/shared/error-json.d.mts +1 -3
- package/dist/cli/shared/function-execution.d.mts +1 -3
- package/dist/cli/shared/github-actions.d.mts +1 -3
- package/dist/cli/shared/logger.d.mts +7 -4
- package/dist/cli/shared/platform-bundle-plugin.d.mts +1 -0
- package/dist/cli/shared/prompt.d.mts +1 -3
- package/dist/cli/shared/readonly-guard.d.mts +0 -2
- package/dist/cli/shared/script-executor.d.mts +1 -3
- package/dist/cli/shared/sdk-builder-pure-plugin.d.mts +1 -0
- package/dist/cli/shared/seed-chunker.d.mts +1 -3
- package/dist/cli/shared/seed-context.d.mts +0 -2
- package/dist/cli/shared/sourcemap-sources.d.mts +1 -0
- package/dist/cli/shared/tailordb-namespaces.d.mts +1 -3
- package/dist/cli/shared/type-generator.d.mts +0 -2
- package/dist/cli/shared/workspace-name.d.mts +1 -3
- package/dist/completion/zsh-worker.zsh +5 -5
- package/dist/configure/config/index.d.mts +2 -4
- package/dist/configure/config/types.d.mts +27 -4
- package/dist/configure/index.d.mts +7 -9
- package/dist/configure/index.mjs +1 -1
- package/dist/configure/services/aigateway/index.d.mts +0 -2
- package/dist/configure/services/aigateway/types.d.mts +0 -2
- package/dist/configure/services/auth/index.d.mts +0 -2
- package/dist/configure/services/auth/types.d.mts +0 -2
- package/dist/configure/services/executor/executor.d.mts +0 -2
- package/dist/configure/services/executor/operation.d.mts +0 -2
- package/dist/configure/services/executor/trigger/event.d.mts +0 -2
- package/dist/configure/services/executor/trigger/index.d.mts +0 -2
- package/dist/configure/services/executor/trigger/schedule.d.mts +0 -2
- package/dist/configure/services/executor/trigger/webhook.d.mts +1 -3
- package/dist/configure/services/http-adapter/http-adapter.d.mts +0 -2
- package/dist/configure/services/idp/index.d.mts +0 -2
- package/dist/configure/services/idp/permission.d.mts +0 -2
- package/dist/configure/services/idp/types.d.mts +0 -2
- package/dist/configure/services/index.d.mts +5 -5
- package/dist/configure/services/resolver/index.d.mts +1 -1
- package/dist/configure/services/resolver/permission.d.mts +0 -2
- package/dist/configure/services/resolver/resolver.d.mts +1 -3
- package/dist/configure/services/resolver/types.d.mts +1 -3
- package/dist/configure/services/secrets/index.d.mts +0 -2
- package/dist/configure/services/secrets/types.d.mts +0 -2
- package/dist/configure/services/staticwebsite/index.d.mts +0 -2
- package/dist/configure/services/staticwebsite/types.d.mts +0 -2
- package/dist/configure/services/tailordb/permission.d.mts +0 -2
- package/dist/configure/services/tailordb/schema.d.mts +0 -2
- package/dist/configure/services/tailordb/types.d.mts +0 -2
- package/dist/configure/services/workflow/execution-policy.d.mts +0 -2
- package/dist/configure/services/workflow/execution-policy.types.d.mts +0 -2
- package/dist/configure/services/workflow/job.d.mts +0 -2
- package/dist/configure/services/workflow/wait-point.d.mts +0 -2
- package/dist/configure/services/workflow/workflow.d.mts +0 -2
- package/dist/configure/types/aigateway-name.d.mts +1 -3
- package/dist/configure/types/auth-namespace-name.d.mts +1 -3
- package/dist/configure/types/connection-name.d.mts +1 -3
- package/dist/configure/types/field.d.mts +1 -3
- package/dist/configure/types/field.types.d.mts +0 -2
- package/dist/configure/types/idp-name.d.mts +1 -3
- package/dist/configure/types/permission-operand.types.d.mts +0 -2
- package/dist/configure/types/secret-vault-name.d.mts +1 -3
- package/dist/configure/types/type.d.mts +0 -2
- package/dist/{crashreport-BCIy33Cz.mjs → crashreport-DGU6lwiX.mjs} +2 -2
- package/dist/{crashreport-BCIy33Cz.mjs.map → crashreport-DGU6lwiX.mjs.map} +1 -1
- package/dist/crashreport-WsYAWARW.mjs +1 -0
- package/dist/{logger-RgtbhJ83.mjs → errors-BXmGBX-7.mjs} +6 -3
- package/dist/errors-BXmGBX-7.mjs.map +1 -0
- package/dist/field-parse-BQhUAbpM.mjs +2 -0
- package/dist/{field-parse-C41e3UAF.mjs.map → field-parse-BQhUAbpM.mjs.map} +1 -1
- package/dist/guards-CiFVxoXR.mjs +2 -0
- package/dist/guards-CiFVxoXR.mjs.map +1 -0
- package/dist/kysely/index.d.mts +0 -2
- package/dist/{kysely-type-DxyIWXc6.mjs → kysely-type-B0ri1-Xs.mjs} +9 -7
- package/dist/kysely-type-B0ri1-Xs.mjs.map +1 -0
- package/dist/manager-B813m43t.mjs +2 -0
- package/dist/manager-B813m43t.mjs.map +1 -0
- package/dist/parser/service/idp/types.d.mts +1 -3
- package/dist/parser/service/tailordb/type-source.d.mts +1 -3
- package/dist/parser/service/tailordb/types.d.mts +0 -2
- package/dist/plugin/builtin/enum-constants/index.d.mts +0 -2
- package/dist/plugin/builtin/file-utils/index.d.mts +0 -2
- package/dist/plugin/builtin/kysely-type/index.d.mts +0 -2
- package/dist/plugin/builtin/kysely-type/index.mjs +1 -1
- package/dist/plugin/builtin/seed/index.d.mts +0 -2
- package/dist/plugin/builtin/seed/seed-type-processor.d.mts +1 -3
- package/dist/plugin/get-generated-table.d.mts +1 -3
- package/dist/plugin/index.mjs +1 -1
- package/dist/plugin/types.d.mts +0 -2
- package/dist/plugin/with-context.d.mts +1 -3
- package/dist/register-ts-hook-CQ7shKO5.mjs +1055 -0
- package/dist/register-ts-hook-CQ7shKO5.mjs.map +1 -0
- package/dist/runtime/aigateway.d.mts +1 -3
- package/dist/runtime/authconnection.d.mts +1 -3
- package/dist/runtime/context.d.mts +0 -2
- package/dist/runtime/date.d.mts +0 -2
- package/dist/runtime/field-parse.d.mts +0 -2
- package/dist/runtime/file.d.mts +0 -2
- package/dist/runtime/globals.d.mts +0 -2
- package/dist/runtime/iconv.d.mts +1 -3
- package/dist/runtime/idp.d.mts +1 -3
- package/dist/runtime/index.d.mts +1 -3
- package/dist/runtime/index.mjs +1 -1
- package/dist/runtime/logger.d.mts +1 -3
- package/dist/runtime/secretmanager.d.mts +1 -3
- package/dist/runtime/temporal.d.mts +0 -2
- package/dist/runtime/types.d.mts +0 -2
- package/dist/runtime/workflow.d.mts +0 -2
- package/dist/{schema-B6hJQWp6.mjs → schema-BU1aIQ63.mjs} +2 -2
- package/dist/{schema-B6hJQWp6.mjs.map → schema-BU1aIQ63.mjs.map} +1 -1
- package/dist/secret-file-BxZ-J_Nz.mjs +2 -0
- package/dist/secret-file-BxZ-J_Nz.mjs.map +1 -0
- package/dist/seed/idp-user-password.d.mts +0 -2
- package/dist/seed/index.d.mts +0 -2
- package/dist/service-CaGmqg0r.mjs +2 -0
- package/dist/{service-9rwi_I4d.mjs.map → service-CaGmqg0r.mjs.map} +1 -1
- package/dist/service-DEq_hdht.mjs +1 -0
- package/dist/{service-9SBPNpK8.mjs → service-eeXdVrDK.mjs} +4 -4
- package/dist/service-eeXdVrDK.mjs.map +1 -0
- package/dist/shared/src/color.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/aigateway_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/aigateway_resource_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/application_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/application_resource_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/auth_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/auth_resource_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/events_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/events_resource_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/executor_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/executor_resource_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/function_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/function_registry_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/function_resource_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/http_adapter_resource_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/idp_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/idp_resource_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/metadata_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/metadata_resource_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/meter_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/pipeline_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/pipeline_resource_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/resource_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/secret_manager_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/secret_manager_resource_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/security_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/security_resource_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/service_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/stateflow_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/stateflow_resource_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/staticwebsite_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/staticwebsite_resource_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/tailordb_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/tailordb_resource_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/telemetryrouter_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/telemetryrouter_resource_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/workflow_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/workflow_resource_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/workspace_pb.d.mts +1 -3
- package/dist/tailor-proto/src/tailor/v1/workspace_resource_pb.d.mts +1 -3
- package/dist/types/aigateway.generated.d.mts +1 -3
- package/dist/types/app-config.generated.d.mts +1 -3
- package/dist/types/auth-connection.generated.d.mts +1 -3
- package/dist/types/auth.generated.d.mts +1 -3
- package/dist/types/executor.generated.d.mts +1 -3
- package/dist/types/field.generated.d.mts +1 -3
- package/dist/types/helpers.d.mts +1 -3
- package/dist/types/http-adapter.generated.d.mts +1 -3
- package/dist/types/idp.generated.d.mts +1 -3
- package/dist/types/resolver.generated.d.mts +1 -3
- package/dist/types/secrets.generated.d.mts +1 -3
- package/dist/types/staticwebsite.generated.d.mts +1 -3
- package/dist/types/tailordb.generated.d.mts +1 -3
- package/dist/types/workflow.generated.d.mts +1 -3
- package/dist/utils/test/index.d.mts +1 -3
- package/dist/utils/test/index.mjs +1 -1
- package/dist/vitest/date-representation.d.mts +1 -3
- package/dist/vitest/environment.d.mts +0 -2
- package/dist/vitest/index.d.mts +0 -2
- package/dist/vitest/migration-steps.d.mts +1 -3
- package/dist/vitest/mock-kysely.d.mts +0 -2
- package/dist/vitest/mocks/aigateway.d.mts +0 -2
- package/dist/vitest/mocks/authconnection.d.mts +0 -2
- package/dist/vitest/mocks/file.d.mts +0 -2
- package/dist/vitest/mocks/iconv.d.mts +0 -2
- package/dist/vitest/mocks/idp.d.mts +0 -2
- package/dist/vitest/mocks/logger.d.mts +0 -2
- package/dist/vitest/mocks/secretmanager.d.mts +0 -2
- package/dist/vitest/mocks/tailordb-pglite.d.mts +0 -2
- package/dist/vitest/mocks/tailordb.d.mts +0 -2
- package/dist/vitest/mocks/workflow.d.mts +0 -2
- package/dist/vitest/pglite-kysely.d.mts +0 -2
- package/dist/vitest/pglite-temporal.d.mts +1 -3
- package/dist/vitest/setup.d.mts +0 -2
- package/dist/vitest/workflow-local.d.mts +0 -2
- package/docs/cli/application.md +2 -1
- package/docs/cli/tailordb.md +9 -7
- package/docs/cli/user.md +5 -5
- package/docs/cli/workspace.md +1 -1
- package/docs/cli-reference.md +27 -26
- package/docs/configuration.md +15 -2
- package/docs/github-actions.md +33 -10
- package/docs/services/secret.md +6 -0
- package/docs/services/tailordb/index.md +23 -0
- package/docs/services/tailordb/migration.md +14 -9
- package/docs/testing.md +2 -2
- package/package.json +12 -12
- package/dist/application-B9_NHiUC.mjs +0 -207
- package/dist/application-B9_NHiUC.mjs.map +0 -1
- package/dist/cli/commands/tailordb/migrate/remote-state.d.mts +0 -1
- package/dist/crashreport-IN6H7GX3.mjs +0 -1
- package/dist/errors-BOF68LJ5.mjs +0 -5
- package/dist/errors-BOF68LJ5.mjs.map +0 -1
- package/dist/field-parse-C41e3UAF.mjs +0 -2
- package/dist/guards-yDXyKC9F.mjs +0 -2
- package/dist/guards-yDXyKC9F.mjs.map +0 -1
- package/dist/kysely-type-DxyIWXc6.mjs.map +0 -1
- package/dist/logger-RgtbhJ83.mjs.map +0 -1
- package/dist/manager-DTRhIupk.mjs +0 -2
- package/dist/manager-DTRhIupk.mjs.map +0 -1
- package/dist/register-ts-hook-Dp9reSRG.mjs +0 -1053
- package/dist/register-ts-hook-Dp9reSRG.mjs.map +0 -1
- package/dist/secret-file-C9wp_FCX.mjs +0 -2
- package/dist/secret-file-C9wp_FCX.mjs.map +0 -1
- package/dist/service-9SBPNpK8.mjs.map +0 -1
- package/dist/service-9rwi_I4d.mjs +0 -2
- package/dist/service-Ca1WwyIt.mjs +0 -1
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import{t as e}from"./multiline-EyzjEwn9.mjs";import{resolve as t}from"pathe";const n=new TextEncoder;function mapFieldTypeToPostgresType(e){switch(e){case`uuid`:return`uuid`;case`string`:case`enum`:return`text`;case`boolean`:case`bool`:return`boolean`;case`integer`:return`integer`;case`float`:return`double precision`;case`decimal`:return`numeric`;case`date`:return`date`;case`datetime`:return`timestamptz`;case`time`:return`time`;case`nested`:return`jsonb`;default:throw Error(`Field type "${e}" has no PostgreSQL column type.`)}}function identifier(e){return`"${e.replaceAll(`"`,`""`)}"`}function fnv1aHex(e){let t=2166136261;for(let r of n.encode(e))t=Math.imul(t^r,16777619)>>>0;return t.toString(16).padStart(8,`0`)}function derivedName(e,t,r){let i=`_${fnv1aHex(JSON.stringify([e,t,r]))}_${r}`,a=`${e}_${t}`;for(;n.encode(a+i).length>63;)a=a.slice(0,-1);return a+i}function derivedIdentifier(e,t,n){return identifier(derivedName(e,t,n))}function dollarQuoted(e){let t=`$fk$`;for(;e.includes(t);)t=`${t.slice(0,-1)}_$`;return`${t}\n${e}\n${t}`}function stringLiteral(e){return`'${e.replaceAll(`'`,`''`)}'`}function columnType(e){let t=e.type===`decimal`?`numeric(1000, ${e.scale??6})`:mapFieldTypeToPostgresType(e.type);return e.array&&e.type!==`nested`?`${t}[]`:t}function scalarLiteral(e,t,n){let r=mapFieldTypeToPostgresType(t.type);if(e instanceof Date){if(Number.isNaN(e.getTime()))throw Error(`Default of field ${n} is an invalid Date.`);return`${stringLiteral(e.toISOString())}::${r}`}switch(typeof e){case`string`:return r===`text`?stringLiteral(e):`${stringLiteral(e)}::${r}`;case`number`:if(!Number.isFinite(e))throw Error(`Default of field ${n} is not a finite number.`);return String(e);case`boolean`:return e?`TRUE`:`FALSE`;default:throw Error(`Default of field ${n} cannot be rendered as a SQL literal.`)}}const r=/* @__PURE__ */ new Map([[`datetime`,`now()`],[`date`,`CURRENT_DATE`],[`time`,`LOCALTIME`]]);function defaultExpression(e,t){let n=e.default,i=r.get(e.type);if(n===`now`&&i!==void 0)return i;if(e.array){if(!Array.isArray(n))throw Error(`Default of array field ${t} must be an array.`);let r=columnType(e);return n.length===0?`'{}'::${r}`:`ARRAY[${n.map(n=>scalarLiteral(n,e,t)).join(`, `)}]::${r}`}return scalarLiteral(n,e,t)}function parseSerialFormat(e,t){let n=/^(?<prefix>[^%]*)%(?<zero>0?)(?<width>\d*)(?<conversion>[a-zA-Z])(?<suffix>[^%]*)$/.exec(e)?.groups,r=n?.conversion;if(!n||r!==`d`&&r!==`x`&&r!==`X`)throw Error(`Serial format "${e}" of field ${t} is not supported; use a single %d, %x, or %X specifier with an optional width (e.g. "INV-%05d").`);return{prefix:n.prefix??``,zeroPad:n.zero===`0`,width:n.width?Number(n.width):0,conversion:r,suffix:n.suffix??``}}function sequenceName(e,t){return derivedIdentifier(e,t,`seq`)}function sequenceRange(e){let t=[`START WITH ${e.start}`,`MINVALUE ${e.start}`];return e.maxValue!==void 0&&t.push(`MAXVALUE ${e.maxValue}`),t.join(` `)}const i={d:e=>e,x:e=>`to_hex(${e})`,X:e=>`upper(to_hex(${e}))`};function serialStringDefault(e,t,n){let r=`nextval(${stringLiteral(e)})`;if(t===void 0)return`(${r}::text)`;let{prefix:a,width:o,zeroPad:s,conversion:c,suffix:l}=parseSerialFormat(t,n),u=i[c](r),d=c===`d`?`${u}::text`:u;return o>0&&(d=`format('%${o}s', ${u})`,s&&(d=`translate(${d}, ' ', '0')`)),`(${[...a?[stringLiteral(a)]:[],d,...l?[stringLiteral(l)]:[]].join(` || `)})`}function columnDefinition(e,t,n){let r=identifier(t),i=`${identifier(e)}.${r}`,a=[r,columnType(n)];if(n.serial)return n.type===`integer`?(a.push(`GENERATED BY DEFAULT AS IDENTITY (${sequenceRange(n.serial)})`),n.unique&&a.push(`UNIQUE`),a.join(` `)):(n.required&&a.push(`NOT NULL`),n.unique&&a.push(`UNIQUE`),a.push(`DEFAULT ${serialStringDefault(sequenceName(e,t),n.serial.format,i)}`),a.join(` `));let o=n.default!==void 0,s=n.hooks?.create!==void 0||n.optionalOnCreate===!0;return n.required&&(o||!s)&&a.push(`NOT NULL`),n.unique&&a.push(`UNIQUE`),o&&a.push(`DEFAULT ${defaultExpression(n,i)}`),a.join(` `)}function jsonPathKey(e){return`"${e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`)}"`}function referencesWithin(e,t,n){let r=t.array?`${n}[*]`:n;return t.type===`nested`?Object.entries(t.fields??{}).flatMap(([t,n])=>referencesWithin(e,n,`${r}.${jsonPathKey(t)}`)):!t.foreignKey||t.foreignKeyType===void 0?[]:[{column:e,path:r,table:t.foreignKeyType,field:t.foreignKeyField??`id`,type:t.type}]}function tableReferences(e){return Object.entries(e.fields).filter(([e])=>e!==`id`).flatMap(([e,t])=>referencesWithin(e,t,`$`))}function isConstraintReference(e,t){if(e.path!==`$`)return!1;let n=e.field===`id`?`uuid`:t.get(e.table)?.fields[e.field]?.type;return n===void 0||mapFieldTypeToPostgresType(n)===mapFieldTypeToPostgresType(e.type)}function referenceClause(e){return`REFERENCES ${identifier(e.table)} (${identifier(e.field)})`}function declaredType(e){return e===`bool`?`boolean`:e}function checkReference(e,t){let n=t.get(e.table);if(!n)return{problem:`references unknown table "${e.table}".`};let r=e.field===`id`?{type:`uuid`,unique:!0}:n.fields[e.field];if(!r)return{problem:`references unknown field "${e.field}" of table "${e.table}".`};let i=e.field===`id`||declaredType(r.type)===declaredType(e.type);return!r.unique||!i?{problem:`references "${e.table}"."${e.field}", which must be unique and of the same type as the referencing field.`}:{pgType:mapFieldTypeToPostgresType(r.type)}}function referencedColumnType(e,t,n){let r=checkReference(e,t);if(`problem`in r)throw Error(`Field ${n} ${r.problem}`);return r.pgType}function withoutReference(e){let{foreignKey:t,foreignKeyType:n,foreignKeyField:r,...i}=e;return i}function withoutUnresolvableReference(e,t){return e.fields?{...e,fields:Object.fromEntries(Object.entries(e.fields).map(([e,n])=>[e,withoutUnresolvableReference(n,t)]))}:!e.foreignKey||e.foreignKeyType===void 0?e:`problem`in checkReference({column:``,path:`$`,table:e.foreignKeyType,field:e.foreignKeyField??`id`,type:e.type},t)?withoutReference(e):e}function dropUnresolvableReferences(e){let t=new Map(e.map(e=>[e.name,e]));return e.map(e=>({...e,fields:Object.fromEntries(Object.entries(e.fields).map(([e,n])=>[e,withoutUnresolvableReference(n,t)]))}))}function referenceCheck(e,t,n){let r=referencedColumnType(e,t,n),i=r===mapFieldTypeToPostgresType(e.type)?`parent.${identifier(e.field)} = (fk_check.v #>> '{}')::${r}`:`parent.${identifier(e.field)}::text = (fk_check.v #>> '{}')`,a=`violates foreign key constraints: % not found in ${`${identifier(e.table)}.${identifier(e.field)}`.replaceAll(`%`,`%%`)}`;return[` FOR v IN SELECT jsonb_path_query(to_jsonb(NEW.${identifier(e.column)}), ${stringLiteral(e.path)}) LOOP`,` IF jsonb_typeof(fk_check.v) <> 'null' AND NOT EXISTS (SELECT 1 FROM ${identifier(e.table)} AS parent WHERE ${i}) THEN`,` RAISE EXCEPTION ${stringLiteral(a)}, fk_check.v #>> '{}' USING ERRCODE = 'foreign_key_violation';`,` END IF;`,` END LOOP;`].join(`
|
|
1
|
+
import{t as e}from"./multiline-EyzjEwn9.mjs";import{resolve as t}from"pathe";const n=new TextEncoder;function mapFieldTypeToPostgresType(e){switch(e){case`uuid`:return`uuid`;case`string`:case`enum`:return`text`;case`boolean`:case`bool`:return`boolean`;case`integer`:return`integer`;case`float`:return`double precision`;case`decimal`:return`numeric`;case`date`:return`date`;case`datetime`:return`timestamptz`;case`time`:return`time`;case`nested`:return`jsonb`;default:throw Error(`Field type "${e}" has no PostgreSQL column type.`)}}function identifier(e){return`"${e.replaceAll(`"`,`""`)}"`}function fnv1aHex(e){let t=2166136261;for(let r of n.encode(e))t=Math.imul(t^r,16777619)>>>0;return t.toString(16).padStart(8,`0`)}function derivedName(e,t,r){let i=`_${fnv1aHex(JSON.stringify([e,t,r]))}_${r}`,a=`${e}_${t}`;for(;n.encode(a+i).length>63;)a=a.slice(0,-1);return a+i}function derivedIdentifier(e,t,n){return identifier(derivedName(e,t,n))}function dollarQuoted(e){let t=`$fk$`;for(;e.includes(t);)t=`${t.slice(0,-1)}_$`;return`${t}\n${e}\n${t}`}function stringLiteral(e){return`'${e.replaceAll(`'`,`''`)}'`}function columnType(e){let t=e.type===`decimal`?`numeric(1000, ${e.scale??6})`:mapFieldTypeToPostgresType(e.type);return e.array&&e.type!==`nested`?`${t}[]`:t}function scalarLiteral(e,t,n){let r=mapFieldTypeToPostgresType(t.type);if(e instanceof Date){if(Number.isNaN(e.getTime()))throw Error(`Default of field ${n} is an invalid Date.`);return`${stringLiteral(e.toISOString())}::${r}`}switch(typeof e){case`string`:return r===`text`?stringLiteral(e):`${stringLiteral(e)}::${r}`;case`number`:if(!Number.isFinite(e))throw Error(`Default of field ${n} is not a finite number.`);return String(e);case`boolean`:return e?`TRUE`:`FALSE`;default:throw Error(`Default of field ${n} cannot be rendered as a SQL literal.`)}}const r=/* @__PURE__ */ new Map([[`datetime`,`now()`],[`date`,`CURRENT_DATE`],[`time`,`LOCALTIME`]]);function defaultExpression(e,t){let n=e.default,i=r.get(e.type);if(n===`now`&&i!==void 0)return i;if(e.array){if(!Array.isArray(n))throw Error(`Default of array field ${t} must be an array.`);let r=columnType(e);return n.length===0?`'{}'::${r}`:`ARRAY[${n.map(n=>scalarLiteral(n,e,t)).join(`, `)}]::${r}`}return scalarLiteral(n,e,t)}function parseSerialFormat(e,t){let n=/^(?<prefix>[^%]*)%(?<zero>0?)(?<width>\d*)(?<conversion>[a-zA-Z])(?<suffix>[^%]*)$/.exec(e)?.groups,r=n?.conversion;if(!n||r!==`d`&&r!==`x`&&r!==`X`)throw Error(`Serial format "${e}" of field ${t} is not supported; use a single %d, %x, or %X specifier with an optional width (e.g. "INV-%05d").`);return{prefix:n.prefix??``,zeroPad:n.zero===`0`,width:n.width?Number(n.width):0,conversion:r,suffix:n.suffix??``}}function sequenceName(e,t){return derivedIdentifier(e,t,`seq`)}function sequenceRange(e){let t=[`START WITH ${e.start}`,`MINVALUE ${e.start}`];return e.maxValue!==void 0&&t.push(`MAXVALUE ${e.maxValue}`),t.join(` `)}const i={d:e=>e,x:e=>`to_hex(${e})`,X:e=>`upper(to_hex(${e}))`};function serialStringDefault(e,t,n){let r=`nextval(${stringLiteral(e)})`;if(t===void 0)return`(${r}::text)`;let{prefix:a,width:o,zeroPad:s,conversion:c,suffix:l}=parseSerialFormat(t,n),u=i[c](r),d=c===`d`?`${u}::text`:u;return o>0&&(d=`format('%${o}s', ${u})`,s&&(d=`translate(${d}, ' ', '0')`)),`(${[...a?[stringLiteral(a)]:[],d,...l?[stringLiteral(l)]:[]].join(` || `)})`}function columnDefinition(e,t,n){let r=identifier(t),i=`${identifier(e)}.${r}`,a=[r,columnType(n)];if(n.serial)return n.type===`integer`?(a.push(`GENERATED BY DEFAULT AS IDENTITY (${sequenceRange(n.serial)})`),n.unique&&a.push(`UNIQUE`),a.join(` `)):(n.required&&a.push(`NOT NULL`),n.unique&&a.push(`UNIQUE`),a.push(`DEFAULT ${serialStringDefault(sequenceName(e,t),n.serial.format,i)}`),a.join(` `));let o=n.default!==void 0,s=n.hooks?.create!==void 0||n.optionalOnCreate===!0;return n.required&&(o||!s)&&a.push(`NOT NULL`),n.unique&&a.push(`UNIQUE`),o&&a.push(`DEFAULT ${defaultExpression(n,i)}`),a.join(` `)}function jsonPathKey(e){return`"${e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`)}"`}function referencesWithin(e,t,n){let r=t.array?`${n}[*]`:n;return t.type===`nested`?Object.entries(t.fields??{}).flatMap(([t,n])=>referencesWithin(e,n,`${r}.${jsonPathKey(t)}`)):!t.foreignKey||t.foreignKeyType===void 0?[]:[{column:e,path:r,table:t.foreignKeyType,field:t.foreignKeyField??`id`,type:t.type}]}const a=/* @__PURE__ */ new Set([`integer`,`float`,`decimal`,`boolean`,`bool`,`uuid`]);function nestedUniqueMembers(e,t,n){return t.array?[]:t.type===`nested`?Object.entries(t.fields??{}).flatMap(([t,r])=>nestedUniqueMembers(e,r,[...n,t])):t.unique&&n.length>0?[{column:e,path:n,field:t}]:[]}function nestedUniqueIndex(e,t){let n=t.path.map(stringLiteral).join(`, `),r=`${identifier(t.column)} #>> ARRAY[${n}]`,i=a.has(t.field.type)?`CAST(${r} AS ${mapFieldTypeToPostgresType(t.field.type)})`:r;return`CREATE UNIQUE INDEX IF NOT EXISTS ${derivedIdentifier(e,`${t.column}.${t.path.join(`.`)}`,`nested_idx`)} ON ${identifier(e)} ((${i}))`}function tableReferences(e){return Object.entries(e.fields).filter(([e])=>e!==`id`).flatMap(([e,t])=>referencesWithin(e,t,`$`))}function isConstraintReference(e,t){if(e.path!==`$`)return!1;let n=e.field===`id`?`uuid`:t.get(e.table)?.fields[e.field]?.type;return n===void 0||mapFieldTypeToPostgresType(n)===mapFieldTypeToPostgresType(e.type)}function referenceClause(e){return`REFERENCES ${identifier(e.table)} (${identifier(e.field)})`}function declaredType(e){return e===`bool`?`boolean`:e}function checkReference(e,t){let n=t.get(e.table);if(!n)return{problem:`references unknown table "${e.table}".`};let r=e.field===`id`?{type:`uuid`,unique:!0}:n.fields[e.field];if(!r)return{problem:`references unknown field "${e.field}" of table "${e.table}".`};let i=e.field===`id`||declaredType(r.type)===declaredType(e.type);return!r.unique||!i?{problem:`references "${e.table}"."${e.field}", which must be unique and of the same type as the referencing field.`}:{pgType:mapFieldTypeToPostgresType(r.type)}}function referencedColumnType(e,t,n){let r=checkReference(e,t);if(`problem`in r)throw Error(`Field ${n} ${r.problem}`);return r.pgType}function withoutReference(e){let{foreignKey:t,foreignKeyType:n,foreignKeyField:r,...i}=e;return i}function withoutUnresolvableReference(e,t){return e.fields?{...e,fields:Object.fromEntries(Object.entries(e.fields).map(([e,n])=>[e,withoutUnresolvableReference(n,t)]))}:!e.foreignKey||e.foreignKeyType===void 0?e:`problem`in checkReference({column:``,path:`$`,table:e.foreignKeyType,field:e.foreignKeyField??`id`,type:e.type},t)?withoutReference(e):e}function dropUnresolvableReferences(e){let t=new Map(e.map(e=>[e.name,e]));return e.map(e=>({...e,fields:Object.fromEntries(Object.entries(e.fields).map(([e,n])=>[e,withoutUnresolvableReference(n,t)]))}))}function referenceCheck(e,t,n){let r=referencedColumnType(e,t,n),i=r===mapFieldTypeToPostgresType(e.type)?`parent.${identifier(e.field)} = (fk_check.v #>> '{}')::${r}`:`parent.${identifier(e.field)}::text = (fk_check.v #>> '{}')`,a=`violates foreign key constraints: % not found in ${`${identifier(e.table)}.${identifier(e.field)}`.replaceAll(`%`,`%%`)}`;return[` FOR v IN SELECT jsonb_path_query(to_jsonb(NEW.${identifier(e.column)}), ${stringLiteral(e.path)}) LOOP`,` IF jsonb_typeof(fk_check.v) <> 'null' AND NOT EXISTS (SELECT 1 FROM ${identifier(e.table)} AS parent WHERE ${i}) THEN`,` RAISE EXCEPTION ${stringLiteral(a)}, fk_check.v #>> '{}' USING ERRCODE = 'foreign_key_violation';`,` END IF;`,` END LOOP;`].join(`
|
|
2
2
|
`)}function referenceTrigger(e,t,n){if(t.length===0)return[];let r=derivedIdentifier(e.name,`references`,`fk`);return[`CREATE OR REPLACE FUNCTION ${r}() RETURNS trigger LANGUAGE plpgsql AS ${dollarQuoted([`<<fk_check>>`,`DECLARE v jsonb;`,`BEGIN`,...t.map(t=>referenceCheck(t,n,`${e.name}.${t.column}`)),` RETURN NULL;`,`END`].join(`
|
|
3
|
-
`))}`,`CREATE OR REPLACE TRIGGER ${r} AFTER INSERT OR UPDATE ON ${identifier(e.name)} FOR EACH ROW EXECUTE FUNCTION ${r}()`]}function
|
|
4
|
-
`)}
|
|
3
|
+
`))}`,`CREATE OR REPLACE TRIGGER ${r} AFTER INSERT OR UPDATE ON ${identifier(e.name)} FOR EACH ROW EXECUTE FUNCTION ${r}()`]}function incomingReferences(e,t){return[...t.values()].flatMap(n=>tableReferences(n).filter(n=>!isConstraintReference(n,t)&&n.table===e.name).flatMap(e=>{let r=checkReference(e,t);return`pgType`in r?[{...e,child:n.name,pgType:r.pgType}]:[]}))}function holdsParent(e){let t=`child.${identifier(e.column)}`,n=`OLD.${identifier(e.field)}`,r=e.pgType===mapFieldTypeToPostgresType(e.type);if(r&&e.path===`$[*]`)return`${n} = ANY(${t})`;let i=r?`(held.v #>> '{}')::${e.pgType} = ${n}`:`(held.v #>> '{}') = ${n}::text`,a=r?`WHEN NOT pg_input_is_valid(held.v #>> '{}', ${stringLiteral(e.pgType)}) THEN false `:``;return`EXISTS (SELECT 1 FROM jsonb_path_query(to_jsonb(${t}), ${stringLiteral(e.path)}) AS held(v) WHERE CASE WHEN jsonb_typeof(held.v) = 'null' THEN false ${a}ELSE ${i} END)`}const o=`old_rows`;function holds(e,t){return`EXISTS (SELECT 1 FROM ${t} AS child WHERE ${holdsParent(e)})`}function refuseWhen(e,t,n){let r=`update or delete on table \`${e.name}\` violates foreign key constraint: some record is still referenced from table \`${t.child}\``;return[` IF ${n} THEN`,` RAISE EXCEPTION ${stringLiteral(r.replaceAll(`%`,`%%`))} USING ERRCODE = 'foreign_key_violation';`,` END IF;`].join(`
|
|
4
|
+
`)}function referencedDeleteCheck(e,t){let n=holds(t,identifier(t.child));return refuseWhen(e,t,t.child===e.name?`${n} OR ${holds(t,o)}`:n)}function referencedUpdateCheck(e,t){let n=identifier(t.field);return refuseWhen(e,t,`NEW.${n} IS DISTINCT FROM OLD.${n} AND ${holds(t,identifier(t.child))}`)}function referencedTrigger(e,t){let n=incomingReferences(e,t);return n.length===0?[]:[[`referenced_delete`,`DELETE`,n.some(t=>t.child===e.name)?` REFERENCING OLD TABLE AS ${o}`:``,referencedDeleteCheck],[`referenced_update`,`UPDATE`,``,referencedUpdateCheck]].flatMap(([t,r,i,a])=>{let o=derivedIdentifier(e.name,t,`fk`);return[`CREATE OR REPLACE FUNCTION ${o}() RETURNS trigger LANGUAGE plpgsql AS ${dollarQuoted([`BEGIN`,...n.map(t=>a(e,t)),` RETURN NULL;`,`END`].join(`
|
|
5
|
+
`))}`,`CREATE OR REPLACE TRIGGER ${o} AFTER ${r} ON ${identifier(e.name)}${i} FOR EACH ROW EXECUTE FUNCTION ${o}()`]})}function generateTableDDL(e,t={}){let n=identifier(e.name),r=new Map((t.tables??[e]).map(e=>[e.name,e])),i=[],a=[],o=[` "id" uuid PRIMARY KEY DEFAULT gen_random_uuid()`],s=tableReferences(e),c=new Map(s.filter(e=>isConstraintReference(e,r)).map(e=>[e.column,e]));for(let[r,s]of Object.entries(e.fields)){if(r===`id`)continue;if(s.serial&&s.type!==`integer`){let t=sequenceName(e.name,r);i.push(`CREATE SEQUENCE IF NOT EXISTS ${t} ${sequenceRange(s.serial)}`),a.push(`ALTER SEQUENCE ${t} OWNED BY ${n}.${identifier(r)}`)}let l=c.get(r),u=l&&!t.deferredReferences?.has(r)?` ${referenceClause(l)}`:``;o.push(` ${columnDefinition(e.name,r,s)}${u}`)}let l=[...Object.entries(e.indexes??{}).filter(([,e])=>e.unique).map(([t,r])=>`CREATE UNIQUE INDEX IF NOT EXISTS ${derivedIdentifier(e.name,t,`idx`)} ON ${n} (${r.fields.map(identifier).join(`, `)})`),...Object.entries(e.fields).filter(([e])=>e!==`id`).flatMap(([e,t])=>nestedUniqueMembers(e,t,[])).map(t=>nestedUniqueIndex(e.name,t))];for(let t of c.values())referencedColumnType(t,r,`${e.name}.${t.column}`);return[...i,`CREATE TABLE IF NOT EXISTS ${n} (\n${o.join(`,
|
|
6
|
+
`)}\n)`,...a,...l,...referenceTrigger(e,s.filter(e=>!isConstraintReference(e,r)),r),...referencedTrigger(e,r)]}function addForeignKey(e,t){let n=derivedName(e.name,t.column,`fk`),r=identifier(e.name);return`DO ${dollarQuoted([`BEGIN`,`IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = ${stringLiteral(n)} AND conrelid = ${stringLiteral(r)}::regclass) THEN`,`ALTER TABLE ${r} ADD CONSTRAINT ${identifier(n)} FOREIGN KEY (${identifier(t.column)}) ${referenceClause(t)};`,`END IF;`,`END`].join(`
|
|
5
7
|
`))}`}function planCreation(e){let t=new Set(e.map(e=>e.name)),n=new Map(e.map(e=>[e.name,e])),r=/* @__PURE__ */ new Set,i=[...e],a=[],o=/* @__PURE__ */ new Map,pendingOf=e=>tableReferences(e).filter(e=>isConstraintReference(e,n)).filter(n=>t.has(n.table)&&n.table!==e.name&&!r.has(n.table));for(;i.length>0;){let e=i.findIndex(e=>pendingOf(e).length===0),[t]=i.splice(Math.max(e,0),1),n=pendingOf(t);n.length>0&&o.set(t,n),r.add(t.name),a.push(t)}return{ordered:a,deferred:o}}function generateSchemaDDL(e){let{ordered:t,deferred:n}=planCreation(e),r=t.map(t=>generateTableDDL(t,{tables:e,deferredReferences:new Set(n.get(t)?.map(e=>e.column))})),i=t.flatMap(e=>(n.get(e)??[]).map(t=>addForeignKey(e,t)));return[...r,i].filter(e=>e.length>0).map(e=>e.map(e=>`${e};`).join(`
|
|
6
8
|
`)).join(`
|
|
7
9
|
|
|
8
10
|
`)}function templateLiteral(e){return`\`${e.replaceAll(`\\`,`\\\\`).replaceAll("`","\\`").replaceAll("${","\\${").replaceAll(`\r`,`\\r`)}\``}function generatePgliteSchemaModule(e,t){let n=e.map(({namespace:e,tables:t})=>` ${JSON.stringify(e)}: ${templateLiteral(generateSchemaDDL(t))},`);return[`/**`,` * Auto-generated PGlite schema for TailorDB tables.`," * Create a namespace's tables in a test with `pglite.exec(pgliteSchema[namespace])`.",` *`,` * DO NOT EDIT - This file is auto-generated by ${t.generatedBy}.`,` */`,``,`export const pgliteSchema = {`,...n,`} as const;`,``].join(`
|
|
9
|
-
`)}function toDDLTables(e){return Object.values(e).map(e=>({name:e.name,fields:Object.fromEntries(Object.entries(e.fields).map(([e,t])=>[e,t.config])),indexes:e.indexes}))}function generatePGliteSchemaModule(e){return generatePgliteSchemaModule(e.map(({namespace:e,tables:t})=>({namespace:e,tables:toDDLTables(t)})),{generatedBy:`the kysely-type plugin`})}function mapFieldTypeToColumnType(e,t=!1){switch(e){case`uuid`:case`string`:case`decimal`:return`string`;case`integer`:case`float`:return`number`;case`date`:return t?`TemporalDate`:`Timestamp`;case`datetime`:return t?`TemporalInstant`:`Timestamp`;case`time`:return t?`TemporalTime`:`string`;case`bool`:case`boolean`:return`boolean`;case`enum`:case`nested`:throw Error(`Field type "${e}" has no scalar column type; resolve it before mapping.`);default:return`string`}}const
|
|
10
|
-
`)}${a.length>0?`;`:``}\n}`,s=Object.values(n).some(e=>e.required!==!0),c=Object.values(n).some(e=>e.hooks?.create||e.default!==void 0||e.optionalOnCreate===!0);return usesColumnTypeAlias(i)||s||c?{type:`ObjectColumnType<${o}>`,usedUtilityTypes:{...i,ObjectColumnType:!0}}:{type:o,usedUtilityTypes:i}}function getBaseType(e,t,n){let r=e.type,i=emptyUsedUtilityTypes();if(r===`enum`)return{type:getEnumType(e),usedUtilityTypes:i};if(r===`nested`)return getNestedType(e,t);let a=mapFieldTypeToColumnType(r,t&&!(n&&r===`time`));switch(a){case`Timestamp`:i.Timestamp=!0;break;case`TemporalDate`:i.TemporalDate=!0;break;case`TemporalInstant`:i.TemporalInstant=!0;break;case`TemporalTime`:i.TemporalTime=!0}return{type:a,usedUtilityTypes:i}}function generateFieldType(e,t,n=!1){let r=getBaseType(e,t,n),i={...r.usedUtilityTypes},
|
|
11
|
+
`)}function toDDLTables(e){return Object.values(e).map(e=>({name:e.name,fields:Object.fromEntries(Object.entries(e.fields).map(([e,t])=>[e,t.config])),indexes:e.indexes}))}function generatePGliteSchemaModule(e){return generatePgliteSchemaModule(e.map(({namespace:e,tables:t})=>({namespace:e,tables:toDDLTables(t)})),{generatedBy:`the kysely-type plugin`})}function mapFieldTypeToColumnType(e,t=!1){switch(e){case`uuid`:case`string`:case`decimal`:return`string`;case`integer`:case`float`:return`number`;case`date`:return t?`TemporalDate`:`Timestamp`;case`datetime`:return t?`TemporalInstant`:`Timestamp`;case`time`:return t?`TemporalTime`:`string`;case`bool`:case`boolean`:return`boolean`;case`enum`:case`nested`:throw Error(`Field type "${e}" has no scalar column type; resolve it before mapping.`);default:return`string`}}const s=/* @__PURE__ */ new Map([[`Timestamp`,{select:`Date`,write:`Date | string`}],[`TemporalDate`,{select:`Temporal.PlainDate`,write:`Temporal.PlainDate | string`}],[`TemporalInstant`,{select:`Temporal.Instant`,write:`Temporal.Instant | string`}],[`TemporalTime`,{select:`Temporal.PlainTime`,write:`Temporal.PlainTime | string`}]]);function emptyUsedUtilityTypes(){return{Timestamp:!1,TemporalDate:!1,TemporalInstant:!1,TemporalTime:!1,Serial:!1,ObjectColumnType:!1,ArrayColumnType:!1}}function mergeUsedUtilityTypes(e,t){return{Timestamp:e.Timestamp||t.Timestamp,TemporalDate:e.TemporalDate||t.TemporalDate,TemporalInstant:e.TemporalInstant||t.TemporalInstant,TemporalTime:e.TemporalTime||t.TemporalTime,Serial:e.Serial||t.Serial,ObjectColumnType:e.ObjectColumnType||t.ObjectColumnType,ArrayColumnType:e.ArrayColumnType||t.ArrayColumnType}}function usesColumnTypeAlias(e){return e.Timestamp||e.TemporalDate||e.TemporalInstant||e.TemporalTime}function getEnumType(e){let t=e.allowedValues;return t&&Array.isArray(t)?t.map(e=>`"${typeof e==`string`?e:e.value}"`).join(` | `):`string`}function getNestedType(e,t){let n=e.fields;if(!n||typeof n!=`object`)return{type:`string`,usedUtilityTypes:emptyUsedUtilityTypes()};let r=Object.entries(n).map(([e,n])=>{let r=generateFieldType(n,t,!0);return{fieldType:`${e}${n.required===!0?``:`?`}: ${r.type}`,usedUtilityTypes:r.usedUtilityTypes}}),i=r.reduce((e,t)=>mergeUsedUtilityTypes(e,t.usedUtilityTypes),emptyUsedUtilityTypes()),a=r.map(e=>e.fieldType),o=`{\n ${a.join(`;
|
|
12
|
+
`)}${a.length>0?`;`:``}\n}`,s=Object.values(n).some(e=>e.required!==!0),c=Object.values(n).some(e=>e.hooks?.create||e.default!==void 0||e.optionalOnCreate===!0);return usesColumnTypeAlias(i)||s||c?{type:`ObjectColumnType<${o}>`,usedUtilityTypes:{...i,ObjectColumnType:!0}}:{type:o,usedUtilityTypes:i}}function getBaseType(e,t,n){let r=e.type,i=emptyUsedUtilityTypes();if(r===`enum`)return{type:getEnumType(e),usedUtilityTypes:i};if(r===`nested`)return getNestedType(e,t);let a=mapFieldTypeToColumnType(r,t&&!(n&&r===`time`));switch(a){case`Timestamp`:i.Timestamp=!0;break;case`TemporalDate`:i.TemporalDate=!0;break;case`TemporalInstant`:i.TemporalInstant=!0;break;case`TemporalTime`:i.TemporalTime=!0}return{type:a,usedUtilityTypes:i}}function generateFieldType(e,t,n=!1){let r=getBaseType(e,t,n),i={...r.usedUtilityTypes},a=e.array===!0,o=e.required!==!0,c=s.has(r.type),l=r.type;return a&&(c||l.startsWith(`ObjectColumnType<`)?(l=`ArrayColumnType<${r.type}>`,i.ArrayColumnType=!0):l=e.type===`enum`?`(${r.type})[]`:`${r.type}[]`),o&&(l=`${l} | null`),e.serial&&(i.Serial=!0,l=`Serial<${l}>`),(e.hooks?.create||e.default!==void 0||e.optionalOnCreate===!0)&&(l=`Generated<${l}>`),{type:l,usedUtilityTypes:i}}function generateTableInterface(t,n,r){let i=Object.entries(n).filter(([e])=>e!==`id`).map(([e,t])=>({fieldName:e,...generateFieldType(t,r)})),a=[`id: Generated<string>;`,...i.map(e=>`${e.fieldName}: ${e.type};`)],o=i.reduce((e,t)=>mergeUsedUtilityTypes(e,t.usedUtilityTypes),emptyUsedUtilityTypes());return{typeDef:e`
|
|
11
13
|
${t}: {
|
|
12
14
|
${a.join(`
|
|
13
15
|
`)}
|
|
@@ -47,5 +49,5 @@ import{t as e}from"./multiline-EyzjEwn9.mjs";import{resolve as t}from"pathe";con
|
|
|
47
49
|
`].join(`
|
|
48
50
|
|
|
49
51
|
`)+`
|
|
50
|
-
`}const
|
|
51
|
-
//# sourceMappingURL=kysely-type-
|
|
52
|
+
`}const c=`@tailor-platform/kysely-type`,l=`./generated/tailordb.ts`;function kyselyTypePlugin(e){return{id:c,description:`Generates Kysely type definitions for TailorDB tables`,pluginConfig:e,async onTailorDBReady(e){let{distPath:n,pgliteSchemaPath:r,temporal:i}=e.pluginConfig;if(r&&t(n)===t(r))throw Error(`distPath and pgliteSchemaPath must resolve to different files.`);let a=[];for(let t of e.tailordb){let e=[];for(let n of Object.values(t.tables)){let t=await processKyselyType(n,i);e.push(t)}e.length!==0&&a.push({namespace:t.namespace,types:e})}let o=[];if(a.length>0){let t=generateUnifiedKyselyTypes(a,i);o.push({path:e.pluginConfig.distPath,content:t}),e.pluginConfig.pgliteSchemaPath&&o.push({path:e.pluginConfig.pgliteSchemaPath,content:generatePGliteSchemaModule(e.tailordb.filter(e=>Object.keys(e.tables).length>0))})}return{files:o}}}}export{processKyselyFields as a,dropUnresolvableReferences as c,generateUnifiedKyselyTypes as i,generatePgliteSchemaModule as l,c as n,s as o,kyselyTypePlugin as r,mapFieldTypeToColumnType as s,l as t,withoutReference as u};
|
|
53
|
+
//# sourceMappingURL=kysely-type-B0ri1-Xs.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kysely-type-B0ri1-Xs.mjs","names":["multiline","utf8","fieldType","name","hash","byte","value","suffix","tableName","memberName","kind","head","tag","body","base","field","pgType","label","CURRENT_TIME_EXPRESSIONS","currentTime","v","groups","format","conversion","fieldName","range","serial","SERIAL_CONVERSIONS","nextval","sequence","number","width","zeroPad","prefix","column","parts","hasDefault","filledOnCreate","key","here","path","child","CASTABLE_UNIQUE_TYPES","keys","member","indexed","table","reference","targetType","tables","type","target","targetField","sameType","check","_foreignKey","_type","_field","rest","byName","comparison","message","references","parentValue","notComparable","DELETED_ROWS","source","condition","remaining","event","transition","tableIdentifier","options","t","sequences","ownerships","columns","constraintReferences","r","constraint","inline","indexes","index","names","created","ordered","deferred","pending","statements","constraints","group","statement","entries","namespaces","namespace","temporal","COLUMN_TYPE_ALIASES","a","b","usedUtilityTypes","allowedValues","fieldConfig","fields","fieldResults","config","result","aggregatedUtilityTypes","acc","fieldTypes","obj","hasOptionalFields","hasGeneratedFields","nested","baseTypeResult","isArray","isNullable","isColumnTypeBase","finalType","fieldLines","parsedField","namespaceData","globalUsedUtilityTypes","ns","utilityTypeImports","types","line","KyselyGeneratorID","DEFAULT_KYSELY_TYPES_DIST_PATH","ctx","pgliteSchemaPath","resolve","distPath","allNamespaceData","typeMetadataList","metadata","files","content"],"sources":["../src/utils/tailordb-ddl.ts","../src/plugin/builtin/kysely-type/pglite-schema.ts","../src/utils/field-column-type.ts","../src/plugin/builtin/kysely-type/type-processor.ts","../src/plugin/builtin/kysely-type/index.ts"],"sourcesContent":["/**\n * PostgreSQL DDL derived from TailorDB table definitions, for creating the\n * tables a PGlite-backed test needs. The columns match the flat shape the\n * Kysely type generators emit, not TailorDB's storage layout.\n */\n\n/** The field shape the DDL generator reads; parsed and snapshot field configs are both assignable. */\nexport interface DDLFieldConfig {\n type: string;\n required?: boolean;\n array?: boolean;\n unique?: boolean;\n serial?: { start: number; maxValue?: number; format?: string };\n scale?: number;\n default?: unknown;\n optionalOnCreate?: boolean;\n foreignKey?: boolean;\n foreignKeyType?: string;\n foreignKeyField?: string;\n hooks?: { create?: unknown; update?: unknown };\n fields?: Record<string, DDLFieldConfig>;\n}\n\n/** A table to emit DDL for. */\nexport interface DDLTableConfig {\n name: string;\n fields: Record<string, DDLFieldConfig>;\n indexes?: Record<string, { fields: string[]; unique?: boolean }>;\n}\n\nconst MAX_IDENTIFIER_BYTES = 63;\n// The platform rounds decimals to their scale (6 unless configured); numeric\n// needs a precision to carry a scale, and the maximum leaves it unconstrained.\nconst DECIMAL_PRECISION = 1000;\nconst DEFAULT_DECIMAL_SCALE = 6;\nconst utf8 = new TextEncoder();\n\n/**\n * Map a TailorDB field type to the PostgreSQL column type PGlite tests use for it.\n * @param fieldType - TailorDB field type name\n * @returns The PostgreSQL type name\n * @throws If the type is not a TailorDB field type\n */\nexport function mapFieldTypeToPostgresType(fieldType: string): string {\n switch (fieldType) {\n case \"uuid\":\n return \"uuid\";\n case \"string\":\n case \"enum\":\n return \"text\";\n case \"boolean\":\n case \"bool\":\n return \"boolean\";\n case \"integer\":\n return \"integer\";\n case \"float\":\n return \"double precision\";\n case \"decimal\":\n return \"numeric\";\n case \"date\":\n return \"date\";\n case \"datetime\":\n return \"timestamptz\";\n case \"time\":\n return \"time\";\n case \"nested\":\n return \"jsonb\";\n default:\n throw new Error(`Field type \"${fieldType}\" has no PostgreSQL column type.`);\n }\n}\n\nfunction identifier(name: string): string {\n return `\"${name.replaceAll('\"', '\"\"')}\"`;\n}\n\nfunction fnv1aHex(value: string): string {\n let hash = 0x811c9dc5;\n for (const byte of utf8.encode(value)) {\n hash = Math.imul(hash ^ byte, 0x01000193) >>> 0;\n }\n return hash.toString(16).padStart(8, \"0\");\n}\n\ntype DerivedNameKind = \"seq\" | \"idx\" | \"nested_idx\" | \"fk\";\n\nfunction derivedName(tableName: string, memberName: string, kind: DerivedNameKind): string {\n const suffix = `_${fnv1aHex(JSON.stringify([tableName, memberName, kind]))}_${kind}`;\n let head = `${tableName}_${memberName}`;\n while (utf8.encode(head + suffix).length > MAX_IDENTIFIER_BYTES) head = head.slice(0, -1);\n return head + suffix;\n}\n\nfunction derivedIdentifier(tableName: string, memberName: string, kind: DerivedNameKind): string {\n return identifier(derivedName(tableName, memberName, kind));\n}\n\nfunction dollarQuoted(body: string): string {\n let tag = \"$fk$\";\n while (body.includes(tag)) tag = `${tag.slice(0, -1)}_$`;\n return `${tag}\\n${body}\\n${tag}`;\n}\n\nfunction stringLiteral(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`;\n}\n\nfunction columnType(field: DDLFieldConfig): string {\n const base =\n field.type === \"decimal\"\n ? `numeric(${DECIMAL_PRECISION}, ${field.scale ?? DEFAULT_DECIMAL_SCALE})`\n : mapFieldTypeToPostgresType(field.type);\n return field.array && field.type !== \"nested\" ? `${base}[]` : base;\n}\n\nfunction scalarLiteral(value: unknown, field: DDLFieldConfig, label: string): string {\n const pgType = mapFieldTypeToPostgresType(field.type);\n if (value instanceof Date) {\n if (Number.isNaN(value.getTime())) {\n throw new Error(`Default of field ${label} is an invalid Date.`);\n }\n return `${stringLiteral(value.toISOString())}::${pgType}`;\n }\n switch (typeof value) {\n case \"string\":\n return pgType === \"text\" ? stringLiteral(value) : `${stringLiteral(value)}::${pgType}`;\n case \"number\":\n if (!Number.isFinite(value)) {\n throw new Error(`Default of field ${label} is not a finite number.`);\n }\n return String(value);\n case \"boolean\":\n return value ? \"TRUE\" : \"FALSE\";\n default:\n throw new Error(`Default of field ${label} cannot be rendered as a SQL literal.`);\n }\n}\n\nconst CURRENT_TIME_EXPRESSIONS = new Map([\n [\"datetime\", \"now()\"],\n [\"date\", \"CURRENT_DATE\"],\n [\"time\", \"LOCALTIME\"],\n]);\n\nfunction defaultExpression(field: DDLFieldConfig, label: string): string {\n const value = field.default;\n const currentTime = CURRENT_TIME_EXPRESSIONS.get(field.type);\n if (value === \"now\" && currentTime !== undefined) {\n return currentTime;\n }\n if (field.array) {\n if (!Array.isArray(value)) {\n throw new Error(`Default of array field ${label} must be an array.`);\n }\n const pgType = columnType(field);\n if (value.length === 0) return `'{}'::${pgType}`;\n return `ARRAY[${value.map((v) => scalarLiteral(v, field, label)).join(\", \")}]::${pgType}`;\n }\n return scalarLiteral(value, field, label);\n}\n\ninterface SerialFormat {\n prefix: string;\n width: number;\n zeroPad: boolean;\n conversion: \"d\" | \"x\" | \"X\";\n suffix: string;\n}\n\n// printf-style with exactly one conversion specifier; octal has no Postgres\n// formatting function to stand in for it.\nfunction parseSerialFormat(format: string, label: string): SerialFormat {\n const match =\n /^(?<prefix>[^%]*)%(?<zero>0?)(?<width>\\d*)(?<conversion>[a-zA-Z])(?<suffix>[^%]*)$/.exec(\n format,\n );\n const groups = match?.groups;\n const conversion = groups?.conversion;\n if (!groups || (conversion !== \"d\" && conversion !== \"x\" && conversion !== \"X\")) {\n throw new Error(\n `Serial format \"${format}\" of field ${label} is not supported; use a single %d, %x, or %X specifier with an optional width (e.g. \"INV-%05d\").`,\n );\n }\n return {\n prefix: groups.prefix ?? \"\",\n zeroPad: groups.zero === \"0\",\n width: groups.width ? Number(groups.width) : 0,\n conversion,\n suffix: groups.suffix ?? \"\",\n };\n}\n\nfunction sequenceName(tableName: string, fieldName: string): string {\n return derivedIdentifier(tableName, fieldName, \"seq\");\n}\n\n// A sequence's minimum defaults to 1, which rejects a start of 0.\nfunction sequenceRange(serial: NonNullable<DDLFieldConfig[\"serial\"]>): string {\n const range = [`START WITH ${serial.start}`, `MINVALUE ${serial.start}`];\n if (serial.maxValue !== undefined) range.push(`MAXVALUE ${serial.maxValue}`);\n return range.join(\" \");\n}\n\nconst SERIAL_CONVERSIONS: Record<SerialFormat[\"conversion\"], (nextval: string) => string> = {\n d: (nextval) => nextval,\n x: (nextval) => `to_hex(${nextval})`,\n X: (nextval) => `upper(to_hex(${nextval}))`,\n};\n\nfunction serialStringDefault(sequence: string, format: string | undefined, label: string): string {\n const nextval = `nextval(${stringLiteral(sequence)})`;\n if (format === undefined) return `(${nextval}::text)`;\n const { prefix, width, zeroPad, conversion, suffix } = parseSerialFormat(format, label);\n const number = SERIAL_CONVERSIONS[conversion](nextval);\n let value = conversion === \"d\" ? `${number}::text` : number;\n if (width > 0) {\n value = `format('%${width}s', ${number})`;\n if (zeroPad) value = `translate(${value}, ' ', '0')`;\n }\n const parts = [\n ...(prefix ? [stringLiteral(prefix)] : []),\n value,\n ...(suffix ? [stringLiteral(suffix)] : []),\n ];\n return `(${parts.join(\" || \")})`;\n}\n\nfunction columnDefinition(tableName: string, fieldName: string, field: DDLFieldConfig): string {\n const column = identifier(fieldName);\n const label = `${identifier(tableName)}.${column}`;\n const parts = [column, columnType(field)];\n\n if (field.serial) {\n if (field.type === \"integer\") {\n parts.push(`GENERATED BY DEFAULT AS IDENTITY (${sequenceRange(field.serial)})`);\n if (field.unique) parts.push(\"UNIQUE\");\n return parts.join(\" \");\n }\n if (field.required) parts.push(\"NOT NULL\");\n if (field.unique) parts.push(\"UNIQUE\");\n parts.push(\n `DEFAULT ${serialStringDefault(sequenceName(tableName, fieldName), field.serial.format, label)}`,\n );\n return parts.join(\" \");\n }\n\n const hasDefault = field.default !== undefined;\n const filledOnCreate = field.hooks?.create !== undefined || field.optionalOnCreate === true;\n if (field.required && (hasDefault || !filledOnCreate)) parts.push(\"NOT NULL\");\n if (field.unique) parts.push(\"UNIQUE\");\n if (hasDefault) parts.push(`DEFAULT ${defaultExpression(field, label)}`);\n return parts.join(\" \");\n}\n\ninterface Reference {\n /** Column holding the reference */\n column: string;\n /** JSONPath from the column value to each referencing value; `$` for a scalar column */\n path: string;\n table: string;\n field: string;\n /** TailorDB type of the referencing value */\n type: string;\n}\n\nfunction jsonPathKey(key: string): string {\n return `\"${key.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll('\"', '\\\\\"')}\"`;\n}\n\nfunction referencesWithin(column: string, field: DDLFieldConfig, path: string): Reference[] {\n const here = field.array ? `${path}[*]` : path;\n if (field.type === \"nested\") {\n return Object.entries(field.fields ?? {}).flatMap(([key, child]) =>\n referencesWithin(column, child, `${here}.${jsonPathKey(key)}`),\n );\n }\n if (!field.foreignKey || field.foreignKeyType === undefined) return [];\n return [\n {\n column,\n path: here,\n table: field.foreignKeyType,\n field: field.foreignKeyField ?? \"id\",\n type: field.type,\n },\n ];\n}\n\n// The platform indexes a unique member of a nested object by the value at its\n// path, cast to the member's type. Members inside an array have no single value\n// to index, so they are left out.\nconst CASTABLE_UNIQUE_TYPES = new Set([\"integer\", \"float\", \"decimal\", \"boolean\", \"bool\", \"uuid\"]);\n\ninterface NestedUniqueMember {\n column: string;\n path: string[];\n field: DDLFieldConfig;\n}\n\nfunction nestedUniqueMembers(\n column: string,\n field: DDLFieldConfig,\n path: string[],\n): NestedUniqueMember[] {\n if (field.array) return [];\n if (field.type === \"nested\") {\n return Object.entries(field.fields ?? {}).flatMap(([key, child]) =>\n nestedUniqueMembers(column, child, [...path, key]),\n );\n }\n return field.unique && path.length > 0 ? [{ column, path, field }] : [];\n}\n\nfunction nestedUniqueIndex(tableName: string, member: NestedUniqueMember): string {\n const keys = member.path.map(stringLiteral).join(\", \");\n const value = `${identifier(member.column)} #>> ARRAY[${keys}]`;\n const indexed = CASTABLE_UNIQUE_TYPES.has(member.field.type)\n ? `CAST(${value} AS ${mapFieldTypeToPostgresType(member.field.type)})`\n : value;\n const name = derivedIdentifier(\n tableName,\n `${member.column}.${member.path.join(\".\")}`,\n \"nested_idx\",\n );\n return `CREATE UNIQUE INDEX IF NOT EXISTS ${name} ON ${identifier(tableName)} ((${indexed}))`;\n}\n\nfunction tableReferences(table: DDLTableConfig): Reference[] {\n return Object.entries(table.fields)\n .filter(([fieldName]) => fieldName !== \"id\")\n .flatMap(([fieldName, field]) => referencesWithin(fieldName, field, \"$\"));\n}\n\n// Postgres cannot reference from an array or jsonb column, nor from a column\n// whose type differs from the referenced one (a string field related to id),\n// so only a plain column of the same storage type becomes a FOREIGN KEY constraint.\nfunction isConstraintReference(\n reference: Reference,\n tables: ReadonlyMap<string, DDLTableConfig>,\n): boolean {\n if (reference.path !== \"$\") return false;\n const targetType =\n reference.field === \"id\" ? \"uuid\" : tables.get(reference.table)?.fields[reference.field]?.type;\n return (\n targetType === undefined ||\n mapFieldTypeToPostgresType(targetType) === mapFieldTypeToPostgresType(reference.type)\n );\n}\n\nfunction referenceClause(reference: Reference): string {\n return `REFERENCES ${identifier(reference.table)} (${identifier(reference.field)})`;\n}\n\nfunction declaredType(type: string): string {\n return type === \"bool\" ? \"boolean\" : type;\n}\n\ntype ReferenceCheck = { pgType: string } | { problem: string };\n\nfunction checkReference(\n reference: Reference,\n tables: ReadonlyMap<string, DDLTableConfig>,\n): ReferenceCheck {\n const target = tables.get(reference.table);\n if (!target) return { problem: `references unknown table \"${reference.table}\".` };\n const targetField =\n reference.field === \"id\" ? { type: \"uuid\", unique: true } : target.fields[reference.field];\n if (!targetField) {\n return {\n problem: `references unknown field \"${reference.field}\" of table \"${reference.table}\".`,\n };\n }\n const sameType =\n reference.field === \"id\" || declaredType(targetField.type) === declaredType(reference.type);\n if (!targetField.unique || !sameType) {\n return {\n problem: `references \"${reference.table}\".\"${reference.field}\", which must be unique and of the same type as the referencing field.`,\n };\n }\n return { pgType: mapFieldTypeToPostgresType(targetField.type) };\n}\n\nfunction referencedColumnType(\n reference: Reference,\n tables: ReadonlyMap<string, DDLTableConfig>,\n label: string,\n): string {\n const check = checkReference(reference, tables);\n if (\"problem\" in check) throw new Error(`Field ${label} ${check.problem}`);\n return check.pgType;\n}\n\n/**\n * The field without the relation it declares.\n * @param field - A field config\n * @returns The field with its foreign key settings removed\n */\nexport function withoutReference(field: DDLFieldConfig): DDLFieldConfig {\n const {\n foreignKey: _foreignKey,\n foreignKeyType: _type,\n foreignKeyField: _field,\n ...rest\n } = field;\n return rest;\n}\n\nfunction withoutUnresolvableReference(\n field: DDLFieldConfig,\n tables: ReadonlyMap<string, DDLTableConfig>,\n): DDLFieldConfig {\n if (field.fields) {\n return {\n ...field,\n fields: Object.fromEntries(\n Object.entries(field.fields).map(([name, child]) => [\n name,\n withoutUnresolvableReference(child, tables),\n ]),\n ),\n };\n }\n if (!field.foreignKey || field.foreignKeyType === undefined) return field;\n const reference = {\n column: \"\",\n path: \"$\",\n table: field.foreignKeyType,\n field: field.foreignKeyField ?? \"id\",\n type: field.type,\n };\n return \"problem\" in checkReference(reference, tables) ? withoutReference(field) : field;\n}\n\n/**\n * Remove the references the given tables cannot satisfy: a target table or\n * field that is missing, not unique, or of another type than the referencing\n * field. {@link generateSchemaDDL} rejects such references, so this lets a\n * schema that is only partly consistent still render, minus those references.\n * @param tables - Tables of one schema\n * @returns The tables, with unsatisfiable references removed from their fields\n */\nexport function dropUnresolvableReferences(tables: readonly DDLTableConfig[]): DDLTableConfig[] {\n const byName = new Map(tables.map((table) => [table.name, table]));\n return tables.map((table) => ({\n ...table,\n fields: Object.fromEntries(\n Object.entries(table.fields).map(([name, field]) => [\n name,\n withoutUnresolvableReference(field, byName),\n ]),\n ),\n }));\n}\n\nfunction referenceCheck(\n reference: Reference,\n tables: ReadonlyMap<string, DDLTableConfig>,\n label: string,\n): string {\n const pgType = referencedColumnType(reference, tables, label);\n const comparison =\n pgType === mapFieldTypeToPostgresType(reference.type)\n ? `parent.${identifier(reference.field)} = (fk_check.v #>> '{}')::${pgType}`\n : `parent.${identifier(reference.field)}::text = (fk_check.v #>> '{}')`;\n const target = `${identifier(reference.table)}.${identifier(reference.field)}`;\n const message = `violates foreign key constraints: % not found in ${target.replaceAll(\"%\", \"%%\")}`;\n return [\n ` FOR v IN SELECT jsonb_path_query(to_jsonb(NEW.${identifier(reference.column)}), ${stringLiteral(reference.path)}) LOOP`,\n ` IF jsonb_typeof(fk_check.v) <> 'null' AND NOT EXISTS (SELECT 1 FROM ${identifier(reference.table)} AS parent WHERE ${comparison}) THEN`,\n ` RAISE EXCEPTION ${stringLiteral(message)}, fk_check.v #>> '{}' USING ERRCODE = 'foreign_key_violation';`,\n \" END IF;\",\n \" END LOOP;\",\n ].join(\"\\n\");\n}\n\nfunction referenceTrigger(\n table: DDLTableConfig,\n references: readonly Reference[],\n tables: ReadonlyMap<string, DDLTableConfig>,\n): string[] {\n if (references.length === 0) return [];\n const name = derivedIdentifier(table.name, \"references\", \"fk\");\n const checks = references.map((reference) =>\n referenceCheck(reference, tables, `${table.name}.${reference.column}`),\n );\n const body = [\n \"<<fk_check>>\",\n \"DECLARE v jsonb;\",\n \"BEGIN\",\n ...checks,\n \" RETURN NULL;\",\n \"END\",\n ].join(\"\\n\");\n return [\n `CREATE OR REPLACE FUNCTION ${name}() RETURNS trigger LANGUAGE plpgsql AS ${dollarQuoted(body)}`,\n `CREATE OR REPLACE TRIGGER ${name} AFTER INSERT OR UPDATE ON ${identifier(table.name)} FOR EACH ROW EXECUTE FUNCTION ${name}()`,\n ];\n}\n\ninterface IncomingReference extends Reference {\n /** Table whose array or nested column holds the reference */\n child: string;\n pgType: string;\n}\n\nfunction incomingReferences(\n table: DDLTableConfig,\n tables: ReadonlyMap<string, DDLTableConfig>,\n): IncomingReference[] {\n return [...tables.values()].flatMap((child) =>\n tableReferences(child)\n .filter(\n (reference) => !isConstraintReference(reference, tables) && reference.table === table.name,\n )\n .flatMap((reference) => {\n const check = checkReference(reference, tables);\n return \"pgType\" in check ? [{ ...reference, child: child.name, pgType: check.pgType }] : [];\n }),\n );\n}\n\nfunction holdsParent(reference: IncomingReference): string {\n const column = `child.${identifier(reference.column)}`;\n const parentValue = `OLD.${identifier(reference.field)}`;\n const sameType = reference.pgType === mapFieldTypeToPostgresType(reference.type);\n if (sameType && reference.path === \"$[*]\") return `${parentValue} = ANY(${column})`;\n const comparison = sameType\n ? `(held.v #>> '{}')::${reference.pgType} = ${parentValue}`\n : `(held.v #>> '{}') = ${parentValue}::text`;\n const notComparable = sameType\n ? `WHEN NOT pg_input_is_valid(held.v #>> '{}', ${stringLiteral(reference.pgType)}) THEN false `\n : \"\";\n return `EXISTS (SELECT 1 FROM jsonb_path_query(to_jsonb(${column}), ${stringLiteral(reference.path)}) AS held(v) WHERE CASE WHEN jsonb_typeof(held.v) = 'null' THEN false ${notComparable}ELSE ${comparison} END)`;\n}\n\nconst DELETED_ROWS = \"old_rows\";\n\nfunction holds(reference: IncomingReference, source: string): string {\n return `EXISTS (SELECT 1 FROM ${source} AS child WHERE ${holdsParent(reference)})`;\n}\n\nfunction refuseWhen(\n table: DDLTableConfig,\n reference: IncomingReference,\n condition: string,\n): string {\n const message = `update or delete on table \\`${table.name}\\` violates foreign key constraint: some record is still referenced from table \\`${reference.child}\\``;\n return [\n ` IF ${condition} THEN`,\n ` RAISE EXCEPTION ${stringLiteral(message.replaceAll(\"%\", \"%%\"))} USING ERRCODE = 'foreign_key_violation';`,\n \" END IF;\",\n ].join(\"\\n\");\n}\n\nfunction referencedDeleteCheck(table: DDLTableConfig, reference: IncomingReference): string {\n const remaining = holds(reference, identifier(reference.child));\n const condition =\n reference.child === table.name\n ? `${remaining} OR ${holds(reference, DELETED_ROWS)}`\n : remaining;\n return refuseWhen(table, reference, condition);\n}\n\nfunction referencedUpdateCheck(table: DDLTableConfig, reference: IncomingReference): string {\n const field = identifier(reference.field);\n return refuseWhen(\n table,\n reference,\n `NEW.${field} IS DISTINCT FROM OLD.${field} AND ${holds(reference, identifier(reference.child))}`,\n );\n}\n\nfunction referencedTrigger(\n table: DDLTableConfig,\n tables: ReadonlyMap<string, DDLTableConfig>,\n): string[] {\n const references = incomingReferences(table, tables);\n if (references.length === 0) return [];\n const selfReferencing = references.some((reference) => reference.child === table.name);\n const deletedRows = selfReferencing ? ` REFERENCING OLD TABLE AS ${DELETED_ROWS}` : \"\";\n return (\n [\n [\"referenced_delete\", \"DELETE\", deletedRows, referencedDeleteCheck],\n [\"referenced_update\", \"UPDATE\", \"\", referencedUpdateCheck],\n ] as const\n ).flatMap(([member, event, transition, check]) => {\n const name = derivedIdentifier(table.name, member, \"fk\");\n const body = [\n \"BEGIN\",\n ...references.map((reference) => check(table, reference)),\n \" RETURN NULL;\",\n \"END\",\n ].join(\"\\n\");\n return [\n `CREATE OR REPLACE FUNCTION ${name}() RETURNS trigger LANGUAGE plpgsql AS ${dollarQuoted(body)}`,\n `CREATE OR REPLACE TRIGGER ${name} AFTER ${event} ON ${identifier(table.name)}${transition} FOR EACH ROW EXECUTE FUNCTION ${name}()`,\n ];\n });\n}\n\n/** What {@link generateTableDDL} needs to know about the other tables of the schema. */\nexport interface TableDDLOptions {\n /** Every table of the schema, to resolve the types referenced columns point at */\n tables?: readonly DDLTableConfig[];\n /** Columns whose FOREIGN KEY is added after all tables exist, because the target is created later */\n deferredReferences?: ReadonlySet<string>;\n}\n\n/**\n * DDL statements that create one table: any sequences its string serial\n * fields draw from, the table, the sequences' ownership of their columns,\n * its unique indexes, then the triggers that enforce the references Postgres\n * cannot express as a FOREIGN KEY (inside array and nested columns): one\n * checking the references the table holds, one refusing to delete a row, and\n * one refusing to change the key of a row, that another table's array or\n * nested value still points at. Every statement\n * is `IF NOT EXISTS` or otherwise idempotent, so re-applying the script on a\n * database that already has the table is a no-op. Owning a sequence makes\n * `DROP TABLE` drop it and `TRUNCATE ... RESTART IDENTITY` reset it to the\n * configured start. Index names end in `_idx` so they cannot take the\n * `<table>_<column>_key` name Postgres gives a UNIQUE column, which\n * `IF NOT EXISTS` would otherwise silently skip.\n * @param table - Table name, fields, and indexes\n * @param options - The schema's other tables, and references to leave to later statements\n * @returns Statements in execution order, without trailing semicolons\n * @throws If a field type, default, or serial format cannot be expressed\n */\nexport function generateTableDDL(table: DDLTableConfig, options: TableDDLOptions = {}): string[] {\n const tableIdentifier = identifier(table.name);\n const tables = new Map((options.tables ?? [table]).map((t) => [t.name, t]));\n const sequences: string[] = [];\n const ownerships: string[] = [];\n const columns = [` \"id\" uuid PRIMARY KEY DEFAULT gen_random_uuid()`];\n const references = tableReferences(table);\n const constraintReferences = new Map(\n references.filter((r) => isConstraintReference(r, tables)).map((r) => [r.column, r]),\n );\n\n for (const [fieldName, field] of Object.entries(table.fields)) {\n if (fieldName === \"id\") continue;\n if (field.serial && field.type !== \"integer\") {\n const sequence = sequenceName(table.name, fieldName);\n sequences.push(`CREATE SEQUENCE IF NOT EXISTS ${sequence} ${sequenceRange(field.serial)}`);\n ownerships.push(\n `ALTER SEQUENCE ${sequence} OWNED BY ${tableIdentifier}.${identifier(fieldName)}`,\n );\n }\n const constraint = constraintReferences.get(fieldName);\n const inline =\n constraint && !options.deferredReferences?.has(fieldName)\n ? ` ${referenceClause(constraint)}`\n : \"\";\n columns.push(` ${columnDefinition(table.name, fieldName, field)}${inline}`);\n }\n\n const indexes = [\n ...Object.entries(table.indexes ?? {})\n .filter(([, index]) => index.unique)\n .map(\n ([name, index]) =>\n `CREATE UNIQUE INDEX IF NOT EXISTS ${derivedIdentifier(table.name, name, \"idx\")} ON ${tableIdentifier} (${index.fields.map(identifier).join(\", \")})`,\n ),\n ...Object.entries(table.fields)\n .filter(([fieldName]) => fieldName !== \"id\")\n .flatMap(([fieldName, field]) => nestedUniqueMembers(fieldName, field, []))\n .map((member) => nestedUniqueIndex(table.name, member)),\n ];\n\n for (const reference of constraintReferences.values()) {\n referencedColumnType(reference, tables, `${table.name}.${reference.column}`);\n }\n\n return [\n ...sequences,\n `CREATE TABLE IF NOT EXISTS ${tableIdentifier} (\\n${columns.join(\",\\n\")}\\n)`,\n ...ownerships,\n ...indexes,\n ...referenceTrigger(\n table,\n references.filter((r) => !isConstraintReference(r, tables)),\n tables,\n ),\n ...referencedTrigger(table, tables),\n ];\n}\n\nfunction addForeignKey(table: DDLTableConfig, reference: Reference): string {\n const name = derivedName(table.name, reference.column, \"fk\");\n const tableIdentifier = identifier(table.name);\n const body = [\n \"BEGIN\",\n `IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = ${stringLiteral(name)} AND conrelid = ${stringLiteral(tableIdentifier)}::regclass) THEN`,\n `ALTER TABLE ${tableIdentifier} ADD CONSTRAINT ${identifier(name)} FOREIGN KEY (${identifier(reference.column)}) ${referenceClause(reference)};`,\n \"END IF;\",\n \"END\",\n ].join(\"\\n\");\n return `DO ${dollarQuoted(body)}`;\n}\n\n// Tables come after the tables they reference. Where references form a cycle,\n// the first table of the cycle is created without the constraint that points\n// at a table not yet created, and the constraint is added once all tables exist.\nfunction planCreation(tables: readonly DDLTableConfig[]): {\n ordered: DDLTableConfig[];\n deferred: Map<DDLTableConfig, Reference[]>;\n} {\n const names = new Set(tables.map((table) => table.name));\n const byName = new Map(tables.map((table) => [table.name, table]));\n const created = new Set<string>();\n const remaining = [...tables];\n const ordered: DDLTableConfig[] = [];\n const deferred = new Map<DDLTableConfig, Reference[]>();\n const pendingOf = (table: DDLTableConfig) =>\n tableReferences(table)\n .filter((r) => isConstraintReference(r, byName))\n .filter((r) => names.has(r.table) && r.table !== table.name && !created.has(r.table));\n while (remaining.length > 0) {\n const index = remaining.findIndex((table) => pendingOf(table).length === 0);\n const [table] = remaining.splice(Math.max(index, 0), 1) as [DDLTableConfig];\n const pending = pendingOf(table);\n if (pending.length > 0) deferred.set(table, pending);\n created.add(table.name);\n ordered.push(table);\n }\n return { ordered, deferred };\n}\n\n/**\n * A single SQL script creating every given table, for `pglite.exec()`. Tables\n * are created after the tables they reference.\n * @param tables - Tables to create\n * @returns The script, empty when there are no tables\n * @throws If a field references a table or field that is not among the tables\n */\nexport function generateSchemaDDL(tables: readonly DDLTableConfig[]): string {\n const { ordered, deferred } = planCreation(tables);\n const statements = ordered.map((table) =>\n generateTableDDL(table, {\n tables,\n deferredReferences: new Set(deferred.get(table)?.map((r) => r.column)),\n }),\n );\n const constraints = ordered.flatMap((table) =>\n (deferred.get(table) ?? []).map((reference) => addForeignKey(table, reference)),\n );\n return [...statements, constraints]\n .filter((group) => group.length > 0)\n .map((group) => group.map((statement) => `${statement};`).join(\"\\n\"))\n .join(\"\\n\\n\");\n}\n\n/** One namespace's tables, as the schema module groups them. */\nexport interface PgliteSchemaNamespace {\n namespace: string;\n tables: readonly DDLTableConfig[];\n}\n\n/** Options for {@link generatePgliteSchemaModule}. */\nexport interface PgliteSchemaModuleOptions {\n /** Named in the generated header as the producer users must not edit around. */\n generatedBy: string;\n}\n\n// A template literal keeps line feeds but folds a carriage return into one.\nfunction templateLiteral(value: string): string {\n const escaped = value\n .replaceAll(\"\\\\\", \"\\\\\\\\\")\n .replaceAll(\"`\", \"\\\\`\")\n .replaceAll(\"${\", \"\\\\${\")\n .replaceAll(\"\\r\", \"\\\\r\");\n return `\\`${escaped}\\``;\n}\n\n/**\n * Render the module that exports each namespace's `CREATE TABLE` script for\n * `pglite.exec()`.\n * @param namespaces - Namespaces with the tables to create\n * @param options - Header wording\n * @returns TypeScript source of the schema module\n */\nexport function generatePgliteSchemaModule(\n namespaces: readonly PgliteSchemaNamespace[],\n options: PgliteSchemaModuleOptions,\n): string {\n const entries = namespaces.map(\n ({ namespace, tables }) =>\n ` ${JSON.stringify(namespace)}: ${templateLiteral(generateSchemaDDL(tables))},`,\n );\n return [\n \"/**\",\n \" * Auto-generated PGlite schema for TailorDB tables.\",\n \" * Create a namespace's tables in a test with `pglite.exec(pgliteSchema[namespace])`.\",\n \" *\",\n ` * DO NOT EDIT - This file is auto-generated by ${options.generatedBy}.`,\n \" */\",\n \"\",\n \"export const pgliteSchema = {\",\n ...entries,\n \"} as const;\",\n \"\",\n ].join(\"\\n\");\n}\n","import { generatePgliteSchemaModule, type DDLTableConfig } from \"#/utils/tailordb-ddl\";\nimport type { TailorDBType } from \"#/parser/service/tailordb/types\";\n\n/** Tables of one namespace, as the schema module groups them. */\nexport interface PGliteSchemaNamespace {\n namespace: string;\n tables: Record<string, TailorDBType>;\n}\n\n/**\n * Reduce parsed tables to what the DDL generator reads.\n * @param tables - Parsed TailorDB tables keyed by name\n * @returns DDL table configs in the same order\n */\nexport function toDDLTables(tables: Record<string, TailorDBType>): DDLTableConfig[] {\n return Object.values(tables).map((type) => ({\n name: type.name,\n fields: Object.fromEntries(\n Object.entries(type.fields).map(([fieldName, field]) => [fieldName, field.config]),\n ),\n indexes: type.indexes,\n }));\n}\n\n/**\n * Render the module that exports each namespace's `CREATE TABLE` script for\n * `pglite.exec()`.\n * @param namespaces - Namespaces with their parsed tables\n * @returns TypeScript source of the schema module\n */\nexport function generatePGliteSchemaModule(namespaces: readonly PGliteSchemaNamespace[]): string {\n return generatePgliteSchemaModule(\n namespaces.map(({ namespace, tables }) => ({ namespace, tables: toDDLTables(tables) })),\n { generatedBy: \"the kysely-type plugin\" },\n );\n}\n","/** The Kysely column type a TailorDB field maps to, before array/null modifiers. */\nexport type FieldColumnType =\n | \"string\"\n | \"number\"\n | \"boolean\"\n | \"Timestamp\"\n | \"TemporalDate\"\n | \"TemporalInstant\"\n | \"TemporalTime\";\n\n/**\n * Map a scalar TailorDB field type to the column type generated code uses for it.\n *\n * With `temporal: false` (the default), `date`/`datetime` resolve to `Timestamp` and\n * `time` to `string`, because that's what the function runtime hands back for them by\n * default. With `temporal: true`, `date`/`datetime`/`time` resolve to their\n * `Temporal.PlainDate`/`Temporal.Instant`/`Temporal.PlainTime` counterparts instead,\n * matching a `getDB` created with `createGetDB({ temporal: true })`.\n *\n * `enum` and `nested` carry their own shape, so each generator resolves them\n * before reaching here; passing either is a caller bug rather than a `string`\n * column.\n * @param fieldType - TailorDB scalar field type name\n * @param temporal - Whether to map date/datetime/time fields to their Temporal column\n * types instead of their `Date`/`string` defaults\n * @returns The column type for the field, defaulting to `string`\n * @throws If given `enum` or `nested`\n */\nexport function mapFieldTypeToColumnType(fieldType: string, temporal = false): FieldColumnType {\n switch (fieldType) {\n case \"uuid\":\n case \"string\":\n case \"decimal\":\n return \"string\";\n case \"integer\":\n case \"float\":\n return \"number\";\n case \"date\":\n return temporal ? \"TemporalDate\" : \"Timestamp\";\n case \"datetime\":\n return temporal ? \"TemporalInstant\" : \"Timestamp\";\n case \"time\":\n return temporal ? \"TemporalTime\" : \"string\";\n case \"bool\":\n case \"boolean\":\n return \"boolean\";\n case \"enum\":\n case \"nested\":\n throw new Error(\n `Field type \"${fieldType}\" has no scalar column type; resolve it before mapping.`,\n );\n default:\n return \"string\";\n }\n}\n\n/** The select and write types a `ColumnType`-shaped alias expands to. */\nexport type ColumnTypeAliasExpansion = {\n /** Type the alias reads back as. */\n readonly select: string;\n /** Type the alias accepts on insert and update. */\n readonly write: string;\n};\n\n/**\n * Column types whose alias expands to a `ColumnType`, mapped to that expansion.\n *\n * Kysely only unwraps a `ColumnType` at the top level of a table property, so an\n * array of one of these stays wrapped in `ArrayColumnType<...>` rather than taking\n * a `[]` suffix, which would nest the `ColumnType` out of Kysely's reach. Where a\n * generator has to spell out the slots itself, it reads the expansion from here\n * rather than inlining the alias, which would nest just the same.\n *\n * Both type generators track alias usage per alias to decide which declarations to\n * emit, so adding an entry here also means teaching them to report the new alias.\n */\nexport const COLUMN_TYPE_ALIASES: ReadonlyMap<string, ColumnTypeAliasExpansion> = new Map<\n FieldColumnType,\n ColumnTypeAliasExpansion\n>([\n [\"Timestamp\", { select: \"Date\", write: \"Date | string\" }],\n [\"TemporalDate\", { select: \"Temporal.PlainDate\", write: \"Temporal.PlainDate | string\" }],\n [\"TemporalInstant\", { select: \"Temporal.Instant\", write: \"Temporal.Instant | string\" }],\n [\"TemporalTime\", { select: \"Temporal.PlainTime\", write: \"Temporal.PlainTime | string\" }],\n]);\n","import { COLUMN_TYPE_ALIASES, mapFieldTypeToColumnType } from \"#/utils/field-column-type\";\nimport multiline from \"#/utils/multiline\";\nimport {\n type KyselyFieldConfig,\n type KyselyNamespaceMetadata,\n type KyselyTypeMetadata,\n type UsedUtilityTypes,\n} from \"./types\";\nimport type { TailorDBType } from \"#/parser/service/tailordb/types\";\n\ntype FieldTypeResult = {\n type: string;\n usedUtilityTypes: UsedUtilityTypes;\n};\n\nfunction emptyUsedUtilityTypes(): UsedUtilityTypes {\n return {\n Timestamp: false,\n TemporalDate: false,\n TemporalInstant: false,\n TemporalTime: false,\n Serial: false,\n ObjectColumnType: false,\n ArrayColumnType: false,\n };\n}\n\nfunction mergeUsedUtilityTypes(a: UsedUtilityTypes, b: UsedUtilityTypes): UsedUtilityTypes {\n return {\n Timestamp: a.Timestamp || b.Timestamp,\n TemporalDate: a.TemporalDate || b.TemporalDate,\n TemporalInstant: a.TemporalInstant || b.TemporalInstant,\n TemporalTime: a.TemporalTime || b.TemporalTime,\n Serial: a.Serial || b.Serial,\n ObjectColumnType: a.ObjectColumnType || b.ObjectColumnType,\n ArrayColumnType: a.ArrayColumnType || b.ArrayColumnType,\n };\n}\n\n/**\n * Whether a utility-type usage record uses any `ColumnType`-shaped alias.\n * @param usedUtilityTypes - Utility-type usage record to check\n * @returns Whether any `ColumnType`-shaped alias is used\n */\nfunction usesColumnTypeAlias(usedUtilityTypes: UsedUtilityTypes): boolean {\n return (\n usedUtilityTypes.Timestamp ||\n usedUtilityTypes.TemporalDate ||\n usedUtilityTypes.TemporalInstant ||\n usedUtilityTypes.TemporalTime\n );\n}\n\n/**\n * Get the enum type definition.\n * @param fieldConfig - The field configuration\n * @returns The enum type as a string union\n */\nfunction getEnumType(fieldConfig: KyselyFieldConfig): string {\n const allowedValues = fieldConfig.allowedValues;\n\n if (allowedValues && Array.isArray(allowedValues)) {\n return allowedValues\n .map((v: string | { value: string }) => {\n const value = typeof v === \"string\" ? v : v.value;\n return `\"${value}\"`;\n })\n .join(\" | \");\n }\n return \"string\";\n}\n\n/**\n * Get the nested object type definition.\n * @param fieldConfig - The field configuration\n * @param temporal - Whether date/datetime/time fields resolve to their Temporal column\n * types instead of their `Date`/`string` defaults\n * @returns The nested type with used utility types\n */\nfunction getNestedType(fieldConfig: KyselyFieldConfig, temporal: boolean): FieldTypeResult {\n const fields = fieldConfig.fields;\n if (!fields || typeof fields !== \"object\") {\n return {\n type: \"string\",\n usedUtilityTypes: emptyUsedUtilityTypes(),\n };\n }\n\n const fieldResults = Object.entries(fields).map(([fieldName, config]) => {\n const result = generateFieldType(config, temporal, true);\n const optional = config.required !== true ? \"?\" : \"\";\n return {\n fieldType: `${fieldName}${optional}: ${result.type}`,\n usedUtilityTypes: result.usedUtilityTypes,\n };\n });\n\n const aggregatedUtilityTypes = fieldResults.reduce(\n (acc, result) => mergeUsedUtilityTypes(acc, result.usedUtilityTypes),\n emptyUsedUtilityTypes(),\n );\n\n const fieldTypes = fieldResults.map((r) => r.fieldType);\n const obj = `{\\n ${fieldTypes.join(\";\\n \")}${fieldTypes.length > 0 ? \";\" : \"\"}\\n}`;\n\n const hasOptionalFields = Object.values(fields).some((config) => config.required !== true);\n const hasGeneratedFields = Object.values(fields).some(\n (config) =>\n config.hooks?.create || config.default !== undefined || config.optionalOnCreate === true,\n );\n if (usesColumnTypeAlias(aggregatedUtilityTypes) || hasOptionalFields || hasGeneratedFields) {\n return {\n type: `ObjectColumnType<${obj}>`,\n usedUtilityTypes: { ...aggregatedUtilityTypes, ObjectColumnType: true },\n };\n }\n return { type: obj, usedUtilityTypes: aggregatedUtilityTypes };\n}\n\n/**\n * Get the base Kysely type for a field (without array/null modifiers).\n * @param fieldConfig - The field configuration\n * @param temporal - Whether date/datetime/time fields resolve to their Temporal column\n * types instead of their `Date`/`string` defaults\n * @param nested - Whether the field is inside an object\n * @returns The base type with used utility types\n */\nfunction getBaseType(\n fieldConfig: KyselyFieldConfig,\n temporal: boolean,\n nested: boolean,\n): FieldTypeResult {\n const fieldType = fieldConfig.type;\n const usedUtilityTypes = emptyUsedUtilityTypes();\n\n if (fieldType === \"enum\") {\n return { type: getEnumType(fieldConfig), usedUtilityTypes };\n }\n if (fieldType === \"nested\") {\n return getNestedType(fieldConfig, temporal);\n }\n\n const type = mapFieldTypeToColumnType(fieldType, temporal && !(nested && fieldType === \"time\"));\n switch (type) {\n case \"Timestamp\":\n usedUtilityTypes.Timestamp = true;\n break;\n case \"TemporalDate\":\n usedUtilityTypes.TemporalDate = true;\n break;\n case \"TemporalInstant\":\n usedUtilityTypes.TemporalInstant = true;\n break;\n case \"TemporalTime\":\n usedUtilityTypes.TemporalTime = true;\n break;\n case \"string\":\n case \"number\":\n case \"boolean\":\n break;\n }\n\n return { type, usedUtilityTypes };\n}\n\n/**\n * Generate the complete field type including array and null modifiers.\n * @param fieldConfig - The field configuration\n * @param temporal - Whether date/datetime/time fields resolve to their Temporal column\n * types instead of their `Date`/`string` defaults\n * @param nested - Whether the field is inside an object\n * @returns The complete field type with used utility types\n */\nfunction generateFieldType(\n fieldConfig: KyselyFieldConfig,\n temporal: boolean,\n nested = false,\n): FieldTypeResult {\n const baseTypeResult = getBaseType(fieldConfig, temporal, nested);\n const usedUtilityTypes = { ...baseTypeResult.usedUtilityTypes };\n\n const isArray = fieldConfig.array === true;\n const isNullable = fieldConfig.required !== true;\n\n // A ColumnType-shaped alias and ObjectColumnType cannot be wrapped with [] for\n // arrays, because Kysely only resolves ColumnType at the top-level table\n // property. Use ArrayColumnType to keep the ColumnType at the top level.\n const isColumnTypeBase = COLUMN_TYPE_ALIASES.has(baseTypeResult.type);\n\n let finalType = baseTypeResult.type;\n if (isArray) {\n if (isColumnTypeBase || finalType.startsWith(\"ObjectColumnType<\")) {\n finalType = `ArrayColumnType<${baseTypeResult.type}>`;\n usedUtilityTypes.ArrayColumnType = true;\n } else {\n const needsParens = fieldConfig.type === \"enum\";\n finalType = needsParens ? `(${baseTypeResult.type})[]` : `${baseTypeResult.type}[]`;\n }\n }\n if (isNullable) {\n finalType = `${finalType} | null`;\n }\n\n if (fieldConfig.serial) {\n usedUtilityTypes.Serial = true;\n finalType = `Serial<${finalType}>`;\n }\n if (\n fieldConfig.hooks?.create ||\n fieldConfig.default !== undefined ||\n fieldConfig.optionalOnCreate === true\n ) {\n finalType = `Generated<${finalType}>`;\n }\n\n return { type: finalType, usedUtilityTypes };\n}\n\n/**\n * Generate the table interface.\n * @param name - Table name\n * @param fields - Field configurations keyed by field name\n * @param temporal - Whether date/datetime/time fields resolve to their Temporal column\n * types instead of their `Date`/`string` defaults\n * @returns The type definition and used utility types\n */\nfunction generateTableInterface(\n name: string,\n fields: Record<string, KyselyFieldConfig>,\n temporal: boolean,\n): {\n typeDef: string;\n usedUtilityTypes: UsedUtilityTypes;\n} {\n const fieldEntries = Object.entries(fields).filter(([fieldName]) => fieldName !== \"id\");\n\n const fieldResults = fieldEntries.map(([fieldName, fieldConfig]) => ({\n fieldName,\n ...generateFieldType(fieldConfig, temporal),\n }));\n\n const fieldLines = [\n \"id: Generated<string>;\",\n ...fieldResults.map((result) => `${result.fieldName}: ${result.type};`),\n ];\n\n const aggregatedUtilityTypes = fieldResults.reduce(\n (acc, result) => mergeUsedUtilityTypes(acc, result.usedUtilityTypes),\n emptyUsedUtilityTypes(),\n );\n\n const typeDef = multiline /* ts */ `\n ${name}: {\n ${fieldLines.join(\"\\n\")}\n }\n `;\n\n return { typeDef, usedUtilityTypes: aggregatedUtilityTypes };\n}\n\n/**\n * Generate KyselyTypeMetadata from field configurations.\n * @param name - Table name\n * @param fields - Field configurations keyed by field name\n * @param temporal - Whether date/datetime/time fields resolve to their Temporal column\n * types instead of their `Date`/`string` defaults. Defaults to `false`.\n * @returns Generated Kysely type metadata\n */\nexport function processKyselyFields(\n name: string,\n fields: Record<string, KyselyFieldConfig>,\n temporal = false,\n): KyselyTypeMetadata {\n const result = generateTableInterface(name, fields, temporal);\n\n return {\n name,\n typeDef: result.typeDef,\n usedUtilityTypes: result.usedUtilityTypes,\n };\n}\n\n/**\n * Convert a TailorDBType into KyselyTypeMetadata.\n * @param type - Parsed TailorDB table\n * @param temporal - Whether date/datetime/time fields resolve to their Temporal column\n * types instead of their `Date`/`string` defaults. Defaults to `false`.\n * @returns Generated Kysely type metadata\n */\nexport async function processKyselyType(\n type: TailorDBType,\n temporal = false,\n): Promise<KyselyTypeMetadata> {\n return processKyselyFields(\n type.name,\n Object.fromEntries(\n Object.entries(type.fields).map(([fieldName, parsedField]) => [\n fieldName,\n parsedField.config,\n ]),\n ),\n temporal,\n );\n}\n\n/**\n * Generate unified types file from multiple namespaces.\n * @param namespaceData - Namespace metadata\n * @param temporal - Whether `kyselyTypePlugin` was configured with `{ temporal: true }`;\n * passed to `createGetDB` so the generated `getDB` always reads back the Temporal values\n * the tables above are typed with. Defaults to `false`.\n * @returns Generated types file contents\n */\nexport function generateUnifiedKyselyTypes(\n namespaceData: KyselyNamespaceMetadata[],\n temporal = false,\n): string {\n if (namespaceData.length === 0) {\n return \"\";\n }\n\n // Aggregate used utility types from all namespaces\n const globalUsedUtilityTypes = namespaceData\n .flatMap((ns) => ns.types)\n .reduce(\n (acc, type) => mergeUsedUtilityTypes(acc, type.usedUtilityTypes),\n emptyUsedUtilityTypes(),\n );\n\n const utilityTypeImports: string[] = [\"type Generated\"];\n if (globalUsedUtilityTypes.Timestamp) {\n utilityTypeImports.push(\"type Timestamp\");\n }\n if (globalUsedUtilityTypes.TemporalDate) {\n utilityTypeImports.push(\"type TemporalDate\");\n }\n if (globalUsedUtilityTypes.TemporalInstant) {\n utilityTypeImports.push(\"type TemporalInstant\");\n }\n if (globalUsedUtilityTypes.TemporalTime) {\n utilityTypeImports.push(\"type TemporalTime\");\n }\n if (globalUsedUtilityTypes.ObjectColumnType) {\n utilityTypeImports.push(\"type ObjectColumnType\");\n }\n if (globalUsedUtilityTypes.ArrayColumnType) {\n utilityTypeImports.push(\"type ArrayColumnType\");\n }\n if (globalUsedUtilityTypes.Serial) {\n utilityTypeImports.push(\"type Serial\");\n }\n\n const importsSection = multiline /* ts */ `\n import {\n createGetDB,\n ${utilityTypeImports.join(\",\\n\")},\n type NamespaceDB,\n type NamespaceInsertable,\n type NamespaceSelectable,\n type NamespaceTable,\n type NamespaceTableName,\n type NamespaceTransaction,\n type NamespaceUpdateable,\n } from \"@tailor-platform/sdk/kysely\";\n `;\n\n // Generate Namespace interface with multiple namespaces\n const namespaceInterfaces = namespaceData\n .map(({ namespace, types }) => {\n const typeDefsWithIndent = types\n .map((type) => {\n return type.typeDef\n .split(\"\\n\")\n .map((line) => (line.trim() ? ` ${line}` : \"\"))\n .join(\"\\n\");\n })\n .join(\"\\n\\n\");\n\n return ` \"${namespace}\": {\\n${typeDefsWithIndent}\\n }`;\n })\n .join(\",\\n\");\n\n const namespaceInterface = `export interface Namespace {\\n${namespaceInterfaces}\\n}`;\n\n const getDBFunction = multiline /* ts */ `\n export const getDB = createGetDB<Namespace>(${temporal ? \"{ temporal: true }\" : \"\"});\n\n export type DB<N extends keyof Namespace = keyof Namespace> = NamespaceDB<Namespace, N>;\n `;\n\n const utilityTypeExports = multiline /* ts */ `\n export type Transaction<K extends keyof Namespace | DB = keyof Namespace> =\n NamespaceTransaction<Namespace, K>;\n\n type TableName = NamespaceTableName<Namespace>;\n export type Table<T extends TableName> = NamespaceTable<Namespace, T>;\n\n export type Insertable<T extends TableName> = NamespaceInsertable<Namespace, T>;\n export type Selectable<T extends TableName> = NamespaceSelectable<Namespace, T>;\n export type Updateable<T extends TableName> = NamespaceUpdateable<Namespace, T>;\n `;\n\n return (\n [importsSection, namespaceInterface, getDBFunction, utilityTypeExports].join(\"\\n\\n\") + \"\\n\"\n );\n}\n","import { resolve } from \"pathe\";\nimport { generatePGliteSchemaModule } from \"./pglite-schema\";\nimport { processKyselyType, generateUnifiedKyselyTypes } from \"./type-processor\";\nimport type { Plugin, GeneratorResult, TailorDBReadyContext } from \"#/plugin/types\";\nimport type { KyselyTypeMetadata, KyselyNamespaceMetadata } from \"./types\";\n\n/** Unique identifier for the Kysely type generator plugin. */\nexport const KyselyGeneratorID = \"@tailor-platform/kysely-type\";\n\ntype KyselyTypePluginOptions = {\n distPath: string;\n pgliteSchemaPath?: string;\n /**\n * When `true`, generated tables map date/datetime fields and top-level time fields to\n * `Temporal.PlainDate`/`Temporal.Instant`/`Temporal.PlainTime` columns instead of\n * their `Date`/`string` defaults, and the generated `getDB` reads them back as those\n * Temporal values. Nested time fields remain strings. Defaults to `false`.\n */\n temporal?: boolean;\n};\n\n// Register this plugin's config type under its own id, via the package's\n// real public specifier, so callers can resolve it type-safely from a\n// `Plugin[]` array (see plugin/get-plugin-config.ts's resolvePluginConfig)\n// without importing KyselyTypePluginOptions, which stays unexported.\ndeclare module \"@tailor-platform/sdk/plugin\" {\n interface PluginConfigRegistry {\n \"@tailor-platform/kysely-type\": KyselyTypePluginOptions;\n }\n}\n\n/** Conventional output path used when `kyselyTypePlugin` has no `distPath` configured. */\nexport const DEFAULT_KYSELY_TYPES_DIST_PATH = \"./generated/tailordb.ts\";\n\n/**\n * Plugin that generates Kysely type definitions for TailorDB tables.\n * @param options - Plugin options\n * @param options.distPath - Output file path for generated types\n * @param options.pgliteSchemaPath - Output file path for the PGlite `CREATE TABLE` script module; omit to skip it\n * @param options.temporal - When `true`, generated tables map date/datetime fields and\n * top-level time fields to their `Temporal.PlainDate`/`Temporal.Instant`/\n * `Temporal.PlainTime` counterparts instead of `Date`/`string`. Nested time fields\n * remain strings. Defaults to `false`.\n * @returns Plugin instance with onTailorDBReady hook\n */\nexport function kyselyTypePlugin(\n options: KyselyTypePluginOptions,\n): Plugin<unknown, KyselyTypePluginOptions> {\n return {\n id: KyselyGeneratorID,\n description: \"Generates Kysely type definitions for TailorDB tables\",\n pluginConfig: options,\n\n async onTailorDBReady(\n ctx: TailorDBReadyContext<KyselyTypePluginOptions>,\n ): Promise<GeneratorResult> {\n const { distPath, pgliteSchemaPath, temporal } = ctx.pluginConfig;\n if (pgliteSchemaPath && resolve(distPath) === resolve(pgliteSchemaPath)) {\n throw new Error(\"distPath and pgliteSchemaPath must resolve to different files.\");\n }\n\n const allNamespaceData: KyselyNamespaceMetadata[] = [];\n\n for (const ns of ctx.tailordb) {\n const typeMetadataList: KyselyTypeMetadata[] = [];\n\n for (const type of Object.values(ns.tables)) {\n const metadata = await processKyselyType(type, temporal);\n typeMetadataList.push(metadata);\n }\n\n if (typeMetadataList.length === 0) continue;\n\n allNamespaceData.push({\n namespace: ns.namespace,\n types: typeMetadataList,\n });\n }\n\n const files: GeneratorResult[\"files\"] = [];\n if (allNamespaceData.length > 0) {\n const content = generateUnifiedKyselyTypes(allNamespaceData, temporal);\n files.push({\n path: ctx.pluginConfig.distPath,\n content,\n });\n if (ctx.pluginConfig.pgliteSchemaPath) {\n files.push({\n path: ctx.pluginConfig.pgliteSchemaPath,\n content: generatePGliteSchemaModule(\n ctx.tailordb.filter((ns) => Object.keys(ns.tables).length > 0),\n ),\n });\n }\n }\n\n return { files };\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{t as e}from"./schema-BU1aIQ63.mjs";import{t}from"./assert-WeXvmG4j.mjs";import{n,t as r}from"./guards-CiFVxoXR.mjs";var PluginManager=class{plugins=/* @__PURE__ */ new Map;generatedExecutors=[];generatedTables=[];generatedResolvers=[];processedResolverNamespaces=/* @__PURE__ */ new Set;namespaceGeneratedTableKeys=/* @__PURE__ */ new Set;namespaceGeneratedExecutorKeys=/* @__PURE__ */ new Set;constructor(e=[]){for(let t of e){if(this.plugins.has(t.id))throw Error(`Duplicate plugin ID "${t.id}" detected. Each plugin must have a unique ID.`);this.plugins.set(t.id,t)}}async processAttachment(e){let n=this.plugins.get(e.pluginId);if(!n)return{success:!1,error:`Plugin "${e.pluginId}" not found`};let r=n.tableConfigRequired;if((typeof r==`function`?r(n.pluginConfig):r===!0)&&(e.tableConfig===void 0||e.tableConfig===null))return{success:!1,error:`Plugin "${n.id}" requires tableConfig, but none was provided for table "${e.table.name}".`};if(!n.onTableLoaded)return{success:!1,error:`Plugin "${n.id}" does not support table-attached processing (missing onTableLoaded method). Use onNamespaceLoaded via definePlugins() instead.`};let i;try{i=await n.onTableLoaded({table:e.table,tableConfig:e.tableConfig,pluginConfig:n.pluginConfig,namespace:e.namespace})}catch(t){let r=t instanceof Error?t.message:String(t);return{success:!1,error:`Plugin "${n.id}" threw an error while processing table "${e.table.name}": ${r}`}}for(let t of i.resolvers??[])this.generatedResolvers.push({resolver:t,pluginId:n.id,namespace:e.namespace,sourceTableName:e.table.name});if(i.tables&&Object.keys(i.tables).length>0){let r=t(n.importPath,`plugin "${n.id}" missing importPath`);for(let[t,a]of Object.entries(i.tables))this.generatedTables.push({pluginId:e.pluginId,pluginImportPath:r,sourceTableName:e.table.name,kind:t,table:a,namespace:e.namespace,pluginConfig:n.pluginConfig})}if(i.executors&&i.executors.length>0)for(let t of i.executors)this.generatedExecutors.push({executor:t,pluginId:e.pluginId,namespace:e.namespace,sourceTableName:e.table.name});return{success:!0,output:i}}async processNamespacePlugins(e){let n=[];for(let[i,a]of this.plugins){if(!a.onNamespaceLoaded)continue;let o=a.pluginConfig,s={pluginConfig:o,namespace:e},c;try{c=await a.onNamespaceLoaded(s)}catch(t){let r=t instanceof Error?t.message:String(t);n.push({pluginId:i,config:o,result:{success:!1,error:`Plugin "${a.id}" threw an error during namespace processing for "${e}": ${r}`}});continue}let l=JSON.stringify([i,e]);if(!this.processedResolverNamespaces.has(l)){for(let t of c.resolvers??[])this.generatedResolvers.push({resolver:t,pluginId:i,namespace:e});this.processedResolverNamespaces.add(l)}if(c.executors&&c.executors.length>0)for(let t of c.executors){let n=`${i}:${t.name}`;this.namespaceGeneratedExecutorKeys.has(n)||(this.namespaceGeneratedExecutorKeys.add(n),this.generatedExecutors.push({executor:t,pluginId:i,namespace:e}))}if(c.tables&&Object.keys(c.tables).length>0){let n=t(a.importPath,`plugin "${a.id}" missing importPath`);for(let[t,o]of Object.entries(c.tables)){let s=`${i}:${t}:${r(o)??``}`;this.namespaceGeneratedTableKeys.has(s)||(this.namespaceGeneratedTableKeys.add(s),this.generatedTables.push({pluginId:i,pluginImportPath:n,sourceTableName:`(namespace)`,kind:t,table:o,namespace:e,pluginConfig:a.pluginConfig}))}}n.push({pluginId:i,config:o,result:{success:!0,output:c}})}return n}async processAttachmentsForTable(e){let{rawTable:t,attachments:n,namespace:i}=e,a=t,o,s=[],c=[];for(let e of n){let t=await this.processAttachment({table:a,tableConfig:e.config,namespace:i,pluginId:e.pluginId});if(!t.success)throw Error(t.error);let n=t.output,l=n.extends?.fields;l&&Object.keys(l).length>0&&(a=this.extendTable({originalTable:a,extendFields:l,pluginId:e.pluginId}),o=a,c.push({kind:`extended`,tableName:a.name,fieldCount:Object.keys(l).length,pluginId:e.pluginId}));let u=this.getPlugin(e.pluginId);for(let[t,i]of Object.entries(n.tables??{})){let n=r(i)??``;s.push({tableName:n,table:i,kind:t,pluginId:e.pluginId,pluginImportPath:this.getPluginImportPath(e.pluginId)??``,pluginConfig:u?.pluginConfig}),c.push({kind:`generated`,tableName:n,pluginId:e.pluginId})}}return{extendedTable:o,generatedTables:s,events:c}}getPlugin(e){return this.plugins.get(e)}getPluginImportPath(e){return this.plugins.get(e)?.importPath}getPluginGeneratedResolvers(){return this.generatedResolvers}getPluginGeneratedExecutorsWithImportPath(){return this.generatedExecutors.map(e=>({...e,pluginImportPath:this.getPluginImportPath(e.pluginId)??``}))}getPluginGeneratedTables(){return this.generatedTables}getPluginsWithGenerationHooks(){return Array.from(this.plugins.values()).filter(e=>n(e))}generatePluginFiles(e){let{outputDir:t,sourceTableInfoMap:n,configPath:r,tableGenerator:i,executorGenerator:a}=e,o=i(this.generatedTables,t);return a(this.getPluginGeneratedExecutorsWithImportPath(),t,o,n,r)}extendTable(t){let{originalTable:n,extendFields:r,pluginId:i}=t,a=Object.keys(n.fields),o=Object.keys(n.metadata.files),s=Object.keys(r),c=s.filter(e=>a.includes(e)),l=s.filter(e=>o.includes(e));if(c.length>0)throw Error(`Plugin "${i}" attempted to add fields that already exist in table "${n.name}": ${c.join(`, `)}. extendFields cannot overwrite existing fields.`);if(l.length>0)throw Error(`Plugin "${i}" attempted to add fields that collide with file keys already declared via .files() on table "${n.name}": ${l.join(`, `)}.`);let{id:u,...d}={...n.fields,...r},f=n.metadata.settings?.pluralForm,p=f?[n.name,f]:n.name;return copyMetadataToExtendedTable(n,e.table(p,d))}};function copyMetadataToExtendedTable(e,t){let n=t;e._description&&(n=n.description(e._description));let r=e.metadata;if(Object.keys(r.files).length>0&&(n=n.files(r.files)),r.settings){let{pluralForm:e,...t}=r.settings;Object.keys(t).length>0&&(n=n.features(t))}if(r.permissions.record&&(n=n.permission(r.permissions.record)),r.permissions.gql&&(n=n.gqlPermission(r.permissions.gql)),r.indexes&&Object.keys(r.indexes).length>0){let e=Object.entries(r.indexes).map(([e,t])=>({name:e,fields:t.fields,unique:t.unique}));n=n.indexes(...e)}if(r.typeHook&&(n=n.hooks(r.typeHook)),r.typeValidate&&(n=n.validate(r.typeValidate)),e.plugins.length>0)for(let t of e.plugins)n=n.plugin({[t.pluginId]:t.config});return n}export{PluginManager as t};
|
|
2
|
+
//# sourceMappingURL=manager-B813m43t.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager-B813m43t.mjs","names":["db","getRawPluginTableName","plugin","plugins","context","tableConfigRequired","output","error","message","resolver","importPath","assertDefined","kind","table","executor","results","pluginId","config","namespace","resolverNamespaceKey","executorKey","tableKey","params","currentTable","rawTable","extendedTable","generatedTables","events","attachment","attachments","result","extendFields","tableName","info","hasGenerationHooks","tableGenerationResult","tableGenerator","outputDir","executorGenerator","sourceTableInfoMap","configPath","existingFieldNames","originalTable","existingFileNames","newFieldNames","duplicateFields","name","duplicateFiles","_id","fieldsWithoutId","pluralForm","extended","original","metadata","_pluralForm","features","indexDefs","def"],"sources":["../src/plugin/manager.ts"],"sourcesContent":["import { db, type TailorAnyDBType } from \"#/configure/services/tailordb/index\";\nimport { getRawPluginTableName, hasGenerationHooks } from \"#/plugin/guards\";\nimport { assertDefined } from \"#/utils/assert\";\nimport type {\n TailorTypePermission,\n TailorTypeGqlPermission,\n} from \"#/configure/services/tailordb/permission\";\nimport type {\n TailorAnyDBField,\n TypeHook,\n TypeValidateFn,\n} from \"#/configure/services/tailordb/types\";\nimport type {\n Plugin,\n PluginAttachment,\n PluginGeneratedExecutor,\n PluginGeneratedResolver,\n PluginGeneratedTable,\n PluginNamespaceProcessContext,\n PluginOutput,\n TablePluginOutput,\n} from \"#/plugin/types\";\nimport type { TailorDBTypeRaw } from \"#/types/tailordb.generated\";\n\n/**\n * Context for processing a single plugin attachment on a raw TailorDBType\n */\nexport interface ProcessAttachmentContext {\n table: TailorAnyDBType;\n tableConfig: unknown;\n namespace: string;\n pluginId: string;\n}\n\n/**\n * Information about a plugin-generated table (for table file generation)\n */\nexport interface PluginGeneratedTableInfo {\n /** Plugin ID that generated this table */\n pluginId: string;\n /** Plugin import path for resolving executor files */\n pluginImportPath: string;\n /** Source table name that triggered the plugin */\n sourceTableName: string;\n /** Kind identifier for this generated table */\n kind: string;\n /** The generated TailorDB table object */\n table: PluginGeneratedTable;\n /** Namespace where this table was generated */\n namespace: string;\n /** Plugin config used to generate this table */\n pluginConfig?: unknown;\n}\n\n/**\n * Extended executor info with plugin import path\n */\nexport interface PluginExecutorInfoExtended extends PluginExecutorInfo {\n /** Plugin's import path for resolving executor files */\n pluginImportPath: string;\n}\n\n/**\n * Result of processing a table-attached plugin\n */\nexport type ProcessAttachmentResult =\n | { success: true; output: TablePluginOutput }\n | { success: false; error: string };\n\n/**\n * Result of processing a namespace plugin\n */\nexport type ProcessNamespaceResult =\n | { success: true; output: PluginOutput }\n | { success: false; error: string };\n\n/**\n * Parameters for processing all plugin attachments of a TailorDB table.\n */\nexport interface ProcessAttachmentsForTableParams {\n rawTable: TailorDBTypeRaw;\n attachments: PluginAttachment[];\n namespace: string;\n}\n\n/**\n * Progress event emitted while processing plugin attachments for a TailorDB table.\n * Plain data so the caller (typically the cli) can format and output it.\n */\ntype ProcessAttachmentEvent =\n | { kind: \"extended\"; tableName: string; fieldCount: number; pluginId: string }\n | { kind: \"generated\"; tableName: string; pluginId: string };\n\n/**\n * Generated table produced by a plugin during attachment processing.\n * `table` is raw plugin output; the caller must validate it before use.\n */\ninterface ProcessAttachmentsGeneratedTable {\n tableName: string;\n table: unknown;\n kind: string;\n pluginId: string;\n pluginImportPath: string;\n pluginConfig?: unknown;\n}\n\n/**\n * Result of {@link PluginManager.processAttachmentsForTable}.\n */\nexport interface ProcessAttachmentsForTableResult {\n /**\n * Final table after all extends are applied; undefined if no plugin extended the table.\n * Raw builder output; the caller must validate it before use.\n */\n extendedTable?: unknown;\n /** Tables newly generated by plugins for this attachment chain. */\n generatedTables: ProcessAttachmentsGeneratedTable[];\n /** Events for the caller to render. */\n events: ProcessAttachmentEvent[];\n}\n\n/**\n * Information about a plugin-generated executor\n */\nexport interface PluginExecutorInfo {\n /** The executor definition */\n executor: PluginGeneratedExecutor;\n /** Plugin ID that generated this executor */\n pluginId: string;\n /** Namespace where the executor was generated */\n namespace: string;\n /** Source table name (for table-attached executors, undefined for namespace) */\n sourceTableName?: string;\n}\n\nexport interface PluginResolverInfo {\n resolver: PluginGeneratedResolver;\n pluginId: string;\n namespace: string;\n sourceTableName?: string;\n}\n\n/**\n * Manages plugin registration and processing\n */\nexport class PluginManager {\n private plugins: Map<string, Plugin> = new Map();\n private generatedExecutors: PluginExecutorInfo[] = [];\n private generatedTables: PluginGeneratedTableInfo[] = [];\n private generatedResolvers: PluginResolverInfo[] = [];\n private processedResolverNamespaces = new Set<string>();\n private namespaceGeneratedTableKeys: Set<string> = new Set();\n private namespaceGeneratedExecutorKeys: Set<string> = new Set();\n\n constructor(plugins: Plugin[] = []) {\n for (const plugin of plugins) {\n if (this.plugins.has(plugin.id)) {\n throw new Error(\n `Duplicate plugin ID \"${plugin.id}\" detected. Each plugin must have a unique ID.`,\n );\n }\n this.plugins.set(plugin.id, plugin);\n }\n }\n\n /**\n * Process a single plugin attachment on a raw TailorDBType.\n * This method is called during table loading before parsing.\n * @param context - Context containing the raw table, config, namespace, and plugin ID\n * @returns Result with plugin output on success, or error message on failure\n */\n async processAttachment(context: ProcessAttachmentContext): Promise<ProcessAttachmentResult> {\n const plugin = this.plugins.get(context.pluginId);\n if (!plugin) {\n return {\n success: false,\n error: `Plugin \"${context.pluginId}\" not found`,\n };\n }\n\n const tableConfigRequired = plugin.tableConfigRequired;\n const resolvedRequired =\n typeof tableConfigRequired === \"function\"\n ? tableConfigRequired(plugin.pluginConfig)\n : tableConfigRequired === true;\n if (resolvedRequired && (context.tableConfig === undefined || context.tableConfig === null)) {\n return {\n success: false,\n error: `Plugin \"${plugin.id}\" requires tableConfig, but none was provided for table \"${context.table.name}\".`,\n };\n }\n\n // Check if plugin supports table-attached processing\n if (!plugin.onTableLoaded) {\n return {\n success: false,\n error: `Plugin \"${plugin.id}\" does not support table-attached processing (missing onTableLoaded method). Use onNamespaceLoaded via definePlugins() instead.`,\n };\n }\n\n // Execute plugin onTableLoaded with the raw TailorDB table\n let output: TablePluginOutput;\n try {\n output = await plugin.onTableLoaded({\n table: context.table,\n tableConfig: context.tableConfig,\n pluginConfig: plugin.pluginConfig,\n namespace: context.namespace,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n error: `Plugin \"${plugin.id}\" threw an error while processing table \"${context.table.name}\": ${message}`,\n };\n }\n\n for (const resolver of output.resolvers ?? []) {\n this.generatedResolvers.push({\n resolver,\n pluginId: plugin.id,\n namespace: context.namespace,\n sourceTableName: context.table.name,\n });\n }\n\n // Collect generated tables\n if (output.tables && Object.keys(output.tables).length > 0) {\n // importPath is guaranteed by schema validation for plugins with definition-time hooks\n const importPath = assertDefined(\n plugin.importPath,\n `plugin \"${plugin.id}\" missing importPath`,\n );\n for (const [kind, table] of Object.entries(output.tables)) {\n this.generatedTables.push({\n pluginId: context.pluginId,\n pluginImportPath: importPath,\n sourceTableName: context.table.name,\n kind,\n table,\n namespace: context.namespace,\n pluginConfig: plugin.pluginConfig,\n });\n }\n }\n\n // Collect generated executors\n if (output.executors && output.executors.length > 0) {\n for (const executor of output.executors) {\n this.generatedExecutors.push({\n executor,\n pluginId: context.pluginId,\n namespace: context.namespace,\n sourceTableName: context.table.name,\n });\n }\n }\n\n return { success: true, output };\n }\n\n /**\n * Process namespace plugins that don't require a source table.\n * This method is called once per namespace for plugins with onNamespaceLoaded method.\n * @param namespace - The target namespace for generated tables\n * @returns Array of results with plugin outputs and configs\n */\n async processNamespacePlugins(\n namespace: string,\n ): Promise<Array<{ pluginId: string; config: unknown; result: ProcessNamespaceResult }>> {\n const results: Array<{ pluginId: string; config: unknown; result: ProcessNamespaceResult }> =\n [];\n\n for (const [pluginId, plugin] of this.plugins) {\n // Skip plugins without onNamespaceLoaded method\n if (!plugin.onNamespaceLoaded) {\n continue;\n }\n\n // Use stored plugin config (from definePlugins)\n const config = plugin.pluginConfig;\n\n // Execute plugin onNamespaceLoaded\n const context: PluginNamespaceProcessContext = {\n pluginConfig: config,\n namespace,\n };\n\n let output: Awaited<ReturnType<NonNullable<Plugin[\"onNamespaceLoaded\"]>>>;\n try {\n output = await plugin.onNamespaceLoaded(context);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n results.push({\n pluginId,\n config,\n result: {\n success: false,\n error: `Plugin \"${plugin.id}\" threw an error during namespace processing for \"${namespace}\": ${message}`,\n },\n });\n continue;\n }\n\n const resolverNamespaceKey = JSON.stringify([pluginId, namespace]);\n if (!this.processedResolverNamespaces.has(resolverNamespaceKey)) {\n for (const resolver of output.resolvers ?? []) {\n this.generatedResolvers.push({ resolver, pluginId, namespace });\n }\n this.processedResolverNamespaces.add(resolverNamespaceKey);\n }\n\n // Collect generated executors (namespace - no source table)\n if (output.executors && output.executors.length > 0) {\n for (const executor of output.executors) {\n const executorKey = `${pluginId}:${executor.name}`;\n if (this.namespaceGeneratedExecutorKeys.has(executorKey)) {\n continue;\n }\n this.namespaceGeneratedExecutorKeys.add(executorKey);\n this.generatedExecutors.push({\n executor,\n pluginId,\n namespace,\n });\n }\n }\n\n // Collect generated tables (namespace - no source table)\n if (output.tables && Object.keys(output.tables).length > 0) {\n // importPath is guaranteed by schema validation for plugins with definition-time hooks\n const importPath = assertDefined(\n plugin.importPath,\n `plugin \"${plugin.id}\" missing importPath`,\n );\n for (const [kind, table] of Object.entries(output.tables)) {\n const tableKey = `${pluginId}:${kind}:${getRawPluginTableName(table) ?? \"\"}`;\n if (this.namespaceGeneratedTableKeys.has(tableKey)) {\n continue;\n }\n this.namespaceGeneratedTableKeys.add(tableKey);\n this.generatedTables.push({\n pluginId,\n pluginImportPath: importPath,\n sourceTableName: \"(namespace)\",\n kind,\n table,\n namespace,\n pluginConfig: plugin.pluginConfig,\n });\n }\n }\n\n results.push({\n pluginId,\n config,\n result: { success: true, output },\n });\n }\n\n return results;\n }\n\n /**\n * Run every plugin attachment for a single TailorDB table in order, threading the\n * extended table through the chain. Returns plain data (no logging, no shared state)\n * so the caller decides how to apply updates and render progress.\n * @param params - The raw table, its attachments, and the target namespace\n * @returns Final extended table (if any), generated tables, and render events\n */\n async processAttachmentsForTable(\n params: ProcessAttachmentsForTableParams,\n ): Promise<ProcessAttachmentsForTableResult> {\n const { rawTable, attachments, namespace } = params;\n // The runtime value is a configure-layer builder instance; we accept the structural\n // TailorDBTypeRaw at the boundary so callers (cli) don't need to depend on TailorAnyDBType.\n let currentTable: TailorAnyDBType = rawTable as unknown as TailorAnyDBType;\n let extendedTable: TailorAnyDBType | undefined;\n const generatedTables: ProcessAttachmentsGeneratedTable[] = [];\n const events: ProcessAttachmentEvent[] = [];\n\n for (const attachment of attachments) {\n const result = await this.processAttachment({\n table: currentTable,\n tableConfig: attachment.config,\n namespace,\n pluginId: attachment.pluginId,\n });\n if (!result.success) {\n throw new Error(result.error);\n }\n\n const output = result.output;\n const extendFields = output.extends?.fields;\n if (extendFields && Object.keys(extendFields).length > 0) {\n currentTable = this.extendTable({\n originalTable: currentTable,\n extendFields,\n pluginId: attachment.pluginId,\n });\n extendedTable = currentTable;\n events.push({\n kind: \"extended\",\n tableName: currentTable.name,\n fieldCount: Object.keys(extendFields).length,\n pluginId: attachment.pluginId,\n });\n }\n\n const plugin = this.getPlugin(attachment.pluginId);\n for (const [kind, table] of Object.entries(output.tables ?? {})) {\n const tableName = getRawPluginTableName(table) ?? \"\";\n generatedTables.push({\n tableName,\n table,\n kind,\n pluginId: attachment.pluginId,\n pluginImportPath: this.getPluginImportPath(attachment.pluginId) ?? \"\",\n pluginConfig: plugin?.pluginConfig,\n });\n events.push({ kind: \"generated\", tableName, pluginId: attachment.pluginId });\n }\n }\n\n return { extendedTable, generatedTables, events };\n }\n\n /**\n * Get a plugin by its ID\n * @param pluginId - The plugin ID to look up\n * @returns The plugin instance, or undefined if not found\n */\n getPlugin(pluginId: string): Plugin | undefined {\n return this.plugins.get(pluginId);\n }\n\n /**\n * Get the import path for a plugin\n * @param pluginId - The plugin ID to look up\n * @returns The plugin's import path, or undefined if not found\n */\n getPluginImportPath(pluginId: string): string | undefined {\n return this.plugins.get(pluginId)?.importPath;\n }\n\n /**\n * Get all plugin-generated resolvers.\n * @returns Resolver definitions with their source plugin and namespace\n */\n getPluginGeneratedResolvers(): ReadonlyArray<PluginResolverInfo> {\n return this.generatedResolvers;\n }\n\n /**\n * Get all plugin-generated executors with import paths\n * @returns Array of plugin-generated executor info with import paths\n */\n getPluginGeneratedExecutorsWithImportPath(): ReadonlyArray<PluginExecutorInfoExtended> {\n return this.generatedExecutors.map((info) => ({\n ...info,\n pluginImportPath: this.getPluginImportPath(info.pluginId) ?? \"\",\n }));\n }\n\n /**\n * Get all plugin-generated tables\n * @returns Array of plugin-generated table info\n */\n getPluginGeneratedTables(): ReadonlyArray<PluginGeneratedTableInfo> {\n return this.generatedTables;\n }\n\n /**\n * Get plugins that have any generation-time hooks.\n * @returns Array of plugins with generation hooks\n */\n getPluginsWithGenerationHooks(): Plugin[] {\n return Array.from(this.plugins.values()).filter((plugin) => hasGenerationHooks(plugin));\n }\n\n /**\n * Generate plugin files (tables and executors).\n * @param params - Parameters for file generation\n * @returns Generated executor file paths\n */\n generatePluginFiles(params: GeneratePluginFilesParams): string[] {\n const { outputDir, sourceTableInfoMap, configPath, tableGenerator, executorGenerator } = params;\n\n // Generate table files\n const tableGenerationResult = tableGenerator(this.generatedTables, outputDir);\n\n // Generate executor files\n const pluginExecutors = this.getPluginGeneratedExecutorsWithImportPath();\n return executorGenerator(\n pluginExecutors,\n outputDir,\n tableGenerationResult,\n sourceTableInfoMap,\n configPath,\n );\n }\n\n /**\n * Extend a TailorDB table with new fields.\n * This method handles the `db.table()` call and metadata copying internally.\n * @param params - Parameters for table extension\n * @returns The extended TailorDB table\n */\n extendTable(params: ExtendTableParams): TailorAnyDBType {\n const { originalTable, extendFields, pluginId } = params;\n const existingFieldNames = Object.keys(originalTable.fields);\n const existingFileNames = Object.keys(originalTable.metadata.files);\n const newFieldNames = Object.keys(extendFields);\n const duplicateFields = newFieldNames.filter((name) => existingFieldNames.includes(name));\n const duplicateFiles = newFieldNames.filter((name) => existingFileNames.includes(name));\n\n if (duplicateFields.length > 0) {\n throw new Error(\n `Plugin \"${pluginId}\" attempted to add fields that already exist in table \"${originalTable.name}\": ${duplicateFields.join(\", \")}. ` +\n `extendFields cannot overwrite existing fields.`,\n );\n }\n\n if (duplicateFiles.length > 0) {\n throw new Error(\n `Plugin \"${pluginId}\" attempted to add fields that collide with file keys already declared via .files() on table \"${originalTable.name}\": ${duplicateFiles.join(\", \")}.`,\n );\n }\n\n const mergedFields = {\n ...originalTable.fields,\n ...extendFields,\n };\n\n const { id: _id, ...fieldsWithoutId } = mergedFields;\n const pluralForm = originalTable.metadata.settings?.pluralForm;\n const tableName = pluralForm\n ? ([originalTable.name, pluralForm] as [string, string])\n : originalTable.name;\n const extendedTable = db.table(tableName, fieldsWithoutId);\n return copyMetadataToExtendedTable(originalTable, extendedTable);\n }\n}\n\n/**\n * Source info for user-defined tables\n */\nexport type SourceTableInfo = {\n filePath: string;\n exportName: string;\n};\n\n/**\n * Result of generating plugin table files\n */\nexport interface PluginTableGenerationResult {\n /** Map of table name to generated file path (relative to outputDir) */\n tableFilePaths: Map<string, string>;\n /** List of all generated file paths (absolute) */\n generatedFiles: string[];\n}\n\n/**\n * Parameters for generating plugin files\n */\nexport interface GeneratePluginFilesParams {\n /** Base output directory (e.g., .tailor/plugin) */\n outputDir: string;\n /** Map of source table names to their source info */\n sourceTableInfoMap: Map<string, SourceTableInfo>;\n /** Path to tailor.config.ts (used for resolving plugin import paths) */\n configPath: string;\n /** Function to generate table files */\n tableGenerator: (\n tables: ReadonlyArray<PluginGeneratedTableInfo>,\n outputDir: string,\n ) => PluginTableGenerationResult;\n /** Function to generate executor files */\n executorGenerator: (\n executors: ReadonlyArray<PluginExecutorInfoExtended>,\n outputDir: string,\n tableGenerationResult: PluginTableGenerationResult,\n sourceTableInfoMap: Map<string, SourceTableInfo>,\n configPath: string,\n ) => string[];\n}\n\n/**\n * Parameters for extending a TailorDB table\n */\nexport interface ExtendTableParams {\n /** The original TailorDB table to extend */\n originalTable: TailorAnyDBType;\n /** New fields to add to the table */\n extendFields: Record<string, unknown>;\n /** The ID of the plugin extending the table */\n pluginId: string;\n}\n\n/**\n * Copy metadata from original table to extended table.\n * Preserves files, settings, permissions, indexes, and plugins.\n * @param original - The original TailorDB table with metadata\n * @param extended - The newly created extended table\n * @returns The extended table with copied metadata\n */\nfunction copyMetadataToExtendedTable(\n original: TailorAnyDBType,\n extended: TailorAnyDBType,\n): TailorAnyDBType {\n let result = extended;\n\n // Copy description\n if (original._description) {\n result = result.description(original._description);\n }\n\n // Copy files metadata\n const metadata = original.metadata;\n if (Object.keys(metadata.files).length > 0) {\n result = result.files(metadata.files);\n }\n\n // Copy settings/features (excluding pluralForm which is set during construction)\n if (metadata.settings) {\n const { pluralForm: _pluralForm, ...features } = metadata.settings;\n if (Object.keys(features).length > 0) {\n result = result.features(\n features as typeof features & { aggregation?: true; bulkUpsert?: true },\n );\n }\n }\n\n // Copy permissions from metadata\n // Zod schema operand types are wider unions than the configure layer's discriminated PermissionCondition,\n // so type assertions are needed here.\n if (metadata.permissions.record) {\n result = result.permission(metadata.permissions.record as TailorTypePermission);\n }\n if (metadata.permissions.gql) {\n result = result.gqlPermission(metadata.permissions.gql as TailorTypeGqlPermission);\n }\n\n // Copy indexes from metadata (indexes are stored in metadata, not as a direct property)\n if (metadata.indexes && Object.keys(metadata.indexes).length > 0) {\n const indexDefs = Object.entries(metadata.indexes).map(([name, def]) => ({\n name,\n // Cast fields array to tuple type (IndexDef expects [T, T, ...T[]])\n fields: def.fields as [string, string, ...string[]],\n unique: def.unique,\n }));\n result = result.indexes(...indexDefs);\n }\n\n if (metadata.typeHook) {\n result = result.hooks(metadata.typeHook as TypeHook<Record<string, TailorAnyDBField>>);\n }\n if (metadata.typeValidate) {\n result = result.validate(\n metadata.typeValidate as TypeValidateFn<Record<string, TailorAnyDBField>>,\n );\n }\n\n // Copy plugins (but don't re-process them)\n if (original.plugins.length > 0) {\n for (const plugin of original.plugins) {\n // Use type assertion as plugin ID is dynamic at runtime\n result = result.plugin({\n [plugin.pluginId]: plugin.config,\n });\n }\n }\n\n return result;\n}\n"],"mappings":"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"}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { PluginGeneratedTableSource, TypeSourceInfoEntry } from "./types.mjs";
|
|
2
|
-
//#region src/parser/service/tailordb/type-source.d.ts
|
|
3
2
|
/**
|
|
4
3
|
* Checks if a table source is generated by a plugin.
|
|
5
4
|
* @param source - The table source entry to check.
|
|
6
5
|
* @returns True if the source was generated by a plugin.
|
|
7
6
|
*/
|
|
8
|
-
export declare function isPluginGeneratedTable(source: TypeSourceInfoEntry): source is PluginGeneratedTableSource;
|
|
9
|
-
//#endregion
|
|
7
|
+
export declare function isPluginGeneratedTable(source: TypeSourceInfoEntry): source is PluginGeneratedTableSource;
|
|
@@ -2,7 +2,6 @@ import { EnumValue } from "../../../configure/types/field.types.mjs";
|
|
|
2
2
|
import { TailorDBTypeParsedSettings } from "../../../types/tailordb.generated.mjs";
|
|
3
3
|
import { RawRelationConfig, TailorDBTypeMetadata } from "../../../configure/services/tailordb/types.mjs";
|
|
4
4
|
import { ValueOperand } from "../../../configure/services/auth/types.mjs";
|
|
5
|
-
//#region src/parser/service/tailordb/types.d.ts
|
|
6
5
|
interface UserDefinedTypeSource {
|
|
7
6
|
filePath: string;
|
|
8
7
|
exportName: string;
|
|
@@ -128,5 +127,4 @@ export interface TailorDBType {
|
|
|
128
127
|
};
|
|
129
128
|
typeValidateExpr?: string;
|
|
130
129
|
}
|
|
131
|
-
//#endregion
|
|
132
130
|
export {};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Plugin } from "../../types.mjs";
|
|
2
|
-
//#region src/plugin/builtin/enum-constants/index.d.ts
|
|
3
2
|
/** Unique identifier for the enum constants generator plugin. */
|
|
4
3
|
export declare const EnumConstantsGeneratorID = "@tailor-platform/enum-constants";
|
|
5
4
|
type EnumConstantsPluginOptions = {
|
|
@@ -12,5 +11,4 @@ type EnumConstantsPluginOptions = {
|
|
|
12
11
|
* @returns Plugin instance with onTailorDBReady hook
|
|
13
12
|
*/
|
|
14
13
|
export declare function enumConstantsPlugin(options: EnumConstantsPluginOptions): Plugin<unknown, EnumConstantsPluginOptions>;
|
|
15
|
-
//#endregion
|
|
16
14
|
export {};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Plugin } from "../../types.mjs";
|
|
2
|
-
//#region src/plugin/builtin/file-utils/index.d.ts
|
|
3
2
|
/** Unique identifier for the file utilities generator plugin. */
|
|
4
3
|
export declare const FileUtilsGeneratorID = "@tailor-platform/file-utils";
|
|
5
4
|
type FileUtilsPluginOptions = {
|
|
@@ -12,5 +11,4 @@ type FileUtilsPluginOptions = {
|
|
|
12
11
|
* @returns Plugin instance with onTailorDBReady hook
|
|
13
12
|
*/
|
|
14
13
|
export declare function fileUtilsPlugin(options: FileUtilsPluginOptions): Plugin<unknown, FileUtilsPluginOptions>;
|
|
15
|
-
//#endregion
|
|
16
14
|
export {};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Plugin } from "../../types.mjs";
|
|
2
|
-
//#region src/plugin/builtin/kysely-type/index.d.ts
|
|
3
2
|
/** Unique identifier for the Kysely type generator plugin. */
|
|
4
3
|
export declare const KyselyGeneratorID = "@tailor-platform/kysely-type";
|
|
5
4
|
type KyselyTypePluginOptions = {
|
|
@@ -32,5 +31,4 @@ export declare const DEFAULT_KYSELY_TYPES_DIST_PATH = "./generated/tailordb.ts";
|
|
|
32
31
|
* @returns Plugin instance with onTailorDBReady hook
|
|
33
32
|
*/
|
|
34
33
|
export declare function kyselyTypePlugin(options: KyselyTypePluginOptions): Plugin<unknown, KyselyTypePluginOptions>;
|
|
35
|
-
//#endregion
|
|
36
34
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{t as DEFAULT_KYSELY_TYPES_DIST_PATH,n as KyselyGeneratorID,r as kyselyTypePlugin}from"../../../kysely-type-
|
|
1
|
+
export{t as DEFAULT_KYSELY_TYPES_DIST_PATH,n as KyselyGeneratorID,r as kyselyTypePlugin}from"../../../kysely-type-B0ri1-Xs.mjs";
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Plugin } from "../../types.mjs";
|
|
2
|
-
//#region src/plugin/builtin/seed/index.d.ts
|
|
3
2
|
/** Unique identifier for the seed generator plugin. */
|
|
4
3
|
export declare const SeedGeneratorID = "@tailor-platform/seed";
|
|
5
4
|
type DisableIdpUserSyncDirections = {
|
|
@@ -56,5 +55,4 @@ declare module "@tailor-platform/sdk/plugin" {
|
|
|
56
55
|
* @returns Plugin instance with onTailorDBReady hook
|
|
57
56
|
*/
|
|
58
57
|
export declare function seedPlugin(options: SeedPluginOptions): Plugin<unknown, SeedPluginOptions>;
|
|
59
|
-
//#endregion
|
|
60
58
|
export {};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import "../../types.mjs";
|
|
2
|
-
//#region src/plugin/builtin/seed/seed-type-processor.d.ts
|
|
3
2
|
/**
|
|
4
3
|
* Seed ordering information for a TailorDB namespace.
|
|
5
4
|
*/
|
|
@@ -31,5 +30,4 @@ export interface SeedNamespaceConfig {
|
|
|
31
30
|
* instead of assuming `id`.
|
|
32
31
|
*/
|
|
33
32
|
selfRefKeys?: Record<string, Record<string, string>>;
|
|
34
|
-
}
|
|
35
|
-
//#endregion
|
|
33
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { TailorAnyDBType } from "../configure/services/tailordb/types.mjs";
|
|
2
|
-
//#region src/plugin/get-generated-table.d.ts
|
|
3
2
|
/**
|
|
4
3
|
* Get a generated table from a plugin by loading the config and resolving everything automatically.
|
|
5
4
|
* For table-attached plugins, calls onTableLoaded() with the source table.
|
|
@@ -24,5 +23,4 @@ export declare function getGeneratedTable(configPath: string, pluginId: string,
|
|
|
24
23
|
* @param sourceTable - The TailorDB table as exported from its source file
|
|
25
24
|
* @returns The table with every plugin-added field
|
|
26
25
|
*/
|
|
27
|
-
export declare function getExtendedTable<T extends TailorAnyDBType>(configPath: string, sourceTable: T): Promise<T>;
|
|
28
|
-
//#endregion
|
|
26
|
+
export declare function getExtendedTable<T extends TailorAnyDBType>(configPath: string, sourceTable: T): Promise<T>;
|
package/dist/plugin/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"../manager-
|
|
1
|
+
import{t as e}from"../manager-B813m43t.mjs";import*as t from"pathe";import*as n from"node:fs";import{pathToFileURL as r}from"node:url";function withPluginContext(e){return e}const i=/* @__PURE__ */ new Map,a=[`onTableLoaded`,`onNamespaceLoaded`,`onTailorDBReady`,`onResolverReady`,`onExecutorReady`,`onDeployed`];function isPlugin(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;if(typeof t.id!=`string`||typeof t.description!=`string`||t.importPath!==void 0&&typeof t.importPath!=`string`||t.tableConfigRequired!==void 0&&typeof t.tableConfigRequired!=`boolean`&&typeof t.tableConfigRequired!=`function`)return!1;for(let e of a)if(t[e]!==void 0&&typeof t[e]!=`function`)return!1;return!((t.onTableLoaded||t.onNamespaceLoaded)&&!t.importPath)}async function loadAndCacheConfig(e){let a=t.resolve(e),o=i.get(a);if(o)return o;if(!n.existsSync(a))return null;let s=await import(r(a).href);if(!s?.default)throw Error(`Invalid config module at "${a}": default export not found`);let c=s.default,l=t.dirname(a),u=/* @__PURE__ */ new Map;if(Object.hasOwn(s,`plugins`)){let e=s.plugins;if(!Array.isArray(e))throw Error(`Invalid \`plugins\` export in "${a}": expected an array returned by definePlugins(), got ${typeof e}`);for(let t of e){if(!isPlugin(t))throw Error(`Invalid \`plugins\` export in "${a}": every item must be a plugin created by definePlugins()`);if(u.has(t.id))throw Error(`Duplicate plugin ID "${t.id}" detected in "${a}". Each plugin must have a unique ID.`);u.set(t.id,{plugin:t,pluginConfig:t.pluginConfig})}}let d={config:c,plugins:u,configDir:l};return i.set(a,d),d}async function resolveNamespaceForTable(e,i,a){if(!e.db)throw Error(`No db configuration found in config`);for(let[o,s]of Object.entries(e.db)){let e=s;if(!e.external&&e.files)for(let s of e.files){let e=t.resolve(i,s),c;try{c=n.globSync(e)}catch{continue}for(let e of c){let t=await import(r(e).href);for(let e of Object.values(t))if(e===a)return o}}}throw Error(`Could not resolve namespace for table "${a.name}". Ensure the table file is included in a db namespace's files pattern.`)}async function resolveNamespaceForNamespacePlugin(e,t,n,r){if(!e.db)throw Error(`No db configuration found in config`);if(!t.onNamespaceLoaded)throw Error(`Plugin "${t.id}" does not have a onNamespaceLoaded() method`);for(let i of Object.keys(e.db)){if(e.db[i].external)continue;let a=await t.onNamespaceLoaded({pluginConfig:r,namespace:i});if(a.tables?.[n])return{namespace:i,output:a}}throw Error(`Could not resolve namespace for plugin "${t.id}" with kind "${n}". No namespace produced a table with that kind.`)}const o=/* @__PURE__ */ new WeakMap,s=/* @__PURE__ */ new WeakMap;function getCacheKey(e,t){if(t===void 0)return e;try{return`${e}:${JSON.stringify(t)}`}catch{throw Error(`pluginConfig must be JSON-serializable for caching. Received non-serializable value.`)}}async function getGeneratedTable(e,t,n,r){let i=await loadAndCacheConfig(e);if(!i)return{name:`__placeholder_${r}__`,fields:{}};let{config:a,configDir:o,plugins:s}=i,c=s.get(t);if(!c)throw Error(`Plugin "${t}" not found in config at "${e}". Ensure the plugin is registered via definePlugins().`);let{plugin:l,pluginConfig:u}=c;return n===null?getGeneratedTableForNamespacePlugin(a,l,r,u):getGeneratedTableForTableAttachedPlugin(l,n,r,u,await resolveNamespaceForTable(a,o,n))}async function getGeneratedTableForTableAttachedPlugin(e,t,n,r,i){if(!e.onTableLoaded)throw Error(`Plugin "${e.id}" does not have an onTableLoaded() method`);let a=o.get(e);a||(a=/* @__PURE__ */ new Map,o.set(e,a));let s=getCacheKey(`${t.name}:ns=${i}`,r),c=a.get(s);if(!c){let n=t.plugins.find(t=>t.pluginId===e.id)?.config;c=await e.onTableLoaded({table:t,tableConfig:n??{},pluginConfig:r,namespace:i}),a.set(s,c)}let l=c.tables?.[n];if(!l)throw Error(`Generated table not found: plugin=${e.id}, sourceTable=${t.name}, kind=${n}`);return l}async function getGeneratedTableForNamespacePlugin(e,t,n,r){if(!t.onNamespaceLoaded)throw Error(`Plugin "${t.id}" does not have a onNamespaceLoaded() method`);let i=s.get(t);if(i||(i=/* @__PURE__ */ new Map,s.set(t,i)),e.db)for(let t of Object.keys(e.db)){if(e.db[t].external)continue;let a=getCacheKey(`namespace:ns=${t}`,r),o=i.get(a);if(o?.tables?.[n])return o.tables[n]}let{namespace:a,output:o}=await resolveNamespaceForNamespacePlugin(e,t,n,r),c=getCacheKey(`namespace:ns=${a}`,r);i.set(c,o);let l=o.tables?.[n];if(!l)throw Error(`Generated table not found: plugin=${t.id}, kind=${n}`);return l}const c=/* @__PURE__ */ new Map;async function getExtendedTable(e,n){if(n.plugins.length===0)return n;let r=t.resolve(e),i=c.get(r);i||(i=/* @__PURE__ */ new WeakMap,c.set(r,i));let a=i.get(n);if(a)return a;let o=applyPluginExtensions(r,n);return i.set(n,o),o.catch(()=>i.delete(n)),o}async function applyPluginExtensions(t,n){let r=await loadAndCacheConfig(t);if(!r)return n;let{config:i,configDir:a,plugins:o}=r,s=await resolveNamespaceForTable(i,a,n),{extendedTable:c}=await new e([...o.values()].map(e=>e.plugin)).processAttachmentsForTable({rawTable:n,attachments:[...n.plugins],namespace:s});return c??n}export{getExtendedTable,getGeneratedTable,withPluginContext};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/dist/plugin/types.d.mts
CHANGED
|
@@ -3,7 +3,6 @@ import { IdProvider, OAuth2Client } from "../types/auth.generated.mjs";
|
|
|
3
3
|
import { TailorDBType, TypeSourceInfoEntry } from "../parser/service/tailordb/types.mjs";
|
|
4
4
|
import { Executor } from "../types/executor.generated.mjs";
|
|
5
5
|
import { Resolver } from "../types/resolver.generated.mjs";
|
|
6
|
-
//#region src/plugin/types.d.ts
|
|
7
6
|
/**
|
|
8
7
|
* A single generated file to write to disk.
|
|
9
8
|
*/
|
|
@@ -355,5 +354,4 @@ export interface DeployedHookResult {
|
|
|
355
354
|
/** Values included in deploy's JSON result. Interface-typed values are accepted, but a `Date` or class instance nested inside one fails the deploy instead of the type check. */
|
|
356
355
|
outputs?: Record<string, PluginOutputValue>;
|
|
357
356
|
}
|
|
358
|
-
//#endregion
|
|
359
357
|
export type { PluginAttachment };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { TailorEnv, TailorPrincipal } from "../runtime/types.mjs";
|
|
2
|
-
//#region src/plugin/with-context.d.ts
|
|
3
2
|
/**
|
|
4
3
|
* Plugin executor factory function type.
|
|
5
4
|
* Takes context and returns an executor configuration.
|
|
@@ -96,5 +95,4 @@ export type PluginRecord = {
|
|
|
96
95
|
* );
|
|
97
96
|
* ```
|
|
98
97
|
*/
|
|
99
|
-
export declare function withPluginContext<Ctx>(factory: PluginExecutorFactory<Ctx>): PluginExecutorFactory<Ctx>;
|
|
100
|
-
//#endregion
|
|
98
|
+
export declare function withPluginContext<Ctx>(factory: PluginExecutorFactory<Ctx>): PluginExecutorFactory<Ctx>;
|