@cleverbrush/server 4.5.0 → 5.1.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 +28 -0
- package/README.md +486 -20
- package/dist/Cors.d.ts +28 -0
- package/dist/Endpoint.d.ts +32 -14
- package/dist/EndpointOptions.d.ts +31 -0
- package/dist/EndpointPath.d.ts +23 -0
- package/dist/ErrorMap.d.ts +90 -0
- package/dist/Implementation.d.ts +193 -0
- package/dist/RequestContext.d.ts +2 -2
- package/dist/Server.d.ts +17 -9
- package/dist/VirtualHttp.d.ts +2 -0
- package/dist/chunk-YCSREVQU.js +2 -0
- package/dist/chunk-YCSREVQU.js.map +1 -0
- package/dist/contract.d.ts +4 -2
- package/dist/contract.js +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/middlewares/Idempotency.d.ts +20 -41
- package/dist/middlewares/ResponseCache.d.ts +7 -0
- package/dist/middlewares/ResponseSnapshot.d.ts +9 -0
- package/dist/multipart.d.ts +9 -0
- package/dist/types.d.ts +12 -1
- package/dist/upload.d.ts +16 -0
- package/dist/withRequestSignal.d.ts +29 -0
- package/package.json +10 -7
- package/dist/chunk-L2OPVEOF.js +0 -2
- package/dist/chunk-L2OPVEOF.js.map +0 -1
|
@@ -1,52 +1,31 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Server-side idempotency middleware.
|
|
3
|
-
*
|
|
4
|
-
* Ensures mutating requests with the same idempotency key produce the
|
|
5
|
-
* same result exactly once — subsequent replays return the stored
|
|
6
|
-
* response without re-executing the handler.
|
|
7
|
-
*
|
|
8
|
-
* @module
|
|
9
|
-
*/
|
|
10
1
|
import type { RequestContext } from '../RequestContext.js';
|
|
11
2
|
import type { Middleware } from '../types.js';
|
|
12
|
-
/**
|
|
13
|
-
* Configuration for {@link idempotency}.
|
|
14
|
-
*/
|
|
3
|
+
/** Configuration for bounded, process-local mutation response replay. */
|
|
15
4
|
export interface ServerIdempotencyOptions {
|
|
16
5
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
6
|
+
* Explicit authorization/tenant scope. Run after authentication and
|
|
7
|
+
* authorization. Return undefined to skip; use a fixed string only for
|
|
8
|
+
* deliberately public operations. Never use an unverified identity header.
|
|
19
9
|
*/
|
|
10
|
+
scope: (ctx: RequestContext) => string | undefined;
|
|
11
|
+
/** Stored response lifetime in milliseconds. Default: 86,400,000. */
|
|
20
12
|
ttl?: number;
|
|
21
|
-
/**
|
|
22
|
-
* Header name to read the idempotency key from.
|
|
23
|
-
* Defaults to `"x-idempotency-key"`.
|
|
24
|
-
*/
|
|
13
|
+
/** Case-insensitive request header. Default: x-idempotency-key. */
|
|
25
14
|
headerName?: string;
|
|
26
|
-
/**
|
|
27
|
-
* Predicate that decides whether a request should be skipped.
|
|
28
|
-
* Defaults to skipping non-mutating requests (GET, HEAD, OPTIONS).
|
|
29
|
-
*/
|
|
15
|
+
/** Default: skip GET, HEAD, OPTIONS and other non-mutating methods. */
|
|
30
16
|
skip?: (ctx: RequestContext) => boolean;
|
|
17
|
+
/** Maximum retained keys, including pending requests. Default: 1000. */
|
|
18
|
+
maxEntries?: number;
|
|
19
|
+
/** Maximum response body retained per key. Default: 65,536 bytes. */
|
|
20
|
+
maxResponseBytes?: number;
|
|
31
21
|
}
|
|
32
22
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* GET, HEAD, and OPTIONS requests pass through without checking.
|
|
41
|
-
*
|
|
42
|
-
* @param options - Configuration.
|
|
43
|
-
* @returns A server-side {@link Middleware}.
|
|
44
|
-
*
|
|
45
|
-
* @example
|
|
46
|
-
* ```ts
|
|
47
|
-
* server.handle(CreateTodo, createHandler, {
|
|
48
|
-
* middlewares: [idempotency({ ttl: 86_400_000 })]
|
|
49
|
-
* });
|
|
50
|
-
* ```
|
|
23
|
+
* Replay completed mutations and coalesce concurrent requests within one
|
|
24
|
+
* middleware instance. Keys include explicit scope, method and full request URL.
|
|
25
|
+
* Reusing a key means retrying the same input; bodies are not fingerprinted.
|
|
26
|
+
* This is not durable exactly-once execution: restarts, expiry and thrown
|
|
27
|
+
* failures may permit another execution. Use database deduplication for that.
|
|
28
|
+
* Oversized/incomplete responses retain a non-replayable reservation (409).
|
|
29
|
+
* Capacity exhaustion returns 503 without executing the operation.
|
|
51
30
|
*/
|
|
52
|
-
export declare function idempotency(options
|
|
31
|
+
export declare function idempotency(options: ServerIdempotencyOptions): Middleware;
|
|
@@ -22,6 +22,10 @@ export interface ServerCacheOptions {
|
|
|
22
22
|
* Per-tag TTL overrides: `{ [tagName]: ttlMs }`.
|
|
23
23
|
*/
|
|
24
24
|
ttlByTag?: Record<string, number>;
|
|
25
|
+
/** Maximum retained cache keys. Default: 1000 (oldest keys are evicted). */
|
|
26
|
+
maxEntries?: number;
|
|
27
|
+
/** Maximum retained response body size. Default: 65,536 bytes. */
|
|
28
|
+
maxResponseBytes?: number;
|
|
25
29
|
}
|
|
26
30
|
/**
|
|
27
31
|
* Server-side cache response middleware.
|
|
@@ -36,6 +40,9 @@ export interface ServerCacheOptions {
|
|
|
36
40
|
* - **Mutation (POST/PUT/PATCH/DELETE)**: Lets the handler run, then
|
|
37
41
|
* invalidates all cache entries whose tag names start with any of the
|
|
38
42
|
* endpoint's cache tag names. Older in-flight reads cannot refill them.
|
|
43
|
+
* - By default, retain at most 1000 keys and bodies up to 65,536 bytes. Private/no-store and
|
|
44
|
+
* Set-Cookie responses are not cached. Install after authorization and encode
|
|
45
|
+
* every identity/tenant/representation dimension in tag properties.
|
|
39
46
|
*
|
|
40
47
|
* @param options - Cache configuration.
|
|
41
48
|
* @returns A server-side {@link Middleware}.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { OutgoingHttpHeaders, ServerResponse } from 'node:http';
|
|
2
|
+
/** @internal A complete, bounded response suitable for replay. */
|
|
3
|
+
export interface ResponseSnapshot {
|
|
4
|
+
status: number;
|
|
5
|
+
headers: OutgoingHttpHeaders;
|
|
6
|
+
body: Buffer;
|
|
7
|
+
}
|
|
8
|
+
/** @internal Capture all write/end overloads without changing their behavior. */
|
|
9
|
+
export declare function captureResponse(response: ServerResponse, next: () => Promise<void>, maxBytes: number): Promise<ResponseSnapshot | undefined>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { IncomingMessage } from 'node:http';
|
|
2
|
+
import type { FilePart, RejectedFile } from './types.js';
|
|
3
|
+
import type { UploadConfiguration } from './upload.js';
|
|
4
|
+
/** @internal Buffered multipart parsing with a bound on the entire wire body. */
|
|
5
|
+
export declare function parseMultipart(req: IncomingMessage, options: UploadConfiguration, maxBodySize: number): Promise<{
|
|
6
|
+
fields: Record<string, string>;
|
|
7
|
+
files: Record<string, FilePart | FilePart[]>;
|
|
8
|
+
rejectedFiles: RejectedFile[];
|
|
9
|
+
}>;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { EndpointMetadata } from './Endpoint.js';
|
|
2
|
+
import type { RuntimeEndpointOptions } from './EndpointOptions.js';
|
|
2
3
|
import type { RequestContext } from './RequestContext.js';
|
|
3
4
|
import type { SubscriptionMetadata } from './Subscription.js';
|
|
4
5
|
/**
|
|
5
6
|
* A registered endpoint pairing its metadata (method, path, schemas) with
|
|
6
7
|
* the handler function and any per-endpoint middleware.
|
|
7
8
|
*/
|
|
8
|
-
export interface EndpointRegistration {
|
|
9
|
+
export interface EndpointRegistration extends RuntimeEndpointOptions {
|
|
9
10
|
readonly endpoint: EndpointMetadata;
|
|
10
11
|
readonly handler: (...args: any[]) => any;
|
|
11
12
|
readonly middlewares?: readonly Middleware[];
|
|
@@ -100,6 +101,8 @@ export interface FilePart {
|
|
|
100
101
|
* Describes a file that was rejected during multipart parsing.
|
|
101
102
|
*/
|
|
102
103
|
export interface RejectedFile {
|
|
104
|
+
/** Multipart field name, when available. */
|
|
105
|
+
readonly fieldName?: string;
|
|
103
106
|
/** Original filename as provided by the client. */
|
|
104
107
|
readonly filename: string;
|
|
105
108
|
/** MIME type of the file (e.g. `'application/xlsx'`). */
|
|
@@ -112,6 +115,14 @@ export interface RejectedFile {
|
|
|
112
115
|
* `EndpointBuilder.upload()`.
|
|
113
116
|
*/
|
|
114
117
|
export interface UploadOptions {
|
|
118
|
+
/** Maximum bytes per text field. Default: 1 MiB. */
|
|
119
|
+
maxFieldSize?: number;
|
|
120
|
+
/** Maximum text fields per request. Default: 100. */
|
|
121
|
+
maxFieldCount?: number;
|
|
122
|
+
/** Maximum UTF-8 bytes per field name. Default: 100. */
|
|
123
|
+
maxFieldNameSize?: number;
|
|
124
|
+
/** Maximum parts. Default: maxFileCount + maxFieldCount. */
|
|
125
|
+
maxPartCount?: number;
|
|
115
126
|
/**
|
|
116
127
|
* Maximum allowed file size per uploaded file in bytes.
|
|
117
128
|
* @default 10_485_760 (10 MB)
|
package/dist/upload.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type InferType, type ObjectSchemaBuilder, type SchemaBuilder } from '@cleverbrush/schema';
|
|
2
|
+
import type { FilePart, UploadOptions } from './types.js';
|
|
3
|
+
/** A buffered file in an upload contract. Safe to import in browser contracts. */
|
|
4
|
+
export declare function file(): import("@cleverbrush/schema").AnySchemaBuilder<true, false, FilePart, false, {}, FilePart>;
|
|
5
|
+
/** Flat object of file() and array(file()) fields. */
|
|
6
|
+
export type UploadSchema = ObjectSchemaBuilder<any, any, any, any, any, any, any>;
|
|
7
|
+
/** Upload metadata shared by the server, typed client, and OpenAPI generator. */
|
|
8
|
+
export interface UploadConfiguration extends UploadOptions {
|
|
9
|
+
readonly schema?: UploadSchema;
|
|
10
|
+
}
|
|
11
|
+
/** The upload state carried through immutable endpoint chaining. */
|
|
12
|
+
export type UploadContract = boolean | UploadSchema;
|
|
13
|
+
/** Files received by a handler, inferred from the upload schema. */
|
|
14
|
+
export type UploadFiles<T extends UploadContract> = T extends UploadSchema ? InferType<T> : Record<string, FilePart>;
|
|
15
|
+
/** @internal Validate the supported multipart shape in either chaining order. */
|
|
16
|
+
export declare function validateUploadConfiguration(upload: UploadConfiguration | null, body: SchemaBuilder<any, any, any, any, any> | null): void;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
/** HTTP lifecycle fields required to cancel request-owned work. */
|
|
3
|
+
export interface RequestSignalContext {
|
|
4
|
+
readonly request: Pick<IncomingMessage, 'aborted' | 'once' | 'off'>;
|
|
5
|
+
readonly response: Pick<ServerResponse, 'destroyed' | 'writableFinished' | 'once' | 'off'>;
|
|
6
|
+
}
|
|
7
|
+
/** Application-owned deadline and optional cancellation for request work. */
|
|
8
|
+
export interface RequestSignalOptions {
|
|
9
|
+
/** Positive integer deadline in milliseconds, at most 2,147,483,647. */
|
|
10
|
+
timeoutMs: number;
|
|
11
|
+
/** Additional cancellation, such as application shutdown. */
|
|
12
|
+
signal?: AbortSignal;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Run cooperative work with cancellation on disconnect, deadline or caller abort.
|
|
16
|
+
*
|
|
17
|
+
* The visitor must observe its signal; this helper does not forcibly interrupt
|
|
18
|
+
* arbitrary promises. A normal response finish does not cancel the work. The
|
|
19
|
+
* deadline timer and all listeners are removed when work settles, including on
|
|
20
|
+
* failure. Already-aborted inputs reject without invoking the visitor.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* await withRequestSignal(context, signal => loadReport(signal), {
|
|
25
|
+
* timeoutMs: 30_000
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function withRequestSignal<T>(context: RequestSignalContext, work: (signal: AbortSignal) => T | PromiseLike<T>, options: RequestSignalOptions): Promise<T>;
|
package/package.json
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
"email": "andrew_zol@cleverbrush.com"
|
|
6
6
|
},
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@cleverbrush/auth": "^
|
|
9
|
-
"@cleverbrush/di": "^
|
|
10
|
-
"@cleverbrush/schema": "^
|
|
11
|
-
"@fastify/busboy": "^3.2.
|
|
12
|
-
"ws": "^8.
|
|
8
|
+
"@cleverbrush/auth": "^5.1.0",
|
|
9
|
+
"@cleverbrush/di": "^5.1.0",
|
|
10
|
+
"@cleverbrush/schema": "^5.1.0",
|
|
11
|
+
"@fastify/busboy": "^3.2.2",
|
|
12
|
+
"ws": "^8.22.0"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
15
|
"@types/busboy": "1.5.4",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"typescript",
|
|
30
30
|
"cleverbrush"
|
|
31
31
|
],
|
|
32
|
-
"license": "BSD
|
|
32
|
+
"license": "BSD-3-Clause",
|
|
33
33
|
"main": "./dist/index.js",
|
|
34
34
|
"exports": {
|
|
35
35
|
".": {
|
|
@@ -43,6 +43,9 @@
|
|
|
43
43
|
},
|
|
44
44
|
"sideEffects": false,
|
|
45
45
|
"name": "@cleverbrush/server",
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=24"
|
|
48
|
+
},
|
|
46
49
|
"readme": "https://github.com/cleverbrush/framework/tree/master/libs/server#readme",
|
|
47
50
|
"repository": {
|
|
48
51
|
"type": "git",
|
|
@@ -55,5 +58,5 @@
|
|
|
55
58
|
},
|
|
56
59
|
"type": "module",
|
|
57
60
|
"types": "./dist/index.d.ts",
|
|
58
|
-
"version": "
|
|
61
|
+
"version": "5.1.0"
|
|
59
62
|
}
|
package/dist/chunk-L2OPVEOF.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
function f(n,e){if(n===null)return["null"];switch(typeof n){case"undefined":return["undefined"];case"string":case"boolean":return[typeof n,n];case"number":return["number",Object.is(n,-0)?"-0":String(n)];case"bigint":return["bigint",String(n)];case"object":{if(e.has(n))throw new TypeError("Cache tag values must not contain cycles.");if(n instanceof Date){if(!Number.isFinite(n.getTime()))throw new TypeError("Cache tag dates must be valid.");return["date",n.toISOString()]}let t=Object.getPrototypeOf(n);if(!Array.isArray(n)&&t!==Object.prototype&&t!==null)throw new TypeError("Unsupported cache tag object.");if(Object.getOwnPropertySymbols(n).length>0)throw new TypeError("Cache tag values cannot have symbol keys.");e.add(n);try{if(Array.isArray(n)){if(Object.keys(n).some(a=>!/^(0|[1-9]\d*)$/.test(a)||Number(a)>=n.length))throw new TypeError("Cache tag arrays cannot have named properties.");return["array",Array.from({length:n.length},(a,s)=>{let i=Object.getOwnPropertyDescriptor(n,s);if(i&&!("value"in i))throw new TypeError("Cache tag values cannot contain getters.");return f(i?.value,e)})]}return["object",Object.keys(n).sort().map(a=>{let s=Object.getOwnPropertyDescriptor(n,a);if(!("value"in s))throw new TypeError("Cache tag values cannot contain getters.");return[a,f(s.value,e)]})]}finally{e.delete(n)}}default:throw new TypeError(`Unsupported cache tag value: ${typeof n}.`)}}function B(n,e){let t=[];for(let a of Object.keys(n.properties).sort()){let s=n.properties[a].getValue(e);s.success&&s.value!==void 0&&t.push([a,f(s.value,new Set)])}return`ct2:${JSON.stringify([n.name,t])}`}import{object as b,SYMBOL_HAS_PROPERTIES as x,SYMBOL_SCHEMA_PROPERTY_DESCRIPTOR as R}from"@cleverbrush/schema";function E(n){let e={};if(n.paramsSchema){let a=n.paramsSchema;typeof a.introspect=="function"&&a.introspect().objectSchema?e.params=a.introspect().objectSchema:a[x]===!0&&(e.params=a)}if(n.bodySchema){let a=n.bodySchema;(a[x]===!0||typeof a.introspect=="function")&&(e.body=a)}n.querySchema&&(e.query=n.querySchema),n.headerSchema&&(e.headers=n.headerSchema);let t=b(e);return b.getPropertiesFor(t)}function z(n){return n==null||typeof n!="object"?!1:typeof n[R]=="object"&&n[R]!==null}function O(n,e){let t={};for(let[a,s]of Object.entries(e)){if(!z(s))throw new Error(`Cache tag "${n}": property "${a}" is not a valid PropertyDescriptor. Make sure you select a leaf property from the tree (e.g. p.query.id, not p.query).`);let i=s[R];t[a]={getValue:o=>i.getValue(o)}}return{name:n,properties:t}}var P=Symbol.for("cleverbrush.tracked");function G(n,e){return{[P]:!0,id:n,data:e}}function ee(n){return n!==null&&typeof n=="object"&&P in n&&n[P]===!0}var u=class n{#s;#a;#n;#i;#r;#o;#l;#t;#d;#h;#c;#u;#p;#y;constructor(e,t="/",a=null,s=null,i=null,o=null,y=null,d=null,l=null,h=null,c=[],m=null,g=!1,S=null){this.#s=e,this.#a=t,this.#n=a,this.#i=s,this.#r=i,this.#o=o,this.#l=y,this.#t=d,this.#d=l,this.#h=h,this.#c=c,this.#u=m,this.#p=g,this.#y=S}#e(e){return new n(e.basePath??this.#s,e.pathTemplate??this.#a,e.incomingSchema!==void 0?e.incomingSchema:this.#n,e.outgoingSchema!==void 0?e.outgoingSchema:this.#i,e.querySchema!==void 0?e.querySchema:this.#r,e.headerSchema!==void 0?e.headerSchema:this.#o,e.serviceSchemas!==void 0?e.serviceSchemas:this.#l,e.authRoles!==void 0?e.authRoles:this.#t,e.summary!==void 0?e.summary:this.#d,e.description!==void 0?e.description:this.#h,e.tags??this.#c,e.operationId!==void 0?e.operationId:this.#u,e.deprecated??this.#p,e.externalDocs!==void 0?e.externalDocs:this.#y)}incoming(e){return this.#e({incomingSchema:e})}outgoing(e){return this.#e({outgoingSchema:e})}query(e){return this.#e({querySchema:e})}headers(e){return this.#e({headerSchema:e})}inject(e){return this.#e({serviceSchemas:e})}authorize(...e){let t;e.length>0&&typeof e[0]=="object"&&e[0]!==null&&"introspect"in e[0]?t=e.slice(1):t=e;let a=this.#t?[...this.#t,...t]:t;return this.#e({authRoles:a})}public(){return this.#e({authRoles:null})}summary(e){return this.#e({summary:e})}description(e){return this.#e({description:e})}tags(...e){return this.#e({tags:e})}operationId(e){return this.#e({operationId:e})}deprecated(){return this.#e({deprecated:!0})}externalDocs(e,t){return this.#e({externalDocs:{url:e,description:t}})}introspect(){return{protocol:"subscription",basePath:this.#s,pathTemplate:this.#a,incomingSchema:this.#n,outgoingSchema:this.#i,querySchema:this.#r,headerSchema:this.#o,serviceSchemas:this.#l,authRoles:this.#t,summary:this.#d,description:this.#h,tags:this.#c,operationId:this.#u,deprecated:this.#p,externalDocs:this.#y}}};function k(n,e){return new u(n,e??"/")}function w(n){return n instanceof u}function se(n,e){let t=[],a=[];for(let s of Object.keys(n)){let i=n[s],o=e[s];for(let y of Object.keys(i)){let d=i[y],l=o[y],h=typeof l=="function"?l:l.handler,c=typeof l=="function"?void 0:l.middlewares;w(d)?a.push({endpoint:d,handler:h,middlewares:c}):t.push({endpoint:d,handler:h,middlewares:c})}}return{_entries:t,_subscriptions:a}}var T=class n{#s;#a;#n;#i;#r;#o;#l;#t;#d;#h;#c;#u;#p;#y;#e;#m;#g;#S;#f;#R;#P;#B;#b;#x;#T;constructor(e,t,a,s,i,o,y=null,d=null,l=null,h=null,c=[],m=null,g=!1,S=null,C=null,A=null,v=null,I=null,D=null,Q=null,K=null,M=null,U=null,F=null,q=[]){this.#s=e,this.#a=t,this.#n=a,this.#i=s,this.#r=i,this.#o=o,this.#l=y,this.#t=d,this.#d=l,this.#h=h,this.#c=c,this.#u=m,this.#p=g,this.#y=S,this.#e=C,this.#m=A,this.#g=v,this.#S=I,this.#f=D,this.#R=Q,this.#P=K,this.#B=M,this.#b=U,this.#x=F,this.#T=q}body(e){return new n(this.#s,this.#a,this.#n,e,this.#r,this.#o,this.#l,this.#t,this.#d,this.#h,this.#c,this.#u,this.#p,this.#y,this.#e,this.#m,this.#g,this.#S,this.#f,this.#R,this.#P,this.#B,this.#b,this.#x,this.#T)}query(e){return new n(this.#s,this.#a,this.#n,this.#i,e,this.#o,this.#l,this.#t,this.#d,this.#h,this.#c,this.#u,this.#p,this.#y,this.#e,this.#m,this.#g,this.#S,this.#f,this.#R,this.#P,this.#B,this.#b,this.#x,this.#T)}headers(e){return new n(this.#s,this.#a,this.#n,this.#i,this.#r,e,this.#l,this.#t,this.#d,this.#h,this.#c,this.#u,this.#p,this.#y,this.#e,this.#m,this.#g,this.#S,this.#f,this.#R,this.#P,this.#B,this.#b,this.#x,this.#T)}inject(e){return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,e,this.#t,this.#d,this.#h,this.#c,this.#u,this.#p,this.#y,this.#e,this.#m,this.#g,this.#S,this.#f,this.#R,this.#P,this.#B,this.#b,this.#x,this.#T)}authorize(...e){let t;e.length>0&&typeof e[0]=="object"&&e[0]!==null&&"introspect"in e[0]?t=e.slice(1):t=e;let a=this.#t?[...this.#t,...t]:t;return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,this.#l,a,this.#d,this.#h,this.#c,this.#u,this.#p,this.#y,this.#e,this.#m,this.#g,this.#S,this.#f,this.#R,this.#P,this.#B,this.#b,this.#x,this.#T)}public(){return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,this.#l,null,this.#d,this.#h,this.#c,this.#u,this.#p,this.#y,this.#e,this.#m,this.#g,this.#S,this.#f,this.#R,this.#P,this.#B,this.#b,this.#x,this.#T)}returns(e){let t=e!=null&&typeof e=="object"&&"introspect"in e?e:null;return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,this.#l,this.#t,this.#d,this.#h,this.#c,this.#u,this.#p,t??this.#y,this.#e,this.#m,this.#g,this.#S,this.#f,this.#R,this.#P,this.#B,this.#b,this.#x,this.#T)}responses(e){return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,this.#l,this.#t,this.#d,this.#h,this.#c,this.#u,this.#p,this.#y,e,this.#m,this.#g,this.#S,this.#f,this.#R,this.#P,this.#B,this.#b,this.#x,this.#T)}summary(e){return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,this.#l,this.#t,e,this.#h,this.#c,this.#u,this.#p,this.#y,this.#e,this.#m,this.#g,this.#S,this.#f,this.#R,this.#P,this.#B,this.#b,this.#x,this.#T)}description(e){return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,this.#l,this.#t,this.#d,e,this.#c,this.#u,this.#p,this.#y,this.#e,this.#m,this.#g,this.#S,this.#f,this.#R,this.#P,this.#B,this.#b,this.#x,this.#T)}tags(...e){return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,this.#l,this.#t,this.#d,this.#h,e,this.#u,this.#p,this.#y,this.#e,this.#m,this.#g,this.#S,this.#f,this.#R,this.#P,this.#B,this.#b,this.#x,this.#T)}operationId(e){return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,this.#l,this.#t,this.#d,this.#h,this.#c,e,this.#p,this.#y,this.#e,this.#m,this.#g,this.#S,this.#f,this.#R,this.#P,this.#B,this.#b,this.#x,this.#T)}deprecated(){return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,this.#l,this.#t,this.#d,this.#h,this.#c,this.#u,!0,this.#y,this.#e,this.#m,this.#g,this.#S,this.#f,this.#R,this.#P,this.#B,this.#b,this.#x,this.#T)}example(e){return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,this.#l,this.#t,this.#d,this.#h,this.#c,this.#u,this.#p,this.#y,this.#e,e,this.#g,this.#S,this.#f,this.#R,this.#P,this.#B,this.#b,this.#x,this.#T)}examples(e){return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,this.#l,this.#t,this.#d,this.#h,this.#c,this.#u,this.#p,this.#y,this.#e,this.#m,e,this.#S,this.#f,this.#R,this.#P,this.#B,this.#b,this.#x,this.#T)}producesFile(e,t){return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,this.#l,this.#t,this.#d,this.#h,this.#c,this.#u,this.#p,this.#y,this.#e,this.#m,this.#g,{contentType:e,description:t},this.#f,this.#R,this.#P,this.#B,this.#b,this.#x,this.#T)}upload(e){return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,this.#l,this.#t,this.#d,this.#h,this.#c,this.#u,this.#p,this.#y,this.#e,this.#m,this.#g,this.#S,this.#f,this.#R,this.#P,this.#B,this.#b,{maxFileSize:e?.maxFileSize??10*1024*1024,allowedMimeTypes:e?.allowedMimeTypes,maxFileCount:e?.maxFileCount??10},this.#T)}get path(){let e=this.#a,t=this.#n,a;if(typeof t=="string")a=t;else{let{literals:s,segments:i}=t.introspect().templateDefinition,o="";for(let y=0;y<i.length;y++)o+=s[y]+`:${i[y].path}`;o+=s[i.length]??"",a=o}return a==="/"?e||"/":e+a}introspect(){return{method:this.#s,basePath:this.#a,pathTemplate:this.#n,bodySchema:this.#i,querySchema:this.#r,headerSchema:this.#o,serviceSchemas:this.#l,authRoles:this.#t,summary:this.#d,description:this.#h,tags:this.#c,operationId:this.#u,deprecated:this.#p,responseSchema:this.#y,responsesSchemas:this.#e,example:this.#m,examples:this.#g,producesFile:this.#S,produces:this.#f,responseHeaderSchema:this.#R,externalDocs:this.#P,links:this.#B,callbacks:this.#b,fileUpload:this.#x,cacheTags:this.#T}}produces(e){return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,this.#l,this.#t,this.#d,this.#h,this.#c,this.#u,this.#p,this.#y,this.#e,this.#m,this.#g,this.#S,e,this.#R,this.#P,this.#B,this.#b,this.#x,this.#T)}responseHeaders(e){return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,this.#l,this.#t,this.#d,this.#h,this.#c,this.#u,this.#p,this.#y,this.#e,this.#m,this.#g,this.#S,this.#f,e,this.#P,this.#B,this.#b,this.#x,this.#T)}externalDocs(e,t){return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,this.#l,this.#t,this.#d,this.#h,this.#c,this.#u,this.#p,this.#y,this.#e,this.#m,this.#g,this.#S,this.#f,this.#R,{url:e,description:t},this.#B,this.#b,this.#x,this.#T)}links(e){return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,this.#l,this.#t,this.#d,this.#h,this.#c,this.#u,this.#p,this.#y,this.#e,this.#m,this.#g,this.#S,this.#f,this.#R,this.#P,e,this.#b,this.#x,this.#T)}callbacks(e){return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,this.#l,this.#t,this.#d,this.#h,this.#c,this.#u,this.#p,this.#y,this.#e,this.#m,this.#g,this.#S,this.#f,this.#R,this.#P,this.#B,e,this.#x,this.#T)}cacheTag(e,t){return this.clearsCacheTag(e,t)}clearsCacheTag(e,t){if(!t)return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,this.#l,this.#t,this.#d,this.#h,this.#c,this.#u,this.#p,this.#y,this.#e,this.#m,this.#g,this.#S,this.#f,this.#R,this.#P,this.#B,this.#b,this.#x,[...this.#T,{name:e,properties:{}}]);let a=Y(this.#n),s=E({paramsSchema:a,bodySchema:this.#i,querySchema:this.#r,headerSchema:this.#o}),i=t(s);if(typeof i!="object"||i===null)throw new Error(`Cache tag "${e}": selector must return an object with property descriptors (e.g. { id: p.query.id }).`);let o=O(e,i);return new n(this.#s,this.#a,this.#n,this.#i,this.#r,this.#o,this.#l,this.#t,this.#d,this.#h,this.#c,this.#u,this.#p,this.#y,this.#e,this.#m,this.#g,this.#S,this.#f,this.#R,this.#P,this.#B,this.#b,this.#x,[...this.#T,o])}};function r(n,e,t,a,s){return new T(n,e,t??"/",null,null,null,null,a??null,s?.summary??null,s?.description??null,s?.tags??[],s?.operationId??null,s?.deprecated??!1,null,null,null,null,null,null,null)}function p(n,e){return{get:t=>r("GET",n,t,e),post:t=>r("POST",n,t,e),put:t=>r("PUT",n,t,e),patch:t=>r("PATCH",n,t,e),delete:t=>r("DELETE",n,t,e),head:t=>r("HEAD",n,t,e),options:t=>r("OPTIONS",n,t,e),public:()=>p(n,null)}}function L(n){return{...p(n,null),authorize(...e){let t;return e.length>0&&typeof e[0]=="object"&&e[0]!==null&&"introspect"in e[0]?t=e.slice(1):t=e,p(n,t)},public(){return p(n,null)}}}function Y(n){if(n&&typeof n!="string"&&typeof n.introspect=="function"){let e=n.introspect();if(e.objectSchema)return e.objectSchema}return null}function N(n){return H}var H={get:(n,e)=>r("GET",n,e),post:(n,e)=>r("POST",n,e),put:(n,e)=>r("PUT",n,e),patch:(n,e)=>r("PATCH",n,e),delete:(n,e)=>r("DELETE",n,e),head:(n,e)=>r("HEAD",n,e),options:(n,e)=>r("OPTIONS",n,e),resource:L,subscription:(n,e)=>k(n,e)};import{object as $,parseString as V}from"@cleverbrush/schema";function j(n){let e=$(n);return((t,...a)=>V(e,s=>s(t,...a)))}function J(n,...e){return n!=null&&Array.isArray(n.raw)?j({})(n):j(n??{})}function ye(n){for(let e of Object.values(n))Object.freeze(e);return Object.freeze(n)}function le(n,e){let t={};for(let a of Object.keys(n))t[a]={...n[a]};for(let a of Object.keys(e))Object.hasOwn(t,a)?t[a]={...t[a],...e[a]}:t[a]={...e[a]};for(let a of Object.values(t))Object.freeze(a);return Object.freeze(t)}function de(n,...e){let t={};for(let a of e)t[a]=n[a],Object.freeze(t[a]);return Object.freeze(t)}function he(n,...e){let t=new Set(e),a={};for(let s of Object.keys(n))t.has(s)||(a[s]=n[s],Object.freeze(a[s]));return Object.freeze(a)}export{B as a,E as b,O as c,G as d,ee as e,u as f,se as g,T as h,N as i,H as j,J as k,ye as l,le as m,de as n,he as o};
|
|
2
|
-
//# sourceMappingURL=chunk-L2OPVEOF.js.map
|