@spfn/core 0.3.0-beta.2 → 0.3.0-beta.20
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 +331 -16
- package/dist/app-config/index.d.ts +134 -0
- package/dist/app-config/index.js +58 -0
- package/dist/app-config/index.js.map +1 -0
- package/dist/authz/index.js +1 -381
- package/dist/authz/index.js.map +1 -1
- package/dist/{boss-D16fO2oG.d.ts → boss-BiDCbbAQ.d.ts} +60 -7
- package/dist/codegen/index.d.ts +93 -15
- package/dist/codegen/index.js +626 -165
- package/dist/codegen/index.js.map +1 -1
- package/dist/config/index.d.ts +0 -63
- package/dist/config/index.js +15 -15
- package/dist/config/index.js.map +1 -1
- package/dist/contract/index.d.ts +40 -17
- package/dist/contract/index.js +147 -23
- package/dist/contract/index.js.map +1 -1
- package/dist/db/index.d.ts +201 -34
- package/dist/db/index.js +294 -158
- package/dist/db/index.js.map +1 -1
- package/dist/{define-middleware-DfDP39Nq.d.ts → define-middleware-CVKgqo8S.d.ts} +1 -1
- package/dist/env/index.d.ts +6 -442
- package/dist/env/index.js +13 -16
- package/dist/env/index.js.map +1 -1
- package/dist/env/loader.js +24 -1
- package/dist/env/loader.js.map +1 -1
- package/dist/error-BcdBVfRA.d.ts +150 -0
- package/dist/errors/index.js +1 -381
- package/dist/errors/index.js.map +1 -1
- package/dist/event/index.d.ts +5 -5
- package/dist/event/index.js +32 -1
- package/dist/event/index.js.map +1 -1
- package/dist/event/sse/client.d.ts +18 -4
- package/dist/event/sse/client.js +38 -2
- package/dist/event/sse/client.js.map +1 -1
- package/dist/event/sse/index.d.ts +5 -4
- package/dist/event/ws/client.d.ts +3 -2
- package/dist/event/ws/index.d.ts +4 -3
- package/dist/job/index.d.ts +48 -3
- package/dist/job/index.js +131 -52
- package/dist/job/index.js.map +1 -1
- package/dist/logger/index.js +0 -12
- package/dist/logger/index.js.map +1 -1
- package/dist/middleware/index.d.ts +6 -2
- package/dist/middleware/index.js +7 -388
- package/dist/middleware/index.js.map +1 -1
- package/dist/nextjs/index.d.ts +88 -8
- package/dist/nextjs/index.js +138 -62
- package/dist/nextjs/index.js.map +1 -1
- package/dist/nextjs/server.d.ts +45 -7
- package/dist/nextjs/server.js +14 -0
- package/dist/nextjs/server.js.map +1 -1
- package/dist/ops/index.d.ts +59 -43
- package/dist/ops/index.js +543 -97
- package/dist/ops/index.js.map +1 -1
- package/dist/registry-C2KQCh0m.d.ts +473 -0
- package/dist/route/index.d.ts +5 -3
- package/dist/route/index.js +48 -28
- package/dist/route/index.js.map +1 -1
- package/dist/{router-Qbssr11H.d.ts → route-builder-BHKgGkwI.d.ts} +3 -126
- package/dist/{token-manager-BT5EnUAR.d.ts → router-CysBmgv3.d.ts} +81 -127
- package/dist/router-DaDrprJd.d.ts +172 -0
- package/dist/server/index.d.ts +185 -14
- package/dist/server/index.js +834 -78
- package/dist/server/index.js.map +1 -1
- package/dist/surface/index.d.ts +109 -0
- package/dist/surface/index.js +908 -0
- package/dist/surface/index.js.map +1 -0
- package/dist/token-manager-Ckjt2-qq.d.ts +122 -0
- package/dist/{types-ZQODsBft.d.ts → types-B8zAxFsE.d.ts} +2 -1
- package/dist/types-CxhPH4s_.d.ts +375 -0
- package/dist/{types-D1c57Ko-.d.ts → types-D52SokSM.d.ts} +43 -4
- package/dist/{types-2AbaW4Ie.d.ts → types-W4u_S0lF.d.ts} +4 -3
- package/docs/file-upload.md +195 -333
- package/package.json +20 -9
- package/src/cache/README.md +330 -0
- package/src/codegen/README.md +634 -0
- package/src/config/README.md +333 -0
- package/src/contract/README.md +440 -0
- package/src/db/README.md +589 -0
- package/src/db/manager/README.md +500 -0
- package/src/db/schema/README.md +354 -0
- package/src/db/transaction/README.md +822 -0
- package/src/env/README.md +787 -0
- package/src/errors/README.md +429 -0
- package/src/event/README.md +789 -0
- package/src/job/README.md +613 -0
- package/src/logger/README.md +321 -0
- package/src/middleware/README.md +634 -0
- package/src/nextjs/README.md +688 -0
- package/src/route/README.md +763 -0
- package/src/security/README.md +100 -0
- package/src/server/README.md +704 -0
- package/dist/types-9oszaJqp.d.ts +0 -250
|
@@ -25,6 +25,21 @@ type EventHandler<TPayload> = (payload: TPayload) => void | Promise<void>;
|
|
|
25
25
|
* Job queue sender function type (used by job module)
|
|
26
26
|
*/
|
|
27
27
|
type JobQueueSender = (queueName: string, payload: unknown) => Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* What a contracted event promises to clients compiled separately from the
|
|
30
|
+
* server, written into `contracts/current.json` by `@spfn/core:contract`.
|
|
31
|
+
*
|
|
32
|
+
* The same version markers a route's `.contract()` carries; the payload shape
|
|
33
|
+
* is the event's own schema, so it is not repeated here.
|
|
34
|
+
*/
|
|
35
|
+
interface EventContract {
|
|
36
|
+
/** Contract version the event first appeared in. */
|
|
37
|
+
since: string;
|
|
38
|
+
/** Contract version the event was announced for removal in. */
|
|
39
|
+
deprecatedIn?: string;
|
|
40
|
+
/** Contract version the event was removed in. */
|
|
41
|
+
removedIn?: string;
|
|
42
|
+
}
|
|
28
43
|
/**
|
|
29
44
|
* Event definition interface
|
|
30
45
|
*/
|
|
@@ -37,6 +52,22 @@ interface EventDef<TPayload = void> {
|
|
|
37
52
|
* TypeBox payload schema (optional)
|
|
38
53
|
*/
|
|
39
54
|
readonly schema?: TSchema;
|
|
55
|
+
/**
|
|
56
|
+
* The contract declared with `.contract()`, absent when the event is not
|
|
57
|
+
* part of the published contract.
|
|
58
|
+
*
|
|
59
|
+
* Named with an underscore because `.contract()` holds the plain name, as
|
|
60
|
+
* a router's `_contractVersion` sits beside `.contractVersion()`.
|
|
61
|
+
*/
|
|
62
|
+
readonly _contract?: EventContract;
|
|
63
|
+
/**
|
|
64
|
+
* Publish this event in `contracts/current.json`.
|
|
65
|
+
*
|
|
66
|
+
* Sets the contract on this definition and returns it. An event is defined
|
|
67
|
+
* once and shared, so a second call throws instead of one of the two
|
|
68
|
+
* declarations silently winning.
|
|
69
|
+
*/
|
|
70
|
+
contract: (contract: EventContract) => EventDef<TPayload>;
|
|
40
71
|
/**
|
|
41
72
|
* Subscribe to this event (in-memory handler)
|
|
42
73
|
*/
|
|
@@ -104,9 +135,32 @@ type InferEventPayload$1<TEvent> = TEvent extends EventDef<infer TPayload> ? TPa
|
|
|
104
135
|
*/
|
|
105
136
|
|
|
106
137
|
/**
|
|
107
|
-
*
|
|
138
|
+
* How a client reaches the contracted events of a router.
|
|
139
|
+
*
|
|
140
|
+
* Declared on the router because it is the stream's promise, not one event's:
|
|
141
|
+
* `createServer` checks it against `.events()` at boot, so the document cannot
|
|
142
|
+
* describe a path or an auth mode the server does not serve.
|
|
108
143
|
*/
|
|
109
|
-
interface
|
|
144
|
+
interface EventRouterContract {
|
|
145
|
+
/**
|
|
146
|
+
* `'tokenExchange'` when `.events()` enables `auth` — the client first posts
|
|
147
|
+
* to the token path and opens the stream with `?token=`. `'none'` otherwise.
|
|
148
|
+
*/
|
|
149
|
+
auth: 'none' | 'tokenExchange';
|
|
150
|
+
/**
|
|
151
|
+
* The stream path `.events()` registers.
|
|
152
|
+
* @default '/events/stream'
|
|
153
|
+
*/
|
|
154
|
+
streamPath?: string;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* What every router of events carries — the SSE event router and the
|
|
158
|
+
* WebSocket router alike.
|
|
159
|
+
*
|
|
160
|
+
* The WebSocket router builds on this rather than on `EventRouterDef`, because
|
|
161
|
+
* only an SSE event router can be contracted.
|
|
162
|
+
*/
|
|
163
|
+
interface EventRouterBase<TEvents extends Record<string, EventDef<any>>> {
|
|
110
164
|
/**
|
|
111
165
|
* Event definitions
|
|
112
166
|
*/
|
|
@@ -122,21 +176,42 @@ interface EventRouterDef<TEvents extends Record<string, EventDef<any>>> {
|
|
|
122
176
|
[K in keyof TEvents]: TEvents[K]['_payload'];
|
|
123
177
|
};
|
|
124
178
|
}
|
|
179
|
+
/**
|
|
180
|
+
* Event Router Definition
|
|
181
|
+
*/
|
|
182
|
+
interface EventRouterDef<TEvents extends Record<string, EventDef<any>>> extends EventRouterBase<TEvents> {
|
|
183
|
+
/**
|
|
184
|
+
* The contract declared with `.contract()`, absent when the router declares
|
|
185
|
+
* none. Underscored for the same reason as `EventDef._contract`.
|
|
186
|
+
*/
|
|
187
|
+
readonly _contract?: EventRouterContract;
|
|
188
|
+
/**
|
|
189
|
+
* Declare how a client reaches this router's contracted events.
|
|
190
|
+
*
|
|
191
|
+
* Sets the contract on this router and returns it. A `streamPath` that does
|
|
192
|
+
* not start with `/` throws here, where the typo is.
|
|
193
|
+
*/
|
|
194
|
+
contract: (contract: EventRouterContract) => EventRouterDef<TEvents>;
|
|
195
|
+
}
|
|
125
196
|
/**
|
|
126
197
|
* Infer event names from EventRouter
|
|
127
198
|
*/
|
|
128
|
-
type InferEventNames<T> = T extends
|
|
199
|
+
type InferEventNames<T> = T extends EventRouterBase<infer E> ? keyof E & string : never;
|
|
129
200
|
/**
|
|
130
201
|
* Infer payload type for specific event
|
|
131
202
|
*/
|
|
132
|
-
type InferEventPayload<T extends
|
|
203
|
+
type InferEventPayload<T extends EventRouterBase<any>, K extends InferEventNames<T>> = T['_types'][K];
|
|
133
204
|
/**
|
|
134
205
|
* Infer all event payloads map
|
|
135
206
|
*/
|
|
136
|
-
type InferEventPayloads<T extends
|
|
207
|
+
type InferEventPayloads<T extends EventRouterBase<any>> = T['_types'];
|
|
137
208
|
/**
|
|
138
209
|
* Define an event router for SSE subscription
|
|
139
210
|
*
|
|
211
|
+
* `.contract({ auth })` on the router, together with `.contract({ since })` on
|
|
212
|
+
* its events, publishes those events in `contracts/current.json` — see the
|
|
213
|
+
* contract README.
|
|
214
|
+
*
|
|
140
215
|
* @example
|
|
141
216
|
* ```typescript
|
|
142
217
|
* export const eventRouter = defineEventRouter({
|
|
@@ -154,125 +229,4 @@ type InferEventPayloads<T extends EventRouterDef<any>> = T['_types'];
|
|
|
154
229
|
*/
|
|
155
230
|
declare function defineEventRouter<TEvents extends Record<string, EventDef<any>>>(events: TEvents): EventRouterDef<TEvents>;
|
|
156
231
|
|
|
157
|
-
|
|
158
|
-
* SSE Token Manager
|
|
159
|
-
*
|
|
160
|
-
* Auth-agnostic token issuance and verification for SSE connections.
|
|
161
|
-
* Issues one-time-use tokens with TTL for Token Exchange pattern.
|
|
162
|
-
*
|
|
163
|
-
* @example
|
|
164
|
-
* ```typescript
|
|
165
|
-
* const manager = new SSETokenManager({ ttl: 30000 });
|
|
166
|
-
*
|
|
167
|
-
* // Issue token for authenticated user
|
|
168
|
-
* const token = await manager.issue('user-123');
|
|
169
|
-
*
|
|
170
|
-
* // Verify and consume token (one-time use)
|
|
171
|
-
* const subject = await manager.verify(token); // 'user-123'
|
|
172
|
-
* const again = await manager.verify(token); // null (already consumed)
|
|
173
|
-
*
|
|
174
|
-
* // Cleanup on shutdown
|
|
175
|
-
* manager.destroy();
|
|
176
|
-
* ```
|
|
177
|
-
*/
|
|
178
|
-
/**
|
|
179
|
-
* Minimal cache client interface (compatible with ioredis Redis | Cluster)
|
|
180
|
-
*/
|
|
181
|
-
type CacheClient = {
|
|
182
|
-
set(key: string, value: string, ...args: any[]): Promise<any>;
|
|
183
|
-
getdel?(key: string): Promise<string | null>;
|
|
184
|
-
get(key: string): Promise<string | null>;
|
|
185
|
-
del(...keys: string[]): Promise<number>;
|
|
186
|
-
};
|
|
187
|
-
/**
|
|
188
|
-
* Stored SSE token data
|
|
189
|
-
*/
|
|
190
|
-
interface SSEToken {
|
|
191
|
-
subject: string;
|
|
192
|
-
expiresAt: number;
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Token storage interface
|
|
196
|
-
*
|
|
197
|
-
* Implement this for custom storage backends (e.g., Redis for multi-instance).
|
|
198
|
-
*/
|
|
199
|
-
interface SSETokenStore {
|
|
200
|
-
/** Store a token */
|
|
201
|
-
set(token: string, data: SSEToken): Promise<void>;
|
|
202
|
-
/** Get and delete a token (one-time use) */
|
|
203
|
-
consume(token: string): Promise<SSEToken | null>;
|
|
204
|
-
/** Remove expired tokens */
|
|
205
|
-
cleanup(): Promise<void>;
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* SSETokenManager configuration
|
|
209
|
-
*/
|
|
210
|
-
interface SSETokenManagerConfig {
|
|
211
|
-
/**
|
|
212
|
-
* Token time-to-live in milliseconds
|
|
213
|
-
* @default 30000
|
|
214
|
-
*/
|
|
215
|
-
ttl?: number;
|
|
216
|
-
/**
|
|
217
|
-
* Custom token store (default: in-memory Map)
|
|
218
|
-
*/
|
|
219
|
-
store?: SSETokenStore;
|
|
220
|
-
/**
|
|
221
|
-
* Cleanup interval in milliseconds
|
|
222
|
-
* @default 60000
|
|
223
|
-
*/
|
|
224
|
-
cleanupInterval?: number;
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Redis/Valkey-backed token store for multi-instance deployments.
|
|
228
|
-
*
|
|
229
|
-
* Uses SET EX for automatic TTL expiry and GETDEL for atomic one-time consumption.
|
|
230
|
-
* No cleanup needed — Redis handles expiration automatically.
|
|
231
|
-
*
|
|
232
|
-
* @example
|
|
233
|
-
* ```typescript
|
|
234
|
-
* import { getCache } from '@spfn/core/cache';
|
|
235
|
-
*
|
|
236
|
-
* const cache = getCache();
|
|
237
|
-
* if (cache) {
|
|
238
|
-
* const store = new CacheTokenStore(cache);
|
|
239
|
-
* const manager = new SSETokenManager({ store });
|
|
240
|
-
* }
|
|
241
|
-
* ```
|
|
242
|
-
*/
|
|
243
|
-
declare class CacheTokenStore implements SSETokenStore {
|
|
244
|
-
private cache;
|
|
245
|
-
private prefix;
|
|
246
|
-
constructor(cache: CacheClient);
|
|
247
|
-
set(token: string, data: SSEToken): Promise<void>;
|
|
248
|
-
consume(token: string): Promise<SSEToken | null>;
|
|
249
|
-
cleanup(): Promise<void>;
|
|
250
|
-
}
|
|
251
|
-
declare class SSETokenManager {
|
|
252
|
-
private store;
|
|
253
|
-
private ttl;
|
|
254
|
-
private cleanupTimer;
|
|
255
|
-
constructor(config?: SSETokenManagerConfig);
|
|
256
|
-
/**
|
|
257
|
-
* How long an issued token stays valid, in milliseconds.
|
|
258
|
-
*
|
|
259
|
-
* Exposed so a caller that has to report an expiry to its client computes the same
|
|
260
|
-
* number this manager stamps on the token, instead of assuming the default.
|
|
261
|
-
*/
|
|
262
|
-
get ttlMs(): number;
|
|
263
|
-
/**
|
|
264
|
-
* Issue a new one-time-use token for the given subject
|
|
265
|
-
*/
|
|
266
|
-
issue(subject: string): Promise<string>;
|
|
267
|
-
/**
|
|
268
|
-
* Verify and consume a token
|
|
269
|
-
* @returns subject string if valid, null if invalid/expired/already consumed
|
|
270
|
-
*/
|
|
271
|
-
verify(token: string): Promise<string | null>;
|
|
272
|
-
/**
|
|
273
|
-
* Cleanup timer and resources
|
|
274
|
-
*/
|
|
275
|
-
destroy(): void;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
export { CacheTokenStore as C, type EventDef as E, type InferEventNames as I, type JobQueueSender as J, type PubSubCache as P, SSETokenManager as S, type EventHandler as a, type EventRouterDef as b, type InferEventPayload$1 as c, type InferEventPayloads as d, type InferEventPayload as e, defineEventRouter as f, type SSEToken as g, type SSETokenManagerConfig as h, type SSETokenStore as i };
|
|
232
|
+
export { type EventRouterDef as E, type InferEventNames as I, type JobQueueSender as J, type PubSubCache as P, type EventDef as a, type EventContract as b, type EventHandler as c, type EventRouterContract as d, type InferEventPayload$1 as e, type InferEventPayloads as f, type InferEventPayload as g, defineEventRouter as h, type EventRouterBase as i };
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { a as NamedMiddleware } from './define-middleware-CVKgqo8S.js';
|
|
2
|
+
import { R as RouteDef } from './route-builder-BHKgGkwI.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Router Definition
|
|
6
|
+
*
|
|
7
|
+
* Provides router composition and middleware management
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Router definition - holds all routes
|
|
12
|
+
*/
|
|
13
|
+
interface Router<TRoutes extends Record<string, RouteDef<any, any, any> | Router<any>>> {
|
|
14
|
+
routes: TRoutes;
|
|
15
|
+
_routes: TRoutes;
|
|
16
|
+
_packageRouters: Router<any>[];
|
|
17
|
+
_globalMiddlewares: NamedMiddleware<string>[];
|
|
18
|
+
/** The contract version these routes publish, or null when uncontracted. */
|
|
19
|
+
_contractVersion: string | null;
|
|
20
|
+
/**
|
|
21
|
+
* Whether a client ever addresses these routes by name.
|
|
22
|
+
*
|
|
23
|
+
* True for an ordinary router. A mounted package router that is true here
|
|
24
|
+
* has its routes written into the app's generated route map, which is what
|
|
25
|
+
* lets the package's own client (`authApi.login`) resolve a name through the
|
|
26
|
+
* app's RPC proxy. It is also what makes an app route sharing a name with a
|
|
27
|
+
* package route a defect worth refusing a build over: the map holds one
|
|
28
|
+
* entry per name, so one of the two paths would become unreachable while the
|
|
29
|
+
* generated types still describe the app's route.
|
|
30
|
+
*
|
|
31
|
+
* False says no client names these routes: they are reached by URL, by
|
|
32
|
+
* something that was handed the URL, so nothing of them belongs in the map
|
|
33
|
+
* and a name they share with an app route is only a shared name.
|
|
34
|
+
* `createOpsRouter` sets it — `spfn ops` invokes an ops command over the URL
|
|
35
|
+
* the manifest gave it.
|
|
36
|
+
*/
|
|
37
|
+
_publishesRouteMap: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* The namespace of the command surface that built this router, absent on
|
|
40
|
+
* any other. Set by `defineSurface` (and so by `createOpsRouter`) as a
|
|
41
|
+
* non-enumerable property, so `.packages()` can refuse two surfaces on one
|
|
42
|
+
* namespace.
|
|
43
|
+
*/
|
|
44
|
+
readonly _surfaceNamespace?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Register package routers (type-hidden)
|
|
47
|
+
*
|
|
48
|
+
* Package routes are:
|
|
49
|
+
* - Recognized by RPC proxy and backend
|
|
50
|
+
* - NOT exposed in client types (use package's own API like authApi, cmsApi)
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* import { authRouter } from '@spfn/auth/server';
|
|
55
|
+
* import { cmsAppRouter } from '@spfn/cms/server';
|
|
56
|
+
*
|
|
57
|
+
* export const appRouter = defineRouter({
|
|
58
|
+
* getRoot,
|
|
59
|
+
* getStatus,
|
|
60
|
+
* })
|
|
61
|
+
* .packages([authRouter, cmsAppRouter]);
|
|
62
|
+
*
|
|
63
|
+
* // Client usage:
|
|
64
|
+
* // api.getRoot.call({}) - app routes
|
|
65
|
+
* // authApi.login.call({}) - package API
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
packages(routers: Router<any>[]): Router<TRoutes>;
|
|
69
|
+
/**
|
|
70
|
+
* Register global middlewares
|
|
71
|
+
*
|
|
72
|
+
* Applied to all routes unless explicitly skipped via .skip()
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* import { authMiddleware, loggingMiddleware } from './middlewares';
|
|
77
|
+
*
|
|
78
|
+
* export const appRouter = defineRouter({
|
|
79
|
+
* getRoot,
|
|
80
|
+
* getStatus,
|
|
81
|
+
* })
|
|
82
|
+
* .packages([authRouter])
|
|
83
|
+
* .use([authMiddleware, loggingMiddleware]);
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
use(middlewares: NamedMiddleware<string>[]): Router<TRoutes>;
|
|
87
|
+
/**
|
|
88
|
+
* Declare the contract version these routes publish.
|
|
89
|
+
*
|
|
90
|
+
* A client compiled against this server — a mobile app in a store — is
|
|
91
|
+
* generated from one version of the contract and cannot be updated when the
|
|
92
|
+
* server changes. The server announces this version on every response so
|
|
93
|
+
* that client can tell whether the two ends still agree.
|
|
94
|
+
*
|
|
95
|
+
* This is the version's source. A released snapshot is written to
|
|
96
|
+
* `contracts/released/<version>.json` from what is declared here, so the
|
|
97
|
+
* filename follows the code rather than the code having to be told what the
|
|
98
|
+
* filename said.
|
|
99
|
+
*
|
|
100
|
+
* Only a server with contracted routes needs it. Without it the contract
|
|
101
|
+
* generator still writes `current.json` and still runs the compatibility
|
|
102
|
+
* gate; what it cannot do is cut a release or announce a version.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```ts
|
|
106
|
+
* export const appRouter = defineRouter({ getRoot, listItems })
|
|
107
|
+
* .contractVersion('1.2.0')
|
|
108
|
+
* .packages([authRouter]);
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
contractVersion(version: string): Router<TRoutes>;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Define a router with multiple routes (tRPC-style)
|
|
115
|
+
*
|
|
116
|
+
* Supports chainable API for packages and middlewares:
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```ts
|
|
120
|
+
* // Basic usage
|
|
121
|
+
* export const appRouter = defineRouter({
|
|
122
|
+
* getRoot,
|
|
123
|
+
* getStatus,
|
|
124
|
+
* listExamples,
|
|
125
|
+
* });
|
|
126
|
+
*
|
|
127
|
+
* // With package routers (type-hidden)
|
|
128
|
+
* export const appRouter = defineRouter({
|
|
129
|
+
* getRoot,
|
|
130
|
+
* getStatus,
|
|
131
|
+
* })
|
|
132
|
+
* .packages([authRouter, cmsAppRouter]);
|
|
133
|
+
*
|
|
134
|
+
* // With global middlewares
|
|
135
|
+
* export const appRouter = defineRouter({
|
|
136
|
+
* getRoot,
|
|
137
|
+
* getStatus,
|
|
138
|
+
* })
|
|
139
|
+
* .packages([authRouter])
|
|
140
|
+
* .use([authMiddleware, loggingMiddleware]);
|
|
141
|
+
*
|
|
142
|
+
* export type AppRouter = typeof appRouter;
|
|
143
|
+
* ```
|
|
144
|
+
*
|
|
145
|
+
* Package routes:
|
|
146
|
+
* - Recognized by RPC proxy and backend for routing
|
|
147
|
+
* - NOT included in AppRouter type (use authApi, cmsApi instead)
|
|
148
|
+
* - Prevents confusion between app API and package APIs
|
|
149
|
+
*/
|
|
150
|
+
declare function defineRouter<TRoutes extends Record<string, RouteDef<any, any, any> | Router<any>>>(routes: TRoutes): Router<TRoutes>;
|
|
151
|
+
/**
|
|
152
|
+
* A router no client addresses by name.
|
|
153
|
+
*
|
|
154
|
+
* The app's generated route map carries the routes of every package router the
|
|
155
|
+
* app mounts with `.packages()`, so that a package client calling its own route
|
|
156
|
+
* by name resolves through the app's RPC proxy. A router built here is left out
|
|
157
|
+
* of that map: its routes are reached by URL, by a tool that was told the URL,
|
|
158
|
+
* so no name of theirs has to resolve anywhere and a name shared with an app
|
|
159
|
+
* route is only a shared name.
|
|
160
|
+
*
|
|
161
|
+
* Declared by the package that ships the router, because only it knows whether
|
|
162
|
+
* any client names these routes: `createOpsRouter` and the tracking routes of
|
|
163
|
+
* `@spfn/notification` do it, and any package whose surface is reached by URL
|
|
164
|
+
* may. The obligation is the whole of it — a package whose client *does* name
|
|
165
|
+
* its routes must use `defineRouter`, or those names land in nobody's map and
|
|
166
|
+
* resolve nowhere (and a collision that really would take an app route's entry
|
|
167
|
+
* generates silently). `defineRouter` is the default for exactly that reason: a
|
|
168
|
+
* package that says nothing is carried and checked.
|
|
169
|
+
*/
|
|
170
|
+
declare function defineUnmappedRouter<TRoutes extends Record<string, RouteDef<any, any, any> | Router<any>>>(routes: TRoutes): Router<TRoutes>;
|
|
171
|
+
|
|
172
|
+
export { type Router as R, defineUnmappedRouter as a, defineRouter as d };
|