@gaganref/confect-server 10.3.1-fork.8 → 10.3.1-fork.80

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 (180) hide show
  1. package/dist/ActionCall.d.ts +30 -0
  2. package/dist/ActionCall.d.ts.map +1 -0
  3. package/dist/ActionCall.js +41 -0
  4. package/dist/ActionCall.js.map +1 -0
  5. package/dist/ActionRunner.d.ts +1 -1
  6. package/dist/ActionRunner.d.ts.map +1 -1
  7. package/dist/ActionRunner.js +3 -3
  8. package/dist/ActionRunner.js.map +1 -1
  9. package/dist/AiGatewayDecisionClient.js +1 -1
  10. package/dist/AiGatewayLanguageClient.js +1 -1
  11. package/dist/Auth.d.ts +31 -2
  12. package/dist/Auth.d.ts.map +1 -1
  13. package/dist/Auth.js +23 -3
  14. package/dist/Auth.js.map +1 -1
  15. package/dist/Callback.d.ts +1 -1
  16. package/dist/Callback.d.ts.map +1 -1
  17. package/dist/Callback.js +6 -6
  18. package/dist/Callback.js.map +1 -1
  19. package/dist/ConvexConfigProvider.js +2 -2
  20. package/dist/ConvexFunctionDefinitions.d.ts.map +1 -1
  21. package/dist/ConvexFunctionDefinitions.js +4 -4
  22. package/dist/ConvexFunctionDefinitions.js.map +1 -1
  23. package/dist/ConvexLogger.js +1 -1
  24. package/dist/CronJobs.d.ts.map +1 -1
  25. package/dist/CronJobs.js +7 -6
  26. package/dist/CronJobs.js.map +1 -1
  27. package/dist/DatabaseSchema.js +2 -2
  28. package/dist/DatabaseWriter.d.ts +36 -2
  29. package/dist/DatabaseWriter.d.ts.map +1 -1
  30. package/dist/DatabaseWriter.js +55 -8
  31. package/dist/DatabaseWriter.js.map +1 -1
  32. package/dist/ExecutionMetadata.js +1 -1
  33. package/dist/FunctionImpl.js +2 -2
  34. package/dist/FunctionRegistryItem.d.ts +1 -0
  35. package/dist/FunctionRegistryItem.d.ts.map +1 -1
  36. package/dist/FunctionRegistryItem.js +2 -1
  37. package/dist/FunctionRegistryItem.js.map +1 -1
  38. package/dist/GroupImpl.d.ts +21 -2
  39. package/dist/GroupImpl.d.ts.map +1 -1
  40. package/dist/GroupImpl.js +21 -22
  41. package/dist/GroupImpl.js.map +1 -1
  42. package/dist/GroupRegistry.d.ts +1 -0
  43. package/dist/GroupRegistry.d.ts.map +1 -1
  44. package/dist/GroupRegistry.js +10 -3
  45. package/dist/GroupRegistry.js.map +1 -1
  46. package/dist/Handler.d.ts +8 -4
  47. package/dist/Handler.d.ts.map +1 -1
  48. package/dist/Handler.js.map +1 -1
  49. package/dist/HttpRouter.d.ts +3 -0
  50. package/dist/HttpRouter.d.ts.map +1 -1
  51. package/dist/HttpRouter.js +29 -10
  52. package/dist/HttpRouter.js.map +1 -1
  53. package/dist/MiddlewareImpl.js +1 -1
  54. package/dist/MountInit.d.ts +31 -0
  55. package/dist/MountInit.d.ts.map +1 -0
  56. package/dist/MountInit.js +49 -0
  57. package/dist/MountInit.js.map +1 -0
  58. package/dist/MutationRunner.d.ts +1 -1
  59. package/dist/MutationRunner.d.ts.map +1 -1
  60. package/dist/MutationRunner.js +3 -3
  61. package/dist/MutationRunner.js.map +1 -1
  62. package/dist/MutationTransactionContext.d.ts.map +1 -1
  63. package/dist/MutationTransactionContext.js +4 -3
  64. package/dist/MutationTransactionContext.js.map +1 -1
  65. package/dist/OfficialComponent.d.ts +60 -0
  66. package/dist/OfficialComponent.d.ts.map +1 -0
  67. package/dist/OfficialComponent.js +72 -0
  68. package/dist/OfficialComponent.js.map +1 -0
  69. package/dist/OrderedQuery.d.ts +4 -5
  70. package/dist/OrderedQuery.d.ts.map +1 -1
  71. package/dist/OrderedQuery.js.map +1 -1
  72. package/dist/QueryInitializer.js +2 -2
  73. package/dist/QueryRunner.js +2 -2
  74. package/dist/QueryStream.d.ts +120 -12
  75. package/dist/QueryStream.d.ts.map +1 -1
  76. package/dist/QueryStream.js +143 -41
  77. package/dist/QueryStream.js.map +1 -1
  78. package/dist/QueryStreamCursor.js +1 -1
  79. package/dist/QueryStreamIndexPrefix.js +1 -1
  80. package/dist/QueryStreamIndexRange.js +2 -2
  81. package/dist/QueryStreamKey.js +1 -1
  82. package/dist/QueryStreamKeyBounds.js +2 -2
  83. package/dist/QueryStreamKeyLayout.js +2 -2
  84. package/dist/QueryStreamKeyValues.js +2 -2
  85. package/dist/QueryStreamPagination.js +1 -1
  86. package/dist/QueryStreamReadBudget.d.ts +3 -2
  87. package/dist/QueryStreamReadBudget.d.ts.map +1 -1
  88. package/dist/QueryStreamReadBudget.js +8 -5
  89. package/dist/QueryStreamReadBudget.js.map +1 -1
  90. package/dist/QueryTransactionContext.js +2 -2
  91. package/dist/RegisteredConvexFunction.d.ts +10 -5
  92. package/dist/RegisteredConvexFunction.d.ts.map +1 -1
  93. package/dist/RegisteredConvexFunction.js +45 -29
  94. package/dist/RegisteredConvexFunction.js.map +1 -1
  95. package/dist/RegisteredFunction.d.ts +39 -22
  96. package/dist/RegisteredFunction.d.ts.map +1 -1
  97. package/dist/RegisteredFunction.js +155 -42
  98. package/dist/RegisteredFunction.js.map +1 -1
  99. package/dist/RegisteredNodeFunction.d.ts +1 -1
  100. package/dist/RegisteredNodeFunction.d.ts.map +1 -1
  101. package/dist/RegisteredNodeFunction.js +10 -6
  102. package/dist/RegisteredNodeFunction.js.map +1 -1
  103. package/dist/RegistryItems.d.ts +7 -0
  104. package/dist/RegistryItems.d.ts.map +1 -1
  105. package/dist/RegistryItems.js +8 -3
  106. package/dist/RegistryItems.js.map +1 -1
  107. package/dist/RequestMetadata.js +1 -1
  108. package/dist/Scheduler.d.ts +1 -1
  109. package/dist/Scheduler.d.ts.map +1 -1
  110. package/dist/Scheduler.js +14 -13
  111. package/dist/Scheduler.js.map +1 -1
  112. package/dist/Storage.js +1 -1
  113. package/dist/StorageActionWriter.js +1 -1
  114. package/dist/StorageReader.js +1 -1
  115. package/dist/StorageWriter.js +1 -1
  116. package/dist/Table.d.ts +6 -6
  117. package/dist/Table.d.ts.map +1 -1
  118. package/dist/TableInfo.d.ts +1 -1
  119. package/dist/TableInfo.d.ts.map +1 -1
  120. package/dist/TableInfo.js.map +1 -1
  121. package/dist/TransactionMetadata.js +1 -1
  122. package/dist/VectorSearch.js +1 -1
  123. package/dist/index.d.ts +3 -0
  124. package/dist/index.d.ts.map +1 -1
  125. package/dist/index.js +21 -18
  126. package/dist/internal/AiGatewayDecisionClient.js +1 -1
  127. package/dist/internal/AiGatewayLanguageClient.js +1 -1
  128. package/dist/internal/AiGatewayServiceToken.js +1 -1
  129. package/dist/internal/DocumentPatch.d.ts +16 -0
  130. package/dist/internal/DocumentPatch.d.ts.map +1 -0
  131. package/dist/internal/DocumentPatch.js +36 -0
  132. package/dist/internal/DocumentPatch.js.map +1 -0
  133. package/dist/internal/httpBody.d.ts +13 -0
  134. package/dist/internal/httpBody.d.ts.map +1 -0
  135. package/dist/internal/httpBody.js +47 -0
  136. package/dist/internal/httpBody.js.map +1 -0
  137. package/dist/internal/httpOptions.d.ts +4 -0
  138. package/dist/internal/httpOptions.d.ts.map +1 -0
  139. package/dist/internal/httpOptions.js +83 -0
  140. package/dist/internal/httpOptions.js.map +1 -0
  141. package/dist/internal/observability.d.ts +5 -0
  142. package/dist/internal/observability.d.ts.map +1 -0
  143. package/dist/internal/observability.js +21 -0
  144. package/dist/internal/observability.js.map +1 -0
  145. package/dist/internal/reservedArgument.d.ts +8 -0
  146. package/dist/internal/reservedArgument.d.ts.map +1 -0
  147. package/dist/internal/reservedArgument.js +30 -0
  148. package/dist/internal/reservedArgument.js.map +1 -0
  149. package/package.json +5 -5
  150. package/src/ActionCall.ts +83 -0
  151. package/src/ActionRunner.ts +3 -2
  152. package/src/Auth.ts +49 -1
  153. package/src/Callback.ts +3 -2
  154. package/src/ConvexFunctionDefinitions.ts +2 -1
  155. package/src/CronJobs.ts +2 -1
  156. package/src/DatabaseWriter.ts +183 -25
  157. package/src/FunctionRegistryItem.ts +4 -0
  158. package/src/GroupImpl.ts +61 -8
  159. package/src/GroupRegistry.ts +7 -3
  160. package/src/Handler.ts +21 -5
  161. package/src/HttpRouter.ts +69 -5
  162. package/src/MountInit.ts +80 -0
  163. package/src/MutationRunner.ts +3 -2
  164. package/src/MutationTransactionContext.ts +2 -1
  165. package/src/OfficialComponent.ts +168 -0
  166. package/src/OrderedQuery.ts +4 -5
  167. package/src/QueryStream.ts +391 -61
  168. package/src/QueryStreamReadBudget.ts +19 -6
  169. package/src/RegisteredConvexFunction.ts +35 -2
  170. package/src/RegisteredFunction.ts +251 -45
  171. package/src/RegisteredNodeFunction.ts +11 -1
  172. package/src/RegistryItems.ts +31 -0
  173. package/src/Scheduler.ts +17 -19
  174. package/src/TableInfo.ts +2 -1
  175. package/src/index.ts +3 -0
  176. package/src/internal/DocumentPatch.ts +87 -0
  177. package/src/internal/httpBody.ts +72 -0
  178. package/src/internal/httpOptions.ts +154 -0
  179. package/src/internal/observability.ts +27 -0
  180. package/src/internal/reservedArgument.ts +56 -0
@@ -0,0 +1,13 @@
1
+ import type * as ByteSize from "effect/ByteSize";
2
+ import * as Effect from "effect/Effect";
3
+ import * as HttpServerRequest from "effect/http/HttpServerRequest";
4
+ import * as HttpServerResponse from "effect/http/HttpServerResponse";
5
+ /**
6
+ * Count the body before downstream middleware or decoding. Configure maxBytes
7
+ * from the endpoint's policy. Non-identity Content-Encoding receives 415. Read
8
+ * arrayBuffer in the wrapped effect to verify the same bytes the decoder uses.
9
+ */
10
+ export declare const withBodyLimit: <A, E, R>(effect: Effect.Effect<A, E, R>, options: {
11
+ readonly maxBytes: ByteSize.ByteSize;
12
+ }) => Effect.Effect<A | HttpServerResponse.HttpServerResponse, E, HttpServerRequest.HttpServerRequest | Exclude<R, HttpServerRequest.HttpServerRequest>>;
13
+ //# sourceMappingURL=httpBody.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"httpBody.d.ts","sourceRoot":"","sources":["../../src/internal/httpBody.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,KAAK,iBAAiB,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,kBAAkB,MAAM,gCAAgC,CAAC;AAOrE;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,UAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,WACrB;IAAE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAA;CAAE,uJAoD/C,CAAC"}
@@ -0,0 +1,47 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Schema from "effect/Schema";
3
+ import * as Stream from "effect/Stream";
4
+ import * as HttpServerRequest from "effect/http/HttpServerRequest";
5
+ import * as HttpServerResponse from "effect/http/HttpServerResponse";
6
+ //#region src/internal/httpBody.ts
7
+ var BodyTooLarge = class extends Schema.TaggedError()("BodyTooLarge", {}) {};
8
+ /**
9
+ * Count the body before downstream middleware or decoding. Configure maxBytes
10
+ * from the endpoint's policy. Non-identity Content-Encoding receives 415. Read
11
+ * arrayBuffer in the wrapped effect to verify the same bytes the decoder uses.
12
+ */
13
+ const withBodyLimit = (effect, options) => Effect.gen(function* () {
14
+ const request = yield* HttpServerRequest.HttpServerRequest;
15
+ const encoding = request.headers["content-encoding"]?.trim().toLowerCase();
16
+ if (encoding !== void 0 && encoding !== "identity") return HttpServerResponse.empty({ status: 415 });
17
+ let size = 0;
18
+ const chunks = [];
19
+ if (yield* (request.source instanceof Request && request.source.body === null ? Effect.void : Stream.runForEach(request.stream, (chunk) => {
20
+ size += chunk.byteLength;
21
+ if (BigInt(size) > options.maxBytes) return Effect.fail(new BodyTooLarge());
22
+ chunks.push(chunk);
23
+ return Effect.void;
24
+ })).pipe(Effect.as(false), Effect.catchTag("BodyTooLarge", () => Effect.succeed(true)), Effect.orDie)) return HttpServerResponse.empty({ status: 413 });
25
+ const bytes = new Uint8Array(size);
26
+ let offset = 0;
27
+ for (const chunk of chunks) {
28
+ bytes.set(chunk, offset);
29
+ offset += chunk.byteLength;
30
+ }
31
+ const source = new Request(request.originalUrl, {
32
+ method: request.method,
33
+ headers: request.headers,
34
+ ...request.method === "GET" || request.method === "HEAD" ? {} : { body: bytes }
35
+ });
36
+ source.arrayBuffer = () => Promise.resolve(bytes.buffer);
37
+ source.text = () => Promise.resolve(new TextDecoder().decode(bytes));
38
+ const buffered = HttpServerRequest.fromWeb(source).modify({
39
+ url: request.url,
40
+ remoteAddress: request.remoteAddress
41
+ });
42
+ return yield* Effect.provideService(effect, HttpServerRequest.HttpServerRequest, buffered);
43
+ });
44
+ //#endregion
45
+ export { withBodyLimit };
46
+
47
+ //# sourceMappingURL=httpBody.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"httpBody.js","names":[],"sources":["../../src/internal/httpBody.ts"],"sourcesContent":["import type * as ByteSize from \"effect/ByteSize\";\nimport * as Effect from \"effect/Effect\";\nimport * as Schema from \"effect/Schema\";\nimport * as Stream from \"effect/Stream\";\nimport * as HttpServerRequest from \"effect/http/HttpServerRequest\";\nimport * as HttpServerResponse from \"effect/http/HttpServerResponse\";\n\nclass BodyTooLarge extends Schema.TaggedError<BodyTooLarge>()(\n \"BodyTooLarge\",\n {},\n) {}\n\n/**\n * Count the body before downstream middleware or decoding. Configure maxBytes\n * from the endpoint's policy. Non-identity Content-Encoding receives 415. Read\n * arrayBuffer in the wrapped effect to verify the same bytes the decoder uses.\n */\nexport const withBodyLimit = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n options: { readonly maxBytes: ByteSize.ByteSize },\n) =>\n Effect.gen(function* () {\n const request = yield* HttpServerRequest.HttpServerRequest;\n const encoding = request.headers[\"content-encoding\"]?.trim().toLowerCase();\n if (encoding !== undefined && encoding !== \"identity\")\n return HttpServerResponse.empty({ status: 415 });\n let size = 0;\n const chunks: Array<Uint8Array> = [];\n const empty =\n request.source instanceof Request && request.source.body === null;\n const read = empty\n ? Effect.void\n : Stream.runForEach(request.stream, (chunk) => {\n size += chunk.byteLength;\n if (BigInt(size) > options.maxBytes)\n return Effect.fail(new BodyTooLarge());\n chunks.push(chunk);\n return Effect.void;\n });\n const limited = yield* read.pipe(\n Effect.as(false),\n Effect.catchTag(\"BodyTooLarge\", () => Effect.succeed(true)),\n Effect.orDie,\n );\n if (limited) return HttpServerResponse.empty({ status: 413 });\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n const source = new Request(request.originalUrl, {\n method: request.method,\n headers: request.headers,\n ...(request.method === \"GET\" || request.method === \"HEAD\"\n ? {}\n : { body: bytes }),\n });\n // WORKAROUND: Effect 4.0.4 caches text and bytes independently. Remove these\n // overrides when the minimum Effect version shares text and byte reads.\n source.arrayBuffer = () => Promise.resolve(bytes.buffer);\n source.text = () => Promise.resolve(new TextDecoder().decode(bytes));\n const buffered = HttpServerRequest.fromWeb(source).modify({\n url: request.url,\n remoteAddress: request.remoteAddress,\n });\n return yield* Effect.provideService(\n effect,\n HttpServerRequest.HttpServerRequest,\n buffered,\n );\n });\n"],"mappings":";;;;;;AAOA,IAAM,eAAN,cAA2B,OAAO,YAA0B,CAAC,CAC3D,gBACA,CAAC,CACH,CAAC,CAAC,CAAC;;;;;;AAOH,MAAa,iBACX,QACA,YAEA,OAAO,IAAI,aAAa;CACtB,MAAM,UAAU,OAAO,kBAAkB;CACzC,MAAM,WAAW,QAAQ,QAAQ,mBAAmB,EAAE,KAAK,CAAC,CAAC,YAAY;CACzE,IAAI,aAAa,KAAA,KAAa,aAAa,YACzC,OAAO,mBAAmB,MAAM,EAAE,QAAQ,IAAI,CAAC;CACjD,IAAI,OAAO;CACX,MAAM,SAA4B,CAAC;CAiBnC,IAAI,QAfF,QAAQ,kBAAkB,WAAW,QAAQ,OAAO,SAAS,OAE3D,OAAO,OACP,OAAO,WAAW,QAAQ,SAAS,UAAU;EAC3C,QAAQ,MAAM;EACd,IAAI,OAAO,IAAI,IAAI,QAAQ,UACzB,OAAO,OAAO,KAAK,IAAI,aAAa,CAAC;EACvC,OAAO,KAAK,KAAK;EACjB,OAAO,OAAO;CAChB,CAAC,EAAA,CACuB,KAC1B,OAAO,GAAG,KAAK,GACf,OAAO,SAAS,sBAAsB,OAAO,QAAQ,IAAI,CAAC,GAC1D,OAAO,KACT,GACa,OAAO,mBAAmB,MAAM,EAAE,QAAQ,IAAI,CAAC;CAC5D,MAAM,QAAQ,IAAI,WAAW,IAAI;CACjC,IAAI,SAAS;CACb,KAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,IAAI,OAAO,MAAM;EACvB,UAAU,MAAM;CAClB;CACA,MAAM,SAAS,IAAI,QAAQ,QAAQ,aAAa;EAC9C,QAAQ,QAAQ;EAChB,SAAS,QAAQ;EACjB,GAAI,QAAQ,WAAW,SAAS,QAAQ,WAAW,SAC/C,CAAC,IACD,EAAE,MAAM,MAAM;CACpB,CAAC;CAGD,OAAO,oBAAoB,QAAQ,QAAQ,MAAM,MAAM;CACvD,OAAO,aAAa,QAAQ,QAAQ,IAAI,YAAY,CAAC,CAAC,OAAO,KAAK,CAAC;CACnE,MAAM,WAAW,kBAAkB,QAAQ,MAAM,CAAC,CAAC,OAAO;EACxD,KAAK,QAAQ;EACb,eAAe,QAAQ;CACzB,CAAC;CACD,OAAO,OAAO,OAAO,eACnB,QACA,kBAAkB,mBAClB,QACF;AACF,CAAC"}
@@ -0,0 +1,4 @@
1
+ import * as Layer from "effect/Layer";
2
+ import * as HttpRouter from "effect/http/HttpRouter";
3
+ export declare const withOptions: <A, E, R>(routes: Layer.Layer<A, E, R>, endpoints: ReadonlySet<string>) => Layer.Layer<A, E, HttpRouter.HttpRouter | Exclude<R, HttpRouter.HttpRouter> | Exclude<HttpRouter.Request<"Error", any>, A> | Exclude<HttpRouter.Request<"Requires", any>, A>>;
4
+ //# sourceMappingURL=httpOptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"httpOptions.d.ts","sourceRoot":"","sources":["../../src/internal/httpOptions.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;AA2CrD,eAAO,MAAM,WAAW,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,UACzB,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,aACjB,WAAW,CAAC,MAAM,CAAC,kLAwG7B,CAAC"}
@@ -0,0 +1,83 @@
1
+ import * as Context from "effect/Context";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Layer from "effect/Layer";
4
+ import * as Exit from "effect/Exit";
5
+ import * as HttpRouter from "effect/http/HttpRouter";
6
+ import * as HttpServerError from "effect/http/HttpServerError";
7
+ import * as HttpServerRequest from "effect/http/HttpServerRequest";
8
+ //#region src/internal/httpOptions.ts
9
+ const notFound = Effect.flatMap(HttpServerRequest.HttpServerRequest, (request) => Effect.fail(new HttpServerError.HttpServerError({ reason: new HttpServerError.RouteNotFound({ request }) })));
10
+ const optional = /(\/:[^/()]*?)\?(\/?)/;
11
+ const forms = (path) => optional.test(path) ? [path.replace(optional, "$1$2"), path.replace(optional, "$2") || "/"] : [path];
12
+ const missingRouteContext = `Service not found: ${HttpRouter.RouteContext.key}`;
13
+ const preflight = (handler) => handler.pipe(Effect.updateContext(Context.omit(HttpRouter.RouteContext)), Effect.catchDefect((defect) => defect instanceof Error && defect.message === missingRouteContext ? notFound : Effect.die(defect)));
14
+ const withOptions = (routes, endpoints) => Layer.unwrap(Effect.gen(function* () {
15
+ const router = yield* HttpRouter.HttpRouter;
16
+ const registered = [];
17
+ const wrap = (target, prefix) => {
18
+ const addAll = (entries) => Effect.contextWith((context) => {
19
+ for (const route of entries) registered.push({
20
+ route,
21
+ prefix,
22
+ context
23
+ });
24
+ return target.addAll(entries);
25
+ });
26
+ return HttpRouter.HttpRouter.of({
27
+ ...target,
28
+ addAll,
29
+ add: (method, path, handler, options) => addAll([HttpRouter.route(method, path, handler, options)]),
30
+ prefixed: (next) => wrap(target.prefixed(next), `${prefix}${next.replace(/\/$/, "")}`)
31
+ });
32
+ };
33
+ const register = Effect.gen(function* () {
34
+ const byMethod = /* @__PURE__ */ new Map();
35
+ const first = yield* HttpRouter.make;
36
+ const explicit = yield* HttpRouter.make;
37
+ for (const { route, prefix, context } of registered) {
38
+ const at = (target) => prefix === "" ? target : target.prefixed(prefix);
39
+ if (route.method === "OPTIONS" || route.method === "*") {
40
+ yield* at(explicit).addAll([{
41
+ ...route,
42
+ handler: notFound
43
+ }]);
44
+ continue;
45
+ }
46
+ const copy = {
47
+ ...route,
48
+ method: "OPTIONS",
49
+ handler: endpoints.has(`${route.method} ${route.path}`) ? preflight(route.handler) : notFound
50
+ };
51
+ const candidate = byMethod.get(route.method) ?? (yield* HttpRouter.make);
52
+ byMethod.set(route.method, candidate);
53
+ yield* Effect.provideContext(at(candidate).addAll([copy]), context);
54
+ const placed = prefix === "" ? copy : HttpRouter.prefixRoute(copy, prefix);
55
+ for (const path of forms(placed.path)) {
56
+ const form = first.addAll([{
57
+ ...placed,
58
+ path
59
+ }]);
60
+ yield* Effect.exit(Effect.provideContext(form, context));
61
+ }
62
+ }
63
+ const get = byMethod.get("GET");
64
+ if (get !== void 0) {
65
+ const head = byMethod.get("HEAD") ?? (yield* HttpRouter.make);
66
+ byMethod.set("HEAD", head);
67
+ yield* Effect.exit(head.add("OPTIONS", "*", get.asHttpEffect()));
68
+ }
69
+ const claimed = yield* Effect.exit(explicit.add("OPTIONS", "*", notFound));
70
+ if (Exit.isFailure(claimed)) return;
71
+ const candidates = new Map(Array.from(byMethod, ([method, candidate]) => [method, candidate.asHttpEffect()]));
72
+ const fallback = first.asHttpEffect();
73
+ yield* router.add("OPTIONS", "*", Effect.flatMap(HttpServerRequest.HttpServerRequest, (request) => {
74
+ const method = request.headers["access-control-request-method"];
75
+ return method === void 0 ? fallback : candidates.get(method) ?? notFound;
76
+ }));
77
+ });
78
+ return Layer.effectDiscard(register).pipe(Layer.provideMerge(routes.pipe(Layer.provide(Layer.succeed(HttpRouter.HttpRouter, wrap(router, ""))))));
79
+ }));
80
+ //#endregion
81
+ export { withOptions };
82
+
83
+ //# sourceMappingURL=httpOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"httpOptions.js","names":[],"sources":["../../src/internal/httpOptions.ts"],"sourcesContent":["import * as Context from \"effect/Context\";\nimport * as Effect from \"effect/Effect\";\nimport * as Exit from \"effect/Exit\";\nimport * as Layer from \"effect/Layer\";\nimport * as HttpRouter from \"effect/http/HttpRouter\";\nimport * as HttpServerError from \"effect/http/HttpServerError\";\nimport * as HttpServerRequest from \"effect/http/HttpServerRequest\";\n\n/* oxlint-disable effecttsgo/any-unknown-in-error-context -- Preserve the router's erased request errors at the routing boundary. */\n\ntype Route = Parameters<HttpRouter.HttpRouter[\"addAll\"]>[0][number];\n\nconst notFound = Effect.flatMap(\n HttpServerRequest.HttpServerRequest,\n (request) =>\n Effect.fail(\n new HttpServerError.HttpServerError({\n reason: new HttpServerError.RouteNotFound({ request }),\n }),\n ),\n);\n\n// Effect's router adds `/a/:b` and `/a` for `/a/:b?` in one call, so an earlier\n// `/a/:id` rejects both. Split the same way, each form claims `first` alone.\nconst optional = /(\\/:[^/()]*?)\\?(\\/?)/;\nconst forms = (path: Route[\"path\"]) =>\n (optional.test(path)\n ? [path.replace(optional, \"$1$2\"), path.replace(optional, \"$2\") || \"/\"]\n : [path]) as ReadonlyArray<Route[\"path\"]>;\n\nconst missingRouteContext = `Service not found: ${HttpRouter.RouteContext.key}`;\n\n// WORKAROUND: Effect 4.0.4 compiles endpoint middleware, decoding and the\n// handler into one route handler. Its endpoint body reads RouteContext before\n// decoding or calling the handler, so without RouteContext a preflight that\n// middleware passes on stops there. Remove when Effect can run an endpoint's\n// middleware around another handler.\nconst preflight = (handler: Route[\"handler\"]) =>\n handler.pipe(\n Effect.updateContext(Context.omit(HttpRouter.RouteContext)),\n Effect.catchDefect((defect) =>\n defect instanceof Error && defect.message === missingRouteContext\n ? notFound\n : Effect.die(defect),\n ),\n );\n\nexport const withOptions = <A, E, R>(\n routes: Layer.Layer<A, E, R>,\n endpoints: ReadonlySet<string>,\n) =>\n Layer.unwrap(\n Effect.gen(function* () {\n const router = yield* HttpRouter.HttpRouter;\n const registered: Array<{\n readonly route: Route;\n readonly prefix: string;\n readonly context: Context.Context<never>;\n }> = [];\n const wrap = (\n target: HttpRouter.HttpRouter,\n prefix: string,\n ): HttpRouter.HttpRouter => {\n const addAll: HttpRouter.HttpRouter[\"addAll\"] = (entries) =>\n Effect.contextWith((context: Context.Context<never>) => {\n for (const route of entries)\n registered.push({ route, prefix, context });\n return target.addAll(entries);\n });\n return HttpRouter.HttpRouter.of({\n ...target,\n addAll,\n add: (method, path, handler, options) =>\n addAll([HttpRouter.route(method, path, handler, options)]),\n prefixed: (next) =>\n wrap(target.prefixed(next), `${prefix}${next.replace(/\\/$/, \"\")}`),\n });\n };\n const register = Effect.gen(function* () {\n // Effect's routers decide which paths match: one per declared method,\n // and `first`, which refuses a path equivalent to an earlier one.\n const byMethod = new Map<string, HttpRouter.HttpRouter>();\n const first = yield* HttpRouter.make;\n const explicit = yield* HttpRouter.make;\n for (const { route, prefix, context } of registered) {\n const at = (target: HttpRouter.HttpRouter) =>\n prefix === \"\" ? target : target.prefixed(prefix);\n if (route.method === \"OPTIONS\" || route.method === \"*\") {\n yield* at(explicit).addAll([{ ...route, handler: notFound }]);\n continue;\n }\n const copy: Route = {\n ...route,\n method: \"OPTIONS\",\n handler: endpoints.has(`${route.method} ${route.path}`)\n ? preflight(route.handler)\n : notFound,\n };\n const candidate =\n byMethod.get(route.method) ?? (yield* HttpRouter.make);\n byMethod.set(route.method, candidate);\n // Route registration erases request requirements, as in Effect's router.\n yield* Effect.provideContext(at(candidate).addAll([copy]), context);\n // Split the prefixed path: an optional parameter may sit in the prefix.\n const placed =\n prefix === \"\" ? copy : HttpRouter.prefixRoute(copy, prefix);\n for (const path of forms(placed.path)) {\n const form = first.addAll([{ ...placed, path }]);\n yield* Effect.exit(Effect.provideContext(form, context));\n }\n }\n // Effect's router answers HEAD from GET where no HEAD route matches. The\n // root wildcard matches last, unless a HEAD route already claims it.\n const get = byMethod.get(\"GET\");\n if (get !== undefined) {\n const head = byMethod.get(\"HEAD\") ?? (yield* HttpRouter.make);\n byMethod.set(\"HEAD\", head);\n yield* Effect.exit(head.add(\"OPTIONS\", \"*\", get.asHttpEffect()));\n }\n // An explicit OPTIONS route on the root wildcard answers every path.\n const claimed = yield* Effect.exit(\n explicit.add(\"OPTIONS\", \"*\", notFound),\n );\n if (Exit.isFailure(claimed)) return;\n const candidates = new Map(\n Array.from(byMethod, ([method, candidate]) => [\n method,\n candidate.asHttpEffect(),\n ]),\n );\n const fallback = first.asHttpEffect();\n // The root wildcard matches last, so explicit OPTIONS routes still win.\n yield* router.add(\n \"OPTIONS\",\n \"*\",\n Effect.flatMap(HttpServerRequest.HttpServerRequest, (request) => {\n const method = request.headers[\"access-control-request-method\"];\n return method === undefined\n ? fallback\n : (candidates.get(method) ?? notFound);\n }),\n );\n });\n return Layer.effectDiscard(register).pipe(\n Layer.provideMerge(\n routes.pipe(\n Layer.provide(\n Layer.succeed(HttpRouter.HttpRouter, wrap(router, \"\")),\n ),\n ),\n ),\n );\n }),\n );\n"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import * as Layer from "effect/Layer";
2
+ import * as Scope from "effect/Scope";
3
+ export declare const scope: Scope.Closeable;
4
+ export declare const memoized: (layer: Layer.Layer<never>) => Layer.Layer<never>;
5
+ //# sourceMappingURL=observability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observability.d.ts","sourceRoot":"","sources":["../../src/internal/observability.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAItC,eAAO,MAAM,KAAK,iBAAqB,CAAC;AAGxC,eAAO,MAAM,QAAQ,UAAW,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,KAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAerE,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { layer } from "../ConvexConfigProvider.js";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Layer from "effect/Layer";
4
+ import * as Duration from "effect/Duration";
5
+ import * as Exit from "effect/Exit";
6
+ import * as Scope from "effect/Scope";
7
+ //#region src/internal/observability.ts
8
+ const memoMap = Layer.makeMemoMapUnsafe();
9
+ const scope = Scope.makeUnsafe();
10
+ const layers = /* @__PURE__ */ new WeakMap();
11
+ const memoized = (layer$1) => {
12
+ const cached = layers.get(layer$1);
13
+ if (cached !== void 0) return cached;
14
+ const built = Layer.buildWithMemoMap(layer$1, memoMap, scope).pipe(Effect.provide(layer), Effect.cachedWithTTL((exit) => Exit.isSuccess(exit) ? Duration.infinity : Duration.zero), Effect.runSync, Effect.uninterruptible, Layer.effectContext);
15
+ layers.set(layer$1, built);
16
+ return built;
17
+ };
18
+ //#endregion
19
+ export { memoized, scope };
20
+
21
+ //# sourceMappingURL=observability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observability.js","names":["layer","ConvexConfigProvider.layer"],"sources":["../../src/internal/observability.ts"],"sourcesContent":["import * as Duration from \"effect/Duration\";\nimport * as Effect from \"effect/Effect\";\nimport * as Exit from \"effect/Exit\";\nimport * as Layer from \"effect/Layer\";\nimport * as Scope from \"effect/Scope\";\nimport * as ConvexConfigProvider from \"../ConvexConfigProvider.js\";\n\nconst memoMap = Layer.makeMemoMapUnsafe();\nexport const scope = Scope.makeUnsafe();\nconst layers = new WeakMap<Layer.Layer<never>, Layer.Layer<never>>();\n\nexport const memoized = (layer: Layer.Layer<never>): Layer.Layer<never> => {\n const cached = layers.get(layer);\n if (cached !== undefined) return cached;\n const built = Layer.buildWithMemoMap(layer, memoMap, scope).pipe(\n Effect.provide(ConvexConfigProvider.layer),\n // A failed first build is retried on the next invocation instead of failing every later one.\n Effect.cachedWithTTL((exit) =>\n Exit.isSuccess(exit) ? Duration.infinity : Duration.zero,\n ),\n Effect.runSync,\n Effect.uninterruptible,\n Layer.effectContext,\n );\n layers.set(layer, built);\n return built;\n};\n"],"mappings":";;;;;;;AAOA,MAAM,UAAU,MAAM,kBAAkB;AACxC,MAAa,QAAQ,MAAM,WAAW;AACtC,MAAM,yBAAS,IAAI,QAAgD;AAEnE,MAAa,YAAY,YAAkD;CACzE,MAAM,SAAS,OAAO,IAAIA,OAAK;CAC/B,IAAI,WAAW,KAAA,GAAW,OAAO;CACjC,MAAM,QAAQ,MAAM,iBAAiBA,SAAO,SAAS,KAAK,CAAC,CAAC,KAC1D,OAAO,QAAQC,KAA0B,GAEzC,OAAO,eAAe,SACpB,KAAK,UAAU,IAAI,IAAI,SAAS,WAAW,SAAS,IACtD,GACA,OAAO,SACP,OAAO,iBACP,MAAM,aACR;CACA,OAAO,IAAID,SAAO,KAAK;CACvB,OAAO;AACT"}
@@ -0,0 +1,8 @@
1
+ import * as Ref from "@confect/core/Ref";
2
+ import * as Context from "effect/Context";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Tracer from "effect/Tracer";
5
+ export declare const Forward: Context.Reference<((span: Tracer.Span) => unknown) | undefined>;
6
+ export declare const runWithCodec: <Ref_ extends Ref.Any>(ref: Ref_, args: Ref.Args<Ref_>, call: (native: Ref.FunctionReference<Ref_>, encoded: unknown) => PromiseLike<unknown>) => Effect.Effect<Ref.Returns<Ref_>, import("effect/Schema").SchemaError | Ref.Error<Ref_>, never>;
7
+ export declare const encodeArgs: <Ref_ extends Ref.Any>(ref: Ref_, args: Ref.Args<Ref_>) => Effect.Effect<unknown, never, never>;
8
+ //# sourceMappingURL=reservedArgument.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reservedArgument.d.ts","sourceRoot":"","sources":["../../src/internal/reservedArgument.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,GAAG,MAAM,mBAAmB,CAAC;AACzC,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,eAAO,MAAM,OAAO,4BACV,MAAM,CAAC,IAAI,KAAK,OAAO,cAG/B,CAAC;AAyBH,eAAO,MAAM,YAAY,GAAI,IAAI,SAAS,GAAG,CAAC,GAAG,OAC1C,IAAI,QACH,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QACd,CACJ,MAAM,EAAE,GAAG,CAAC,iBAAiB,CAAC,IAAI,CAAC,EACnC,OAAO,EAAE,OAAO,KACb,WAAW,CAAC,OAAO,CAAC,mGAMxB,CAAC;AAEJ,eAAO,MAAM,UAAU,GAAI,IAAI,SAAS,GAAG,CAAC,GAAG,OACxC,IAAI,QACH,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,yCAInB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { convexToJson } from "convex/values";
2
+ import * as Ref from "@confect/core/Ref";
3
+ import * as Context from "effect/Context";
4
+ import * as Effect from "effect/Effect";
5
+ import * as Tracer from "effect/Tracer";
6
+ //#region src/internal/reservedArgument.ts
7
+ const Forward = Context.Reference("@confect/server/RegisteredFunction/Forward", { defaultValue: () => void 0 });
8
+ const inject = (ref, encoded, context) => {
9
+ if (ref.reservedArgument === void 0 || ref.functionType === "query") return encoded;
10
+ const forward = Context.get(context, Forward);
11
+ const span = Context.getOrUndefined(context, Tracer.ParentSpan);
12
+ if (forward === void 0 || span?._tag !== "Span") return encoded;
13
+ try {
14
+ const value = forward(span);
15
+ if (value === void 0) return encoded;
16
+ convexToJson(value);
17
+ return {
18
+ ...encoded,
19
+ [ref.reservedArgument]: value
20
+ };
21
+ } catch {
22
+ return encoded;
23
+ }
24
+ };
25
+ const runWithCodec = (ref, args, call) => Effect.withFiber((fiber) => Ref.runWithCodec(ref, args, (native, encoded) => call(native, inject(ref, encoded, fiber.context))));
26
+ const encodeArgs = (ref, args) => Effect.withFiberSucceed((fiber) => inject(ref, Ref.encodeArgsSync(ref, args), fiber.context));
27
+ //#endregion
28
+ export { Forward, encodeArgs, runWithCodec };
29
+
30
+ //# sourceMappingURL=reservedArgument.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reservedArgument.js","names":[],"sources":["../../src/internal/reservedArgument.ts"],"sourcesContent":["import { convexToJson, type Value } from \"convex/values\";\nimport * as Ref from \"@confect/core/Ref\";\nimport * as Context from \"effect/Context\";\nimport * as Effect from \"effect/Effect\";\nimport * as Tracer from \"effect/Tracer\";\n\nexport const Forward = Context.Reference<\n ((span: Tracer.Span) => unknown) | undefined\n>(\"@confect/server/RegisteredFunction/Forward\", {\n defaultValue: () => undefined,\n});\n\nconst inject = (\n ref: Ref.Any,\n encoded: unknown,\n context: Context.Context<never>,\n): unknown => {\n if (ref.reservedArgument === undefined || ref.functionType === \"query\")\n return encoded;\n const forward = Context.get(context, Forward);\n const span = Context.getOrUndefined(context, Tracer.ParentSpan);\n if (forward === undefined || span?._tag !== \"Span\") return encoded;\n try {\n const value = forward(span);\n if (value === undefined) return encoded;\n convexToJson(value as Value);\n return {\n ...(encoded as Record<string, unknown>),\n [ref.reservedArgument]: value,\n };\n } catch {\n return encoded;\n }\n};\n\nexport const runWithCodec = <Ref_ extends Ref.Any>(\n ref: Ref_,\n args: Ref.Args<Ref_>,\n call: (\n native: Ref.FunctionReference<Ref_>,\n encoded: unknown,\n ) => PromiseLike<unknown>,\n) =>\n Effect.withFiber((fiber) =>\n Ref.runWithCodec(ref, args, (native, encoded) =>\n call(native, inject(ref, encoded, fiber.context)),\n ),\n );\n\nexport const encodeArgs = <Ref_ extends Ref.Any>(\n ref: Ref_,\n args: Ref.Args<Ref_>,\n) =>\n Effect.withFiberSucceed((fiber) =>\n inject(ref, Ref.encodeArgsSync(ref, args), fiber.context),\n );\n"],"mappings":";;;;;;AAMA,MAAa,UAAU,QAAQ,UAE7B,8CAA8C,EAC9C,oBAAoB,KAAA,EACtB,CAAC;AAED,MAAM,UACJ,KACA,SACA,YACY;CACZ,IAAI,IAAI,qBAAqB,KAAA,KAAa,IAAI,iBAAiB,SAC7D,OAAO;CACT,MAAM,UAAU,QAAQ,IAAI,SAAS,OAAO;CAC5C,MAAM,OAAO,QAAQ,eAAe,SAAS,OAAO,UAAU;CAC9D,IAAI,YAAY,KAAA,KAAa,MAAM,SAAS,QAAQ,OAAO;CAC3D,IAAI;EACF,MAAM,QAAQ,QAAQ,IAAI;EAC1B,IAAI,UAAU,KAAA,GAAW,OAAO;EAChC,aAAa,KAAc;EAC3B,OAAO;GACL,GAAI;IACH,IAAI,mBAAmB;EAC1B;CACF,QAAQ;EACN,OAAO;CACT;AACF;AAEA,MAAa,gBACX,KACA,MACA,SAKA,OAAO,WAAW,UAChB,IAAI,aAAa,KAAK,OAAO,QAAQ,YACnC,KAAK,QAAQ,OAAO,KAAK,SAAS,MAAM,OAAO,CAAC,CAClD,CACF;AAEF,MAAa,cACX,KACA,SAEA,OAAO,kBAAkB,UACvB,OAAO,KAAK,IAAI,eAAe,KAAK,IAAI,GAAG,MAAM,OAAO,CAC1D"}
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@gaganref/confect-server",
3
- "version": "10.3.1-fork.8",
3
+ "version": "10.3.1-fork.80",
4
4
  "dependencies": {
5
5
  "@effect/ai-openai-compat": "4.0.4",
6
6
  "@effect/ai-openrouter": "4.0.4"
7
7
  },
8
8
  "peerDependencies": {
9
- "@confect/core": "npm:@gaganref/confect-core@10.3.1-fork.8",
10
- "@effect/platform-node": "^4.0.0",
11
- "convex": "^1.45.0",
12
- "effect": "^4.0.4"
9
+ "@confect/core": "npm:@gaganref/confect-core@10.3.1-fork.80",
10
+ "@effect/platform-node": ">=4.0.0 <4.1.0",
11
+ "convex": "^1.49.0",
12
+ "effect": ">=4.0.4 <4.1.0"
13
13
  },
14
14
  "description": "Backend bindings to the Convex platform",
15
15
  "author": "RJ Dellecese",
@@ -0,0 +1,83 @@
1
+ import * as ReservedArgument from "./internal/reservedArgument.js";
2
+ import * as ActionCall from "@confect/core/ActionCall";
3
+ import type * as Ref from "@confect/core/Ref";
4
+ import type { FunctionReference } from "convex/server";
5
+ import * as Context from "effect/Context";
6
+ import * as Data from "effect/Data";
7
+ import * as Effect from "effect/Effect";
8
+ import * as ActionCtx from "./ActionCtx.js";
9
+ import * as ActionRunner from "./ActionRunner.js";
10
+ import type * as DatabaseSchema from "./DatabaseSchema.js";
11
+ import type * as DataModel from "./DataModel.js";
12
+ import type * as Handler from "./Handler.js";
13
+ import * as MiddlewareImpl from "./MiddlewareImpl.js";
14
+ import * as MutationRunner from "./MutationRunner.js";
15
+ import * as QueryRunner from "./QueryRunner.js";
16
+ import * as Scheduler from "./Scheduler.js";
17
+
18
+ export class ActionCallAlreadyUsed extends Data.TaggedError(
19
+ "ActionCallAlreadyUsed",
20
+ )<{}> {}
21
+ export class ActionCallNotUsed extends Data.TaggedError(
22
+ "ActionCallNotUsed",
23
+ )<{}> {}
24
+ export class MissingFunctionType extends Data.TaggedError(
25
+ "MissingFunctionType",
26
+ )<{}> {}
27
+ export class NestedActionNotAllowed extends Data.TaggedError(
28
+ "NestedActionNotAllowed",
29
+ )<{}> {}
30
+
31
+ export class SchedulingNotAllowed extends Data.TaggedError(
32
+ "SchedulingNotAllowed",
33
+ )<{}> {}
34
+
35
+ export const layer = <S extends DatabaseSchema.AnyWithProps>(schema: S) =>
36
+ MiddlewareImpl.make(schema, ActionCall.Middleware, (effect) =>
37
+ Effect.gen(function* () {
38
+ const ctx = yield* ActionCtx.ActionCtx<
39
+ DataModel.ToConvex<DataModel.FromSchema<S>>,
40
+ DatabaseSchema.Scope<S>
41
+ >();
42
+ let claimed = false;
43
+ const call: ActionCall.Call = <
44
+ Target extends Ref.AnyQuery | Ref.AnyMutation,
45
+ >(
46
+ ref: Target,
47
+ ...args: Ref.OptionalArgs<NoInfer<Target>>
48
+ ) =>
49
+ Effect.suspend(() => {
50
+ if (claimed) return Effect.die(new ActionCallAlreadyUsed());
51
+ claimed = true;
52
+ if (ref.functionType !== "query" && ref.functionType !== "mutation")
53
+ return Effect.die(new MissingFunctionType());
54
+ return ReservedArgument.runWithCodec(
55
+ ref,
56
+ (args[0] ?? {}) as Ref.Args<Target>,
57
+ (native, encoded) =>
58
+ ref.functionType === "query"
59
+ ? ctx.runQuery(
60
+ native as FunctionReference<"query">,
61
+ encoded as never,
62
+ )
63
+ : ctx.runMutation(
64
+ native as FunctionReference<"mutation">,
65
+ encoded as never,
66
+ ),
67
+ );
68
+ }).pipe(Effect.withSpan("ActionCall.call"));
69
+ return yield* effect.pipe(
70
+ Effect.provideService(ActionCall.ActionCall, call),
71
+ Effect.updateContext(
72
+ (context: Context.Context<Handler.ActionServices<S>>) =>
73
+ Context.omit(
74
+ QueryRunner.QueryRunner,
75
+ MutationRunner.MutationRunner,
76
+ ActionRunner.ActionRunner,
77
+ ActionCtx.ActionCtx(),
78
+ Scheduler.Scheduler,
79
+ )(context),
80
+ ),
81
+ );
82
+ }),
83
+ );
@@ -1,4 +1,5 @@
1
- import * as Ref from "@confect/core/Ref";
1
+ import * as ReservedArgument from "./internal/reservedArgument.js";
2
+ import type * as Ref from "@confect/core/Ref";
2
3
  import { type GenericActionCtx } from "convex/server";
3
4
  import * as Effect from "effect/Effect";
4
5
  import * as Context from "effect/Context";
@@ -18,7 +19,7 @@ const make = (runAction: GenericActionCtx<any>["runAction"]) => ({
18
19
  Ref.Error<Action> | Schema.SchemaError
19
20
  > =>
20
21
  run(
21
- Ref.runWithCodec(
22
+ ReservedArgument.runWithCodec(
22
23
  action,
23
24
  (args[0] ?? {}) as Ref.Args<Action>,
24
25
  (functionReference, encodedArgs) =>
package/src/Auth.ts CHANGED
@@ -1,4 +1,9 @@
1
- import type { Auth as ConvexAuth } from "convex/server";
1
+ import type {
2
+ Auth as ConvexAuth,
3
+ MutationAuth as ConvexMutationAuth,
4
+ SignJwtOptions,
5
+ UserIdentity,
6
+ } from "convex/server";
2
7
  import * as Context from "effect/Context";
3
8
  import { flow } from "effect/Function";
4
9
  import * as Effect from "effect/Effect";
@@ -26,8 +31,51 @@ export class Auth extends Context.Service<Auth, ReturnType<typeof make>>()(
26
31
  "@confect/server/Auth",
27
32
  ) {}
28
33
 
34
+ /**
35
+ * The outcome of Convex's identity verification for the current request.
36
+ */
37
+ export type Identity =
38
+ | { readonly _tag: "Absent" }
39
+ | { readonly _tag: "Valid"; readonly identity: UserIdentity }
40
+ | { readonly _tag: "Invalid" };
41
+
42
+ /**
43
+ * Read HTTP identity without failing for missing or rejected credentials.
44
+ * Convex verifies the credential. Rejected reads expose no token or error
45
+ * detail.
46
+ */
47
+ export const getUserIdentity: Effect.Effect<Identity, never, Auth> = Auth.pipe(
48
+ Effect.flatMap((auth) =>
49
+ auth.getUserIdentity.pipe(
50
+ Effect.map((identity): Identity => ({ _tag: "Valid", identity })),
51
+ Effect.catchTag("NoUserIdentityFoundError", () =>
52
+ Effect.succeed<Identity>({ _tag: "Absent" }),
53
+ ),
54
+ Effect.catchDefect(() => Effect.succeed<Identity>({ _tag: "Invalid" })),
55
+ ),
56
+ ),
57
+ );
58
+
29
59
  export const layer = (auth: ConvexAuth) => Layer.succeed(Auth, make(auth));
30
60
 
61
+ /**
62
+ * Mutation-only deployment signing, available in applications and components.
63
+ */
64
+ export class MutationAuth extends Context.Service<
65
+ MutationAuth,
66
+ {
67
+ readonly signJwt: (options: SignJwtOptions) => Effect.Effect<string>;
68
+ }
69
+ >()("@confect/server/Auth/MutationAuth") {}
70
+
71
+ /**
72
+ * SDK rejections remain defects, as with the other native auth operations.
73
+ */
74
+ export const mutationLayer = (auth: ConvexMutationAuth) =>
75
+ Layer.succeed(MutationAuth, {
76
+ signJwt: (options) => Effect.promise(() => auth.signJwt(options)),
77
+ });
78
+
31
79
  export type ForTarget<Target extends DatabaseSchema.Target> =
32
80
  Target["kind"] extends "component" ? never : Auth;
33
81
 
package/src/Callback.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as Callback from "@confect/core/Callback";
2
2
  import * as MiddlewareSpec from "@confect/core/MiddlewareSpec";
3
- import * as Ref from "@confect/core/Ref";
3
+ import type * as Ref from "@confect/core/Ref";
4
+ import { getFunctionReference } from "@confect/core/RefInternal";
4
5
  import {
5
6
  compileAst,
6
7
  UnsupportedPropertySignatureKeyTypeError,
@@ -305,7 +306,7 @@ export const create = Effect.fn("Callback.create")(function* <
305
306
  yield* Effect.fromResult(verify(contract, ref));
306
307
  }
307
308
  const text = yield* Effect.promise(() =>
308
- createFunctionHandle(Ref.getFunctionReference(ref)),
309
+ createFunctionHandle(getFunctionReference(ref)),
309
310
  );
310
311
  return yield* Schema.decodeEffect(Callback.handle(contract))(text).pipe(
311
312
  Effect.orDie,
@@ -63,7 +63,7 @@ export const buildForGroup = <Group extends GroupSpec.AnyWithProps>(
63
63
  databaseSchema: DatabaseSchema.AnyWithProps,
64
64
  groupLayer: Layer.Layer<GroupImpl.GroupImpl<"Finalized">>,
65
65
  ): ForGroup<Group> => {
66
- const { functionRegistryItems, middlewareRegistryItems } =
66
+ const { functionRegistryItems, middlewareRegistryItems, observability } =
67
67
  GroupRegistry.make(groupLayer);
68
68
  return mapLeaves<
69
69
  FunctionRegistryItem.AnyWithProps,
@@ -83,6 +83,7 @@ export const buildForGroup = <Group extends GroupSpec.AnyWithProps>(
83
83
  databaseSchema,
84
84
  confect,
85
85
  ResolvedMiddleware.resolve(confect, middlewareRegistryItems),
86
+ observability,
86
87
  ),
87
88
  ),
88
89
  Match.exhaustive,
package/src/CronJobs.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Ref } from "@confect/core";
2
+ import { getFunctionReference } from "@confect/core/RefInternal";
2
3
  import type { CronJob as ConvexCronJob } from "convex/server";
3
4
  import { cronJobs as makeConvexCrons, type Crons } from "convex/server";
4
5
  import { pipe } from "effect/Function";
@@ -35,7 +36,7 @@ const Proto = {
35
36
  crons: { ...this.convexCronJobs.crons },
36
37
  });
37
38
 
38
- const functionReference = Ref.getFunctionReference(cronJob.ref);
39
+ const functionReference = getFunctionReference(cronJob.ref);
39
40
  const encodedArgs = Ref.encodeArgsSync(cronJob.ref, cronJob.args);
40
41
 
41
42
  Match.value(cronJob.schedule).pipe(