@procedures/client 0.8.0 → 0.9.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.
Files changed (197) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/README.md +95 -8
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/adapters/http/client/transport.d.ts +4 -0
  5. package/dist/adapters/http/client/transport.d.ts.map +1 -1
  6. package/dist/adapters/http/client/transport.js +11 -1
  7. package/dist/adapters/http/client/transport.js.map +1 -1
  8. package/dist/adapters/http/client/types.d.ts +19 -0
  9. package/dist/adapters/http/client/types.d.ts.map +1 -1
  10. package/dist/adapters/http/server/cors.d.ts +64 -0
  11. package/dist/adapters/http/server/cors.d.ts.map +1 -0
  12. package/dist/adapters/http/server/cors.js +113 -0
  13. package/dist/adapters/http/server/cors.js.map +1 -0
  14. package/dist/adapters/http/server/handler.d.ts +136 -0
  15. package/dist/adapters/http/server/handler.d.ts.map +1 -0
  16. package/dist/adapters/http/server/handler.js +495 -0
  17. package/dist/adapters/http/server/handler.js.map +1 -0
  18. package/dist/adapters/http/server/strategies.d.ts +14 -5
  19. package/dist/adapters/http/server/strategies.d.ts.map +1 -1
  20. package/dist/adapters/http/server/strategies.js.map +1 -1
  21. package/dist/adapters/http/server/transport.d.ts +30 -46
  22. package/dist/adapters/http/server/transport.d.ts.map +1 -1
  23. package/dist/adapters/http/server/transport.js +48 -432
  24. package/dist/adapters/http/server/transport.js.map +1 -1
  25. package/dist/adapters/http/server/types.d.ts +13 -0
  26. package/dist/adapters/http/server/types.d.ts.map +1 -1
  27. package/dist/adapters/websocket/client/transport.d.ts.map +1 -1
  28. package/dist/adapters/websocket/client/transport.js +4 -12
  29. package/dist/adapters/websocket/client/transport.js.map +1 -1
  30. package/dist/adapters/websocket/server/transport.d.ts +46 -1
  31. package/dist/adapters/websocket/server/transport.d.ts.map +1 -1
  32. package/dist/adapters/websocket/server/transport.js +152 -15
  33. package/dist/adapters/websocket/server/transport.js.map +1 -1
  34. package/dist/adapters/websocket/server/types.d.ts +10 -3
  35. package/dist/adapters/websocket/server/types.d.ts.map +1 -1
  36. package/dist/adapters/websocket/server/upgrade-router.d.ts +28 -0
  37. package/dist/adapters/websocket/server/upgrade-router.d.ts.map +1 -0
  38. package/dist/adapters/websocket/server/upgrade-router.js +62 -0
  39. package/dist/adapters/websocket/server/upgrade-router.js.map +1 -0
  40. package/dist/adapters/websocket/server/upgrade.d.ts +68 -0
  41. package/dist/adapters/websocket/server/upgrade.d.ts.map +1 -0
  42. package/dist/adapters/websocket/server/upgrade.js +49 -0
  43. package/dist/adapters/websocket/server/upgrade.js.map +1 -0
  44. package/dist/adapters/websocket/shared/rpc.d.ts +2 -0
  45. package/dist/adapters/websocket/shared/rpc.d.ts.map +1 -1
  46. package/dist/adapters/websocket/shared/rpc.js +8 -2
  47. package/dist/adapters/websocket/shared/rpc.js.map +1 -1
  48. package/dist/browser.d.ts +12 -4
  49. package/dist/browser.d.ts.map +1 -1
  50. package/dist/browser.js +13 -2
  51. package/dist/browser.js.map +1 -1
  52. package/dist/client/client.d.ts +43 -0
  53. package/dist/client/client.d.ts.map +1 -1
  54. package/dist/client/client.js +69 -1
  55. package/dist/client/client.js.map +1 -1
  56. package/dist/events/publisher.d.ts +25 -1
  57. package/dist/events/publisher.d.ts.map +1 -1
  58. package/dist/events/publisher.js +66 -9
  59. package/dist/events/publisher.js.map +1 -1
  60. package/dist/events/rows.d.ts +31 -0
  61. package/dist/events/rows.d.ts.map +1 -0
  62. package/dist/events/rows.js +39 -0
  63. package/dist/events/rows.js.map +1 -0
  64. package/dist/index.d.ts +1 -1
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +1 -1
  67. package/dist/index.js.map +1 -1
  68. package/dist/node.d.ts +14 -0
  69. package/dist/node.d.ts.map +1 -1
  70. package/dist/node.js +9 -0
  71. package/dist/node.js.map +1 -1
  72. package/dist/procedures/capability.d.ts +6 -0
  73. package/dist/procedures/capability.d.ts.map +1 -1
  74. package/dist/procedures/capability.js +25 -0
  75. package/dist/procedures/capability.js.map +1 -1
  76. package/dist/procedures/collection/changes.d.ts +94 -0
  77. package/dist/procedures/collection/changes.d.ts.map +1 -0
  78. package/dist/procedures/collection/changes.js +182 -0
  79. package/dist/procedures/collection/changes.js.map +1 -0
  80. package/dist/procedures/collection/index.d.ts +10 -3
  81. package/dist/procedures/collection/index.d.ts.map +1 -1
  82. package/dist/procedures/collection/index.js +8 -1
  83. package/dist/procedures/collection/index.js.map +1 -1
  84. package/dist/procedures/collection/partition.d.ts +67 -0
  85. package/dist/procedures/collection/partition.d.ts.map +1 -0
  86. package/dist/procedures/collection/partition.js +82 -0
  87. package/dist/procedures/collection/partition.js.map +1 -0
  88. package/dist/procedures/collection/procedures.d.ts +39 -2
  89. package/dist/procedures/collection/procedures.d.ts.map +1 -1
  90. package/dist/procedures/collection/procedures.js +147 -44
  91. package/dist/procedures/collection/procedures.js.map +1 -1
  92. package/dist/procedures/collection/query.d.ts +246 -0
  93. package/dist/procedures/collection/query.d.ts.map +1 -0
  94. package/dist/procedures/collection/query.js +854 -0
  95. package/dist/procedures/collection/query.js.map +1 -0
  96. package/dist/procedures/collection/schemas.d.ts +50 -0
  97. package/dist/procedures/collection/schemas.d.ts.map +1 -1
  98. package/dist/procedures/collection/schemas.js +144 -6
  99. package/dist/procedures/collection/schemas.js.map +1 -1
  100. package/dist/procedures/collection/storage.d.ts +58 -6
  101. package/dist/procedures/collection/storage.d.ts.map +1 -1
  102. package/dist/procedures/collection/storage.js +23 -0
  103. package/dist/procedures/collection/storage.js.map +1 -1
  104. package/dist/procedures/elicit.d.ts +190 -0
  105. package/dist/procedures/elicit.d.ts.map +1 -0
  106. package/dist/procedures/elicit.js +127 -0
  107. package/dist/procedures/elicit.js.map +1 -0
  108. package/dist/procedures/hints.d.ts +43 -0
  109. package/dist/procedures/hints.d.ts.map +1 -0
  110. package/dist/procedures/hints.js +74 -0
  111. package/dist/procedures/hints.js.map +1 -0
  112. package/dist/procedures/index.d.ts +9 -2
  113. package/dist/procedures/index.d.ts.map +1 -1
  114. package/dist/procedures/index.js +5 -1
  115. package/dist/procedures/index.js.map +1 -1
  116. package/dist/procedures/invoke.d.ts +24 -2
  117. package/dist/procedures/invoke.d.ts.map +1 -1
  118. package/dist/procedures/invoke.js +14 -1
  119. package/dist/procedures/invoke.js.map +1 -1
  120. package/dist/procedures/progress.d.ts +24 -0
  121. package/dist/procedures/progress.d.ts.map +1 -0
  122. package/dist/procedures/progress.js +11 -0
  123. package/dist/procedures/progress.js.map +1 -0
  124. package/dist/procedures/registry.d.ts.map +1 -1
  125. package/dist/procedures/registry.js +5 -0
  126. package/dist/procedures/registry.js.map +1 -1
  127. package/dist/procedures/types.d.ts +55 -0
  128. package/dist/procedures/types.d.ts.map +1 -1
  129. package/dist/procedures/types.js.map +1 -1
  130. package/dist/procedures/untrusted.d.ts +28 -0
  131. package/dist/procedures/untrusted.d.ts.map +1 -0
  132. package/dist/procedures/untrusted.js +32 -0
  133. package/dist/procedures/untrusted.js.map +1 -0
  134. package/dist/server/browser-guard.d.ts +12 -2
  135. package/dist/server/browser-guard.d.ts.map +1 -1
  136. package/dist/server/browser-guard.js +43 -6
  137. package/dist/server/browser-guard.js.map +1 -1
  138. package/dist/server/host-policy.d.ts +10 -1
  139. package/dist/server/host-policy.d.ts.map +1 -1
  140. package/dist/server/host-policy.js +5 -0
  141. package/dist/server/host-policy.js.map +1 -1
  142. package/dist/server/index.d.ts +1 -1
  143. package/dist/server/index.d.ts.map +1 -1
  144. package/dist/server/index.js.map +1 -1
  145. package/dist/server/procedure-server.d.ts +68 -7
  146. package/dist/server/procedure-server.d.ts.map +1 -1
  147. package/dist/server/procedure-server.js +124 -24
  148. package/dist/server/procedure-server.js.map +1 -1
  149. package/dist/server/request-auth.d.ts +51 -4
  150. package/dist/server/request-auth.d.ts.map +1 -1
  151. package/dist/server/request-auth.js +116 -5
  152. package/dist/server/request-auth.js.map +1 -1
  153. package/dist/server/types.d.ts +73 -5
  154. package/dist/server/types.d.ts.map +1 -1
  155. package/dist/server/types.js.map +1 -1
  156. package/package.json +7 -3
  157. package/src/adapters/http/client/transport.ts +11 -1
  158. package/src/adapters/http/client/types.ts +22 -0
  159. package/src/adapters/http/server/cors.ts +144 -0
  160. package/src/adapters/http/server/handler.ts +624 -0
  161. package/src/adapters/http/server/strategies.ts +16 -6
  162. package/src/adapters/http/server/transport.ts +55 -478
  163. package/src/adapters/http/server/types.ts +15 -0
  164. package/src/adapters/websocket/client/transport.ts +4 -12
  165. package/src/adapters/websocket/server/transport.ts +166 -16
  166. package/src/adapters/websocket/server/types.ts +11 -3
  167. package/src/adapters/websocket/server/upgrade-router.ts +77 -0
  168. package/src/adapters/websocket/server/upgrade.ts +88 -0
  169. package/src/adapters/websocket/shared/rpc.ts +9 -2
  170. package/src/browser.ts +85 -2
  171. package/src/client/client.ts +83 -1
  172. package/src/events/publisher.ts +75 -11
  173. package/src/events/rows.ts +48 -0
  174. package/src/index.ts +1 -1
  175. package/src/node.ts +21 -0
  176. package/src/procedures/capability.ts +21 -0
  177. package/src/procedures/collection/changes.ts +245 -0
  178. package/src/procedures/collection/index.ts +57 -1
  179. package/src/procedures/collection/partition.ts +123 -0
  180. package/src/procedures/collection/procedures.ts +206 -51
  181. package/src/procedures/collection/query.ts +1009 -0
  182. package/src/procedures/collection/schemas.ts +196 -7
  183. package/src/procedures/collection/storage.ts +78 -6
  184. package/src/procedures/elicit.ts +320 -0
  185. package/src/procedures/hints.ts +91 -0
  186. package/src/procedures/index.ts +83 -2
  187. package/src/procedures/invoke.ts +33 -2
  188. package/src/procedures/progress.ts +25 -0
  189. package/src/procedures/registry.ts +4 -0
  190. package/src/procedures/types.ts +65 -0
  191. package/src/procedures/untrusted.ts +50 -0
  192. package/src/server/browser-guard.ts +48 -6
  193. package/src/server/host-policy.ts +13 -1
  194. package/src/server/index.ts +3 -0
  195. package/src/server/procedure-server.ts +147 -26
  196. package/src/server/request-auth.ts +128 -6
  197. package/src/server/types.ts +82 -5
@@ -0,0 +1,144 @@
1
+ /**
2
+ * The CORS headers of a procedure server, without a framework. `procedureHandler` applies them to
3
+ * the requests on its path. The Express shim `HttpServerTransport` applies them to each request of
4
+ * its app, as before. This module imports only the types of `node:http`.
5
+ */
6
+
7
+ import type { IncomingMessage, ServerResponse } from "node:http";
8
+ import { HTTPHeaders, HTTPMethod } from "../shared/index.js";
9
+ import { PROTOCOL_HEADER } from "../../../protocol.js";
10
+ import { toMs, type Duration } from "../../../duration.js";
11
+
12
+ /** The CORS options of a procedure server. */
13
+ export interface CorsOptions {
14
+ /**
15
+ * The origins that can read the responses: `"*"`, one origin, a list, or a function that
16
+ * decides for each origin. A response names the origin of the request when the origin is
17
+ * permitted, with `Vary: Origin`.
18
+ * @default "*"
19
+ */
20
+ readonly origin?: string | readonly string[] | ((origin: string) => boolean) | undefined;
21
+ /** The methods of `Access-Control-Allow-Methods`. @default GET, POST, PUT, DELETE, PATCH, OPTIONS */
22
+ readonly methods?: readonly string[] | undefined;
23
+ /** The request headers of `Access-Control-Allow-Headers`. @default the headers of `HttpTransport` */
24
+ readonly allowedHeaders?: readonly string[] | undefined;
25
+ /** The response headers that a page can read (`Access-Control-Expose-Headers`). @default none */
26
+ readonly exposedHeaders?: readonly string[] | undefined;
27
+ /**
28
+ * True: a page can send cookies (`fetch` with `credentials: "include"`). The response then has
29
+ * `Access-Control-Allow-Credentials: true`. A browser refuses `"*"` with credentials, so give the
30
+ * origins.
31
+ */
32
+ readonly credentials?: boolean | undefined;
33
+ /** The time that a browser keeps the answer to a preflight request (`Access-Control-Max-Age`). */
34
+ readonly maxAge?: Duration | undefined;
35
+ }
36
+
37
+ /** The request headers that `HttpTransport` sends: the default `allowedHeaders`. */
38
+ export const DEFAULT_CORS_HEADERS: readonly string[] = Object.freeze([
39
+ "Content-Type",
40
+ "Accept",
41
+ HTTPHeaders.AUTHORIZATION,
42
+ HTTPHeaders.API_KEY,
43
+ HTTPHeaders.REQUEST_ID,
44
+ HTTPHeaders.TRACE_ID,
45
+ HTTPHeaders.SPAN_ID,
46
+ HTTPHeaders.PARENT_SPAN_ID,
47
+ "traceparent",
48
+ PROTOCOL_HEADER,
49
+ HTTPHeaders.METADATA,
50
+ "collection",
51
+ "collectionName",
52
+ "database",
53
+ ]);
54
+
55
+ /** The methods of the default `Access-Control-Allow-Methods`. */
56
+ export const DEFAULT_CORS_METHODS: readonly string[] = Object.freeze([
57
+ HTTPMethod.GET,
58
+ HTTPMethod.POST,
59
+ HTTPMethod.PUT,
60
+ HTTPMethod.DELETE,
61
+ HTTPMethod.PATCH,
62
+ HTTPMethod.OPTIONS,
63
+ ]);
64
+
65
+ /** The CORS options with their defaults, ready for each request. */
66
+ export interface CorsPolicy {
67
+ /** The permitted origin to send back for a request origin, or undefined for none. */
68
+ readonly allowOrigin: (requestOrigin: string | undefined) => string | undefined;
69
+ /** True when the permitted origin depends on the request: the response gets `Vary: Origin`. */
70
+ readonly varies: boolean;
71
+ readonly methods: string | undefined;
72
+ readonly allowedHeaders: string | undefined;
73
+ readonly exposedHeaders: string | undefined;
74
+ readonly credentials: boolean;
75
+ /** The value of `Access-Control-Max-Age` in seconds, or undefined. */
76
+ readonly maxAge: string | undefined;
77
+ }
78
+
79
+ /**
80
+ * This function makes the CORS policy of the options. `defaultCredentials` is the default of the
81
+ * `credentials` option.
82
+ */
83
+ export function corsPolicy(options: CorsOptions, defaultCredentials: boolean): CorsPolicy {
84
+ const origin = options.origin ?? "*";
85
+ const allowOrigin = (requestOrigin: string | undefined): string | undefined => {
86
+ if (origin === "*") return "*";
87
+ if (requestOrigin === undefined) return undefined;
88
+ if (typeof origin === "function") return origin(requestOrigin) ? requestOrigin : undefined;
89
+ const list: readonly string[] = typeof origin === "string" ? [origin] : origin;
90
+ return list.includes(requestOrigin) ? requestOrigin : undefined;
91
+ };
92
+ const join = (list: readonly string[] | undefined): string | undefined => (list === undefined || list.length === 0 ? undefined : list.join(", "));
93
+ const maxAgeMs = options.maxAge === undefined ? undefined : toMs(options.maxAge, "cors.maxAge");
94
+ return {
95
+ allowOrigin,
96
+ varies: origin !== "*",
97
+ methods: join("methods" in options ? options.methods : DEFAULT_CORS_METHODS),
98
+ allowedHeaders: join("allowedHeaders" in options ? options.allowedHeaders : DEFAULT_CORS_HEADERS),
99
+ exposedHeaders: join(options.exposedHeaders),
100
+ credentials: options.credentials ?? defaultCredentials,
101
+ maxAge: maxAgeMs === undefined || maxAgeMs <= 0 ? undefined : String(Math.floor(maxAgeMs / 1000)),
102
+ };
103
+ }
104
+
105
+ /** This function adds a value to the `Vary` header of a response, one time. */
106
+ function vary(res: ServerResponse, field: string): void {
107
+ const current = res.getHeader("Vary");
108
+ const text = Array.isArray(current) ? current.join(", ") : current === undefined ? "" : String(current);
109
+ const fields = text.split(",").map((part) => part.trim().toLowerCase());
110
+ if (fields.includes("*") || fields.includes(field.toLowerCase())) return;
111
+ res.setHeader("Vary", text.trim() === "" ? field : `${text}, ${field}`);
112
+ }
113
+
114
+ /**
115
+ * This function sets the CORS headers of a response. It gives true for a preflight request
116
+ * (`OPTIONS`): the function then ends the response with 204.
117
+ */
118
+ export function applyCors(req: IncomingMessage, res: ServerResponse, policy: CorsPolicy): boolean {
119
+ const requestOrigin = typeof req.headers.origin === "string" ? req.headers.origin : undefined;
120
+ const allowed = policy.allowOrigin(requestOrigin);
121
+ if (policy.varies) vary(res, "Origin");
122
+ if (allowed !== undefined) res.setHeader("Access-Control-Allow-Origin", allowed);
123
+ if (policy.methods !== undefined) res.setHeader("Access-Control-Allow-Methods", policy.methods);
124
+ if (policy.allowedHeaders !== undefined) res.setHeader("Access-Control-Allow-Headers", policy.allowedHeaders);
125
+ if (policy.exposedHeaders !== undefined) res.setHeader("Access-Control-Expose-Headers", policy.exposedHeaders);
126
+ if (policy.credentials) res.setHeader("Access-Control-Allow-Credentials", "true");
127
+ if (req.method !== "OPTIONS") return false;
128
+ if (policy.maxAge !== undefined) res.setHeader("Access-Control-Max-Age", policy.maxAge);
129
+ res.statusCode = 204;
130
+ res.end();
131
+ return true;
132
+ }
133
+
134
+ /**
135
+ * The origins that the CORS options permit, for the browser checks: a page that CORS lets read the
136
+ * response can also send a call. Without CORS, no other origin can send a call.
137
+ */
138
+ export function corsOrigins(cors: CorsOptions | undefined): readonly string[] | "*" | ((origin: string) => boolean) {
139
+ if (!cors) return [];
140
+ const origin = cors.origin ?? "*";
141
+ if (origin === "*") return "*";
142
+ if (typeof origin === "function") return origin;
143
+ return typeof origin === "string" ? [origin] : origin;
144
+ }