@tailor-platform/sdk 1.74.0 → 1.75.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/CHANGELOG.md +26 -0
- package/dist/application-BJKNlv8c.mjs +3 -0
- package/dist/{application-DwmoI6ZQ.mjs → application-DYshsH-K.mjs} +61 -11
- package/dist/application-DYshsH-K.mjs.map +1 -0
- package/dist/brand-Eo4pLXPJ.mjs.map +1 -1
- package/dist/cli/commands/deploy/workflow-execution-policy.d.mts +1 -0
- package/dist/cli/commands/tailordb/migrate/snapshot.d.mts +1 -16
- package/dist/cli/index.mjs +23 -34
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/lib.d.mts +2 -2
- package/dist/cli/lib.mjs +3 -3
- package/dist/cli/lib.mjs.map +1 -1
- package/dist/completion/zsh-worker.zsh +9 -9
- package/dist/configure/config/types.d.mts +3 -1
- package/dist/configure/index.d.mts +3 -1
- package/dist/configure/index.mjs +113 -5
- package/dist/configure/index.mjs.map +1 -1
- package/dist/configure/services/index.d.mts +3 -1
- package/dist/configure/services/tailordb/schema.d.mts +5 -19
- package/dist/configure/services/workflow/execution-policy.d.mts +71 -0
- package/dist/configure/services/workflow/execution-policy.types.d.mts +104 -0
- package/dist/configure/services/workflow/index.d.mts +3 -1
- package/dist/configure/services/workflow/job.d.mts +7 -3
- package/dist/configure/types/field-runtime.d.mts +17 -0
- package/dist/configure/types/type.d.mts +1 -18
- package/dist/field-runtime-9bfXBAOK.mjs +183 -0
- package/dist/field-runtime-9bfXBAOK.mjs.map +1 -0
- package/dist/{globals-B8XX5TRB.mjs → globals-CcU1ONiK.mjs} +2 -2
- package/dist/globals-CcU1ONiK.mjs.map +1 -0
- package/dist/{job-CtU73PGa.mjs → job-D-PbD1P3.mjs} +5 -3
- package/dist/job-D-PbD1P3.mjs.map +1 -0
- package/dist/plugin/builtin/seed/index.mjs +1 -1
- package/dist/{registry-BozuxbPp.mjs → registry-NfSW0BRo.mjs} +4 -3
- package/dist/registry-NfSW0BRo.mjs.map +1 -0
- package/dist/runtime/globals.d.mts +1 -1
- package/dist/runtime/index.d.mts +1 -1
- package/dist/runtime/workflow.d.mts +22 -3
- package/dist/{runtime-Zkg3SUwi.mjs → runtime-CJ5usBOu.mjs} +456 -397
- package/dist/runtime-CJ5usBOu.mjs.map +1 -0
- package/dist/{schema-DAdZSFOd.mjs → schema-Dl_y0m9e.mjs} +8 -167
- package/dist/schema-Dl_y0m9e.mjs.map +1 -0
- package/dist/secretmanager-Bd45j7an.mjs +98 -0
- package/dist/secretmanager-Bd45j7an.mjs.map +1 -0
- package/dist/{seed-DoMTMLcm.mjs → seed-fm0LeYP2.mjs} +14 -3
- package/dist/seed-fm0LeYP2.mjs.map +1 -0
- package/dist/{service_pb-CIrhGwHk.mjs → service_pb-4unFyubn.mjs} +16 -6
- package/dist/{service_pb-CIrhGwHk.mjs.map → service_pb-4unFyubn.mjs.map} +1 -1
- package/dist/{service_pb-DjwIn4jO.mjs → service_pb-D-PXRoMg.mjs} +1 -1
- package/dist/tailor-proto/src/tailor/v1/service_pb.d.mts +1 -1
- package/dist/tailor-proto/src/tailor/v1/workflow_pb.d.mts +29 -9
- package/dist/tailor-proto/src/tailor/v1/workflow_resource_pb.d.mts +35 -1
- package/dist/types-BwzB2okW.mjs +199 -0
- package/dist/types-BwzB2okW.mjs.map +1 -0
- package/dist/types-KlawuVKa.mjs +4 -0
- package/dist/utils/test/index.mjs +1 -1
- package/dist/utils/test/index.mjs.map +1 -1
- package/dist/vitest/environment.mjs +1 -1
- package/dist/vitest/index.d.mts +8 -1
- package/dist/vitest/index.mjs +779 -1
- package/dist/vitest/index.mjs.map +1 -1
- package/dist/vitest/mock.d.mts +8 -363
- package/dist/vitest/mocks/aigateway.d.mts +30 -0
- package/dist/vitest/mocks/authconnection.d.mts +28 -0
- package/dist/vitest/mocks/file.d.mts +41 -0
- package/dist/vitest/mocks/iconv.d.mts +27 -0
- package/dist/vitest/mocks/idp.d.mts +44 -0
- package/dist/vitest/mocks/secretmanager.d.mts +33 -0
- package/dist/vitest/mocks/tailordb.d.mts +71 -0
- package/dist/vitest/mocks/workflow.d.mts +117 -0
- package/dist/vitest/setup.mjs +2 -2
- package/dist/workflow-DSwnYPPP.mjs.map +1 -1
- package/docs/configuration.md +24 -0
- package/docs/services/workflow.md +78 -0
- package/package.json +8 -8
- package/dist/application-BndtMTFY.mjs +0 -3
- package/dist/application-DwmoI6ZQ.mjs.map +0 -1
- package/dist/field-DOsJCPFa.mjs +0 -22
- package/dist/field-DOsJCPFa.mjs.map +0 -1
- package/dist/globals-B8XX5TRB.mjs.map +0 -1
- package/dist/job-CtU73PGa.mjs.map +0 -1
- package/dist/mock-Ce1GCi4-.mjs +0 -871
- package/dist/mock-Ce1GCi4-.mjs.map +0 -1
- package/dist/registry-BozuxbPp.mjs.map +0 -1
- package/dist/runtime-Zkg3SUwi.mjs.map +0 -1
- package/dist/schema-DAdZSFOd.mjs.map +0 -1
- package/dist/seed-DoMTMLcm.mjs.map +0 -1
- package/dist/types-qhFZ8y9B.mjs +0 -4
- package/dist/types-ywCGpzDZ.mjs +0 -360
- package/dist/types-ywCGpzDZ.mjs.map +0 -1
|
@@ -3,6 +3,7 @@ import { InferFieldsOutput, TypeLevelError, output } from "../../../types/helper
|
|
|
3
3
|
import { FieldOptions, FieldOutput, FieldValidateInput, TailorFieldType, TailorToTs, Validators } from "../../types/field.types.mjs";
|
|
4
4
|
import { DBFieldMetadata, DefinedDBFieldMetadata, ExcludeNestedDBFields, Hook, Hooks, IndexDef, RelationType, SerialConfig, TailorDBField as TailorDBField$1, TailorDBType as TailorDBType$1, TypeFeatures } from "./types.mjs";
|
|
5
5
|
import { AllowedValues, AllowedValuesOutput } from "../../types/field.mjs";
|
|
6
|
+
import { FieldParseArgs, FieldParseInternalArgs } from "../../types/field-runtime.mjs";
|
|
6
7
|
import { PluginConfigs } from "../../../plugin/types.mjs";
|
|
7
8
|
import { TailorTypeGqlPermission, TailorTypePermission } from "./permission.mjs";
|
|
8
9
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
@@ -76,7 +77,7 @@ type WithDBFieldSerial<Defined> = Defined & {
|
|
|
76
77
|
update: false;
|
|
77
78
|
};
|
|
78
79
|
};
|
|
79
|
-
type WithDBFieldCloneOptions<Defined extends DefinedDBFieldMetadata, NewOpt extends FieldOptions> = Omit<Defined, "array"> & {
|
|
80
|
+
type WithDBFieldCloneOptions<Defined extends DefinedDBFieldMetadata, NewOpt extends FieldOptions> = IsAny<Defined> extends true ? Defined : Omit<Defined, "array"> & {
|
|
80
81
|
array: NewOpt extends {
|
|
81
82
|
array: true;
|
|
82
83
|
} ? true : Defined["array"];
|
|
@@ -101,12 +102,12 @@ type DBFieldRelationMethod<Defined extends DefinedDBFieldMetadata, Output> = IsA
|
|
|
101
102
|
} ? TypeLevelError<".relation() has already been set"> : DBFieldRelationFn<Defined, Output>;
|
|
102
103
|
type DBFieldIndexMethod<Defined extends DefinedDBFieldMetadata, Output> = IsAny<Defined> extends true ? DBFieldIndexFn<Defined, Output> : Defined extends {
|
|
103
104
|
index: unknown;
|
|
104
|
-
} ? TypeLevelError<".index() has already been set"> : Defined extends {
|
|
105
|
+
} ? TypeLevelError<".index() has already been set"> : boolean extends Defined["array"] ? DBFieldIndexFn<Defined, Output> | TypeLevelError<"index cannot be set on array fields"> : Defined extends {
|
|
105
106
|
array: true;
|
|
106
107
|
} ? TypeLevelError<"index cannot be set on array fields"> : DBFieldIndexFn<Defined, Output>;
|
|
107
108
|
type DBFieldUniqueMethod<Defined extends DefinedDBFieldMetadata, Output> = IsAny<Defined> extends true ? DBFieldUniqueFn<Defined, Output> : Defined extends {
|
|
108
109
|
unique: unknown;
|
|
109
|
-
} ? TypeLevelError<".unique() has already been set"> : Defined extends {
|
|
110
|
+
} ? TypeLevelError<".unique() has already been set"> : boolean extends Defined["array"] ? DBFieldUniqueFn<Defined, Output> | TypeLevelError<"unique cannot be set on array fields"> : Defined extends {
|
|
110
111
|
array: true;
|
|
111
112
|
} ? TypeLevelError<"unique cannot be set on array fields"> : DBFieldUniqueFn<Defined, Output>;
|
|
112
113
|
type DBFieldVectorMethod<Defined extends DefinedDBFieldMetadata, Output> = IsAny<Defined> extends true ? DBFieldVectorFn<Defined, Output> : Defined extends {
|
|
@@ -213,11 +214,7 @@ interface TailorDBType<Fields extends Record<string, TailorAnyDBField> = any, Us
|
|
|
213
214
|
gqlPermission<U extends object = User, P extends TailorTypeGqlPermission<U> = TailorTypeGqlPermission<U>>(permission: P): TailorDBType<Fields, U>;
|
|
214
215
|
description(description: string): TailorDBType<Fields, User>;
|
|
215
216
|
pickFields<K extends keyof Fields>(keys: K[]): Pick<Fields, K>;
|
|
216
|
-
pickFields<K extends keyof Fields, const Opt extends FieldOptions>(keys: K[], options: Opt): { [P in K]: Fields[P] extends TailorDBField<infer D, infer _O> ? TailorDBField<
|
|
217
|
-
array: Opt extends {
|
|
218
|
-
array: true;
|
|
219
|
-
} ? true : D["array"];
|
|
220
|
-
}, FieldOutput<TailorToTs[D["type"]], Opt>> : never };
|
|
217
|
+
pickFields<K extends keyof Fields, const Opt extends FieldOptions>(keys: K[], options: Opt): { [P in K]: Fields[P] extends TailorDBField<infer D, infer _O> ? TailorDBField<WithDBFieldCloneOptions<D, Opt>, FieldOutput<TailorToTs[D["type"]], Opt>> : never };
|
|
221
218
|
omitFields<K extends keyof Fields>(keys: K[]): Omit<Fields, K>;
|
|
222
219
|
plugin<P extends keyof PluginConfigs<keyof Fields & string>>(config: { [K in P]: PluginConfigs<keyof Fields & string>[K] }): TailorDBType<Fields, User>;
|
|
223
220
|
}
|
|
@@ -240,17 +237,6 @@ type RelationSelfConfig = {
|
|
|
240
237
|
};
|
|
241
238
|
backward?: string;
|
|
242
239
|
};
|
|
243
|
-
type FieldParseArgs = {
|
|
244
|
-
value: unknown;
|
|
245
|
-
data: unknown;
|
|
246
|
-
user: TailorUser;
|
|
247
|
-
};
|
|
248
|
-
type FieldParseInternalArgs = {
|
|
249
|
-
value: any;
|
|
250
|
-
data: unknown;
|
|
251
|
-
user: TailorUser;
|
|
252
|
-
pathArray: string[];
|
|
253
|
-
};
|
|
254
240
|
type DBFieldDefined<T extends TailorFieldType, Opt extends FieldOptions> = {
|
|
255
241
|
type: T;
|
|
256
242
|
array: Opt extends {
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { ExecutionPolicyConcurrency, ExecutionPolicyDefInput, ExecutionPolicyExactInstance, ExecutionPolicyGroupOptions, ExecutionPolicyInstance, ExecutionPolicyWildcardInstance, ResolvedExecutionPolicyInstance } from "./execution-policy.types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/configure/services/workflow/execution-policy.d.ts
|
|
4
|
+
type ResolveKey<Def, Fallback extends string> = Def extends {
|
|
5
|
+
key: infer K extends string;
|
|
6
|
+
} ? K : Fallback;
|
|
7
|
+
type ResolveMatchType<Def> = Def extends {
|
|
8
|
+
matchType: infer M extends "exact" | "prefix";
|
|
9
|
+
} ? M : "exact";
|
|
10
|
+
/**
|
|
11
|
+
* Define a single workflow job function execution policy.
|
|
12
|
+
*
|
|
13
|
+
* Use this when declaring a policy outside the
|
|
14
|
+
* {@link defineWorkflowExecutionPolicies} builder — for example, when the
|
|
15
|
+
* runtime key prefix needs to differ from the corresponding workspace-unique
|
|
16
|
+
* name.
|
|
17
|
+
*
|
|
18
|
+
* When `matchType: "prefix"` is set, the returned instance has `keyFor(suffix)`
|
|
19
|
+
* instead of a directly-usable `key` (see {@link ExecutionPolicyWildcardInstance}).
|
|
20
|
+
* @param name - Workspace-unique name. Must match `^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$`.
|
|
21
|
+
* @param def - Optional overrides for `key` (defaults to `name`), `matchType`, `separator` (the `keyFor` join character, defaults to `.`), and concurrency
|
|
22
|
+
* @returns An execution policy instance
|
|
23
|
+
* @example
|
|
24
|
+
* export const perTenant = defineWorkflowExecutionPolicy("tenant-api", {
|
|
25
|
+
* matchType: "prefix",
|
|
26
|
+
* concurrencyPolicy: { maxConcurrentExecutions: 3 },
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* perTenant.keyFor(tenantId); // "tenant-api.<tenantId>"
|
|
30
|
+
*/
|
|
31
|
+
declare function defineWorkflowExecutionPolicy<const N extends string, const D extends (Omit<ExecutionPolicyDefInput, "name"> & {
|
|
32
|
+
separator?: string;
|
|
33
|
+
}) | undefined = undefined>(name: N, def?: D): ResolvedExecutionPolicyInstance<ResolveKey<D, N>, ResolveMatchType<D>>;
|
|
34
|
+
/**
|
|
35
|
+
* Define a group of workflow job function execution policies. Property names
|
|
36
|
+
* become the workspace-unique `name` and default `key` verbatim, matching the
|
|
37
|
+
* mental model of {@link defineWaitPoints}. Provide `name` / `key` explicitly
|
|
38
|
+
* to override the property-name default (for example, when the property name
|
|
39
|
+
* is not valid for the execution policy grammar or when the runtime key
|
|
40
|
+
* prefix needs to differ).
|
|
41
|
+
*
|
|
42
|
+
* When `matchType: "prefix"` is set, the returned instance has `keyFor(suffix)`
|
|
43
|
+
* instead of a directly-usable `key` (see {@link ExecutionPolicyWildcardInstance}).
|
|
44
|
+
* `matchType` can be combined with an explicit `key`, or left to apply to
|
|
45
|
+
* the property-name-derived prefix.
|
|
46
|
+
*
|
|
47
|
+
* The return type mirrors the builder's return type so JSDoc on each property
|
|
48
|
+
* is preserved in IDE autocompletion.
|
|
49
|
+
* @param builder - Callback that receives a `define` factory and returns a record of policies
|
|
50
|
+
* @param options - Group-wide options; `separator` overrides the `.` `keyFor` uses to join the prefix and suffix for every prefix policy in the group
|
|
51
|
+
* @returns The same object returned by the builder (with `name` / `key` resolved on each instance)
|
|
52
|
+
* @example
|
|
53
|
+
* export const executionPolicies = defineWorkflowExecutionPolicies((define) => ({
|
|
54
|
+
* premium: define({ concurrencyPolicy: { maxConcurrentExecutions: 5 } }),
|
|
55
|
+
* "tenant-api": define({
|
|
56
|
+
* matchType: "prefix",
|
|
57
|
+
* concurrencyPolicy: { maxConcurrentExecutions: 3 },
|
|
58
|
+
* }),
|
|
59
|
+
* }));
|
|
60
|
+
*
|
|
61
|
+
* // In a workflow job function:
|
|
62
|
+
* await tailor.workflow.triggerJobFunction("worker", args, {
|
|
63
|
+
* executionPolicyKey: executionPolicies.premium.key,
|
|
64
|
+
* });
|
|
65
|
+
* await tailor.workflow.triggerJobFunction("worker", args, {
|
|
66
|
+
* executionPolicyKey: executionPolicies["tenant-api"].keyFor(input.tenantId),
|
|
67
|
+
* });
|
|
68
|
+
*/
|
|
69
|
+
declare function defineWorkflowExecutionPolicies<T extends Record<string, ExecutionPolicyInstance>>(builder: (define: <const D extends ExecutionPolicyDefInput | undefined = undefined>(def?: D) => ResolvedExecutionPolicyInstance<ResolveKey<D, string>, ResolveMatchType<D>>) => T, options?: ExecutionPolicyGroupOptions): T;
|
|
70
|
+
//#endregion
|
|
71
|
+
export { type ExecutionPolicyConcurrency, type ExecutionPolicyDefInput, type ExecutionPolicyExactInstance, type ExecutionPolicyGroupOptions, type ExecutionPolicyInstance, type ExecutionPolicyWildcardInstance, type ResolvedExecutionPolicyInstance, defineWorkflowExecutionPolicies, defineWorkflowExecutionPolicy };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { ExecutionPolicyKey } from "../../../runtime/workflow.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/configure/services/workflow/execution-policy.types.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Optional per-key concurrency cap applied to job function dispatches that
|
|
6
|
+
* resolve to a policy's `executionPolicyKey`.
|
|
7
|
+
*/
|
|
8
|
+
interface ExecutionPolicyConcurrency {
|
|
9
|
+
/** Maximum number of concurrent executions allowed per resolved key. */
|
|
10
|
+
maxConcurrentExecutions: number;
|
|
11
|
+
}
|
|
12
|
+
/** Fields shared by both {@link ExecutionPolicyExactInstance} and {@link ExecutionPolicyWildcardInstance}. */
|
|
13
|
+
interface ExecutionPolicyBase {
|
|
14
|
+
/** Workspace-unique name for this policy. */
|
|
15
|
+
readonly name: string;
|
|
16
|
+
/** Optional per-key concurrency cap. */
|
|
17
|
+
readonly concurrencyPolicy?: ExecutionPolicyConcurrency;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* An execution policy declared with `matchType: "exact"` (the default).
|
|
21
|
+
* `key` is branded as {@link ExecutionPolicyKey}, so it can be passed
|
|
22
|
+
* directly as the `executionPolicyKey` option.
|
|
23
|
+
*/
|
|
24
|
+
interface ExecutionPolicyExactInstance<Key extends string = string> extends ExecutionPolicyBase {
|
|
25
|
+
/** Declared key; the platform registers it verbatim. */
|
|
26
|
+
readonly key: Key & ExecutionPolicyKey;
|
|
27
|
+
readonly matchType: "exact";
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* An execution policy declared with `matchType: "prefix"`. The platform
|
|
31
|
+
* registers the declared key prefix with a trailing `*`, and matches every
|
|
32
|
+
* dispatch whose runtime key begins with that prefix. There is no
|
|
33
|
+
* directly-usable `key` — use `keyFor` to build a concrete, branded runtime
|
|
34
|
+
* key at the call site instead of hand-concatenating the prefix and a
|
|
35
|
+
* suffix.
|
|
36
|
+
*/
|
|
37
|
+
interface ExecutionPolicyWildcardInstance extends ExecutionPolicyBase {
|
|
38
|
+
readonly matchType: "prefix";
|
|
39
|
+
/**
|
|
40
|
+
* Build a concrete runtime key by appending `suffix` after this policy's
|
|
41
|
+
* declared key prefix, separated by `.` unless a different separator was
|
|
42
|
+
* configured where this policy was declared.
|
|
43
|
+
* @param suffix - Value appended after the wildcard prefix
|
|
44
|
+
* @returns The concrete key to pass as `executionPolicyKey`
|
|
45
|
+
* @throws If the resulting key does not match the execution policy key
|
|
46
|
+
* grammar (for example, an empty `suffix`)
|
|
47
|
+
* @example
|
|
48
|
+
* // key: "tenant-api", matchType: "prefix"
|
|
49
|
+
* tenantApi.keyFor(tenantId); // "tenant-api.<tenantId>"
|
|
50
|
+
*/
|
|
51
|
+
keyFor(suffix: string): ExecutionPolicyKey;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* A declared workflow job function execution policy — either
|
|
55
|
+
* {@link ExecutionPolicyExactInstance} or {@link ExecutionPolicyWildcardInstance}.
|
|
56
|
+
*/
|
|
57
|
+
type ExecutionPolicyInstance<Key extends string = string> = ExecutionPolicyExactInstance<Key> | ExecutionPolicyWildcardInstance;
|
|
58
|
+
/**
|
|
59
|
+
* Resolves to {@link ExecutionPolicyWildcardInstance} when `MatchType` is
|
|
60
|
+
* known at the type level to be `"prefix"`, to {@link ExecutionPolicyExactInstance}
|
|
61
|
+
* when it's known to be `"exact"`, or to their union when `MatchType` is the
|
|
62
|
+
* unnarrowed `"exact" | "prefix"` (e.g. a caller passed a non-literal
|
|
63
|
+
* `matchType`) — narrowing to one branch in that case would claim a `key` or
|
|
64
|
+
* `keyFor` that may not exist on the actual runtime instance.
|
|
65
|
+
*/
|
|
66
|
+
type ResolvedExecutionPolicyInstance<Key extends string, MatchType extends "exact" | "prefix"> = "exact" | "prefix" extends MatchType ? ExecutionPolicyExactInstance<Key> | ExecutionPolicyWildcardInstance : MatchType extends "prefix" ? ExecutionPolicyWildcardInstance : ExecutionPolicyExactInstance<Key>;
|
|
67
|
+
/**
|
|
68
|
+
* Body of an execution policy declaration.
|
|
69
|
+
*
|
|
70
|
+
* When both `name` and `key` are omitted in the `defineWorkflowExecutionPolicies`
|
|
71
|
+
* builder, the property name is used verbatim for both (like
|
|
72
|
+
* `defineWaitPoints`). Provide `name` when the property identifier is not
|
|
73
|
+
* valid execution policy grammar, and provide `key` when the runtime key
|
|
74
|
+
* prefix needs to differ from `name` (e.g. it needs `:` or `.`).
|
|
75
|
+
*/
|
|
76
|
+
interface ExecutionPolicyDefInput {
|
|
77
|
+
/** Overrides the property-name-derived `name`. 3-63 characters from `[a-z0-9-]`; must start and end with `[a-z0-9]`. */
|
|
78
|
+
name?: string;
|
|
79
|
+
/** Overrides the property-name-derived `key` prefix. Independent of `matchType` — both may be set together. */
|
|
80
|
+
key?: string;
|
|
81
|
+
/**
|
|
82
|
+
* `"exact"` (the default) matches a dispatch whose runtime key equals
|
|
83
|
+
* `key` (or the resolved `name`, if `key` is omitted). `"prefix"`
|
|
84
|
+
* registers `key` as a wildcard prefix — the platform appends a trailing
|
|
85
|
+
* `*`, and the resulting instance exposes `keyFor(suffix)` to build
|
|
86
|
+
* concrete dispatch keys instead of a directly-usable `key`.
|
|
87
|
+
*/
|
|
88
|
+
matchType?: "exact" | "prefix";
|
|
89
|
+
/** Optional per-key concurrency cap. */
|
|
90
|
+
concurrencyPolicy?: ExecutionPolicyConcurrency;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Options for {@link defineWorkflowExecutionPolicies}, applying to every
|
|
94
|
+
* policy declared by the builder (not settable per policy).
|
|
95
|
+
*/
|
|
96
|
+
interface ExecutionPolicyGroupOptions {
|
|
97
|
+
/**
|
|
98
|
+
* Separator `keyFor(suffix)` inserts between a wildcard policy's declared
|
|
99
|
+
* `key` prefix and `suffix`. Defaults to `.`.
|
|
100
|
+
*/
|
|
101
|
+
separator?: string;
|
|
102
|
+
}
|
|
103
|
+
//#endregion
|
|
104
|
+
export { ExecutionPolicyConcurrency, ExecutionPolicyDefInput, ExecutionPolicyExactInstance, ExecutionPolicyGroupOptions, ExecutionPolicyInstance, ExecutionPolicyWildcardInstance, ResolvedExecutionPolicyInstance };
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { ExecutionPolicyConcurrency, ExecutionPolicyDefInput, ExecutionPolicyExactInstance, ExecutionPolicyGroupOptions, ExecutionPolicyInstance, ExecutionPolicyWildcardInstance, ResolvedExecutionPolicyInstance } from "./execution-policy.types.mjs";
|
|
1
2
|
import { WorkflowServiceConfig, WorkflowServiceInput } from "../../config/types.mjs";
|
|
2
3
|
import { ConcurrencyPolicy, RetryPolicy } from "../../../types/workflow.generated.mjs";
|
|
3
4
|
import { WORKFLOW_TEST_ENV_KEY } from "./test-env-key.mjs";
|
|
4
5
|
import { WorkflowJob, WorkflowJobContext, createWorkflowJob } from "./job.mjs";
|
|
5
6
|
import { Workflow, WorkflowConfig, createWorkflow } from "./workflow.mjs";
|
|
7
|
+
import { defineWorkflowExecutionPolicies, defineWorkflowExecutionPolicy } from "./execution-policy.mjs";
|
|
6
8
|
import { WaitPointInstance, defineWaitPoint, defineWaitPoints } from "./wait-point.mjs";
|
|
7
|
-
export { type ConcurrencyPolicy, type RetryPolicy, WORKFLOW_TEST_ENV_KEY, WaitPointInstance, Workflow, WorkflowConfig, WorkflowJob, WorkflowJobContext, type WorkflowServiceConfig, type WorkflowServiceInput, createWorkflow, createWorkflowJob, defineWaitPoint, defineWaitPoints };
|
|
9
|
+
export { type ConcurrencyPolicy, type ExecutionPolicyConcurrency, type ExecutionPolicyDefInput, type ExecutionPolicyExactInstance, type ExecutionPolicyGroupOptions, type ExecutionPolicyInstance, type ExecutionPolicyWildcardInstance, type ResolvedExecutionPolicyInstance, type RetryPolicy, WORKFLOW_TEST_ENV_KEY, WaitPointInstance, Workflow, WorkflowConfig, WorkflowJob, WorkflowJobContext, type WorkflowServiceConfig, type WorkflowServiceInput, createWorkflow, createWorkflowJob, defineWaitPoint, defineWaitPoints, defineWorkflowExecutionPolicies, defineWorkflowExecutionPolicy };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { TailorEnv, TailorInvoker } from "../../../runtime/types.mjs";
|
|
2
2
|
import { JsonCompatible, TypeLevelError } from "../../../types/helpers.mjs";
|
|
3
|
+
import { TriggerJobFunctionOptions } from "../../../runtime/workflow.mjs";
|
|
3
4
|
import { WORKFLOW_TEST_ENV_KEY } from "./test-env-key.mjs";
|
|
4
5
|
|
|
5
6
|
//#region src/configure/services/workflow/job.d.ts
|
|
@@ -28,15 +29,18 @@ interface WorkflowJob<Name extends string = string, Input = undefined, Output =
|
|
|
28
29
|
name: Name;
|
|
29
30
|
/**
|
|
30
31
|
* Trigger this job with the given input. Returns a Promise that resolves
|
|
31
|
-
* to the job's output value.
|
|
32
|
+
* to the job's output value. Accepts an optional second argument to pass
|
|
33
|
+
* `executionPolicyKey` for platform-side concurrency enforcement.
|
|
32
34
|
* @example
|
|
33
35
|
* body: async (input) => {
|
|
34
36
|
* const a = await jobA.trigger({ id: input.id });
|
|
35
|
-
* const b = await jobB.trigger({ id: input.id }
|
|
37
|
+
* const b = await jobB.trigger({ id: input.id }, {
|
|
38
|
+
* executionPolicyKey: `tenant-api.${input.tenantId}`,
|
|
39
|
+
* });
|
|
36
40
|
* return { a, b };
|
|
37
41
|
* }
|
|
38
42
|
*/
|
|
39
|
-
trigger: [Input] extends [undefined] ? () => Promise<Awaited<Output>> : (input: Input) => Promise<Awaited<Output>>;
|
|
43
|
+
trigger: [Input] extends [undefined] ? (input?: undefined, options?: TriggerJobFunctionOptions) => Promise<Awaited<Output>> : (input: Input, options?: TriggerJobFunctionOptions) => Promise<Awaited<Output>>;
|
|
40
44
|
body: (input: Input, context: WorkflowJobContext) => Output | Promise<Output>;
|
|
41
45
|
}
|
|
42
46
|
interface CreateWorkflowJobConfig<Name extends string, I, O> {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { TailorUser } from "../../runtime/types.mjs";
|
|
2
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
3
|
+
|
|
4
|
+
//#region src/configure/types/field-runtime.d.ts
|
|
5
|
+
type FieldParseArgs = {
|
|
6
|
+
value: unknown;
|
|
7
|
+
data: unknown;
|
|
8
|
+
user: TailorUser;
|
|
9
|
+
};
|
|
10
|
+
type FieldParseInternalArgs = {
|
|
11
|
+
value: unknown;
|
|
12
|
+
data: unknown;
|
|
13
|
+
user: TailorUser;
|
|
14
|
+
pathArray: string[];
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
export { FieldParseArgs, FieldParseInternalArgs };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { TailorUser } from "../../runtime/types.mjs";
|
|
2
1
|
import { TypeLevelError } from "../../types/helpers.mjs";
|
|
3
2
|
import { DefinedFieldMetadata, FieldMetadata, FieldValidateInput, TailorField as TailorField$1, TailorFieldType } from "./field.types.mjs";
|
|
3
|
+
import { FieldParseArgs, FieldParseInternalArgs } from "./field-runtime.mjs";
|
|
4
4
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
5
5
|
|
|
6
6
|
//#region src/configure/types/type.d.ts
|
|
@@ -78,22 +78,5 @@ interface TailorField<Defined extends DefinedFieldMetadata = DefinedFieldMetadat
|
|
|
78
78
|
*/
|
|
79
79
|
_parseInternal(args: FieldParseInternalArgs): StandardSchemaV1.Result<Output>;
|
|
80
80
|
}
|
|
81
|
-
type FieldParseArgs = {
|
|
82
|
-
value: unknown;
|
|
83
|
-
data: unknown;
|
|
84
|
-
user: TailorUser;
|
|
85
|
-
};
|
|
86
|
-
type FieldParseInternalArgs = {
|
|
87
|
-
value: any;
|
|
88
|
-
data: unknown;
|
|
89
|
-
user: TailorUser;
|
|
90
|
-
pathArray: string[];
|
|
91
|
-
};
|
|
92
|
-
/**
|
|
93
|
-
* Create a UUID field for resolver input/output.
|
|
94
|
-
* @param options - Field configuration options
|
|
95
|
-
* @returns A UUID field
|
|
96
|
-
* @example t.uuid()
|
|
97
|
-
*/
|
|
98
81
|
//#endregion
|
|
99
82
|
export { TailorAnyField, TailorField };
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
//#region src/configure/types/field.ts
|
|
2
|
+
/**
|
|
3
|
+
* Normalize allowed values into EnumValue objects with descriptions.
|
|
4
|
+
* @param values - Allowed values as strings or EnumValue objects
|
|
5
|
+
* @returns Normalized allowed values
|
|
6
|
+
*/
|
|
7
|
+
function mapAllowedValues(values) {
|
|
8
|
+
return values.map((value) => {
|
|
9
|
+
if (typeof value === "string") return {
|
|
10
|
+
value,
|
|
11
|
+
description: ""
|
|
12
|
+
};
|
|
13
|
+
return {
|
|
14
|
+
...value,
|
|
15
|
+
description: value.description ?? ""
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/configure/types/field-runtime.ts
|
|
22
|
+
const regex = {
|
|
23
|
+
uuid: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
|
|
24
|
+
date: /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/,
|
|
25
|
+
time: /^(?<hour>\d{2}):(?<minute>\d{2})$/,
|
|
26
|
+
datetime: /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})T(?<hour>\d{2}):(?<minute>\d{2}):(?<second>\d{2})(.(?<millisec>\d{3}))?Z$/,
|
|
27
|
+
decimal: /^-?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/
|
|
28
|
+
};
|
|
29
|
+
function validateValue(args) {
|
|
30
|
+
const { field, value, data, user, pathArray } = args;
|
|
31
|
+
const issues = [];
|
|
32
|
+
const path = pathArray.length > 0 ? pathArray : void 0;
|
|
33
|
+
switch (field.type) {
|
|
34
|
+
case "string":
|
|
35
|
+
if (typeof value !== "string") issues.push({
|
|
36
|
+
message: `Expected a string: received ${String(value)}`,
|
|
37
|
+
path
|
|
38
|
+
});
|
|
39
|
+
break;
|
|
40
|
+
case "integer":
|
|
41
|
+
if (typeof value !== "number" || !Number.isInteger(value)) issues.push({
|
|
42
|
+
message: `Expected an integer: received ${String(value)}`,
|
|
43
|
+
path
|
|
44
|
+
});
|
|
45
|
+
break;
|
|
46
|
+
case "float":
|
|
47
|
+
if (typeof value !== "number" || !Number.isFinite(value)) issues.push({
|
|
48
|
+
message: `Expected a number: received ${String(value)}`,
|
|
49
|
+
path
|
|
50
|
+
});
|
|
51
|
+
break;
|
|
52
|
+
case "boolean":
|
|
53
|
+
if (typeof value !== "boolean") issues.push({
|
|
54
|
+
message: `Expected a boolean: received ${String(value)}`,
|
|
55
|
+
path
|
|
56
|
+
});
|
|
57
|
+
break;
|
|
58
|
+
case "uuid":
|
|
59
|
+
if (typeof value !== "string" || !regex.uuid.test(value)) issues.push({
|
|
60
|
+
message: `Expected a valid UUID: received ${String(value)}`,
|
|
61
|
+
path
|
|
62
|
+
});
|
|
63
|
+
break;
|
|
64
|
+
case "date":
|
|
65
|
+
if (typeof value !== "string" || !regex.date.test(value)) issues.push({
|
|
66
|
+
message: `Expected to match "yyyy-MM-dd" format: received ${String(value)}`,
|
|
67
|
+
path
|
|
68
|
+
});
|
|
69
|
+
break;
|
|
70
|
+
case "datetime":
|
|
71
|
+
if (typeof value !== "string" || !regex.datetime.test(value)) issues.push({
|
|
72
|
+
message: `Expected to match ISO format: received ${String(value)}`,
|
|
73
|
+
path
|
|
74
|
+
});
|
|
75
|
+
break;
|
|
76
|
+
case "time":
|
|
77
|
+
if (typeof value !== "string" || !regex.time.test(value)) issues.push({
|
|
78
|
+
message: `Expected to match "HH:mm" format: received ${String(value)}`,
|
|
79
|
+
path
|
|
80
|
+
});
|
|
81
|
+
break;
|
|
82
|
+
case "decimal":
|
|
83
|
+
if (typeof value !== "string" || !regex.decimal.test(value)) issues.push({
|
|
84
|
+
message: `Expected a decimal string: received ${String(value)}`,
|
|
85
|
+
path
|
|
86
|
+
});
|
|
87
|
+
break;
|
|
88
|
+
case "enum":
|
|
89
|
+
if (field._metadata.allowedValues) {
|
|
90
|
+
const allowedValues = field._metadata.allowedValues.map((v) => v.value);
|
|
91
|
+
if (typeof value !== "string" || !allowedValues.includes(value)) issues.push({
|
|
92
|
+
message: `Must be one of [${allowedValues.join(", ")}]: received ${String(value)}`,
|
|
93
|
+
path
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
break;
|
|
97
|
+
case "nested":
|
|
98
|
+
if (typeof value !== "object" || value === null || Array.isArray(value) || value instanceof Date) issues.push({
|
|
99
|
+
message: `Expected an object: received ${String(value)}`,
|
|
100
|
+
path
|
|
101
|
+
});
|
|
102
|
+
else if (Object.keys(field.fields).length > 0) for (const [fieldName, nestedField] of Object.entries(field.fields)) {
|
|
103
|
+
const fieldValue = value[fieldName];
|
|
104
|
+
const result = nestedField._parseInternal({
|
|
105
|
+
value: fieldValue,
|
|
106
|
+
data,
|
|
107
|
+
user,
|
|
108
|
+
pathArray: pathArray.concat(fieldName)
|
|
109
|
+
});
|
|
110
|
+
if (result.issues) issues.push(...result.issues);
|
|
111
|
+
}
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
const validateFns = field._metadata.validate;
|
|
115
|
+
if (validateFns && validateFns.length > 0) for (const validateInput of validateFns) {
|
|
116
|
+
const { fn, message } = typeof validateInput === "function" ? {
|
|
117
|
+
fn: validateInput,
|
|
118
|
+
message: "Validation failed"
|
|
119
|
+
} : {
|
|
120
|
+
fn: validateInput[0],
|
|
121
|
+
message: validateInput[1]
|
|
122
|
+
};
|
|
123
|
+
if (!fn({
|
|
124
|
+
value,
|
|
125
|
+
data,
|
|
126
|
+
user
|
|
127
|
+
})) issues.push({
|
|
128
|
+
message,
|
|
129
|
+
path
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
return issues;
|
|
133
|
+
}
|
|
134
|
+
function parseInternal(args) {
|
|
135
|
+
const { field, value, data, user, pathArray } = args;
|
|
136
|
+
const issues = [];
|
|
137
|
+
const path = pathArray.length > 0 ? pathArray : void 0;
|
|
138
|
+
const isNullOrUndefined = value === null || value === void 0;
|
|
139
|
+
if (field._metadata.required && isNullOrUndefined) {
|
|
140
|
+
issues.push({
|
|
141
|
+
message: "Required field is missing",
|
|
142
|
+
path
|
|
143
|
+
});
|
|
144
|
+
return { issues };
|
|
145
|
+
}
|
|
146
|
+
if (!field._metadata.required && isNullOrUndefined) return { value: value ?? null };
|
|
147
|
+
if (field._metadata.array) {
|
|
148
|
+
if (!Array.isArray(value)) {
|
|
149
|
+
issues.push({
|
|
150
|
+
message: "Expected an array",
|
|
151
|
+
path
|
|
152
|
+
});
|
|
153
|
+
return { issues };
|
|
154
|
+
}
|
|
155
|
+
for (let i = 0; i < value.length; i++) {
|
|
156
|
+
const elementValue = value[i];
|
|
157
|
+
const elementIssues = validateValue({
|
|
158
|
+
field,
|
|
159
|
+
value: elementValue,
|
|
160
|
+
data,
|
|
161
|
+
user,
|
|
162
|
+
pathArray: pathArray.concat(`[${i}]`)
|
|
163
|
+
});
|
|
164
|
+
if (elementIssues.length > 0) issues.push(...elementIssues);
|
|
165
|
+
}
|
|
166
|
+
if (issues.length > 0) return { issues };
|
|
167
|
+
return { value };
|
|
168
|
+
}
|
|
169
|
+
const valueIssues = validateValue({
|
|
170
|
+
field,
|
|
171
|
+
value,
|
|
172
|
+
data,
|
|
173
|
+
user,
|
|
174
|
+
pathArray
|
|
175
|
+
});
|
|
176
|
+
issues.push(...valueIssues);
|
|
177
|
+
if (issues.length > 0) return { issues };
|
|
178
|
+
return { value };
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
//#endregion
|
|
182
|
+
export { mapAllowedValues as n, parseInternal as t };
|
|
183
|
+
//# sourceMappingURL=field-runtime-9bfXBAOK.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field-runtime-9bfXBAOK.mjs","names":[],"sources":["../src/configure/types/field.ts","../src/configure/types/field-runtime.ts"],"sourcesContent":["import type { EnumValue } from \"#/configure/types/field.types\";\n\nexport type AllowedValues = readonly [string | EnumValue, ...(string | EnumValue)[]];\n\n/**\n * Normalize allowed values into EnumValue objects with descriptions.\n * @param values - Allowed values as strings or EnumValue objects\n * @returns Normalized allowed values\n */\nexport function mapAllowedValues(values: AllowedValues): EnumValue[] {\n return values.map((value) => {\n if (typeof value === \"string\") {\n return { value, description: \"\" };\n }\n return { ...value, description: value.description ?? \"\" };\n });\n}\n\nexport type AllowedValuesOutput<V extends AllowedValues> = V[number] extends infer T\n ? T extends string\n ? T\n : T extends { value: infer K }\n ? K\n : never\n : never;\n","import type { FieldMetadata, TailorFieldType } from \"#/configure/types/field.types\";\nimport type { TailorUser } from \"#/runtime/types\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\nconst regex = {\n uuid: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,\n date: /^(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})$/,\n time: /^(?<hour>\\d{2}):(?<minute>\\d{2})$/,\n datetime:\n /^(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})T(?<hour>\\d{2}):(?<minute>\\d{2}):(?<second>\\d{2})(.(?<millisec>\\d{3}))?Z$/,\n decimal: /^-?(\\d+\\.?\\d*|\\.\\d+)([eE][+-]?\\d+)?$/,\n} as const;\n\nexport type FieldParseArgs = {\n value: unknown;\n data: unknown;\n user: TailorUser;\n};\n\nexport type FieldParseInternalArgs = {\n value: unknown;\n data: unknown;\n user: TailorUser;\n pathArray: string[];\n};\n\nexport type FieldRuntime<T extends TailorFieldType = TailorFieldType> = {\n readonly type: T;\n readonly fields: Record<string, FieldRuntime>;\n _metadata: FieldMetadata;\n _parseInternal(args: FieldParseInternalArgs): StandardSchemaV1.Result<unknown>;\n};\n\ntype FieldValidateValueArgs<T extends TailorFieldType> = {\n field: FieldRuntime<T>;\n value: unknown;\n data: unknown;\n user: TailorUser;\n pathArray: string[];\n};\n\ntype FieldParseRuntimeArgs<T extends TailorFieldType> = FieldParseInternalArgs & {\n field: FieldRuntime<T>;\n};\n\nfunction validateValue<T extends TailorFieldType>(\n args: FieldValidateValueArgs<T>,\n): StandardSchemaV1.Issue[] {\n const { field, value, data, user, pathArray } = args;\n const issues: StandardSchemaV1.Issue[] = [];\n const path = pathArray.length > 0 ? pathArray : undefined;\n\n switch (field.type) {\n case \"string\":\n if (typeof value !== \"string\") {\n issues.push({\n message: `Expected a string: received ${String(value)}`,\n path,\n });\n }\n break;\n\n case \"integer\":\n if (typeof value !== \"number\" || !Number.isInteger(value)) {\n issues.push({\n message: `Expected an integer: received ${String(value)}`,\n path,\n });\n }\n break;\n\n case \"float\":\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n issues.push({\n message: `Expected a number: received ${String(value)}`,\n path,\n });\n }\n break;\n\n case \"boolean\":\n if (typeof value !== \"boolean\") {\n issues.push({\n message: `Expected a boolean: received ${String(value)}`,\n path,\n });\n }\n break;\n\n case \"uuid\":\n if (typeof value !== \"string\" || !regex.uuid.test(value)) {\n issues.push({\n message: `Expected a valid UUID: received ${String(value)}`,\n path,\n });\n }\n break;\n case \"date\":\n if (typeof value !== \"string\" || !regex.date.test(value)) {\n issues.push({\n message: `Expected to match \"yyyy-MM-dd\" format: received ${String(value)}`,\n path,\n });\n }\n break;\n case \"datetime\":\n if (typeof value !== \"string\" || !regex.datetime.test(value)) {\n issues.push({\n message: `Expected to match ISO format: received ${String(value)}`,\n path,\n });\n }\n break;\n case \"time\":\n if (typeof value !== \"string\" || !regex.time.test(value)) {\n issues.push({\n message: `Expected to match \"HH:mm\" format: received ${String(value)}`,\n path,\n });\n }\n break;\n case \"decimal\":\n if (typeof value !== \"string\" || !regex.decimal.test(value)) {\n issues.push({\n message: `Expected a decimal string: received ${String(value)}`,\n path,\n });\n }\n break;\n\n case \"enum\":\n if (field._metadata.allowedValues) {\n const allowedValues = field._metadata.allowedValues.map((v) => v.value);\n if (typeof value !== \"string\" || !allowedValues.includes(value)) {\n issues.push({\n message: `Must be one of [${allowedValues.join(\", \")}]: received ${String(value)}`,\n path,\n });\n }\n }\n break;\n\n case \"nested\":\n // Runtime input may not match the declared field type.\n // oxlint-disable typescript/no-unnecessary-condition\n if (\n typeof value !== \"object\" ||\n value === null ||\n Array.isArray(value) ||\n value instanceof Date\n ) {\n // oxlint-enable typescript/no-unnecessary-condition\n issues.push({\n message: `Expected an object: received ${String(value)}`,\n path,\n });\n } else if (Object.keys(field.fields).length > 0) {\n for (const [fieldName, nestedField] of Object.entries(field.fields)) {\n const fieldValue = (value as Record<string, unknown>)[fieldName];\n const result = nestedField._parseInternal({\n value: fieldValue,\n data,\n user,\n pathArray: pathArray.concat(fieldName),\n });\n if (result.issues) {\n issues.push(...result.issues);\n }\n }\n }\n break;\n }\n\n const validateFns = field._metadata.validate;\n if (validateFns && validateFns.length > 0) {\n for (const validateInput of validateFns) {\n const { fn, message } =\n typeof validateInput === \"function\"\n ? { fn: validateInput, message: \"Validation failed\" }\n : { fn: validateInput[0], message: validateInput[1] };\n\n if (!fn({ value, data, user })) {\n issues.push({\n message,\n path,\n });\n }\n }\n }\n\n return issues;\n}\n\nexport function parseInternal<T extends TailorFieldType, Output>(\n args: FieldParseRuntimeArgs<T>,\n): StandardSchemaV1.Result<Output> {\n const { field, value, data, user, pathArray } = args;\n const issues: StandardSchemaV1.Issue[] = [];\n const path = pathArray.length > 0 ? pathArray : undefined;\n\n const isNullOrUndefined = value === null || value === undefined;\n if (field._metadata.required && isNullOrUndefined) {\n issues.push({\n message: \"Required field is missing\",\n path,\n });\n return { issues };\n }\n\n if (!field._metadata.required && isNullOrUndefined) {\n return { value: (value ?? null) as Output };\n }\n\n if (field._metadata.array) {\n if (!Array.isArray(value)) {\n issues.push({\n message: \"Expected an array\",\n path,\n });\n return { issues };\n }\n\n for (let i = 0; i < value.length; i++) {\n const elementValue = value[i];\n const elementPath = pathArray.concat(`[${i}]`);\n\n const elementIssues = validateValue({\n field,\n value: elementValue,\n data,\n user,\n pathArray: elementPath,\n });\n if (elementIssues.length > 0) {\n issues.push(...elementIssues);\n }\n }\n\n if (issues.length > 0) {\n return { issues };\n }\n return { value: value as Output };\n }\n\n const valueIssues = validateValue({ field, value, data, user, pathArray });\n issues.push(...valueIssues);\n\n if (issues.length > 0) {\n return { issues };\n }\n\n return { value: value as Output };\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as runRegisteredJob, l as runRegisteredWorkflow } from "./registry-
|
|
1
|
+
import { c as runRegisteredJob, l as runRegisteredWorkflow } from "./registry-NfSW0BRo.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/vitest/workflow-runtime.ts
|
|
4
4
|
function createDefaultWorkflowRuntime() {
|
|
@@ -106,4 +106,4 @@ function cleanupPlatformGlobals(global) {
|
|
|
106
106
|
|
|
107
107
|
//#endregion
|
|
108
108
|
export { cleanupPlatformGlobals as n, installPlatformGlobals as r, RUNTIME_FLAG_KEY as t };
|
|
109
|
-
//# sourceMappingURL=globals-
|
|
109
|
+
//# sourceMappingURL=globals-CcU1ONiK.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"globals-CcU1ONiK.mjs","names":[],"sources":["../src/vitest/workflow-runtime.ts","../src/vitest/globals.ts"],"sourcesContent":["// Default `tailor.workflow` runner installed by the `tailor-runtime` environment.\n// Must stay free of `vitest` (`vi`): it loads via `./globals` in the environment\n// realm where `vi` is unavailable, hence relative imports only (no `@/` alias).\nimport { runRegisteredJob, runRegisteredWorkflow } from \"../configure/services/workflow/registry\";\nimport type { TriggerJobFunctionOptions } from \"../runtime/workflow\";\n\nexport interface DefaultWorkflowRuntime {\n triggerJobFunction: (\n name: string,\n args?: unknown,\n options?: TriggerJobFunctionOptions,\n ) => unknown;\n triggerWorkflow: (name: string, args?: unknown, options?: unknown) => Promise<string>;\n resumeWorkflow: (executionId: string) => Promise<string>;\n wait: (key: string, payload?: unknown) => unknown;\n resolve: (\n executionId: string,\n key: string,\n callback: (payload: unknown) => unknown,\n ) => Promise<void>;\n}\n\nexport function createDefaultWorkflowRuntime(): DefaultWorkflowRuntime {\n return {\n triggerJobFunction: (name, args) => runRegisteredJob(name, args),\n triggerWorkflow: (name, args) => runRegisteredWorkflow(name, args),\n resumeWorkflow: async (executionId: string): Promise<string> => executionId,\n wait: (key: string): unknown => {\n throw new Error(\n `No wait handler for \"${key}\". Acquire mockWorkflow() and call setWaitHandler(...).`,\n );\n },\n resolve: async (): Promise<void> => {\n throw new Error(\n \"No resolve handler. Acquire mockWorkflow() and call setResolveHandler(...).\",\n );\n },\n };\n}\n","/**\n * Base platform globals for the tailor-runtime test environment.\n *\n * This module is intentionally free of any `vitest` (`vi`) dependency so it can\n * be imported from the Vitest *environment* module (which runs in a realm where\n * `vi` is not available). It installs only the always-present structural pieces:\n *\n * - `globalThis.tailor` / `globalThis.tailordb` container objects\n * - `globalThis.tailor.context.getInvoker` default stub\n * - the platform error classes (`TailorErrors`, `TailorErrorMessage`,\n * `TailorDBFileError`)\n * - the `__tailorRuntimeActive` sentinel flag\n *\n * The per-namespace mock behavior (TailorDB client, workflow, secretmanager, …)\n * is installed on demand by the `xMock()` factories in `./mock`, which run in\n * test context where `vi` *is* available.\n */\n\nimport { createDefaultWorkflowRuntime } from \"./workflow-runtime\";\nimport type { ContextInvoker } from \"../runtime/context\";\nimport type { TailorDBFileErrorCode } from \"../runtime/file\";\n\n// Sentinel set when the tailor-runtime environment is active. setup.ts reads it\n// to decide whether to run its blocked-globals lifecycle and config-secret\n// loading.\nexport const RUNTIME_FLAG_KEY = \"__tailorRuntimeActive\";\n\n// ---------------------------------------------------------------------------\n// Error class mocks\n// ---------------------------------------------------------------------------\n\ninterface TailorErrorItem {\n message: string;\n path: (string | number)[];\n}\n\nclass TailorErrorsMock extends Error {\n errors: TailorErrorItem[];\n\n constructor(errors: TailorErrorItem[]) {\n if (!Array.isArray(errors)) {\n throw new TypeError(\"TailorErrors: errors must be an array\");\n }\n const validated = errors.map((e, i) => {\n if (typeof e.message !== \"string\") {\n throw new TypeError(`TailorErrors: errors[${i}].message must be a string`);\n }\n if (!Array.isArray(e.path)) {\n throw new TypeError(`TailorErrors: errors[${i}].path must be an array`);\n }\n return { message: e.message, path: e.path };\n });\n // Match the PF runtime's TailorErrors serialization, which prefixes the\n // JSON payload with \"TailorErrors: \". Other SDK code (e.g. apply\n // integration fixtures) strips this prefix before JSON.parse.\n super(`TailorErrors: ${JSON.stringify({ errors: validated })}`);\n this.name = \"TailorErrors\";\n this.errors = validated;\n }\n}\n\nclass TailorErrorMessageMock extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TailorErrorMessage\";\n }\n}\n\nclass TailorDBFileErrorMock extends Error {\n code?: TailorDBFileErrorCode;\n override cause: unknown;\n\n constructor(message: string, code?: TailorDBFileErrorCode, cause?: unknown) {\n super(message);\n this.name = \"TailorDBFileError\";\n this.code = code;\n this.cause = cause;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Base install / cleanup\n// ---------------------------------------------------------------------------\n\n// Stub-only injection. SDK consumers configure invokers at the body level\n// (resolver/executor/workflow `.body()` `invoker` arg) or, for bundled tests,\n// via `vi.spyOn(globalThis.tailor.context, \"getInvoker\")`.\nfunction defaultGetInvoker(): ContextInvoker | null {\n return null;\n}\n\n/**\n * Install the always-present base platform globals (containers, context stub,\n * error classes, runtime flag). Per-namespace mocks are layered on top by the\n * `xMock()` factories in `./mock`.\n * @param global - The global object to install into (typically `globalThis`)\n */\nexport function installPlatformGlobals(global: typeof globalThis): void {\n const g = global as Record<string, unknown>;\n\n g[RUNTIME_FLAG_KEY] = true;\n\n // Containers. Namespace mocks (secretmanager, …) are added to these by the\n // corresponding `xMock()` on acquisition. `workflow` carries a default runner\n // so `.trigger()` runs the real job chain locally without `mockWorkflow()`;\n // `mockWorkflow()` overlays and restores it.\n g.tailor = {\n context: { getInvoker: defaultGetInvoker },\n workflow: createDefaultWorkflowRuntime(),\n };\n g.tailordb = {};\n\n g.TailorErrors = TailorErrorsMock;\n g.TailorErrorMessage = TailorErrorMessageMock;\n g.TailorDBFileError = TailorDBFileErrorMock;\n}\n\n/**\n * Remove the base platform globals (and anything the namespace mocks layered on\n * top, since they live under the same containers).\n * @param global - The global object to clean up (typically `globalThis`)\n */\nexport function cleanupPlatformGlobals(global: typeof globalThis): void {\n const g = global as Record<string, unknown>;\n delete g.tailordb;\n delete g.tailor;\n delete g.TailorErrors;\n delete g.TailorErrorMessage;\n delete g.TailorDBFileError;\n delete g[RUNTIME_FLAG_KEY];\n}\n"],"mappings":";;;AAsBA,SAAgB,+BAAuD;CACrE,OAAO;EACL,qBAAqB,MAAM,SAAS,iBAAiB,MAAM,IAAI;EAC/D,kBAAkB,MAAM,SAAS,sBAAsB,MAAM,IAAI;EACjE,gBAAgB,OAAO,gBAAyC;EAChE,OAAO,QAAyB;GAC9B,MAAM,IAAI,MACR,wBAAwB,IAAI,wDAC9B;EACF;EACA,SAAS,YAA2B;GAClC,MAAM,IAAI,MACR,6EACF;EACF;CACF;AACF;;;;;;;;;;;;;;;;;;;;;ACbA,MAAa,mBAAmB;AAWhC,IAAM,mBAAN,cAA+B,MAAM;CACnC;CAEA,YAAY,QAA2B;EACrC,IAAI,CAAC,MAAM,QAAQ,MAAM,GACvB,MAAM,IAAI,UAAU,uCAAuC;EAE7D,MAAM,YAAY,OAAO,KAAK,GAAG,MAAM;GACrC,IAAI,OAAO,EAAE,YAAY,UACvB,MAAM,IAAI,UAAU,wBAAwB,EAAE,2BAA2B;GAE3E,IAAI,CAAC,MAAM,QAAQ,EAAE,IAAI,GACvB,MAAM,IAAI,UAAU,wBAAwB,EAAE,wBAAwB;GAExE,OAAO;IAAE,SAAS,EAAE;IAAS,MAAM,EAAE;GAAK;EAC5C,CAAC;EAID,MAAM,iBAAiB,KAAK,UAAU,EAAE,QAAQ,UAAU,CAAC,GAAG;EAC9D,KAAK,OAAO;EACZ,KAAK,SAAS;CAChB;AACF;AAEA,IAAM,yBAAN,cAAqC,MAAM;CACzC,YAAY,SAAiB;EAC3B,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;AAEA,IAAM,wBAAN,cAAoC,MAAM;CACxC;CACA,AAAS;CAET,YAAY,SAAiB,MAA8B,OAAiB;EAC1E,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,OAAO;EACZ,KAAK,QAAQ;CACf;AACF;AASA,SAAS,oBAA2C;CAClD,OAAO;AACT;;;;;;;AAQA,SAAgB,uBAAuB,QAAiC;CACtE,MAAM,IAAI;CAEV,EAAE,oBAAoB;CAMtB,EAAE,SAAS;EACT,SAAS,EAAE,YAAY,kBAAkB;EACzC,UAAU,6BAA6B;CACzC;CACA,EAAE,WAAW,CAAC;CAEd,EAAE,eAAe;CACjB,EAAE,qBAAqB;CACvB,EAAE,oBAAoB;AACxB;;;;;;AAOA,SAAgB,uBAAuB,QAAiC;CACtE,MAAM,IAAI;CACV,OAAO,EAAE;CACT,OAAO,EAAE;CACT,OAAO,EAAE;CACT,OAAO,EAAE;CACT,OAAO,EAAE;CACT,OAAO,EAAE;AACX"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as brandValue } from "./brand-Eo4pLXPJ.mjs";
|
|
2
|
-
import { n as dispatchTriggerJob, o as registerJob } from "./registry-
|
|
2
|
+
import { n as dispatchTriggerJob, o as registerJob } from "./registry-NfSW0BRo.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/configure/services/workflow/job.ts
|
|
5
5
|
/**
|
|
@@ -40,7 +40,9 @@ function createWorkflowJob(config) {
|
|
|
40
40
|
if (!process.env.TAILOR_PLATFORM_BUNDLE) registerJob(config.name, body);
|
|
41
41
|
const trigger = process.env.TAILOR_PLATFORM_BUNDLE ? async () => {
|
|
42
42
|
throw new Error("This workflow job's .trigger() is rewritten at build time and is unavailable in the bundle");
|
|
43
|
-
} : async (args
|
|
43
|
+
} : async function trigger(args, options) {
|
|
44
|
+
return arguments.length >= 2 ? await dispatchTriggerJob(config.name, args, options) : await dispatchTriggerJob(config.name, args);
|
|
45
|
+
};
|
|
44
46
|
return brandValue({
|
|
45
47
|
name: config.name,
|
|
46
48
|
trigger,
|
|
@@ -50,4 +52,4 @@ function createWorkflowJob(config) {
|
|
|
50
52
|
|
|
51
53
|
//#endregion
|
|
52
54
|
export { createWorkflowJob as t };
|
|
53
|
-
//# sourceMappingURL=job-
|
|
55
|
+
//# sourceMappingURL=job-D-PbD1P3.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-D-PbD1P3.mjs","names":[],"sources":["../src/configure/services/workflow/job.ts"],"sourcesContent":["import { brandValue } from \"#/utils/brand\";\nimport { dispatchTriggerJob, registerJob, type RegisteredJobBody } from \"./registry\";\nimport type { TailorEnv, TailorInvoker } from \"#/runtime/types\";\nimport type { TriggerJobFunctionOptions } from \"#/runtime/workflow\";\nimport type { JsonCompatible, TypeLevelError } from \"#/types/helpers\";\n\n/**\n * Context object passed as the second argument to workflow job body functions.\n */\nexport type WorkflowJobContext = {\n env: TailorEnv;\n invoker?: TailorInvoker;\n};\n\n/**\n * The body function type for a workflow job.\n * Resolves to the callable signature when `I` / `O` are JsonValue-compatible,\n * or to a type-level error that surfaces at the `body:` property.\n */\ntype JobBody<I, O> = [null] extends [I]\n ? TypeLevelError<\"Input cannot be null at the top level\">\n : [I] extends [undefined]\n ? [O] extends [JsonCompatible<O> | undefined | void]\n ? (input: I, context: WorkflowJobContext) => O | Promise<O>\n : TypeLevelError<\"Output must be JsonValue-compatible (plain objects/arrays; no class instances or functions)\">\n : [undefined] extends [I]\n ? TypeLevelError<\"Input cannot include undefined at the top level\">\n : [I] extends [JsonCompatible<I>]\n ? [O] extends [JsonCompatible<O> | undefined | void]\n ? (input: I, context: WorkflowJobContext) => O | Promise<O>\n : TypeLevelError<\"Output must be JsonValue-compatible (plain objects/arrays; no class instances or functions)\">\n : TypeLevelError<\"Input must be JsonValue-compatible (plain objects/arrays; no class instances or functions)\">;\n\n/**\n * WorkflowJob represents a job that can be triggered in a workflow.\n *\n * Type constraints:\n * - Input: Must be JsonValue-compatible (plain objects/arrays; no class instances or functions) or undefined.\n * - Output: Must be JsonValue-compatible (plain objects/arrays; no class instances or functions), undefined, or void.\n * - Trigger returns `Awaited<Output>` as-is (no Jsonify transformation).\n */\nexport interface WorkflowJob<Name extends string = string, Input = undefined, Output = undefined> {\n name: Name;\n /**\n * Trigger this job with the given input. Returns a Promise that resolves\n * to the job's output value. Accepts an optional second argument to pass\n * `executionPolicyKey` for platform-side concurrency enforcement.\n * @example\n * body: async (input) => {\n * const a = await jobA.trigger({ id: input.id });\n * const b = await jobB.trigger({ id: input.id }, {\n * executionPolicyKey: `tenant-api.${input.tenantId}`,\n * });\n * return { a, b };\n * }\n */\n trigger: [Input] extends [undefined]\n ? (input?: undefined, options?: TriggerJobFunctionOptions) => Promise<Awaited<Output>>\n : (input: Input, options?: TriggerJobFunctionOptions) => Promise<Awaited<Output>>;\n body: (input: Input, context: WorkflowJobContext) => Output | Promise<Output>;\n}\n\nexport { WORKFLOW_TEST_ENV_KEY } from \"./test-env-key\";\n\ninterface CreateWorkflowJobConfig<Name extends string, I, O> {\n readonly name: Name;\n readonly body: JobBody<I, O>;\n}\n\n/**\n * Create a workflow job definition.\n *\n * All jobs must be named exports from the workflow file.\n * Job names must be unique across the entire project.\n *\n * Input and output must be JsonValue-compatible (primitives, plain objects, arrays).\n * Functions and objects with a `toJSON` method are rejected at the type level;\n * class instances exposing methods are rejected via the property walk.\n * @param config - Job configuration with name and body function.\n * @param config.name - Unique job name across the project.\n * @param config.body - Async function that processes the job input.\n * @returns A WorkflowJob that can be triggered from other jobs.\n * @example\n * // Simple job with async body:\n * export const fetchData = createWorkflowJob({\n * name: \"fetch-data\",\n * body: async (input: { id: string }) => {\n * const db = getDB(\"tailordb\");\n * return await db.selectFrom(\"Table\").selectAll().where(\"id\", \"=\", input.id).executeTakeFirst();\n * },\n * });\n * @example\n * // Orchestrator job that fans out to other jobs.\n * export const orchestrate = createWorkflowJob({\n * name: \"orchestrate\",\n * body: async (input: { orderId: string }) => {\n * const inventory = await checkInventory.trigger({ orderId: input.orderId });\n * const payment = await processPayment.trigger({ orderId: input.orderId });\n * return { inventory, payment };\n * },\n * });\n */\nexport function createWorkflowJob<const Name extends string, I = undefined, O = undefined>(\n config: CreateWorkflowJobConfig<Name, I, O>,\n): WorkflowJob<Name, I, Awaited<O>> {\n const body = config.body as (input: I, context: WorkflowJobContext) => O | Promise<O>;\n\n // Test-only registry/trigger shim; the platform bundle sets the flag so it is DCE'd.\n if (!process.env.TAILOR_PLATFORM_BUNDLE) {\n registerJob(config.name, body as RegisteredJobBody);\n }\n\n const trigger = process.env.TAILOR_PLATFORM_BUNDLE\n ? async () => {\n throw new Error(\n \"This workflow job's .trigger() is rewritten at build time and is unavailable in the bundle\",\n );\n }\n : // Preserve arity: use `arguments.length` (regular function, not arrow) so\n // `.trigger(args, undefined)` is treated as \"options passed\" — matching\n // the bundler rewrite, which forwards the literal `undefined` from the\n // AST as a third argument. Without this, local execution and bundled\n // workflows would hand mocks different call shapes.\n async function trigger(args?: unknown, options?: TriggerJobFunctionOptions) {\n // oxlint-disable-next-line prefer-rest-params\n return (\n arguments.length >= 2\n ? await dispatchTriggerJob(config.name, args, options)\n : await dispatchTriggerJob(config.name, args)\n ) as Awaited<O>;\n };\n\n return brandValue(\n { name: config.name, trigger, body } as WorkflowJob<Name, I, Awaited<O>>,\n \"workflow-job\",\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsGA,SAAgB,kBACd,QACkC;CAClC,MAAM,OAAO,OAAO;CAGpB,IAAI,CAAC,QAAQ,IAAI,wBACf,YAAY,OAAO,MAAM,IAAyB;CAGpD,MAAM,UAAU,QAAQ,IAAI,yBACxB,YAAY;EACV,MAAM,IAAI,MACR,4FACF;CACF,IAMA,eAAe,QAAQ,MAAgB,SAAqC;EAE1E,OACE,UAAU,UAAU,IAChB,MAAM,mBAAmB,OAAO,MAAM,MAAM,OAAO,IACnD,MAAM,mBAAmB,OAAO,MAAM,IAAI;CAElD;CAEJ,OAAO,WACL;EAAE,MAAM,OAAO;EAAM;EAAS;CAAK,GACnC,cACF;AACF"}
|
|
@@ -163,9 +163,10 @@ async function runRegisteredWorkflow(name, args) {
|
|
|
163
163
|
if (workflow) await runRegisteredJob(workflow.mainJobName, args);
|
|
164
164
|
return TRIGGER_DEFAULT;
|
|
165
165
|
}
|
|
166
|
-
function dispatchTriggerJob(name, args) {
|
|
166
|
+
function dispatchTriggerJob(name, args, options) {
|
|
167
167
|
const workflow = currentPlatformWorkflow();
|
|
168
|
-
|
|
168
|
+
if (!workflow) return runRegisteredJob(name, args);
|
|
169
|
+
return arguments.length >= 3 ? workflow.triggerJobFunction(name, args, options) : workflow.triggerJobFunction(name, args);
|
|
169
170
|
}
|
|
170
171
|
function dispatchTriggerWorkflow(name, args, options) {
|
|
171
172
|
const workflow = currentPlatformWorkflow();
|
|
@@ -174,4 +175,4 @@ function dispatchTriggerWorkflow(name, args, options) {
|
|
|
174
175
|
|
|
175
176
|
//#endregion
|
|
176
177
|
export { getRegisteredWorkflow as a, runRegisteredJob as c, buildJobContext as d, clearWorkflowTestEnv as f, getRegisteredJob as i, runRegisteredWorkflow as l, platformSerialize as m, dispatchTriggerJob as n, registerJob as o, writeWorkflowTestEnv as p, dispatchTriggerWorkflow as r, registerWorkflow as s, TRIGGER_DEFAULT as t, WORKFLOW_TEST_ENV_KEY as u };
|
|
177
|
-
//# sourceMappingURL=registry-
|
|
178
|
+
//# sourceMappingURL=registry-NfSW0BRo.mjs.map
|