@spfn/core 0.3.0-beta.3 → 0.3.0-beta.30

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.
Files changed (104) hide show
  1. package/README.md +301 -10
  2. package/dist/app-config/index.d.ts +39 -1
  3. package/dist/app-config/index.js.map +1 -1
  4. package/dist/authz/index.js +47 -391
  5. package/dist/authz/index.js.map +1 -1
  6. package/dist/{boss-D16fO2oG.d.ts → boss-BiDCbbAQ.d.ts} +60 -7
  7. package/dist/codegen/index.d.ts +157 -16
  8. package/dist/codegen/index.js +772 -166
  9. package/dist/codegen/index.js.map +1 -1
  10. package/dist/config/index.js +4 -4
  11. package/dist/config/index.js.map +1 -1
  12. package/dist/contract/index.d.ts +39 -16
  13. package/dist/contract/index.js +147 -23
  14. package/dist/contract/index.js.map +1 -1
  15. package/dist/db/index.d.ts +230 -35
  16. package/dist/db/index.js +316 -160
  17. package/dist/db/index.js.map +1 -1
  18. package/dist/env/index.d.ts +6 -442
  19. package/dist/env/index.js +13 -16
  20. package/dist/env/index.js.map +1 -1
  21. package/dist/env/loader.js +24 -1
  22. package/dist/env/loader.js.map +1 -1
  23. package/dist/error-CIZlYJlL.d.ts +157 -0
  24. package/dist/errors/index.d.ts +18 -1
  25. package/dist/errors/index.js +47 -391
  26. package/dist/errors/index.js.map +1 -1
  27. package/dist/event/index.d.ts +5 -5
  28. package/dist/event/index.js +202 -3
  29. package/dist/event/index.js.map +1 -1
  30. package/dist/event/sse/client.d.ts +18 -4
  31. package/dist/event/sse/client.js +94 -18
  32. package/dist/event/sse/client.js.map +1 -1
  33. package/dist/event/sse/index.d.ts +18 -5
  34. package/dist/event/sse/index.js +452 -114
  35. package/dist/event/sse/index.js.map +1 -1
  36. package/dist/event/ws/client.d.ts +3 -2
  37. package/dist/event/ws/index.d.ts +4 -3
  38. package/dist/job/index.d.ts +48 -3
  39. package/dist/job/index.js +131 -52
  40. package/dist/job/index.js.map +1 -1
  41. package/dist/logger/index.js +0 -12
  42. package/dist/logger/index.js.map +1 -1
  43. package/dist/middleware/index.js +52 -397
  44. package/dist/middleware/index.js.map +1 -1
  45. package/dist/nextjs/index.d.ts +75 -14
  46. package/dist/nextjs/index.js +200 -84
  47. package/dist/nextjs/index.js.map +1 -1
  48. package/dist/nextjs/server.d.ts +46 -8
  49. package/dist/nextjs/server.js +15 -1
  50. package/dist/nextjs/server.js.map +1 -1
  51. package/dist/ops/index.d.ts +61 -42
  52. package/dist/ops/index.js +648 -97
  53. package/dist/ops/index.js.map +1 -1
  54. package/dist/registry-C2KQCh0m.d.ts +473 -0
  55. package/dist/route/index.d.ts +5 -2
  56. package/dist/route/index.js +107 -28
  57. package/dist/route/index.js.map +1 -1
  58. package/dist/route/types.d.ts +7 -1
  59. package/dist/{router-Cy7rAfmj.d.ts → route-builder-DRW-MSCJ.d.ts} +51 -126
  60. package/dist/router-C57y-vz1.d.ts +184 -0
  61. package/dist/router-CX5uVjmU.d.ts +406 -0
  62. package/dist/server/index.d.ts +130 -7
  63. package/dist/server/index.js +1174 -164
  64. package/dist/server/index.js.map +1 -1
  65. package/dist/state/client.d.ts +206 -0
  66. package/dist/state/client.js +678 -0
  67. package/dist/state/client.js.map +1 -0
  68. package/dist/state/index.d.ts +443 -0
  69. package/dist/state/index.js +644 -0
  70. package/dist/state/index.js.map +1 -0
  71. package/dist/state/react.d.ts +49 -0
  72. package/dist/state/react.js +50 -0
  73. package/dist/state/react.js.map +1 -0
  74. package/dist/surface/index.d.ts +115 -0
  75. package/dist/surface/index.js +1013 -0
  76. package/dist/surface/index.js.map +1 -0
  77. package/dist/token-manager-Ckjt2-qq.d.ts +122 -0
  78. package/dist/{types-CfYVhIQ9.d.ts → types-5Rl11_Nb.d.ts} +43 -4
  79. package/dist/types-CKH0D3Dy.d.ts +441 -0
  80. package/dist/{types-ZQODsBft.d.ts → types-CurMab2Q.d.ts} +52 -2
  81. package/dist/{types-2AbaW4Ie.d.ts → types-DncqXfWN.d.ts} +4 -3
  82. package/docs/file-upload.md +195 -333
  83. package/package.json +39 -9
  84. package/src/cache/README.md +330 -0
  85. package/src/codegen/README.md +721 -0
  86. package/src/config/README.md +333 -0
  87. package/src/contract/README.md +442 -0
  88. package/src/db/README.md +589 -0
  89. package/src/db/manager/README.md +500 -0
  90. package/src/db/schema/README.md +354 -0
  91. package/src/db/transaction/README.md +845 -0
  92. package/src/env/README.md +787 -0
  93. package/src/errors/README.md +445 -0
  94. package/src/event/README.md +994 -0
  95. package/src/job/README.md +613 -0
  96. package/src/logger/README.md +321 -0
  97. package/src/middleware/README.md +634 -0
  98. package/src/nextjs/README.md +756 -0
  99. package/src/route/README.md +763 -0
  100. package/src/security/README.md +100 -0
  101. package/src/server/README.md +704 -0
  102. package/src/state/README.md +806 -0
  103. package/dist/token-manager-BT5EnUAR.d.ts +0 -278
  104. package/dist/types-9oszaJqp.d.ts +0 -250
@@ -1,8 +1,8 @@
1
- import { a as NamedMiddleware } from './define-middleware-CVKgqo8S.js';
2
1
  import { Context, MiddlewareHandler } from 'hono';
2
+ import { a as NamedMiddleware } from './define-middleware-CVKgqo8S.js';
3
3
  import { TSchema, Static } from '@sinclair/typebox';
4
4
  import { ContentfulStatusCode, RedirectStatusCode } from 'hono/utils/http-status';
5
- import { HttpMethod } from './route/types.js';
5
+ import { HttpMethod, RouteEffect } from './route/types.js';
6
6
 
7
7
  /**
8
8
  * Route Input Types
@@ -296,6 +296,13 @@ type RouteDef<TInput extends RouteInput = RouteInput, TInterceptor extends Route
296
296
  * the compatibility gate read it.
297
297
  */
298
298
  contract?: RouteContract;
299
+ /**
300
+ * What invoking this route does. Read by a command surface, which
301
+ * announces it in its manifest; codegen and the contract ignore it.
302
+ */
303
+ effect?: RouteEffect;
304
+ /** One line a command surface announces beside the route; codegen and the contract ignore it. */
305
+ summary?: string;
299
306
  handler: RouteHandlerFn<TInput, TInterceptor, TResponse>;
300
307
  _input: TInput;
301
308
  _interceptor: TInterceptor;
@@ -312,6 +319,8 @@ declare class RouteBuilder<TInput extends RouteInput = {}, TInterceptor extends
312
319
  _middlewares?: (MiddlewareHandler | NamedMiddleware<string>)[];
313
320
  _skipMiddlewares?: string[] | '*';
314
321
  _contract?: RouteContract;
322
+ _effect?: RouteEffect;
323
+ _summary?: string;
315
324
  /**
316
325
  * Create a new RouteBuilder with copied properties and optional overrides
317
326
  */
@@ -472,6 +481,45 @@ declare class RouteBuilder<TInput extends RouteInput = {}, TInterceptor extends
472
481
  * ```
473
482
  */
474
483
  contract(contract: RouteContract): RouteBuilder<TInput, TInterceptor, TResponse>;
484
+ /**
485
+ * Declare what invoking this route does
486
+ *
487
+ * Read by a command surface (`@spfn/core/surface`, `@spfn/core/ops`),
488
+ * which announces it in its manifest so a machine caller can tell a read
489
+ * from a write before it calls — `spfn ops call` asks for `--yes` before a
490
+ * `destructive` command. A surface built with `defineSurface` refuses an
491
+ * app command that does not declare one; on `/_ops` it is optional.
492
+ *
493
+ * Nothing else reads it: codegen, the route map, and the contract are
494
+ * unaffected, and a route outside any surface simply carries it.
495
+ *
496
+ * @example
497
+ * ```ts
498
+ * export const pageAdd = app.route.post('/pages')
499
+ * .input({ body: PageAddBody })
500
+ * .effect('write')
501
+ * .summary('Add a page to the blueprint')
502
+ * .handler(async (c) => { ... });
503
+ * ```
504
+ */
505
+ effect(effect: RouteEffect): RouteBuilder<TInput, TInterceptor, TResponse>;
506
+ /**
507
+ * Describe this route in one line for a command surface's manifest
508
+ *
509
+ * A surface announces it beside the command in `spfn ops list` and
510
+ * `--describe`, and refuses one that is empty or longer than 500
511
+ * characters. Codegen, the route map, and the contract ignore it. On a
512
+ * module command the module's own summary wins.
513
+ *
514
+ * @example
515
+ * ```ts
516
+ * export const pageAdd = app.route.post('/pages')
517
+ * .effect('write')
518
+ * .summary('Add a page to the blueprint')
519
+ * .handler(async (c) => { ... });
520
+ * ```
521
+ */
522
+ summary(summary: string): RouteBuilder<TInput, TInterceptor, TResponse>;
475
523
  /**
476
524
  * Define handler function
477
525
  *
@@ -550,127 +598,4 @@ declare const route: {
550
598
  delete: (path: string) => RouteBuilder;
551
599
  };
552
600
 
553
- /**
554
- * Router Definition
555
- *
556
- * Provides router composition and middleware management
557
- */
558
-
559
- /**
560
- * Router definition - holds all routes
561
- */
562
- interface Router<TRoutes extends Record<string, RouteDef<any, any, any> | Router<any>>> {
563
- routes: TRoutes;
564
- _routes: TRoutes;
565
- _packageRouters: Router<any>[];
566
- _globalMiddlewares: NamedMiddleware<string>[];
567
- /** The contract version these routes publish, or null when uncontracted. */
568
- _contractVersion: string | null;
569
- /**
570
- * Register package routers (type-hidden)
571
- *
572
- * Package routes are:
573
- * - Recognized by RPC proxy and backend
574
- * - NOT exposed in client types (use package's own API like authApi, cmsApi)
575
- *
576
- * @example
577
- * ```ts
578
- * import { authRouter } from '@spfn/auth/server';
579
- * import { cmsAppRouter } from '@spfn/cms/server';
580
- *
581
- * export const appRouter = defineRouter({
582
- * getRoot,
583
- * getStatus,
584
- * })
585
- * .packages([authRouter, cmsAppRouter]);
586
- *
587
- * // Client usage:
588
- * // api.getRoot.call({}) - app routes
589
- * // authApi.login.call({}) - package API
590
- * ```
591
- */
592
- packages(routers: Router<any>[]): Router<TRoutes>;
593
- /**
594
- * Register global middlewares
595
- *
596
- * Applied to all routes unless explicitly skipped via .skip()
597
- *
598
- * @example
599
- * ```ts
600
- * import { authMiddleware, loggingMiddleware } from './middlewares';
601
- *
602
- * export const appRouter = defineRouter({
603
- * getRoot,
604
- * getStatus,
605
- * })
606
- * .packages([authRouter])
607
- * .use([authMiddleware, loggingMiddleware]);
608
- * ```
609
- */
610
- use(middlewares: NamedMiddleware<string>[]): Router<TRoutes>;
611
- /**
612
- * Declare the contract version these routes publish.
613
- *
614
- * A client compiled against this server — a mobile app in a store — is
615
- * generated from one version of the contract and cannot be updated when the
616
- * server changes. The server announces this version on every response so
617
- * that client can tell whether the two ends still agree.
618
- *
619
- * This is the version's source. A released snapshot is written to
620
- * `contracts/released/<version>.json` from what is declared here, so the
621
- * filename follows the code rather than the code having to be told what the
622
- * filename said.
623
- *
624
- * Only a server with contracted routes needs it. Without it the contract
625
- * generator still writes `current.json` and still runs the compatibility
626
- * gate; what it cannot do is cut a release or announce a version.
627
- *
628
- * @example
629
- * ```ts
630
- * export const appRouter = defineRouter({ getRoot, listItems })
631
- * .contractVersion('1.2.0')
632
- * .packages([authRouter]);
633
- * ```
634
- */
635
- contractVersion(version: string): Router<TRoutes>;
636
- }
637
- /**
638
- * Define a router with multiple routes (tRPC-style)
639
- *
640
- * Supports chainable API for packages and middlewares:
641
- *
642
- * @example
643
- * ```ts
644
- * // Basic usage
645
- * export const appRouter = defineRouter({
646
- * getRoot,
647
- * getStatus,
648
- * listExamples,
649
- * });
650
- *
651
- * // With package routers (type-hidden)
652
- * export const appRouter = defineRouter({
653
- * getRoot,
654
- * getStatus,
655
- * })
656
- * .packages([authRouter, cmsAppRouter]);
657
- *
658
- * // With global middlewares
659
- * export const appRouter = defineRouter({
660
- * getRoot,
661
- * getStatus,
662
- * })
663
- * .packages([authRouter])
664
- * .use([authMiddleware, loggingMiddleware]);
665
- *
666
- * export type AppRouter = typeof appRouter;
667
- * ```
668
- *
669
- * Package routes:
670
- * - Recognized by RPC proxy and backend for routing
671
- * - NOT included in AppRouter type (use authApi, cmsApi instead)
672
- * - Prevents confusion between app API and package APIs
673
- */
674
- declare function defineRouter<TRoutes extends Record<string, RouteDef<any, any, any> | Router<any>>>(routes: TRoutes): Router<TRoutes>;
675
-
676
- export { type MergedInput as M, type PaginatedResult as P, type Router as R, type RouteDef as a, RouteBuilder as b, type RouteAuthProfile as c, type RouteBuilderContext as d, type RouteContract as e, type RouteHandlerFn as f, type RouteInput as g, defineRouter as h, route as r };
601
+ export { type MergedInput as M, type PaginatedResult as P, type RouteDef as R, type RouteAuthProfile as a, type RouteBuilderContext as b, type RouteContract as c, type RouteHandlerFn as d, type RouteInput as e, RouteBuilder as f, route as r };
@@ -0,0 +1,184 @@
1
+ import { a as NamedMiddleware } from './define-middleware-CVKgqo8S.js';
2
+ import { R as RouteDef } from './route-builder-DRW-MSCJ.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
+ * The manifest of the states that built this router — each state's key
47
+ * fields and whether it has a write, in declaration order — absent on any
48
+ * other. Set by `defineStateRouter` on the router it derives as a
49
+ * non-enumerable property; it is the object the snapshot route answers as
50
+ * `manifest`, and what `@spfn/core:states` reads to write the app's declared
51
+ * state ids. Written structurally so the route module does not import state.
52
+ */
53
+ readonly _stateManifest?: Readonly<Record<string, {
54
+ readonly key: readonly string[];
55
+ readonly write: boolean;
56
+ }>>;
57
+ /**
58
+ * Register package routers (type-hidden)
59
+ *
60
+ * Package routes are:
61
+ * - Recognized by RPC proxy and backend
62
+ * - NOT exposed in client types (use package's own API like authApi, cmsApi)
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * import { authRouter } from '@spfn/auth/server';
67
+ * import { cmsAppRouter } from '@spfn/cms/server';
68
+ *
69
+ * export const appRouter = defineRouter({
70
+ * getRoot,
71
+ * getStatus,
72
+ * })
73
+ * .packages([authRouter, cmsAppRouter]);
74
+ *
75
+ * // Client usage:
76
+ * // api.getRoot.call({}) - app routes
77
+ * // authApi.login.call({}) - package API
78
+ * ```
79
+ */
80
+ packages(routers: Router<any>[]): Router<TRoutes>;
81
+ /**
82
+ * Register global middlewares
83
+ *
84
+ * Applied to all routes unless explicitly skipped via .skip()
85
+ *
86
+ * @example
87
+ * ```ts
88
+ * import { authMiddleware, loggingMiddleware } from './middlewares';
89
+ *
90
+ * export const appRouter = defineRouter({
91
+ * getRoot,
92
+ * getStatus,
93
+ * })
94
+ * .packages([authRouter])
95
+ * .use([authMiddleware, loggingMiddleware]);
96
+ * ```
97
+ */
98
+ use(middlewares: NamedMiddleware<string>[]): Router<TRoutes>;
99
+ /**
100
+ * Declare the contract version these routes publish.
101
+ *
102
+ * A client compiled against this server — a mobile app in a store — is
103
+ * generated from one version of the contract and cannot be updated when the
104
+ * server changes. The server announces this version on every response so
105
+ * that client can tell whether the two ends still agree.
106
+ *
107
+ * This is the version's source. A released snapshot is written to
108
+ * `contracts/released/<version>.json` from what is declared here, so the
109
+ * filename follows the code rather than the code having to be told what the
110
+ * filename said.
111
+ *
112
+ * Only a server with contracted routes needs it. Without it the contract
113
+ * generator still writes `current.json` and still runs the compatibility
114
+ * gate; what it cannot do is cut a release or announce a version.
115
+ *
116
+ * @example
117
+ * ```ts
118
+ * export const appRouter = defineRouter({ getRoot, listItems })
119
+ * .contractVersion('1.2.0')
120
+ * .packages([authRouter]);
121
+ * ```
122
+ */
123
+ contractVersion(version: string): Router<TRoutes>;
124
+ }
125
+ /**
126
+ * Define a router with multiple routes (tRPC-style)
127
+ *
128
+ * Supports chainable API for packages and middlewares:
129
+ *
130
+ * @example
131
+ * ```ts
132
+ * // Basic usage
133
+ * export const appRouter = defineRouter({
134
+ * getRoot,
135
+ * getStatus,
136
+ * listExamples,
137
+ * });
138
+ *
139
+ * // With package routers (type-hidden)
140
+ * export const appRouter = defineRouter({
141
+ * getRoot,
142
+ * getStatus,
143
+ * })
144
+ * .packages([authRouter, cmsAppRouter]);
145
+ *
146
+ * // With global middlewares
147
+ * export const appRouter = defineRouter({
148
+ * getRoot,
149
+ * getStatus,
150
+ * })
151
+ * .packages([authRouter])
152
+ * .use([authMiddleware, loggingMiddleware]);
153
+ *
154
+ * export type AppRouter = typeof appRouter;
155
+ * ```
156
+ *
157
+ * Package routes:
158
+ * - Recognized by RPC proxy and backend for routing
159
+ * - NOT included in AppRouter type (use authApi, cmsApi instead)
160
+ * - Prevents confusion between app API and package APIs
161
+ */
162
+ declare function defineRouter<TRoutes extends Record<string, RouteDef<any, any, any> | Router<any>>>(routes: TRoutes): Router<TRoutes>;
163
+ /**
164
+ * A router no client addresses by name.
165
+ *
166
+ * The app's generated route map carries the routes of every package router the
167
+ * app mounts with `.packages()`, so that a package client calling its own route
168
+ * by name resolves through the app's RPC proxy. A router built here is left out
169
+ * of that map: its routes are reached by URL, by a tool that was told the URL,
170
+ * so no name of theirs has to resolve anywhere and a name shared with an app
171
+ * route is only a shared name.
172
+ *
173
+ * Declared by the package that ships the router, because only it knows whether
174
+ * any client names these routes: `createOpsRouter` and the tracking routes of
175
+ * `@spfn/notification` do it, and any package whose surface is reached by URL
176
+ * may. The obligation is the whole of it — a package whose client *does* name
177
+ * its routes must use `defineRouter`, or those names land in nobody's map and
178
+ * resolve nowhere (and a collision that really would take an app route's entry
179
+ * generates silently). `defineRouter` is the default for exactly that reason: a
180
+ * package that says nothing is carried and checked.
181
+ */
182
+ declare function defineUnmappedRouter<TRoutes extends Record<string, RouteDef<any, any, any> | Router<any>>>(routes: TRoutes): Router<TRoutes>;
183
+
184
+ export { type Router as R, defineUnmappedRouter as a, defineRouter as d };