@isomorph.ai/app-sdk 1.32.0 → 1.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -0
- package/dist/index.d.ts +74 -2
- package/dist/index.js +42 -0
- package/dist/integration-execute-input-rules.d.ts +130 -0
- package/dist/integration-execute-input-rules.js +42 -0
- package/dist/integration-operations.d.ts +35 -0
- package/dist/integration-operations.js +45 -0
- package/dist/jobs.d.ts +3 -2
- package/dist/jobs.js +6 -5
- package/dist/runtime.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -473,6 +473,32 @@ Without `onProgress` the call is unchanged and `ctx.progress` does nothing. At
|
|
|
473
473
|
most 256 steps of up to 1 KiB each reach the page; further steps are dropped.
|
|
474
474
|
The action still has the 300 s action budget. (Unreleased)
|
|
475
475
|
|
|
476
|
+
## Watching a query: `data.watch`
|
|
477
|
+
|
|
478
|
+
Progress, status and export screens re-read one query on a timer:
|
|
479
|
+
|
|
480
|
+
```ts
|
|
481
|
+
const stop = isomorph.data.watch(
|
|
482
|
+
() => isomorph.data.from('imports').select('*').eq('id', importId).single(),
|
|
483
|
+
({ data }) => setImport(data),
|
|
484
|
+
{ every: 3000, maxEvery: 15000 }, // the defaults
|
|
485
|
+
);
|
|
486
|
+
// on unmount
|
|
487
|
+
stop();
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
`build()` runs at once and then every `every` ms (3 s). While the tab is
|
|
491
|
+
hidden no read is made (where there is no `document`, as in Node, nothing is
|
|
492
|
+
skipped). While the answer is unchanged the interval doubles up to `maxEvery`
|
|
493
|
+
(15 s) and goes back to `every` on the first change; every result, changed or
|
|
494
|
+
not, reaches `onResult`. A read that fails (a 401, the network) reaches it
|
|
495
|
+
too, as `{ data: null, error }` with the error `await`ing the query would
|
|
496
|
+
have thrown, and the timer keeps running. There is no new transport or route: each tick is an ordinary
|
|
497
|
+
`QueryBuilder.execute()`, so it counts as app activity and is billed and
|
|
498
|
+
authorized like any read. Watch the job row, not the data table. Use
|
|
499
|
+
`realtime.channel` only when several people edit the same rows and sub-second
|
|
500
|
+
updates matter. (1.32.0)
|
|
501
|
+
|
|
476
502
|
## Running on Lambda
|
|
477
503
|
|
|
478
504
|
On a serverless cell Harbour runs an app's server code as Lambda functions, from a `runtime.zip` Kit Build makes; nothing in the app changes. The Web Function starts `dist/lambda-entry.js` (the zip's `index.js` is `import "@isomorph.ai/app-sdk/dist/lambda-entry.js"`), which serves actions on the port in `AWS_LAMBDA_HTTP_ENDPOINT` and stops on SIGTERM. The Event Function's handler is `node_modules/@isomorph.ai/app-sdk/dist/lambda-events-entry.handler`: `{"job": "<name>"}` runs that job once, as `--run-job <name>` does, and SQS records work queued runs until none are left.
|
package/dist/index.d.ts
CHANGED
|
@@ -39,6 +39,15 @@ export interface IsomorphResult<T> {
|
|
|
39
39
|
data: T;
|
|
40
40
|
count?: number;
|
|
41
41
|
}
|
|
42
|
+
/** `data.watch` timing: `every` ms between reads (default 3000), backing off to `maxEvery` (default 15000) while the answer does not change. */
|
|
43
|
+
export interface WatchOptions {
|
|
44
|
+
every?: number;
|
|
45
|
+
maxEvery?: number;
|
|
46
|
+
}
|
|
47
|
+
/** What `data.watch` delivers: the read's result, or `{ data: null, error }` when the read failed (the error `await`ing the query would have thrown). */
|
|
48
|
+
export type WatchResult = IsomorphResult<any> & {
|
|
49
|
+
error?: Error;
|
|
50
|
+
};
|
|
42
51
|
/** How Slack renders a message's `text`: plain text, or Slack mrkdwn (`*bold*`, `<url|label>`, `<@U123>`); plain when absent. */
|
|
43
52
|
export type SlackTextFormat = 'plain' | 'mrkdwn';
|
|
44
53
|
/**
|
|
@@ -1105,18 +1114,25 @@ export interface BooksLineInput {
|
|
|
1105
1114
|
export interface BooksBillLineInput extends BooksLineInput {
|
|
1106
1115
|
purchaseOrderItemId?: string;
|
|
1107
1116
|
}
|
|
1117
|
+
export interface BooksInvoiceLineInput extends BooksLineInput {
|
|
1118
|
+
salesOrderItemId?: string;
|
|
1119
|
+
}
|
|
1108
1120
|
export interface BooksDocument {
|
|
1109
1121
|
id: string;
|
|
1110
1122
|
number: string;
|
|
1111
1123
|
status: string;
|
|
1112
1124
|
currency: string;
|
|
1113
1125
|
total: string;
|
|
1126
|
+
referenceNumber?: string;
|
|
1114
1127
|
vendorId?: string;
|
|
1115
1128
|
customerId?: string;
|
|
1116
1129
|
lineItems: {
|
|
1117
1130
|
itemId: string;
|
|
1118
1131
|
lineItemId?: string;
|
|
1119
1132
|
purchaseOrderItemId?: string;
|
|
1133
|
+
sku?: string;
|
|
1134
|
+
taxId?: string;
|
|
1135
|
+
isInvoiced?: boolean;
|
|
1120
1136
|
quantity: string;
|
|
1121
1137
|
rate: string;
|
|
1122
1138
|
total: string;
|
|
@@ -1137,6 +1153,43 @@ export type ZohoBooksRequest = {
|
|
|
1137
1153
|
vendorId: string;
|
|
1138
1154
|
pageToken?: string;
|
|
1139
1155
|
};
|
|
1156
|
+
} | {
|
|
1157
|
+
operation: 'zohobooks.salesorder.list';
|
|
1158
|
+
resource: 'organization';
|
|
1159
|
+
input: {
|
|
1160
|
+
customerId: string;
|
|
1161
|
+
pageToken?: string;
|
|
1162
|
+
};
|
|
1163
|
+
} | {
|
|
1164
|
+
operation: 'zohobooks.salesorder.read' | 'zohobooks.creditnote.read';
|
|
1165
|
+
resource: 'organization';
|
|
1166
|
+
input: {
|
|
1167
|
+
documentId: string;
|
|
1168
|
+
};
|
|
1169
|
+
} | {
|
|
1170
|
+
operation: 'zohobooks.invoice.reviseDraft';
|
|
1171
|
+
resource: 'organization';
|
|
1172
|
+
idempotencyKey: string;
|
|
1173
|
+
input: {
|
|
1174
|
+
documentId: string;
|
|
1175
|
+
lineItems: {
|
|
1176
|
+
lineItemId: string;
|
|
1177
|
+
quantity: string;
|
|
1178
|
+
}[];
|
|
1179
|
+
};
|
|
1180
|
+
} | {
|
|
1181
|
+
operation: 'zohobooks.creditnote.create';
|
|
1182
|
+
resource: 'organization';
|
|
1183
|
+
idempotencyKey: string;
|
|
1184
|
+
input: {
|
|
1185
|
+
documentId: string;
|
|
1186
|
+
documentDate: string;
|
|
1187
|
+
referenceNumber?: string;
|
|
1188
|
+
lineItems: {
|
|
1189
|
+
lineItemId: string;
|
|
1190
|
+
quantity: string;
|
|
1191
|
+
}[];
|
|
1192
|
+
};
|
|
1140
1193
|
} | {
|
|
1141
1194
|
operation: 'zohobooks.purchaseorder.read';
|
|
1142
1195
|
resource: 'organization';
|
|
@@ -1169,7 +1222,7 @@ export type ZohoBooksRequest = {
|
|
|
1169
1222
|
documentDate: string;
|
|
1170
1223
|
documentNumber?: string;
|
|
1171
1224
|
referenceNumber?: string;
|
|
1172
|
-
lineItems:
|
|
1225
|
+
lineItems: BooksInvoiceLineInput[];
|
|
1173
1226
|
};
|
|
1174
1227
|
};
|
|
1175
1228
|
export type IntegrationRequest = ZohoBooksRequest | ServiceRequest | SlackChannelHistoryRequest | SlackMessagePostRequest | SlackMessageUpdateRequest | SlackMessageDeleteRequest | SlackDmSendRequest | SlackUserLookupRequest | WarehouseViewReadRequest | WarehouseTableAppendRequest | PhoneSmsListRequest | PhoneNumberGetRequest | GmailThreadListRequest | GmailThreadReadRequest | GmailMessageReadRequest | GmailAttachmentReadRequest | GmailMessageSendRequest | BasecampProjectListRequest | BasecampTodolistListRequest | BasecampTodoListRequest | BasecampTodoCreateRequest | BasecampTodoCompleteRequest | BasecampMessageListRequest | BasecampMessagePostRequest | BasecampCommentListRequest | BasecampCommentPostRequest | BasecampCampfirePostRequest | BasecampPeopleListRequest | SharePointListListRequest | SharePointItemListRequest | SharePointItemCreateRequest | SharePointItemUpdateRequest | SharePointDriveListRequest | SharePointFileListRequest | SharePointFileSearchRequest | SharePointFileReadRequest | SharePointFileUploadRequest | CalendarCalendarListRequest | CalendarEventListRequest | CalendarEventReadRequest | CalendarEventCreateRequest | CalendarEventUpdateRequest | CalendarEventCancelRequest | DriveFileListRequest | DriveFileSearchRequest | DriveFileReadRequest | DriveFileUploadRequest | DriveFolderCreateRequest | DocsDocumentReadRequest | DocsDocumentCreateRequest | DocsDocumentAppendRequest | DocsTextReplaceRequest | SheetsSpreadsheetReadRequest | SheetsValuesReadRequest | SheetsValuesAppendRequest | SheetsValuesUpdateRequest | SheetsValuesClearRequest | SheetsSpreadsheetCreateRequest | OutlookMessageListRequest | OutlookMessageReadRequest | OutlookAttachmentReadRequest | OutlookMessageSendRequest | OutlookMessageReplyRequest | OutlookEventListRequest | OutlookEventReadRequest | OutlookEventCreateRequest | OutlookEventUpdateRequest | OutlookEventCancelRequest | OneDriveFileListRequest | OneDriveFileSearchRequest | OneDriveFileReadRequest | OneDriveFileUploadRequest | OneDriveFolderCreateRequest | ExcelWorksheetListRequest | ExcelRangeReadRequest | ExcelRangeUpdateRequest | ExcelTableListRequest | ExcelRowAddRequest | ExcelWorksheetAddRequest | TeamsMessageListRequest | TeamsMessagePostRequest | TeamsReplyPostRequest;
|
|
@@ -1676,6 +1729,12 @@ export type IntegrationResult<R extends IntegrationRequest> = R extends {
|
|
|
1676
1729
|
}[];
|
|
1677
1730
|
hasMore: boolean;
|
|
1678
1731
|
nextPageToken?: string;
|
|
1732
|
+
} : R extends {
|
|
1733
|
+
operation: 'zohobooks.salesorder.list';
|
|
1734
|
+
} ? {
|
|
1735
|
+
booksSalesOrders: BooksDocument[];
|
|
1736
|
+
hasMore: boolean;
|
|
1737
|
+
nextPageToken?: string;
|
|
1679
1738
|
} : R extends {
|
|
1680
1739
|
operation: 'zohobooks.purchaseorder.list';
|
|
1681
1740
|
} ? {
|
|
@@ -1685,7 +1744,7 @@ export type IntegrationResult<R extends IntegrationRequest> = R extends {
|
|
|
1685
1744
|
} : R extends {
|
|
1686
1745
|
operation: 'zohobooks.invoice.pdf';
|
|
1687
1746
|
} ? GmailAttachmentReadResult : R extends {
|
|
1688
|
-
operation: 'zohobooks.bill.create' | 'zohobooks.invoice.create';
|
|
1747
|
+
operation: 'zohobooks.bill.create' | 'zohobooks.invoice.create' | 'zohobooks.invoice.reviseDraft' | 'zohobooks.creditnote.create';
|
|
1689
1748
|
} ? {
|
|
1690
1749
|
id: string;
|
|
1691
1750
|
} : R extends ZohoBooksRequest ? {
|
|
@@ -1895,6 +1954,7 @@ export declare function createClient(options?: ClientOptions): {
|
|
|
1895
1954
|
data: {
|
|
1896
1955
|
from: <T = Record<string, unknown>>(table: string) => QueryBuilder<T, T[]>;
|
|
1897
1956
|
rpc: <T = unknown>(name: string, args?: Record<string, unknown>) => Promise<T>;
|
|
1957
|
+
watch: <T = Record<string, unknown>>(build: () => QueryBuilder<T, any>, onResult: (result: WatchResult) => void, options?: WatchOptions) => (() => void);
|
|
1898
1958
|
};
|
|
1899
1959
|
files: {
|
|
1900
1960
|
createUpload: (input: {
|
|
@@ -1925,6 +1985,11 @@ export declare function createClient(options?: ClientOptions): {
|
|
|
1925
1985
|
}) => Promise<T>;
|
|
1926
1986
|
};
|
|
1927
1987
|
jobs: {
|
|
1988
|
+
/** Select the owner's folder for a declared configurable file trigger. */
|
|
1989
|
+
configureTrigger: (name: string, configuration: {
|
|
1990
|
+
folderId: string;
|
|
1991
|
+
}) => Promise<JobTriggerStatus>;
|
|
1992
|
+
getTrigger: (name: string) => Promise<JobTriggerStatus>;
|
|
1928
1993
|
enqueue: (name: string, input?: unknown) => Promise<{
|
|
1929
1994
|
id: string;
|
|
1930
1995
|
}>;
|
|
@@ -1962,6 +2027,13 @@ export type HarbourResult<T> = IsomorphResult<T>;
|
|
|
1962
2027
|
export type HarbourClient = IsomorphClient;
|
|
1963
2028
|
/** @deprecated Internal transformation lane only; a kit app uses IsomorphCompatSource. */
|
|
1964
2029
|
export type HarbourCompatSource = import('./supabase-compat.js').IsomorphCompatSource;
|
|
2030
|
+
/** Owner-selected folder; activation still requires the owner's background consent. */
|
|
2031
|
+
export interface JobTriggerStatus {
|
|
2032
|
+
name: string;
|
|
2033
|
+
folderId?: string;
|
|
2034
|
+
state: 'configured' | 'unconfigured';
|
|
2035
|
+
updatedAt?: string;
|
|
2036
|
+
}
|
|
1965
2037
|
/** Provider file metadata delivered to a file.created job; bytes are read through its connection. */
|
|
1966
2038
|
export interface FileArrivalInput {
|
|
1967
2039
|
type: 'file.created';
|
package/dist/index.js
CHANGED
|
@@ -707,6 +707,45 @@ export function createClient(options = {}) {
|
|
|
707
707
|
data: {
|
|
708
708
|
from: (table) => new QueryBuilder(transport, table),
|
|
709
709
|
rpc: (name, args = {}) => transport.json(`/_harbour/data/rpc/${encodeURIComponent(name)}`, { method: 'POST', body: JSON.stringify(args) }),
|
|
710
|
+
// A query on a timer: QueryBuilder.execute() now and every `every` ms,
|
|
711
|
+
// no read while the tab is hidden, the interval doubling up to
|
|
712
|
+
// `maxEvery` while the answer is unchanged. No new transport or route;
|
|
713
|
+
// each read is an ordinary read (it counts as app activity), so watch
|
|
714
|
+
// the job row, not the data table. A failed read is delivered as
|
|
715
|
+
// { data: null, error } and the timer keeps going.
|
|
716
|
+
watch: (build, onResult, options = {}) => {
|
|
717
|
+
const every = options.every ?? 3_000;
|
|
718
|
+
const maxEvery = options.maxEvery ?? 15_000;
|
|
719
|
+
let delay = every;
|
|
720
|
+
let previous;
|
|
721
|
+
let stopped = false;
|
|
722
|
+
let timer;
|
|
723
|
+
const schedule = () => { if (!stopped)
|
|
724
|
+
timer = setTimer(tick, delay); };
|
|
725
|
+
const tick = async () => {
|
|
726
|
+
if (typeof document !== 'undefined' && document.hidden) {
|
|
727
|
+
schedule();
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
let result;
|
|
731
|
+
try {
|
|
732
|
+
result = await build().execute();
|
|
733
|
+
}
|
|
734
|
+
catch (error) {
|
|
735
|
+
result = { data: null, error: error instanceof Error ? error : new Error(String(error)) };
|
|
736
|
+
}
|
|
737
|
+
if (stopped)
|
|
738
|
+
return;
|
|
739
|
+
const json = JSON.stringify({ ...result, error: result.error?.message });
|
|
740
|
+
delay = json === previous ? Math.min(delay * 2, maxEvery) : every;
|
|
741
|
+
previous = json;
|
|
742
|
+
onResult(result);
|
|
743
|
+
schedule();
|
|
744
|
+
};
|
|
745
|
+
void tick();
|
|
746
|
+
return () => { stopped = true; if (timer !== undefined)
|
|
747
|
+
clearTimer(timer); };
|
|
748
|
+
},
|
|
710
749
|
},
|
|
711
750
|
files: {
|
|
712
751
|
createUpload: (input) => transport.json('/_harbour/files/uploads', { method: 'POST', body: JSON.stringify(input) }),
|
|
@@ -746,6 +785,9 @@ export function createClient(options = {}) {
|
|
|
746
785
|
},
|
|
747
786
|
},
|
|
748
787
|
jobs: {
|
|
788
|
+
/** Select the owner's folder for a declared configurable file trigger. */
|
|
789
|
+
configureTrigger: (name, configuration) => transport.json('/_harbour/integrations/trigger-config', { method: 'POST', body: JSON.stringify({ name, configuration }) }),
|
|
790
|
+
getTrigger: (name) => transport.json('/_harbour/integrations/trigger-config', { method: 'POST', body: JSON.stringify({ name }) }),
|
|
749
791
|
enqueue: (name, input) => transport.json('/_harbour/actions/isomorph-jobs-enqueue', { method: 'POST', body: JSON.stringify({ name, input: input ?? null }) }),
|
|
750
792
|
get: (id) => transport.json('/_harbour/actions/isomorph-jobs-get', { method: 'POST', body: JSON.stringify({ id }) }),
|
|
751
793
|
cancel: (id) => transport.json('/_harbour/actions/isomorph-jobs-cancel', { method: 'POST', body: JSON.stringify({ id }) }),
|
|
@@ -2386,6 +2386,13 @@ export declare const IntegrationExecuteInputRules: {
|
|
|
2386
2386
|
readonly minLength: 0;
|
|
2387
2387
|
readonly maxLength: 2000;
|
|
2388
2388
|
};
|
|
2389
|
+
readonly salesOrderItemId: {
|
|
2390
|
+
readonly kind: "string";
|
|
2391
|
+
readonly required: false;
|
|
2392
|
+
readonly minLength: 0;
|
|
2393
|
+
readonly maxLength: 32;
|
|
2394
|
+
readonly pattern: "^[0-9]{1,32}$";
|
|
2395
|
+
};
|
|
2389
2396
|
};
|
|
2390
2397
|
};
|
|
2391
2398
|
};
|
|
@@ -2414,6 +2421,129 @@ export declare const IntegrationExecuteInputRules: {
|
|
|
2414
2421
|
};
|
|
2415
2422
|
};
|
|
2416
2423
|
};
|
|
2424
|
+
readonly "zohobooks.salesorder.list": {
|
|
2425
|
+
readonly idempotencyKey: false;
|
|
2426
|
+
readonly fields: {
|
|
2427
|
+
readonly customerId: {
|
|
2428
|
+
readonly kind: "string";
|
|
2429
|
+
readonly required: true;
|
|
2430
|
+
readonly minLength: 0;
|
|
2431
|
+
readonly maxLength: 32;
|
|
2432
|
+
readonly pattern: "^[0-9]{1,32}$";
|
|
2433
|
+
};
|
|
2434
|
+
readonly pageToken: {
|
|
2435
|
+
readonly kind: "string";
|
|
2436
|
+
readonly required: false;
|
|
2437
|
+
readonly minLength: 1;
|
|
2438
|
+
readonly maxLength: 2048;
|
|
2439
|
+
};
|
|
2440
|
+
};
|
|
2441
|
+
};
|
|
2442
|
+
readonly "zohobooks.salesorder.read": {
|
|
2443
|
+
readonly idempotencyKey: false;
|
|
2444
|
+
readonly fields: {
|
|
2445
|
+
readonly documentId: {
|
|
2446
|
+
readonly kind: "string";
|
|
2447
|
+
readonly required: true;
|
|
2448
|
+
readonly minLength: 0;
|
|
2449
|
+
readonly maxLength: 32;
|
|
2450
|
+
readonly pattern: "^[0-9]{1,32}$";
|
|
2451
|
+
};
|
|
2452
|
+
};
|
|
2453
|
+
};
|
|
2454
|
+
readonly "zohobooks.invoice.reviseDraft": {
|
|
2455
|
+
readonly idempotencyKey: true;
|
|
2456
|
+
readonly fields: {
|
|
2457
|
+
readonly documentId: {
|
|
2458
|
+
readonly kind: "string";
|
|
2459
|
+
readonly required: true;
|
|
2460
|
+
readonly minLength: 0;
|
|
2461
|
+
readonly maxLength: 32;
|
|
2462
|
+
readonly pattern: "^[0-9]{1,32}$";
|
|
2463
|
+
};
|
|
2464
|
+
readonly lineItems: {
|
|
2465
|
+
readonly kind: "object[]";
|
|
2466
|
+
readonly required: true;
|
|
2467
|
+
readonly minItems: 1;
|
|
2468
|
+
readonly maxItems: 100;
|
|
2469
|
+
readonly fields: {
|
|
2470
|
+
readonly lineItemId: {
|
|
2471
|
+
readonly kind: "string";
|
|
2472
|
+
readonly required: true;
|
|
2473
|
+
readonly minLength: 0;
|
|
2474
|
+
readonly maxLength: 32;
|
|
2475
|
+
readonly pattern: "^[0-9]{1,32}$";
|
|
2476
|
+
};
|
|
2477
|
+
readonly quantity: {
|
|
2478
|
+
readonly kind: "string";
|
|
2479
|
+
readonly required: true;
|
|
2480
|
+
readonly minLength: 0;
|
|
2481
|
+
readonly maxLength: 17;
|
|
2482
|
+
readonly pattern: "^[0-9]{1,10}(\\.[0-9]{1,6})?$";
|
|
2483
|
+
};
|
|
2484
|
+
};
|
|
2485
|
+
};
|
|
2486
|
+
};
|
|
2487
|
+
};
|
|
2488
|
+
readonly "zohobooks.creditnote.create": {
|
|
2489
|
+
readonly idempotencyKey: true;
|
|
2490
|
+
readonly fields: {
|
|
2491
|
+
readonly documentId: {
|
|
2492
|
+
readonly kind: "string";
|
|
2493
|
+
readonly required: true;
|
|
2494
|
+
readonly minLength: 0;
|
|
2495
|
+
readonly maxLength: 32;
|
|
2496
|
+
readonly pattern: "^[0-9]{1,32}$";
|
|
2497
|
+
};
|
|
2498
|
+
readonly documentDate: {
|
|
2499
|
+
readonly kind: "string";
|
|
2500
|
+
readonly required: true;
|
|
2501
|
+
readonly minLength: 0;
|
|
2502
|
+
readonly maxLength: 10;
|
|
2503
|
+
readonly pattern: "^[0-9]{4}-[0-9]{2}-[0-9]{2}$";
|
|
2504
|
+
};
|
|
2505
|
+
readonly referenceNumber: {
|
|
2506
|
+
readonly kind: "string";
|
|
2507
|
+
readonly required: false;
|
|
2508
|
+
readonly minLength: 1;
|
|
2509
|
+
readonly maxLength: 100;
|
|
2510
|
+
};
|
|
2511
|
+
readonly lineItems: {
|
|
2512
|
+
readonly kind: "object[]";
|
|
2513
|
+
readonly required: true;
|
|
2514
|
+
readonly minItems: 1;
|
|
2515
|
+
readonly maxItems: 100;
|
|
2516
|
+
readonly fields: {
|
|
2517
|
+
readonly lineItemId: {
|
|
2518
|
+
readonly kind: "string";
|
|
2519
|
+
readonly required: true;
|
|
2520
|
+
readonly minLength: 0;
|
|
2521
|
+
readonly maxLength: 32;
|
|
2522
|
+
readonly pattern: "^[0-9]{1,32}$";
|
|
2523
|
+
};
|
|
2524
|
+
readonly quantity: {
|
|
2525
|
+
readonly kind: "string";
|
|
2526
|
+
readonly required: true;
|
|
2527
|
+
readonly minLength: 0;
|
|
2528
|
+
readonly maxLength: 17;
|
|
2529
|
+
readonly pattern: "^[0-9]{1,10}(\\.[0-9]{1,6})?$";
|
|
2530
|
+
};
|
|
2531
|
+
};
|
|
2532
|
+
};
|
|
2533
|
+
};
|
|
2534
|
+
};
|
|
2535
|
+
readonly "zohobooks.creditnote.read": {
|
|
2536
|
+
readonly idempotencyKey: false;
|
|
2537
|
+
readonly fields: {
|
|
2538
|
+
readonly documentId: {
|
|
2539
|
+
readonly kind: "string";
|
|
2540
|
+
readonly required: true;
|
|
2541
|
+
readonly minLength: 0;
|
|
2542
|
+
readonly maxLength: 32;
|
|
2543
|
+
readonly pattern: "^[0-9]{1,32}$";
|
|
2544
|
+
};
|
|
2545
|
+
};
|
|
2546
|
+
};
|
|
2417
2547
|
};
|
|
2418
2548
|
export type IntegrationExecuteOperation = keyof typeof IntegrationExecuteInputRules;
|
|
2419
2549
|
/** The upper bound of one integer input as a literal type: integrationExecuteInputMaximum('slack.channel.history', 'limit') is 15. */
|
|
@@ -729,6 +729,7 @@ export const IntegrationExecuteInputRules = {
|
|
|
729
729
|
rate: { kind: "string", required: true, minLength: 0, maxLength: 17, pattern: "^[0-9]{1,10}(\\.[0-9]{1,6})?$" },
|
|
730
730
|
taxId: { kind: "string", required: false, minLength: 0, maxLength: 32, pattern: "^[0-9]{1,32}$" },
|
|
731
731
|
description: { kind: "string", required: false, minLength: 0, maxLength: 2000 },
|
|
732
|
+
salesOrderItemId: { kind: "string", required: false, minLength: 0, maxLength: 32, pattern: "^[0-9]{1,32}$" },
|
|
732
733
|
} },
|
|
733
734
|
},
|
|
734
735
|
},
|
|
@@ -744,6 +745,47 @@ export const IntegrationExecuteInputRules = {
|
|
|
744
745
|
documentId: { kind: "string", required: true, minLength: 0, maxLength: 32, pattern: "^[0-9]{1,32}$" },
|
|
745
746
|
},
|
|
746
747
|
},
|
|
748
|
+
"zohobooks.salesorder.list": {
|
|
749
|
+
idempotencyKey: false,
|
|
750
|
+
fields: {
|
|
751
|
+
customerId: { kind: "string", required: true, minLength: 0, maxLength: 32, pattern: "^[0-9]{1,32}$" },
|
|
752
|
+
pageToken: { kind: "string", required: false, minLength: 1, maxLength: 2048 },
|
|
753
|
+
},
|
|
754
|
+
},
|
|
755
|
+
"zohobooks.salesorder.read": {
|
|
756
|
+
idempotencyKey: false,
|
|
757
|
+
fields: {
|
|
758
|
+
documentId: { kind: "string", required: true, minLength: 0, maxLength: 32, pattern: "^[0-9]{1,32}$" },
|
|
759
|
+
},
|
|
760
|
+
},
|
|
761
|
+
"zohobooks.invoice.reviseDraft": {
|
|
762
|
+
idempotencyKey: true,
|
|
763
|
+
fields: {
|
|
764
|
+
documentId: { kind: "string", required: true, minLength: 0, maxLength: 32, pattern: "^[0-9]{1,32}$" },
|
|
765
|
+
lineItems: { kind: "object[]", required: true, minItems: 1, maxItems: 100, fields: {
|
|
766
|
+
lineItemId: { kind: "string", required: true, minLength: 0, maxLength: 32, pattern: "^[0-9]{1,32}$" },
|
|
767
|
+
quantity: { kind: "string", required: true, minLength: 0, maxLength: 17, pattern: "^[0-9]{1,10}(\\.[0-9]{1,6})?$" },
|
|
768
|
+
} },
|
|
769
|
+
},
|
|
770
|
+
},
|
|
771
|
+
"zohobooks.creditnote.create": {
|
|
772
|
+
idempotencyKey: true,
|
|
773
|
+
fields: {
|
|
774
|
+
documentId: { kind: "string", required: true, minLength: 0, maxLength: 32, pattern: "^[0-9]{1,32}$" },
|
|
775
|
+
documentDate: { kind: "string", required: true, minLength: 0, maxLength: 10, pattern: "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" },
|
|
776
|
+
referenceNumber: { kind: "string", required: false, minLength: 1, maxLength: 100 },
|
|
777
|
+
lineItems: { kind: "object[]", required: true, minItems: 1, maxItems: 100, fields: {
|
|
778
|
+
lineItemId: { kind: "string", required: true, minLength: 0, maxLength: 32, pattern: "^[0-9]{1,32}$" },
|
|
779
|
+
quantity: { kind: "string", required: true, minLength: 0, maxLength: 17, pattern: "^[0-9]{1,10}(\\.[0-9]{1,6})?$" },
|
|
780
|
+
} },
|
|
781
|
+
},
|
|
782
|
+
},
|
|
783
|
+
"zohobooks.creditnote.read": {
|
|
784
|
+
idempotencyKey: false,
|
|
785
|
+
fields: {
|
|
786
|
+
documentId: { kind: "string", required: true, minLength: 0, maxLength: 32, pattern: "^[0-9]{1,32}$" },
|
|
787
|
+
},
|
|
788
|
+
},
|
|
747
789
|
};
|
|
748
790
|
/** The upper bound of one integer input as a literal type: integrationExecuteInputMaximum('slack.channel.history', 'limit') is 15. */
|
|
749
791
|
export function integrationExecuteInputMaximum(operation, field) {
|
|
@@ -623,4 +623,39 @@ export declare const IntegrationOperations: {
|
|
|
623
623
|
readonly declaredMode: false;
|
|
624
624
|
readonly idempotencyKey: false;
|
|
625
625
|
};
|
|
626
|
+
readonly "zohobooks.salesorder.list": {
|
|
627
|
+
readonly kind: "saas";
|
|
628
|
+
readonly identities: readonly ["user"];
|
|
629
|
+
readonly readOnly: true;
|
|
630
|
+
readonly declaredMode: false;
|
|
631
|
+
readonly idempotencyKey: false;
|
|
632
|
+
};
|
|
633
|
+
readonly "zohobooks.salesorder.read": {
|
|
634
|
+
readonly kind: "saas";
|
|
635
|
+
readonly identities: readonly ["user"];
|
|
636
|
+
readonly readOnly: true;
|
|
637
|
+
readonly declaredMode: false;
|
|
638
|
+
readonly idempotencyKey: false;
|
|
639
|
+
};
|
|
640
|
+
readonly "zohobooks.invoice.reviseDraft": {
|
|
641
|
+
readonly kind: "saas";
|
|
642
|
+
readonly identities: readonly ["user"];
|
|
643
|
+
readonly readOnly: false;
|
|
644
|
+
readonly declaredMode: false;
|
|
645
|
+
readonly idempotencyKey: true;
|
|
646
|
+
};
|
|
647
|
+
readonly "zohobooks.creditnote.create": {
|
|
648
|
+
readonly kind: "saas";
|
|
649
|
+
readonly identities: readonly ["user"];
|
|
650
|
+
readonly readOnly: false;
|
|
651
|
+
readonly declaredMode: false;
|
|
652
|
+
readonly idempotencyKey: true;
|
|
653
|
+
};
|
|
654
|
+
readonly "zohobooks.creditnote.read": {
|
|
655
|
+
readonly kind: "saas";
|
|
656
|
+
readonly identities: readonly ["user"];
|
|
657
|
+
readonly readOnly: true;
|
|
658
|
+
readonly declaredMode: false;
|
|
659
|
+
readonly idempotencyKey: false;
|
|
660
|
+
};
|
|
626
661
|
};
|
|
@@ -806,5 +806,50 @@ export const IntegrationOperations = {
|
|
|
806
806
|
"readOnly": true,
|
|
807
807
|
"declaredMode": false,
|
|
808
808
|
"idempotencyKey": false
|
|
809
|
+
},
|
|
810
|
+
"zohobooks.salesorder.list": {
|
|
811
|
+
"kind": "saas",
|
|
812
|
+
"identities": [
|
|
813
|
+
"user"
|
|
814
|
+
],
|
|
815
|
+
"readOnly": true,
|
|
816
|
+
"declaredMode": false,
|
|
817
|
+
"idempotencyKey": false
|
|
818
|
+
},
|
|
819
|
+
"zohobooks.salesorder.read": {
|
|
820
|
+
"kind": "saas",
|
|
821
|
+
"identities": [
|
|
822
|
+
"user"
|
|
823
|
+
],
|
|
824
|
+
"readOnly": true,
|
|
825
|
+
"declaredMode": false,
|
|
826
|
+
"idempotencyKey": false
|
|
827
|
+
},
|
|
828
|
+
"zohobooks.invoice.reviseDraft": {
|
|
829
|
+
"kind": "saas",
|
|
830
|
+
"identities": [
|
|
831
|
+
"user"
|
|
832
|
+
],
|
|
833
|
+
"readOnly": false,
|
|
834
|
+
"declaredMode": false,
|
|
835
|
+
"idempotencyKey": true
|
|
836
|
+
},
|
|
837
|
+
"zohobooks.creditnote.create": {
|
|
838
|
+
"kind": "saas",
|
|
839
|
+
"identities": [
|
|
840
|
+
"user"
|
|
841
|
+
],
|
|
842
|
+
"readOnly": false,
|
|
843
|
+
"declaredMode": false,
|
|
844
|
+
"idempotencyKey": true
|
|
845
|
+
},
|
|
846
|
+
"zohobooks.creditnote.read": {
|
|
847
|
+
"kind": "saas",
|
|
848
|
+
"identities": [
|
|
849
|
+
"user"
|
|
850
|
+
],
|
|
851
|
+
"readOnly": true,
|
|
852
|
+
"declaredMode": false,
|
|
853
|
+
"idempotencyKey": false
|
|
809
854
|
}
|
|
810
855
|
};
|
package/dist/jobs.d.ts
CHANGED
|
@@ -8,13 +8,14 @@ export interface EmailArrivalTrigger {
|
|
|
8
8
|
subjectContains?: string;
|
|
9
9
|
};
|
|
10
10
|
}
|
|
11
|
-
export declare const FILE_MIME_TYPES: readonly ["application/pdf", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"];
|
|
11
|
+
export declare const FILE_MIME_TYPES: readonly ["application/pdf", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "image/png", "image/jpeg"];
|
|
12
12
|
export declare const providerFileId: (value: unknown) => value is string;
|
|
13
13
|
export interface FileCreatedTrigger {
|
|
14
14
|
type: 'file.created';
|
|
15
15
|
connection: string;
|
|
16
16
|
resource: string;
|
|
17
|
-
folderId
|
|
17
|
+
folderId?: string;
|
|
18
|
+
configurableFolder?: true;
|
|
18
19
|
driveId?: string;
|
|
19
20
|
mimeTypes?: string[];
|
|
20
21
|
}
|
package/dist/jobs.js
CHANGED
|
@@ -6,7 +6,7 @@ import { stripTypeScriptTypes } from 'node:module';
|
|
|
6
6
|
import { parse } from 'acorn';
|
|
7
7
|
export const JOBS_DIR = 'jobs';
|
|
8
8
|
const LOGICAL_NAME = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
9
|
-
export const FILE_MIME_TYPES = ['application/pdf', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'];
|
|
9
|
+
export const FILE_MIME_TYPES = ['application/pdf', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'image/png', 'image/jpeg'];
|
|
10
10
|
export const providerFileId = (value) => typeof value === 'string' && /^[A-Za-z0-9!._,=-]{1,256}$/.test(value);
|
|
11
11
|
function literalObject(node) {
|
|
12
12
|
const value = node;
|
|
@@ -30,12 +30,13 @@ function literalObject(node) {
|
|
|
30
30
|
export function eventTrigger(value) {
|
|
31
31
|
if (value?.type === 'file.created') {
|
|
32
32
|
const t = value;
|
|
33
|
-
if (Object.keys(t).some(k => !['type', 'connection', 'resource', 'folderId', 'driveId', 'mimeTypes'].includes(k))
|
|
33
|
+
if (Object.keys(t).some(k => !['type', 'connection', 'resource', 'folderId', 'configurableFolder', 'driveId', 'mimeTypes'].includes(k))
|
|
34
34
|
|| typeof t.connection !== 'string' || !LOGICAL_NAME.test(t.connection)
|
|
35
35
|
|| typeof t.resource !== 'string' || !t.resource.trim() || t.resource.length > 320
|
|
36
|
-
||
|
|
37
|
-
|| (t.
|
|
38
|
-
|
|
36
|
+
|| (t.configurableFolder !== undefined && t.configurableFolder !== true)
|
|
37
|
+
|| (t.folderId === undefined ? t.configurableFolder !== true : !providerFileId(t.folderId)) || (t.driveId !== undefined && !providerFileId(t.driveId))
|
|
38
|
+
|| (t.mimeTypes !== undefined && (!Array.isArray(t.mimeTypes) || !t.mimeTypes.length || t.mimeTypes.length > FILE_MIME_TYPES.length || new Set(t.mimeTypes).size !== t.mimeTypes.length || t.mimeTypes.some(m => !FILE_MIME_TYPES.includes(m)))))
|
|
39
|
+
throw new Error('file.created requires a connection, resource, folder ID and optional PDF/XLSX/PNG/JPEG MIME types');
|
|
39
40
|
return t;
|
|
40
41
|
}
|
|
41
42
|
const trigger = value;
|
package/dist/runtime.js
CHANGED
|
@@ -395,7 +395,7 @@ export class Runtime {
|
|
|
395
395
|
if (job.trigger.type === 'file.created') {
|
|
396
396
|
const instant = (v) => typeof v === 'string' && /^\d{4}-\d{2}-\d{2}T/.test(v) && Number.isFinite(Date.parse(v));
|
|
397
397
|
if (Object.keys(input).some(k => !['type', 'provider', 'sourceId', 'fileId', 'folderId', 'driveId', 'name', 'mimeType', 'size', 'createdAt', 'observedAt'].includes(k))
|
|
398
|
-
|| input.type !== 'file.created' || !['drive', 'sharepoint'].includes(String(input.provider)) || !providerFileId(input.fileId) || input.folderId !== job.trigger.folderId
|
|
398
|
+
|| input.type !== 'file.created' || !['drive', 'sharepoint'].includes(String(input.provider)) || !providerFileId(input.fileId) || !providerFileId(input.folderId) || (!job.trigger.configurableFolder && input.folderId !== job.trigger.folderId)
|
|
399
399
|
|| (input.driveId !== undefined && !providerFileId(input.driveId)) || (input.provider === 'sharepoint' && !input.driveId)
|
|
400
400
|
|| (job.trigger.driveId !== undefined && input.driveId !== job.trigger.driveId)
|
|
401
401
|
|| typeof input.name !== 'string' || !input.name || input.name.length > 1024 || !Number.isSafeInteger(input.size) || Number(input.size) < 0
|