@tailor-platform/sdk 1.76.2 → 1.78.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-CqjCcZ2n.mjs → application-CUxVA7Fs.mjs} +8 -8
- package/dist/application-CUxVA7Fs.mjs.map +1 -0
- package/dist/application-Dp_-ioiP.mjs +3 -0
- package/dist/cli/commands/deploy/deploy.d.mts +8 -3
- package/dist/cli/commands/show.d.mts +9 -3
- package/dist/cli/commands/workspace/create.d.mts +3 -0
- package/dist/cli/commands/workspace/list.d.mts +1 -0
- package/dist/cli/commands/workspace/transform.d.mts +2 -0
- package/dist/cli/index.mjs +69 -22
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/lib.d.mts +2 -2
- package/dist/cli/lib.mjs +2 -2
- package/dist/cli/lib.mjs.map +1 -1
- package/dist/cli/shared/workspace-name.d.mts +1 -0
- package/dist/cli/skills.mjs +1 -1
- package/dist/completion/zsh-worker.zsh +18 -1
- package/dist/configure/index.mjs +198 -4
- package/dist/configure/index.mjs.map +1 -1
- package/dist/configure/services/idp/index.d.mts +1 -4
- package/dist/{crashreport-DZDr-TvH.mjs → crashreport-BNWUM6Kf.mjs} +2 -2
- package/dist/{crashreport-DZDr-TvH.mjs.map → crashreport-BNWUM6Kf.mjs.map} +1 -1
- package/dist/{crashreport-np4-_DX2.mjs → crashreport-BafWvjjX.mjs} +1 -1
- package/dist/errors-DVFS0AZk.mjs +100 -0
- package/dist/errors-DVFS0AZk.mjs.map +1 -0
- package/dist/{globals-z6zYMjlr.mjs → globals-CvizbGLY.mjs} +2 -2
- package/dist/{globals-z6zYMjlr.mjs.map → globals-CvizbGLY.mjs.map} +1 -1
- package/dist/{logger-BEiZZ3qT.mjs → logger-BwS4ppwO.mjs} +3 -3
- package/dist/logger-BwS4ppwO.mjs.map +1 -0
- package/dist/{registry-CTgoVWc_.mjs → registry-CYBRvfaU.mjs} +2 -2
- package/dist/{registry-CTgoVWc_.mjs.map → registry-CYBRvfaU.mjs.map} +1 -1
- package/dist/{runtime-DlklyuHN.mjs → runtime-BD2vYJFT.mjs} +1169 -539
- package/dist/runtime-BD2vYJFT.mjs.map +1 -0
- package/dist/{schema-DbTR1c6M.mjs → schema-U6DxoZ8D.mjs} +203 -3
- package/dist/schema-U6DxoZ8D.mjs.map +1 -0
- package/dist/{secretmanager-Bd45j7an.mjs → secretmanager-IY4UvinW.mjs} +42 -9
- package/dist/secretmanager-IY4UvinW.mjs.map +1 -0
- package/dist/service-CghpdV-9.mjs +3 -0
- package/dist/{service-DBFZQloR.mjs → service-Cp0I7ZFe.mjs} +3 -3
- package/dist/{service-DBFZQloR.mjs.map → service-Cp0I7ZFe.mjs.map} +1 -1
- package/dist/{service-BCRJ-3NV.mjs → service-D12iQGcS.mjs} +2 -2
- package/dist/{service-BCRJ-3NV.mjs.map → service-D12iQGcS.mjs.map} +1 -1
- package/dist/{test-env-key-IPapa1KJ.mjs → test-env-key-DuZycyWM.mjs} +2 -2
- package/dist/{test-env-key-IPapa1KJ.mjs.map → test-env-key-DuZycyWM.mjs.map} +1 -1
- package/dist/types/auth.generated.d.mts +9 -36
- package/dist/types/executor.generated.d.mts +19 -59
- package/dist/types/idp.generated.d.mts +518 -517
- package/dist/types/resolver.generated.d.mts +6 -2
- package/dist/types/tailordb.generated.d.mts +8 -7
- package/dist/utils/test/index.mjs +1 -1
- package/dist/vitest/environment.mjs +1 -1
- package/dist/vitest/index.d.mts +8 -8
- package/dist/vitest/index.mjs +600 -186
- package/dist/vitest/index.mjs.map +1 -1
- package/dist/vitest/mock.d.mts +8 -8
- package/dist/vitest/mocks/aigateway.d.mts +14 -4
- package/dist/vitest/mocks/authconnection.d.mts +14 -4
- package/dist/vitest/mocks/file.d.mts +24 -6
- package/dist/vitest/mocks/iconv.d.mts +28 -4
- package/dist/vitest/mocks/idp.d.mts +25 -9
- package/dist/vitest/mocks/secretmanager.d.mts +13 -4
- package/dist/vitest/mocks/tailordb.d.mts +48 -7
- package/dist/vitest/mocks/workflow.d.mts +41 -9
- package/dist/vitest/setup.mjs +2 -2
- package/docs/cli/application.md +58 -11
- package/docs/cli/setup.md +1 -1
- package/docs/cli/workspace.md +6 -4
- package/docs/cli-reference.md +12 -8
- package/docs/runtime.md +3 -4
- package/docs/services/aigateway.md +2 -0
- package/docs/services/tailordb.md +42 -0
- package/docs/services/workflow.md +1 -1
- package/docs/testing.md +103 -89
- package/package.json +7 -7
- package/dist/application-6zsDLGKv.mjs +0 -3
- package/dist/application-CqjCcZ2n.mjs.map +0 -1
- package/dist/errors-Dtf2WPaW.mjs +0 -42
- package/dist/errors-Dtf2WPaW.mjs.map +0 -1
- package/dist/field-runtime-D4QWRiB1.mjs +0 -203
- package/dist/field-runtime-D4QWRiB1.mjs.map +0 -1
- package/dist/logger-BEiZZ3qT.mjs.map +0 -1
- package/dist/runtime-DlklyuHN.mjs.map +0 -1
- package/dist/schema-DbTR1c6M.mjs.map +0 -1
- package/dist/secretmanager-Bd45j7an.mjs.map +0 -1
- package/dist/service-CPMlIg3X.mjs +0 -3
- package/dist/types-BzJ7A_fn.mjs +0 -199
- package/dist/types-BzJ7A_fn.mjs.map +0 -1
- package/dist/types-CG9H7HuE.mjs +0 -4
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { FileDownloadAsBase64Response, FileDownloadResponse, FileDownloadStreamResponse, FileMetadata, FileStreamIterator, FileUploadOptions, FileUploadResponse, FileUploadStreamOptions } from "../../runtime/file.mjs";
|
|
2
|
+
import { Mock } from "vitest";
|
|
1
3
|
//#region src/vitest/mocks/file.d.ts
|
|
2
4
|
type FileResolver = (method: string, call: FileCall) => unknown;
|
|
3
5
|
interface FileCall {
|
|
@@ -7,8 +9,14 @@ interface FileCall {
|
|
|
7
9
|
fieldName: string;
|
|
8
10
|
recordId: string;
|
|
9
11
|
}
|
|
12
|
+
/** Controls fallback behavior for File calls without a configured result. */
|
|
13
|
+
interface MockFileOptions {
|
|
14
|
+
/** Return a type-compatible fixture or throw when no behavior is configured. */
|
|
15
|
+
onUnhandled?: "fallback" | "error";
|
|
16
|
+
}
|
|
10
17
|
/**
|
|
11
18
|
* Acquire a disposable mock for `tailordb.file`. Restored on dispose.
|
|
19
|
+
* @param options - Controls behavior for calls without a configured result
|
|
12
20
|
* @returns Disposable File mock control object
|
|
13
21
|
* @example
|
|
14
22
|
* ```typescript
|
|
@@ -16,26 +24,36 @@ interface FileCall {
|
|
|
16
24
|
*
|
|
17
25
|
* test("mock file download", async () => {
|
|
18
26
|
* using file = mockFile();
|
|
19
|
-
* file.
|
|
27
|
+
* file.download.mockResolvedValue({ data: new Uint8Array(), metadata: { ... } });
|
|
20
28
|
* // …
|
|
21
29
|
* });
|
|
22
30
|
* ```
|
|
23
31
|
*/
|
|
24
|
-
declare function mockFile(): {
|
|
32
|
+
declare function mockFile(options?: MockFileOptions): {
|
|
25
33
|
setResolver(value: FileResolver): void;
|
|
26
34
|
/**
|
|
27
|
-
* Enqueue a single result for the next `tailordb.file` call
|
|
28
|
-
*
|
|
35
|
+
* Enqueue a single result for the next `tailordb.file` call.
|
|
36
|
+
* The queue is shared across all methods and namespaces.
|
|
29
37
|
* @param result - Result to return from the next file call
|
|
30
38
|
*/
|
|
31
39
|
enqueueResult(result: unknown): void;
|
|
32
40
|
/**
|
|
33
41
|
* Enqueue results for multiple subsequent `tailordb.file` calls.
|
|
42
|
+
* The queue is shared across all methods and namespaces.
|
|
34
43
|
* @param results - Results to enqueue, one per upcoming call
|
|
35
44
|
*/
|
|
36
45
|
enqueueResults(...results: unknown[]): void;
|
|
37
|
-
|
|
46
|
+
calls: FileCall[];
|
|
47
|
+
clear(): void;
|
|
38
48
|
reset(): void;
|
|
49
|
+
delete: Mock<(namespace: string, typeName: string, fieldName: string, recordId: string) => Promise<void>>;
|
|
50
|
+
upload: Mock<(namespace: string, typeName: string, fieldName: string, recordId: string, data: string | ArrayBuffer | Uint8Array | number[], options?: FileUploadOptions) => Promise<FileUploadResponse>>;
|
|
51
|
+
download: Mock<(namespace: string, typeName: string, fieldName: string, recordId: string) => Promise<FileDownloadResponse>>;
|
|
52
|
+
downloadAsBase64: Mock<(namespace: string, typeName: string, fieldName: string, recordId: string) => Promise<FileDownloadAsBase64Response>>;
|
|
53
|
+
getMetadata: Mock<(namespace: string, typeName: string, fieldName: string, recordId: string) => Promise<FileMetadata>>;
|
|
54
|
+
openDownloadStream: Mock<(namespace: string, typeName: string, fieldName: string, recordId: string) => Promise<FileStreamIterator>>;
|
|
55
|
+
downloadStream: Mock<(namespace: string, typeName: string, fieldName: string, recordId: string) => Promise<FileDownloadStreamResponse>>;
|
|
56
|
+
uploadStream: Mock<(namespace: string, typeName: string, fieldName: string, recordId: string, readableStream: ReadableStream<Uint8Array | ArrayBuffer>, options?: FileUploadStreamOptions) => Promise<FileUploadResponse>>;
|
|
39
57
|
} & Disposable;
|
|
40
58
|
//#endregion
|
|
41
|
-
export { mockFile };
|
|
59
|
+
export { MockFileOptions, mockFile };
|
|
@@ -1,11 +1,24 @@
|
|
|
1
|
+
import { MockInstance } from "vitest";
|
|
1
2
|
//#region src/vitest/mocks/iconv.d.ts
|
|
2
3
|
type IconvResolver = (method: string, args: unknown[]) => unknown;
|
|
4
|
+
type IconvMethod = "convert" | "convertBuffer" | "decode" | "encode" | "encodings";
|
|
3
5
|
interface IconvCall {
|
|
4
|
-
method:
|
|
6
|
+
method: IconvMethod;
|
|
5
7
|
args: unknown[];
|
|
6
8
|
}
|
|
9
|
+
type ConversionResult = string | Uint8Array;
|
|
10
|
+
type ConvertMockProcedure = (input: string | Uint8Array | ArrayBuffer, fromEncoding: string, toEncoding: string) => ConversionResult;
|
|
11
|
+
type ConvertBufferMockProcedure = (input: Uint8Array | ArrayBuffer, fromEncoding: string, toEncoding: string) => ConversionResult;
|
|
12
|
+
type EncodeMockProcedure = (input: string, encoding: string) => ConversionResult;
|
|
13
|
+
type TypedOperationMock<RuntimeProcedure, MockProcedure extends (...args: never[]) => unknown> = RuntimeProcedure & MockInstance<MockProcedure>;
|
|
14
|
+
/** Controls how unconfigured Iconv operations are handled. */
|
|
15
|
+
interface MockIconvOptions {
|
|
16
|
+
/** Return an empty type-compatible value or throw when no behavior is configured. */
|
|
17
|
+
onUnhandled?: "fallback" | "error";
|
|
18
|
+
}
|
|
7
19
|
/**
|
|
8
20
|
* Acquire a disposable mock for `tailor.iconv`. Restored on dispose.
|
|
21
|
+
* @param options - Fallback behavior for unconfigured operations
|
|
9
22
|
* @returns Disposable Iconv mock control object
|
|
10
23
|
* @example
|
|
11
24
|
* ```typescript
|
|
@@ -13,15 +26,26 @@ interface IconvCall {
|
|
|
13
26
|
*
|
|
14
27
|
* test("mock encoding conversion", () => {
|
|
15
28
|
* using iconv = mockIconv();
|
|
16
|
-
* iconv.
|
|
29
|
+
* iconv.decode.mockReturnValue("decoded-text");
|
|
17
30
|
* // …
|
|
18
31
|
* });
|
|
19
32
|
* ```
|
|
20
33
|
*/
|
|
21
|
-
declare function mockIconv(): {
|
|
34
|
+
declare function mockIconv(options?: MockIconvOptions): {
|
|
35
|
+
/** The `convert` `vi.fn`. */
|
|
36
|
+
convert: TypedOperationMock<(<T extends string>(str: string | Uint8Array | ArrayBuffer, fromEncoding: string, toEncoding: T) => T extends "UTF8" | "UTF-8" ? string : Uint8Array), ConvertMockProcedure>;
|
|
37
|
+
/** The `convertBuffer` `vi.fn`. */
|
|
38
|
+
convertBuffer: TypedOperationMock<(<T extends string>(buffer: Uint8Array | ArrayBuffer, fromEncoding: string, toEncoding: T) => T extends "UTF8" | "UTF-8" ? string : Uint8Array), ConvertBufferMockProcedure>;
|
|
39
|
+
/** The `decode` `vi.fn`. */
|
|
40
|
+
decode: import("vitest").Mock<(input: Uint8Array | ArrayBuffer, encoding: string) => string>;
|
|
41
|
+
/** The `encode` `vi.fn`. */
|
|
42
|
+
encode: TypedOperationMock<(<T extends string>(str: string, encoding: T) => T extends "UTF8" | "UTF-8" ? string : Uint8Array), EncodeMockProcedure>;
|
|
43
|
+
/** The `encodings` `vi.fn`. */
|
|
44
|
+
encodings: import("vitest").Mock<() => string[]>;
|
|
22
45
|
setResolver(value: IconvResolver): void;
|
|
23
46
|
readonly calls: IconvCall[];
|
|
47
|
+
clear: () => void;
|
|
24
48
|
reset(): void;
|
|
25
49
|
} & Disposable;
|
|
26
50
|
//#endregion
|
|
27
|
-
export { mockIconv };
|
|
51
|
+
export { MockIconvOptions, mockIconv };
|
|
@@ -1,44 +1,60 @@
|
|
|
1
|
+
import { IdpClientConstructor, IdpClientInstance } from "../../runtime/idp.mjs";
|
|
1
2
|
import { Mock } from "vitest";
|
|
2
3
|
//#region src/vitest/mocks/idp.d.ts
|
|
4
|
+
type IdpMethod = keyof IdpClientInstance;
|
|
3
5
|
type IdpResolver = (method: string, args: unknown[], namespace: string) => unknown;
|
|
4
6
|
interface IdpCall {
|
|
5
7
|
method: string;
|
|
6
8
|
args: unknown[];
|
|
7
9
|
namespace: string;
|
|
8
10
|
}
|
|
11
|
+
/** Controls fallback behavior for IdP calls without a configured result. */
|
|
12
|
+
interface MockIdpOptions {
|
|
13
|
+
/** Return a type-compatible fixture or throw when no behavior is configured. */
|
|
14
|
+
onUnhandled?: "fallback" | "error";
|
|
15
|
+
}
|
|
16
|
+
type IdpNamespaceMocks = { [Method in IdpMethod]: Mock<IdpClientInstance[Method]>; };
|
|
9
17
|
/**
|
|
10
18
|
* Acquire a disposable mock for `tailor.idp`. Restored on dispose.
|
|
19
|
+
* @param options - Controls behavior for calls without a configured result
|
|
11
20
|
* @returns Disposable IDP mock control object
|
|
12
21
|
* @example
|
|
13
22
|
* ```typescript
|
|
14
23
|
* import { mockIdp } from "@tailor-platform/sdk/vitest";
|
|
15
24
|
*
|
|
16
|
-
* test("
|
|
25
|
+
* test("returns a user", async () => {
|
|
17
26
|
* using idp = mockIdp();
|
|
18
|
-
* idp.
|
|
19
|
-
*
|
|
20
|
-
*
|
|
27
|
+
* idp.namespace("my-idp").user.mockResolvedValue({
|
|
28
|
+
* id: "u-1",
|
|
29
|
+
* name: "alice",
|
|
30
|
+
* disabled: false,
|
|
31
|
+
* mfaEnrolled: false,
|
|
32
|
+
* mfaFactorIds: [],
|
|
33
|
+
* });
|
|
21
34
|
* // …
|
|
22
35
|
* });
|
|
23
36
|
* ```
|
|
24
37
|
*/
|
|
25
|
-
declare function mockIdp(): {
|
|
38
|
+
declare function mockIdp(options?: MockIdpOptions): {
|
|
26
39
|
/** The mock IDP `Client` constructor (`vi.fn`). */
|
|
27
|
-
Client: Mock
|
|
40
|
+
Client: Mock<IdpClientConstructor>;
|
|
41
|
+
namespace: (name: string) => IdpNamespaceMocks;
|
|
28
42
|
setResolver(value: IdpResolver): void;
|
|
29
43
|
/**
|
|
30
|
-
* Enqueue a single result for the next IDP call
|
|
31
|
-
*
|
|
44
|
+
* Enqueue a single result for the next IDP call.
|
|
45
|
+
* The queue is shared across all methods and namespaces.
|
|
32
46
|
* @param result - Result to return from the next IDP call
|
|
33
47
|
*/
|
|
34
48
|
enqueueResult(result: unknown): void;
|
|
35
49
|
/**
|
|
36
50
|
* Enqueue results for multiple subsequent IDP calls.
|
|
51
|
+
* The queue is shared across all methods and namespaces.
|
|
37
52
|
* @param results - Results to enqueue, one per upcoming call
|
|
38
53
|
*/
|
|
39
54
|
enqueueResults(...results: unknown[]): void;
|
|
40
55
|
readonly calls: IdpCall[];
|
|
56
|
+
clear(): void;
|
|
41
57
|
reset(): void;
|
|
42
58
|
} & Disposable;
|
|
43
59
|
//#endregion
|
|
44
|
-
export { mockIdp };
|
|
60
|
+
export { MockIdpOptions, mockIdp };
|
|
@@ -5,31 +5,40 @@ interface SecretCall {
|
|
|
5
5
|
name?: string;
|
|
6
6
|
names?: readonly string[];
|
|
7
7
|
}
|
|
8
|
+
/** Initial fixtures for a Secret Manager mock. */
|
|
9
|
+
interface MockSecretmanagerOptions {
|
|
10
|
+
/** Secrets to merge over fixtures inherited from the currently installed mock. */
|
|
11
|
+
secrets?: Record<string, Record<string, string>>;
|
|
12
|
+
}
|
|
8
13
|
/**
|
|
9
14
|
* Acquire a disposable mock for `tailor.secretmanager`. The secret store is
|
|
10
15
|
* inherited (cloned) from the currently-installed mock on acquisition and
|
|
11
16
|
* restored on dispose, so secrets seeded outside the test survive across
|
|
12
17
|
* `using` scopes while per-test `setSecrets()` overrides stay isolated.
|
|
18
|
+
* @param options - Initial Secret Manager fixtures
|
|
13
19
|
* @returns Disposable SecretManager mock control object
|
|
14
20
|
* @example
|
|
15
21
|
* ```typescript
|
|
16
22
|
* import { mockSecretmanager } from "@tailor-platform/sdk/vitest";
|
|
17
23
|
*
|
|
18
24
|
* test("reads secrets from vault", async () => {
|
|
19
|
-
* using sm = mockSecretmanager();
|
|
20
|
-
* sm.
|
|
25
|
+
* using sm = mockSecretmanager({ secrets: { "my-vault": { API_KEY: "sk-123" } } });
|
|
26
|
+
* sm.setSecret("my-vault", "API_KEY", "replacement");
|
|
21
27
|
* // …
|
|
22
28
|
* });
|
|
23
29
|
* ```
|
|
24
30
|
*/
|
|
25
|
-
declare function mockSecretmanager(): {
|
|
31
|
+
declare function mockSecretmanager(options?: MockSecretmanagerOptions): {
|
|
26
32
|
/** The `getSecret` `vi.fn`. */
|
|
27
33
|
getSecret: import("vitest").Mock<(vault: string, name: string) => Promise<string | undefined>>;
|
|
28
34
|
/** The `getSecrets` `vi.fn`. */
|
|
29
35
|
getSecrets: import("vitest").Mock<(<const T extends readonly string[]>(vault: string, names: T) => Promise<Partial<Record<T[number], string>>>)>;
|
|
30
36
|
setSecrets(secrets: Record<string, Record<string, string>>): void;
|
|
37
|
+
setSecret(vault: string, name: string, value: string): void;
|
|
38
|
+
mergeSecrets(vault: string, secrets: Record<string, string>): void;
|
|
31
39
|
readonly calls: SecretCall[];
|
|
40
|
+
clear(): void;
|
|
32
41
|
reset(): void;
|
|
33
42
|
} & Disposable;
|
|
34
43
|
//#endregion
|
|
35
|
-
export { mockSecretmanager };
|
|
44
|
+
export { MockSecretmanagerOptions, mockSecretmanager };
|
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
//#region src/vitest/mocks/tailordb.d.ts
|
|
2
|
-
type QueryResolver = (query: string, params: unknown[]) => unknown[];
|
|
2
|
+
type QueryResolver = (query: string, params: unknown[]) => unknown[] | undefined;
|
|
3
|
+
/** Controls how unmatched TailorDB queries are handled. */
|
|
4
|
+
interface MockTailordbOptions {
|
|
5
|
+
/** Return an empty result or throw when no configured query behavior matches. */
|
|
6
|
+
onUnhandled?: "fallback" | "error";
|
|
7
|
+
}
|
|
8
|
+
/** Matches a TailorDB query by SQL text and optionally by parameters. */
|
|
9
|
+
interface QueryMatch {
|
|
10
|
+
/** Exact SQL text or regular expression to match. */
|
|
11
|
+
sql: string | RegExp;
|
|
12
|
+
/** Exact parameters or a predicate for parameter matching. */
|
|
13
|
+
params?: readonly unknown[] | ((params: unknown[]) => boolean);
|
|
14
|
+
}
|
|
15
|
+
/** Selects TailorDB queries that receive a configured response. */
|
|
16
|
+
type QueryMatcher = string | RegExp | QueryMatch | ((query: string, params: unknown[]) => boolean);
|
|
17
|
+
/** Configures persistent and one-time responses for matched queries. */
|
|
18
|
+
interface QueryBehavior<Row> {
|
|
19
|
+
/** Return these rows for every matching query after one-time responses are consumed. */
|
|
20
|
+
returnsRows(rows: Row[]): QueryBehavior<Row>;
|
|
21
|
+
/** Return these rows for the next matching query. */
|
|
22
|
+
returnsRowsOnce(rows: Row[]): QueryBehavior<Row>;
|
|
23
|
+
/** Reject every matching query after one-time responses are consumed. */
|
|
24
|
+
rejects(error: unknown): QueryBehavior<Row>;
|
|
25
|
+
/** Reject the next matching query. */
|
|
26
|
+
rejectsOnce(error: unknown): QueryBehavior<Row>;
|
|
27
|
+
}
|
|
3
28
|
interface ExecutedQuery {
|
|
4
29
|
query: string;
|
|
5
30
|
params: unknown[];
|
|
@@ -19,32 +44,41 @@ declare class MockQueryResult {
|
|
|
19
44
|
* `tailordb.Client` whose `queryObject` is a shared `vi.fn()` (so query
|
|
20
45
|
* responses can be staged before the client is constructed). Restored on
|
|
21
46
|
* dispose.
|
|
47
|
+
* @param options - Query fallback behavior
|
|
22
48
|
* @returns Disposable TailorDB mock control object
|
|
23
49
|
* @example
|
|
24
50
|
* ```typescript
|
|
25
51
|
* import { mockTailordb } from "@tailor-platform/sdk/vitest";
|
|
26
52
|
*
|
|
27
|
-
* test("
|
|
53
|
+
* test("query-based", async () => {
|
|
28
54
|
* using db = mockTailordb();
|
|
29
|
-
* db.
|
|
55
|
+
* db.onQuery({ sql: /FROM users/, params: ["u-1"] }).returnsRows([{ age: 30 }]);
|
|
30
56
|
* // …
|
|
31
|
-
* expect(db.queryObject).
|
|
57
|
+
* expect(db.queryObject).toHaveBeenCalled();
|
|
32
58
|
* expect(db.Client).toHaveBeenCalledWith({ namespace: "tailordb" });
|
|
33
59
|
* });
|
|
34
60
|
* ```
|
|
35
61
|
*/
|
|
36
|
-
declare function mockTailordb(): {
|
|
62
|
+
declare function mockTailordb(options?: MockTailordbOptions): {
|
|
37
63
|
/** The mock `tailordb.Client` constructor (`vi.fn`). */
|
|
38
64
|
Client: import("vitest").Mock<(this: any, config?: {
|
|
39
65
|
namespace?: string;
|
|
40
66
|
}) => void>;
|
|
41
67
|
/** The shared `queryObject` `vi.fn` used by every client and transaction. */
|
|
42
|
-
queryObject: import("vitest").Mock<(
|
|
68
|
+
queryObject: import("vitest").Mock<(query: string, params?: unknown[]) => Promise<MockQueryResult>>;
|
|
43
69
|
/**
|
|
44
70
|
* Set a fallback query resolver. Called when the enqueue queue is empty.
|
|
45
71
|
* @param resolver - Function that returns rows for a given query and params
|
|
46
72
|
*/
|
|
47
73
|
setQueryResolver(resolver: QueryResolver): void;
|
|
74
|
+
/**
|
|
75
|
+
* Configure responses for queries matching SQL text, parameters, or a predicate.
|
|
76
|
+
* More recently registered matchers take precedence.
|
|
77
|
+
* Do not combine matchers with a direct `queryObject.mockImplementation()` override.
|
|
78
|
+
* @param matcher - Query matcher
|
|
79
|
+
* @returns Chainable query behavior
|
|
80
|
+
*/
|
|
81
|
+
onQuery<Row = unknown>(matcher: QueryMatcher): QueryBehavior<Row>;
|
|
48
82
|
/**
|
|
49
83
|
* Enqueue rows for the next `queryObject` call (FIFO; takes priority over
|
|
50
84
|
* `setQueryResolver`). Call with no arguments for an empty result.
|
|
@@ -56,6 +90,11 @@ declare function mockTailordb(): {
|
|
|
56
90
|
* @param rowsList - Rows arrays, one per upcoming query
|
|
57
91
|
*/
|
|
58
92
|
enqueueResults(...rowsList: unknown[][]): void;
|
|
93
|
+
/**
|
|
94
|
+
* Enqueue row arrays for subsequent queries whose exact order is under test.
|
|
95
|
+
* @param rowsList - Rows arrays, one per upcoming query
|
|
96
|
+
*/
|
|
97
|
+
enqueueRows(...rowsList: unknown[][]): void;
|
|
59
98
|
/**
|
|
60
99
|
* All queries executed via `queryObject`, in order, derived from the vi.fn
|
|
61
100
|
* call records.
|
|
@@ -67,8 +106,10 @@ declare function mockTailordb(): {
|
|
|
67
106
|
* @returns Created clients array
|
|
68
107
|
*/
|
|
69
108
|
readonly createdClients: CreatedClient[];
|
|
109
|
+
/** Clear recorded calls while preserving configured query behavior. */
|
|
110
|
+
clear(): void;
|
|
70
111
|
/** Reset query responses and recorded calls (keeps the mock installed). */
|
|
71
112
|
reset(): void;
|
|
72
113
|
} & Disposable;
|
|
73
114
|
//#endregion
|
|
74
|
-
export { mockTailordb };
|
|
115
|
+
export { MockTailordbOptions, QueryBehavior, QueryMatch, QueryMatcher, mockTailordb };
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { TailorEnv } from "../../runtime/types.mjs";
|
|
2
2
|
import { TriggerJobFunctionOptions } from "../../runtime/workflow.mjs";
|
|
3
|
+
import { WorkflowJob } from "../../configure/services/workflow/job.mjs";
|
|
4
|
+
import { Workflow } from "../../configure/services/workflow/workflow.mjs";
|
|
5
|
+
import { WaitPointInstance } from "../../configure/services/workflow/wait-point.mjs";
|
|
6
|
+
import { Mock } from "vitest";
|
|
3
7
|
//#region src/vitest/mocks/workflow.d.ts
|
|
4
8
|
type JobHandler = (jobName: string, args: unknown, options?: TriggerJobFunctionOptions) => unknown;
|
|
5
9
|
type TriggerWorkflowOptions = {
|
|
@@ -21,6 +25,7 @@ interface TriggeredJob {
|
|
|
21
25
|
args: unknown;
|
|
22
26
|
options?: TriggerJobFunctionOptions;
|
|
23
27
|
}
|
|
28
|
+
type WaitPayload<Payload> = [Payload] extends [undefined] ? undefined : Payload;
|
|
24
29
|
/**
|
|
25
30
|
* Acquire a disposable mock for workflow operations (`tailor.workflow`).
|
|
26
31
|
* Restored on dispose.
|
|
@@ -29,25 +34,50 @@ interface TriggeredJob {
|
|
|
29
34
|
* ```typescript
|
|
30
35
|
* import { mockWorkflow } from "@tailor-platform/sdk/vitest";
|
|
31
36
|
*
|
|
32
|
-
* test("job
|
|
37
|
+
* test("job trigger", async () => {
|
|
33
38
|
* using wf = mockWorkflow();
|
|
34
|
-
* wf.
|
|
35
|
-
*
|
|
36
|
-
*
|
|
39
|
+
* const job = wf.job(validateOrder);
|
|
40
|
+
* job.mockResolvedValue({ valid: true });
|
|
41
|
+
* await runWorkflowUnderTest();
|
|
42
|
+
* expect(job).toHaveBeenCalled();
|
|
37
43
|
* });
|
|
38
44
|
* ```
|
|
39
45
|
*/
|
|
40
46
|
declare function mockWorkflow(): {
|
|
41
47
|
/** The `triggerJobFunction` `vi.fn`. */
|
|
42
|
-
triggerJobFunction:
|
|
48
|
+
triggerJobFunction: Mock<(jobName: string, args?: unknown, _options?: TriggerJobFunctionOptions) => unknown>;
|
|
43
49
|
/** The `triggerWorkflow` `vi.fn`. */
|
|
44
|
-
triggerWorkflow:
|
|
50
|
+
triggerWorkflow: Mock<(workflowName: string, args?: unknown, _options?: TriggerWorkflowOptions) => Promise<string>>;
|
|
45
51
|
/** The `resumeWorkflow` `vi.fn`. */
|
|
46
|
-
resumeWorkflow:
|
|
52
|
+
resumeWorkflow: Mock<(executionId: string) => Promise<string>>;
|
|
47
53
|
/** The `wait` `vi.fn`. */
|
|
48
|
-
wait:
|
|
54
|
+
wait: Mock<(_key: string, _payload?: unknown) => unknown>;
|
|
49
55
|
/** The `resolve` `vi.fn`. */
|
|
50
|
-
resolve:
|
|
56
|
+
resolve: Mock<(_executionId: string, _key: string, _callback: (payload: unknown) => unknown) => Promise<void>>;
|
|
57
|
+
/**
|
|
58
|
+
* Get a stable, typed mock for a workflow job's `trigger` method.
|
|
59
|
+
* The real trigger behavior is used until an implementation or result is configured.
|
|
60
|
+
* @param definition - Workflow job definition to mock
|
|
61
|
+
* @returns Typed `trigger` mock for the definition
|
|
62
|
+
*/
|
|
63
|
+
job<Name extends string, Input, Output>(definition: WorkflowJob<Name, Input, Output>): Mock<WorkflowJob<Name, Input, Output>["trigger"]>;
|
|
64
|
+
/**
|
|
65
|
+
* Get a stable, typed mock for a workflow definition's `trigger` method.
|
|
66
|
+
* The real trigger behavior is used until an implementation or result is configured.
|
|
67
|
+
* @param definition - Workflow definition to mock
|
|
68
|
+
* @returns Typed `trigger` mock for the definition
|
|
69
|
+
*/
|
|
70
|
+
workflow<Definition extends Workflow>(definition: Definition): Mock<Definition["trigger"]>;
|
|
71
|
+
/**
|
|
72
|
+
* Get stable, typed mocks for a wait point's `wait` and `resolve` methods.
|
|
73
|
+
* @param definition - Wait point definition to mock
|
|
74
|
+
* @returns Typed wait point mock control object
|
|
75
|
+
*/
|
|
76
|
+
waitPoint<Payload, Result>(definition: WaitPointInstance<Payload, Result>): {
|
|
77
|
+
wait: Mock<WaitPointInstance<Payload, Result>["wait"]>;
|
|
78
|
+
resolve: Mock<WaitPointInstance<Payload, Result>["resolve"]>;
|
|
79
|
+
setResolvePayload(payload: WaitPayload<Payload>): void;
|
|
80
|
+
};
|
|
51
81
|
/**
|
|
52
82
|
* Set a fallback job handler. Called when the enqueue queue is empty.
|
|
53
83
|
* @param handler - Function returning a result for a job name, args, and options
|
|
@@ -115,6 +145,8 @@ declare function mockWorkflow(): {
|
|
|
115
145
|
executionId: string;
|
|
116
146
|
key: string;
|
|
117
147
|
}[];
|
|
148
|
+
/** Clear recorded calls while preserving configured responses. */
|
|
149
|
+
clear(): void;
|
|
118
150
|
/** Reset all workflow responses and recorded calls (keeps the mock installed). */
|
|
119
151
|
reset(): void;
|
|
120
152
|
} & Disposable;
|
package/dist/vitest/setup.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as RUNTIME_FLAG_KEY } from "../globals-
|
|
2
|
-
import { t as mockSecretmanager } from "../secretmanager-
|
|
1
|
+
import { t as RUNTIME_FLAG_KEY } from "../globals-CvizbGLY.mjs";
|
|
2
|
+
import { t as mockSecretmanager } from "../secretmanager-IY4UvinW.mjs";
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
4
|
import { afterEach, beforeAll, beforeEach } from "vitest";
|
|
5
5
|
|
package/docs/cli/application.md
CHANGED
|
@@ -59,19 +59,66 @@ tailor-sdk deploy [options]
|
|
|
59
59
|
|
|
60
60
|
**Options**
|
|
61
61
|
|
|
62
|
-
| Option
|
|
63
|
-
|
|
|
64
|
-
| `--workspace-id <WORKSPACE_ID>`
|
|
65
|
-
| `--profile <PROFILE>`
|
|
66
|
-
| `--config <CONFIG>`
|
|
67
|
-
| `--yes`
|
|
68
|
-
| `--
|
|
69
|
-
| `--
|
|
70
|
-
| `--
|
|
71
|
-
| `--
|
|
72
|
-
| `--
|
|
62
|
+
| Option | Alias | Description | Required | Default | Env |
|
|
63
|
+
| --------------------------------------- | ----- | ------------------------------------------------------------------------------------ | -------- | -------------------- | --------------------------------- |
|
|
64
|
+
| `--workspace-id <WORKSPACE_ID>` | `-w` | Workspace ID | No | - | `TAILOR_PLATFORM_WORKSPACE_ID` |
|
|
65
|
+
| `--profile <PROFILE>` | `-p` | Workspace profile | No | - | `TAILOR_PLATFORM_PROFILE` |
|
|
66
|
+
| `--config <CONFIG>` | `-c` | Path to SDK config file. Use comma-separated paths to deploy multiple apps together. | No | `"tailor.config.ts"` | `TAILOR_PLATFORM_SDK_CONFIG_PATH` |
|
|
67
|
+
| `--yes` | `-y` | Skip confirmation prompts | No | `false` | - |
|
|
68
|
+
| `--create-workspace` | - | Create a workspace when the account has none | No | - | - |
|
|
69
|
+
| `--workspace-name <WORKSPACE_NAME>` | - | Name for a workspace created during deploy | No | - | - |
|
|
70
|
+
| `--workspace-region <WORKSPACE_REGION>` | - | Region for a workspace created during deploy | No | - | - |
|
|
71
|
+
| `--organization-id <ORGANIZATION_ID>` | - | Organization ID for a workspace created during deploy | No | - | `TAILOR_PLATFORM_ORGANIZATION_ID` |
|
|
72
|
+
| `--folder-id <FOLDER_ID>` | - | Folder ID for a workspace created during deploy | No | - | `TAILOR_PLATFORM_FOLDER_ID` |
|
|
73
|
+
| `--dry-run` | `-d` | Run the command without making any changes | No | - | - |
|
|
74
|
+
| `--no-schema-check` | - | Skip schema diff check against migration snapshots | No | - | - |
|
|
75
|
+
| `--no-validate` | - | Skip client-side validation against platform resource constraints | No | - | - |
|
|
76
|
+
| `--no-cache` | - | Disable bundle caching for this run | No | - | - |
|
|
77
|
+
| `--clean-cache` | - | Clean the bundle cache before building | No | - | - |
|
|
73
78
|
|
|
74
79
|
See [Global Options](../cli-reference.md#global-options) for options available to all commands.
|
|
80
|
+
**Workspace Selection:**
|
|
81
|
+
|
|
82
|
+
After validating the configuration file, `deploy` resolves a workspace before bundling the
|
|
83
|
+
application. Explicit configuration takes precedence in this order: `--workspace-id`,
|
|
84
|
+
`TAILOR_PLATFORM_WORKSPACE_ID`, and the selected profile. Otherwise, `deploy` reuses the workspace
|
|
85
|
+
previously selected for that configuration from project-local state. Each config file keeps an
|
|
86
|
+
independent selection, including when multiple configs share a directory. An explicit workspace also
|
|
87
|
+
updates this selection. Saved selections are verified against the workspaces currently visible to
|
|
88
|
+
the authenticated user before reuse, and `deploy` warns when it uses one.
|
|
89
|
+
|
|
90
|
+
When the project has no saved selection, `deploy` discovers the account's workspaces:
|
|
91
|
+
|
|
92
|
+
- One or more workspaces open a selection prompt in an interactive terminal, with an option to
|
|
93
|
+
create a new workspace. With one workspace in non-interactive or JSON mode, it is selected
|
|
94
|
+
automatically. With multiple workspaces, pass `--workspace-id` instead.
|
|
95
|
+
- No workspaces open a guided creation flow in an interactive terminal. The flow asks for a name,
|
|
96
|
+
fetches the available regions from the Platform, and confirms before creating anything. After
|
|
97
|
+
creation, the output shows how to reuse the workspace with `--workspace-id` or
|
|
98
|
+
`TAILOR_PLATFORM_WORKSPACE_ID` from CI or another machine.
|
|
99
|
+
|
|
100
|
+
In CI and other non-interactive environments, workspace creation must be explicit:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
tailor-sdk deploy \
|
|
104
|
+
--create-workspace \
|
|
105
|
+
--workspace-name example-workspace \
|
|
106
|
+
--workspace-region us-west
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
`--create-workspace` only creates when the account has no workspace. If the existing workspace
|
|
110
|
+
matches the requested name, region, organization, and folder, `deploy` reuses it so the same command
|
|
111
|
+
is safe to rerun. If multiple workspaces exist, the flag never creates another one or guesses which
|
|
112
|
+
workspace to use. `--yes` skips deployment confirmation but does not authorize workspace creation.
|
|
113
|
+
|
|
114
|
+
If a saved workspace has been deleted or is no longer accessible, interactive terminals return to
|
|
115
|
+
workspace selection. Non-interactive environments stop with `WORKSPACE_CONTEXT_STALE` instead of
|
|
116
|
+
silently switching to another workspace. Automatically selected targets are printed with their
|
|
117
|
+
region, organization, and workspace ID.
|
|
118
|
+
|
|
119
|
+
`--dry-run` never creates a workspace or writes project context. When an account has no workspace,
|
|
120
|
+
create one explicitly before requesting a deployment plan.
|
|
121
|
+
|
|
75
122
|
**Config File Modification:**
|
|
76
123
|
|
|
77
124
|
On first run, `deploy` automatically injects a stable `id: "<uuid>"` field into your `defineConfig({...})` call in `tailor.config.ts`. This UUID is used to track your application across renames so the SDK can recognize ownership across renames. Commit the generated id to version control. See [Configuration](../configuration.md#application-settings) for details.
|
package/docs/cli/setup.md
CHANGED
|
@@ -174,7 +174,7 @@ tailor-sdk setup tag [options]
|
|
|
174
174
|
| Option | Alias | Description | Required | Default |
|
|
175
175
|
| ----------------------------- | ----- | ---------------------------------------------------------------------------- | -------- | ------- |
|
|
176
176
|
| `--name <NAME>` | `-n` | Name (defaults to the config 'name') | No | - |
|
|
177
|
-
| `--tag-pattern <TAG_PATTERN>` | - | Tag glob to match (defaults to v
|
|
177
|
+
| `--tag-pattern <TAG_PATTERN>` | - | Tag glob to match (defaults to v*) | No | `"v*"` |
|
|
178
178
|
| `--branch <BRANCH>` | - | Tag-reachability guard branch (no guard when omitted) | No | - |
|
|
179
179
|
| `--environment <ENVIRONMENT>` | - | GitHub Environment for the plan/deploy jobs (defaults to the workspace name) | No | - |
|
|
180
180
|
| `--dir <DIR>` | `-d` | App directory (for monorepo setups) | No | `"."` |
|
package/docs/cli/workspace.md
CHANGED
|
@@ -106,6 +106,7 @@ tailor-sdk workspace create [options]
|
|
|
106
106
|
| `--organization-id <ORGANIZATION_ID>` | `-o` | Organization ID to workspace associate with | No | - | `TAILOR_PLATFORM_ORGANIZATION_ID` |
|
|
107
107
|
| `--folder-id <FOLDER_ID>` | `-f` | Folder ID to workspace associate with | No | - | `TAILOR_PLATFORM_FOLDER_ID` |
|
|
108
108
|
| `--profile-name <PROFILE_NAME>` | `-p` | Profile name to create | No | - | - |
|
|
109
|
+
| `--profile <PROFILE>` | - | Workspace profile used for authentication and Platform selection | No | - | `TAILOR_PLATFORM_PROFILE` |
|
|
109
110
|
| `--profile-user <PROFILE_USER>` | - | User email for the profile (defaults to current user) | No | - | - |
|
|
110
111
|
| `--permission <PERMISSION>` | - | Profile permission (requires --profile-name). 'read' blocks all write commands while the profile is active. | No | `"write"` | - |
|
|
111
112
|
|
|
@@ -161,10 +162,11 @@ tailor-sdk workspace list [options]
|
|
|
161
162
|
|
|
162
163
|
**Options**
|
|
163
164
|
|
|
164
|
-
| Option
|
|
165
|
-
|
|
|
166
|
-
| `--order <ORDER>`
|
|
167
|
-
| `--limit <LIMIT>`
|
|
165
|
+
| Option | Alias | Description | Required | Default | Env |
|
|
166
|
+
| --------------------- | ----- | ---------------------------------------------------------------- | -------- | -------- | ------------------------- |
|
|
167
|
+
| `--order <ORDER>` | - | Sort order (asc or desc) | No | `"desc"` | - |
|
|
168
|
+
| `--limit <LIMIT>` | `-l` | Maximum number of items to return (0 or omit: unlimited) | No | - | - |
|
|
169
|
+
| `--profile <PROFILE>` | - | Workspace profile used for authentication and Platform selection | No | - | `TAILOR_PLATFORM_PROFILE` |
|
|
168
170
|
|
|
169
171
|
See [Global Options](../cli-reference.md#global-options) for options available to all commands.
|
|
170
172
|
|
package/docs/cli-reference.md
CHANGED
|
@@ -11,12 +11,13 @@ tailor-sdk <command> [options]
|
|
|
11
11
|
## Global Options
|
|
12
12
|
|
|
13
13
|
<a id="global-options"></a>
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
|
17
|
-
| `--env-file
|
|
18
|
-
| `--
|
|
19
|
-
| `--
|
|
14
|
+
|
|
15
|
+
| Option | Alias | Description | Required | Default |
|
|
16
|
+
| ------------------------------------------- | ----- | --------------------------------------------------- | -------- | ------- |
|
|
17
|
+
| `--env-file <ENV_FILE>` | `-e` | Path to the environment file (error if not found) | No | - |
|
|
18
|
+
| `--env-file-if-exists <ENV_FILE_IF_EXISTS>` | - | Path to the environment file (ignored if not found) | No | - |
|
|
19
|
+
| `--verbose` | - | Enable verbose logging | No | `false` |
|
|
20
|
+
| `--json` | `-j` | Output as JSON | No | `false` |
|
|
20
21
|
|
|
21
22
|
### JSON Output
|
|
22
23
|
|
|
@@ -27,8 +28,11 @@ human-readable text or empty stdout.
|
|
|
27
28
|
Commands that only perform side effects and do not define a structured result may leave stdout empty
|
|
28
29
|
even when `--json` is passed.
|
|
29
30
|
|
|
30
|
-
Errors, warnings, progress, and diagnostic messages are written to stderr.
|
|
31
|
-
|
|
31
|
+
Errors, warnings, progress, and diagnostic messages are written to stderr. After argument parsing,
|
|
32
|
+
a command failure under `--json` emits a JSON error envelope to stderr. CLI errors include a stable
|
|
33
|
+
`error.code` and may include structured `error.next` and `error.context` fields for automated
|
|
34
|
+
recovery. Diagnostic lines may precede the error envelope, and stdout is not guaranteed to contain
|
|
35
|
+
an error object.
|
|
32
36
|
|
|
33
37
|
## Common Options
|
|
34
38
|
|
package/docs/runtime.md
CHANGED
|
@@ -95,17 +95,16 @@ import { expect, test } from "vitest";
|
|
|
95
95
|
|
|
96
96
|
test("encodes via iconv", () => {
|
|
97
97
|
using iconvM = mockIconv();
|
|
98
|
-
iconvM.
|
|
98
|
+
iconvM.convert.mockReturnValue(new Uint8Array([0x82, 0xa0]));
|
|
99
99
|
|
|
100
100
|
const out = iconv.convert("あ", "UTF-8", "Shift_JIS");
|
|
101
101
|
|
|
102
102
|
expect(out).toEqual(new Uint8Array([0x82, 0xa0]));
|
|
103
|
-
expect(iconvM.
|
|
103
|
+
expect(iconvM.convert).toHaveBeenCalledWith("あ", "UTF-8", "Shift_JIS");
|
|
104
104
|
}); // iconvM disposed here — the iconv mock is removed (previous state restored)
|
|
105
105
|
|
|
106
106
|
test("reads from a vault", async () => {
|
|
107
|
-
using sm = mockSecretmanager();
|
|
108
|
-
sm.setSecrets({ "my-vault": { API_KEY: "sk-123" } });
|
|
107
|
+
using sm = mockSecretmanager({ secrets: { "my-vault": { API_KEY: "sk-123" } } });
|
|
109
108
|
|
|
110
109
|
await expect(secretmanager.getSecret("my-vault", "API_KEY")).resolves.toBe("sk-123");
|
|
111
110
|
});
|
|
@@ -111,3 +111,5 @@ const { url } = await aigateway.get("my-aigateway");
|
|
|
111
111
|
```
|
|
112
112
|
|
|
113
113
|
Type narrowing is provided by the generated `tailor.d.ts` (the `AIGatewayNameRegistry` interface). Run `tailor-sdk generate` (or `deploy`) after defining new AI Gateways to refresh it. Before the first generate run, `get()` accepts any string.
|
|
114
|
+
|
|
115
|
+
The same URL is also shown by `tailor-sdk show`, which lists the URL of each AI Gateway defined in `aiGateways` once it has been deployed.
|