zitejs 0.10.0-start.6 → 0.10.0-start.8

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.
Files changed (70) hide show
  1. package/dist/cjs/backend/index.d.ts +115 -3
  2. package/dist/cjs/backend/index.test.js +58 -0
  3. package/dist/cjs/integrations/rules.d.ts +13 -0
  4. package/dist/cjs/integrations/rules.js +29 -0
  5. package/dist/cjs/integrations/rules.test.js +1 -0
  6. package/dist/cjs/sync/lib.js +10 -13
  7. package/dist/cjs/vite/index.js +8 -3
  8. package/dist/cjs/vite/index.test.js +10 -2
  9. package/dist/esm/backend/index.d.ts +115 -3
  10. package/dist/esm/backend/index.test.js +58 -0
  11. package/dist/esm/integrations/rules.d.ts +13 -0
  12. package/dist/esm/integrations/rules.js +29 -0
  13. package/dist/esm/integrations/rules.test.js +1 -0
  14. package/dist/esm/start/airtable/arrayFields.d.ts +10 -0
  15. package/dist/esm/start/airtable/arrayFields.js +30 -0
  16. package/dist/esm/start/airtable/dispatch.d.ts +54 -0
  17. package/dist/esm/start/airtable/dispatch.js +465 -0
  18. package/dist/esm/start/airtable/formulas.d.ts +69 -0
  19. package/dist/esm/start/airtable/formulas.js +235 -0
  20. package/dist/esm/start/airtable/index.d.ts +11 -0
  21. package/dist/esm/start/airtable/index.js +70 -0
  22. package/dist/esm/start/authHooks.d.ts +7 -0
  23. package/dist/esm/start/authHooks.js +10 -0
  24. package/dist/esm/start/authHooksModule.d.ts +1 -0
  25. package/dist/esm/start/authHooksModule.js +3 -0
  26. package/dist/esm/start/clientErrorMessage.test.d.ts +1 -0
  27. package/dist/esm/start/clientErrorMessage.test.js +105 -0
  28. package/dist/esm/start/data/baseRunner.d.ts +92 -0
  29. package/dist/esm/start/data/baseRunner.js +83 -0
  30. package/dist/esm/start/data/dispatch.d.ts +16 -0
  31. package/dist/esm/start/data/dispatch.js +198 -0
  32. package/dist/esm/start/data/index.d.ts +18 -0
  33. package/dist/esm/start/data/index.js +76 -0
  34. package/dist/esm/start/data/sqlNameMappings.d.ts +58 -0
  35. package/dist/esm/start/data/sqlNameMappings.js +92 -0
  36. package/dist/esm/start/data/transformations.d.ts +128 -0
  37. package/dist/esm/start/data/transformations.js +318 -0
  38. package/dist/esm/start/data/types.d.ts +91 -0
  39. package/dist/esm/start/data/types.js +14 -0
  40. package/dist/esm/start/describe.d.ts +17 -1
  41. package/dist/esm/start/describe.js +27 -5
  42. package/dist/esm/start/errors.d.ts +46 -0
  43. package/dist/esm/start/errors.js +99 -0
  44. package/dist/esm/start/errors.test.d.ts +1 -0
  45. package/dist/esm/start/errors.test.js +23 -0
  46. package/dist/esm/start/index.d.ts +3 -19
  47. package/dist/esm/start/index.js +28 -36
  48. package/dist/esm/start/instance.d.ts +1 -2
  49. package/dist/esm/start/instance.js +11 -4
  50. package/dist/esm/start/previewClaim.d.ts +10 -0
  51. package/dist/esm/start/previewClaim.js +32 -0
  52. package/dist/esm/start/redactSecrets.d.ts +7 -0
  53. package/dist/esm/start/redactSecrets.js +131 -0
  54. package/dist/esm/start/redactSecrets.test.d.ts +1 -0
  55. package/dist/esm/start/redactSecrets.test.js +151 -0
  56. package/dist/esm/start/router.d.ts +6 -3
  57. package/dist/esm/start/router.js +47 -7
  58. package/dist/esm/start/runLog.d.ts +7 -4
  59. package/dist/esm/start/runLog.js +64 -6
  60. package/dist/esm/start/server.d.ts +7 -3
  61. package/dist/esm/start/server.js +124 -22
  62. package/dist/esm/start/types.d.ts +68 -3
  63. package/dist/esm/start/version.d.ts +1 -0
  64. package/dist/esm/start/version.js +2 -0
  65. package/dist/esm/start/vite.js +33 -4
  66. package/dist/esm/start/workflowRun.js +2 -1
  67. package/dist/esm/sync/lib.js +10 -13
  68. package/dist/esm/vite/index.js +8 -3
  69. package/dist/esm/vite/index.test.js +10 -2
  70. package/package.json +16 -8
@@ -6,6 +6,8 @@ const requestContext = { user: { id: "u1", email: "a@b.c", roles: [] } };
6
6
  // Direct execute() calls need the step surface the runtime always provides.
7
7
  const stepStub = {
8
8
  run: async (_name, fn) => await fn(),
9
+ sleep: async () => { },
10
+ sleepUntil: async () => { },
9
11
  };
10
12
  afterEach(() => {
11
13
  vi.unstubAllGlobals();
@@ -205,6 +207,62 @@ describe("platform-triggered runs", () => {
205
207
  return params.trigger;
206
208
  },
207
209
  });
210
+ createEndpoint({
211
+ trigger: { table: "orders", on: ["updated"], fields: ["status"] },
212
+ execute: async ({ input, trigger }) => {
213
+ // @ts-expect-error a database change has no cursor API
214
+ trigger?.advance("x");
215
+ const status = input.record?.status;
216
+ return { status, changed: input.changedFields, at: input.event };
217
+ },
218
+ });
219
+ createEndpoint({
220
+ // @ts-expect-error a database trigger names its table, not a connection
221
+ trigger: { table: "orders", on: ["created"], integration: "x" },
222
+ execute: async () => 1,
223
+ });
224
+ createEndpoint({
225
+ trigger: { form: "Intake form", on: ["submitted"] },
226
+ execute: async ({ input, trigger }) => {
227
+ // @ts-expect-error a form submission has no cursor API
228
+ trigger?.advance("x");
229
+ return {
230
+ email: input.answers.Email,
231
+ workEmail: input.answersById["wWorkEmail"],
232
+ id: input.submissionId,
233
+ };
234
+ },
235
+ });
236
+ createEndpoint({
237
+ // @ts-expect-error a form trigger watches submissions only
238
+ trigger: { form: "Intake form", on: ["updated"] },
239
+ execute: async () => 1,
240
+ });
241
+ createEndpoint({
242
+ // @ts-expect-error only created, updated and deleted
243
+ trigger: { table: "orders", on: ["archived"] },
244
+ execute: async () => 1,
245
+ });
246
+ });
247
+ it("hands a database trigger its change without parsing it against the input schema", async () => {
248
+ const endpoint = createEndpoint({
249
+ inputSchema: z.object({ orderId: z.string() }),
250
+ trigger: { table: "orders", on: ["created"] },
251
+ execute: async ({ input }) => input.recordId,
252
+ });
253
+ await expect(endpoint.execute({
254
+ step: stepStub,
255
+ input: {
256
+ event: "created",
257
+ table: "orders",
258
+ recordId: "rec_1",
259
+ record: { id: "rec_1" },
260
+ previous: null,
261
+ changedFields: [],
262
+ },
263
+ context: { user: null },
264
+ trigger: { headers: {}, deliveryId: "db:e1:rec_1" },
265
+ })).resolves.toBe("rec_1");
208
266
  });
209
267
  it("types a trigger's registration exports and checks what subscribe returns", async () => {
210
268
  const subscribe = (async (input) => ({
@@ -38,11 +38,24 @@ declare const FIELDS_BY_TYPE: {
38
38
  jira: readonly string[];
39
39
  typeform: readonly string[];
40
40
  apollo: readonly string[];
41
+ clay: readonly string[];
41
42
  attio: readonly string[];
42
43
  granola: readonly string[];
44
+ clickup: readonly string[];
43
45
  dropbox: readonly string[];
46
+ zendesk: readonly string[];
47
+ smartsheet: readonly string[];
44
48
  amazonS3: readonly string[];
45
49
  snowflake: readonly string[];
50
+ databricks: readonly string[];
51
+ confluence: readonly string[];
52
+ pipedrive: readonly string[];
53
+ shopify: readonly string[];
54
+ sharepoint: readonly string[];
55
+ excel: readonly string[];
56
+ x: readonly string[];
57
+ zoomMeetings: readonly string[];
58
+ smartsuite: readonly string[];
46
59
  };
47
60
  /** A service type `integrations.get` serves: one used through its npm package with a token. */
48
61
  export type CredentialServiceType = keyof typeof FIELDS_BY_TYPE;
@@ -44,15 +44,43 @@ const FIELDS_BY_TYPE = {
44
44
  jira: extras("cloudId", "siteUrl"),
45
45
  typeform: extras(),
46
46
  apollo: extras(),
47
+ clay: extras(),
47
48
  attio: extras(),
48
49
  granola: extras(),
50
+ clickup: extras(),
49
51
  dropbox: extras(),
52
+ // Every path is https://{subdomain}.zendesk.com/api/v2/..., and a token is
53
+ // only valid on the account it was issued for, so the subdomain travels with
54
+ // it rather than being configured per app.
55
+ zendesk: extras("subdomain"),
56
+ // Smartsheet's US, EU, AU and Gov regions are separate, and a token is only
57
+ // valid on its own region's host, so the host travels with it.
58
+ smartsheet: extras("apiBaseUrl"),
50
59
  // The IAM key alone reaches nothing: every call needs the region and the
51
60
  // bucket, and S3-compatible providers need the endpoint too.
52
61
  amazonS3: extras("keyId", "region", "bucket", "endpoint", "pathPrefix"),
53
62
  // The SQL API lives on each account's own host, and the token is pinned to
54
63
  // one role; the warehouse is optional and falls back to the user's default.
55
64
  snowflake: extras("accountUrl", "role", "warehouse"),
65
+ // A statement is addressed by workspace host and SQL warehouse, and the token
66
+ // derives neither.
67
+ databricks: extras("host", "warehouseId"),
68
+ // Cloud Confluence is addressed through api.atlassian.com by cloud id, the
69
+ // same as Jira; the site URL is only for links a human will click.
70
+ confluence: extras("cloudId", "siteUrl"),
71
+ // OAuth returns a per-company api_domain alongside the token, so there is no
72
+ // one host to call.
73
+ pipedrive: extras("apiBaseUrl"),
74
+ // Shopify has no global API host: every call goes to the store's own domain
75
+ // under a pinned API version. The storefront pair is the shopper-facing API,
76
+ // which installs predating those scopes do not have.
77
+ shopify: extras("shopDomain", "apiBaseUrl", "storefrontApiUrl", "storefrontAccessToken"),
78
+ sharepoint: extras(),
79
+ excel: extras(),
80
+ x: extras(),
81
+ zoomMeetings: extras(),
82
+ // Every request names the workspace in an Account-Id header beside the key.
83
+ smartsuite: extras("workspaceId"),
56
84
  };
57
85
  /** Per service type: `accessToken`, then its extra labels sorted (Salesforce `instanceUrl`). */
58
86
  export const CREDENTIAL_FIELDS = FIELDS_BY_TYPE;
@@ -65,6 +93,7 @@ export const OPTIONAL_CREDENTIAL_FIELDS = {
65
93
  // Only S3-compatible providers set an endpoint, and a prefix is opt-in.
66
94
  amazonS3: ["endpoint", "pathPrefix"],
67
95
  snowflake: ["warehouse"],
96
+ shopify: ["storefrontApiUrl", "storefrontAccessToken"],
68
97
  };
69
98
  /**
70
99
  * Types the runtime never serves: those with a generated client (Airtable, email,
@@ -16,6 +16,7 @@ describe("CREDENTIAL_FIELDS", () => {
16
16
  ]);
17
17
  expect(CREDENTIAL_FIELDS.jira).toEqual(["accessToken", "cloudId", "siteUrl"]);
18
18
  expect(CREDENTIAL_FIELDS.granola).toEqual(["accessToken"]);
19
+ expect(CREDENTIAL_FIELDS.smartsheet).toEqual(["accessToken", "apiBaseUrl"]);
19
20
  });
20
21
  it("has no type the runtime never serves", () => {
21
22
  for (const type of NON_CREDENTIAL_SERVICE_TYPES) {
@@ -0,0 +1,10 @@
1
+ export type AirtableFieldShape = {
2
+ type: string;
3
+ options?: unknown;
4
+ };
5
+ export declare const isArrayValuedAirtableField: (field: AirtableFieldShape) => boolean;
6
+ export declare const airtableEqualsFormula: ({ field, fieldName, value, }: {
7
+ field: AirtableFieldShape;
8
+ fieldName: string;
9
+ value: string;
10
+ }) => string;
@@ -0,0 +1,30 @@
1
+ import { z } from 'zod';
2
+ const ARRAY_VALUED_AIRTABLE_FIELD_TYPES = new Set([
3
+ 'multipleLookupValues',
4
+ 'multipleSelects',
5
+ 'multipleRecordLinks',
6
+ 'multipleCollaborators',
7
+ 'multipleAttachments',
8
+ ]);
9
+ const resultTypeOptionsSchema = z.object({
10
+ result: z.object({ type: z.string().optional() }).optional(),
11
+ });
12
+ export const isArrayValuedAirtableField = (field) => {
13
+ if (field.type === 'formula' || field.type === 'rollup') {
14
+ const resultType = resultTypeOptionsSchema.safeParse(field.options).data
15
+ ?.result?.type;
16
+ return resultType
17
+ ? ARRAY_VALUED_AIRTABLE_FIELD_TYPES.has(resultType)
18
+ : false;
19
+ }
20
+ return ARRAY_VALUED_AIRTABLE_FIELD_TYPES.has(field.type);
21
+ };
22
+ const ELEMENT_SEPARATOR = ', ';
23
+ export const airtableEqualsFormula = ({ field, fieldName, value, }) => {
24
+ if (!isArrayValuedAirtableField(field)) {
25
+ return `${fieldName}=${value}`;
26
+ }
27
+ const needle = `"${ELEMENT_SEPARATOR}" & ${value} & "${ELEMENT_SEPARATOR}"`;
28
+ const haystack = `"${ELEMENT_SEPARATOR}" & ARRAYJOIN(${fieldName}) & "${ELEMENT_SEPARATOR}"`;
29
+ return `SEARCH(${needle}, ${haystack}) != ""`;
30
+ };
@@ -0,0 +1,54 @@
1
+ /** As `@fillout/zite`'s `IntegrationFieldMappingType`, from zite.lock. */
2
+ export type AirtableFieldMapping = {
3
+ mapping: {
4
+ sdkName: string;
5
+ };
6
+ fieldType?: string;
7
+ fieldName?: string;
8
+ fieldOptions?: Record<string, unknown>;
9
+ };
10
+ export type AirtableFieldMappings = Record<string, AirtableFieldMapping>;
11
+ export type AirtableNameMappings = {
12
+ bases: Record<string, {
13
+ mapping: {
14
+ sdkName: string;
15
+ };
16
+ tables: Record<string, {
17
+ mapping: {
18
+ sdkName: string;
19
+ };
20
+ primaryFieldId?: string;
21
+ fields: AirtableFieldMappings;
22
+ }>;
23
+ }>;
24
+ };
25
+ /** An app's Airtable integration as its build declares it. */
26
+ export type AirtableSettings = {
27
+ baseId: string;
28
+ nameMappings: AirtableNameMappings | null;
29
+ };
30
+ /** Answers one Airtable request; the platform puts the connection's token on it. */
31
+ export type AirtableFetch = (path: string, init: {
32
+ method: string;
33
+ body?: unknown;
34
+ }) => Promise<Response>;
35
+ export type AirtableContext = {
36
+ settings: AirtableSettings;
37
+ fetch: AirtableFetch;
38
+ /** One request's reads, so the same read twice in a request goes to Airtable once. */
39
+ reads?: Map<string, Promise<unknown>>;
40
+ sleep?: (ms: number) => Promise<void>;
41
+ };
42
+ /** The npm SDK's error, whose shape apps (and the goldens) see: not an `Error`. */
43
+ export declare class AirtableError {
44
+ error: string;
45
+ message: string;
46
+ statusCode: number;
47
+ constructor(error: string, message: string, statusCode: number);
48
+ toString(): string;
49
+ }
50
+ export declare function airtableRecordToSdkNames(record: Record<string, any> | undefined, fieldMappings: AirtableFieldMappings | undefined): Record<string, any> | undefined;
51
+ /** A Duration cell (seconds) as HH:mm:ss, keeping seconds and fractions (ZIT-3889). */
52
+ export declare function formatAirtableDuration(durationSeconds: number): string;
53
+ /** One Airtable table call, as classic's dispatch runs it. */
54
+ export declare function executeAirtableCall(context: AirtableContext, methodName: string, params: any): Promise<any>;