silgi 0.43.29 → 0.50.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/README.md +103 -1
- package/dist/_virtual/_rolldown/runtime.mjs +5 -0
- package/dist/adapters/_fetch-adapter.d.mts +18 -0
- package/dist/adapters/_fetch-adapter.mjs +53 -0
- package/dist/adapters/astro.d.mts +15 -0
- package/dist/adapters/astro.mjs +31 -0
- package/dist/adapters/aws-lambda.d.mts +42 -0
- package/dist/adapters/aws-lambda.mjs +92 -0
- package/dist/adapters/express.d.mts +16 -0
- package/dist/adapters/express.mjs +110 -0
- package/dist/adapters/message-port.d.mts +42 -0
- package/dist/adapters/message-port.mjs +132 -0
- package/dist/adapters/nestjs.d.mts +25 -0
- package/dist/adapters/nestjs.mjs +83 -0
- package/dist/adapters/nextjs.d.mts +14 -0
- package/dist/adapters/nextjs.mjs +29 -0
- package/dist/adapters/peer.d.mts +27 -0
- package/dist/adapters/peer.mjs +36 -0
- package/dist/adapters/remix.d.mts +15 -0
- package/dist/adapters/remix.mjs +30 -0
- package/dist/adapters/solidstart.d.mts +12 -0
- package/dist/adapters/solidstart.mjs +29 -0
- package/dist/adapters/sveltekit.d.mts +14 -0
- package/dist/adapters/sveltekit.mjs +30 -0
- package/dist/broker/index.d.mts +62 -0
- package/dist/broker/index.mjs +153 -0
- package/dist/broker/nats.d.mts +33 -0
- package/dist/broker/nats.mjs +31 -0
- package/dist/broker/redis.d.mts +51 -0
- package/dist/broker/redis.mjs +92 -0
- package/dist/builder.d.mts +55 -0
- package/dist/builder.mjs +70 -0
- package/dist/callable.d.mts +19 -0
- package/dist/callable.mjs +42 -0
- package/dist/caller.mjs +90 -0
- package/dist/client/adapters/fetch/index.d.mts +15 -0
- package/dist/client/adapters/fetch/index.mjs +57 -0
- package/dist/client/adapters/ofetch/index.d.mts +55 -0
- package/dist/client/adapters/ofetch/index.mjs +91 -0
- package/dist/client/adapters/websocket/index.d.mts +20 -0
- package/dist/client/adapters/websocket/index.mjs +101 -0
- package/dist/client/client.d.mts +37 -0
- package/dist/client/client.mjs +80 -0
- package/dist/client/consume.d.mts +50 -0
- package/dist/client/consume.mjs +66 -0
- package/dist/client/dynamic-link.d.mts +16 -0
- package/dist/client/dynamic-link.mjs +19 -0
- package/dist/client/index.d.mts +6 -0
- package/dist/client/index.mjs +5 -0
- package/dist/client/interceptor.d.mts +31 -0
- package/dist/client/interceptor.mjs +34 -0
- package/dist/client/openapi.d.mts +29 -0
- package/dist/client/openapi.mjs +89 -0
- package/dist/client/plugins/batch.d.mts +26 -0
- package/dist/client/plugins/batch.mjs +64 -0
- package/dist/client/plugins/circuit-breaker.d.mts +24 -0
- package/dist/client/plugins/circuit-breaker.mjs +60 -0
- package/dist/client/plugins/csrf.d.mts +13 -0
- package/dist/client/plugins/csrf.mjs +20 -0
- package/dist/client/plugins/dedupe.d.mts +10 -0
- package/dist/client/plugins/dedupe.mjs +28 -0
- package/dist/client/plugins/index.d.mts +8 -0
- package/dist/client/plugins/index.mjs +8 -0
- package/dist/client/plugins/otel.d.mts +12 -0
- package/dist/client/plugins/otel.mjs +27 -0
- package/dist/client/plugins/retry.d.mts +34 -0
- package/dist/client/plugins/retry.mjs +79 -0
- package/dist/client/plugins/timeout.d.mts +10 -0
- package/dist/client/plugins/timeout.mjs +14 -0
- package/dist/client/server.d.mts +16 -0
- package/dist/client/server.mjs +59 -0
- package/dist/client/types.d.mts +29 -0
- package/dist/codec/devalue.d.mts +21 -0
- package/dist/codec/devalue.mjs +33 -0
- package/dist/codec/msgpack.d.mts +18 -0
- package/dist/codec/msgpack.mjs +45 -0
- package/dist/codec/sanitize.mjs +38 -0
- package/dist/codegen/emitters.d.mts +51 -0
- package/dist/codegen/emitters.mjs +143 -0
- package/dist/codegen/generate.d.mts +25 -0
- package/dist/codegen/generate.mjs +224 -0
- package/dist/codegen/index.d.mts +44 -0
- package/dist/codegen/index.mjs +103 -0
- package/dist/codegen/parse.d.mts +124 -0
- package/dist/codegen/parse.mjs +135 -0
- package/dist/codegen/preserve.d.mts +21 -0
- package/dist/codegen/preserve.mjs +62 -0
- package/dist/codegen/schema-to-code.d.mts +57 -0
- package/dist/codegen/schema-to-code.mjs +167 -0
- package/dist/compile.d.mts +46 -0
- package/dist/compile.mjs +332 -0
- package/dist/core/codec.mjs +67 -0
- package/dist/core/context-bridge.mjs +11 -0
- package/dist/core/dispatch.mjs +62 -0
- package/dist/core/error.d.mts +99 -60
- package/dist/core/error.mjs +125 -92
- package/dist/core/handler.d.mts +6 -0
- package/dist/core/handler.mjs +153 -0
- package/dist/core/input.mjs +49 -0
- package/dist/core/iterator.d.mts +17 -0
- package/dist/core/iterator.mjs +79 -0
- package/dist/core/router-utils.mjs +22 -0
- package/dist/core/schema.d.mts +20 -0
- package/dist/core/schema.mjs +33 -0
- package/dist/core/serve.d.mts +51 -0
- package/dist/core/serve.mjs +76 -0
- package/dist/core/sse.d.mts +18 -0
- package/dist/core/sse.mjs +110 -0
- package/dist/core/storage.d.mts +17 -4
- package/dist/core/storage.mjs +60 -13
- package/dist/core/task.d.mts +62 -0
- package/dist/core/task.mjs +165 -0
- package/dist/core/trace-map.d.mts +13 -0
- package/dist/core/trace-map.mjs +13 -0
- package/dist/core/url.mjs +28 -0
- package/dist/core/utils.mjs +24 -0
- package/dist/index.d.mts +17 -21
- package/dist/index.mjs +14 -22
- package/dist/integrations/ai/index.d.mts +25 -0
- package/dist/integrations/ai/index.mjs +117 -0
- package/dist/integrations/better-auth/index.d.mts +41 -0
- package/dist/integrations/better-auth/index.mjs +331 -0
- package/dist/integrations/drizzle/index.d.mts +27 -0
- package/dist/integrations/drizzle/index.mjs +285 -0
- package/dist/integrations/hey-api/index.d.mts +2 -0
- package/dist/integrations/hey-api/index.mjs +2 -0
- package/dist/integrations/hey-api/to-client.d.mts +20 -0
- package/dist/integrations/hey-api/to-client.mjs +39 -0
- package/dist/integrations/pinia-colada/general-utils.d.mts +13 -0
- package/dist/integrations/pinia-colada/general-utils.mjs +9 -0
- package/dist/integrations/pinia-colada/index.d.mts +6 -0
- package/dist/integrations/pinia-colada/index.mjs +5 -0
- package/dist/integrations/pinia-colada/key.d.mts +11 -0
- package/dist/integrations/pinia-colada/key.mjs +11 -0
- package/dist/integrations/pinia-colada/procedure-utils.d.mts +25 -0
- package/dist/integrations/pinia-colada/procedure-utils.mjs +33 -0
- package/dist/integrations/pinia-colada/router-utils.d.mts +17 -0
- package/dist/integrations/pinia-colada/router-utils.mjs +30 -0
- package/dist/integrations/pinia-colada/types.d.mts +25 -0
- package/dist/integrations/react/index.d.mts +83 -0
- package/dist/integrations/react/index.mjs +196 -0
- package/dist/integrations/tanstack-query/index.d.mts +120 -0
- package/dist/integrations/tanstack-query/index.mjs +100 -0
- package/dist/integrations/tanstack-query/ssr.d.mts +60 -0
- package/dist/integrations/tanstack-query/ssr.mjs +102 -0
- package/dist/integrations/zod/converter.d.mts +75 -0
- package/dist/integrations/zod/converter.mjs +345 -0
- package/dist/integrations/zod/index.d.mts +2 -0
- package/dist/integrations/zod/index.mjs +2 -0
- package/dist/lazy.d.mts +22 -0
- package/dist/lazy.mjs +34 -0
- package/dist/lifecycle.d.mts +36 -0
- package/dist/lifecycle.mjs +46 -0
- package/dist/map-input.d.mts +17 -0
- package/dist/map-input.mjs +47 -0
- package/dist/plugins/analytics/accumulator.d.mts +24 -0
- package/dist/plugins/analytics/accumulator.mjs +91 -0
- package/dist/plugins/analytics/alerts.d.mts +59 -0
- package/dist/plugins/analytics/alerts.mjs +140 -0
- package/dist/plugins/analytics/collector.d.mts +38 -0
- package/dist/plugins/analytics/collector.mjs +275 -0
- package/dist/plugins/analytics/cost.d.mts +61 -0
- package/dist/plugins/analytics/cost.mjs +97 -0
- package/dist/plugins/analytics/export.d.mts +7 -0
- package/dist/plugins/analytics/export.mjs +86 -0
- package/dist/plugins/analytics/normalize.mjs +144 -0
- package/dist/plugins/analytics/query.mjs +164 -0
- package/dist/plugins/analytics/request-id.mjs +34 -0
- package/dist/plugins/analytics/routes.d.mts +11 -0
- package/dist/plugins/analytics/routes.mjs +211 -0
- package/dist/plugins/analytics/sse.d.mts +31 -0
- package/dist/plugins/analytics/sse.mjs +74 -0
- package/dist/plugins/analytics/store.mjs +103 -0
- package/dist/plugins/analytics/timeseries.d.mts +50 -0
- package/dist/plugins/analytics/timeseries.mjs +169 -0
- package/dist/plugins/analytics/trace.d.mts +48 -0
- package/dist/plugins/analytics/trace.mjs +83 -0
- package/dist/plugins/analytics/types.d.mts +145 -0
- package/dist/plugins/analytics/types.mjs +40 -0
- package/dist/plugins/analytics/utils.d.mts +4 -0
- package/dist/plugins/analytics/utils.mjs +56 -0
- package/dist/plugins/analytics.d.mts +18 -0
- package/dist/plugins/analytics.mjs +188 -0
- package/dist/plugins/batch-server.d.mts +20 -0
- package/dist/plugins/batch-server.mjs +91 -0
- package/dist/plugins/body-limit.d.mts +19 -0
- package/dist/plugins/body-limit.mjs +49 -0
- package/dist/plugins/cache.d.mts +170 -0
- package/dist/plugins/cache.mjs +212 -0
- package/dist/plugins/coerce.d.mts +24 -0
- package/dist/plugins/coerce.mjs +70 -0
- package/dist/plugins/cookies.d.mts +14 -0
- package/dist/plugins/cookies.mjs +48 -0
- package/dist/plugins/cors.d.mts +43 -0
- package/dist/plugins/cors.mjs +62 -0
- package/dist/plugins/file-upload.d.mts +38 -0
- package/dist/plugins/file-upload.mjs +102 -0
- package/dist/plugins/index.d.mts +18 -0
- package/dist/plugins/index.mjs +17 -0
- package/dist/plugins/otel.d.mts +35 -0
- package/dist/plugins/otel.mjs +40 -0
- package/dist/plugins/pino.d.mts +60 -0
- package/dist/plugins/pino.mjs +42 -0
- package/dist/plugins/pubsub.d.mts +50 -0
- package/dist/plugins/pubsub.mjs +53 -0
- package/dist/plugins/ratelimit.d.mts +53 -0
- package/dist/plugins/ratelimit.mjs +92 -0
- package/dist/plugins/signing.d.mts +41 -0
- package/dist/plugins/signing.mjs +118 -0
- package/dist/plugins/strict-get.d.mts +10 -0
- package/dist/plugins/strict-get.mjs +33 -0
- package/dist/scalar.d.mts +49 -0
- package/dist/scalar.mjs +311 -0
- package/dist/silgi.d.mts +144 -0
- package/dist/silgi.mjs +164 -0
- package/dist/trpc-interop.d.mts +22 -0
- package/dist/trpc-interop.mjs +68 -0
- package/dist/types.d.mts +108 -0
- package/dist/ws.d.mts +88 -0
- package/dist/ws.mjs +205 -0
- package/lib/dashboard/index.html +120 -0
- package/lib/ocache.d.mts +1 -0
- package/lib/ocache.mjs +1 -0
- package/lib/ofetch.d.mts +1 -0
- package/lib/ofetch.mjs +1 -0
- package/lib/srvx.d.mts +1 -0
- package/lib/srvx.mjs +1 -0
- package/lib/unstorage.d.mts +1 -0
- package/lib/unstorage.mjs +1 -0
- package/package.json +314 -150
- package/dist/build.d.mts +0 -3
- package/dist/build.mjs +0 -4
- package/dist/cli/build/build.mjs +0 -15
- package/dist/cli/build/dev.d.mts +0 -10
- package/dist/cli/build/dev.mjs +0 -92
- package/dist/cli/build/prepare.d.mts +0 -6
- package/dist/cli/build/prepare.mjs +0 -15
- package/dist/cli/commands/commands.mjs +0 -90
- package/dist/cli/commands/env.mjs +0 -53
- package/dist/cli/commands/init.mjs +0 -84
- package/dist/cli/commands/install.mjs +0 -52
- package/dist/cli/commands/prepare.mjs +0 -65
- package/dist/cli/commands/reset.mjs +0 -46
- package/dist/cli/commands/run.mjs +0 -31
- package/dist/cli/commands/watch.mjs +0 -153
- package/dist/cli/config/defaults.mjs +0 -117
- package/dist/cli/config/index.d.mts +0 -3
- package/dist/cli/config/index.mjs +0 -4
- package/dist/cli/config/loader.d.mts +0 -6
- package/dist/cli/config/loader.mjs +0 -71
- package/dist/cli/config/resolvers/compatibility.mjs +0 -71
- package/dist/cli/config/resolvers/imports.mjs +0 -35
- package/dist/cli/config/resolvers/paths.mjs +0 -98
- package/dist/cli/config/resolvers/storage.mjs +0 -23
- package/dist/cli/config/resolvers/url.mjs +0 -9
- package/dist/cli/config/types.d.mts +0 -14
- package/dist/cli/config/types.mjs +0 -147
- package/dist/cli/core/apiful.mjs +0 -36
- package/dist/cli/core/devServer.mjs +0 -10
- package/dist/cli/core/env.mjs +0 -68
- package/dist/cli/core/installPackage.mjs +0 -60
- package/dist/cli/core/runtimeConfig.mjs +0 -70
- package/dist/cli/core/scan.mjs +0 -35
- package/dist/cli/core/silgi.mjs +0 -111
- package/dist/cli/framework/emptyFramework.mjs +0 -7
- package/dist/cli/framework/h3.mjs +0 -55
- package/dist/cli/framework/index.mjs +0 -15
- package/dist/cli/framework/nitro.mjs +0 -24
- package/dist/cli/framework/nuxt.mjs +0 -10
- package/dist/cli/index.d.mts +0 -1
- package/dist/cli/index.mjs +0 -29
- package/dist/cli/module/exportScan.mjs +0 -180
- package/dist/cli/module/install.mjs +0 -49
- package/dist/cli/module/scan.mjs +0 -193
- package/dist/cli/scan/prepareCommands.mjs +0 -40
- package/dist/cli/scan/prepareConfigs.mjs +0 -33
- package/dist/cli/scan/prepareCoreFile.mjs +0 -118
- package/dist/cli/scan/prepareScanFile.mjs +0 -59
- package/dist/cli/scan/prepareSchema.mjs +0 -128
- package/dist/cli/scan/scanExportFile.mjs +0 -288
- package/dist/cli/scan/writeCoreFile.mjs +0 -22
- package/dist/cli/scan/writeTypesAndFiles.mjs +0 -72
- package/dist/cli/utils/cancel.mjs +0 -14
- package/dist/cli/utils/common.mjs +0 -15
- package/dist/cli/utils/compatibility.mjs +0 -33
- package/dist/cli/utils/debug.mjs +0 -11
- package/dist/cli/utils/ignore.mjs +0 -56
- package/dist/cli/utils/processManager.mjs +0 -170
- package/dist/cli/utils/readScanFile.mjs +0 -58
- package/dist/cli/utils/storage.mjs +0 -23
- package/dist/core/context.d.mts +0 -30
- package/dist/core/context.mjs +0 -32
- package/dist/core/createSilgi.d.mts +0 -6
- package/dist/core/createSilgi.mjs +0 -153
- package/dist/core/event.d.mts +0 -26
- package/dist/core/event.mjs +0 -44
- package/dist/core/index.d.mts +0 -25
- package/dist/core/index.mjs +0 -30
- package/dist/core/orchestrate.mjs +0 -115
- package/dist/core/response.d.mts +0 -20
- package/dist/core/response.mjs +0 -105
- package/dist/core/silgi.d.mts +0 -19
- package/dist/core/silgi.mjs +0 -141
- package/dist/core/silgiApp.d.mts +0 -9
- package/dist/core/silgiApp.mjs +0 -23
- package/dist/core/unctx.d.mts +0 -21
- package/dist/core/unctx.mjs +0 -35
- package/dist/core/utils/event-stream.d.mts +0 -53
- package/dist/core/utils/event-stream.mjs +0 -38
- package/dist/core/utils/event.d.mts +0 -8
- package/dist/core/utils/event.mjs +0 -12
- package/dist/core/utils/internal/event-stream.d.mts +0 -45
- package/dist/core/utils/internal/event-stream.mjs +0 -137
- package/dist/core/utils/internal/obj.mjs +0 -9
- package/dist/core/utils/internal/object.mjs +0 -29
- package/dist/core/utils/internal/query.mjs +0 -73
- package/dist/core/utils/internal/req.mjs +0 -35
- package/dist/core/utils/merge.d.mts +0 -14
- package/dist/core/utils/merge.mjs +0 -27
- package/dist/core/utils/middleware.d.mts +0 -14
- package/dist/core/utils/middleware.mjs +0 -12
- package/dist/core/utils/request.mjs +0 -35
- package/dist/core/utils/resolver.d.mts +0 -7
- package/dist/core/utils/resolver.mjs +0 -29
- package/dist/core/utils/runtime.d.mts +0 -7
- package/dist/core/utils/runtime.mjs +0 -20
- package/dist/core/utils/sanitize.mjs +0 -22
- package/dist/core/utils/schema.d.mts +0 -34
- package/dist/core/utils/schema.mjs +0 -33
- package/dist/core/utils/service.d.mts +0 -13
- package/dist/core/utils/service.mjs +0 -19
- package/dist/core/utils/shared.d.mts +0 -6
- package/dist/core/utils/shared.mjs +0 -7
- package/dist/core/utils/storage.d.mts +0 -24
- package/dist/core/utils/storage.mjs +0 -54
- package/dist/kit/add/add-commands.d.mts +0 -6
- package/dist/kit/add/add-commands.mjs +0 -12
- package/dist/kit/add/add-core-file.d.mts +0 -9
- package/dist/kit/add/add-core-file.mjs +0 -11
- package/dist/kit/add/add-imports.d.mts +0 -14
- package/dist/kit/add/add-imports.mjs +0 -56
- package/dist/kit/add/add-npm.d.mts +0 -14
- package/dist/kit/add/add-npm.mjs +0 -23
- package/dist/kit/define.d.mts +0 -28
- package/dist/kit/define.mjs +0 -25
- package/dist/kit/errors.d.mts +0 -6
- package/dist/kit/errors.mjs +0 -11
- package/dist/kit/esm.d.mts +0 -11
- package/dist/kit/esm.mjs +0 -21
- package/dist/kit/fs.d.mts +0 -4
- package/dist/kit/fs.mjs +0 -13
- package/dist/kit/function-utils.d.mts +0 -27
- package/dist/kit/function-utils.mjs +0 -75
- package/dist/kit/gen.d.mts +0 -5
- package/dist/kit/gen.mjs +0 -26
- package/dist/kit/hash.d.mts +0 -4
- package/dist/kit/hash.mjs +0 -10
- package/dist/kit/index.d.mts +0 -22
- package/dist/kit/index.mjs +0 -23
- package/dist/kit/isFramework.d.mts +0 -6
- package/dist/kit/isFramework.mjs +0 -21
- package/dist/kit/logger.d.mts +0 -6
- package/dist/kit/logger.mjs +0 -10
- package/dist/kit/migration.d.mts +0 -113
- package/dist/kit/migration.mjs +0 -301
- package/dist/kit/module.d.mts +0 -14
- package/dist/kit/module.mjs +0 -53
- package/dist/kit/path.d.mts +0 -7
- package/dist/kit/path.mjs +0 -26
- package/dist/kit/preset.d.mts +0 -8
- package/dist/kit/preset.mjs +0 -11
- package/dist/kit/resolve.d.mts +0 -37
- package/dist/kit/resolve.mjs +0 -82
- package/dist/kit/template.d.mts +0 -19
- package/dist/kit/template.mjs +0 -91
- package/dist/kit/useRequest.d.mts +0 -19
- package/dist/kit/useRequest.mjs +0 -63
- package/dist/kit/utils.d.mts +0 -34
- package/dist/kit/utils.mjs +0 -91
- package/dist/package.mjs +0 -176
- package/dist/presets/_all.gen.d.mts +0 -6
- package/dist/presets/_all.gen.mjs +0 -18
- package/dist/presets/_resolve.d.mts +0 -12
- package/dist/presets/_resolve.mjs +0 -57
- package/dist/presets/_types.gen.d.mts +0 -8
- package/dist/presets/_types.gen.mjs +0 -5
- package/dist/presets/h3/preset.d.mts +0 -6
- package/dist/presets/h3/preset.mjs +0 -35
- package/dist/presets/hono/preset.d.mts +0 -6
- package/dist/presets/hono/preset.mjs +0 -30
- package/dist/presets/index.d.mts +0 -3
- package/dist/presets/index.mjs +0 -3
- package/dist/presets/nitro/preset.d.mts +0 -6
- package/dist/presets/nitro/preset.mjs +0 -37
- package/dist/presets/npmpackage/preset.d.mts +0 -6
- package/dist/presets/npmpackage/preset.mjs +0 -29
- package/dist/presets/nuxt/preset.d.mts +0 -6
- package/dist/presets/nuxt/preset.mjs +0 -41
- package/dist/runtime/index.d.mts +0 -4
- package/dist/runtime/index.mjs +0 -5
- package/dist/runtime/internal/config.d.mts +0 -11
- package/dist/runtime/internal/config.mjs +0 -97
- package/dist/runtime/internal/debug.d.mts +0 -6
- package/dist/runtime/internal/debug.mjs +0 -11
- package/dist/runtime/internal/defu.d.mts +0 -4
- package/dist/runtime/internal/defu.mjs +0 -9
- package/dist/runtime/internal/index.d.mts +0 -7
- package/dist/runtime/internal/index.mjs +0 -8
- package/dist/runtime/internal/nitro.d.mts +0 -6
- package/dist/runtime/internal/nitro.mjs +0 -36
- package/dist/runtime/internal/nuxt.d.mts +0 -12
- package/dist/runtime/internal/nuxt.mjs +0 -16
- package/dist/runtime/internal/ofetch.d.mts +0 -8
- package/dist/runtime/internal/ofetch.mjs +0 -39
- package/dist/runtime/internal/plugin.d.mts +0 -7
- package/dist/runtime/internal/plugin.mjs +0 -8
- package/dist/types/cliConfig.d.mts +0 -288
- package/dist/types/cliConfig.mjs +0 -0
- package/dist/types/cliHooks.d.mts +0 -142
- package/dist/types/cliHooks.mjs +0 -0
- package/dist/types/compatibility.d.mts +0 -13
- package/dist/types/compatibility.mjs +0 -0
- package/dist/types/config.d.mts +0 -46
- package/dist/types/config.mjs +0 -0
- package/dist/types/dotenv.d.mts +0 -29
- package/dist/types/dotenv.mjs +0 -0
- package/dist/types/event.d.mts +0 -63
- package/dist/types/event.mjs +0 -0
- package/dist/types/global.d.mts +0 -24
- package/dist/types/global.mjs +0 -0
- package/dist/types/helper.d.mts +0 -25
- package/dist/types/helper.mjs +0 -0
- package/dist/types/hooks.d.mts +0 -37
- package/dist/types/hooks.mjs +0 -0
- package/dist/types/index.d.mts +0 -26
- package/dist/types/index.mjs +0 -0
- package/dist/types/kits.d.mts +0 -32
- package/dist/types/kits.mjs +0 -0
- package/dist/types/middleware.d.mts +0 -31
- package/dist/types/middleware.mjs +0 -0
- package/dist/types/module.d.mts +0 -102
- package/dist/types/module.mjs +0 -0
- package/dist/types/preset.d.mts +0 -20
- package/dist/types/preset.mjs +0 -0
- package/dist/types/route.d.mts +0 -59
- package/dist/types/route.mjs +0 -0
- package/dist/types/runtime/index.d.mts +0 -5
- package/dist/types/runtime/index.mjs +0 -0
- package/dist/types/runtime/nuxt.d.mts +0 -13
- package/dist/types/runtime/nuxt.mjs +0 -0
- package/dist/types/runtime/ofetch.d.mts +0 -14
- package/dist/types/runtime/ofetch.mjs +0 -0
- package/dist/types/runtime/plugin.d.mts +0 -8
- package/dist/types/runtime/plugin.mjs +0 -0
- package/dist/types/runtime/silgi.d.mts +0 -11
- package/dist/types/runtime/silgi.mjs +0 -0
- package/dist/types/schema.d.mts +0 -86
- package/dist/types/schema.mjs +0 -0
- package/dist/types/service.d.mts +0 -102
- package/dist/types/service.mjs +0 -0
- package/dist/types/shared.d.mts +0 -19
- package/dist/types/shared.mjs +0 -0
- package/dist/types/silgi.d.mts +0 -71
- package/dist/types/silgi.mjs +0 -0
- package/dist/types/silgiCLI.d.mts +0 -118
- package/dist/types/silgiCLI.mjs +0 -0
- package/dist/types/standard-schema.d.mts +0 -61
- package/dist/types/standard-schema.mjs +0 -0
- package/dist/types/storage.d.mts +0 -30
- package/dist/types/storage.mjs +0 -0
- package/dist/types/tree-kill.d.mts +0 -18
- package/dist/types/tree-kill.mjs +0 -0
- package/lib/config.d.mts +0 -7
- package/lib/config.mjs +0 -5
- package/lib/meta.d.mts +0 -4
- package/lib/meta.mjs +0 -6
- package/lib/runtime-meta.d.mts +0 -4
- package/lib/runtime-meta.mjs +0 -32
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
//#region src/codegen/emitters.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Schema emitters — code generation strategies for each Standard Schema library.
|
|
4
|
+
*
|
|
5
|
+
* Each emitter knows how to produce code strings for a specific validation library.
|
|
6
|
+
* The generic converter delegates to the active emitter.
|
|
7
|
+
*/
|
|
8
|
+
type SchemaTarget = 'zod' | 'valibot' | 'arktype';
|
|
9
|
+
interface SchemaEmitter {
|
|
10
|
+
/** Import statement for the generated file */
|
|
11
|
+
importStatement: string;
|
|
12
|
+
/** Type inference helper: wraps a schema reference to extract its inferred type */
|
|
13
|
+
inferType(schemaExpr: string): string;
|
|
14
|
+
string(): string;
|
|
15
|
+
number(): string;
|
|
16
|
+
int(): string;
|
|
17
|
+
boolean(): string;
|
|
18
|
+
null(): string;
|
|
19
|
+
unknown(): string;
|
|
20
|
+
email(): string;
|
|
21
|
+
url(): string;
|
|
22
|
+
uuid(): string;
|
|
23
|
+
datetime(): string;
|
|
24
|
+
date(): string;
|
|
25
|
+
ipv4(): string;
|
|
26
|
+
ipv6(): string;
|
|
27
|
+
min(base: string, n: number): string;
|
|
28
|
+
max(base: string, n: number): string;
|
|
29
|
+
gt(base: string, n: number): string;
|
|
30
|
+
lt(base: string, n: number): string;
|
|
31
|
+
regex(base: string, pattern: string): string;
|
|
32
|
+
literal(value: unknown): string;
|
|
33
|
+
enum(values: unknown[]): string;
|
|
34
|
+
array(items: string): string;
|
|
35
|
+
object(entries: {
|
|
36
|
+
key: string;
|
|
37
|
+
value: string;
|
|
38
|
+
required: boolean;
|
|
39
|
+
}[]): string;
|
|
40
|
+
record(keySchema: string, valueSchema: string): string;
|
|
41
|
+
union(members: string[]): string;
|
|
42
|
+
discriminatedUnion(discriminator: string, members: string[]): string;
|
|
43
|
+
intersection(parts: string[]): string;
|
|
44
|
+
optional(base: string): string;
|
|
45
|
+
nullable(base: string): string;
|
|
46
|
+
default(base: string, value: unknown): string;
|
|
47
|
+
describe(base: string, description: string): string;
|
|
48
|
+
}
|
|
49
|
+
declare function getEmitter(target: SchemaTarget): SchemaEmitter;
|
|
50
|
+
//#endregion
|
|
51
|
+
export { SchemaEmitter, SchemaTarget, getEmitter };
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
//#region src/codegen/emitters.ts
|
|
2
|
+
const zodEmitter = {
|
|
3
|
+
importStatement: "import { z } from 'zod'",
|
|
4
|
+
inferType: (expr) => `z.infer<typeof ${expr}>`,
|
|
5
|
+
string: () => "z.string()",
|
|
6
|
+
number: () => "z.number()",
|
|
7
|
+
int: () => "z.int()",
|
|
8
|
+
boolean: () => "z.boolean()",
|
|
9
|
+
null: () => "z.null()",
|
|
10
|
+
unknown: () => "z.unknown()",
|
|
11
|
+
email: () => "z.string().email()",
|
|
12
|
+
url: () => "z.string().url()",
|
|
13
|
+
uuid: () => "z.string().uuid()",
|
|
14
|
+
datetime: () => "z.string().datetime()",
|
|
15
|
+
date: () => "z.string().date()",
|
|
16
|
+
ipv4: () => "z.string().ip({ version: \"v4\" })",
|
|
17
|
+
ipv6: () => "z.string().ip({ version: \"v6\" })",
|
|
18
|
+
min: (base, n) => `${base}.min(${n})`,
|
|
19
|
+
max: (base, n) => `${base}.max(${n})`,
|
|
20
|
+
gt: (base, n) => `${base}.gt(${n})`,
|
|
21
|
+
lt: (base, n) => `${base}.lt(${n})`,
|
|
22
|
+
regex: (base, pattern) => `${base}.regex(/${pattern}/)`,
|
|
23
|
+
literal: (value) => `z.literal(${JSON.stringify(value)})`,
|
|
24
|
+
enum: (values) => `z.enum([${values.map((v) => JSON.stringify(v)).join(", ")}])`,
|
|
25
|
+
array: (items) => `z.array(${items})`,
|
|
26
|
+
object: (entries) => {
|
|
27
|
+
return `z.object({\n${entries.map(({ key, value, required }) => {
|
|
28
|
+
return ` ${isSafeIdentifier(key) ? key : JSON.stringify(key)}: ${value}${required ? "" : ".optional()"}`;
|
|
29
|
+
}).join(",\n")},\n})`;
|
|
30
|
+
},
|
|
31
|
+
record: (k, v) => `z.record(${k}, ${v})`,
|
|
32
|
+
union: (members) => `z.union([${members.join(", ")}])`,
|
|
33
|
+
discriminatedUnion: (disc, members) => `z.discriminatedUnion(${JSON.stringify(disc)}, [${members.join(", ")}])`,
|
|
34
|
+
intersection: (parts) => parts.reduce((acc, part) => `${acc}.and(${part})`),
|
|
35
|
+
optional: (base) => `${base}.optional()`,
|
|
36
|
+
nullable: (base) => `${base}.nullable()`,
|
|
37
|
+
default: (base, value) => `${base}.default(${JSON.stringify(value)})`,
|
|
38
|
+
describe: (base, desc) => `${base}.describe(${JSON.stringify(desc)})`
|
|
39
|
+
};
|
|
40
|
+
const valibotEmitter = {
|
|
41
|
+
importStatement: "import * as v from 'valibot'",
|
|
42
|
+
inferType: (expr) => `v.InferOutput<typeof ${expr}>`,
|
|
43
|
+
string: () => "v.string()",
|
|
44
|
+
number: () => "v.number()",
|
|
45
|
+
int: () => "v.pipe(v.number(), v.integer())",
|
|
46
|
+
boolean: () => "v.boolean()",
|
|
47
|
+
null: () => "v.null()",
|
|
48
|
+
unknown: () => "v.unknown()",
|
|
49
|
+
email: () => "v.pipe(v.string(), v.email())",
|
|
50
|
+
url: () => "v.pipe(v.string(), v.url())",
|
|
51
|
+
uuid: () => "v.pipe(v.string(), v.uuid())",
|
|
52
|
+
datetime: () => "v.pipe(v.string(), v.isoTimestamp())",
|
|
53
|
+
date: () => "v.pipe(v.string(), v.isoDate())",
|
|
54
|
+
ipv4: () => "v.pipe(v.string(), v.ipv4())",
|
|
55
|
+
ipv6: () => "v.pipe(v.string(), v.ipv6())",
|
|
56
|
+
min: (base, n) => wrapValibotPipe(base, `v.minValue(${n})`),
|
|
57
|
+
max: (base, n) => wrapValibotPipe(base, `v.maxValue(${n})`),
|
|
58
|
+
gt: (base, n) => wrapValibotPipe(base, `v.gtValue(${n})`),
|
|
59
|
+
lt: (base, n) => wrapValibotPipe(base, `v.ltValue(${n})`),
|
|
60
|
+
regex: (base, pattern) => wrapValibotPipe(base, `v.regex(/${pattern}/)`),
|
|
61
|
+
literal: (value) => `v.literal(${JSON.stringify(value)})`,
|
|
62
|
+
enum: (values) => `v.picklist([${values.map((v) => JSON.stringify(v)).join(", ")}])`,
|
|
63
|
+
array: (items) => `v.array(${items})`,
|
|
64
|
+
object: (entries) => {
|
|
65
|
+
const requiredEntries = entries.filter((e) => e.required);
|
|
66
|
+
const optionalEntries = entries.filter((e) => !e.required);
|
|
67
|
+
return `v.object({\n${[...requiredEntries.map(({ key, value }) => {
|
|
68
|
+
return ` ${isSafeIdentifier(key) ? key : JSON.stringify(key)}: ${value}`;
|
|
69
|
+
}), ...optionalEntries.map(({ key, value }) => {
|
|
70
|
+
return ` ${isSafeIdentifier(key) ? key : JSON.stringify(key)}: v.optional(${value})`;
|
|
71
|
+
})].join(",\n")},\n})`;
|
|
72
|
+
},
|
|
73
|
+
record: (_k, v) => `v.record(v.string(), ${v})`,
|
|
74
|
+
union: (members) => `v.union([${members.join(", ")}])`,
|
|
75
|
+
discriminatedUnion: (disc, members) => `v.variant(${JSON.stringify(disc)}, [${members.join(", ")}])`,
|
|
76
|
+
intersection: (parts) => `v.intersect([${parts.join(", ")}])`,
|
|
77
|
+
optional: (base) => `v.optional(${base})`,
|
|
78
|
+
nullable: (base) => `v.nullable(${base})`,
|
|
79
|
+
default: (base, value) => `v.optional(${base}, ${JSON.stringify(value)})`,
|
|
80
|
+
describe: (base, desc) => `v.pipe(${base}, v.description(${JSON.stringify(desc)}))`
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Valibot uses `v.pipe(schema, ...actions)` for constraints.
|
|
84
|
+
* If the base is already a pipe, inject the action into it.
|
|
85
|
+
*/
|
|
86
|
+
function wrapValibotPipe(base, action) {
|
|
87
|
+
if (base.startsWith("v.pipe(") && base.endsWith(")")) return `${base.slice(0, -1)}, ${action})`;
|
|
88
|
+
return `v.pipe(${base}, ${action})`;
|
|
89
|
+
}
|
|
90
|
+
const emitters = {
|
|
91
|
+
zod: zodEmitter,
|
|
92
|
+
valibot: valibotEmitter,
|
|
93
|
+
arktype: {
|
|
94
|
+
importStatement: "import { type } from 'arktype'",
|
|
95
|
+
inferType: (expr) => `typeof ${expr}.infer`,
|
|
96
|
+
string: () => "type('string')",
|
|
97
|
+
number: () => "type('number')",
|
|
98
|
+
int: () => "type('number.integer')",
|
|
99
|
+
boolean: () => "type('boolean')",
|
|
100
|
+
null: () => "type('null')",
|
|
101
|
+
unknown: () => "type('unknown')",
|
|
102
|
+
email: () => "type('string.email')",
|
|
103
|
+
url: () => "type('string.url')",
|
|
104
|
+
uuid: () => "type('string.uuid')",
|
|
105
|
+
datetime: () => "type('string.date.iso')",
|
|
106
|
+
date: () => "type('string.date')",
|
|
107
|
+
ipv4: () => "type('string.ip')",
|
|
108
|
+
ipv6: () => "type('string.ip')",
|
|
109
|
+
min: (base, n) => `${base}.atLeast(${n})`,
|
|
110
|
+
max: (base, n) => `${base}.atMost(${n})`,
|
|
111
|
+
gt: (base, n) => `${base}.moreThan(${n})`,
|
|
112
|
+
lt: (base, n) => `${base}.lessThan(${n})`,
|
|
113
|
+
regex: (base, pattern) => `${base}.matching(/${pattern}/)`,
|
|
114
|
+
literal: (value) => `type(${JSON.stringify(JSON.stringify(value))})`,
|
|
115
|
+
enum: (values) => {
|
|
116
|
+
return `type(${values.map((v) => JSON.stringify(JSON.stringify(v))).join(" + ' | ' + ")})`;
|
|
117
|
+
},
|
|
118
|
+
array: (items) => `${items}.array()`,
|
|
119
|
+
object: (entries) => {
|
|
120
|
+
return `type({\n${entries.map(({ key, value, required }) => {
|
|
121
|
+
return ` [${required ? JSON.stringify(key) : JSON.stringify(`${key}?`)}]: ${value}`;
|
|
122
|
+
}).join(",\n")},\n})`;
|
|
123
|
+
},
|
|
124
|
+
record: (_k, v) => `type({ '[string]': ${v} })`,
|
|
125
|
+
union: (members) => members.reduce((acc, m) => `${acc}.or(${m})`),
|
|
126
|
+
discriminatedUnion: (_disc, members) => members.reduce((acc, m) => `${acc}.or(${m})`),
|
|
127
|
+
intersection: (parts) => parts.reduce((acc, p) => `${acc}.and(${p})`),
|
|
128
|
+
optional: (base) => `${base}.optional()`,
|
|
129
|
+
nullable: (base) => `${base}.or(type('null'))`,
|
|
130
|
+
default: (base, value) => `${base}.default(${JSON.stringify(value)})`,
|
|
131
|
+
describe: (base, desc) => `${base}.describe(${JSON.stringify(desc)})`
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
function getEmitter(target) {
|
|
135
|
+
const emitter = emitters[target];
|
|
136
|
+
if (!emitter) throw new Error(`Unknown schema target: ${target}`);
|
|
137
|
+
return emitter;
|
|
138
|
+
}
|
|
139
|
+
function isSafeIdentifier(s) {
|
|
140
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(s);
|
|
141
|
+
}
|
|
142
|
+
//#endregion
|
|
143
|
+
export { getEmitter };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ParsedOperation } from "./parse.mjs";
|
|
2
|
+
import { SchemaTarget } from "./emitters.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/codegen/generate.d.ts
|
|
5
|
+
interface GenerateOptions {
|
|
6
|
+
/** How to group operations into folders: by tag, by first path segment, or flat */
|
|
7
|
+
groupBy?: 'tag' | 'path' | 'flat';
|
|
8
|
+
/** Silgi instance variable name (default: "s") */
|
|
9
|
+
instanceName?: string;
|
|
10
|
+
/** Custom header comment */
|
|
11
|
+
header?: string;
|
|
12
|
+
/** Target schema library (default: "zod") */
|
|
13
|
+
schema?: SchemaTarget;
|
|
14
|
+
}
|
|
15
|
+
interface GeneratedFiles {
|
|
16
|
+
/** schemas.gen.ts — validation schemas for all components + operation I/O */
|
|
17
|
+
schemas: string;
|
|
18
|
+
/** router.gen.ts — root router importing all operation files */
|
|
19
|
+
router: string;
|
|
20
|
+
/** routes/<group>/<operationId>.ts — one file per operation */
|
|
21
|
+
routes: Map<string, string>;
|
|
22
|
+
}
|
|
23
|
+
declare function generateCode(operations: ParsedOperation[], components: Record<string, Record<string, unknown>>, options?: GenerateOptions): GeneratedFiles;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { GenerateOptions, generateCode };
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { getEmitter } from "./emitters.mjs";
|
|
2
|
+
import { createSchemaContext, emitComponentSchemas, jsonSchemaToCode } from "./schema-to-code.mjs";
|
|
3
|
+
//#region src/codegen/generate.ts
|
|
4
|
+
/**
|
|
5
|
+
* Code generator — one file per operation, inline $resolve, URL-based grouping.
|
|
6
|
+
*
|
|
7
|
+
* Output structure:
|
|
8
|
+
* schemas.gen.ts — Shared validation schemas
|
|
9
|
+
* router.gen.ts — Root router importing all operation files
|
|
10
|
+
* routes/
|
|
11
|
+
* pets/
|
|
12
|
+
* listPets.ts — Single operation with inline $resolve
|
|
13
|
+
* createPet.ts
|
|
14
|
+
* store/
|
|
15
|
+
* getInventory.ts
|
|
16
|
+
*/
|
|
17
|
+
const STATUS_TO_ERROR_CODE = {
|
|
18
|
+
400: "BAD_REQUEST",
|
|
19
|
+
401: "UNAUTHORIZED",
|
|
20
|
+
403: "FORBIDDEN",
|
|
21
|
+
404: "NOT_FOUND",
|
|
22
|
+
405: "METHOD_NOT_ALLOWED",
|
|
23
|
+
408: "TIMEOUT",
|
|
24
|
+
409: "CONFLICT",
|
|
25
|
+
410: "GONE",
|
|
26
|
+
422: "UNPROCESSABLE_ENTITY",
|
|
27
|
+
429: "TOO_MANY_REQUESTS",
|
|
28
|
+
500: "INTERNAL_SERVER_ERROR",
|
|
29
|
+
502: "BAD_GATEWAY",
|
|
30
|
+
503: "SERVICE_UNAVAILABLE"
|
|
31
|
+
};
|
|
32
|
+
function generateCode(operations, components, options = {}) {
|
|
33
|
+
const { groupBy = "tag", instanceName = "s", header = "// This file is auto-generated by silgi/codegen — DO NOT EDIT", schema: target = "zod" } = options;
|
|
34
|
+
const emitter = getEmitter(target);
|
|
35
|
+
const ctx = createSchemaContext(target, components);
|
|
36
|
+
const operationSchemas = [];
|
|
37
|
+
const operationSchemaNames = /* @__PURE__ */ new Map();
|
|
38
|
+
for (const op of operations) {
|
|
39
|
+
const names = {};
|
|
40
|
+
const inputSchema = buildInputSchema(op, ctx);
|
|
41
|
+
if (inputSchema) {
|
|
42
|
+
const name = `${op.operationId}Input`;
|
|
43
|
+
operationSchemas.push(`export const ${name}Schema = ${inputSchema}`);
|
|
44
|
+
names.input = `${name}Schema`;
|
|
45
|
+
}
|
|
46
|
+
if (op.successSchema) {
|
|
47
|
+
const name = `${op.operationId}Output`;
|
|
48
|
+
const code = jsonSchemaToCode(op.successSchema, ctx);
|
|
49
|
+
operationSchemas.push(`export const ${name}Schema = ${code}`);
|
|
50
|
+
names.output = `${name}Schema`;
|
|
51
|
+
}
|
|
52
|
+
operationSchemaNames.set(op.operationId, names);
|
|
53
|
+
}
|
|
54
|
+
const componentCode = emitComponentSchemas(ctx);
|
|
55
|
+
const schemasFile = [
|
|
56
|
+
header,
|
|
57
|
+
emitter.importStatement,
|
|
58
|
+
"",
|
|
59
|
+
"// ── Component Schemas ──",
|
|
60
|
+
"",
|
|
61
|
+
componentCode,
|
|
62
|
+
"",
|
|
63
|
+
"// ── Operation Schemas ──",
|
|
64
|
+
"",
|
|
65
|
+
operationSchemas.join("\n\n"),
|
|
66
|
+
""
|
|
67
|
+
].join("\n");
|
|
68
|
+
const groups = groupOperations(operations, groupBy);
|
|
69
|
+
const routeFiles = /* @__PURE__ */ new Map();
|
|
70
|
+
for (const [groupName, ops] of groups) for (const op of ops) {
|
|
71
|
+
const filePath = `${groupName}/${op.operationId}`;
|
|
72
|
+
routeFiles.set(filePath, generateOperationFile(op, operationSchemaNames, {
|
|
73
|
+
header: header.replace("DO NOT EDIT", "Implement your resolver"),
|
|
74
|
+
instanceName,
|
|
75
|
+
schemasImportPath: "../../schemas.gen.ts"
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
schemas: schemasFile,
|
|
80
|
+
router: generateRootRouter(groups, operationSchemaNames, {
|
|
81
|
+
header,
|
|
82
|
+
instanceName
|
|
83
|
+
}),
|
|
84
|
+
routes: routeFiles
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function buildInputSchema(op, ctx) {
|
|
88
|
+
const e = ctx.emitter;
|
|
89
|
+
const parts = [];
|
|
90
|
+
for (const p of op.pathParams) parts.push({
|
|
91
|
+
key: p.name,
|
|
92
|
+
value: jsonSchemaToCode(p.schema, ctx),
|
|
93
|
+
required: true
|
|
94
|
+
});
|
|
95
|
+
for (const p of op.queryParams) parts.push({
|
|
96
|
+
key: p.name,
|
|
97
|
+
value: jsonSchemaToCode(p.schema, ctx),
|
|
98
|
+
required: p.required
|
|
99
|
+
});
|
|
100
|
+
if (op.body) if (op.body.type === "object" && op.body.properties && !hasOverlap(parts, op.body.properties)) {
|
|
101
|
+
const required = new Set(op.body.required ?? []);
|
|
102
|
+
for (const [key, prop] of Object.entries(op.body.properties)) parts.push({
|
|
103
|
+
key,
|
|
104
|
+
value: jsonSchemaToCode(prop, ctx),
|
|
105
|
+
required: required.has(key)
|
|
106
|
+
});
|
|
107
|
+
} else parts.push({
|
|
108
|
+
key: "body",
|
|
109
|
+
value: jsonSchemaToCode(op.body, ctx),
|
|
110
|
+
required: op.bodyRequired
|
|
111
|
+
});
|
|
112
|
+
if (parts.length === 0) return null;
|
|
113
|
+
return e.object(parts);
|
|
114
|
+
}
|
|
115
|
+
function hasOverlap(parts, properties) {
|
|
116
|
+
const existing = new Set(parts.map((p) => p.key));
|
|
117
|
+
return Object.keys(properties).some((k) => existing.has(k));
|
|
118
|
+
}
|
|
119
|
+
function generateOperationFile(op, schemaNames, opts) {
|
|
120
|
+
const s = opts.instanceName;
|
|
121
|
+
const names = schemaNames.get(op.operationId) ?? {};
|
|
122
|
+
const lines = [
|
|
123
|
+
opts.header,
|
|
124
|
+
"import { silgi, SilgiError } from 'silgi'",
|
|
125
|
+
`import * as schemas from '${opts.schemasImportPath}'`,
|
|
126
|
+
"",
|
|
127
|
+
`const ${s} = silgi()`,
|
|
128
|
+
""
|
|
129
|
+
];
|
|
130
|
+
if (op.summary) lines.push(`/** ${op.summary} */`);
|
|
131
|
+
lines.push(`export const ${op.operationId} = ${s}`);
|
|
132
|
+
const routeParts = [];
|
|
133
|
+
routeParts.push(` path: '${op.silgiPath}',`);
|
|
134
|
+
routeParts.push(` method: '${op.method}',`);
|
|
135
|
+
if (op.summary) routeParts.push(` summary: ${JSON.stringify(op.summary)},`);
|
|
136
|
+
if (op.tags.length) routeParts.push(` tags: [${op.tags.map((t) => JSON.stringify(t)).join(", ")}],`);
|
|
137
|
+
if (op.deprecated) routeParts.push(" deprecated: true,");
|
|
138
|
+
routeParts.push(` operationId: ${JSON.stringify(op.operationId)},`);
|
|
139
|
+
if (op.successStatus !== 200) routeParts.push(` successStatus: ${op.successStatus},`);
|
|
140
|
+
if (op.security === false) routeParts.push(" security: false,");
|
|
141
|
+
else if (op.security) routeParts.push(` security: [${op.security.map((v) => JSON.stringify(v)).join(", ")}],`);
|
|
142
|
+
lines.push(` .$route({`);
|
|
143
|
+
lines.push(routeParts.join("\n"));
|
|
144
|
+
lines.push(` })`);
|
|
145
|
+
if (names.input) lines.push(` .$input(schemas.${names.input})`);
|
|
146
|
+
if (names.output) lines.push(` .$output(schemas.${names.output})`);
|
|
147
|
+
if (op.errors.size > 0) {
|
|
148
|
+
const errorEntries = [];
|
|
149
|
+
for (const [status, { description }] of op.errors) {
|
|
150
|
+
const code = STATUS_TO_ERROR_CODE[status] ?? `ERROR_${status}`;
|
|
151
|
+
const finalCode = description && /^[A-Z_]+$/.test(description) ? description : code;
|
|
152
|
+
errorEntries.push(` ${finalCode}: ${status},`);
|
|
153
|
+
}
|
|
154
|
+
lines.push(` .$errors({`);
|
|
155
|
+
lines.push(errorEntries.join("\n"));
|
|
156
|
+
lines.push(` })`);
|
|
157
|
+
}
|
|
158
|
+
lines.push(` .$resolve(({ input, ctx, fail }) => {`);
|
|
159
|
+
lines.push(` // TODO: implement ${op.operationId}`);
|
|
160
|
+
lines.push(` throw new SilgiError({`);
|
|
161
|
+
lines.push(` code: 'INTERNAL_SERVER_ERROR',`);
|
|
162
|
+
lines.push(` message: 'Not implemented: ${op.operationId}',`);
|
|
163
|
+
lines.push(` })`);
|
|
164
|
+
lines.push(` })`);
|
|
165
|
+
lines.push("");
|
|
166
|
+
return lines.join("\n");
|
|
167
|
+
}
|
|
168
|
+
function generateRootRouter(groups, _schemaNames, opts) {
|
|
169
|
+
const s = opts.instanceName;
|
|
170
|
+
const lines = [
|
|
171
|
+
opts.header,
|
|
172
|
+
"import { silgi } from 'silgi'",
|
|
173
|
+
""
|
|
174
|
+
];
|
|
175
|
+
for (const [groupName, ops] of groups) for (const op of ops) lines.push(`import { ${op.operationId} } from './routes/${groupName}/${op.operationId}.ts'`);
|
|
176
|
+
lines.push("");
|
|
177
|
+
lines.push(`const ${s} = silgi()`);
|
|
178
|
+
lines.push("");
|
|
179
|
+
if (groups.size === 1 && groups.has("default")) {
|
|
180
|
+
const ops = groups.get("default");
|
|
181
|
+
lines.push(`export const router = ${s}.router({`);
|
|
182
|
+
for (const op of ops) lines.push(` ${op.operationId},`);
|
|
183
|
+
lines.push("})");
|
|
184
|
+
} else {
|
|
185
|
+
lines.push(`export const router = ${s}.router({`);
|
|
186
|
+
for (const [groupName, ops] of groups) {
|
|
187
|
+
const safeName = isSafeIdentifier(groupName) ? groupName : JSON.stringify(groupName);
|
|
188
|
+
lines.push(` ${safeName}: {`);
|
|
189
|
+
for (const op of ops) lines.push(` ${op.operationId},`);
|
|
190
|
+
lines.push(` },`);
|
|
191
|
+
}
|
|
192
|
+
lines.push("})");
|
|
193
|
+
}
|
|
194
|
+
lines.push("");
|
|
195
|
+
lines.push("export type AppRouter = typeof router");
|
|
196
|
+
lines.push("");
|
|
197
|
+
return lines.join("\n");
|
|
198
|
+
}
|
|
199
|
+
function groupOperations(operations, groupBy) {
|
|
200
|
+
const groups = /* @__PURE__ */ new Map();
|
|
201
|
+
for (const op of operations) {
|
|
202
|
+
let key;
|
|
203
|
+
switch (groupBy) {
|
|
204
|
+
case "tag":
|
|
205
|
+
key = op.tags[0] ?? "default";
|
|
206
|
+
break;
|
|
207
|
+
case "path":
|
|
208
|
+
key = op.path.split("/").find(Boolean) ?? "default";
|
|
209
|
+
break;
|
|
210
|
+
case "flat":
|
|
211
|
+
key = "default";
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
key = key.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
215
|
+
if (!groups.has(key)) groups.set(key, []);
|
|
216
|
+
groups.get(key).push(op);
|
|
217
|
+
}
|
|
218
|
+
return groups;
|
|
219
|
+
}
|
|
220
|
+
function isSafeIdentifier(s) {
|
|
221
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(s);
|
|
222
|
+
}
|
|
223
|
+
//#endregion
|
|
224
|
+
export { generateCode };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { OpenAPISpec, ParsedOperation, parseOpenAPI } from "./parse.mjs";
|
|
2
|
+
import { SchemaEmitter, SchemaTarget, getEmitter } from "./emitters.mjs";
|
|
3
|
+
import { GenerateOptions, generateCode } from "./generate.mjs";
|
|
4
|
+
import { SchemaContext, createSchemaContext, jsonSchemaToCode } from "./schema-to-code.mjs";
|
|
5
|
+
import { extractResolveBody, spliceResolveBody } from "./preserve.mjs";
|
|
6
|
+
|
|
7
|
+
//#region src/codegen/index.d.ts
|
|
8
|
+
interface GenerateFromSpecOptions extends GenerateOptions {
|
|
9
|
+
/** Path to OpenAPI spec file (JSON or YAML) or a spec object */
|
|
10
|
+
spec: string | OpenAPISpec;
|
|
11
|
+
/** Output directory for generated files (default: "./generated") */
|
|
12
|
+
outDir?: string;
|
|
13
|
+
/**
|
|
14
|
+
* What to do when route files already exist:
|
|
15
|
+
* - "smart" (default) — regenerate $route/$input/$output/$errors, preserve $resolve body
|
|
16
|
+
* - "skip" — don't touch existing route files at all
|
|
17
|
+
* - "overwrite" — regenerate everything including $resolve
|
|
18
|
+
*/
|
|
19
|
+
routeStrategy?: 'smart' | 'skip' | 'overwrite';
|
|
20
|
+
}
|
|
21
|
+
interface GenerateResult {
|
|
22
|
+
/** Paths of all generated files */
|
|
23
|
+
files: string[];
|
|
24
|
+
/** Number of operations processed */
|
|
25
|
+
operationCount: number;
|
|
26
|
+
/** Number of component schemas generated */
|
|
27
|
+
schemaCount: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Generate Silgi code from an OpenAPI spec file or object.
|
|
31
|
+
*/
|
|
32
|
+
declare function generateFromSpec(options: GenerateFromSpecOptions): Promise<GenerateResult>;
|
|
33
|
+
/**
|
|
34
|
+
* Generate Silgi code without writing to disk.
|
|
35
|
+
* Useful for programmatic use or custom output handling.
|
|
36
|
+
*/
|
|
37
|
+
declare function generate(spec: OpenAPISpec, options?: GenerateOptions): {
|
|
38
|
+
schemas: string;
|
|
39
|
+
router: string;
|
|
40
|
+
routes: Map<string, string>;
|
|
41
|
+
operations: ReturnType<typeof parseOpenAPI>['operations'];
|
|
42
|
+
};
|
|
43
|
+
//#endregion
|
|
44
|
+
export { GenerateFromSpecOptions, type GenerateOptions, GenerateResult, type OpenAPISpec, type ParsedOperation, type SchemaContext, type SchemaEmitter, type SchemaTarget, createSchemaContext, extractResolveBody, generate, generateCode, generateFromSpec, getEmitter, jsonSchemaToCode, parseOpenAPI, spliceResolveBody };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { getEmitter } from "./emitters.mjs";
|
|
2
|
+
import { createSchemaContext, jsonSchemaToCode } from "./schema-to-code.mjs";
|
|
3
|
+
import { generateCode } from "./generate.mjs";
|
|
4
|
+
import { parseOpenAPI } from "./parse.mjs";
|
|
5
|
+
import { extractResolveBody, spliceResolveBody } from "./preserve.mjs";
|
|
6
|
+
import { extname, join, resolve } from "node:path";
|
|
7
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
8
|
+
//#region src/codegen/index.ts
|
|
9
|
+
/**
|
|
10
|
+
* silgi/codegen — OpenAPI → Silgi code generator.
|
|
11
|
+
*
|
|
12
|
+
* Takes an OpenAPI 3.x spec and generates:
|
|
13
|
+
* - Validation schemas (Zod, Valibot, or ArkType) for all components and operation I/O
|
|
14
|
+
* - Co-located route modules (handlers + procedures in the same file, per domain)
|
|
15
|
+
* - Root router that combines all route modules
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { generateFromSpec } from 'silgi/codegen'
|
|
20
|
+
*
|
|
21
|
+
* await generateFromSpec({
|
|
22
|
+
* spec: './openapi.json',
|
|
23
|
+
* outDir: './src/generated',
|
|
24
|
+
* schema: 'zod', // or 'valibot' or 'arktype'
|
|
25
|
+
* })
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* Generate Silgi code from an OpenAPI spec file or object.
|
|
30
|
+
*/
|
|
31
|
+
async function generateFromSpec(options) {
|
|
32
|
+
const { outDir = "./generated", routeStrategy = "smart", ...genOpts } = options;
|
|
33
|
+
const { operations, components, tags: _tags } = parseOpenAPI(typeof options.spec === "string" ? await loadSpec(options.spec) : options.spec);
|
|
34
|
+
const { schemas, router, routes } = generateCode(operations, components, genOpts);
|
|
35
|
+
const outputDir = resolve(outDir);
|
|
36
|
+
await mkdir(outputDir, { recursive: true });
|
|
37
|
+
const files = [];
|
|
38
|
+
const schemasPath = join(outputDir, "schemas.gen.ts");
|
|
39
|
+
await writeFile(schemasPath, schemas, "utf-8");
|
|
40
|
+
files.push(schemasPath);
|
|
41
|
+
const routerPath = join(outputDir, "router.gen.ts");
|
|
42
|
+
await writeFile(routerPath, router, "utf-8");
|
|
43
|
+
files.push(routerPath);
|
|
44
|
+
if (routes.size > 0) {
|
|
45
|
+
const { extractResolveBody, spliceResolveBody } = await import("./preserve.mjs");
|
|
46
|
+
for (const [filePath, code] of routes) {
|
|
47
|
+
const fullPath = join(outputDir, "routes", `${filePath}.ts`);
|
|
48
|
+
await mkdir(join(fullPath, ".."), { recursive: true });
|
|
49
|
+
if (routeStrategy === "skip") {
|
|
50
|
+
if (await fileExists(fullPath)) continue;
|
|
51
|
+
}
|
|
52
|
+
if (routeStrategy === "smart" && await fileExists(fullPath)) {
|
|
53
|
+
const preserved = extractResolveBody(await readFile(fullPath, "utf-8"));
|
|
54
|
+
if (preserved) await writeFile(fullPath, spliceResolveBody(code, preserved), "utf-8");
|
|
55
|
+
else await writeFile(fullPath, code, "utf-8");
|
|
56
|
+
files.push(fullPath);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
await writeFile(fullPath, code, "utf-8");
|
|
60
|
+
files.push(fullPath);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const schemaCount = (schemas.match(/^export const \w+Schema/gm) ?? []).length;
|
|
64
|
+
return {
|
|
65
|
+
files,
|
|
66
|
+
operationCount: operations.length,
|
|
67
|
+
schemaCount
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Generate Silgi code without writing to disk.
|
|
72
|
+
* Useful for programmatic use or custom output handling.
|
|
73
|
+
*/
|
|
74
|
+
function generate(spec, options = {}) {
|
|
75
|
+
const { operations, components } = parseOpenAPI(spec);
|
|
76
|
+
return {
|
|
77
|
+
...generateCode(operations, components, options),
|
|
78
|
+
operations
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
async function loadSpec(path) {
|
|
82
|
+
const resolved = resolve(path);
|
|
83
|
+
const content = await readFile(resolved, "utf-8");
|
|
84
|
+
const ext = extname(resolved).toLowerCase();
|
|
85
|
+
if (ext === ".yaml" || ext === ".yml") try {
|
|
86
|
+
const { parse } = await import("yaml");
|
|
87
|
+
return parse(content);
|
|
88
|
+
} catch {
|
|
89
|
+
throw new Error("YAML spec detected but \"yaml\" package is not installed. Install it with: pnpm add -D yaml");
|
|
90
|
+
}
|
|
91
|
+
return JSON.parse(content);
|
|
92
|
+
}
|
|
93
|
+
async function fileExists(path) {
|
|
94
|
+
try {
|
|
95
|
+
const { access } = await import("node:fs/promises");
|
|
96
|
+
await access(path);
|
|
97
|
+
return true;
|
|
98
|
+
} catch {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//#endregion
|
|
103
|
+
export { createSchemaContext, extractResolveBody, generate, generateCode, generateFromSpec, getEmitter, jsonSchemaToCode, parseOpenAPI, spliceResolveBody };
|