@gaganref/confect-server 10.3.1-fork.9 → 10.3.1-fork.90
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/dist/ActionCall.d.ts +30 -0
- package/dist/ActionCall.d.ts.map +1 -0
- package/dist/ActionCall.js +41 -0
- package/dist/ActionCall.js.map +1 -0
- package/dist/ActionRunner.d.ts +1 -1
- package/dist/ActionRunner.d.ts.map +1 -1
- package/dist/ActionRunner.js +3 -3
- package/dist/ActionRunner.js.map +1 -1
- package/dist/AiGatewayDecisionClient.js +1 -1
- package/dist/AiGatewayLanguageClient.js +1 -1
- package/dist/Auth.d.ts +31 -2
- package/dist/Auth.d.ts.map +1 -1
- package/dist/Auth.js +23 -3
- package/dist/Auth.js.map +1 -1
- package/dist/Callback.d.ts +1 -1
- package/dist/Callback.d.ts.map +1 -1
- package/dist/Callback.js +6 -6
- package/dist/Callback.js.map +1 -1
- package/dist/ComponentCtx.d.ts +4 -0
- package/dist/ComponentCtx.d.ts.map +1 -1
- package/dist/ConvexConfigProvider.js +2 -2
- package/dist/ConvexFunctionDefinitions.d.ts.map +1 -1
- package/dist/ConvexFunctionDefinitions.js +4 -4
- package/dist/ConvexFunctionDefinitions.js.map +1 -1
- package/dist/ConvexLogger.js +1 -1
- package/dist/CronJobs.d.ts.map +1 -1
- package/dist/CronJobs.js +7 -6
- package/dist/CronJobs.js.map +1 -1
- package/dist/DatabaseSchema.js +2 -2
- package/dist/DatabaseWriter.d.ts +44 -2
- package/dist/DatabaseWriter.d.ts.map +1 -1
- package/dist/DatabaseWriter.js +59 -9
- package/dist/DatabaseWriter.js.map +1 -1
- package/dist/ExecutionMetadata.js +1 -1
- package/dist/FunctionImpl.js +2 -2
- package/dist/FunctionRegistryItem.d.ts +1 -0
- package/dist/FunctionRegistryItem.d.ts.map +1 -1
- package/dist/FunctionRegistryItem.js +2 -1
- package/dist/FunctionRegistryItem.js.map +1 -1
- package/dist/GroupImpl.d.ts +21 -2
- package/dist/GroupImpl.d.ts.map +1 -1
- package/dist/GroupImpl.js +21 -22
- package/dist/GroupImpl.js.map +1 -1
- package/dist/GroupRegistry.d.ts +1 -0
- package/dist/GroupRegistry.d.ts.map +1 -1
- package/dist/GroupRegistry.js +10 -3
- package/dist/GroupRegistry.js.map +1 -1
- package/dist/Handler.d.ts +8 -4
- package/dist/Handler.d.ts.map +1 -1
- package/dist/Handler.js.map +1 -1
- package/dist/HttpRouter.d.ts +3 -0
- package/dist/HttpRouter.d.ts.map +1 -1
- package/dist/HttpRouter.js +29 -10
- package/dist/HttpRouter.js.map +1 -1
- package/dist/MiddlewareImpl.js +1 -1
- package/dist/MountInit.d.ts +31 -0
- package/dist/MountInit.d.ts.map +1 -0
- package/dist/MountInit.js +49 -0
- package/dist/MountInit.js.map +1 -0
- package/dist/MutationRunner.d.ts +1 -1
- package/dist/MutationRunner.d.ts.map +1 -1
- package/dist/MutationRunner.js +3 -3
- package/dist/MutationRunner.js.map +1 -1
- package/dist/MutationTransactionContext.d.ts.map +1 -1
- package/dist/MutationTransactionContext.js +4 -3
- package/dist/MutationTransactionContext.js.map +1 -1
- package/dist/OfficialComponent.d.ts +60 -0
- package/dist/OfficialComponent.d.ts.map +1 -0
- package/dist/OfficialComponent.js +72 -0
- package/dist/OfficialComponent.js.map +1 -0
- package/dist/OrderedQuery.d.ts +4 -5
- package/dist/OrderedQuery.d.ts.map +1 -1
- package/dist/OrderedQuery.js.map +1 -1
- package/dist/QueryInitializer.js +2 -2
- package/dist/QueryRunner.js +2 -2
- package/dist/QueryStream.d.ts +120 -12
- package/dist/QueryStream.d.ts.map +1 -1
- package/dist/QueryStream.js +143 -41
- package/dist/QueryStream.js.map +1 -1
- package/dist/QueryStreamCursor.js +1 -1
- package/dist/QueryStreamIndexPrefix.js +1 -1
- package/dist/QueryStreamIndexRange.js +2 -2
- package/dist/QueryStreamKey.js +1 -1
- package/dist/QueryStreamKeyBounds.js +2 -2
- package/dist/QueryStreamKeyLayout.js +2 -2
- package/dist/QueryStreamKeyValues.js +2 -2
- package/dist/QueryStreamPagination.js +1 -1
- package/dist/QueryStreamReadBudget.d.ts +3 -2
- package/dist/QueryStreamReadBudget.d.ts.map +1 -1
- package/dist/QueryStreamReadBudget.js +8 -5
- package/dist/QueryStreamReadBudget.js.map +1 -1
- package/dist/QueryTransactionContext.js +2 -2
- package/dist/RegisteredConvexFunction.d.ts +10 -5
- package/dist/RegisteredConvexFunction.d.ts.map +1 -1
- package/dist/RegisteredConvexFunction.js +49 -29
- package/dist/RegisteredConvexFunction.js.map +1 -1
- package/dist/RegisteredFunction.d.ts +48 -22
- package/dist/RegisteredFunction.d.ts.map +1 -1
- package/dist/RegisteredFunction.js +163 -42
- package/dist/RegisteredFunction.js.map +1 -1
- package/dist/RegisteredNodeFunction.d.ts +1 -1
- package/dist/RegisteredNodeFunction.d.ts.map +1 -1
- package/dist/RegisteredNodeFunction.js +10 -6
- package/dist/RegisteredNodeFunction.js.map +1 -1
- package/dist/RegistryItems.d.ts +7 -0
- package/dist/RegistryItems.d.ts.map +1 -1
- package/dist/RegistryItems.js +8 -3
- package/dist/RegistryItems.js.map +1 -1
- package/dist/RequestMetadata.js +1 -1
- package/dist/Scheduler.d.ts +1 -1
- package/dist/Scheduler.d.ts.map +1 -1
- package/dist/Scheduler.js +14 -13
- package/dist/Scheduler.js.map +1 -1
- package/dist/Storage.js +1 -1
- package/dist/StorageActionWriter.js +1 -1
- package/dist/StorageReader.js +1 -1
- package/dist/StorageWriter.js +1 -1
- package/dist/Table.d.ts +6 -6
- package/dist/Table.d.ts.map +1 -1
- package/dist/TableInfo.d.ts +7 -7
- package/dist/TableInfo.d.ts.map +1 -1
- package/dist/TableInfo.js.map +1 -1
- package/dist/TransactionMetadata.js +1 -1
- package/dist/VectorSearch.js +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -18
- package/dist/internal/AiGatewayDecisionClient.js +1 -1
- package/dist/internal/AiGatewayLanguageClient.js +1 -1
- package/dist/internal/AiGatewayServiceToken.js +1 -1
- package/dist/internal/DocumentPatch.d.ts +16 -0
- package/dist/internal/DocumentPatch.d.ts.map +1 -0
- package/dist/internal/DocumentPatch.js +36 -0
- package/dist/internal/DocumentPatch.js.map +1 -0
- package/dist/internal/httpBody.d.ts +13 -0
- package/dist/internal/httpBody.d.ts.map +1 -0
- package/dist/internal/httpBody.js +47 -0
- package/dist/internal/httpBody.js.map +1 -0
- package/dist/internal/httpOptions.d.ts +4 -0
- package/dist/internal/httpOptions.d.ts.map +1 -0
- package/dist/internal/httpOptions.js +83 -0
- package/dist/internal/httpOptions.js.map +1 -0
- package/dist/internal/observability.d.ts +5 -0
- package/dist/internal/observability.d.ts.map +1 -0
- package/dist/internal/observability.js +21 -0
- package/dist/internal/observability.js.map +1 -0
- package/dist/internal/reservedArgument.d.ts +8 -0
- package/dist/internal/reservedArgument.d.ts.map +1 -0
- package/dist/internal/reservedArgument.js +30 -0
- package/dist/internal/reservedArgument.js.map +1 -0
- package/package.json +5 -5
- package/src/ActionCall.ts +83 -0
- package/src/ActionRunner.ts +3 -2
- package/src/Auth.ts +49 -1
- package/src/Callback.ts +3 -2
- package/src/ComponentCtx.ts +2 -0
- package/src/ConvexFunctionDefinitions.ts +2 -1
- package/src/CronJobs.ts +2 -1
- package/src/DatabaseWriter.ts +190 -26
- package/src/FunctionRegistryItem.ts +4 -0
- package/src/GroupImpl.ts +61 -8
- package/src/GroupRegistry.ts +7 -3
- package/src/Handler.ts +21 -5
- package/src/HttpRouter.ts +69 -5
- package/src/MountInit.ts +80 -0
- package/src/MutationRunner.ts +3 -2
- package/src/MutationTransactionContext.ts +2 -1
- package/src/OfficialComponent.ts +168 -0
- package/src/OrderedQuery.ts +4 -5
- package/src/QueryStream.ts +391 -61
- package/src/QueryStreamReadBudget.ts +19 -6
- package/src/RegisteredConvexFunction.ts +39 -2
- package/src/RegisteredFunction.ts +305 -49
- package/src/RegisteredNodeFunction.ts +11 -1
- package/src/RegistryItems.ts +31 -0
- package/src/Scheduler.ts +17 -19
- package/src/TableInfo.ts +18 -22
- package/src/index.ts +3 -0
- package/src/internal/DocumentPatch.ts +87 -0
- package/src/internal/httpBody.ts +72 -0
- package/src/internal/httpOptions.ts +154 -0
- package/src/internal/observability.ts +27 -0
- package/src/internal/reservedArgument.ts +56 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DocumentPatch.js","names":[],"sources":["../../src/internal/DocumentPatch.ts"],"sourcesContent":["import type { ReadonlyValue } from \"@confect/core/SchemaToValidator\";\nimport { pipe } from \"effect/Function\";\nimport * as Effect from \"effect/Effect\";\nimport * as Record from \"effect/Record\";\nimport * as Schema from \"effect/Schema\";\nimport * as SchemaAST from \"effect/SchemaAST\";\nimport type * as Table from \"../Table.js\";\n\nexport type EncodedPatch = Record.ReadonlyRecord<\n string,\n ReadonlyValue | undefined\n>;\n\nexport type PatchEncoder = (\n patch: Record.ReadonlyRecord<string, unknown>,\n) => Effect.Effect<EncodedPatch, Schema.SchemaError>;\n\nconst patchEncoders = new WeakMap<Table.AnyWithProps, PatchEncoder | null>();\n\n/**\n * Returns the encoder for patches to the table's documents, or `undefined` when\n * the table's codec does not encode each field independently. The encoder maps\n * every patched field of the table to its encoded value, or to `undefined` when\n * the patch unsets the field or the field's codec encodes the value as an\n * absent key. Keys outside the table's fields are left out.\n */\nexport const encoder = (\n table: Table.AnyWithProps,\n): PatchEncoder | undefined => {\n let cached = patchEncoders.get(table);\n if (cached === undefined) {\n cached = makePatchEncoder(table);\n patchEncoders.set(table, cached);\n }\n return cached ?? undefined;\n};\n\n// A struct with no encoding of its own encodes each field through that field's\n// codec alone, so a patch encodes field by field. A union or a transformation\n// over the whole struct can make one field's encoding depend on another field.\n// A struct-level check must see the decoded fields before they are encoded,\n// and keys under an index signature have no field codec of their own.\nconst makePatchEncoder = (table: Table.AnyWithProps): PatchEncoder | null => {\n const ast = table.Fields.ast;\n if (\n !SchemaAST.isObjects(ast) ||\n ast.encoding !== undefined ||\n ast.checks !== undefined ||\n ast.indexSignatures.length > 0\n ) {\n return null;\n }\n // A field's codec runs only when the patch gives the field a value, since a\n // codec can handle a missing key. Each comes from the table, whose codecs\n // need no services.\n const fieldEncoders: Record.ReadonlyRecord<\n string,\n (\n value: unknown,\n ) => Effect.Effect<ReadonlyValue | undefined, Schema.SchemaError>\n > = Object.fromEntries(\n ast.propertySignatures.map(({ name, type }) => {\n const key = String(name);\n const encode = Schema.encodeUnknownEffect(\n Schema.Struct({\n [key]: Schema.optionalKey(\n Schema.make<Schema.Codec<unknown, ReadonlyValue>>(type),\n ),\n }),\n );\n return [\n key,\n (value: unknown) =>\n Effect.map(encode({ [key]: value }), (encoded) => encoded[key]),\n ];\n }),\n );\n return (patch) =>\n pipe(\n fieldEncoders,\n Record.filter((_, name) => Object.hasOwn(patch, name)),\n Record.map((encode, name) =>\n patch[name] === undefined ? Effect.undefined : encode(patch[name]),\n ),\n Effect.all,\n );\n};\n"],"mappings":";;;;;;AAiBA,MAAM,gCAAgB,IAAI,QAAiD;;;;;;;;AAS3E,MAAa,WACX,UAC6B;CAC7B,IAAI,SAAS,cAAc,IAAI,KAAK;CACpC,IAAI,WAAW,KAAA,GAAW;EACxB,SAAS,iBAAiB,KAAK;EAC/B,cAAc,IAAI,OAAO,MAAM;CACjC;CACA,OAAO,UAAU,KAAA;AACnB;AAOA,MAAM,oBAAoB,UAAmD;CAC3E,MAAM,MAAM,MAAM,OAAO;CACzB,IACE,CAAC,UAAU,UAAU,GAAG,KACxB,IAAI,aAAa,KAAA,KACjB,IAAI,WAAW,KAAA,KACf,IAAI,gBAAgB,SAAS,GAE7B,OAAO;CAKT,MAAM,gBAKF,OAAO,YACT,IAAI,mBAAmB,KAAK,EAAE,MAAM,WAAW;EAC7C,MAAM,MAAM,OAAO,IAAI;EACvB,MAAM,SAAS,OAAO,oBACpB,OAAO,OAAO,GACX,MAAM,OAAO,YACZ,OAAO,KAA2C,IAAI,CACxD,EACF,CAAC,CACH;EACA,OAAO,CACL,MACC,UACC,OAAO,IAAI,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,YAAY,QAAQ,IAAI,CAClE;CACF,CAAC,CACH;CACA,QAAQ,UACN,KACE,eACA,OAAO,QAAQ,GAAG,SAAS,OAAO,OAAO,OAAO,IAAI,CAAC,GACrD,OAAO,KAAK,QAAQ,SAClB,MAAM,UAAU,KAAA,IAAY,OAAO,YAAY,OAAO,MAAM,KAAK,CACnE,GACA,OAAO,GACT;AACJ"}
|
|
@@ -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 @@
|
|
|
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.
|
|
3
|
+
"version": "10.3.1-fork.90",
|
|
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.
|
|
10
|
-
"@effect/platform-node": "
|
|
11
|
-
"convex": "^1.
|
|
12
|
-
"effect": "
|
|
9
|
+
"@confect/core": "npm:@gaganref/confect-core@10.3.1-fork.90",
|
|
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
|
+
);
|
package/src/ActionRunner.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import * as
|
|
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
|
-
|
|
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 {
|
|
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(
|
|
309
|
+
createFunctionHandle(getFunctionReference(ref)),
|
|
309
310
|
);
|
|
310
311
|
return yield* Schema.decodeEffect(Callback.handle(contract))(text).pipe(
|
|
311
312
|
Effect.orDie,
|
package/src/ComponentCtx.ts
CHANGED
|
@@ -17,6 +17,7 @@ import type {
|
|
|
17
17
|
VectorIndexNames,
|
|
18
18
|
VectorSearchQuery,
|
|
19
19
|
} from "convex/server";
|
|
20
|
+
import type { CommitTsPlaceholder } from "convex/values";
|
|
20
21
|
import type { PatchValue } from "./DatabaseWriter.js";
|
|
21
22
|
|
|
22
23
|
/**
|
|
@@ -104,6 +105,7 @@ export interface DatabaseWriter<
|
|
|
104
105
|
delete<TableName extends TableNamesInDataModel<DataModel>>(
|
|
105
106
|
id: GenericId<TableName, Scope>,
|
|
106
107
|
): Promise<void>;
|
|
108
|
+
readonly vars: { readonly commitTs: CommitTsPlaceholder };
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
export interface StorageReader<Scope extends IdScope.IdScope> {
|
|
@@ -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 =
|
|
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(
|