@superpanel-sdk/runtime 0.2.3 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -10
- package/dist/builder/codegen/emit.d.ts +25 -12
- package/dist/builder/codegen/emit.js +339 -78
- package/dist/builder/codegen/generate.d.ts +21 -2
- package/dist/builder/codegen/generate.js +147 -34
- package/dist/builder/company-import-graph.d.ts +2 -0
- package/dist/builder/company-import-graph.js +40 -8
- package/dist/builder/company-imports.d.ts +29 -0
- package/dist/builder/company-imports.js +122 -0
- package/dist/builder/compile/compile-sequence.d.ts +61 -8
- package/dist/builder/compile/compile-sequence.js +334 -80
- package/dist/builder/compile/function-code.d.ts +19 -3
- package/dist/builder/compile/function-code.js +123 -45
- package/dist/builder/compile/registry.d.ts +7 -3
- package/dist/builder/compile/registry.js +30 -27
- package/dist/builder/errors.d.ts +9 -0
- package/dist/builder/errors.js +17 -0
- package/dist/builder/function-params.d.ts +10 -0
- package/dist/builder/function-params.js +203 -0
- package/dist/builder/load.d.ts +70 -10
- package/dist/builder/load.js +258 -67
- package/dist/builder/paths.d.ts +9 -1
- package/dist/builder/paths.js +32 -2
- package/dist/builder/schedules.d.ts +25 -0
- package/dist/builder/schedules.js +101 -0
- package/dist/builder/slot-schema-validation.d.ts +4 -0
- package/dist/builder/slot-schema-validation.js +10 -0
- package/dist/builder/typecheck.d.ts +8 -0
- package/dist/builder/typecheck.js +102 -0
- package/dist/builder/types.d.ts +127 -19
- package/dist/builder/types.js +21 -1
- package/dist/cli/auth/auth.d.ts +37 -0
- package/dist/cli/auth/auth.js +211 -0
- package/dist/cli/auth/backend-url.d.ts +5 -0
- package/dist/cli/auth/backend-url.js +25 -0
- package/dist/cli/auth/clipboard.d.ts +9 -0
- package/dist/cli/auth/clipboard.js +38 -0
- package/dist/cli/auth/http.d.ts +20 -0
- package/dist/cli/auth/http.js +27 -0
- package/dist/cli/auth/index.d.ts +10 -0
- package/dist/cli/auth/index.js +27 -0
- package/dist/cli/auth/progress.d.ts +12 -0
- package/dist/cli/auth/progress.js +15 -0
- package/dist/cli/auth/serve-login.d.ts +8 -0
- package/dist/cli/auth/serve-login.js +24 -0
- package/dist/cli/calls/index.d.ts +177 -0
- package/dist/cli/calls/index.js +96 -0
- package/dist/cli/compile/index.js +3 -0
- package/dist/cli/config.d.ts +10 -0
- package/dist/cli/config.js +52 -0
- package/dist/cli/debug/index.d.ts +31 -0
- package/dist/cli/debug/index.js +119 -0
- package/dist/cli/exec/index.d.ts +39 -0
- package/dist/cli/exec/index.js +138 -0
- package/dist/cli/exec/session.d.ts +48 -0
- package/dist/cli/exec/session.js +82 -0
- package/dist/cli/exec/trace.d.ts +18 -0
- package/dist/cli/exec/trace.js +52 -0
- package/dist/cli/index.js +112 -9
- package/dist/cli/logs/index.d.ts +47 -0
- package/dist/cli/logs/index.js +113 -0
- package/dist/cli/mobile/index.d.ts +12 -0
- package/dist/cli/mobile/index.js +405 -0
- package/dist/cli/serve/index.d.ts +109 -3
- package/dist/cli/serve/index.js +506 -118
- package/dist/cli/turns/index.d.ts +105 -0
- package/dist/cli/turns/index.js +128 -0
- package/dist/cli/turns/run.d.ts +13 -0
- package/dist/cli/turns/run.js +57 -0
- package/dist/cli/turns/shadow.d.ts +112 -0
- package/dist/cli/turns/shadow.js +54 -0
- package/dist/cli/type-gen/index.js +9 -9
- package/dist/compiler.d.ts +7 -0
- package/dist/compiler.js +7 -0
- package/dist/compute-host/compute-host.d.ts +14 -23
- package/dist/compute-host/compute-host.js +18 -30
- package/dist/compute-host/index.d.ts +2 -4
- package/dist/compute-host/index.js +1 -2
- package/dist/compute-host/source-compute-host.d.ts +10 -10
- package/dist/compute-host/source-compute-host.js +33 -40
- package/dist/core/case-orchestrator/contact-hours.d.ts +70 -0
- package/dist/core/case-orchestrator/contact-hours.js +127 -0
- package/dist/core/case-orchestrator/index.d.ts +3 -0
- package/dist/core/case-orchestrator/index.js +3 -0
- package/dist/core/case-orchestrator/render.d.ts +75 -0
- package/dist/core/case-orchestrator/render.js +244 -0
- package/dist/core/case-orchestrator/time.d.ts +11 -0
- package/dist/core/case-orchestrator/time.js +29 -0
- package/dist/core/case-orchestrator/types.d.ts +708 -0
- package/dist/core/case-orchestrator/types.js +42 -0
- package/dist/core/context/call.d.ts +291 -0
- package/dist/core/context/call.js +94 -0
- package/dist/core/context/channels.d.ts +60 -0
- package/dist/core/context/channels.js +35 -0
- package/dist/core/context/contact.d.ts +96 -6
- package/dist/core/context/contact.js +48 -2
- package/dist/core/context/email-message.d.ts +198 -0
- package/dist/core/context/email-message.js +86 -0
- package/dist/core/context/email.d.ts +109 -0
- package/dist/core/context/email.js +90 -0
- package/dist/core/context/exchanges.d.ts +167 -0
- package/dist/core/context/exchanges.js +81 -0
- package/dist/core/context/instances.d.ts +307 -0
- package/dist/core/context/instances.js +137 -0
- package/dist/core/context/kv.d.ts +113 -0
- package/dist/core/context/kv.js +60 -0
- package/dist/core/context/platform-registry.d.ts +544 -4
- package/dist/core/context/platform-registry.js +14 -2
- package/dist/core/context/platform.d.ts +2 -1
- package/dist/core/context/sms.d.ts +177 -0
- package/dist/core/context/sms.js +77 -0
- package/dist/core/context/types.d.ts +79 -48
- package/dist/core/context/types.js +1 -7
- package/dist/core/conversation/index.d.ts +85 -0
- package/dist/core/conversation/index.js +133 -0
- package/dist/core/functions/errors.d.ts +74 -0
- package/dist/core/functions/errors.js +26 -0
- package/dist/core/functions/events.d.ts +192 -0
- package/dist/core/functions/events.js +23 -0
- package/dist/core/functions/schedules.d.ts +50 -0
- package/dist/core/functions/schedules.js +20 -0
- package/dist/core/functions/types.d.ts +29 -73
- package/dist/core/functions/types.js +1 -4
- package/dist/core/office-hours/index.d.ts +39 -0
- package/dist/core/office-hours/index.js +187 -0
- package/dist/core/page/define.d.ts +904 -0
- package/dist/core/page/define.js +518 -0
- package/dist/core/page/envelope.d.ts +55 -0
- package/dist/core/page/envelope.js +4 -0
- package/dist/core/page/fns.d.ts +448 -0
- package/dist/core/page/fns.js +539 -0
- package/dist/core/page/memory-reader.d.ts +27 -0
- package/dist/core/page/memory-reader.js +299 -0
- package/dist/core/page/ops.d.ts +58 -0
- package/dist/core/page/ops.js +220 -0
- package/dist/core/page/page-host.d.ts +20 -0
- package/dist/core/page/page-host.js +57 -0
- package/dist/core/page/records-query.d.ts +234 -0
- package/dist/core/page/records-query.js +780 -0
- package/dist/core/page/render.d.ts +295 -0
- package/dist/core/page/render.js +1060 -0
- package/dist/core/page/sandbox.d.ts +85 -0
- package/dist/core/page/sandbox.js +357 -0
- package/dist/core/page/time-format.d.ts +46 -0
- package/dist/core/page/time-format.js +125 -0
- package/dist/core/page/timeline.d.ts +40 -0
- package/dist/core/page/timeline.js +2 -0
- package/dist/core/page/typed.d.ts +648 -0
- package/dist/core/page/typed.js +2 -0
- package/dist/core/page/workspace.d.ts +57 -0
- package/dist/core/page/workspace.js +266 -0
- package/dist/core/party/index.d.ts +3 -0
- package/dist/core/party/index.js +3 -0
- package/dist/core/party/schema.d.ts +208 -0
- package/dist/core/party/schema.js +113 -0
- package/dist/core/party/types.d.ts +35 -0
- package/dist/core/party/types.js +15 -0
- package/dist/core/sequence/define.d.ts +56 -0
- package/dist/core/sequence/define.js +10 -0
- package/dist/core/sequence/index.d.ts +63 -0
- package/dist/core/sequence/index.js +231 -0
- package/dist/core/slot/binding.d.ts +40 -0
- package/dist/core/slot/binding.js +2 -0
- package/dist/core/slot/company-metadata.d.ts +102 -0
- package/dist/core/slot/company-metadata.js +536 -0
- package/dist/core/slot/compile-schema.d.ts +19 -13
- package/dist/core/slot/compile-schema.js +51 -248
- package/dist/core/slot/contact-timezone.d.ts +110 -0
- package/dist/core/slot/contact-timezone.js +186 -0
- package/dist/core/slot/field.d.ts +2 -25
- package/dist/core/slot/field.js +0 -71
- package/dist/core/slot/id-ref.d.ts +17 -2
- package/dist/core/slot/id-ref.js +16 -8
- package/dist/core/slot/index.d.ts +12 -13
- package/dist/core/slot/index.js +11 -12
- package/dist/core/slot/naming.d.ts +15 -0
- package/dist/core/slot/naming.js +96 -0
- package/dist/core/slot/platform-fields.d.ts +119 -0
- package/dist/core/slot/platform-fields.js +121 -0
- package/dist/core/slot/ref.d.ts +16 -0
- package/dist/core/slot/ref.js +14 -0
- package/dist/core/slot/row.d.ts +2 -9
- package/dist/core/slot/row.js +13 -23
- package/dist/core/slot/schema-compat.d.ts +17 -0
- package/dist/core/slot/schema-compat.js +103 -0
- package/dist/core/slot/schema.d.ts +353 -76
- package/dist/core/slot/schema.js +163 -10
- package/dist/core/slot/types.d.ts +30 -103
- package/dist/core/slot/value.d.ts +28 -3
- package/dist/core/slot/value.js +93 -57
- package/dist/dev-overlay/protocol.d.ts +74 -8
- package/dist/fn-context/build-context.d.ts +3 -1
- package/dist/fn-context/build-context.js +26 -10
- package/dist/fn-context/fake/empty-api.js +9 -28
- package/dist/fn-context/fake/index.d.ts +13 -4
- package/dist/fn-context/fake/index.js +29 -2
- package/dist/fn-context/fn-params.d.ts +3 -0
- package/dist/fn-context/fn-params.js +10 -0
- package/dist/fn-context/index.d.ts +5 -5
- package/dist/fn-context/index.js +4 -4
- package/dist/fn-context/log.js +2 -2
- package/dist/fn-context/make-ctx.d.ts +11 -0
- package/dist/fn-context/make-ctx.js +20 -9
- package/dist/fn-context/rpc/case-orchestrator-tools.d.ts +32 -0
- package/dist/fn-context/rpc/case-orchestrator-tools.js +12 -0
- package/dist/fn-context/rpc/errors.d.ts +13 -0
- package/dist/fn-context/rpc/errors.js +22 -0
- package/dist/fn-context/rpc/index.d.ts +4 -2
- package/dist/fn-context/rpc/index.js +4 -2
- package/dist/fn-context/rpc/integration/index.d.ts +15 -5
- package/dist/fn-context/rpc/integration/index.js +1 -1
- package/dist/fn-context/rpc/integration/list-surfaces.d.ts +21 -0
- package/dist/fn-context/rpc/integration/{list-bindings.js → list-surfaces.js} +4 -4
- package/dist/fn-context/rpc/log.d.ts +11 -1
- package/dist/fn-context/rpc/platform.d.ts +13 -3
- package/dist/fn-context/rpc/platform.js +1 -1
- package/dist/fn-context/rpc/records.d.ts +85 -0
- package/dist/fn-context/rpc/records.js +24 -0
- package/dist/fn-context/rpc/trpc-client.d.ts +44 -2
- package/dist/fn-context/rpc/trpc-client.js +222 -12
- package/dist/fn-context/rpc/trpc-init.d.ts +21 -3
- package/dist/fn-context/rpc/trpc-init.js +10 -4
- package/dist/fn-context/rpc/trpc-router-factory.d.ts +111 -7
- package/dist/fn-context/rpc/trpc-router-factory.js +2 -0
- package/dist/fn-context/run-scope.d.ts +4 -0
- package/dist/fn-context/run-scope.js +9 -0
- package/dist/fn-context/types.d.ts +52 -5
- package/dist/index.d.ts +36 -46
- package/dist/index.js +30 -33
- package/dist/logger.d.ts +11 -0
- package/dist/logger.js +49 -0
- package/dist/platform.d.ts +75 -0
- package/dist/platform.js +57 -0
- package/dist/testing-compile-child.d.ts +2 -0
- package/dist/testing-compile-child.js +20 -0
- package/dist/testing.d.ts +368 -0
- package/dist/testing.js +439 -0
- package/dist/voice-service/actions.d.ts +50 -6
- package/dist/voice-service/index.d.ts +2 -0
- package/dist/voice-service/index.js +2 -0
- package/dist/voice-service/protocol.d.ts +604 -0
- package/dist/voice-service/protocol.js +67 -0
- package/dist/voice-service/types.d.ts +55 -8
- package/dist/worker.d.ts +11 -0
- package/dist/worker.js +11 -0
- package/package.json +38 -15
- package/dist/builder/compile/compile-agenda.d.ts +0 -15
- package/dist/builder/compile/compile-agenda.js +0 -64
- package/dist/builder/merge.d.ts +0 -4
- package/dist/builder/merge.js +0 -19
- package/dist/compute-host/read-only-cache.d.ts +0 -20
- package/dist/compute-host/read-only-cache.js +0 -61
- package/dist/core/context/db.d.ts +0 -69
- package/dist/core/context/db.js +0 -44
- package/dist/core/context/docusign.d.ts +0 -134
- package/dist/core/context/docusign.js +0 -108
- package/dist/core/context/filevine.d.ts +0 -323
- package/dist/core/context/filevine.js +0 -254
- package/dist/core/context/http.d.ts +0 -9
- package/dist/core/context/http.js +0 -4
- package/dist/core/context/hubspot.d.ts +0 -250
- package/dist/core/context/hubspot.js +0 -191
- package/dist/core/context/twilio.d.ts +0 -50
- package/dist/core/context/twilio.js +0 -42
- package/dist/core/functions/define/case-context.d.ts +0 -14
- package/dist/core/functions/define/case-context.js +0 -15
- package/dist/core/functions/define/compute.d.ts +0 -7
- package/dist/core/functions/define/compute.js +0 -17
- package/dist/core/functions/define/custom.d.ts +0 -4
- package/dist/core/functions/define/custom.js +0 -8
- package/dist/core/functions/define/system.d.ts +0 -7
- package/dist/core/functions/define/system.js +0 -12
- package/dist/core/functions/func-ref.d.ts +0 -16
- package/dist/core/functions/func-ref.js +0 -20
- package/dist/core/slot/deps.d.ts +0 -15
- package/dist/core/slot/deps.js +0 -88
- package/dist/core/slot/derived.d.ts +0 -32
- package/dist/core/slot/derived.js +0 -115
- package/dist/core/slot/platform-session-fields.d.ts +0 -38
- package/dist/core/slot/platform-session-fields.js +0 -48
- package/dist/core/slot/sf-schema.d.ts +0 -23
- package/dist/core/slot/sf-schema.js +0 -125
- package/dist/core/slot/sf-validate.d.ts +0 -14
- package/dist/core/slot/sf-validate.js +0 -132
- package/dist/core/slot/snapshot.d.ts +0 -18
- package/dist/core/slot/snapshot.js +0 -138
- package/dist/core/slot/write.d.ts +0 -48
- package/dist/core/slot/write.js +0 -426
- package/dist/core/stage/builders.d.ts +0 -54
- package/dist/core/stage/builders.js +0 -31
- package/dist/core/stage/condition.d.ts +0 -17
- package/dist/core/stage/condition.js +0 -198
- package/dist/core/stage/drive.d.ts +0 -43
- package/dist/core/stage/drive.js +0 -78
- package/dist/core/stage/finish-when.d.ts +0 -20
- package/dist/core/stage/finish-when.js +0 -82
- package/dist/core/stage/flatten.d.ts +0 -27
- package/dist/core/stage/flatten.js +0 -466
- package/dist/core/stage/index.d.ts +0 -15
- package/dist/core/stage/index.js +0 -13
- package/dist/core/stage/interrupts.d.ts +0 -28
- package/dist/core/stage/interrupts.js +0 -120
- package/dist/core/stage/ivr-fields.d.ts +0 -9
- package/dist/core/stage/ivr-fields.js +0 -75
- package/dist/core/stage/simulate.d.ts +0 -24
- package/dist/core/stage/simulate.js +0 -33
- package/dist/core/stage/transfer-fields.d.ts +0 -19
- package/dist/core/stage/transfer-fields.js +0 -129
- package/dist/core/stage/transfer-spec.d.ts +0 -48
- package/dist/core/stage/transfer-spec.js +0 -113
- package/dist/core/stage/types.d.ts +0 -208
- package/dist/core/stage/types.js +0 -2
- package/dist/core/stage/validate.d.ts +0 -11
- package/dist/core/stage/validate.js +0 -330
- package/dist/core/stage/walk.d.ts +0 -39
- package/dist/core/stage/walk.js +0 -119
- package/dist/fn-context/rpc/integration/list-bindings.d.ts +0 -21
- package/dist/fn-context/system-args.d.ts +0 -6
- package/dist/fn-context/system-args.js +0 -14
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type IntegrationSurfaceMeta } from '../../../core/context/types.js';
|
|
2
|
+
import { type RpcContext } from '../trpc-init.js';
|
|
3
|
+
export type ListSurfacesHandler = (opts: {
|
|
4
|
+
ctx: RpcContext;
|
|
5
|
+
}) => Promise<IntegrationSurfaceMeta[]>;
|
|
6
|
+
export declare function createListSurfacesProcedure(handler: ListSurfacesHandler): import("@trpc/server").TRPCQueryProcedure<{
|
|
7
|
+
input: void;
|
|
8
|
+
output: {
|
|
9
|
+
surfaceKey: "emails" | "envs";
|
|
10
|
+
target: {
|
|
11
|
+
kind: "account" | "resource";
|
|
12
|
+
id: string;
|
|
13
|
+
};
|
|
14
|
+
name: string;
|
|
15
|
+
methods: string[];
|
|
16
|
+
credentials: Record<string, unknown>;
|
|
17
|
+
config: Record<string, unknown>;
|
|
18
|
+
}[];
|
|
19
|
+
meta: object;
|
|
20
|
+
}>;
|
|
21
|
+
//# sourceMappingURL=list-surfaces.d.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { integrationSurfaceKeys } from '../../../core/context/types.js';
|
|
3
3
|
import { publicProcedure } from '../trpc-init.js';
|
|
4
|
-
const
|
|
4
|
+
const integrationSurfaceMeta = z.object({
|
|
5
5
|
surfaceKey: z.enum(integrationSurfaceKeys),
|
|
6
6
|
target: z.object({
|
|
7
7
|
kind: z.enum(['account', 'resource']),
|
|
@@ -12,7 +12,7 @@ const boundIntegrationMeta = z.object({
|
|
|
12
12
|
credentials: z.record(z.string(), z.unknown()),
|
|
13
13
|
config: z.record(z.string(), z.unknown()),
|
|
14
14
|
});
|
|
15
|
-
export function
|
|
16
|
-
return publicProcedure.output(z.array(
|
|
15
|
+
export function createListSurfacesProcedure(handler) {
|
|
16
|
+
return publicProcedure.output(z.array(integrationSurfaceMeta)).query(async (opts) => handler(opts));
|
|
17
17
|
}
|
|
18
|
-
//# sourceMappingURL=list-
|
|
18
|
+
//# sourceMappingURL=list-surfaces.js.map
|
|
@@ -20,7 +20,17 @@ export type LogEmitHandler = (input: {
|
|
|
20
20
|
export declare function createLogRouter(emit: LogEmitHandler): import("@trpc/server").TRPCBuiltRouter<{
|
|
21
21
|
ctx: RpcContext;
|
|
22
22
|
meta: object;
|
|
23
|
-
errorShape: import("@trpc/server").TRPCDefaultErrorShape
|
|
23
|
+
errorShape: import("@trpc/server").TRPCDefaultErrorShape | {
|
|
24
|
+
message: string;
|
|
25
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
|
|
26
|
+
data: {
|
|
27
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
28
|
+
httpStatus: number;
|
|
29
|
+
path?: string;
|
|
30
|
+
stack?: string;
|
|
31
|
+
reason: string;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
24
34
|
transformer: false;
|
|
25
35
|
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
26
36
|
emit: import("@trpc/server").TRPCMutationProcedure<{
|
|
@@ -6,20 +6,30 @@ import { type RpcContext } from './trpc-init.js';
|
|
|
6
6
|
export type PlatformInvokeHandler = (input: {
|
|
7
7
|
surface: string;
|
|
8
8
|
method: string;
|
|
9
|
-
params:
|
|
9
|
+
params: unknown;
|
|
10
10
|
ctx: RpcContext;
|
|
11
11
|
}) => Promise<unknown>;
|
|
12
12
|
export declare function createPlatformRouter(invoke: PlatformInvokeHandler): import("@trpc/server").TRPCBuiltRouter<{
|
|
13
13
|
ctx: RpcContext;
|
|
14
14
|
meta: object;
|
|
15
|
-
errorShape: import("@trpc/server").TRPCDefaultErrorShape
|
|
15
|
+
errorShape: import("@trpc/server").TRPCDefaultErrorShape | {
|
|
16
|
+
message: string;
|
|
17
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
|
|
18
|
+
data: {
|
|
19
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
20
|
+
httpStatus: number;
|
|
21
|
+
path?: string;
|
|
22
|
+
stack?: string;
|
|
23
|
+
reason: string;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
16
26
|
transformer: false;
|
|
17
27
|
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
18
28
|
invoke: import("@trpc/server").TRPCMutationProcedure<{
|
|
19
29
|
input: {
|
|
20
30
|
surface: string;
|
|
21
31
|
method: string;
|
|
22
|
-
params?:
|
|
32
|
+
params?: unknown;
|
|
23
33
|
};
|
|
24
34
|
output: unknown;
|
|
25
35
|
meta: object;
|
|
@@ -3,7 +3,7 @@ import { publicProcedure, router } from './trpc-init.js';
|
|
|
3
3
|
const platformInvokeInput = z.object({
|
|
4
4
|
surface: z.string(),
|
|
5
5
|
method: z.string(),
|
|
6
|
-
params: z.
|
|
6
|
+
params: z.unknown().optional(),
|
|
7
7
|
});
|
|
8
8
|
export function createPlatformRouter(invoke) {
|
|
9
9
|
return router({
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { type RpcContext } from './trpc-init.js';
|
|
3
|
+
/**
|
|
4
|
+
* `ctx.api.db` of every function and the Orchestrator (15 §10.16): the same
|
|
5
|
+
* reads and writes as a page script and its actions, over RPC, one call per request. A write is done
|
|
6
|
+
* each time it is sent (38 §2.7): the platform keeps no key to answer a repeat with the first answer.
|
|
7
|
+
*/
|
|
8
|
+
declare const readInput: z.ZodObject<{
|
|
9
|
+
table: z.ZodString;
|
|
10
|
+
method: z.ZodEnum<{
|
|
11
|
+
count: "count";
|
|
12
|
+
findFirst: "findFirst";
|
|
13
|
+
findMany: "findMany";
|
|
14
|
+
findUnique: "findUnique";
|
|
15
|
+
}>;
|
|
16
|
+
args: z.ZodUnknown;
|
|
17
|
+
}, z.core.$strip>;
|
|
18
|
+
declare const writeInput: z.ZodObject<{
|
|
19
|
+
table: z.ZodString;
|
|
20
|
+
method: z.ZodEnum<{
|
|
21
|
+
create: "create";
|
|
22
|
+
delete: "delete";
|
|
23
|
+
update: "update";
|
|
24
|
+
upsert: "upsert";
|
|
25
|
+
}>;
|
|
26
|
+
args: z.ZodUnknown;
|
|
27
|
+
}, z.core.$strip>;
|
|
28
|
+
export type RecordsReadInput = z.infer<typeof readInput>;
|
|
29
|
+
export type RecordsWriteInput = z.infer<typeof writeInput>;
|
|
30
|
+
/** What a read or write answers: its value, or the reason it was refused (with its code for a write). */
|
|
31
|
+
export type RecordsResult = {
|
|
32
|
+
ok: true;
|
|
33
|
+
value?: unknown;
|
|
34
|
+
} | {
|
|
35
|
+
ok: false;
|
|
36
|
+
error: {
|
|
37
|
+
code: string;
|
|
38
|
+
message: string;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
export type RecordsHandlers = {
|
|
42
|
+
read(input: RecordsReadInput & {
|
|
43
|
+
ctx: RpcContext;
|
|
44
|
+
}): Promise<RecordsResult>;
|
|
45
|
+
write(input: RecordsWriteInput & {
|
|
46
|
+
ctx: RpcContext;
|
|
47
|
+
}): Promise<RecordsResult>;
|
|
48
|
+
};
|
|
49
|
+
export declare function createRecordsRouter(handlers: RecordsHandlers): import("@trpc/server").TRPCBuiltRouter<{
|
|
50
|
+
ctx: RpcContext;
|
|
51
|
+
meta: object;
|
|
52
|
+
errorShape: import("@trpc/server").TRPCDefaultErrorShape | {
|
|
53
|
+
message: string;
|
|
54
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
|
|
55
|
+
data: {
|
|
56
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
57
|
+
httpStatus: number;
|
|
58
|
+
path?: string;
|
|
59
|
+
stack?: string;
|
|
60
|
+
reason: string;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
transformer: false;
|
|
64
|
+
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
65
|
+
read: import("@trpc/server").TRPCMutationProcedure<{
|
|
66
|
+
input: {
|
|
67
|
+
table: string;
|
|
68
|
+
method: "count" | "findFirst" | "findMany" | "findUnique";
|
|
69
|
+
args: unknown;
|
|
70
|
+
};
|
|
71
|
+
output: RecordsResult;
|
|
72
|
+
meta: object;
|
|
73
|
+
}>;
|
|
74
|
+
write: import("@trpc/server").TRPCMutationProcedure<{
|
|
75
|
+
input: {
|
|
76
|
+
table: string;
|
|
77
|
+
method: "create" | "delete" | "update" | "upsert";
|
|
78
|
+
args: unknown;
|
|
79
|
+
};
|
|
80
|
+
output: RecordsResult;
|
|
81
|
+
meta: object;
|
|
82
|
+
}>;
|
|
83
|
+
}>>;
|
|
84
|
+
export {};
|
|
85
|
+
//# sourceMappingURL=records.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { publicProcedure, router } from './trpc-init.js';
|
|
3
|
+
/**
|
|
4
|
+
* `ctx.api.db` of every function and the Orchestrator (15 §10.16): the same
|
|
5
|
+
* reads and writes as a page script and its actions, over RPC, one call per request. A write is done
|
|
6
|
+
* each time it is sent (38 §2.7): the platform keeps no key to answer a repeat with the first answer.
|
|
7
|
+
*/
|
|
8
|
+
const readInput = z.object({
|
|
9
|
+
table: z.string().min(1),
|
|
10
|
+
method: z.enum(['findUnique', 'findFirst', 'findMany', 'count']),
|
|
11
|
+
args: z.unknown(),
|
|
12
|
+
});
|
|
13
|
+
const writeInput = z.object({
|
|
14
|
+
table: z.string().min(1),
|
|
15
|
+
method: z.enum(['create', 'update', 'upsert', 'delete']),
|
|
16
|
+
args: z.unknown(),
|
|
17
|
+
});
|
|
18
|
+
export function createRecordsRouter(handlers) {
|
|
19
|
+
return router({
|
|
20
|
+
read: publicProcedure.input(readInput).mutation(({ ctx, input }) => handlers.read({ ...input, ctx })),
|
|
21
|
+
write: publicProcedure.input(writeInput).mutation(({ ctx, input }) => handlers.write({ ...input, ctx })),
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=records.js.map
|
|
@@ -1,4 +1,41 @@
|
|
|
1
|
-
import type { ApiHost } from '../types.js';
|
|
1
|
+
import type { ApiHost, CaseOrchestratorApiHost } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* A request that got no answer from the platform itself (74 §3.2): the platform always answers JSON, so any
|
|
4
|
+
* other answer is a gateway's. `reached: false` only when the request certainly never got to the platform.
|
|
5
|
+
*/
|
|
6
|
+
export declare class RpcTransportError extends Error {
|
|
7
|
+
readonly reached: boolean | 'unknown';
|
|
8
|
+
readonly name = "RpcTransportError";
|
|
9
|
+
constructor(message: string, reached: boolean | 'unknown');
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* `fetch` for the platform's RPC: a failure to connect, or an answer that is not the platform's (not JSON),
|
|
13
|
+
* becomes an {@link RpcTransportError} saying whether the request reached it. The answer is read whole here:
|
|
14
|
+
* one that breaks as it is read (a body cut off, bad JSON) is an {@link RpcTransportError} too, so whatever
|
|
15
|
+
* fails before this is called (the code's arguments that cannot be sent as JSON) stays the code's.
|
|
16
|
+
*/
|
|
17
|
+
export declare function platformFetch(input: Parameters<typeof fetch>[0], init?: Parameters<typeof fetch>[1]): Promise<Response>;
|
|
18
|
+
/** Sent again: the platform was busy (`TOO_MANY_REQUESTS`), or the request never reached it. */
|
|
19
|
+
export declare function shouldRetryRpc(error: {
|
|
20
|
+
data?: {
|
|
21
|
+
code?: string;
|
|
22
|
+
} | null;
|
|
23
|
+
cause?: unknown;
|
|
24
|
+
}, attempts: number): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* A failed call as company code sees it: an `Error` with the platform's message and, when the platform
|
|
27
|
+
* refused it for a reason of the business (`subject_busy`, `run_ended`, a write's code), that reason as
|
|
28
|
+
* `error.code` (64 §12).
|
|
29
|
+
*/
|
|
30
|
+
export declare function rpcSafe<T>(promise: Promise<T>): Promise<T>;
|
|
31
|
+
/**
|
|
32
|
+
* A read's arguments as sent, `after` cut down to the place the platform reads off it (18 §4.6): the
|
|
33
|
+
* row's `id`, `createdAt` and `updatedAt`, and of each field this read's `orderBy` names, the slot's
|
|
34
|
+
* `value`. `after: rows.at(-1)` is a row with whatever it `include`d; sent whole, a big include tree
|
|
35
|
+
* could pass the request's size limit for nothing. Anything that is no row goes as given, for the
|
|
36
|
+
* platform to refuse with its reason.
|
|
37
|
+
*/
|
|
38
|
+
export declare function placeOnly(args: unknown): unknown;
|
|
2
39
|
export declare function createRpcApiHost(options: {
|
|
3
40
|
baseUrl: string;
|
|
4
41
|
getToken: () => string | Promise<string>;
|
|
@@ -7,5 +44,10 @@ export declare function createRpcApiHost(options: {
|
|
|
7
44
|
getRequestId?: () => string | undefined;
|
|
8
45
|
getTags?: () => string[] | undefined;
|
|
9
46
|
waitUntil?: (promise: Promise<unknown>) => void;
|
|
10
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Asked before each call is sent, with its procedure's path (`platform.invoke`, `log.emit`, …): throws
|
|
49
|
+
* to refuse it. The Worker refuses a `ctx` kept from another call (64 §6).
|
|
50
|
+
*/
|
|
51
|
+
checkCall?: (path: string) => void;
|
|
52
|
+
}): ApiHost & CaseOrchestratorApiHost;
|
|
11
53
|
//# sourceMappingURL=trpc-client.d.ts.map
|
|
@@ -1,9 +1,95 @@
|
|
|
1
|
-
import { createTRPCClient, httpLink } from '@trpc/client';
|
|
1
|
+
import { createTRPCClient, httpLink, retryLink } from '@trpc/client';
|
|
2
2
|
import { platformSurfaces } from '../../core/context/platform-registry.js';
|
|
3
|
-
import { defaultHttpApi } from '../../core/context/http.js';
|
|
4
3
|
import { integrationSurfaceKeys, } from '../../core/context/types.js';
|
|
5
4
|
import { bindEnvService } from '../../core/context/env.js';
|
|
6
|
-
import {
|
|
5
|
+
import { CASE_ORCHESTRATOR_TOOL_NAMES, } from '../../core/case-orchestrator/types.js';
|
|
6
|
+
import { getLogger } from '../../logger.js';
|
|
7
|
+
import { PlatformUnavailableError } from '../../core/functions/errors.js';
|
|
8
|
+
import { REQUEST_ID_HEADER, RUNTIME_VERSION_HEADER, formatRuntimeVersion } from './request-id.js';
|
|
9
|
+
const logger = getLogger(['runtime', 'rpc']);
|
|
10
|
+
/**
|
|
11
|
+
* A call the platform turned away before doing anything (its company over the rate, or no free slot:
|
|
12
|
+
* `TOO_MANY_REQUESTS`) is sent again after a growing pause, long enough together to outlast a rate window.
|
|
13
|
+
*/
|
|
14
|
+
const BUSY_RETRIES = 5;
|
|
15
|
+
const busyDelayMs = (attempt) => Math.min(500 * 2 ** attempt, 5_000) + Math.floor(Math.random() * 250);
|
|
16
|
+
/**
|
|
17
|
+
* A call that certainly never reached the platform (a gateway's error page, a refused connection, a name that
|
|
18
|
+
* did not resolve) is sent again this many times, after the same growing pause (74 §3.2). One that may have
|
|
19
|
+
* reached it (504, a connection cut after it was sent) is not, read or write alike.
|
|
20
|
+
*/
|
|
21
|
+
const UNREACHED_RETRIES = 3;
|
|
22
|
+
/**
|
|
23
|
+
* A request that got no answer from the platform itself (74 §3.2): the platform always answers JSON, so any
|
|
24
|
+
* other answer is a gateway's. `reached: false` only when the request certainly never got to the platform.
|
|
25
|
+
*/
|
|
26
|
+
export class RpcTransportError extends Error {
|
|
27
|
+
reached;
|
|
28
|
+
name = 'RpcTransportError';
|
|
29
|
+
constructor(message, reached) {
|
|
30
|
+
super(message);
|
|
31
|
+
this.reached = reached;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** A gateway's own answer that may come after the platform got the request: its timeouts (504; Cloudflare 520, 524). */
|
|
35
|
+
const MAYBE_REACHED_STATUSES = new Set([504, 520, 524]);
|
|
36
|
+
/** Fetch failures where no connection was ever made. */
|
|
37
|
+
const NOT_CONNECTED = /ECONNREFUSED|ENOTFOUND|EAI_AGAIN|getaddrinfo/;
|
|
38
|
+
function connectFailure(error) {
|
|
39
|
+
for (let current = error, depth = 0; current && depth < 5; depth += 1) {
|
|
40
|
+
const { code, message, errors } = current;
|
|
41
|
+
if (NOT_CONNECTED.test(`${String(code ?? '')} ${String(message ?? '')}`))
|
|
42
|
+
return true;
|
|
43
|
+
if (Array.isArray(errors) && errors.some(connectFailure))
|
|
44
|
+
return true;
|
|
45
|
+
current = current.cause;
|
|
46
|
+
}
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* `fetch` for the platform's RPC: a failure to connect, or an answer that is not the platform's (not JSON),
|
|
51
|
+
* becomes an {@link RpcTransportError} saying whether the request reached it. The answer is read whole here:
|
|
52
|
+
* one that breaks as it is read (a body cut off, bad JSON) is an {@link RpcTransportError} too, so whatever
|
|
53
|
+
* fails before this is called (the code's arguments that cannot be sent as JSON) stays the code's.
|
|
54
|
+
*/
|
|
55
|
+
export async function platformFetch(input, init) {
|
|
56
|
+
let response;
|
|
57
|
+
try {
|
|
58
|
+
response = await fetch(input, init);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
const reached = connectFailure(error) ? false : 'unknown';
|
|
62
|
+
throw new RpcTransportError(`the platform could not be reached: ${error instanceof Error ? error.message : String(error)}`, reached);
|
|
63
|
+
}
|
|
64
|
+
if (!/json/i.test(response.headers.get('content-type') ?? '')) {
|
|
65
|
+
const body = (await response.text().catch(() => '')).slice(0, 120).replace(/\s+/g, ' ');
|
|
66
|
+
throw new RpcTransportError(`HTTP ${response.status} from a gateway, not the platform: ${body}`, MAYBE_REACHED_STATUSES.has(response.status) ? 'unknown' : false);
|
|
67
|
+
}
|
|
68
|
+
let text;
|
|
69
|
+
try {
|
|
70
|
+
text = await response.text();
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
throw new RpcTransportError(`the platform's answer was cut off: ${error instanceof Error ? error.message : String(error)}`, 'unknown');
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
JSON.parse(text);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
throw new RpcTransportError(`the platform's answer is not valid JSON: ${text.slice(0, 120)}`, 'unknown');
|
|
80
|
+
}
|
|
81
|
+
return new Response(text, { status: response.status, statusText: response.statusText, headers: response.headers });
|
|
82
|
+
}
|
|
83
|
+
function transportErrorOf(error) {
|
|
84
|
+
const cause = error?.cause;
|
|
85
|
+
return cause instanceof RpcTransportError ? cause : null;
|
|
86
|
+
}
|
|
87
|
+
/** Sent again: the platform was busy (`TOO_MANY_REQUESTS`), or the request never reached it. */
|
|
88
|
+
export function shouldRetryRpc(error, attempts) {
|
|
89
|
+
if (error.data?.code === 'TOO_MANY_REQUESTS')
|
|
90
|
+
return attempts <= BUSY_RETRIES;
|
|
91
|
+
return transportErrorOf(error)?.reached === false && attempts <= UNREACHED_RETRIES;
|
|
92
|
+
}
|
|
7
93
|
function rpcLogger(c, getTags, waitUntil) {
|
|
8
94
|
const emit = (level, message, extra) => {
|
|
9
95
|
const pending = c.log.emit.mutate({ level, message, extra, tags: getTags?.() }).catch(() => { });
|
|
@@ -20,10 +106,25 @@ function rpcLogger(c, getTags, waitUntil) {
|
|
|
20
106
|
error: (message, extra) => emit('error', message, extra),
|
|
21
107
|
};
|
|
22
108
|
}
|
|
23
|
-
|
|
109
|
+
/**
|
|
110
|
+
* A failed call as company code sees it: an `Error` with the platform's message and, when the platform
|
|
111
|
+
* refused it for a reason of the business (`subject_busy`, `run_ended`, a write's code), that reason as
|
|
112
|
+
* `error.code` (64 §12).
|
|
113
|
+
*/
|
|
114
|
+
export function rpcSafe(promise) {
|
|
24
115
|
return promise.catch((err) => {
|
|
25
116
|
if (err instanceof Error && err.constructor?.name === 'TRPCClientError') {
|
|
26
|
-
|
|
117
|
+
// No answer from the platform, one that broke as it was read (`platformFetch` says so), or its own
|
|
118
|
+
// failure (5xx): the platform's (74 §3.2), marked so. What failed before the request was sent (the
|
|
119
|
+
// code's arguments that are no JSON, a ctx kept from another call) stays the code's.
|
|
120
|
+
const status = err.data?.httpStatus;
|
|
121
|
+
const platform = transportErrorOf(err) !== null || (typeof status === 'number' && status >= 500);
|
|
122
|
+
const message = `RPC call failed: ${transportErrorOf(err)?.message ?? err.message}`;
|
|
123
|
+
const failed = (platform ? new PlatformUnavailableError(message) : new Error(message));
|
|
124
|
+
const reason = err.data?.reason;
|
|
125
|
+
if (typeof reason === 'string')
|
|
126
|
+
failed.code = reason;
|
|
127
|
+
throw failed;
|
|
27
128
|
}
|
|
28
129
|
throw err;
|
|
29
130
|
});
|
|
@@ -48,6 +149,13 @@ function stubSurface(c, meta) {
|
|
|
48
149
|
if (meta.surfaceKey === 'envs') {
|
|
49
150
|
return bindEnvService(stub);
|
|
50
151
|
}
|
|
152
|
+
if (meta.surfaceKey === 'emails') {
|
|
153
|
+
return {
|
|
154
|
+
...stub,
|
|
155
|
+
address: typeof meta.config.address === 'string' ? meta.config.address : meta.name,
|
|
156
|
+
provider: meta.config.provider === 'hotmail' ? 'hotmail' : 'gmail',
|
|
157
|
+
};
|
|
158
|
+
}
|
|
51
159
|
return stub;
|
|
52
160
|
}
|
|
53
161
|
function buildSurfaces(c, metas) {
|
|
@@ -74,6 +182,81 @@ function buildPlatformApis(c) {
|
|
|
74
182
|
// The registry is what guarantees the shape; TS cannot follow it through Object.fromEntries.
|
|
75
183
|
return Object.fromEntries(surfaces);
|
|
76
184
|
}
|
|
185
|
+
/** Every Case Orchestrator tool routes through one procedure; the platform validates and executes it. */
|
|
186
|
+
function buildCaseOrchestratorTools(c) {
|
|
187
|
+
const tools = CASE_ORCHESTRATOR_TOOL_NAMES.map((tool) => [
|
|
188
|
+
tool,
|
|
189
|
+
(input) => rpcSafe(c.caseOrchestratorTools.invoke.mutate({ tool, input })),
|
|
190
|
+
]);
|
|
191
|
+
// The tool registry guarantees the shape; TS cannot follow it through Object.fromEntries.
|
|
192
|
+
return Object.fromEntries(tools);
|
|
193
|
+
}
|
|
194
|
+
/** A records answer: its value, or the error it was refused with (a write's with its code). */
|
|
195
|
+
function unwrapRecords(result) {
|
|
196
|
+
if (result.ok)
|
|
197
|
+
return result.value;
|
|
198
|
+
const error = new Error(result.error.message);
|
|
199
|
+
error.code = result.error.code;
|
|
200
|
+
throw error;
|
|
201
|
+
}
|
|
202
|
+
function isPlainObject(value) {
|
|
203
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
204
|
+
}
|
|
205
|
+
/** The keys of a row the platform always reads off `after`: its id and times. */
|
|
206
|
+
const PLACE_KEYS = new Set(['id', 'createdAt', 'updatedAt']);
|
|
207
|
+
/**
|
|
208
|
+
* A read's arguments as sent, `after` cut down to the place the platform reads off it (18 §4.6): the
|
|
209
|
+
* row's `id`, `createdAt` and `updatedAt`, and of each field this read's `orderBy` names, the slot's
|
|
210
|
+
* `value`. `after: rows.at(-1)` is a row with whatever it `include`d; sent whole, a big include tree
|
|
211
|
+
* could pass the request's size limit for nothing. Anything that is no row goes as given, for the
|
|
212
|
+
* platform to refuse with its reason.
|
|
213
|
+
*/
|
|
214
|
+
export function placeOnly(args) {
|
|
215
|
+
if (!isPlainObject(args) || !isPlainObject(args.after))
|
|
216
|
+
return args;
|
|
217
|
+
const ordered = new Set();
|
|
218
|
+
for (const entry of Array.isArray(args.orderBy) ? args.orderBy : [args.orderBy]) {
|
|
219
|
+
if (isPlainObject(entry))
|
|
220
|
+
for (const field of Object.keys(entry))
|
|
221
|
+
ordered.add(field);
|
|
222
|
+
}
|
|
223
|
+
const place = Object.entries(args.after).flatMap(([key, value]) => {
|
|
224
|
+
if (PLACE_KEYS.has(key))
|
|
225
|
+
return [[key, value]];
|
|
226
|
+
if (!ordered.has(key))
|
|
227
|
+
return [];
|
|
228
|
+
// A slot: only its value places the row (a lookup's included `row` does not).
|
|
229
|
+
return [[key, isPlainObject(value) ? (Object.hasOwn(value, 'value') ? { value: value.value } : {}) : value]];
|
|
230
|
+
});
|
|
231
|
+
return { ...args, after: Object.fromEntries(place) };
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* `ctx.api.db` of every function and the Orchestrator (15 §10.15 task 4, §10.16): every table, as a
|
|
235
|
+
* page script and its actions see them, one request per call; a write is done each time (38 §2.7). A
|
|
236
|
+
* read's `after` goes as its place only ({@link placeOnly}).
|
|
237
|
+
*/
|
|
238
|
+
function buildDbApi(c) {
|
|
239
|
+
const db = new Proxy({}, {
|
|
240
|
+
get(_, table) {
|
|
241
|
+
if (typeof table !== 'string')
|
|
242
|
+
return undefined;
|
|
243
|
+
const read = (method) => async (args) => unwrapRecords(await rpcSafe(c.records.read.mutate({ table, method, args: placeOnly(args ?? {}) })));
|
|
244
|
+
const write = (method) => async (args) => unwrapRecords(await rpcSafe(c.records.write.mutate({ table, method, args: args ?? {} })));
|
|
245
|
+
return {
|
|
246
|
+
$table: table,
|
|
247
|
+
findUnique: read('findUnique'),
|
|
248
|
+
findFirst: read('findFirst'),
|
|
249
|
+
findMany: read('findMany'),
|
|
250
|
+
count: read('count'),
|
|
251
|
+
create: write('create'),
|
|
252
|
+
update: write('update'),
|
|
253
|
+
upsert: write('upsert'),
|
|
254
|
+
delete: write('delete'),
|
|
255
|
+
};
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
return { db };
|
|
259
|
+
}
|
|
77
260
|
export function createRpcApiHost(options) {
|
|
78
261
|
let client;
|
|
79
262
|
let lastBaseUrl;
|
|
@@ -81,9 +264,15 @@ export function createRpcApiHost(options) {
|
|
|
81
264
|
if (!client || lastBaseUrl !== baseUrl) {
|
|
82
265
|
client = createTRPCClient({
|
|
83
266
|
links: [
|
|
267
|
+
retryLink({
|
|
268
|
+
retry: ({ error, attempts }) => shouldRetryRpc(error, attempts),
|
|
269
|
+
retryDelayMs: busyDelayMs,
|
|
270
|
+
}),
|
|
84
271
|
httpLink({
|
|
85
272
|
url: baseUrl,
|
|
86
|
-
|
|
273
|
+
fetch: platformFetch,
|
|
274
|
+
headers: async ({ op }) => {
|
|
275
|
+
options.checkCall?.(op.path);
|
|
87
276
|
const headers = {
|
|
88
277
|
authorization: `Bearer ${await options.getToken()}`,
|
|
89
278
|
[RUNTIME_VERSION_HEADER]: formatRuntimeVersion(options.runtimeVersion, options.runtimeSource),
|
|
@@ -100,18 +289,39 @@ export function createRpcApiHost(options) {
|
|
|
100
289
|
}
|
|
101
290
|
return client;
|
|
102
291
|
}
|
|
292
|
+
/** The integrations the call brought; without them, the backend lists them. */
|
|
293
|
+
async function surfacesOf(c, given) {
|
|
294
|
+
if (given.surfaces)
|
|
295
|
+
return given.surfaces;
|
|
296
|
+
const started = Date.now();
|
|
297
|
+
logger.info('integration.listSurfaces start', { url: options.baseUrl });
|
|
298
|
+
const metas = await rpcSafe(c.integration.listSurfaces.query());
|
|
299
|
+
logger.info('integration.listSurfaces ok', { durationMs: Date.now() - started, count: metas.length });
|
|
300
|
+
return metas;
|
|
301
|
+
}
|
|
103
302
|
return {
|
|
104
|
-
async buildApi(_run) {
|
|
303
|
+
async buildApi(_run, given = {}) {
|
|
304
|
+
const c = getClient(options.baseUrl);
|
|
305
|
+
const metas = await surfacesOf(c, given);
|
|
306
|
+
return {
|
|
307
|
+
...buildPlatformApis(c),
|
|
308
|
+
integration: buildSurfaces(c, metas),
|
|
309
|
+
log: rpcLogger(c, options.getTags, options.waitUntil),
|
|
310
|
+
// Every function's (38 §2.7): each call names its instance.
|
|
311
|
+
tools: buildCaseOrchestratorTools(c),
|
|
312
|
+
...buildDbApi(c),
|
|
313
|
+
};
|
|
314
|
+
},
|
|
315
|
+
async buildCaseOrchestratorApi(_run, given = {}) {
|
|
105
316
|
const c = getClient(options.baseUrl);
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const metas = await rpcSafe(c.integration.listBindings.query());
|
|
109
|
-
console.log(`[rpc timing] integration.listBindings ok ${Date.now() - started}ms count=${metas.length}`);
|
|
317
|
+
// A function's api (25 §7), so a function called from the Orchestrator with its ctx works the same.
|
|
318
|
+
const metas = await surfacesOf(c, given);
|
|
110
319
|
return {
|
|
111
320
|
...buildPlatformApis(c),
|
|
112
321
|
integration: buildSurfaces(c, metas),
|
|
113
322
|
log: rpcLogger(c, options.getTags, options.waitUntil),
|
|
114
|
-
|
|
323
|
+
tools: buildCaseOrchestratorTools(c),
|
|
324
|
+
...buildDbApi(c),
|
|
115
325
|
};
|
|
116
326
|
},
|
|
117
327
|
};
|
|
@@ -1,13 +1,31 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RunClaims } from '../types.js';
|
|
2
2
|
export type RpcContext = {
|
|
3
|
-
run:
|
|
3
|
+
run: RunClaims;
|
|
4
4
|
requestId?: string;
|
|
5
5
|
runtimeVersion?: string;
|
|
6
|
+
/**
|
|
7
|
+
* The platform's gate around every procedure (64 §5): the rate, and whether an Orchestrator's task still
|
|
8
|
+
* runs. Set by the platform's context; every procedure built on {@link publicProcedure} passes through it,
|
|
9
|
+
* so a new one cannot miss it. Absent (a test calling one router directly), the procedure just runs.
|
|
10
|
+
*/
|
|
11
|
+
around?: <T>(call: {
|
|
12
|
+
path: string;
|
|
13
|
+
}, next: () => Promise<T>) => Promise<T>;
|
|
6
14
|
};
|
|
7
15
|
export declare const router: import("@trpc/server").TRPCRouterBuilder<{
|
|
8
16
|
ctx: RpcContext;
|
|
9
17
|
meta: object;
|
|
10
|
-
errorShape: import("@trpc/server").TRPCDefaultErrorShape
|
|
18
|
+
errorShape: import("@trpc/server").TRPCDefaultErrorShape | {
|
|
19
|
+
message: string;
|
|
20
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
|
|
21
|
+
data: {
|
|
22
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
23
|
+
httpStatus: number;
|
|
24
|
+
path?: string;
|
|
25
|
+
stack?: string;
|
|
26
|
+
reason: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
11
29
|
transformer: false;
|
|
12
30
|
}>;
|
|
13
31
|
/**
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { initTRPC, TRPCError } from '@trpc/server';
|
|
2
|
-
import { isRpcCodedError } from './errors.js';
|
|
3
|
-
const t = initTRPC.context().create(
|
|
2
|
+
import { isRpcCodedError, rpcErrorReason } from './errors.js';
|
|
3
|
+
const t = initTRPC.context().create({
|
|
4
|
+
// A refusal's business code (`subject_busy`, `run_ended`, …) goes back beside its message (64 §12).
|
|
5
|
+
errorFormatter({ shape, error }) {
|
|
6
|
+
const reason = rpcErrorReason(error.cause);
|
|
7
|
+
return reason ? { ...shape, data: { ...shape.data, reason } } : shape;
|
|
8
|
+
},
|
|
9
|
+
});
|
|
4
10
|
export const router = t.router;
|
|
5
11
|
/**
|
|
6
12
|
* Applied to every procedure so domain errors reach the caller with the status they declared,
|
|
7
13
|
* without each dispatcher wrapping its own body in try/catch.
|
|
8
14
|
*/
|
|
9
|
-
export const publicProcedure = t.procedure.use(async ({ next }) => {
|
|
10
|
-
const result = await next();
|
|
15
|
+
export const publicProcedure = t.procedure.use(async ({ ctx, path, next }) => {
|
|
16
|
+
const result = ctx.around ? await ctx.around({ path }, () => next()) : await next();
|
|
11
17
|
if (!result.ok && isRpcCodedError(result.error.cause)) {
|
|
12
18
|
const cause = result.error.cause;
|
|
13
19
|
throw new TRPCError({ code: cause.rpcCode, message: cause.message, cause });
|