@snail-js/api 0.1.27 → 1.0.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/LICENSE +21 -0
- package/README.md +125 -605
- package/dist/adapter/plain.d.ts +12 -0
- package/dist/adapter/plain.d.ts.map +1 -0
- package/dist/adapter/react.d.ts +14 -0
- package/dist/adapter/react.d.ts.map +1 -0
- package/dist/adapter/registry.d.ts +16 -0
- package/dist/adapter/registry.d.ts.map +1 -0
- package/dist/adapter/vue.d.ts +15 -0
- package/dist/adapter/vue.d.ts.map +1 -0
- package/dist/chunks/custom-UchOSg_s.js +466 -0
- package/dist/chunks/custom-UchOSg_s.js.map +1 -0
- package/dist/chunks/download-lBC7oOTT.js +160 -0
- package/dist/chunks/download-lBC7oOTT.js.map +1 -0
- package/dist/chunks/object-Ct0w-h4i.js +74 -0
- package/dist/chunks/object-Ct0w-h4i.js.map +1 -0
- package/dist/chunks/plugin-D3RDffDG.js +742 -0
- package/dist/chunks/plugin-D3RDffDG.js.map +1 -0
- package/dist/chunks/react-C1em-gxy.js +62 -0
- package/dist/chunks/react-C1em-gxy.js.map +1 -0
- package/dist/chunks/request-qeRhihEF.js +40 -0
- package/dist/chunks/request-qeRhihEF.js.map +1 -0
- package/dist/chunks/response-D-ubkAFl.js +127 -0
- package/dist/chunks/response-D-ubkAFl.js.map +1 -0
- package/dist/chunks/use-download-FAjtdJ58.js +1816 -0
- package/dist/chunks/use-download-FAjtdJ58.js.map +1 -0
- package/dist/chunks/vue-Dd9EhkQ3.js +34 -0
- package/dist/chunks/vue-Dd9EhkQ3.js.map +1 -0
- package/dist/core/args.d.ts +54 -0
- package/dist/core/args.d.ts.map +1 -0
- package/dist/core/connection.d.ts +15 -0
- package/dist/core/connection.d.ts.map +1 -0
- package/dist/core/context.d.ts +124 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/http-stream.d.ts +28 -0
- package/dist/core/http-stream.d.ts.map +1 -0
- package/dist/core/logger.d.ts +22 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/metadata.d.ts +92 -0
- package/dist/core/metadata.d.ts.map +1 -0
- package/dist/core/metadata.keys.d.ts +41 -0
- package/dist/core/metadata.keys.d.ts.map +1 -0
- package/dist/core/method.d.ts +177 -0
- package/dist/core/method.d.ts.map +1 -0
- package/dist/core/plugin-manager.d.ts +106 -0
- package/dist/core/plugin-manager.d.ts.map +1 -0
- package/dist/core/plugin.d.ts +113 -0
- package/dist/core/plugin.d.ts.map +1 -0
- package/dist/core/reconnect.d.ts +22 -0
- package/dist/core/reconnect.d.ts.map +1 -0
- package/dist/core/resolve-stream.d.ts +45 -0
- package/dist/core/resolve-stream.d.ts.map +1 -0
- package/dist/core/resolve.d.ts +50 -0
- package/dist/core/resolve.d.ts.map +1 -0
- package/dist/core/response.d.ts +60 -0
- package/dist/core/response.d.ts.map +1 -0
- package/dist/core/server.d.ts +132 -0
- package/dist/core/server.d.ts.map +1 -0
- package/dist/core/sse.d.ts +27 -0
- package/dist/core/sse.d.ts.map +1 -0
- package/dist/core/state-bag.d.ts +36 -0
- package/dist/core/state-bag.d.ts.map +1 -0
- package/dist/core/websocket.d.ts +29 -0
- package/dist/core/websocket.d.ts.map +1 -0
- package/dist/decorators/api.d.ts +24 -4
- package/dist/decorators/api.d.ts.map +1 -0
- package/dist/decorators/args.d.ts +77 -14
- package/dist/decorators/args.d.ts.map +1 -0
- package/dist/decorators/custom.d.ts +81 -0
- package/dist/decorators/custom.d.ts.map +1 -0
- package/dist/decorators/header.d.ts +22 -0
- package/dist/decorators/header.d.ts.map +1 -0
- package/dist/decorators/index.d.ts +17 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/dist/decorators/methods.d.ts +33 -0
- package/dist/decorators/methods.d.ts.map +1 -0
- package/dist/decorators/progress.d.ts +24 -6
- package/dist/decorators/progress.d.ts.map +1 -0
- package/dist/decorators/server.d.ts +28 -7
- package/dist/decorators/server.d.ts.map +1 -0
- package/dist/decorators/stream.d.ts +113 -0
- package/dist/decorators/stream.d.ts.map +1 -0
- package/dist/default/options.d.ts +19 -0
- package/dist/default/options.d.ts.map +1 -0
- package/dist/error/base.d.ts +20 -0
- package/dist/error/base.d.ts.map +1 -0
- package/dist/error/decorator.d.ts +14 -0
- package/dist/error/decorator.d.ts.map +1 -0
- package/dist/error/hook.d.ts +14 -0
- package/dist/error/hook.d.ts.map +1 -0
- package/dist/error/index.d.ts +8 -0
- package/dist/error/index.d.ts.map +1 -0
- package/dist/error/options.d.ts +12 -0
- package/dist/error/options.d.ts.map +1 -0
- package/dist/error/plugin.d.ts +11 -0
- package/dist/error/plugin.d.ts.map +1 -0
- package/dist/error/request.d.ts +29 -0
- package/dist/error/request.d.ts.map +1 -0
- package/dist/error/response.d.ts +36 -0
- package/dist/error/response.d.ts.map +1 -0
- package/dist/index.d.ts +56 -11
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2034 -0
- package/dist/index.js.map +1 -0
- package/dist/locale/en.d.ts +5 -0
- package/dist/locale/en.d.ts.map +1 -0
- package/dist/locale/index.d.ts +57 -0
- package/dist/locale/index.d.ts.map +1 -0
- package/dist/locale/types.d.ts +11 -0
- package/dist/locale/types.d.ts.map +1 -0
- package/dist/locale/zh.d.ts +5 -0
- package/dist/locale/zh.d.ts.map +1 -0
- package/dist/plugins/cache/adapters/indexeddb.d.ts +52 -0
- package/dist/plugins/cache/adapters/indexeddb.d.ts.map +1 -0
- package/dist/plugins/cache/adapters/memory.d.ts +60 -0
- package/dist/plugins/cache/adapters/memory.d.ts.map +1 -0
- package/dist/plugins/cache/adapters/web-storage.d.ts +43 -0
- package/dist/plugins/cache/adapters/web-storage.d.ts.map +1 -0
- package/dist/plugins/cache/decorators.d.ts +62 -0
- package/dist/plugins/cache/decorators.d.ts.map +1 -0
- package/dist/plugins/cache/index.d.ts +41 -0
- package/dist/plugins/cache/index.d.ts.map +1 -0
- package/dist/plugins/cache/key.d.ts +48 -0
- package/dist/plugins/cache/key.d.ts.map +1 -0
- package/dist/plugins/cache/manager.d.ts +124 -0
- package/dist/plugins/cache/manager.d.ts.map +1 -0
- package/dist/plugins/cache/plugin.d.ts +64 -0
- package/dist/plugins/cache/plugin.d.ts.map +1 -0
- package/dist/plugins/cache/type.d.ts +116 -0
- package/dist/plugins/cache/type.d.ts.map +1 -0
- package/dist/plugins/index.d.ts +75 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +2265 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/interceptor/decorators.d.ts +44 -0
- package/dist/plugins/interceptor/decorators.d.ts.map +1 -0
- package/dist/plugins/interceptor/index.d.ts +31 -0
- package/dist/plugins/interceptor/index.d.ts.map +1 -0
- package/dist/plugins/interceptor/manager.d.ts +27 -0
- package/dist/plugins/interceptor/manager.d.ts.map +1 -0
- package/dist/plugins/interceptor/plugin.d.ts +65 -0
- package/dist/plugins/interceptor/plugin.d.ts.map +1 -0
- package/dist/plugins/interceptor/type.d.ts +45 -0
- package/dist/plugins/interceptor/type.d.ts.map +1 -0
- package/dist/plugins/pool/index.d.ts +26 -0
- package/dist/plugins/pool/index.d.ts.map +1 -0
- package/dist/plugins/pool/plugin.d.ts +83 -0
- package/dist/plugins/pool/plugin.d.ts.map +1 -0
- package/dist/plugins/pool/scheduler.d.ts +153 -0
- package/dist/plugins/pool/scheduler.d.ts.map +1 -0
- package/dist/plugins/pool/type.d.ts +38 -0
- package/dist/plugins/pool/type.d.ts.map +1 -0
- package/dist/plugins/react/index.d.ts +20 -0
- package/dist/plugins/react/index.d.ts.map +1 -0
- package/dist/plugins/react/index.js +145 -0
- package/dist/plugins/react/index.js.map +1 -0
- package/dist/plugins/react/plugin.d.ts +33 -0
- package/dist/plugins/react/plugin.d.ts.map +1 -0
- package/dist/plugins/react/type.d.ts +32 -0
- package/dist/plugins/react/type.d.ts.map +1 -0
- package/dist/plugins/transform/decorators.d.ts +54 -0
- package/dist/plugins/transform/decorators.d.ts.map +1 -0
- package/dist/plugins/transform/hydrate.d.ts +47 -0
- package/dist/plugins/transform/hydrate.d.ts.map +1 -0
- package/dist/plugins/transform/index.d.ts +41 -0
- package/dist/plugins/transform/index.d.ts.map +1 -0
- package/dist/plugins/transform/plugin.d.ts +20 -0
- package/dist/plugins/transform/plugin.d.ts.map +1 -0
- package/dist/plugins/transform/type.d.ts +67 -0
- package/dist/plugins/transform/type.d.ts.map +1 -0
- package/dist/plugins/validate/decorators.d.ts +24 -0
- package/dist/plugins/validate/decorators.d.ts.map +1 -0
- package/dist/plugins/validate/index.d.ts +40 -0
- package/dist/plugins/validate/index.d.ts.map +1 -0
- package/dist/plugins/validate/plugin.d.ts +13 -0
- package/dist/plugins/validate/plugin.d.ts.map +1 -0
- package/dist/plugins/validate/type.d.ts +54 -0
- package/dist/plugins/validate/type.d.ts.map +1 -0
- package/dist/plugins/version/decorators.d.ts +22 -0
- package/dist/plugins/version/decorators.d.ts.map +1 -0
- package/dist/plugins/version/index.d.ts +23 -0
- package/dist/plugins/version/index.d.ts.map +1 -0
- package/dist/plugins/version/plugin.d.ts +13 -0
- package/dist/plugins/version/plugin.d.ts.map +1 -0
- package/dist/plugins/version/type.d.ts +47 -0
- package/dist/plugins/version/type.d.ts.map +1 -0
- package/dist/plugins/vue/index.d.ts +21 -0
- package/dist/plugins/vue/index.d.ts.map +1 -0
- package/dist/plugins/vue/index.js +114 -0
- package/dist/plugins/vue/index.js.map +1 -0
- package/dist/plugins/vue/plugin.d.ts +15 -0
- package/dist/plugins/vue/plugin.d.ts.map +1 -0
- package/dist/plugins/vue/type.d.ts +34 -0
- package/dist/plugins/vue/type.d.ts.map +1 -0
- package/dist/strategies/index.d.ts +2 -0
- package/dist/strategies/index.d.ts.map +1 -0
- package/dist/strategies/index.js +29 -0
- package/dist/strategies/index.js.map +1 -0
- package/dist/strategies/plain.d.ts +2 -0
- package/dist/strategies/plain.d.ts.map +1 -0
- package/dist/strategies/plain.js +23 -0
- package/dist/strategies/plain.js.map +1 -0
- package/dist/strategies/react.d.ts +2 -0
- package/dist/strategies/react.d.ts.map +1 -0
- package/dist/strategies/react.js +30 -0
- package/dist/strategies/react.js.map +1 -0
- package/dist/strategies/shared/adapter.d.ts +23 -0
- package/dist/strategies/shared/adapter.d.ts.map +1 -0
- package/dist/strategies/shared/dom.d.ts +53 -0
- package/dist/strategies/shared/dom.d.ts.map +1 -0
- package/dist/strategies/shared/error.d.ts +30 -0
- package/dist/strategies/shared/error.d.ts.map +1 -0
- package/dist/strategies/shared/method.d.ts +51 -0
- package/dist/strategies/shared/method.d.ts.map +1 -0
- package/dist/strategies/shared/public.d.ts +33 -0
- package/dist/strategies/shared/public.d.ts.map +1 -0
- package/dist/strategies/shared/queue.d.ts +30 -0
- package/dist/strategies/shared/queue.d.ts.map +1 -0
- package/dist/strategies/shared/retry.d.ts +51 -0
- package/dist/strategies/shared/retry.d.ts.map +1 -0
- package/dist/strategies/shared/state.d.ts +117 -0
- package/dist/strategies/shared/state.d.ts.map +1 -0
- package/dist/strategies/shared/timing.d.ts +53 -0
- package/dist/strategies/shared/timing.d.ts.map +1 -0
- package/dist/strategies/shared/watcher.d.ts +37 -0
- package/dist/strategies/shared/watcher.d.ts.map +1 -0
- package/dist/strategies/use-auto-request.d.ts +77 -0
- package/dist/strategies/use-auto-request.d.ts.map +1 -0
- package/dist/strategies/use-download.d.ts +103 -0
- package/dist/strategies/use-download.d.ts.map +1 -0
- package/dist/strategies/use-fetcher.d.ts +52 -0
- package/dist/strategies/use-fetcher.d.ts.map +1 -0
- package/dist/strategies/use-pagination.d.ts +101 -0
- package/dist/strategies/use-pagination.d.ts.map +1 -0
- package/dist/strategies/use-request.d.ts +50 -0
- package/dist/strategies/use-request.d.ts.map +1 -0
- package/dist/strategies/use-retriable-request.d.ts +46 -0
- package/dist/strategies/use-retriable-request.d.ts.map +1 -0
- package/dist/strategies/use-sse.d.ts +103 -0
- package/dist/strategies/use-sse.d.ts.map +1 -0
- package/dist/strategies/use-token-auth.d.ts +88 -0
- package/dist/strategies/use-token-auth.d.ts.map +1 -0
- package/dist/strategies/use-uploader.d.ts +88 -0
- package/dist/strategies/use-uploader.d.ts.map +1 -0
- package/dist/strategies/use-watcher.d.ts +69 -0
- package/dist/strategies/use-watcher.d.ts.map +1 -0
- package/dist/typings/adapter.d.ts +61 -0
- package/dist/typings/adapter.d.ts.map +1 -0
- package/dist/typings/api.d.ts +122 -0
- package/dist/typings/api.d.ts.map +1 -0
- package/dist/typings/args.d.ts +51 -0
- package/dist/typings/args.d.ts.map +1 -0
- package/dist/typings/index.d.ts +8 -12
- package/dist/typings/index.d.ts.map +1 -0
- package/dist/typings/meta.d.ts +44 -0
- package/dist/typings/meta.d.ts.map +1 -0
- package/dist/typings/plugin.d.ts +114 -0
- package/dist/typings/plugin.d.ts.map +1 -0
- package/dist/typings/response.d.ts +118 -0
- package/dist/typings/response.d.ts.map +1 -0
- package/dist/typings/server.d.ts +83 -0
- package/dist/typings/server.d.ts.map +1 -0
- package/dist/typings/stream.d.ts +150 -0
- package/dist/typings/stream.d.ts.map +1 -0
- package/dist/utils/download.d.ts +97 -0
- package/dist/utils/download.d.ts.map +1 -0
- package/dist/utils/emitter.d.ts +36 -0
- package/dist/utils/emitter.d.ts.map +1 -0
- package/dist/utils/index.d.ts +6 -1
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/is.d.ts +22 -0
- package/dist/utils/is.d.ts.map +1 -0
- package/dist/utils/object.d.ts +44 -0
- package/dist/utils/object.d.ts.map +1 -0
- package/dist/utils/url.d.ts +44 -0
- package/dist/utils/url.d.ts.map +1 -0
- package/package.json +90 -27
- package/README_EN.md +0 -607
- package/dist/cache/index.d.ts +0 -9
- package/dist/cache/indexDBCache.d.ts +0 -13
- package/dist/cache/localstorageCache.d.ts +0 -10
- package/dist/cache/memoryCache.d.ts +0 -11
- package/dist/core/index.d.ts +0 -4
- package/dist/core/snailApi.d.ts +0 -22
- package/dist/core/snailMethod.d.ts +0 -49
- package/dist/core/snailServer.d.ts +0 -35
- package/dist/core/snailSse.d.ts +0 -20
- package/dist/decorators/cache.d.ts +0 -15
- package/dist/decorators/method.d.ts +0 -38
- package/dist/decorators/sse.d.ts +0 -30
- package/dist/decorators/strategy.d.ts +0 -10
- package/dist/decorators/versioning.d.ts +0 -16
- package/dist/eventEmmit/index.d.ts +0 -1
- package/dist/eventEmmit/snail.event.d.ts +0 -10
- package/dist/snail-api.js +0 -4868
- package/dist/snail-api.umd.cjs +0 -4872
- package/dist/strategies/jwtStrategy.d.ts +0 -4
- package/dist/typings/api.option.d.ts +0 -10
- package/dist/typings/apiProxy.d.ts +0 -8
- package/dist/typings/cache.management.option.d.ts +0 -25
- package/dist/typings/cache.type.d.ts +0 -23
- package/dist/typings/content.type.d.ts +0 -5
- package/dist/typings/request.body.d.ts +0 -3
- package/dist/typings/response.data.d.ts +0 -13
- package/dist/typings/snail.event.d.ts +0 -6
- package/dist/typings/snail.method.d.ts +0 -14
- package/dist/typings/snail.option.d.ts +0 -16
- package/dist/typings/sse.d.ts +0 -15
- package/dist/typings/strategy.d.ts +0 -5
- package/dist/typings/versioning.option.d.ts +0 -30
- package/dist/utils/function.d.ts +0 -31
- package/dist/versioning/index.d.ts +0 -1
- package/dist/versioning/versioning.d.ts +0 -12
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { DtoType, PropertyTypeOptions } from "./type.js";
|
|
2
|
+
/** Metadata slot written by `@PropertyType`. */
|
|
3
|
+
export declare const PROPERTY_TYPE_KEY: symbol;
|
|
4
|
+
/** Metadata slot written by `@ExposeName`. */
|
|
5
|
+
export declare const EXPOSE_NAME_KEY: symbol;
|
|
6
|
+
/**
|
|
7
|
+
* Choose the DTO a response payload is hydrated into.
|
|
8
|
+
*
|
|
9
|
+
* Applies to an api class and to a single method; the method wins, so one
|
|
10
|
+
* endpoint can answer with a different shape than its siblings.
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* @Api("/user")
|
|
14
|
+
* @Transform(UserDto)
|
|
15
|
+
* class UserApi {
|
|
16
|
+
* @Get("/:id")
|
|
17
|
+
* getUser(@Params("id") id: string): Promise<UserDto> { return null!; }
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function Transform(dto: DtoType): ClassDecorator & MethodDecorator;
|
|
22
|
+
/**
|
|
23
|
+
* Declare the runtime type of one DTO property.
|
|
24
|
+
*
|
|
25
|
+
* ```ts
|
|
26
|
+
* class OrderDto {
|
|
27
|
+
* @PropertyType(() => UserDto) user!: UserDto;
|
|
28
|
+
* @PropertyType(() => ItemDto, { array: true }) items!: ItemDto[];
|
|
29
|
+
* @PropertyType(() => Date) createdAt!: Date;
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* A property without `@PropertyType` is assigned as-is, so primitives, plain
|
|
34
|
+
* objects and arrays of primitives need no declaration — but they *do* need
|
|
35
|
+
* something that makes the property known, otherwise the unknown-key rule drops
|
|
36
|
+
* them.
|
|
37
|
+
*/
|
|
38
|
+
export declare function PropertyType(type: () => unknown, options?: PropertyTypeOptions): PropertyDecorator;
|
|
39
|
+
/**
|
|
40
|
+
* Read a property from a differently-named JSON key.
|
|
41
|
+
*
|
|
42
|
+
* ```ts
|
|
43
|
+
* class UserDto {
|
|
44
|
+
* @ExposeName("user_name") userName!: string;
|
|
45
|
+
* }
|
|
46
|
+
* // { "user_name": "ada" } → new UserDto().userName === "ada"
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* Excluding a key needs no decorator: undeclared JSON keys are already dropped.
|
|
50
|
+
*/
|
|
51
|
+
export declare function ExposeName(jsonKey: string): PropertyDecorator;
|
|
52
|
+
/** Read the DTO of one method: method first, then the api class. */
|
|
53
|
+
export declare function resolveDto(apiClass: unknown, methodName: string): DtoType | undefined;
|
|
54
|
+
//# sourceMappingURL=decorators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../../src/plugins/transform/decorators.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAoB,MAAM,QAAQ,CAAC;AAc7E,gDAAgD;AAChD,eAAO,MAAM,iBAAiB,QAA+C,CAAC;AAE9E,8CAA8C;AAC9C,eAAO,MAAM,eAAe,QAA6C,CAAC;AAE1E;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,GAAG,eAAe,CAUxE;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,OAAO,EACnB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,iBAAiB,CAQnB;AAID;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAQ7D;AAED,oEAAoE;AACpE,wBAAgB,UAAU,CACxB,QAAQ,EAAE,OAAO,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,GAAG,SAAS,CAKrB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { SnailContext } from "../../core/context.js";
|
|
2
|
+
import type { DtoType } from "./type.js";
|
|
3
|
+
/**
|
|
4
|
+
* The JSON → class hydration engine.
|
|
5
|
+
*
|
|
6
|
+
* Hand-written on purpose: `class-transformer` would be a second runtime
|
|
7
|
+
* dependency next to axios, and `reflect-metadata` cannot help at all here —
|
|
8
|
+
* TypeScript 7 never emits `design:type`, so *no* library can discover a property
|
|
9
|
+
* type without a compiler plugin. The declarations this plugin reads
|
|
10
|
+
* (`@PropertyType`) are therefore not a workaround but the only runtime source of
|
|
11
|
+
* truth available.
|
|
12
|
+
*
|
|
13
|
+
* ## Model
|
|
14
|
+
*
|
|
15
|
+
* ```text
|
|
16
|
+
* hydrate(raw, DtoClass)
|
|
17
|
+
* raw is a primitive / null / too deep → returned unchanged
|
|
18
|
+
* raw is an array → one instance per item
|
|
19
|
+
* DtoClass has static fromJSON → fromJSON(raw, ctx) wins outright
|
|
20
|
+
* otherwise → new DtoClass() + declared properties
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
/** Depth used when the caller does not set `maxDepth`. */
|
|
24
|
+
export declare const DEFAULT_MAX_DEPTH = 32;
|
|
25
|
+
/** Options accepted by {@link hydrate}. */
|
|
26
|
+
export interface HydrateOptions {
|
|
27
|
+
/** Keep JSON keys the DTO does not declare. Defaults to `false`. */
|
|
28
|
+
keepUnknown?: boolean;
|
|
29
|
+
/** Maximum object depth to descend. Defaults to {@link DEFAULT_MAX_DEPTH}. */
|
|
30
|
+
maxDepth?: number;
|
|
31
|
+
/** Forwarded to a DTO's `static fromJSON(raw, ctx)`. */
|
|
32
|
+
ctx?: SnailContext;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Turn a plain JSON payload into an instance of `DtoClass`.
|
|
36
|
+
*
|
|
37
|
+
* A primitive, `null`, an unknown class or an over-deep value is returned
|
|
38
|
+
* unchanged rather than wrapped: the caller asked for a class, but a response that
|
|
39
|
+
* does not look like one is more useful as-is than as an empty instance.
|
|
40
|
+
*
|
|
41
|
+
* ```ts
|
|
42
|
+
* const user = hydrate(raw, UserDto);
|
|
43
|
+
* user instanceof UserDto; // true
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function hydrate<T>(raw: unknown, DtoClass: DtoType<T>, options?: HydrateOptions): T;
|
|
47
|
+
//# sourceMappingURL=hydrate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydrate.d.ts","sourceRoot":"","sources":["../../../src/plugins/transform/hydrate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAoB,MAAM,QAAQ,CAAC;AAExD;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,0DAA0D;AAC1D,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,2CAA2C;AAC3C,MAAM,WAAW,cAAc;IAC7B,oEAAoE;IACpE,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,wDAAwD;IACxD,GAAG,CAAC,EAAE,YAAY,CAAC;CACpB;AA6MD;;;;;;;;;;;GAWG;AACH,wBAAgB,OAAO,CAAC,CAAC,EACvB,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,GAAE,cAAmB,GAC3B,CAAC,CAYH"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { SnailPluginObject } from "../../typings/plugin.js";
|
|
2
|
+
import type { DtoType, TransformOptions } from "./type.js";
|
|
3
|
+
/**
|
|
4
|
+
* JSON → class transform plugin.
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { Transform, PropertyType, ExposeName } from "@snail-js/api/plugins";
|
|
8
|
+
*
|
|
9
|
+
* Service.use(Transform());
|
|
10
|
+
*
|
|
11
|
+
* class UserDto {
|
|
12
|
+
* @ExposeName("user_name") userName!: string;
|
|
13
|
+
* @PropertyType(() => Date) createdAt!: Date;
|
|
14
|
+
* }
|
|
15
|
+
*
|
|
16
|
+
* @Api("/user")
|
|
17
|
+
* @Transform(UserDto)
|
|
18
|
+
* class UserApi {
|
|
19
|
+
* @Get("/:id")
|
|
20
|
+
* getUser(@Params("id") id: string): Promise<UserDto> { return null!; }
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @packageDocumentation
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* The transform plugin factory, and — called with a DTO class — the DTO decorator.
|
|
28
|
+
*
|
|
29
|
+
* Two things share one name because the specification gives both of them the name
|
|
30
|
+
* `Transform`: the factory (`Service.use(Transform())`) and the decorator
|
|
31
|
+
* (`@Transform(UserDto)`). They are told apart by their argument — a DTO is a
|
|
32
|
+
* constructor function with no options of its own, options are never callable —
|
|
33
|
+
* so neither call style has to be renamed.
|
|
34
|
+
*/
|
|
35
|
+
export declare function Transform(dto: DtoType): ClassDecorator & MethodDecorator;
|
|
36
|
+
export declare function Transform(options?: TransformOptions): SnailPluginObject<TransformOptions>;
|
|
37
|
+
export { ExposeName, PropertyType } from "./decorators.js";
|
|
38
|
+
export { hydrate } from "./hydrate.js";
|
|
39
|
+
export type { HydrateOptions } from "./hydrate.js";
|
|
40
|
+
export type { DtoType, PropertyTypeOptions, PropertyTypeSpec, TransformOptions } from "./type.js";
|
|
41
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/transform/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAExD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,GAAG,eAAe,CAAC;AAC1E,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;AAO3F,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,YAAY,EACV,OAAO,EACP,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,QAAQ,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { TransformOptions } from "./type.js";
|
|
2
|
+
/**
|
|
3
|
+
* Create the transform plugin.
|
|
4
|
+
*
|
|
5
|
+
* ```ts
|
|
6
|
+
* Service.use(Transform());
|
|
7
|
+
*
|
|
8
|
+
* @Api("/user")
|
|
9
|
+
* @Transform(UserDto)
|
|
10
|
+
* class UserApi {
|
|
11
|
+
* @Get("/:id")
|
|
12
|
+
* getUser(@Params("id") id: string): Promise<UserDto> { return null!; }
|
|
13
|
+
* }
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* Without a DTO — no decorator and no `dto` option — the plugin is a no-op and the
|
|
17
|
+
* payload stays the plain object JSON.parse produced.
|
|
18
|
+
*/
|
|
19
|
+
export declare const transformPlugin: import("../../index.js").SnailPlugin<TransformOptions>;
|
|
20
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/transform/plugin.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAW,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAqExD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,eAAe,+CAmB1B,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { SnailContext } from "../../core/context.js";
|
|
2
|
+
/**
|
|
3
|
+
* JSON → class transform types.
|
|
4
|
+
*
|
|
5
|
+
* Everything here is deliberately hand-rolled: no `class-transformer`, no
|
|
6
|
+
* `reflect-metadata`, no design-time type emission. TypeScript 7 cannot emit
|
|
7
|
+
* constructor parameter types at all, so the plugin relies on the explicit
|
|
8
|
+
* `@PropertyType()` declarations the DTO author writes — which is also the only
|
|
9
|
+
* way nested types are visible at runtime without a compiler plugin.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* A class the transform plugin can hydrate into.
|
|
13
|
+
*
|
|
14
|
+
* `fromJSON` is optional and hand-written: when a DTO declares it, it wins over
|
|
15
|
+
* automatic hydration, because a class that knows how to build itself from JSON
|
|
16
|
+
* is the authority on its own invariants.
|
|
17
|
+
*/
|
|
18
|
+
export type DtoType<T = unknown> = (new () => T) & {
|
|
19
|
+
/** Hand-written factory. Receives the raw JSON value and the live context. */
|
|
20
|
+
fromJSON?: (raw: unknown, ctx?: SnailContext) => T;
|
|
21
|
+
};
|
|
22
|
+
/** Options for one `@PropertyType()` application. */
|
|
23
|
+
export interface PropertyTypeOptions {
|
|
24
|
+
/**
|
|
25
|
+
* Hydrate an array of `type` instead of a single value.
|
|
26
|
+
*
|
|
27
|
+
* Explicit rather than inferred: an empty JSON array cannot tell the plugin
|
|
28
|
+
* whether it holds DTOs or primitives, so guessing would produce `[]` either
|
|
29
|
+
* way while hiding the mistake.
|
|
30
|
+
*/
|
|
31
|
+
array?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/** What a `@PropertyType()` decorator stores for one property. */
|
|
34
|
+
export interface PropertyTypeSpec {
|
|
35
|
+
/**
|
|
36
|
+
* Lazy type resolver, e.g. `() => ChildDto`.
|
|
37
|
+
*
|
|
38
|
+
* Lazy is required, not cosmetic: two DTOs that reference each other would
|
|
39
|
+
* otherwise hit a temporal dead zone at class-definition time.
|
|
40
|
+
*/
|
|
41
|
+
type: () => unknown;
|
|
42
|
+
/** Extra options, when the decorator was given any. */
|
|
43
|
+
options?: PropertyTypeOptions;
|
|
44
|
+
}
|
|
45
|
+
/** Options accepted by the `Transform` plugin factory. */
|
|
46
|
+
export interface TransformOptions {
|
|
47
|
+
/** DTO used when neither the method nor the api class declares one. */
|
|
48
|
+
dto?: DtoType;
|
|
49
|
+
/**
|
|
50
|
+
* Keep JSON keys the DTO does not declare.
|
|
51
|
+
*
|
|
52
|
+
* Defaults to `false`: a DTO is a whitelist, and carrying undeclared keys onto
|
|
53
|
+
* the instance is how internal backend fields leak into templates. A DTO that
|
|
54
|
+
* declares *nothing* is the exception — there is no whitelist to apply, so every
|
|
55
|
+
* own key of the JSON is assigned.
|
|
56
|
+
*/
|
|
57
|
+
keepUnknown?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Maximum object depth to descend.
|
|
60
|
+
*
|
|
61
|
+
* Defaults to `32`. A self-referencing `@PropertyType` plus deeply nested (or
|
|
62
|
+
* cyclic) JSON would otherwise recurse until the stack blew, taking the whole
|
|
63
|
+
* request with it.
|
|
64
|
+
*/
|
|
65
|
+
maxDepth?: number;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=type.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../src/plugins/transform/type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;;;;;;GAQG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,OAAO,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,GAAG;IACjD,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,YAAY,KAAK,CAAC,CAAC;CACpD,CAAC;AAEF,qDAAqD;AACrD,MAAM,WAAW,mBAAmB;IAClC;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,kEAAkE;AAClE,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,IAAI,EAAE,MAAM,OAAO,CAAC;IAEpB,uDAAuD;IACvD,OAAO,CAAC,EAAE,mBAAmB,CAAC;CAC/B;AAED,0DAA0D;AAC1D,MAAM,WAAW,gBAAgB;IAC/B,uEAAuE;IACvE,GAAG,CAAC,EAAE,OAAO,CAAC;IAEd;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ZodType } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Validate the outgoing request body (or query) against a zod schema.
|
|
4
|
+
*
|
|
5
|
+
* ```ts
|
|
6
|
+
* @Post("/")
|
|
7
|
+
* @Validate(z.object({ name: z.string().min(1) }))
|
|
8
|
+
* create(@Data() body: CreateUser): Promise<User> { return null!; }
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export declare function Validate(schema: ZodType): ClassDecorator & MethodDecorator;
|
|
12
|
+
/**
|
|
13
|
+
* Validate the response payload against a zod schema.
|
|
14
|
+
*
|
|
15
|
+
* Response validation only ever warns: the backend, not the caller, decides what
|
|
16
|
+
* it sends, and throwing away a usable payload because one field is unexpected
|
|
17
|
+
* turns a cosmetic backend drift into a broken page.
|
|
18
|
+
*/
|
|
19
|
+
export declare function ValidateResponse(schema: ZodType): ClassDecorator & MethodDecorator;
|
|
20
|
+
/** Read the request schema of one method: method first, then the api class. */
|
|
21
|
+
export declare function resolveRequestSchema(apiClass: unknown, methodName: string): ZodType | undefined;
|
|
22
|
+
/** Read the response schema of one method: method first, then the api class. */
|
|
23
|
+
export declare function resolveResponseSchema(apiClass: unknown, methodName: string): ZodType | undefined;
|
|
24
|
+
//# sourceMappingURL=decorators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../../src/plugins/validate/decorators.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AA6CnC;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,cAAc,GAAG,eAAe,CAE1E;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,GAAG,cAAc,GAAG,eAAe,CAElF;AAED,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,OAAO,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,GAAG,SAAS,CAKrB;AAED,gFAAgF;AAChF,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,OAAO,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,GAAG,SAAS,CAKrB"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ZodType } from "zod";
|
|
2
|
+
import type { SnailPluginObject } from "../../typings/plugin.js";
|
|
3
|
+
import type { ValidateOptions } from "./type.js";
|
|
4
|
+
/**
|
|
5
|
+
* Zod validation plugin.
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { Validate, ValidateResponse } from "@snail-js/api/plugins";
|
|
9
|
+
*
|
|
10
|
+
* Service.use(Validate());
|
|
11
|
+
*
|
|
12
|
+
* @Api("/user")
|
|
13
|
+
* class UserApi {
|
|
14
|
+
* @Post("/")
|
|
15
|
+
* @Validate(z.object({ name: z.string().min(1) }))
|
|
16
|
+
* @ValidateResponse(z.object({ id: z.number() }))
|
|
17
|
+
* create(@Data() body: CreateUser): Promise<User> { return null!; }
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @packageDocumentation
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* The validate plugin factory, and — called with a zod schema — the request
|
|
25
|
+
* schema decorator.
|
|
26
|
+
*
|
|
27
|
+
* Two things share one name because the brief that specifies this plugin gives
|
|
28
|
+
* both of them the name `Validate`: the factory (`Service.use(Validate())`) and
|
|
29
|
+
* the decorator (`@Validate(schema)`). Rather than rename one of them and break
|
|
30
|
+
* one of the two call styles, the two are told apart by their argument: a zod
|
|
31
|
+
* schema is an object with `safeParse`, options never have one. `Validate()` and
|
|
32
|
+
* `Validate({ request: schema })` return the plugin, `@Validate(schema)` returns
|
|
33
|
+
* the decorator.
|
|
34
|
+
*/
|
|
35
|
+
export declare function Validate(schema: ZodType): ClassDecorator & MethodDecorator;
|
|
36
|
+
export declare function Validate(options?: ValidateOptions): SnailPluginObject<ValidateOptions>;
|
|
37
|
+
export { ValidateResponse } from "./decorators.js";
|
|
38
|
+
export { SnailValidationError } from "./type.js";
|
|
39
|
+
export type { SnailValidationIssue, ValidateOptions } from "./type.js";
|
|
40
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/validate/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAE9C;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,cAAc,GAAG,eAAe,CAAC;AAC5E,wBAAgB,QAAQ,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,iBAAiB,CAAC,eAAe,CAAC,CAAC;AAcxF,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAC9C,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ValidateOptions } from "./type.js";
|
|
2
|
+
/**
|
|
3
|
+
* Create the zod validation plugin.
|
|
4
|
+
*
|
|
5
|
+
* ```ts
|
|
6
|
+
* Service.use(Validate({ strict: false }));
|
|
7
|
+
* ```
|
|
8
|
+
*
|
|
9
|
+
* It is normally used without options, together with the decorators:
|
|
10
|
+
* `Service.use(Validate())`.
|
|
11
|
+
*/
|
|
12
|
+
export declare const validatePlugin: import("../../index.js").SnailPlugin<ValidateOptions>;
|
|
13
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/validate/plugin.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAyF9C;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,8CAyBzB,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { ZodType, core } from "zod";
|
|
2
|
+
import { SnailError } from "../../error/base.js";
|
|
3
|
+
/**
|
|
4
|
+
* Zod validation plugin types.
|
|
5
|
+
*
|
|
6
|
+
* `zod` is an optional peer dependency and this directory is the only place in the
|
|
7
|
+
* library allowed to reference it. Everything here is a *type* reference, so
|
|
8
|
+
* importing the plugin never pulls zod's runtime into the bundle: the schemas are
|
|
9
|
+
* supplied by the application, which already has zod.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* One problem zod reported.
|
|
13
|
+
*
|
|
14
|
+
* Re-exported under a library-owned name so application code can type an error
|
|
15
|
+
* handler without importing zod's internal `core` namespace — the deprecation
|
|
16
|
+
* churn of that namespace should not reach callers through this library.
|
|
17
|
+
*/
|
|
18
|
+
export type SnailValidationIssue = core.$ZodIssue;
|
|
19
|
+
/** Options accepted by the `Validate` plugin factory. */
|
|
20
|
+
export interface ValidateOptions {
|
|
21
|
+
/** Schema applied when no `@Validate()` decorator declares one. */
|
|
22
|
+
request?: ZodType;
|
|
23
|
+
/** Schema applied when no `@ValidateResponse()` decorator declares one. */
|
|
24
|
+
response?: ZodType;
|
|
25
|
+
/**
|
|
26
|
+
* Whether an invalid *request* aborts the call.
|
|
27
|
+
*
|
|
28
|
+
* Defaults to `true`. `false` downgrades the failure to a warning and lets the
|
|
29
|
+
* request go out — useful while developing against a backend whose contract is
|
|
30
|
+
* still moving, and never a good idea in production. Responses are never
|
|
31
|
+
* validated strictly.
|
|
32
|
+
*/
|
|
33
|
+
strict?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Thrown when the request payload does not satisfy its schema.
|
|
37
|
+
*
|
|
38
|
+
* The request is abandoned **before** anything reaches the network, which is the
|
|
39
|
+
* whole point of validating a request: an invalid body that is still sent produces
|
|
40
|
+
* a backend error that looks like a server bug, and a `4xx` that pollutes the
|
|
41
|
+
* application's error handling for what is really a programmer mistake.
|
|
42
|
+
*
|
|
43
|
+
* `issues` is zod's own list, kept verbatim so the application can render field
|
|
44
|
+
* paths and messages instead of parsing a string.
|
|
45
|
+
*/
|
|
46
|
+
export declare class SnailValidationError extends SnailError {
|
|
47
|
+
/** Every issue zod reported, in zod's original shape. */
|
|
48
|
+
readonly issues: readonly SnailValidationIssue[];
|
|
49
|
+
constructor(message: string, options: {
|
|
50
|
+
issues: readonly SnailValidationIssue[];
|
|
51
|
+
cause?: unknown;
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=type.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../src/plugins/validate/type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C;;;;;;;GAOG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,SAAS,CAAC;AAElD,yDAAyD;AACzD,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,oBAAqB,SAAQ,UAAU;IAClD,yDAAyD;IACzD,QAAQ,CAAC,MAAM,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAEjD,YACE,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;QAAE,MAAM,EAAE,SAAS,oBAAoB,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAItE;CACF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Declare the version of an api class or of a single request method.
|
|
3
|
+
*
|
|
4
|
+
* ```ts
|
|
5
|
+
* @Api("/user")
|
|
6
|
+
* @Version("1.2.0")
|
|
7
|
+
* class UserApi {
|
|
8
|
+
* @Get("/legacy")
|
|
9
|
+
* @Version("0.9.0")
|
|
10
|
+
* legacy(): Promise<void> { return null!; }
|
|
11
|
+
* }
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare function Version(version: string): ClassDecorator & MethodDecorator;
|
|
15
|
+
/**
|
|
16
|
+
* Read the version declared for one method.
|
|
17
|
+
*
|
|
18
|
+
* Reads the method slot first, then the class slot, and both walk the prototype
|
|
19
|
+
* chain so a subclass inherits the version of its base api class.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveDeclaredVersion(apiClass: unknown, methodName: string): string | undefined;
|
|
22
|
+
//# sourceMappingURL=decorators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../../src/plugins/version/decorators.ts"],"names":[],"mappings":"AAyBA;;;;;;;;;;;;GAYG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,GAAG,eAAe,CAUzE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,OAAO,EACjB,UAAU,EAAE,MAAM,GACjB,MAAM,GAAG,SAAS,CAKpB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version management plugin.
|
|
3
|
+
*
|
|
4
|
+
* ```ts
|
|
5
|
+
* import { Version, Versioning } from "@snail-js/api/plugins";
|
|
6
|
+
*
|
|
7
|
+
* Service.use(Versioning({ type: "url", defaultVersion: "1.0.0" }));
|
|
8
|
+
*
|
|
9
|
+
* @Api("/user")
|
|
10
|
+
* @Version("1.2.0")
|
|
11
|
+
* class UserApi {
|
|
12
|
+
* @Get("/:id")
|
|
13
|
+
* getUser(@Params("id") id: string): Promise<User> { return null!; }
|
|
14
|
+
* }
|
|
15
|
+
* // → GET /api/v1.2.0/user/1
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @packageDocumentation
|
|
19
|
+
*/
|
|
20
|
+
export { Version } from "./decorators.js";
|
|
21
|
+
export { Versioning } from "./plugin.js";
|
|
22
|
+
export type { VersioningOptions, VersioningPatch, VersioningType } from "./type.js";
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/version/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,YAAY,EAAE,iBAAiB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { VersioningOptions } from "./type.js";
|
|
2
|
+
/**
|
|
3
|
+
* Create the version management plugin.
|
|
4
|
+
*
|
|
5
|
+
* ```ts
|
|
6
|
+
* Service.use(Versioning({ type: "url", defaultVersion: "1.0.0" }));
|
|
7
|
+
* ```
|
|
8
|
+
*
|
|
9
|
+
* The rewrite happens in `beforeRequest`, so it is the last thing that can change
|
|
10
|
+
* the url before the request is hashed, cached and sent.
|
|
11
|
+
*/
|
|
12
|
+
export declare const Versioning: import("../../index.js").SnailPlugin<VersioningOptions>;
|
|
13
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/version/plugin.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,iBAAiB,EAAmC,MAAM,QAAQ,CAAC;AAsMjF;;;;;;;;;GASG;AACH,eAAO,MAAM,UAAU,gDAcrB,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { SnailContext } from "../../core/context.js";
|
|
2
|
+
/**
|
|
3
|
+
* Where the versioning plugin writes the version on the outgoing request.
|
|
4
|
+
*
|
|
5
|
+
* `"custom"` exists because no fixed list of transports covers every backend:
|
|
6
|
+
* some gateways want `Accept: application/vnd.acme.v2+json`, some want the
|
|
7
|
+
* version inside the body. A custom extractor receives the live context and
|
|
8
|
+
* returns the patch to merge instead of guessing.
|
|
9
|
+
*/
|
|
10
|
+
export type VersioningType = "url" | "header" | "query" | "custom";
|
|
11
|
+
/**
|
|
12
|
+
* The change a `custom` extractor asks for.
|
|
13
|
+
*
|
|
14
|
+
* Every field is optional: an extractor that only touches headers must not be
|
|
15
|
+
* forced to restate the url it read from `ctx.request`.
|
|
16
|
+
*/
|
|
17
|
+
export interface VersioningPatch {
|
|
18
|
+
/** Replacement for the request url, used verbatim. */
|
|
19
|
+
url?: string;
|
|
20
|
+
/** Headers to merge into the outgoing request. */
|
|
21
|
+
headers?: Record<string, string>;
|
|
22
|
+
/** Query params to merge into the outgoing request. */
|
|
23
|
+
params?: Record<string, unknown>;
|
|
24
|
+
}
|
|
25
|
+
/** Options accepted by the `Versioning` plugin factory. */
|
|
26
|
+
export interface VersioningOptions {
|
|
27
|
+
/** Transport the version travels on. */
|
|
28
|
+
type: VersioningType;
|
|
29
|
+
/**
|
|
30
|
+
* Version used when neither the method nor the api class declares one.
|
|
31
|
+
*
|
|
32
|
+
* Required on purpose: a default version is a contract with the backend, and
|
|
33
|
+
* silently assuming `"1.0.0"` produces 404s that look like routing bugs.
|
|
34
|
+
*/
|
|
35
|
+
defaultVersion: string;
|
|
36
|
+
/**
|
|
37
|
+
* Key or url segment name.
|
|
38
|
+
*
|
|
39
|
+
* Defaults to `"v"` for `url`/`query` (so `/user/1` becomes `/v1.2.0/user/1`)
|
|
40
|
+
* and to `"x-api-version"` for `header`. Pass `""` in `url` mode for a bare
|
|
41
|
+
* `/1.2.0/user/1` segment.
|
|
42
|
+
*/
|
|
43
|
+
key?: string;
|
|
44
|
+
/** Only for `type: "custom"`. Receives the resolved version and the live context. */
|
|
45
|
+
extractor?: (version: string, ctx: SnailContext) => VersioningPatch | void;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=type.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../src/plugins/version/type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEnE;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,2DAA2D;AAC3D,MAAM,WAAW,iBAAiB;IAChC,wCAAwC;IACxC,IAAI,EAAE,cAAc,CAAC;IAErB;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,qFAAqF;IACrF,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,KAAK,eAAe,GAAG,IAAI,CAAC;CAC5E"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vue adapter plugin.
|
|
3
|
+
*
|
|
4
|
+
* ```ts
|
|
5
|
+
* import { VueAdapter } from "@snail-js/api/plugins/vue";
|
|
6
|
+
*
|
|
7
|
+
* Service.use(VueAdapter());
|
|
8
|
+
*
|
|
9
|
+
* const user = Service.createApi(UserApi).getUser("1");
|
|
10
|
+
* // `user.meta.loading` / `meta.data` / `meta.error` are Vue refs.
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* This sits behind its own subpath rather than in `@snail-js/api/plugins`: that
|
|
14
|
+
* barrel must not statically import `vue`, or an application using only `Cache`
|
|
15
|
+
* would fail to resolve Vue at all.
|
|
16
|
+
*
|
|
17
|
+
* @packageDocumentation
|
|
18
|
+
*/
|
|
19
|
+
export { VueAdapter } from "./plugin.js";
|
|
20
|
+
export type { VueAdapterOptions } from "./type.js";
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/vue/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,YAAY,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC"}
|