@superpanel-sdk/runtime 0.2.3 → 0.5.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 +28 -8
- package/dist/builder/codegen/emit.d.ts +29 -11
- package/dist/builder/codegen/emit.js +328 -61
- package/dist/builder/codegen/generate.d.ts +21 -0
- package/dist/builder/codegen/generate.js +152 -20
- 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 +24 -0
- package/dist/builder/company-imports.js +114 -0
- package/dist/builder/compile/compile-sequence.d.ts +59 -8
- package/dist/builder/compile/compile-sequence.js +279 -77
- package/dist/builder/compile/function-code.d.ts +12 -2
- package/dist/builder/compile/function-code.js +87 -39
- package/dist/builder/compile/registry.d.ts +7 -3
- package/dist/builder/compile/registry.js +24 -23
- package/dist/builder/load.d.ts +70 -10
- package/dist/builder/load.js +250 -61
- package/dist/builder/paths.d.ts +3 -0
- package/dist/builder/paths.js +16 -0
- package/dist/builder/schedules.d.ts +23 -0
- package/dist/builder/schedules.js +102 -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 +105 -0
- package/dist/builder/types.d.ts +91 -19
- package/dist/builder/types.js +2 -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/compile/index.js +3 -0
- package/dist/cli/config.d.ts +10 -0
- package/dist/cli/config.js +52 -0
- package/dist/cli/index.js +28 -8
- package/dist/cli/serve/index.d.ts +73 -3
- package/dist/cli/serve/index.js +365 -116
- package/dist/cli/type-gen/index.js +9 -8
- package/dist/compiler.d.ts +7 -0
- package/dist/compiler.js +7 -0
- package/dist/compute-host/compute-host.d.ts +15 -23
- package/dist/compute-host/compute-host.js +25 -28
- 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 +11 -9
- package/dist/compute-host/source-compute-host.js +46 -32
- package/dist/core/case-orchestrator/contact-hours.d.ts +50 -0
- package/dist/core/case-orchestrator/contact-hours.js +108 -0
- package/dist/core/case-orchestrator/follow-ups.d.ts +31 -0
- package/dist/core/case-orchestrator/follow-ups.js +103 -0
- package/dist/core/case-orchestrator/index.d.ts +6 -0
- package/dist/core/case-orchestrator/index.js +6 -0
- package/dist/core/case-orchestrator/render.d.ts +75 -0
- package/dist/core/case-orchestrator/render.js +239 -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/tools.d.ts +29 -0
- package/dist/core/case-orchestrator/tools.js +31 -0
- package/dist/core/case-orchestrator/types.d.ts +753 -0
- package/dist/core/case-orchestrator/types.js +46 -0
- package/dist/core/case-orchestrator/validate.d.ts +11 -0
- package/dist/core/case-orchestrator/validate.js +63 -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 +159 -0
- package/dist/core/context/email-message.js +59 -0
- package/dist/core/context/email.d.ts +97 -0
- package/dist/core/context/email.js +91 -0
- package/dist/core/context/exchanges.d.ts +142 -0
- package/dist/core/context/exchanges.js +63 -0
- package/dist/core/context/instances.d.ts +278 -0
- package/dist/core/context/instances.js +123 -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 +509 -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 +147 -0
- package/dist/core/context/sms.js +57 -0
- package/dist/core/context/types.d.ts +51 -48
- package/dist/core/context/types.js +1 -7
- package/dist/core/conversation/index.d.ts +31 -0
- package/dist/core/conversation/index.js +14 -0
- package/dist/core/functions/define/bind.d.ts +25 -0
- package/dist/core/functions/define/bind.js +14 -0
- package/dist/core/functions/define/case.d.ts +9 -0
- package/dist/core/functions/define/case.js +13 -0
- package/dist/core/functions/define/events.d.ts +20 -0
- package/dist/core/functions/define/events.js +21 -0
- package/dist/core/functions/define/no-case.d.ts +4 -0
- package/dist/core/functions/define/no-case.js +9 -0
- package/dist/core/functions/events.d.ts +247 -0
- package/dist/core/functions/events.js +32 -0
- package/dist/core/functions/func-ref.d.ts +11 -2
- package/dist/core/functions/schedules.d.ts +51 -0
- package/dist/core/functions/schedules.js +20 -0
- package/dist/core/functions/types.d.ts +62 -51
- package/dist/core/functions/types.js +6 -1
- 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 +834 -0
- package/dist/core/page/define.js +477 -0
- package/dist/core/page/ops.d.ts +58 -0
- package/dist/core/page/ops.js +220 -0
- package/dist/core/page/render.d.ts +253 -0
- package/dist/core/page/render.js +840 -0
- package/dist/core/page/time-format.d.ts +19 -0
- package/dist/core/page/time-format.js +41 -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 +642 -0
- package/dist/core/page/typed.js +2 -0
- package/dist/core/page/workspace.d.ts +33 -0
- package/dist/core/page/workspace.js +231 -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 +137 -0
- package/dist/core/party/schema.js +80 -0
- package/dist/core/party/types.d.ts +40 -0
- package/dist/core/party/types.js +15 -0
- package/dist/core/sequence/define.d.ts +57 -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 +113 -0
- package/dist/core/slot/company-metadata.js +563 -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 -24
- package/dist/core/slot/field.js +0 -69
- 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 +16 -0
- package/dist/core/slot/schema-compat.js +112 -0
- package/dist/core/slot/schema.d.ts +409 -76
- package/dist/core/slot/schema.js +178 -10
- package/dist/core/slot/types.d.ts +27 -94
- package/dist/core/slot/value.d.ts +26 -3
- package/dist/core/slot/value.js +89 -57
- package/dist/dev-overlay/protocol.d.ts +41 -8
- package/dist/fn-context/build-context.d.ts +3 -1
- package/dist/fn-context/build-context.js +20 -10
- package/dist/fn-context/fake/empty-api.js +9 -28
- package/dist/fn-context/fake/index.d.ts +11 -4
- package/dist/fn-context/fake/index.js +27 -2
- package/dist/fn-context/fn-params.d.ts +6 -0
- package/dist/fn-context/fn-params.js +13 -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 +18 -8
- package/dist/fn-context/rpc/case-orchestrator-tools.d.ts +24 -0
- package/dist/fn-context/rpc/case-orchestrator-tools.js +13 -0
- package/dist/fn-context/rpc/index.d.ts +3 -1
- package/dist/fn-context/rpc/index.js +3 -1
- package/dist/fn-context/rpc/integration/index.d.ts +4 -4
- 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/platform.d.ts +2 -2
- package/dist/fn-context/rpc/platform.js +1 -1
- package/dist/fn-context/rpc/records.d.ts +78 -0
- package/dist/fn-context/rpc/records.js +26 -0
- package/dist/fn-context/rpc/trpc-client.d.ts +2 -2
- package/dist/fn-context/rpc/trpc-client.js +88 -7
- package/dist/fn-context/rpc/trpc-init.d.ts +2 -2
- package/dist/fn-context/rpc/trpc-router-factory.d.ts +49 -3
- 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 +36 -3
- package/dist/index.d.ts +37 -46
- package/dist/index.js +33 -33
- package/dist/logger.d.ts +7 -0
- package/dist/logger.js +41 -0
- package/dist/platform.d.ts +76 -0
- package/dist/platform.js +56 -0
- package/dist/voice-service/actions.d.ts +71 -4
- package/dist/voice-service/types.d.ts +42 -5
- package/dist/worker.d.ts +10 -0
- package/dist/worker.js +10 -0
- package/package.json +38 -19
- 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/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
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { isSystemEventName, systemEventKind } from '../../core/functions/events.js';
|
|
2
|
+
import { compileEventModuleCode, compileFunctionCode, compileFunctionModuleCode } from './function-code.js';
|
|
3
3
|
function withCode(entry, code) {
|
|
4
4
|
if (code === undefined)
|
|
5
5
|
return entry;
|
|
@@ -18,31 +18,32 @@ export async function toFunctionRegistry(functions, options = {}) {
|
|
|
18
18
|
? await compileFunctionModuleCode(options.modulePath, name)
|
|
19
19
|
: await compileFunctionCode(def.main)
|
|
20
20
|
: undefined;
|
|
21
|
-
|
|
22
|
-
if (def.kind === 'custom') {
|
|
23
|
-
entry = withCode({ kind: 'custom', writes: [] }, code);
|
|
24
|
-
}
|
|
25
|
-
else if (def.kind === 'system') {
|
|
26
|
-
entry = withCode({ kind: 'system' }, code);
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
entry = withCode({ kind: def.kind }, code);
|
|
30
|
-
}
|
|
21
|
+
const entry = withCode({ kind: def.kind }, code);
|
|
31
22
|
out[name] = entry;
|
|
32
23
|
}
|
|
33
24
|
return out;
|
|
34
25
|
}
|
|
35
|
-
/**
|
|
36
|
-
export
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Project the company `events` export → JSON-safe registry. The kind of each
|
|
28
|
+
* handler is fixed by the platform event table (`case` / `noCase`), not by the author.
|
|
29
|
+
*/
|
|
30
|
+
export async function toEventRegistry(events, options = {}) {
|
|
31
|
+
const includeCode = options.includeCode ?? true;
|
|
32
|
+
const out = {};
|
|
33
|
+
for (const [name, handler] of Object.entries(events)) {
|
|
34
|
+
if (!isSystemEventName(name)) {
|
|
35
|
+
throw new Error(`events: '${name}' is not a platform event`);
|
|
36
|
+
}
|
|
37
|
+
if (typeof handler !== 'function') {
|
|
38
|
+
throw new Error(`events: handler for '${name}' must be a function`);
|
|
39
|
+
}
|
|
40
|
+
const code = includeCode
|
|
41
|
+
? options.modulePath
|
|
42
|
+
? await compileEventModuleCode(options.modulePath, name)
|
|
43
|
+
: await compileFunctionCode(handler)
|
|
44
|
+
: undefined;
|
|
45
|
+
out[name] = withCode({ kind: systemEventKind(name) }, code);
|
|
42
46
|
}
|
|
43
|
-
|
|
44
|
-
? await compileCaseContextViewModuleCode(options.modulePath)
|
|
45
|
-
: await compileFunctionCode(fn);
|
|
46
|
-
return { kind: 'caseContextView', code };
|
|
47
|
+
return out;
|
|
47
48
|
}
|
|
48
49
|
//# sourceMappingURL=registry.js.map
|
package/dist/builder/load.d.ts
CHANGED
|
@@ -1,22 +1,82 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type
|
|
3
|
-
import type {
|
|
4
|
-
|
|
1
|
+
import type { CompanyResolveInput, CompanyResolveResult, ResolveInput, ResolveResult } from '../core/party/schema.js';
|
|
2
|
+
import { type AnyEventHandlers, type WebhookEvent, type WebhookOutcome } from '../core/functions/events.js';
|
|
3
|
+
import type { DefinedNoCaseFunc, FuncMap } from '../core/functions/types.js';
|
|
4
|
+
import { type OfficeHours } from '../core/office-hours/index.js';
|
|
5
|
+
import { type CompanySchema, type SessionSchema } from '../core/slot/schema.js';
|
|
6
|
+
/**
|
|
7
|
+
* A sequence's leftover `slots.ts` (or `slots/index.ts`): the sequence layer has no schema any more
|
|
8
|
+
* (15 §10.17 第 1 条). Its tables and fields are the company's; how a cell is filled is the page's
|
|
9
|
+
* `$extraction`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function assertNoSlotsModule(sequenceDir: string, sequenceId: string): void;
|
|
12
|
+
/** Sequence ids: the directories under `sequences/` with an `index.ts` (`defineSequence`). */
|
|
5
13
|
export declare function listSequenceIds(repoRoot: string): string[];
|
|
6
14
|
export declare function loadCompanySchema(schemaPath: string): Promise<CompanySchema>;
|
|
7
|
-
|
|
15
|
+
/**
|
|
16
|
+
* The company's session fields from `schema/session.ts` (or `schema/session/index.ts`), its
|
|
17
|
+
* `sessionSchema` export (11-remove-sequence-schema §3.1). No file: sessions have no fields.
|
|
18
|
+
*/
|
|
19
|
+
export declare function loadSessionSchema(repoRoot: string): Promise<SessionSchema>;
|
|
20
|
+
/**
|
|
21
|
+
* Sequence office hours from `sequences/<id>/office-hours.ts`. Missing file is `null` (always open).
|
|
22
|
+
* A present file that does not export a valid `officeHours` fails compile.
|
|
23
|
+
*/
|
|
24
|
+
export declare function loadOfficeHours(sequenceDir: string): Promise<OfficeHours | null>;
|
|
8
25
|
/**
|
|
9
26
|
* Load sequence `functions` map from functions.ts or functions/index.ts.
|
|
10
27
|
* Accepts named `functions` or default export FuncMap.
|
|
11
28
|
*/
|
|
12
29
|
export declare function loadSequenceFunctions(functionsPath: string): Promise<FuncMap>;
|
|
13
30
|
/**
|
|
14
|
-
* Load optional `
|
|
31
|
+
* Load optional sequence `events` map from events.ts / events/index.ts.
|
|
32
|
+
* Keys must be platform event names; values are plain handler functions.
|
|
33
|
+
*/
|
|
34
|
+
export declare function loadSequenceEvents(eventsPath: string): Promise<AnyEventHandlers>;
|
|
35
|
+
/**
|
|
36
|
+
* The channels `context.page.ts` has a page function for (17b §9.1). Read from the compiled page code in
|
|
37
|
+
* a context of its own, as the platform runs it: importing the page module here would register its
|
|
38
|
+
* actions in this process, and a second compile would find them named twice. `persona` and `faq` are
|
|
39
|
+
* called when a conversation starts (24 §4), not here.
|
|
40
|
+
*/
|
|
41
|
+
export declare function loadPageChannels(pageCode: string, sequenceId: string): string[];
|
|
42
|
+
/**
|
|
43
|
+
* The Case Orchestrator from orchestrator.ts / orchestrator/index.ts: the entry point (`orchestrator`, or
|
|
44
|
+
* the default export) and `contacts`, whom a Run may contact (required: the platform runs it first).
|
|
45
|
+
*/
|
|
46
|
+
export declare function loadSequenceCaseOrchestrator(caseOrchestratorPath: string): Promise<{
|
|
47
|
+
orchestrator: (...args: never[]) => unknown;
|
|
48
|
+
contacts: (...args: never[]) => unknown;
|
|
49
|
+
}>;
|
|
50
|
+
/** A sequence's `resolve`, registered as a `noCase` function. */
|
|
51
|
+
export declare function loadSequenceResolver(resolvePath: string): Promise<DefinedNoCaseFunc<ResolveInput, ResolveResult>>;
|
|
52
|
+
/** The company `resolve` (§18.2), registered as a `noCase` function of the company part (22 §5). */
|
|
53
|
+
export declare function loadCompanyResolver(resolvePath: string): Promise<DefinedNoCaseFunc<CompanyResolveInput, CompanyResolveResult>>;
|
|
54
|
+
/** The module of the company's webhooks (22 §9) at the repository root. */
|
|
55
|
+
export declare const WEBHOOK_MODULE = "webhook";
|
|
56
|
+
/** `received` of `webhook.ts`, registered as a `noCase` function of the company part. */
|
|
57
|
+
export declare function loadCompanyWebhook(webhookPath: string): Promise<DefinedNoCaseFunc<{
|
|
58
|
+
event: WebhookEvent;
|
|
59
|
+
}, WebhookOutcome>>;
|
|
60
|
+
export declare function isPlatformName(name: string): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* A leftover root `channels.ts` (or `channels/index.ts`): webhook URLs are made and named on the
|
|
63
|
+
* Webhooks page now, like phone numbers, and code refers to them by name only.
|
|
64
|
+
*/
|
|
65
|
+
export declare function assertNoChannelsModule(repoRoot: string): void;
|
|
66
|
+
/**
|
|
67
|
+
* `sequences/<id>/index.ts` default export (`defineSequence({ subject })`): the sequence's business
|
|
68
|
+
* root. Without the file or the declaration, `subject` is undefined and the compile reports it.
|
|
15
69
|
*/
|
|
16
|
-
export declare function
|
|
70
|
+
export declare function loadSequenceDefinition(sequenceDir: string): Promise<{
|
|
71
|
+
subject: unknown;
|
|
72
|
+
label: unknown;
|
|
73
|
+
}>;
|
|
17
74
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
75
|
+
* `sequences/<id>/variables.ts` (14-sequence-instance §4.4): `variables` (from `defineVariables`) and
|
|
76
|
+
* the optional `experiments`. Both undefined without the file.
|
|
20
77
|
*/
|
|
21
|
-
export declare function
|
|
78
|
+
export declare function loadSequenceVariables(sequenceDir: string): Promise<{
|
|
79
|
+
variables: unknown;
|
|
80
|
+
experiments: unknown;
|
|
81
|
+
}>;
|
|
22
82
|
//# sourceMappingURL=load.d.ts.map
|
package/dist/builder/load.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { existsSync, readdirSync, statSync } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { pathToFileURL } from 'node:url';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { runInNewContext } from 'node:vm';
|
|
5
|
+
import { ORCHESTRATOR_FUNCTION } from '../core/case-orchestrator/types.js';
|
|
6
|
+
import { RESOLVE_FUNCTION } from '../core/party/types.js';
|
|
7
|
+
import { isSystemEventName, } from '../core/functions/events.js';
|
|
8
|
+
import { parseOfficeHours } from '../core/office-hours/index.js';
|
|
9
|
+
import { sessionSchemaIssues } from '../core/slot/company-metadata.js';
|
|
10
|
+
import { companySchemaSchema, EMPTY_SESSION_SCHEMA, isCompanySchema, REMOVED_DERIVED_KEYS, REMOVED_IDENTIFIER_KEY, REMOVED_NULLABLE_KEY, REMOVED_SOURCE_KEY, } from '../core/slot/schema.js';
|
|
6
11
|
import { companyImportGraphHref } from './company-import-graph.js';
|
|
7
12
|
import { findTsModule } from './paths.js';
|
|
8
13
|
async function importModule(filePath) {
|
|
@@ -19,32 +24,34 @@ function isFuncMap(value) {
|
|
|
19
24
|
return false;
|
|
20
25
|
}
|
|
21
26
|
const kind = entry.kind;
|
|
22
|
-
if (kind
|
|
27
|
+
if (kind === 'compute' || kind === 'boolCompute') {
|
|
28
|
+
// Compute functions only existed as derived fields' computeFn (13-data-model-v1 §21).
|
|
29
|
+
throw new Error(`functions: ${kind} functions were removed with derived fields; compute it in context.page.ts instead`);
|
|
30
|
+
}
|
|
31
|
+
if (kind !== 'case' && kind !== 'noCase') {
|
|
23
32
|
return false;
|
|
24
33
|
}
|
|
25
34
|
}
|
|
26
35
|
return true;
|
|
27
36
|
}
|
|
28
|
-
function
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
function looksLikeTable(value) {
|
|
32
|
-
return isPlainObject(value) && isPlainObject(value.fields);
|
|
33
|
-
}
|
|
34
|
-
function isCompanySchema(value) {
|
|
35
|
-
if (!isPlainObject(value))
|
|
37
|
+
function isEventHandlers(value) {
|
|
38
|
+
if (value == null || typeof value !== 'object' || Array.isArray(value)) {
|
|
36
39
|
return false;
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
}
|
|
41
|
+
for (const [name, handler] of Object.entries(value)) {
|
|
42
|
+
if (!isSystemEventName(name) || typeof handler !== 'function')
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
return true;
|
|
39
46
|
}
|
|
40
|
-
function
|
|
41
|
-
return
|
|
47
|
+
function isPlainObject(value) {
|
|
48
|
+
return value != null && typeof value === 'object' && !Array.isArray(value);
|
|
42
49
|
}
|
|
43
50
|
/**
|
|
44
51
|
* Resolve the config object from a dynamically imported module.
|
|
45
52
|
*
|
|
46
53
|
* Accepted authoring styles (first match wins):
|
|
47
|
-
* 1. Named export — `export const
|
|
54
|
+
* 1. Named export — `export const companySchema = { … }`
|
|
48
55
|
* 2. Default export is the config
|
|
49
56
|
* 3. Default export is a bag that holds a named key
|
|
50
57
|
*/
|
|
@@ -67,7 +74,17 @@ function pickExport(mod, names, label, isConfig) {
|
|
|
67
74
|
}
|
|
68
75
|
throw new Error(`Could not find ${label} export (${names.join(' | ')}) in module`);
|
|
69
76
|
}
|
|
70
|
-
/**
|
|
77
|
+
/**
|
|
78
|
+
* A sequence's leftover `slots.ts` (or `slots/index.ts`): the sequence layer has no schema any more
|
|
79
|
+
* (15 §10.17 第 1 条). Its tables and fields are the company's; how a cell is filled is the page's
|
|
80
|
+
* `$extraction`.
|
|
81
|
+
*/
|
|
82
|
+
export function assertNoSlotsModule(sequenceDir, sequenceId) {
|
|
83
|
+
if (findTsModule(sequenceDir, 'slots') === undefined)
|
|
84
|
+
return;
|
|
85
|
+
throw new Error(`sequences/${sequenceId}/slots.ts is no longer supported (slots-removed): delete it. Every sequence reads all of the company schema; write how to fill a field on the page in its $extraction, and session fields in schema/session.ts`);
|
|
86
|
+
}
|
|
87
|
+
/** Sequence ids: the directories under `sequences/` with an `index.ts` (`defineSequence`). */
|
|
71
88
|
export function listSequenceIds(repoRoot) {
|
|
72
89
|
const sequencesDir = path.join(repoRoot, 'sequences');
|
|
73
90
|
if (!existsSync(sequencesDir)) {
|
|
@@ -77,7 +94,7 @@ export function listSequenceIds(repoRoot) {
|
|
|
77
94
|
.filter((name) => {
|
|
78
95
|
try {
|
|
79
96
|
return (statSync(path.join(sequencesDir, name)).isDirectory() &&
|
|
80
|
-
findTsModule(path.join(sequencesDir, name), '
|
|
97
|
+
findTsModule(path.join(sequencesDir, name), 'index') !== undefined);
|
|
81
98
|
}
|
|
82
99
|
catch {
|
|
83
100
|
return false;
|
|
@@ -85,13 +102,109 @@ export function listSequenceIds(repoRoot) {
|
|
|
85
102
|
})
|
|
86
103
|
.sort();
|
|
87
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Leftover removed keys, as `table.field: remove …`: derived fields (13-data-model-v1 §21) and
|
|
107
|
+
* `source` (19-page-writable-cells).
|
|
108
|
+
*/
|
|
109
|
+
function leftoverDerivedKeys(value) {
|
|
110
|
+
const leftovers = [];
|
|
111
|
+
if (!isPlainObject(value))
|
|
112
|
+
return leftovers;
|
|
113
|
+
for (const [tableName, table] of Object.entries(value)) {
|
|
114
|
+
const fields = isPlainObject(table) && isPlainObject(table.fields) ? table.fields : {};
|
|
115
|
+
for (const [fieldName, field] of Object.entries(fields)) {
|
|
116
|
+
const keys = isPlainObject(field) ? REMOVED_DERIVED_KEYS.filter((key) => Object.hasOwn(field, key)) : [];
|
|
117
|
+
if (keys.length > 0) {
|
|
118
|
+
leftovers.push(`${tableName}.${fieldName}: remove ${keys.join(', ')} (derived fields were removed)`);
|
|
119
|
+
}
|
|
120
|
+
if (isPlainObject(field) && Object.hasOwn(field, REMOVED_SOURCE_KEY)) {
|
|
121
|
+
leftovers.push(`${tableName}.${fieldName}: remove source (source-removed: a page decides what the AI may write; field(...) opens a cell)`);
|
|
122
|
+
}
|
|
123
|
+
if (isPlainObject(field) && Object.hasOwn(field, REMOVED_NULLABLE_KEY)) {
|
|
124
|
+
leftovers.push(`${tableName}.${fieldName}: remove nullable (nullable-removed: every field starts empty and can be cleared; a page's required says when one must be filled)`);
|
|
125
|
+
}
|
|
126
|
+
if (isPlainObject(field) && Object.hasOwn(field, REMOVED_IDENTIFIER_KEY)) {
|
|
127
|
+
leftovers.push(`${tableName}.${fieldName}: remove identifier (identifier-removed: resolve.ts decides who a conversation is with)`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return leftovers;
|
|
132
|
+
}
|
|
133
|
+
const COMPANY_SCHEMA_EXPORTS = ['companySchema', 'schema'];
|
|
134
|
+
/**
|
|
135
|
+
* Everything the module may offer as its company schema, in {@link pickExport}'s order: the named
|
|
136
|
+
* exports, the default export's named keys, then the default export itself.
|
|
137
|
+
*/
|
|
138
|
+
function companySchemaCandidates(mod) {
|
|
139
|
+
const candidates = COMPANY_SCHEMA_EXPORTS.map((name) => mod[name]);
|
|
140
|
+
const defaultExport = Object.hasOwn(mod, 'default') ? mod.default : undefined;
|
|
141
|
+
if (isPlainObject(defaultExport))
|
|
142
|
+
candidates.push(...COMPANY_SCHEMA_EXPORTS.map((name) => defaultExport[name]));
|
|
143
|
+
candidates.push(defaultExport);
|
|
144
|
+
return candidates.filter((candidate) => candidate !== undefined);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Why none of the candidates parses: the leftover derived keys of the first candidate that has any
|
|
148
|
+
* (a default-exported schema with a table named `schema` is a candidate both as a whole and as that
|
|
149
|
+
* table, so taking the first candidate alone could pick the table), otherwise the first candidate's
|
|
150
|
+
* first Zod issues.
|
|
151
|
+
*/
|
|
152
|
+
function companySchemaProblems(candidates) {
|
|
153
|
+
for (const candidate of candidates) {
|
|
154
|
+
const leftovers = leftoverDerivedKeys(candidate);
|
|
155
|
+
if (leftovers.length > 0)
|
|
156
|
+
return leftovers;
|
|
157
|
+
}
|
|
158
|
+
const issues = companySchemaSchema.safeParse(candidates[0]).error?.issues ?? [];
|
|
159
|
+
return issues.slice(0, 5).map((issue) => `${issue.path.join('.') || '(root)'}: ${issue.message}`);
|
|
160
|
+
}
|
|
88
161
|
export async function loadCompanySchema(schemaPath) {
|
|
89
162
|
const mod = await importModule(schemaPath);
|
|
90
|
-
|
|
163
|
+
try {
|
|
164
|
+
return pickExport(mod, COMPANY_SCHEMA_EXPORTS, 'company schema', isCompanySchema);
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
// Say what is wrong with the schema it does export, in whichever supported form.
|
|
168
|
+
const candidates = companySchemaCandidates(mod);
|
|
169
|
+
if (candidates.length === 0)
|
|
170
|
+
throw error;
|
|
171
|
+
throw new Error(`Invalid company schema in ${schemaPath}: ${companySchemaProblems(candidates).join('; ')}`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* The company's session fields from `schema/session.ts` (or `schema/session/index.ts`), its
|
|
176
|
+
* `sessionSchema` export (11-remove-sequence-schema §3.1). No file: sessions have no fields.
|
|
177
|
+
*/
|
|
178
|
+
export async function loadSessionSchema(repoRoot) {
|
|
179
|
+
const filePath = findTsModule(path.join(repoRoot, 'schema'), 'session');
|
|
180
|
+
if (!filePath)
|
|
181
|
+
return EMPTY_SESSION_SCHEMA;
|
|
182
|
+
const mod = await importModule(filePath);
|
|
183
|
+
if (!Object.hasOwn(mod, 'sessionSchema')) {
|
|
184
|
+
throw new Error(`Could not find sessionSchema export in ${filePath}`);
|
|
185
|
+
}
|
|
186
|
+
const issues = sessionSchemaIssues(mod.sessionSchema);
|
|
187
|
+
if (issues.length > 0)
|
|
188
|
+
throw new Error(issues.map((issue) => issue.message).join('; '));
|
|
189
|
+
return mod.sessionSchema;
|
|
91
190
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
191
|
+
/**
|
|
192
|
+
* Sequence office hours from `sequences/<id>/office-hours.ts`. Missing file is `null` (always open).
|
|
193
|
+
* A present file that does not export a valid `officeHours` fails compile.
|
|
194
|
+
*/
|
|
195
|
+
export async function loadOfficeHours(sequenceDir) {
|
|
196
|
+
const filePath = findTsModule(sequenceDir, 'office-hours');
|
|
197
|
+
if (!filePath)
|
|
198
|
+
return null;
|
|
199
|
+
const mod = await importModule(filePath);
|
|
200
|
+
if (!Object.hasOwn(mod, 'officeHours')) {
|
|
201
|
+
throw new Error(`Could not find officeHours export in ${filePath}`);
|
|
202
|
+
}
|
|
203
|
+
const parsed = parseOfficeHours(mod.officeHours);
|
|
204
|
+
if (!parsed.ok) {
|
|
205
|
+
throw new Error(`office-hours.ts: ${parsed.issues.join('; ')}`);
|
|
206
|
+
}
|
|
207
|
+
return parsed.value;
|
|
95
208
|
}
|
|
96
209
|
/**
|
|
97
210
|
* Load sequence `functions` map from functions.ts or functions/index.ts.
|
|
@@ -115,55 +228,131 @@ export async function loadSequenceFunctions(functionsPath) {
|
|
|
115
228
|
throw new Error(`Could not find functions export (functions | default) as a FuncMap in ${functionsPath}`);
|
|
116
229
|
}
|
|
117
230
|
/**
|
|
118
|
-
* Load optional `
|
|
231
|
+
* Load optional sequence `events` map from events.ts / events/index.ts.
|
|
232
|
+
* Keys must be platform event names; values are plain handler functions.
|
|
119
233
|
*/
|
|
120
|
-
export async function
|
|
121
|
-
const mod = await importModule(
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
234
|
+
export async function loadSequenceEvents(eventsPath) {
|
|
235
|
+
const mod = await importModule(eventsPath);
|
|
236
|
+
for (const handlers of [mod.events, mod.default, mod.default?.events]) {
|
|
237
|
+
if (isPlainObject(handlers) && Object.hasOwn(handlers, 'webhook.received')) {
|
|
238
|
+
throw new Error(`${eventsPath}: webhook.received is no longer a sequence event; export received from ${WEBHOOK_MODULE}.ts at the repository root (22 §9)`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (Object.hasOwn(mod, 'events')) {
|
|
242
|
+
if (isEventHandlers(mod.events))
|
|
243
|
+
return mod.events;
|
|
244
|
+
throw new Error(`events export in ${eventsPath} has unknown event names or non-function handlers`);
|
|
245
|
+
}
|
|
125
246
|
const defaultExport = Object.hasOwn(mod, 'default') ? mod.default : undefined;
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
247
|
+
if (isEventHandlers(defaultExport)) {
|
|
248
|
+
return defaultExport;
|
|
249
|
+
}
|
|
129
250
|
if (defaultExport != null && typeof defaultExport === 'object' && !Array.isArray(defaultExport)) {
|
|
130
|
-
const
|
|
131
|
-
if (
|
|
132
|
-
return
|
|
251
|
+
const bag = defaultExport;
|
|
252
|
+
if (Object.hasOwn(bag, 'events') && isEventHandlers(bag.events)) {
|
|
253
|
+
return bag.events;
|
|
254
|
+
}
|
|
133
255
|
}
|
|
134
|
-
throw new Error(`Could not find
|
|
256
|
+
throw new Error(`Could not find events export (events | default) as an EventHandlers map in ${eventsPath}`);
|
|
135
257
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const
|
|
145
|
-
|
|
258
|
+
/**
|
|
259
|
+
* The channels `context.page.ts` has a page function for (17b §9.1). Read from the compiled page code in
|
|
260
|
+
* a context of its own, as the platform runs it: importing the page module here would register its
|
|
261
|
+
* actions in this process, and a second compile would find them named twice. `persona` and `faq` are
|
|
262
|
+
* called when a conversation starts (24 §4), not here.
|
|
263
|
+
*/
|
|
264
|
+
export function loadPageChannels(pageCode, sequenceId) {
|
|
265
|
+
try {
|
|
266
|
+
const entry = runInNewContext(pageCode);
|
|
267
|
+
// Copied out of the other context: its arrays are not this one's.
|
|
268
|
+
return [...(entry({ mode: 'channels' }).channels ?? [])].map(String);
|
|
269
|
+
}
|
|
270
|
+
catch (error) {
|
|
271
|
+
throw new Error(`sequences/${sequenceId}/context.page.ts: ${error instanceof Error ? error.message : String(error)}`);
|
|
146
272
|
}
|
|
147
|
-
return false;
|
|
148
273
|
}
|
|
149
274
|
/**
|
|
150
|
-
*
|
|
151
|
-
*
|
|
275
|
+
* The Case Orchestrator from orchestrator.ts / orchestrator/index.ts: the entry point (`orchestrator`, or
|
|
276
|
+
* the default export) and `contacts`, whom a Run may contact (required: the platform runs it first).
|
|
152
277
|
*/
|
|
153
|
-
export async function
|
|
154
|
-
const mod = await importModule(
|
|
155
|
-
|
|
156
|
-
|
|
278
|
+
export async function loadSequenceCaseOrchestrator(caseOrchestratorPath) {
|
|
279
|
+
const mod = await importModule(caseOrchestratorPath);
|
|
280
|
+
const orchestrator = [mod[ORCHESTRATOR_FUNCTION], mod.default].find((value) => typeof value === 'function');
|
|
281
|
+
if (!orchestrator) {
|
|
282
|
+
throw new Error(`Could not find ${ORCHESTRATOR_FUNCTION} export (${ORCHESTRATOR_FUNCTION} | default) as a function in ${caseOrchestratorPath}`);
|
|
157
283
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
return defaultExport;
|
|
161
|
-
if (defaultExport != null && typeof defaultExport === 'object' && !Array.isArray(defaultExport)) {
|
|
162
|
-
const bag = defaultExport;
|
|
163
|
-
if (Object.hasOwn(bag, 'agendas') && isAgendasExport(bag.agendas)) {
|
|
164
|
-
return bag.agendas;
|
|
165
|
-
}
|
|
284
|
+
if (typeof mod.contacts !== 'function') {
|
|
285
|
+
throw new Error(`${caseOrchestratorPath}: export contacts, whom a Run may contact: export const contacts: CaseOrchestratorContacts = async (c, ctx) => contactIds`);
|
|
166
286
|
}
|
|
167
|
-
|
|
287
|
+
return { orchestrator: orchestrator, contacts: mod.contacts };
|
|
288
|
+
}
|
|
289
|
+
/** A `resolve.ts` / `resolve/index.ts`: its exported function `resolve` (or the default export). */
|
|
290
|
+
async function loadResolveExport(resolvePath) {
|
|
291
|
+
const mod = await importModule(resolvePath);
|
|
292
|
+
const entry = [mod[RESOLVE_FUNCTION], mod.default].find((value) => typeof value === 'function');
|
|
293
|
+
if (entry)
|
|
294
|
+
return entry;
|
|
295
|
+
throw new Error(`Could not find ${RESOLVE_FUNCTION} export (${RESOLVE_FUNCTION} | default) as a function in ${resolvePath}`);
|
|
296
|
+
}
|
|
297
|
+
/** A sequence's `resolve`, registered as a `noCase` function. */
|
|
298
|
+
export async function loadSequenceResolver(resolvePath) {
|
|
299
|
+
return { kind: 'noCase', main: (await loadResolveExport(resolvePath)) };
|
|
300
|
+
}
|
|
301
|
+
/** The company `resolve` (§18.2), registered as a `noCase` function of the company part (22 §5). */
|
|
302
|
+
export async function loadCompanyResolver(resolvePath) {
|
|
303
|
+
return { kind: 'noCase', main: (await loadResolveExport(resolvePath)) };
|
|
304
|
+
}
|
|
305
|
+
/** The module of the company's webhooks (22 §9) at the repository root. */
|
|
306
|
+
export const WEBHOOK_MODULE = 'webhook';
|
|
307
|
+
/** `received` of `webhook.ts`, registered as a `noCase` function of the company part. */
|
|
308
|
+
export async function loadCompanyWebhook(webhookPath) {
|
|
309
|
+
const mod = await importModule(webhookPath);
|
|
310
|
+
const entry = [mod.received, mod.default].find((value) => typeof value === 'function');
|
|
311
|
+
if (!entry)
|
|
312
|
+
throw new Error(`Could not find received export (received | default) as a function in ${webhookPath}`);
|
|
313
|
+
return { kind: 'noCase', main: entry };
|
|
314
|
+
}
|
|
315
|
+
/** A name the platform keeps (a sequence's directory, a webhook): letters, numbers and single hyphens. */
|
|
316
|
+
const PLATFORM_NAME = /^[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*$/;
|
|
317
|
+
const PLATFORM_NAME_MAX = 40;
|
|
318
|
+
export function isPlatformName(name) {
|
|
319
|
+
return name.length <= PLATFORM_NAME_MAX && PLATFORM_NAME.test(name);
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* A leftover root `channels.ts` (or `channels/index.ts`): webhook URLs are made and named on the
|
|
323
|
+
* Webhooks page now, like phone numbers, and code refers to them by name only.
|
|
324
|
+
*/
|
|
325
|
+
export function assertNoChannelsModule(repoRoot) {
|
|
326
|
+
if (!findTsModule(repoRoot, 'channels'))
|
|
327
|
+
return;
|
|
328
|
+
throw new Error(`channels.ts is no longer supported (channels-removed): delete it. Make webhook URLs on the Webhooks page of each environment and tell them apart in ${WEBHOOK_MODULE}.ts by webhook.name`);
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* `sequences/<id>/index.ts` default export (`defineSequence({ subject })`): the sequence's business
|
|
332
|
+
* root. Without the file or the declaration, `subject` is undefined and the compile reports it.
|
|
333
|
+
*/
|
|
334
|
+
export async function loadSequenceDefinition(sequenceDir) {
|
|
335
|
+
const indexPath = findTsModule(sequenceDir, 'index');
|
|
336
|
+
if (!indexPath)
|
|
337
|
+
return { subject: undefined, label: undefined };
|
|
338
|
+
const mod = await importModule(indexPath);
|
|
339
|
+
const definition = isPlainObject(mod.default) ? mod.default : isPlainObject(mod.sequence) ? mod.sequence : {};
|
|
340
|
+
const { subject, meta } = definition;
|
|
341
|
+
return { subject, label: isPlainObject(meta) ? meta.label : undefined };
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* `sequences/<id>/variables.ts` (14-sequence-instance §4.4): `variables` (from `defineVariables`) and
|
|
345
|
+
* the optional `experiments`. Both undefined without the file.
|
|
346
|
+
*/
|
|
347
|
+
export async function loadSequenceVariables(sequenceDir) {
|
|
348
|
+
const variablesPath = findTsModule(sequenceDir, 'variables');
|
|
349
|
+
if (!variablesPath)
|
|
350
|
+
return { variables: undefined, experiments: undefined };
|
|
351
|
+
const mod = await importModule(variablesPath);
|
|
352
|
+
const bag = isPlainObject(mod.default) ? mod.default : {};
|
|
353
|
+
return {
|
|
354
|
+
variables: mod.variables ?? bag.variables,
|
|
355
|
+
experiments: mod.experiments ?? bag.experiments,
|
|
356
|
+
};
|
|
168
357
|
}
|
|
169
358
|
//# sourceMappingURL=load.js.map
|
package/dist/builder/paths.d.ts
CHANGED
|
@@ -7,4 +7,7 @@ export declare function tsModuleCandidates(dir: string, name: string): string[];
|
|
|
7
7
|
export declare function findTsModule(dir: string, name: string): string | undefined;
|
|
8
8
|
/** Return the first existing candidate, or throw with `missingMessage`. */
|
|
9
9
|
export declare function resolveTsModule(dir: string, name: string, missingMessage: string): string;
|
|
10
|
+
export declare function requireResolveModule(sequenceDir: string, sequenceId: string): string;
|
|
11
|
+
/** The company `resolve.ts` at the repo root (14-sequence-instance §18.2): required. */
|
|
12
|
+
export declare function requireCompanyResolveModule(repoRoot: string): string;
|
|
10
13
|
//# sourceMappingURL=paths.d.ts.map
|
package/dist/builder/paths.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import { RESOLVE_FUNCTION, RESOLVE_MODULE } from '../core/party/types.js';
|
|
3
4
|
/**
|
|
4
5
|
* A TS module may live as `<dir>/<name>.ts` or `<dir>/<name>/index.ts`.
|
|
5
6
|
* File form is preferred when both exist.
|
|
@@ -19,4 +20,19 @@ export function resolveTsModule(dir, name, missingMessage) {
|
|
|
19
20
|
}
|
|
20
21
|
return found;
|
|
21
22
|
}
|
|
23
|
+
export function requireResolveModule(sequenceDir, sequenceId) {
|
|
24
|
+
const resolvePath = findTsModule(sequenceDir, RESOLVE_MODULE);
|
|
25
|
+
if (!resolvePath) {
|
|
26
|
+
throw new Error(`sequences/${sequenceId}/${RESOLVE_MODULE}.ts is required: export ${RESOLVE_FUNCTION} from it to decide which contact and instance a conversation opens on`);
|
|
27
|
+
}
|
|
28
|
+
return resolvePath;
|
|
29
|
+
}
|
|
30
|
+
/** The company `resolve.ts` at the repo root (14-sequence-instance §18.2): required. */
|
|
31
|
+
export function requireCompanyResolveModule(repoRoot) {
|
|
32
|
+
const resolvePath = findTsModule(repoRoot, RESOLVE_MODULE);
|
|
33
|
+
if (!resolvePath) {
|
|
34
|
+
throw new Error(`${RESOLVE_MODULE}.ts is required at the company repo root: export ${RESOLVE_FUNCTION} from it to decide which sequence an inbound conversation goes to`);
|
|
35
|
+
}
|
|
36
|
+
return resolvePath;
|
|
37
|
+
}
|
|
22
38
|
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type ScheduleDefinition, type ScheduleManifest } from '../core/functions/schedules.js';
|
|
2
|
+
import type { FuncMap, FunctionRegistry } from '../core/functions/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Why one job's `cron` / `timezone` cannot run, or `null`. The cron is read by the same parser the
|
|
5
|
+
* worker's job scheduler uses (BullMQ's cron-parser); five fields only, so nothing runs every second.
|
|
6
|
+
*/
|
|
7
|
+
export declare function scheduleTimingIssue(cron: unknown, timezone: unknown): string | null;
|
|
8
|
+
/** Read a `schedules` export: every job named, timed and runnable, else one error listing what is wrong. */
|
|
9
|
+
export declare function parseSchedules(value: unknown, where: string): Record<string, ScheduleDefinition>;
|
|
10
|
+
/** A directory's `schedules.ts`, loaded: what serve runs and what the build records. `null` without the file. */
|
|
11
|
+
export type LoadedSchedules = {
|
|
12
|
+
path: string;
|
|
13
|
+
/** `schedule.<name>` → the job's `run`, as a `noCase` function. */
|
|
14
|
+
functions: FuncMap;
|
|
15
|
+
manifest: ScheduleManifest;
|
|
16
|
+
};
|
|
17
|
+
/** Load and check `<dir>/schedules.ts`; `where` names it in errors (`schedules.ts`, `sequences/pi/schedules.ts`). */
|
|
18
|
+
export declare function loadSchedules(dir: string, where: string): Promise<LoadedSchedules | null>;
|
|
19
|
+
/** The build's registry entries of the jobs: `schedule.<name>` (`code` left out on the serve overlay). */
|
|
20
|
+
export declare function scheduleRegistry(loaded: LoadedSchedules, includeCode: boolean): Promise<FunctionRegistry>;
|
|
21
|
+
/** Authored functions must leave `schedule.*` to `schedules.ts`. */
|
|
22
|
+
export declare function assertNoScheduleNames(names: string[], where: string): void;
|
|
23
|
+
//# sourceMappingURL=schedules.d.ts.map
|