@diagonal-hq/cli 0.0.0-stage → 0.1.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/LICENSE +28 -0
- package/README.md +94 -2
- package/bin/diagonal.mjs +11 -0
- package/dist/cli.mjs +287550 -0
- package/dist/globals.d.ts +72 -0
- package/dist/index.d.ts +274 -0
- package/dist/index.js +33 -0
- package/dist/sdk-contract.d.ts +14028 -0
- package/dist/workflow/console.d.ts +10 -0
- package/dist/workflow/data.d.ts +114 -0
- package/dist/workflow/errors.d.ts +23 -0
- package/dist/workflow/generated/capabilities.d.ts +2157 -0
- package/dist/workflow/index.d.ts +22 -0
- package/dist/workflow/input.d.ts +168 -0
- package/dist/workflow/notifications.d.ts +47 -0
- package/dist/workflow/serial-transaction-transport.d.ts +10 -0
- package/dist/workflow/testing/index.d.ts +26 -0
- package/dist/workflow/transaction.d.ts +1 -0
- package/dist/workflow/transport.d.ts +5 -0
- package/dist/workflow/workflow.d.ts +103 -0
- package/dist/workflow/workspace.d.ts +3 -0
- package/package.json +38 -4
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import './console';
|
|
2
|
+
export { HostError, WorkflowFailure, fail, validationError } from './errors';
|
|
3
|
+
export { invoke, setTransport, type HostTransport } from './transport';
|
|
4
|
+
export { transaction } from './transaction';
|
|
5
|
+
export { data } from './data';
|
|
6
|
+
export { mail, notification, sms } from './notifications';
|
|
7
|
+
export { InputField, InputSchema, v, type ContentDocument, type ContentNode, type ContentOptions, type FileVisibility, type Infer, type InferInput, type InputFieldKind, type InputFieldSpec, type InputShape, type Money, type RecordScope } from './input';
|
|
8
|
+
export { defineWorkflow, parseWorkflowInput, redirect, respond, validateWorkflowInput, type Identity, type InputErrors, type InputValidator, type RequestContext, type ScriptExecution, type WorkflowContext, type WorkflowDefinition, type WorkflowExecution } from './workflow';
|
|
9
|
+
export * from './generated/capabilities';
|
|
10
|
+
/** The embedding host selects its execution context through its supplied declarations. */
|
|
11
|
+
export interface ScriptHostContext {
|
|
12
|
+
}
|
|
13
|
+
/** Declaration-merged by the generated workspace module with one entry per resource. */
|
|
14
|
+
export interface WorkspaceResources {
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Declaration-merged by the generated workspace module with one entry per notification type:
|
|
18
|
+
* its id, the unions of its template ids (all, email-enabled, and SMS-enabled), and the shape
|
|
19
|
+
* of its variables.
|
|
20
|
+
*/
|
|
21
|
+
export interface WorkspaceNotificationTypes {
|
|
22
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import type { ResourceKey } from './data';
|
|
2
|
+
/**
|
|
3
|
+
* A declared input field, as data. The compiler reads a workflow's input schema from its source
|
|
4
|
+
* and saves each field as a workflow input variable, so the platform validates a run's input
|
|
5
|
+
* against these rules before the script starts. The same data travels with the workflow at run
|
|
6
|
+
* time, where the SDK uses it to coerce string values to the declared types.
|
|
7
|
+
*/
|
|
8
|
+
export interface InputFieldSpec {
|
|
9
|
+
readonly kind: InputFieldKind;
|
|
10
|
+
readonly optional: boolean;
|
|
11
|
+
readonly nullable: boolean;
|
|
12
|
+
/** Validation rules in the platform's rule syntax, such as `min:1` or `regex:/^[a-z]+$/`. */
|
|
13
|
+
readonly rules: readonly string[];
|
|
14
|
+
readonly label?: string;
|
|
15
|
+
readonly description?: string;
|
|
16
|
+
/** `select`: the allowed values. */
|
|
17
|
+
readonly options?: readonly (string | number)[];
|
|
18
|
+
/** `list`: the item field. */
|
|
19
|
+
readonly items?: InputFieldSpec;
|
|
20
|
+
/** `object`: the nested fields. */
|
|
21
|
+
readonly fields?: Readonly<Record<string, InputFieldSpec>>;
|
|
22
|
+
/** `record` and `recordReference`: the resource whose definitions or records the value must match. */
|
|
23
|
+
readonly resource?: string;
|
|
24
|
+
/** `recordReference`: the records the ID can name. The platform default is `active`. */
|
|
25
|
+
readonly scope?: RecordScope;
|
|
26
|
+
/** `file`: the accepted MIME types. */
|
|
27
|
+
readonly accept?: readonly string[];
|
|
28
|
+
/** `file`: the visibility of the file. */
|
|
29
|
+
readonly visibility?: FileVisibility;
|
|
30
|
+
/** `content`: the formatting the document may use. */
|
|
31
|
+
readonly content?: ContentOptions;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* A money value as the platform stores it. It is a type alias, not an interface, so that it is
|
|
35
|
+
* assignable to the open money objects of capability inputs such as `money.format`.
|
|
36
|
+
*/
|
|
37
|
+
export type Money = {
|
|
38
|
+
amount: number;
|
|
39
|
+
currency: string;
|
|
40
|
+
};
|
|
41
|
+
export type InputFieldKind = 'text' | 'email' | 'url' | 'uuid' | 'phone' | 'date' | 'datetime' | 'time' | 'timezone' | 'color' | 'number' | 'integer' | 'money' | 'boolean' | 'select' | 'list' | 'object' | 'record' | 'recordReference' | 'roleReference' | 'file' | 'content';
|
|
42
|
+
/** The records a record ID can name: `active`, `archived` (deleted), or `activeOrArchived` (all). */
|
|
43
|
+
export type RecordScope = 'active' | 'archived' | 'activeOrArchived';
|
|
44
|
+
export type FileVisibility = 'public' | 'private';
|
|
45
|
+
export interface ContentOptions {
|
|
46
|
+
/** `false` allows one paragraph only. The default is `true`. */
|
|
47
|
+
readonly multiLine?: boolean;
|
|
48
|
+
/** The marks the text may use. Each mark is allowed unless it is `false`. */
|
|
49
|
+
readonly extensions?: Readonly<Partial<Record<'bold' | 'italic' | 'strike' | 'underline' | 'link', boolean>>>;
|
|
50
|
+
/** The block nodes the document may use. Each node is allowed unless it is `false`. */
|
|
51
|
+
readonly allowedNodes?: Readonly<Partial<Record<'heading' | 'blockquote' | 'bulletList' | 'orderedList' | 'media', boolean>>>;
|
|
52
|
+
}
|
|
53
|
+
/** A rich text node in the platform's content format. */
|
|
54
|
+
export interface ContentNode {
|
|
55
|
+
type: string;
|
|
56
|
+
attrs?: Record<string, unknown>;
|
|
57
|
+
content?: ContentNode[];
|
|
58
|
+
marks?: {
|
|
59
|
+
type: string;
|
|
60
|
+
attrs?: Record<string, unknown>;
|
|
61
|
+
}[];
|
|
62
|
+
text?: string;
|
|
63
|
+
}
|
|
64
|
+
/** A rich text document in the platform's content format. */
|
|
65
|
+
export interface ContentDocument extends ContentNode {
|
|
66
|
+
type: 'doc';
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* One field of a workflow's input schema. `T` is the value type the handler receives; `O` is
|
|
70
|
+
* whether the key may be absent. Every modifier returns a new field, so a field can be shared.
|
|
71
|
+
*/
|
|
72
|
+
export declare class InputField<T, O extends boolean = false> {
|
|
73
|
+
readonly $spec: InputFieldSpec;
|
|
74
|
+
/** Phantom members that carry the static types; they hold no value at run time. */
|
|
75
|
+
readonly $value: T;
|
|
76
|
+
readonly $optional: O;
|
|
77
|
+
constructor($spec: InputFieldSpec);
|
|
78
|
+
/** The key may be absent. */
|
|
79
|
+
optional(): InputField<T | undefined, true>;
|
|
80
|
+
/** The value may be `null`. */
|
|
81
|
+
nullable(): InputField<T | null, O>;
|
|
82
|
+
/** At least `value`: a number's value, a text's length, or a list's item count. */
|
|
83
|
+
min(value: number): InputField<T, O>;
|
|
84
|
+
/** At most `value`: a number's value, a text's length, or a list's item count. */
|
|
85
|
+
max(value: number): InputField<T, O>;
|
|
86
|
+
/** Between `min` and `max`, inclusive, measured as for `min` and `max`. */
|
|
87
|
+
between(min: number, max: number): InputField<T, O>;
|
|
88
|
+
/** Exactly `value`, measured as for `min` and `max`. */
|
|
89
|
+
size(value: number): InputField<T, O>;
|
|
90
|
+
/** The text matches the pattern. */
|
|
91
|
+
regex(pattern: RegExp): InputField<T, O>;
|
|
92
|
+
/** Any other platform validation rule, such as `starts_with:INV-` or `after:today`. */
|
|
93
|
+
rule(rule: string): InputField<T, O>;
|
|
94
|
+
label(label: string): InputField<T, O>;
|
|
95
|
+
description(description: string): InputField<T, O>;
|
|
96
|
+
}
|
|
97
|
+
export type InputShape = Record<string, InputField<unknown, boolean>>;
|
|
98
|
+
type Simplify<T> = {
|
|
99
|
+
[K in keyof T]: T[K];
|
|
100
|
+
} & {};
|
|
101
|
+
/** The value an input schema describes: optional fields become optional keys. */
|
|
102
|
+
export type InferInput<S extends InputShape> = Simplify<{
|
|
103
|
+
[K in keyof S as S[K]['$optional'] extends true ? never : K]: S[K]['$value'];
|
|
104
|
+
} & {
|
|
105
|
+
[K in keyof S as S[K]['$optional'] extends true ? K : never]?: S[K]['$value'];
|
|
106
|
+
}>;
|
|
107
|
+
/** The value a field or schema describes: `Infer<typeof Input>`. */
|
|
108
|
+
export type Infer<F extends InputField<unknown, boolean>> = F['$value'];
|
|
109
|
+
/** A workflow's input schema: the fields of an object. */
|
|
110
|
+
export declare class InputSchema<S extends InputShape> extends InputField<InferInput<S>> {
|
|
111
|
+
readonly shape: S;
|
|
112
|
+
constructor(shape: S);
|
|
113
|
+
}
|
|
114
|
+
/** Builders for a workflow's input schema. */
|
|
115
|
+
export declare const v: {
|
|
116
|
+
text: () => InputField<string, false>;
|
|
117
|
+
email: () => InputField<string, false>;
|
|
118
|
+
url: () => InputField<string, false>;
|
|
119
|
+
uuid: () => InputField<string, false>;
|
|
120
|
+
phone: () => InputField<string, false>;
|
|
121
|
+
/** A calendar date, `YYYY-MM-DD`. */
|
|
122
|
+
date: () => InputField<string, false>;
|
|
123
|
+
/** A date and time, ISO 8601. */
|
|
124
|
+
datetime: () => InputField<string, false>;
|
|
125
|
+
/** A time of day, `HH:MM`. */
|
|
126
|
+
time: () => InputField<string, false>;
|
|
127
|
+
timezone: () => InputField<string, false>;
|
|
128
|
+
color: () => InputField<string, false>;
|
|
129
|
+
number: () => InputField<number, false>;
|
|
130
|
+
integer: () => InputField<number, false>;
|
|
131
|
+
/** An amount of money: `amount` in the currency's minor units, such as cents, and the lowercase ISO 4217 `currency`. */
|
|
132
|
+
money: () => InputField<Money, false>;
|
|
133
|
+
boolean: () => InputField<boolean, false>;
|
|
134
|
+
/** One of `options`. */
|
|
135
|
+
select: <const V extends readonly (string | number)[]>(options: V) => InputField<V[number], false>;
|
|
136
|
+
/** A list whose items each satisfy `items`. */
|
|
137
|
+
list: <T>(items: InputField<T, boolean>) => InputField<Exclude<T, undefined>[], false>;
|
|
138
|
+
/** An object with the given fields. */
|
|
139
|
+
object: <S extends InputShape>(shape: S) => InputSchema<S>;
|
|
140
|
+
/**
|
|
141
|
+
* The field values of a record of `resource`, checked against that resource's field
|
|
142
|
+
* definitions: types, required fields, and each field's own rules.
|
|
143
|
+
*/
|
|
144
|
+
record: <R extends ResourceKey>(resource: R) => InputField<Record<string, unknown>, false>;
|
|
145
|
+
/** The ID of an existing record of `resource`, in `scope`. */
|
|
146
|
+
recordReference: <R extends ResourceKey>(resource: R, options?: {
|
|
147
|
+
scope?: RecordScope;
|
|
148
|
+
}) => InputField<string, false>;
|
|
149
|
+
/** The ID of an existing role. */
|
|
150
|
+
roleReference: () => InputField<string, false>;
|
|
151
|
+
/**
|
|
152
|
+
* A file: the ID of an existing file, or the temporary path of an upload. A data call that
|
|
153
|
+
* writes the value to a file field of a record finalizes the upload.
|
|
154
|
+
*/
|
|
155
|
+
file: (options?: {
|
|
156
|
+
accept?: readonly string[];
|
|
157
|
+
visibility?: FileVisibility;
|
|
158
|
+
}) => InputField<string, false>;
|
|
159
|
+
/** A rich text document with the formatting that `options` allows. */
|
|
160
|
+
content: (options?: ContentOptions) => InputField<ContentDocument, false>;
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* Converts the string forms a request carries (`"5"`, `"true"`) to the declared types. It runs
|
|
164
|
+
* after the platform validated the input against the same schema, so a value it cannot convert
|
|
165
|
+
* is left as it is.
|
|
166
|
+
*/
|
|
167
|
+
export declare function coerceInput(spec: InputFieldSpec, value: unknown): unknown;
|
|
168
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { ResourceKey } from './data';
|
|
2
|
+
import { type MailSendNotificationInput, type MailSendNotificationOutput, type NotificationSendBulkNotificationsInput, type NotificationSendBulkNotificationsOutput, type NotificationSendNotificationInput, type NotificationSetConsentInput, type NotificationSetConsentOutput, type SmsSendNotificationInput, type SmsSendNotificationOutput } from './generated/capabilities';
|
|
3
|
+
import type { WorkspaceNotificationTypes } from './index';
|
|
4
|
+
type Entry = WorkspaceNotificationTypes[keyof WorkspaceNotificationTypes];
|
|
5
|
+
type Declared = [keyof WorkspaceNotificationTypes] extends [never] ? false : true;
|
|
6
|
+
export type NotificationTypeKey = Declared extends true ? Entry extends {
|
|
7
|
+
id: infer I;
|
|
8
|
+
} ? I : never : string;
|
|
9
|
+
type EntryFor<T> = Extract<Entry, {
|
|
10
|
+
id: T;
|
|
11
|
+
}>;
|
|
12
|
+
/**
|
|
13
|
+
* The template ids of one notification type under `Channel`: every template, or only the
|
|
14
|
+
* templates with email or SMS on. Any string while the workspace declares no types.
|
|
15
|
+
*/
|
|
16
|
+
export type NotificationTemplateKey<T, Channel extends 'template' | 'emailTemplate' | 'smsTemplate' = 'template'> = Declared extends true ? (EntryFor<T> extends Record<Channel, infer K> ? K : never) : string;
|
|
17
|
+
/** The variables one notification type declares; any dictionary while the workspace declares no types. */
|
|
18
|
+
export type NotificationVariables<T> = Declared extends true ? EntryFor<T> extends {
|
|
19
|
+
variables: infer V;
|
|
20
|
+
} ? V : never : Record<string, unknown>;
|
|
21
|
+
type NotificationInput<I, T, Channel extends 'template' | 'emailTemplate' | 'smsTemplate' = 'template'> = Omit<I, 'notificationType' | 'notificationTemplate' | 'variables'> & {
|
|
22
|
+
notificationType: T;
|
|
23
|
+
notificationTemplate?: NotificationTemplateKey<T, Channel>;
|
|
24
|
+
} & ({} extends NotificationVariables<T> ? {
|
|
25
|
+
variables?: NotificationVariables<T>;
|
|
26
|
+
} : {
|
|
27
|
+
variables: NotificationVariables<T>;
|
|
28
|
+
});
|
|
29
|
+
export declare const mail: {
|
|
30
|
+
sendNotification: <T extends NotificationTypeKey>(input: NotificationInput<MailSendNotificationInput, T, "emailTemplate">) => Promise<MailSendNotificationOutput>;
|
|
31
|
+
search: (input: import("./index").MailSearchInput) => Promise<import("./index").MailSearchOutput>;
|
|
32
|
+
send: (input: import("./index").MailSendInput) => Promise<import("./index").MailSendOutput>;
|
|
33
|
+
};
|
|
34
|
+
export declare const notification: {
|
|
35
|
+
sendNotification: <T extends NotificationTypeKey>(input: NotificationInput<NotificationSendNotificationInput, T>) => Promise<boolean>;
|
|
36
|
+
sendBulkNotifications: <T extends NotificationTypeKey, R extends ResourceKey>(input: Omit<NotificationInput<NotificationSendBulkNotificationsInput, T>, "resource"> & {
|
|
37
|
+
resource: R;
|
|
38
|
+
}) => Promise<NotificationSendBulkNotificationsOutput>;
|
|
39
|
+
setConsent: <R extends ResourceKey>(input: Omit<NotificationSetConsentInput, "resource"> & {
|
|
40
|
+
resource: R;
|
|
41
|
+
}) => Promise<NotificationSetConsentOutput>;
|
|
42
|
+
send: (input: import("./index").NotificationSendInput) => Promise<import("./index").NotificationSendOutput>;
|
|
43
|
+
};
|
|
44
|
+
export declare const sms: {
|
|
45
|
+
sendNotification: <T extends NotificationTypeKey>(input: NotificationInput<SmsSendNotificationInput, T, "smsTemplate">) => Promise<SmsSendNotificationOutput>;
|
|
46
|
+
};
|
|
47
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { HostTransport } from './transport';
|
|
2
|
+
export declare class SerialTransactionTransport implements HostTransport {
|
|
3
|
+
private readonly transport;
|
|
4
|
+
private pending;
|
|
5
|
+
private settled;
|
|
6
|
+
private transactionOpen;
|
|
7
|
+
private closing;
|
|
8
|
+
constructor(transport: HostTransport);
|
|
9
|
+
call(name: string, input: Record<string, unknown>): Promise<unknown>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type HostTransport } from '../transport';
|
|
2
|
+
import { type InputValidator, type WorkflowContext, type WorkflowDefinition } from '../workflow';
|
|
3
|
+
export declare class MockTransport implements HostTransport {
|
|
4
|
+
private readonly handlers;
|
|
5
|
+
readonly calls: Array<{
|
|
6
|
+
name: string;
|
|
7
|
+
input: unknown;
|
|
8
|
+
}>;
|
|
9
|
+
constructor(handlers: Partial<Record<string, (input: any) => unknown>>);
|
|
10
|
+
call(name: string, input: Record<string, unknown>): Promise<unknown>;
|
|
11
|
+
}
|
|
12
|
+
export declare function runWorkflow<I, O>(workflow: WorkflowDefinition<I, O>, input: I, options?: {
|
|
13
|
+
transport?: HostTransport;
|
|
14
|
+
context?: Omit<Partial<WorkflowContext>, 'execution'> & {
|
|
15
|
+
execution?: Partial<WorkflowContext['execution']>;
|
|
16
|
+
};
|
|
17
|
+
/** The module's `validateInput` export; it runs before the handler, as in the sandbox. */
|
|
18
|
+
validateInput?: InputValidator<I>;
|
|
19
|
+
}): Promise<O>;
|
|
20
|
+
export declare const fake: {
|
|
21
|
+
reset(): /*elided*/ any;
|
|
22
|
+
email: () => string;
|
|
23
|
+
name: () => string;
|
|
24
|
+
uuid: () => string;
|
|
25
|
+
number: (min?: number, max?: number) => number;
|
|
26
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function transaction<T>(fn: () => Promise<T>): Promise<T>;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { ScriptHostContext } from './index';
|
|
2
|
+
import { type InferInput, type InputFieldSpec, type InputSchema, type InputShape } from './input';
|
|
3
|
+
export interface Identity {
|
|
4
|
+
id: string;
|
|
5
|
+
resourceId: string;
|
|
6
|
+
email: string | null;
|
|
7
|
+
name: string | null;
|
|
8
|
+
permissions: string[];
|
|
9
|
+
}
|
|
10
|
+
export interface RequestContext {
|
|
11
|
+
method: string;
|
|
12
|
+
url: string;
|
|
13
|
+
params: Record<string, string>;
|
|
14
|
+
query: Record<string, unknown>;
|
|
15
|
+
body: Record<string, unknown>;
|
|
16
|
+
headers: Record<string, string>;
|
|
17
|
+
}
|
|
18
|
+
export interface ScriptExecution {
|
|
19
|
+
id: string;
|
|
20
|
+
kind: 'workflow' | 'embedded';
|
|
21
|
+
owner: {
|
|
22
|
+
type: string;
|
|
23
|
+
id: string;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export interface WorkflowExecution extends ScriptExecution {
|
|
27
|
+
kind: 'workflow';
|
|
28
|
+
workflowId: string;
|
|
29
|
+
}
|
|
30
|
+
export interface WorkflowContext {
|
|
31
|
+
user: Identity | null;
|
|
32
|
+
callingUser: Identity | null;
|
|
33
|
+
trigger: Record<string, unknown>;
|
|
34
|
+
request: RequestContext | null;
|
|
35
|
+
workspace: {
|
|
36
|
+
id: string;
|
|
37
|
+
timezone: string;
|
|
38
|
+
};
|
|
39
|
+
execution: ScriptHostContext extends {
|
|
40
|
+
embedded: true;
|
|
41
|
+
} ? ScriptExecution : WorkflowExecution;
|
|
42
|
+
now: string;
|
|
43
|
+
}
|
|
44
|
+
export interface WorkflowDefinition<I, O> {
|
|
45
|
+
readonly $diagonal: 'workflow';
|
|
46
|
+
/** The declared input schema, when the workflow has one. */
|
|
47
|
+
readonly input?: InputFieldSpec;
|
|
48
|
+
/** Runs the handler with input that {@link parseWorkflowInput} already converted. */
|
|
49
|
+
run(input: I, ctx: WorkflowContext): Promise<O>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Converts a run's raw input to the declared types. A runner calls it once and passes the result
|
|
53
|
+
* to both `validateInput` and `run`, so the validator and the handler receive the same input.
|
|
54
|
+
*/
|
|
55
|
+
export declare function parseWorkflowInput<I>(workflow: WorkflowDefinition<I, unknown>, input: unknown): I;
|
|
56
|
+
/**
|
|
57
|
+
* The errors an input validator reports, keyed by input field. A key outside the input's own fields
|
|
58
|
+
* (a nested path such as `tags.0`) is allowed; an empty or absent message means the field is valid.
|
|
59
|
+
*/
|
|
60
|
+
export type InputErrors<I> = Partial<Record<keyof I & string, string | string[]>> & Record<string, string | string[] | undefined>;
|
|
61
|
+
/**
|
|
62
|
+
* The `validateInput` export a script may define beside its workflow. It runs before the handler
|
|
63
|
+
* with the same input and context; when it reports any error, the run ends with a 422 and those
|
|
64
|
+
* errors, and the handler does not run.
|
|
65
|
+
*/
|
|
66
|
+
export type InputValidator<I> = (input: I, ctx: WorkflowContext) => InputErrors<I> | void | Promise<InputErrors<I> | void>;
|
|
67
|
+
/** Runs a script's input validator and ends the run with a validation error when it reports one. */
|
|
68
|
+
export declare function validateWorkflowInput<I>(validator: InputValidator<I>, input: I, ctx: WorkflowContext): Promise<void>;
|
|
69
|
+
type Handler<I, O> = (input: I, ctx: WorkflowContext) => Promise<O> | O;
|
|
70
|
+
/**
|
|
71
|
+
* Declares a workflow. With an input schema first, the platform validates every run's input
|
|
72
|
+
* against it before the script starts, and the handler's `input` type comes from the schema.
|
|
73
|
+
*/
|
|
74
|
+
export declare function defineWorkflow<S extends InputShape, O = unknown>(input: InputSchema<S>, handler: Handler<InferInput<S>, O>): WorkflowDefinition<InferInput<S>, O>;
|
|
75
|
+
export declare function defineWorkflow<I = Record<string, unknown>, O = unknown>(handler: Handler<I, O>): WorkflowDefinition<I, O>;
|
|
76
|
+
export type ResponseOutput = {
|
|
77
|
+
$response_status: number;
|
|
78
|
+
$response_body: unknown;
|
|
79
|
+
$response_content_type: string;
|
|
80
|
+
};
|
|
81
|
+
export type RedirectType = 'internal' | 'external' | 'back';
|
|
82
|
+
export type RedirectOutput = {
|
|
83
|
+
redirect_url: string;
|
|
84
|
+
redirect_type: RedirectType;
|
|
85
|
+
permanent: boolean;
|
|
86
|
+
success?: string;
|
|
87
|
+
};
|
|
88
|
+
export declare function respond(body: unknown, options?: {
|
|
89
|
+
status?: number;
|
|
90
|
+
contentType?: string;
|
|
91
|
+
}): ResponseOutput;
|
|
92
|
+
/**
|
|
93
|
+
* Builds the output of a graph `http.redirect` step, with the same `redirect_type` and
|
|
94
|
+
* `permanent` keys. Without a `type`, a path such as `/done` redirects as `internal`. Any other
|
|
95
|
+
* URL, including a protocol-relative `//host`, redirects as `external`, because an Inertia
|
|
96
|
+
* request cannot follow a plain redirect to another origin. A `back` redirect is never permanent.
|
|
97
|
+
*/
|
|
98
|
+
export declare function redirect(url: string, options?: {
|
|
99
|
+
success?: string;
|
|
100
|
+
type?: RedirectType;
|
|
101
|
+
permanent?: boolean;
|
|
102
|
+
}): RedirectOutput;
|
|
103
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,40 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diagonal-hq/cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "The diagonal CLI and the configuration helpers for file-based Diagonal workspaces.",
|
|
5
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/Diagonal-HQ/diagonal.git",
|
|
9
|
+
"directory": "packages/cli"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"./package.json": "./package.json"
|
|
19
|
+
},
|
|
20
|
+
"bin": {
|
|
21
|
+
"diagonal": "./bin/diagonal.mjs"
|
|
22
|
+
},
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=24"
|
|
25
|
+
},
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"bin/diagonal.mjs",
|
|
31
|
+
"dist/cli.mjs",
|
|
32
|
+
"dist/index.js",
|
|
33
|
+
"dist/index.d.ts",
|
|
34
|
+
"dist/globals.d.ts",
|
|
35
|
+
"dist/sdk-contract.d.ts",
|
|
36
|
+
"dist/workflow",
|
|
37
|
+
"LICENSE",
|
|
38
|
+
"README.md"
|
|
39
|
+
]
|
|
40
|
+
}
|