@c15t/backend 1.0.5 → 1.2.0-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +33 -39
- package/.turbo/turbo-fmt.log +3 -3
- package/.turbo/turbo-test.log +531 -0
- package/coverage/coverage-final.json +84 -0
- package/coverage/coverage-summary.json +85 -0
- package/coverage/html/backend/index.html +116 -0
- package/coverage/html/backend/rslib.config.ts.html +415 -0
- package/coverage/html/backend/src/contracts/consent/index.html +161 -0
- package/coverage/html/backend/src/contracts/consent/index.ts.html +112 -0
- package/coverage/html/backend/src/contracts/consent/post.contract.ts.html +559 -0
- package/coverage/html/backend/src/contracts/consent/show-banner.contract.ts.html +220 -0
- package/coverage/html/backend/src/contracts/consent/verify.contract.ts.html +463 -0
- package/coverage/html/backend/src/contracts/index.html +116 -0
- package/coverage/html/backend/src/contracts/index.ts.html +139 -0
- package/coverage/html/backend/src/contracts/meta/index.html +131 -0
- package/coverage/html/backend/src/contracts/meta/index.ts.html +100 -0
- package/coverage/html/backend/src/contracts/meta/status.contract.ts.html +196 -0
- package/coverage/html/backend/src/contracts/shared/index.html +116 -0
- package/coverage/html/backend/src/contracts/shared/jurisdiction.schema.ts.html +175 -0
- package/coverage/html/backend/src/core.ts.html +1624 -0
- package/coverage/html/backend/src/handlers/consent/index.html +161 -0
- package/coverage/html/backend/src/handlers/consent/index.ts.html +112 -0
- package/coverage/html/backend/src/handlers/consent/post.handler.ts.html +889 -0
- package/coverage/html/backend/src/handlers/consent/show-banner.handler.ts.html +535 -0
- package/coverage/html/backend/src/handlers/consent/verify.handler.ts.html +1000 -0
- package/coverage/html/backend/src/handlers/meta/index.html +131 -0
- package/coverage/html/backend/src/handlers/meta/index.ts.html +100 -0
- package/coverage/html/backend/src/handlers/meta/status.handler.ts.html +226 -0
- package/coverage/html/backend/src/index.html +161 -0
- package/coverage/html/backend/src/init.ts.html +1018 -0
- package/coverage/html/backend/src/pkgs/api-router/hooks/index.html +116 -0
- package/coverage/html/backend/src/pkgs/api-router/hooks/processor.ts.html +544 -0
- package/coverage/html/backend/src/pkgs/api-router/index.html +116 -0
- package/coverage/html/backend/src/pkgs/api-router/telemetry.ts.html +334 -0
- package/coverage/html/backend/src/pkgs/api-router/utils/cors.ts.html +304 -0
- package/coverage/html/backend/src/pkgs/api-router/utils/index.html +131 -0
- package/coverage/html/backend/src/pkgs/api-router/utils/ip.ts.html +361 -0
- package/coverage/html/backend/src/pkgs/data-model/fields/field-factory.ts.html +709 -0
- package/coverage/html/backend/src/pkgs/data-model/fields/id-generator.ts.html +256 -0
- package/coverage/html/backend/src/pkgs/data-model/fields/index.html +161 -0
- package/coverage/html/backend/src/pkgs/data-model/fields/superjson-utils.ts.html +136 -0
- package/coverage/html/backend/src/pkgs/data-model/fields/zod-fields.ts.html +496 -0
- package/coverage/html/backend/src/pkgs/data-model/hooks/create-hooks.ts.html +349 -0
- package/coverage/html/backend/src/pkgs/data-model/hooks/index.html +176 -0
- package/coverage/html/backend/src/pkgs/data-model/hooks/update-hooks.ts.html +358 -0
- package/coverage/html/backend/src/pkgs/data-model/hooks/update-many-hooks.ts.html +613 -0
- package/coverage/html/backend/src/pkgs/data-model/hooks/utils.ts.html +538 -0
- package/coverage/html/backend/src/pkgs/data-model/hooks/with-hooks-factory.ts.html +289 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapter-factory.ts.html +289 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.ts.html +2203 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/drizzle-adapter/index.html +116 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/index.html +116 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/dialect.ts.html +670 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/index.html +131 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.ts.html +3634 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/tests/index.html +116 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.ts.html +1417 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/memory-adapter/index.html +116 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.ts.html +2071 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/prisma-adapter/index.html +116 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.ts.html +1834 -0
- package/coverage/html/backend/src/pkgs/db-adapters/adapters/test.ts.html +316 -0
- package/coverage/html/backend/src/pkgs/db-adapters/index.html +131 -0
- package/coverage/html/backend/src/pkgs/db-adapters/utils.ts.html +238 -0
- package/coverage/html/backend/src/pkgs/migrations/get-migration.ts.html +343 -0
- package/coverage/html/backend/src/pkgs/migrations/get-schema/get-schema.ts.html +217 -0
- package/coverage/html/backend/src/pkgs/migrations/get-schema/index.html +146 -0
- package/coverage/html/backend/src/pkgs/migrations/get-schema/process-fields.ts.html +280 -0
- package/coverage/html/backend/src/pkgs/migrations/get-schema/process-tables.ts.html +289 -0
- package/coverage/html/backend/src/pkgs/migrations/index.html +176 -0
- package/coverage/html/backend/src/pkgs/migrations/migration-builders.ts.html +595 -0
- package/coverage/html/backend/src/pkgs/migrations/migration-execution.ts.html +301 -0
- package/coverage/html/backend/src/pkgs/migrations/schema-comparison.ts.html +694 -0
- package/coverage/html/backend/src/pkgs/migrations/type-mapping.ts.html +817 -0
- package/coverage/html/backend/src/pkgs/results/core/error-class.ts.html +976 -0
- package/coverage/html/backend/src/pkgs/results/core/error-codes.ts.html +703 -0
- package/coverage/html/backend/src/pkgs/results/core/index.html +146 -0
- package/coverage/html/backend/src/pkgs/results/core/tracing.ts.html +280 -0
- package/coverage/html/backend/src/pkgs/results/create-telemetry-options.ts.html +271 -0
- package/coverage/html/backend/src/pkgs/results/index.html +131 -0
- package/coverage/html/backend/src/pkgs/results/orpc-error-handler.ts.html +496 -0
- package/coverage/html/backend/src/pkgs/results/results/index.html +131 -0
- package/coverage/html/backend/src/pkgs/results/results/recovery-utils.ts.html +628 -0
- package/coverage/html/backend/src/pkgs/results/results/result-helpers.ts.html +1234 -0
- package/coverage/html/backend/src/pkgs/utils/env.ts.html +337 -0
- package/coverage/html/backend/src/pkgs/utils/index.html +146 -0
- package/coverage/html/backend/src/pkgs/utils/logger.ts.html +199 -0
- package/coverage/html/backend/src/pkgs/utils/url.ts.html +400 -0
- package/coverage/html/backend/src/router.ts.html +109 -0
- package/coverage/html/backend/src/schema/audit-log/index.html +146 -0
- package/coverage/html/backend/src/schema/audit-log/registry.ts.html +436 -0
- package/coverage/html/backend/src/schema/audit-log/schema.ts.html +223 -0
- package/coverage/html/backend/src/schema/audit-log/table.ts.html +640 -0
- package/coverage/html/backend/src/schema/consent/index.html +146 -0
- package/coverage/html/backend/src/schema/consent/registry.ts.html +616 -0
- package/coverage/html/backend/src/schema/consent/schema.ts.html +238 -0
- package/coverage/html/backend/src/schema/consent/table.ts.html +748 -0
- package/coverage/html/backend/src/schema/consent-policy/index.html +146 -0
- package/coverage/html/backend/src/schema/consent-policy/registry.ts.html +1063 -0
- package/coverage/html/backend/src/schema/consent-policy/schema.ts.html +265 -0
- package/coverage/html/backend/src/schema/consent-policy/table.ts.html +535 -0
- package/coverage/html/backend/src/schema/consent-purpose/index.html +146 -0
- package/coverage/html/backend/src/schema/consent-purpose/registry.ts.html +589 -0
- package/coverage/html/backend/src/schema/consent-purpose/schema.ts.html +259 -0
- package/coverage/html/backend/src/schema/consent-purpose/table.ts.html +547 -0
- package/coverage/html/backend/src/schema/consent-record/index.html +131 -0
- package/coverage/html/backend/src/schema/consent-record/schema.ts.html +211 -0
- package/coverage/html/backend/src/schema/consent-record/table.ts.html +457 -0
- package/coverage/html/backend/src/schema/create-registry.ts.html +148 -0
- package/coverage/html/backend/src/schema/definition.ts.html +685 -0
- package/coverage/html/backend/src/schema/domain/index.html +146 -0
- package/coverage/html/backend/src/schema/domain/registry.ts.html +973 -0
- package/coverage/html/backend/src/schema/domain/schema.ts.html +214 -0
- package/coverage/html/backend/src/schema/domain/table.ts.html +496 -0
- package/coverage/html/backend/src/schema/index.html +146 -0
- package/coverage/html/backend/src/schema/schemas.ts.html +166 -0
- package/coverage/html/backend/src/schema/subject/index.html +146 -0
- package/coverage/html/backend/src/schema/subject/registry.ts.html +973 -0
- package/coverage/html/backend/src/schema/subject/schema.ts.html +208 -0
- package/coverage/html/backend/src/schema/subject/table.ts.html +499 -0
- package/coverage/html/backend/src/server.ts.html +475 -0
- package/coverage/html/backend/src/testing/contract-testing.ts.html +1348 -0
- package/coverage/html/backend/src/testing/index.html +116 -0
- package/coverage/html/base.css +224 -0
- package/coverage/html/block-navigation.js +87 -0
- package/coverage/html/favicon.png +0 -0
- package/coverage/html/index.html +626 -0
- package/coverage/html/prettify.css +1 -0
- package/coverage/html/prettify.js +2 -0
- package/coverage/html/sort-arrow-sprite.png +0 -0
- package/coverage/html/sorter.js +196 -0
- package/dist/contracts/consent/index.d.ts +401 -0
- package/dist/contracts/consent/index.d.ts.map +1 -0
- package/dist/contracts/consent/index.test.d.ts +2 -0
- package/dist/contracts/consent/index.test.d.ts.map +1 -0
- package/dist/contracts/consent/post.contract.d.ts +212 -0
- package/dist/contracts/consent/post.contract.d.ts.map +1 -0
- package/dist/contracts/consent/post.contract.test.d.ts +2 -0
- package/dist/contracts/consent/post.contract.test.d.ts.map +1 -0
- package/dist/contracts/consent/show-banner.contract.d.ts +45 -0
- package/dist/contracts/consent/show-banner.contract.d.ts.map +1 -0
- package/dist/contracts/consent/show-banner.contract.test.d.ts +2 -0
- package/dist/contracts/consent/show-banner.contract.test.d.ts.map +1 -0
- package/dist/contracts/consent/verify.contract.d.ts +147 -0
- package/dist/contracts/consent/verify.contract.d.ts.map +1 -0
- package/dist/contracts/consent/verify.contract.test.d.ts +2 -0
- package/dist/contracts/consent/verify.contract.test.d.ts.map +1 -0
- package/dist/contracts/index.d.ts +963 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/meta/index.d.ts +78 -0
- package/dist/contracts/meta/index.d.ts.map +1 -0
- package/dist/contracts/meta/index.test.d.ts +2 -0
- package/dist/contracts/meta/index.test.d.ts.map +1 -0
- package/dist/contracts/meta/status.contract.d.ts +77 -0
- package/dist/contracts/meta/status.contract.d.ts.map +1 -0
- package/dist/contracts/meta/status.contract.test.d.ts +2 -0
- package/dist/contracts/meta/status.contract.test.d.ts.map +1 -0
- package/dist/contracts/shared/jurisdiction.schema.d.ts +24 -0
- package/dist/contracts/shared/jurisdiction.schema.d.ts.map +1 -0
- package/dist/core.cjs +3584 -0
- package/dist/core.d.ts +533 -76
- package/dist/core.d.ts.map +1 -1
- package/dist/{index.js → core.js} +1163 -1286
- package/dist/handlers/consent/index.d.ts +401 -0
- package/dist/handlers/consent/index.d.ts.map +1 -0
- package/dist/handlers/consent/post.handler.d.ts +234 -0
- package/dist/handlers/consent/post.handler.d.ts.map +1 -0
- package/dist/handlers/consent/show-banner.handler.d.ts +57 -0
- package/dist/handlers/consent/show-banner.handler.d.ts.map +1 -0
- package/dist/handlers/consent/show-banner.handler.test.d.ts +2 -0
- package/dist/handlers/consent/show-banner.handler.test.d.ts.map +1 -0
- package/dist/handlers/consent/verify.handler.d.ts +169 -0
- package/dist/handlers/consent/verify.handler.d.ts.map +1 -0
- package/dist/handlers/meta/index.d.ts +78 -0
- package/dist/handlers/meta/index.d.ts.map +1 -0
- package/dist/handlers/meta/status.handler.d.ts +76 -0
- package/dist/handlers/meta/status.handler.d.ts.map +1 -0
- package/dist/init.d.ts.map +1 -1
- package/dist/pkgs/api-router/hooks/processor.d.ts.map +1 -1
- package/dist/pkgs/api-router/types/router-props.d.ts +1 -1
- package/dist/pkgs/api-router/types/router-props.d.ts.map +1 -1
- package/dist/pkgs/api-router/utils/cors.d.ts +1 -1
- package/dist/pkgs/api-router/utils/cors.d.ts.map +1 -1
- package/dist/pkgs/data-model/fields/field-types.d.ts +1 -1
- package/dist/pkgs/data-model/fields/zod-fields.d.ts +32 -32
- package/dist/pkgs/data-model/index.cjs +1433 -1799
- package/dist/pkgs/data-model/index.js +20 -385
- package/dist/pkgs/data-model/schema/index.cjs +1402 -1768
- package/dist/pkgs/data-model/schema/index.js +20 -385
- package/dist/pkgs/db-adapters/adapter-factory.d.ts +2 -2
- package/dist/pkgs/db-adapters/adapter-factory.d.ts.map +1 -1
- package/dist/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.d.ts +4 -4
- package/dist/pkgs/db-adapters/adapters/drizzle-adapter/index.cjs +19 -151
- package/dist/pkgs/db-adapters/adapters/drizzle-adapter/index.js +19 -151
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/dialect.d.ts +1 -1
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/index.cjs +17 -149
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/index.js +17 -149
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.d.ts +2 -2
- package/dist/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.d.ts.map +1 -1
- package/dist/pkgs/db-adapters/adapters/memory-adapter/index.cjs +17 -149
- package/dist/pkgs/db-adapters/adapters/memory-adapter/index.js +17 -149
- package/dist/pkgs/db-adapters/adapters/prisma-adapter/index.cjs +19 -151
- package/dist/pkgs/db-adapters/adapters/prisma-adapter/index.js +19 -151
- package/dist/pkgs/db-adapters/index.cjs +31 -153
- package/dist/pkgs/db-adapters/index.js +31 -153
- package/dist/pkgs/migrations/get-schema/get-schema.d.ts +2 -2
- package/dist/pkgs/migrations/get-schema/index.d.ts +1 -1
- package/dist/pkgs/migrations/index.cjs +30 -153
- package/dist/pkgs/migrations/index.js +30 -153
- package/dist/pkgs/migrations/schema-comparison.d.ts.map +1 -1
- package/dist/pkgs/results/core/error-class.d.ts +23 -21
- package/dist/pkgs/results/core/error-class.d.ts.map +1 -1
- package/dist/pkgs/results/index.cjs +17 -150
- package/dist/pkgs/results/index.d.ts +0 -3
- package/dist/pkgs/results/index.d.ts.map +1 -1
- package/dist/pkgs/results/index.js +17 -138
- package/dist/pkgs/results/orpc-error-handler.d.ts +65 -0
- package/dist/pkgs/results/orpc-error-handler.d.ts.map +1 -0
- package/dist/pkgs/results/types.d.ts +7 -7
- package/dist/pkgs/results/types.d.ts.map +1 -1
- package/dist/pkgs/types/context.d.ts +15 -4
- package/dist/pkgs/types/context.d.ts.map +1 -1
- package/dist/pkgs/types/endpoints.d.ts +3 -4
- package/dist/pkgs/types/endpoints.d.ts.map +1 -1
- package/dist/pkgs/types/options.d.ts +2 -3
- package/dist/pkgs/types/options.d.ts.map +1 -1
- package/dist/pkgs/types/plugins.d.ts +2 -3
- package/dist/pkgs/types/plugins.d.ts.map +1 -1
- package/dist/pkgs/utils/index.d.ts +1 -0
- package/dist/pkgs/utils/index.d.ts.map +1 -1
- package/dist/pkgs/utils/logger.d.ts +16 -0
- package/dist/pkgs/utils/logger.d.ts.map +1 -0
- package/dist/router.cjs +1213 -0
- package/dist/router.d.ts +480 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +1169 -0
- package/dist/schema/audit-log/table.d.ts +1 -1
- package/dist/schema/consent/table.d.ts +1 -1
- package/dist/schema/consent-policy/registry.d.ts +12 -12
- package/dist/schema/consent-policy/schema.d.ts +6 -6
- package/dist/schema/consent-policy/table.d.ts +7 -7
- package/dist/schema/consent-purpose/registry.d.ts +6 -6
- package/dist/schema/consent-purpose/schema.d.ts +6 -6
- package/dist/schema/consent-purpose/table.d.ts +7 -7
- package/dist/schema/consent-record/table.d.ts +1 -1
- package/dist/schema/create-registry.d.ts +32 -32
- package/dist/schema/definition.d.ts +19 -19
- package/dist/schema/domain/registry.d.ts +10 -10
- package/dist/schema/domain/schema.d.ts +5 -5
- package/dist/schema/domain/table.d.ts +6 -6
- package/dist/schema/index.cjs +1409 -1775
- package/dist/schema/index.js +20 -385
- package/dist/schema/schemas.d.ts +19 -19
- package/dist/schema/subject/registry.d.ts +4 -4
- package/dist/schema/subject/schema.d.ts +2 -2
- package/dist/schema/subject/table.d.ts +3 -3
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/testing/contract-testing.d.ts +37 -0
- package/dist/testing/contract-testing.d.ts.map +1 -0
- package/dist/types/context.d.ts +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/options.d.ts +33 -2
- package/dist/types/options.d.ts.map +1 -1
- package/dist/types/plugins.d.ts +3 -4
- package/dist/types/plugins.d.ts.map +1 -1
- package/package.json +22 -30
- package/rslib.config.ts +2 -5
- package/src/contracts/consent/index.test.ts +5 -0
- package/src/contracts/consent/index.ts +9 -0
- package/src/contracts/consent/post.contract.test.ts +526 -0
- package/src/contracts/consent/post.contract.ts +160 -0
- package/src/contracts/consent/show-banner.contract.test.ts +214 -0
- package/src/contracts/consent/show-banner.contract.ts +45 -0
- package/src/contracts/consent/verify.contract.test.ts +185 -0
- package/src/contracts/consent/verify.contract.ts +126 -0
- package/src/contracts/index.ts +18 -0
- package/src/contracts/meta/index.test.ts +5 -0
- package/src/contracts/meta/index.ts +5 -0
- package/src/contracts/meta/status.contract.test.ts +338 -0
- package/src/contracts/meta/status.contract.ts +37 -0
- package/src/contracts/shared/jurisdiction.schema.ts +30 -0
- package/src/core.ts +451 -159
- package/src/handlers/consent/index.ts +9 -0
- package/src/handlers/consent/post.handler.ts +273 -0
- package/src/handlers/consent/show-banner.handler.test.ts +148 -0
- package/src/handlers/consent/show-banner.handler.ts +150 -0
- package/src/handlers/consent/verify.handler.ts +305 -0
- package/src/handlers/meta/index.ts +5 -0
- package/src/handlers/meta/status.handler.ts +47 -0
- package/src/init.ts +8 -5
- package/src/pkgs/api-router/hooks/__tests__/processor.test.ts +6 -0
- package/src/pkgs/api-router/hooks/processor.ts +2 -0
- package/src/pkgs/api-router/types/router-props.ts +1 -1
- package/src/pkgs/api-router/utils/cors.ts +1 -1
- package/src/pkgs/data-model/fields/field-types.ts +1 -1
- package/src/pkgs/data-model/fields/id-generator.ts +1 -1
- package/src/pkgs/db-adapters/README.md +3 -3
- package/src/pkgs/db-adapters/adapter-factory.ts +8 -4
- package/src/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.ts +13 -13
- package/src/pkgs/db-adapters/adapters/kysely-adapter/dialect.ts +1 -1
- package/src/pkgs/db-adapters/adapters/kysely-adapter/tests/postgres.test.ts +1 -1
- package/src/pkgs/db-adapters/adapters/kysely-adapter/tests/sqlite.test.ts +1 -1
- package/src/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.ts +2 -2
- package/src/pkgs/migrations/get-migration.ts +3 -3
- package/src/pkgs/migrations/get-schema/get-schema.ts +2 -2
- package/src/pkgs/migrations/get-schema/index.ts +1 -1
- package/src/pkgs/migrations/migration-builders.ts +2 -2
- package/src/pkgs/migrations/migration-execution.ts +2 -2
- package/src/pkgs/migrations/schema-comparison.ts +5 -4
- package/src/pkgs/results/__tests__/error-class.test.ts +8 -7
- package/src/pkgs/results/core/error-class.ts +31 -43
- package/src/pkgs/results/index.ts +0 -10
- package/src/pkgs/results/orpc-error-handler.ts +137 -0
- package/src/pkgs/results/types.ts +8 -7
- package/src/pkgs/types/context.ts +18 -4
- package/src/pkgs/types/endpoints.ts +3 -5
- package/src/pkgs/types/options.ts +2 -3
- package/src/pkgs/types/plugins.ts +2 -3
- package/src/pkgs/utils/index.ts +1 -0
- package/src/pkgs/utils/logger.ts +38 -0
- package/src/router.ts +8 -0
- package/src/schema/audit-log/table.ts +1 -1
- package/src/schema/consent/table.ts +1 -1
- package/src/schema/consent-policy/table.ts +1 -1
- package/src/schema/consent-purpose/table.ts +1 -1
- package/src/schema/consent-record/table.ts +1 -1
- package/src/schema/definition.ts +2 -2
- package/src/schema/domain/table.ts +1 -1
- package/src/schema/subject/table.ts +1 -1
- package/src/server.ts +130 -0
- package/src/testing/contract-testing.ts +437 -0
- package/src/types/context.ts +1 -1
- package/src/types/index.ts +2 -2
- package/src/types/options.ts +38 -2
- package/src/types/plugins.ts +3 -4
- package/dist/index.cjs +0 -3701
- package/dist/index.d.ts +0 -11
- package/dist/index.d.ts.map +0 -1
- package/dist/init.test.d.ts +0 -2
- package/dist/init.test.d.ts.map +0 -1
- package/dist/integrations/cloudflare.cjs +0 -312
- package/dist/integrations/cloudflare.d.ts +0 -32
- package/dist/integrations/cloudflare.d.ts.map +0 -1
- package/dist/integrations/cloudflare.js +0 -278
- package/dist/integrations/next.cjs +0 -276
- package/dist/integrations/next.d.ts +0 -68
- package/dist/integrations/next.d.ts.map +0 -1
- package/dist/integrations/next.js +0 -239
- package/dist/integrations/node.cjs +0 -257
- package/dist/integrations/node.d.ts +0 -29
- package/dist/integrations/node.d.ts.map +0 -1
- package/dist/integrations/node.js +0 -223
- package/dist/pkgs/api-router/index.d.ts +0 -9
- package/dist/pkgs/api-router/index.d.ts.map +0 -1
- package/dist/pkgs/api-router/utils/define-route.d.ts +0 -87
- package/dist/pkgs/api-router/utils/define-route.d.ts.map +0 -1
- package/dist/pkgs/logger/__tests__/console-formatter.test.d.ts +0 -2
- package/dist/pkgs/logger/__tests__/console-formatter.test.d.ts.map +0 -1
- package/dist/pkgs/logger/__tests__/integration.test.d.ts +0 -2
- package/dist/pkgs/logger/__tests__/integration.test.d.ts.map +0 -1
- package/dist/pkgs/logger/__tests__/log-levels.test.d.ts +0 -2
- package/dist/pkgs/logger/__tests__/log-levels.test.d.ts.map +0 -1
- package/dist/pkgs/logger/__tests__/logger-factory.test.d.ts +0 -2
- package/dist/pkgs/logger/__tests__/logger-factory.test.d.ts.map +0 -1
- package/dist/pkgs/logger/__tests__/result-logging.test.d.ts +0 -2
- package/dist/pkgs/logger/__tests__/result-logging.test.d.ts.map +0 -1
- package/dist/pkgs/logger/__tests__/types.test.d.ts +0 -2
- package/dist/pkgs/logger/__tests__/types.test.d.ts.map +0 -1
- package/dist/pkgs/logger/console-formatter.d.ts +0 -56
- package/dist/pkgs/logger/console-formatter.d.ts.map +0 -1
- package/dist/pkgs/logger/index.cjs +0 -240
- package/dist/pkgs/logger/index.d.ts +0 -35
- package/dist/pkgs/logger/index.d.ts.map +0 -1
- package/dist/pkgs/logger/index.js +0 -185
- package/dist/pkgs/logger/log-levels.d.ts +0 -29
- package/dist/pkgs/logger/log-levels.d.ts.map +0 -1
- package/dist/pkgs/logger/logger-factory.d.ts +0 -42
- package/dist/pkgs/logger/logger-factory.d.ts.map +0 -1
- package/dist/pkgs/logger/result-logging.d.ts +0 -71
- package/dist/pkgs/logger/result-logging.d.ts.map +0 -1
- package/dist/pkgs/logger/telemetry.d.ts +0 -14
- package/dist/pkgs/logger/telemetry.d.ts.map +0 -1
- package/dist/pkgs/logger/types.d.ts +0 -121
- package/dist/pkgs/logger/types.d.ts.map +0 -1
- package/dist/pkgs/results/__tests__/retrieval-pipeline.test.d.ts +0 -2
- package/dist/pkgs/results/__tests__/retrieval-pipeline.test.d.ts.map +0 -1
- package/dist/pkgs/results/__tests__/validation-pipeline.test.d.ts +0 -2
- package/dist/pkgs/results/__tests__/validation-pipeline.test.d.ts.map +0 -1
- package/dist/pkgs/results/h3-integration.d.ts +0 -52
- package/dist/pkgs/results/h3-integration.d.ts.map +0 -1
- package/dist/pkgs/results/pipeline/retrieval-pipeline.d.ts +0 -101
- package/dist/pkgs/results/pipeline/retrieval-pipeline.d.ts.map +0 -1
- package/dist/pkgs/results/pipeline/validation-pipeline.d.ts +0 -89
- package/dist/pkgs/results/pipeline/validation-pipeline.d.ts.map +0 -1
- package/dist/response-types.d.ts +0 -19
- package/dist/response-types.d.ts.map +0 -1
- package/dist/routes/__test__/index.test.d.ts +0 -17
- package/dist/routes/__test__/index.test.d.ts.map +0 -1
- package/dist/routes/__test__/set-consent.test.d.ts +0 -2
- package/dist/routes/__test__/set-consent.test.d.ts.map +0 -1
- package/dist/routes/__test__/show-consent-banner.test.d.ts +0 -2
- package/dist/routes/__test__/show-consent-banner.test.d.ts.map +0 -1
- package/dist/routes/__test__/status.test.d.ts +0 -2
- package/dist/routes/__test__/status.test.d.ts.map +0 -1
- package/dist/routes/__test__/verify-consent.test.d.ts +0 -2
- package/dist/routes/__test__/verify-consent.test.d.ts.map +0 -1
- package/dist/routes/index.d.ts +0 -3
- package/dist/routes/index.d.ts.map +0 -1
- package/dist/routes/set-consent.d.ts +0 -89
- package/dist/routes/set-consent.d.ts.map +0 -1
- package/dist/routes/show-consent-banner.d.ts +0 -15
- package/dist/routes/show-consent-banner.d.ts.map +0 -1
- package/dist/routes/status.d.ts +0 -44
- package/dist/routes/status.d.ts.map +0 -1
- package/dist/routes/types.d.ts +0 -7
- package/dist/routes/types.d.ts.map +0 -1
- package/dist/routes/verify-consent.d.ts +0 -38
- package/dist/routes/verify-consent.d.ts.map +0 -1
- package/src/docs/ADVANCED_JSON_HANDLING.md +0 -99
- package/src/docs/neverthrow.md +0 -171
- package/src/index.ts +0 -34
- package/src/init.test.ts +0 -219
- package/src/integrations/cloudflare.ts +0 -269
- package/src/integrations/next.ts +0 -204
- package/src/integrations/node.ts +0 -141
- package/src/pkgs/api-router/index.ts +0 -148
- package/src/pkgs/api-router/types/h3.d.ts +0 -42
- package/src/pkgs/api-router/utils/define-route.ts +0 -410
- package/src/pkgs/logger/README.md +0 -213
- package/src/pkgs/logger/__tests__/console-formatter.test.ts +0 -67
- package/src/pkgs/logger/__tests__/integration.test.ts +0 -184
- package/src/pkgs/logger/__tests__/log-levels.test.ts +0 -77
- package/src/pkgs/logger/__tests__/logger-factory.test.ts +0 -156
- package/src/pkgs/logger/__tests__/result-logging.test.ts +0 -209
- package/src/pkgs/logger/__tests__/types.test.ts +0 -94
- package/src/pkgs/logger/console-formatter.ts +0 -75
- package/src/pkgs/logger/doc.md +0 -569
- package/src/pkgs/logger/index.ts +0 -59
- package/src/pkgs/logger/log-levels.ts +0 -46
- package/src/pkgs/logger/logger-factory.ts +0 -121
- package/src/pkgs/logger/result-logging.ts +0 -134
- package/src/pkgs/logger/telemetry.ts +0 -96
- package/src/pkgs/logger/types.ts +0 -138
- package/src/pkgs/results/__tests__/retrieval-pipeline.test.ts +0 -157
- package/src/pkgs/results/__tests__/validation-pipeline.test.ts +0 -151
- package/src/pkgs/results/h3-integration.ts +0 -142
- package/src/pkgs/results/pipeline/retrieval-pipeline.ts +0 -188
- package/src/pkgs/results/pipeline/validation-pipeline.ts +0 -164
- package/src/plugins/.keep +0 -0
- package/src/response-types.ts +0 -29
- package/src/routes/__test__/index.test.ts +0 -112
- package/src/routes/__test__/set-consent.test.ts +0 -242
- package/src/routes/__test__/show-consent-banner.test.ts +0 -98
- package/src/routes/__test__/status.test.ts +0 -64
- package/src/routes/__test__/verify-consent.test.ts +0 -266
- package/src/routes/index.ts +0 -12
- package/src/routes/set-consent.ts +0 -249
- package/src/routes/show-consent-banner.ts +0 -131
- package/src/routes/status.ts +0 -61
- package/src/routes/types.ts +0 -7
- package/src/routes/verify-consent.ts +0 -206
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import { DoubleTieError } from '../core/error-class';
|
|
4
|
-
import { ERROR_CODES } from '../core/error-codes';
|
|
5
|
-
import { validationPipeline } from '../pipeline/validation-pipeline';
|
|
6
|
-
|
|
7
|
-
describe('validationPipeline', () => {
|
|
8
|
-
// Define a simple schema for testing
|
|
9
|
-
const userSchema = z.object({
|
|
10
|
-
name: z.string().min(2),
|
|
11
|
-
email: z.string().email(),
|
|
12
|
-
age: z.number().min(18),
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
// Define a simple transformer
|
|
16
|
-
const transformer = (data: z.infer<typeof userSchema>) => ({
|
|
17
|
-
...data,
|
|
18
|
-
nameUpperCase: data.name.toUpperCase(),
|
|
19
|
-
isAdult: data.age >= 18,
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it('should return a function that takes data to validate', () => {
|
|
23
|
-
const validate = validationPipeline(userSchema, transformer);
|
|
24
|
-
expect(typeof validate).toBe('function');
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('should validate and transform valid data successfully', () => {
|
|
28
|
-
const validate = validationPipeline(userSchema, transformer);
|
|
29
|
-
|
|
30
|
-
const validData = {
|
|
31
|
-
name: 'John',
|
|
32
|
-
email: 'john@example.com',
|
|
33
|
-
age: 25,
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const result = validate(validData);
|
|
37
|
-
|
|
38
|
-
expect(result.isOk()).toBe(true);
|
|
39
|
-
expect(result._unsafeUnwrap()).toEqual({
|
|
40
|
-
name: 'John',
|
|
41
|
-
email: 'john@example.com',
|
|
42
|
-
age: 25,
|
|
43
|
-
nameUpperCase: 'JOHN',
|
|
44
|
-
isAdult: true,
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('should return an error result when validation fails', () => {
|
|
49
|
-
const validate = validationPipeline(userSchema, transformer);
|
|
50
|
-
|
|
51
|
-
const invalidData = {
|
|
52
|
-
name: 'J', // Too short
|
|
53
|
-
email: 'not-an-email', // Invalid email
|
|
54
|
-
age: 16, // Below minimum age
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
const result = validate(invalidData);
|
|
58
|
-
|
|
59
|
-
expect(result.isErr()).toBe(true);
|
|
60
|
-
const error = result._unsafeUnwrapErr();
|
|
61
|
-
|
|
62
|
-
expect(error).toBeInstanceOf(DoubleTieError);
|
|
63
|
-
expect(error.code).toBe(ERROR_CODES.INVALID_REQUEST);
|
|
64
|
-
expect(error.statusCode).toBe(400);
|
|
65
|
-
expect(error.meta).toBeDefined();
|
|
66
|
-
expect(error.meta.validationErrors).toBeDefined();
|
|
67
|
-
|
|
68
|
-
// Check that validation errors contain the expected fields
|
|
69
|
-
const validationErrors = error.meta.validationErrors as z.ZodIssue[];
|
|
70
|
-
|
|
71
|
-
// Verify we have all three validation errors
|
|
72
|
-
expect(validationErrors).toHaveLength(3);
|
|
73
|
-
|
|
74
|
-
// Find errors for each field by their path
|
|
75
|
-
const nameError = validationErrors.find((e) => e.path[0] === 'name');
|
|
76
|
-
const emailError = validationErrors.find((e) => e.path[0] === 'email');
|
|
77
|
-
const ageError = validationErrors.find((e) => e.path[0] === 'age');
|
|
78
|
-
|
|
79
|
-
// Verify each error exists
|
|
80
|
-
expect(nameError).toBeDefined();
|
|
81
|
-
expect(emailError).toBeDefined();
|
|
82
|
-
expect(ageError).toBeDefined();
|
|
83
|
-
|
|
84
|
-
// Verify specific error messages
|
|
85
|
-
expect(nameError?.message).toBe(
|
|
86
|
-
'String must contain at least 2 character(s)'
|
|
87
|
-
);
|
|
88
|
-
expect(emailError?.message).toBe('Invalid email');
|
|
89
|
-
expect(ageError?.message).toBe(
|
|
90
|
-
'Number must be greater than or equal to 18'
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
// Verify error codes
|
|
94
|
-
expect(nameError?.code).toBe('too_small');
|
|
95
|
-
expect(emailError?.code).toBe('invalid_string');
|
|
96
|
-
expect(ageError?.code).toBe('too_small');
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it('should return an error result when transformer throws', () => {
|
|
100
|
-
const errorThrowingTransformer = vi.fn().mockImplementation(() => {
|
|
101
|
-
throw new Error('Transformation error');
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
const validate = validationPipeline(userSchema, errorThrowingTransformer);
|
|
105
|
-
|
|
106
|
-
const validData = {
|
|
107
|
-
name: 'John',
|
|
108
|
-
email: 'john@example.com',
|
|
109
|
-
age: 25,
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
const result = validate(validData);
|
|
113
|
-
|
|
114
|
-
expect(result.isErr()).toBe(true);
|
|
115
|
-
const error = result._unsafeUnwrapErr();
|
|
116
|
-
|
|
117
|
-
expect(error).toBeInstanceOf(DoubleTieError);
|
|
118
|
-
expect(error.code).toBe(ERROR_CODES.BAD_REQUEST);
|
|
119
|
-
expect(error.cause).toBeInstanceOf(Error);
|
|
120
|
-
expect(error.cause instanceof Error && error.cause.message).toBe(
|
|
121
|
-
'Transformation error'
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
// Check that the transformer was called with the validated data
|
|
125
|
-
expect(errorThrowingTransformer).toHaveBeenCalledWith(validData);
|
|
126
|
-
|
|
127
|
-
// Check that the input data is included in the metadata
|
|
128
|
-
expect(error.meta.inputData).toEqual(validData);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it('should handle different schema types correctly', () => {
|
|
132
|
-
// Array schema
|
|
133
|
-
const arraySchema = z.array(z.string());
|
|
134
|
-
const arrayTransformer = (data: string[]) =>
|
|
135
|
-
data.map((item) => item.toUpperCase());
|
|
136
|
-
const validateArray = validationPipeline(arraySchema, arrayTransformer);
|
|
137
|
-
|
|
138
|
-
const arrayResult = validateArray(['a', 'b', 'c']);
|
|
139
|
-
expect(arrayResult.isOk()).toBe(true);
|
|
140
|
-
expect(arrayResult._unsafeUnwrap()).toEqual(['A', 'B', 'C']);
|
|
141
|
-
|
|
142
|
-
// Number schema
|
|
143
|
-
const numberSchema = z.number().positive();
|
|
144
|
-
const numberTransformer = (num: number) => num * 2;
|
|
145
|
-
const validateNumber = validationPipeline(numberSchema, numberTransformer);
|
|
146
|
-
|
|
147
|
-
const numberResult = validateNumber(5);
|
|
148
|
-
expect(numberResult.isOk()).toBe(true);
|
|
149
|
-
expect(numberResult._unsafeUnwrap()).toBe(10);
|
|
150
|
-
});
|
|
151
|
-
});
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import { eventHandler, sendError } from 'h3';
|
|
2
|
-
import type { H3Event } from 'h3';
|
|
3
|
-
import { DoubleTieError } from './core/error-class';
|
|
4
|
-
import { ERROR_CODES } from './core/error-codes';
|
|
5
|
-
|
|
6
|
-
// Extend the H3 context type to include our custom _onError property
|
|
7
|
-
declare module 'h3' {
|
|
8
|
-
interface H3EventContext {
|
|
9
|
-
_onError?: (error: unknown) => unknown;
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Creates an H3 error handler middleware that properly handles DoubleTieError instances
|
|
15
|
-
*
|
|
16
|
-
* This utility ensures consistent error handling across your H3.js application and
|
|
17
|
-
* properly converts DoubleTieError objects to H3-compatible error responses.
|
|
18
|
-
*
|
|
19
|
-
* @returns An H3 event handler middleware for error handling
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* ```typescript
|
|
23
|
-
* import { createH3ErrorHandler } from '@doubletie/results';
|
|
24
|
-
* import { createApp } from 'h3';
|
|
25
|
-
*
|
|
26
|
-
* const app = createApp();
|
|
27
|
-
*
|
|
28
|
-
* // Register the error handler middleware
|
|
29
|
-
* app.use(createH3ErrorHandler());
|
|
30
|
-
*
|
|
31
|
-
* // Your routes...
|
|
32
|
-
* ```
|
|
33
|
-
*/
|
|
34
|
-
export function createH3ErrorHandler() {
|
|
35
|
-
return eventHandler((event) => {
|
|
36
|
-
// Attach our error handler to the event context
|
|
37
|
-
event.context._onError = (error: unknown) => {
|
|
38
|
-
event.context.logger.error('Error in H3 error handler', { error });
|
|
39
|
-
// Handle DoubleTieError instances
|
|
40
|
-
if (error instanceof DoubleTieError) {
|
|
41
|
-
event.context.logger.error(
|
|
42
|
-
'Handling DoubleTieError:',
|
|
43
|
-
error.statusCode,
|
|
44
|
-
error.message
|
|
45
|
-
);
|
|
46
|
-
// DoubleTieError is already an H3Error, so we can send it directly
|
|
47
|
-
return sendError(event, error);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// For other errors, create a new DoubleTieError
|
|
51
|
-
event.context.logger.error('Handling generic error', { error });
|
|
52
|
-
const dtError = new DoubleTieError(
|
|
53
|
-
error instanceof Error ? error.message : String(error),
|
|
54
|
-
{
|
|
55
|
-
code: ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
56
|
-
status: 500,
|
|
57
|
-
cause: error instanceof Error ? error : undefined,
|
|
58
|
-
}
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
return sendError(event, dtError);
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
// We need to call event.node.req.on('error') to handle connection errors
|
|
65
|
-
event.node.req.on('error', (err) => {
|
|
66
|
-
event.context.logger.error('Request error event triggered:', { err });
|
|
67
|
-
if (event.context._onError) {
|
|
68
|
-
event.context._onError(err);
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
// Continue with request processing
|
|
73
|
-
return;
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Wraps an H3 event handler with error handling for DoubleTieError
|
|
79
|
-
*
|
|
80
|
-
* @param handler - The event handler to wrap
|
|
81
|
-
* @returns A wrapped handler that automatically handles DoubleTieError instances
|
|
82
|
-
*
|
|
83
|
-
* @example
|
|
84
|
-
* ```typescript
|
|
85
|
-
* import { withH3ErrorHandling } from '@doubletie/results';
|
|
86
|
-
* import { eventHandler } from 'h3';
|
|
87
|
-
*
|
|
88
|
-
* app.use('/api/users', withH3ErrorHandling(
|
|
89
|
-
* eventHandler(async (event) => {
|
|
90
|
-
* // Your handler code that might throw DoubleTieError
|
|
91
|
-
* throw new DoubleTieError('User not found', {
|
|
92
|
-
* code: ERROR_CODES.NOT_FOUND,
|
|
93
|
-
* status: 404
|
|
94
|
-
* });
|
|
95
|
-
* })
|
|
96
|
-
* ));
|
|
97
|
-
* ```
|
|
98
|
-
*/
|
|
99
|
-
export function withH3ErrorHandling(
|
|
100
|
-
handler: (event: H3Event) => Promise<unknown> | unknown
|
|
101
|
-
) {
|
|
102
|
-
return eventHandler(async (event) => {
|
|
103
|
-
try {
|
|
104
|
-
return await handler(event);
|
|
105
|
-
} catch (error) {
|
|
106
|
-
event.context.logger.error('Error caught in withH3ErrorHandling:', {
|
|
107
|
-
error,
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
// Handle DoubleTieError instances
|
|
111
|
-
if (error instanceof DoubleTieError) {
|
|
112
|
-
event.context.logger.error(
|
|
113
|
-
'Handling DoubleTieError in wrapper:',
|
|
114
|
-
error.statusCode,
|
|
115
|
-
error.message
|
|
116
|
-
);
|
|
117
|
-
// DoubleTieError is already an H3Error, so we can send it directly
|
|
118
|
-
return sendError(event, error);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Use the context error handler if available
|
|
122
|
-
if (
|
|
123
|
-
event.context._onError &&
|
|
124
|
-
typeof event.context._onError === 'function'
|
|
125
|
-
) {
|
|
126
|
-
return event.context._onError(error);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Create and send a new DoubleTieError
|
|
130
|
-
const dtError = new DoubleTieError(
|
|
131
|
-
error instanceof Error ? error.message : String(error),
|
|
132
|
-
{
|
|
133
|
-
code: ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
134
|
-
status: 500,
|
|
135
|
-
cause: error instanceof Error ? error : undefined,
|
|
136
|
-
}
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
return sendError(event, dtError);
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
}
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
import { ResultAsync } from 'neverthrow';
|
|
2
|
-
import { DoubleTieError } from '../core/error-class';
|
|
3
|
-
import { ERROR_CODES } from '../core/error-codes';
|
|
4
|
-
import type { ErrorMessageType, SDKResultAsync } from '../types';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Creates a retrieval pipeline that fetches data asynchronously and transforms it.
|
|
8
|
-
* Handles errors in a standardized way and includes null/undefined checks.
|
|
9
|
-
*
|
|
10
|
-
* @template TRawData - Type of the raw data fetched from the source
|
|
11
|
-
* @template TTransformedData - Type of the data after transformation
|
|
12
|
-
*
|
|
13
|
-
* @param fetcher - Async function that fetches the raw data
|
|
14
|
-
* @param transformer - Function that transforms the raw data
|
|
15
|
-
* @param errorCode - Error code to use if the fetcher throws (defaults to NOT_FOUND)
|
|
16
|
-
* @returns A function that returns a ResultAsync with the transformed data or an error
|
|
17
|
-
*
|
|
18
|
-
* @remarks
|
|
19
|
-
* This function implements a common pattern for retrieving and transforming data from
|
|
20
|
-
* external sources like databases, APIs, or file systems. It handles:
|
|
21
|
-
*
|
|
22
|
-
* 1. Asynchronous data fetching with proper error handling
|
|
23
|
-
* 2. Null/undefined checks to detect missing resources
|
|
24
|
-
* 3. Data transformation to convert raw data to the desired format
|
|
25
|
-
* 4. Standardized error creation with appropriate error codes and metadata
|
|
26
|
-
*
|
|
27
|
-
* The pipeline is particularly useful for:
|
|
28
|
-
* - Database queries where records might not exist
|
|
29
|
-
* - API calls that may fail or return empty results
|
|
30
|
-
* - File system operations where files might be missing
|
|
31
|
-
*
|
|
32
|
-
* @see ERROR_CODES.NOT_FOUND for the default error code used when resources are missing
|
|
33
|
-
* @see validationPipeline for handling data validation
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* ```typescript
|
|
37
|
-
* import { retrievalPipeline, ERROR_CODES } from '@doubletie/results';
|
|
38
|
-
* import { db } from './database';
|
|
39
|
-
*
|
|
40
|
-
* // Define types for raw and transformed data
|
|
41
|
-
* interface UserRecord {
|
|
42
|
-
* id: string;
|
|
43
|
-
* first_name: string;
|
|
44
|
-
* last_name: string;
|
|
45
|
-
* email: string;
|
|
46
|
-
* created_at: string;
|
|
47
|
-
* }
|
|
48
|
-
*
|
|
49
|
-
* interface User {
|
|
50
|
-
* id: string;
|
|
51
|
-
* fullName: string;
|
|
52
|
-
* email: string;
|
|
53
|
-
* createdAt: Date;
|
|
54
|
-
* }
|
|
55
|
-
*
|
|
56
|
-
* // Create a retrieval pipeline for fetching users
|
|
57
|
-
* const getUserById = (userId: string) => {
|
|
58
|
-
* return retrievalPipeline<UserRecord, User>(
|
|
59
|
-
* // Fetcher function to get raw data
|
|
60
|
-
* async () => {
|
|
61
|
-
* return await db.users.findUnique({
|
|
62
|
-
* where: { id: userId }
|
|
63
|
-
* });
|
|
64
|
-
* },
|
|
65
|
-
*
|
|
66
|
-
* // Transformer function to format the data
|
|
67
|
-
* (record) => ({
|
|
68
|
-
* id: record.id,
|
|
69
|
-
* fullName: `${record.first_name} ${record.last_name}`,
|
|
70
|
-
* email: record.email,
|
|
71
|
-
* createdAt: new Date(record.created_at)
|
|
72
|
-
* }),
|
|
73
|
-
*
|
|
74
|
-
* // Custom error code for this specific resource type
|
|
75
|
-
* ERROR_CODES.USER_NOT_FOUND
|
|
76
|
-
* );
|
|
77
|
-
* };
|
|
78
|
-
*
|
|
79
|
-
* // Using the pipeline
|
|
80
|
-
* async function handleUserRequest(req, res) {
|
|
81
|
-
* const userId = req.params.id;
|
|
82
|
-
*
|
|
83
|
-
* const userResult = await getUserById(userId)();
|
|
84
|
-
*
|
|
85
|
-
* return userResult.match(
|
|
86
|
-
* (user) => {
|
|
87
|
-
* // Successfully retrieved and transformed the user
|
|
88
|
-
* return res.json(user);
|
|
89
|
-
* },
|
|
90
|
-
* (error) => {
|
|
91
|
-
* // Handle the error based on its code
|
|
92
|
-
* if (error.code === ERROR_CODES.USER_NOT_FOUND) {
|
|
93
|
-
* return res.status(404).json({ error: `User ${userId} not found` });
|
|
94
|
-
* }
|
|
95
|
-
*
|
|
96
|
-
* // Handle other errors
|
|
97
|
-
* console.error(`Error fetching user:`, error);
|
|
98
|
-
* return res.status(error.status).json({ error: error.message });
|
|
99
|
-
* }
|
|
100
|
-
* );
|
|
101
|
-
* }
|
|
102
|
-
* ```
|
|
103
|
-
*/
|
|
104
|
-
export const retrievalPipeline = <TRawData, TTransformedData>(
|
|
105
|
-
fetcher: () => Promise<TRawData>,
|
|
106
|
-
transformer: (data: TRawData) => TTransformedData,
|
|
107
|
-
errorCode: ErrorMessageType = ERROR_CODES.NOT_FOUND
|
|
108
|
-
): (() => SDKResultAsync<TTransformedData>) => {
|
|
109
|
-
return () => {
|
|
110
|
-
return ResultAsync.fromPromise(
|
|
111
|
-
fetcher().then((data) => {
|
|
112
|
-
// Check if data is null or undefined
|
|
113
|
-
if (data === null || data === undefined) {
|
|
114
|
-
throw new Error('Resource not found');
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
try {
|
|
118
|
-
// Transform the data (wrapping in try/catch to handle transformer errors)
|
|
119
|
-
return transformer(data);
|
|
120
|
-
} catch (transformerError) {
|
|
121
|
-
// Explicitly handle transformer errors as BAD_REQUEST
|
|
122
|
-
throw new DoubleTieError(
|
|
123
|
-
transformerError instanceof Error
|
|
124
|
-
? transformerError.message
|
|
125
|
-
: 'Error transforming data',
|
|
126
|
-
{
|
|
127
|
-
code: ERROR_CODES.BAD_REQUEST,
|
|
128
|
-
status: 400,
|
|
129
|
-
cause:
|
|
130
|
-
transformerError instanceof Error
|
|
131
|
-
? transformerError
|
|
132
|
-
: undefined,
|
|
133
|
-
}
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
}),
|
|
137
|
-
(error) => {
|
|
138
|
-
// If the error is already a DoubleTieError, return it directly
|
|
139
|
-
if (error instanceof DoubleTieError) {
|
|
140
|
-
return error;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Check if this is a custom error code or a standard one
|
|
144
|
-
const useCustomErrorCode = errorCode !== ERROR_CODES.NOT_FOUND;
|
|
145
|
-
|
|
146
|
-
// If a custom error code is provided, always use it
|
|
147
|
-
if (useCustomErrorCode) {
|
|
148
|
-
return new DoubleTieError(
|
|
149
|
-
error instanceof Error
|
|
150
|
-
? error.message
|
|
151
|
-
: 'Failed to retrieve resource',
|
|
152
|
-
{
|
|
153
|
-
code: errorCode,
|
|
154
|
-
status: 400, // Custom codes default to 400
|
|
155
|
-
cause: error instanceof Error ? error : undefined,
|
|
156
|
-
}
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Handle standard error cases
|
|
161
|
-
const isNotFoundError =
|
|
162
|
-
error instanceof Error &&
|
|
163
|
-
error.message.toLowerCase().includes('not found');
|
|
164
|
-
|
|
165
|
-
// Use specific error code based on error type
|
|
166
|
-
if (isNotFoundError) {
|
|
167
|
-
// Not found errors
|
|
168
|
-
return new DoubleTieError(error.message, {
|
|
169
|
-
code: ERROR_CODES.NOT_FOUND,
|
|
170
|
-
status: 404,
|
|
171
|
-
cause: error,
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
// All other errors use BAD_REQUEST
|
|
175
|
-
return new DoubleTieError(
|
|
176
|
-
error instanceof Error
|
|
177
|
-
? error.message
|
|
178
|
-
: 'Failed to retrieve resource',
|
|
179
|
-
{
|
|
180
|
-
code: ERROR_CODES.BAD_REQUEST,
|
|
181
|
-
status: 400,
|
|
182
|
-
cause: error instanceof Error ? error : undefined,
|
|
183
|
-
}
|
|
184
|
-
);
|
|
185
|
-
}
|
|
186
|
-
);
|
|
187
|
-
};
|
|
188
|
-
};
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import type { ZodSchema } from 'zod';
|
|
2
|
-
import { ERROR_CODES } from '../core/error-codes';
|
|
3
|
-
import { fail, ok } from '../results/result-helpers';
|
|
4
|
-
import type { SDKResult } from '../types';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Creates a validation pipeline that validates input data with a Zod schema
|
|
8
|
-
* and transforms it to an output format.
|
|
9
|
-
*
|
|
10
|
-
* @template TInput - Type of the input data after validation
|
|
11
|
-
* @template TOutput - Type of the output data after transformation
|
|
12
|
-
*
|
|
13
|
-
* @param schema - Zod schema to validate the input data
|
|
14
|
-
* @param transformer - Function to transform validated data
|
|
15
|
-
* @returns A function that takes input data and returns a Result with the transformed data or an error
|
|
16
|
-
*
|
|
17
|
-
* @remarks
|
|
18
|
-
* This function implements a common pattern for validating and transforming input data.
|
|
19
|
-
* It first validates the input using a Zod schema, and if valid, transforms it using
|
|
20
|
-
* the provided transformer function. If validation fails, it returns a well-structured
|
|
21
|
-
* error with validation details.
|
|
22
|
-
*
|
|
23
|
-
* The validation pipeline is particularly useful for:
|
|
24
|
-
* - API request body validation
|
|
25
|
-
* - Form data validation
|
|
26
|
-
* - Configuration validation
|
|
27
|
-
* - Data import/export validation
|
|
28
|
-
*
|
|
29
|
-
* The transformer function allows you to adapt the validated data to the shape
|
|
30
|
-
* expected by your application logic.
|
|
31
|
-
*
|
|
32
|
-
* @see ValidationErrorDetails for the structure of validation errors
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* ```typescript
|
|
36
|
-
* import { z } from 'zod';
|
|
37
|
-
* import { validationPipeline, ERROR_CODES } from '@doubletie/results';
|
|
38
|
-
*
|
|
39
|
-
* // Define a schema for user input
|
|
40
|
-
* const userSchema = z.object({
|
|
41
|
-
* name: z.string().min(2).max(100),
|
|
42
|
-
* email: z.string().email(),
|
|
43
|
-
* age: z.number().int().min(18).optional(),
|
|
44
|
-
* role: z.enum(['admin', 'user', 'guest'])
|
|
45
|
-
* });
|
|
46
|
-
*
|
|
47
|
-
* // Type inferred from schema
|
|
48
|
-
* type UserInput = z.infer<typeof userSchema>;
|
|
49
|
-
*
|
|
50
|
-
* // Type for the transformed output
|
|
51
|
-
* interface UserRecord {
|
|
52
|
-
* id: string;
|
|
53
|
-
* displayName: string;
|
|
54
|
-
* email: string;
|
|
55
|
-
* age?: number;
|
|
56
|
-
* role: string;
|
|
57
|
-
* createdAt: Date;
|
|
58
|
-
* }
|
|
59
|
-
*
|
|
60
|
-
* // Create a validation pipeline
|
|
61
|
-
* const validateUser = validationPipeline<UserInput, UserRecord>(
|
|
62
|
-
* userSchema,
|
|
63
|
-
* (validData) => ({
|
|
64
|
-
* id: generateId(),
|
|
65
|
-
* displayName: validData.name,
|
|
66
|
-
* email: validData.email.toLowerCase(),
|
|
67
|
-
* age: validData.age,
|
|
68
|
-
* role: validData.role,
|
|
69
|
-
* createdAt: new Date()
|
|
70
|
-
* })
|
|
71
|
-
* );
|
|
72
|
-
*
|
|
73
|
-
* // Using the pipeline
|
|
74
|
-
* function createUser(rawData: unknown) {
|
|
75
|
-
* const result = validateUser(rawData);
|
|
76
|
-
*
|
|
77
|
-
* return result.match(
|
|
78
|
-
* (user) => {
|
|
79
|
-
* // Work with validated and transformed data
|
|
80
|
-
* return saveUserToDatabase(user);
|
|
81
|
-
* },
|
|
82
|
-
* (error) => {
|
|
83
|
-
* // Handle validation errors
|
|
84
|
-
* console.error('Validation failed:', error.meta.validationErrors);
|
|
85
|
-
* throw error;
|
|
86
|
-
* }
|
|
87
|
-
* );
|
|
88
|
-
* }
|
|
89
|
-
* ```
|
|
90
|
-
*/
|
|
91
|
-
export const validationPipeline = <TInput, TOutput>(
|
|
92
|
-
schema: ZodSchema<TInput>,
|
|
93
|
-
transformer: (data: TInput) => TOutput
|
|
94
|
-
): ((data: unknown) => SDKResult<TOutput>) => {
|
|
95
|
-
return (data: unknown) => {
|
|
96
|
-
// Preprocess the data to handle stringified values
|
|
97
|
-
const preprocessData = (value: unknown): unknown => {
|
|
98
|
-
if (typeof value !== 'object' || value === null) {
|
|
99
|
-
// Try parsing stringified JSON values
|
|
100
|
-
if (typeof value === 'string') {
|
|
101
|
-
try {
|
|
102
|
-
// Check if it's a stringified array
|
|
103
|
-
if (value.startsWith('[') && value.endsWith(']')) {
|
|
104
|
-
return JSON.parse(value);
|
|
105
|
-
}
|
|
106
|
-
// Check if it's a stringified boolean
|
|
107
|
-
if (value.toLowerCase() === 'true') {
|
|
108
|
-
return true;
|
|
109
|
-
}
|
|
110
|
-
if (value.toLowerCase() === 'false') {
|
|
111
|
-
return false;
|
|
112
|
-
}
|
|
113
|
-
// Check if it's a stringified object
|
|
114
|
-
if (value.startsWith('{') && value.endsWith('}')) {
|
|
115
|
-
return JSON.parse(value);
|
|
116
|
-
}
|
|
117
|
-
} catch {
|
|
118
|
-
// If parsing fails, return original value
|
|
119
|
-
return value;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return value;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Handle arrays
|
|
126
|
-
if (Array.isArray(value)) {
|
|
127
|
-
return value.map(preprocessData);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Handle objects
|
|
131
|
-
const processed: Record<string, unknown> = {};
|
|
132
|
-
for (const [key, val] of Object.entries(value)) {
|
|
133
|
-
processed[key] = preprocessData(val);
|
|
134
|
-
}
|
|
135
|
-
return processed;
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
const preprocessedData = preprocessData(data);
|
|
139
|
-
const parseResult = schema.safeParse(preprocessedData);
|
|
140
|
-
|
|
141
|
-
if (!parseResult.success) {
|
|
142
|
-
return fail<TOutput>('Validation failed', {
|
|
143
|
-
code: ERROR_CODES.INVALID_REQUEST,
|
|
144
|
-
status: 400,
|
|
145
|
-
meta: {
|
|
146
|
-
validationErrors: parseResult.error.issues,
|
|
147
|
-
},
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
try {
|
|
152
|
-
return ok(transformer(parseResult.data));
|
|
153
|
-
} catch (error) {
|
|
154
|
-
return fail<TOutput>('Error transforming data after validation', {
|
|
155
|
-
code: ERROR_CODES.BAD_REQUEST,
|
|
156
|
-
status: 400,
|
|
157
|
-
cause: error instanceof Error ? error : undefined,
|
|
158
|
-
meta: {
|
|
159
|
-
inputData: parseResult.data,
|
|
160
|
-
},
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
};
|
package/src/plugins/.keep
DELETED
|
File without changes
|
package/src/response-types.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Public API Types
|
|
3
|
-
*
|
|
4
|
-
* This file exports all the types needed by client applications to interact with the API.
|
|
5
|
-
* It contains request and response type definitions for all public endpoints.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
// Import route definitions to extract their types
|
|
9
|
-
import type { z } from 'zod';
|
|
10
|
-
import type { RouteResponseType } from './pkgs/api-router/utils/define-route';
|
|
11
|
-
import type { setConsent } from './routes/set-consent';
|
|
12
|
-
import type { showConsentBanner } from './routes/show-consent-banner';
|
|
13
|
-
import type { verifyConsent } from './routes/verify-consent';
|
|
14
|
-
|
|
15
|
-
// Export the schemas
|
|
16
|
-
import type { SetConsentRequestBody as SetConsentRequestBodyZod } from './routes/set-consent';
|
|
17
|
-
import type { VerifyConsentRequestBody as VerifyConsentRequestBodyZod } from './routes/verify-consent';
|
|
18
|
-
|
|
19
|
-
// Export response types extracted directly from route definitions
|
|
20
|
-
export type SetConsentResponse = RouteResponseType<typeof setConsent>;
|
|
21
|
-
export type ShowConsentBannerResponse = RouteResponseType<
|
|
22
|
-
typeof showConsentBanner
|
|
23
|
-
>;
|
|
24
|
-
export type VerifyConsentResponse = RouteResponseType<typeof verifyConsent>;
|
|
25
|
-
|
|
26
|
-
export type SetConsentRequestBody = z.infer<typeof SetConsentRequestBodyZod>;
|
|
27
|
-
export type VerifyConsentRequestBody = z.infer<
|
|
28
|
-
typeof VerifyConsentRequestBodyZod
|
|
29
|
-
>;
|