zitejs 0.9.123 → 0.9.124

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 (58) hide show
  1. package/README.md +4 -0
  2. package/dist/cjs/auth/index.d.ts +2 -2
  3. package/dist/cjs/bundle/index.d.ts +4 -0
  4. package/dist/cjs/bundle/index.js +28 -9
  5. package/dist/cjs/dev/index.d.ts +5 -0
  6. package/dist/cjs/dev/index.js +46 -0
  7. package/dist/cjs/index.d.ts +2 -0
  8. package/dist/cjs/index.js +7 -1
  9. package/dist/cjs/integrations/client.d.ts +25 -0
  10. package/dist/cjs/integrations/client.js +21 -0
  11. package/dist/cjs/integrations/client.test-d.d.ts +1 -0
  12. package/dist/cjs/integrations/client.test-d.js +50 -0
  13. package/dist/cjs/integrations/index.d.ts +3 -0
  14. package/dist/cjs/integrations/index.js +6 -0
  15. package/dist/cjs/integrations/rules.d.ts +67 -0
  16. package/dist/cjs/integrations/rules.js +104 -0
  17. package/dist/cjs/integrations/rules.test.d.ts +1 -0
  18. package/dist/cjs/integrations/rules.test.js +86 -0
  19. package/dist/cjs/internal/sdkCall.d.ts +1 -0
  20. package/dist/cjs/internal/sdkCall.js +3 -1
  21. package/dist/cjs/runtime/index.d.ts +1 -0
  22. package/dist/cjs/runtime/index.js +3 -1
  23. package/dist/cjs/sync/lib.d.ts +9 -0
  24. package/dist/cjs/sync/lib.js +53 -0
  25. package/dist/cjs/sync/lib.test.js +119 -0
  26. package/dist/esm/auth/index.d.ts +2 -2
  27. package/dist/esm/bundle/index.d.ts +4 -0
  28. package/dist/esm/bundle/index.js +28 -10
  29. package/dist/esm/dev/index.d.ts +5 -0
  30. package/dist/esm/dev/index.js +47 -2
  31. package/dist/esm/index.d.ts +2 -0
  32. package/dist/esm/index.js +1 -0
  33. package/dist/esm/integrations/client.d.ts +25 -0
  34. package/dist/esm/integrations/client.js +17 -0
  35. package/dist/esm/integrations/client.test-d.d.ts +1 -0
  36. package/dist/esm/integrations/client.test-d.js +48 -0
  37. package/dist/esm/integrations/index.d.ts +3 -0
  38. package/dist/esm/integrations/index.js +3 -0
  39. package/dist/esm/integrations/rules.d.ts +67 -0
  40. package/dist/esm/integrations/rules.js +98 -0
  41. package/dist/esm/integrations/rules.test.d.ts +1 -0
  42. package/dist/esm/integrations/rules.test.js +84 -0
  43. package/dist/esm/internal/sdkCall.d.ts +1 -0
  44. package/dist/esm/internal/sdkCall.js +2 -1
  45. package/dist/esm/runtime/index.d.ts +1 -0
  46. package/dist/esm/runtime/index.js +1 -0
  47. package/dist/esm/sync/lib.d.ts +9 -0
  48. package/dist/esm/sync/lib.js +52 -0
  49. package/dist/esm/sync/lib.test.js +120 -1
  50. package/package.json +10 -1
  51. package/dist/cjs/meta/index.d.ts +0 -14
  52. package/dist/cjs/meta/index.js +0 -12
  53. package/dist/cjs/notifications/index.d.ts +0 -25
  54. package/dist/cjs/notifications/index.js +0 -12
  55. package/dist/esm/meta/index.d.ts +0 -14
  56. package/dist/esm/meta/index.js +0 -8
  57. package/dist/esm/notifications/index.d.ts +0 -25
  58. package/dist/esm/notifications/index.js +0 -8
package/README.md CHANGED
@@ -41,4 +41,8 @@ import { ZitePdf } from 'zitejs/pdf';
41
41
 
42
42
  // Scheduled tasks
43
43
  import { ZiteSchedule } from 'zitejs/schedules';
44
+
45
+ // An integration's credentials, by its zite.config.json entry name
46
+ import { integrations } from 'zitejs/integrations';
47
+ const crm = await integrations.get('crm');
44
48
  ```
@@ -67,7 +67,7 @@ export declare const signIn: {
67
67
  }, FetchOptions["throw"] extends true ? true : false>>;
68
68
  } & {
69
69
  social: <FetchOptions extends import("@better-auth/core").ClientFetchOption<Partial<{
70
- provider: (string & {}) | "linear" | "huggingface" | "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "railway" | "vercel" | "wechat";
70
+ provider: "salesforce" | "slack" | "linear" | "notion" | "linkedin" | "github" | (string & {}) | "huggingface" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "gitlab" | "tiktok" | "reddit" | "roblox" | "vk" | "zoom" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "railway" | "vercel" | "wechat";
71
71
  callbackURL?: string | undefined;
72
72
  newUserCallbackURL?: string | undefined;
73
73
  errorCallbackURL?: string | undefined;
@@ -91,7 +91,7 @@ export declare const signIn: {
91
91
  loginHint?: string | undefined;
92
92
  additionalData?: Record<string, any> | undefined;
93
93
  }> & Record<string, any>, Partial<Record<string, any>> & Record<string, any>, Record<string, any> | undefined>>(data_0: import("better-auth/react").Prettify<{
94
- provider: (string & {}) | "linear" | "huggingface" | "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "railway" | "vercel" | "wechat";
94
+ provider: "salesforce" | "slack" | "linear" | "notion" | "linkedin" | "github" | (string & {}) | "huggingface" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "gitlab" | "tiktok" | "reddit" | "roblox" | "vk" | "zoom" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "railway" | "vercel" | "wechat";
95
95
  callbackURL?: string | undefined;
96
96
  newUserCallbackURL?: string | undefined;
97
97
  errorCallbackURL?: string | undefined;
@@ -22,4 +22,8 @@
22
22
  import * as esbuild from 'esbuild';
23
23
  export declare const UNSUPPORTED_IN_WORKERD: Set<string>;
24
24
  export declare const BASE_BUILD_OPTIONS: esbuild.BuildOptions;
25
+ export declare function createAliasPlugin(opts: {
26
+ baseDir?: string;
27
+ sdkPath?: string;
28
+ }): esbuild.Plugin;
25
29
  export declare function runBundle(): Promise<void>;
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.BASE_BUILD_OPTIONS = exports.UNSUPPORTED_IN_WORKERD = void 0;
37
+ exports.createAliasPlugin = createAliasPlugin;
37
38
  exports.runBundle = runBundle;
38
39
  /**
39
40
  * `npx zitejs bundle` — Bundle endpoint files for cloudflare-lambda deployment.
@@ -61,6 +62,8 @@ const path = __importStar(require("path"));
61
62
  const fs = __importStar(require("fs"));
62
63
  const parser_1 = require("@babel/parser");
63
64
  const node_module_1 = require("node:module");
65
+ const client_js_1 = require("../integrations/client.js");
66
+ const sdkCall_js_1 = require("../internal/sdkCall.js");
64
67
  const sourceRoots_js_1 = require("../sourceRoots.js");
65
68
  // workerd's `nodejs_compat` does not provide these. Left external they bundle
66
69
  // fine and then kill the worker at load time with `No such module`; excluded,
@@ -229,7 +232,7 @@ function getSdkImportSource(baseDir) {
229
232
  return 'zite-integrations-backend-sdk';
230
233
  }
231
234
  /**
232
- * `zitejs/db`, `zitejs/api`, `zitejs/integrations` and `zitejs/email` are
235
+ * `zitejs/db`, `zitejs/api` and `zitejs/email` are
233
236
  * tsconfig aliases onto generated files, not real package subpaths — they are
234
237
  * absent from the `exports` map. `zitejs/backend` IS a real subpath export, but
235
238
  * it lands here too and `zitejs` is not in PREBUNDLED_LIBS, so nothing would
@@ -242,6 +245,18 @@ const unresolvedAlias = (specifier, expectedPath) => {
242
245
  throw new Error(`Cannot resolve '${specifier}': expected generated file at ${expectedPath}. ` +
243
246
  `Run \`npx zitejs generate\` before bundling.`);
244
247
  };
248
+ const AUTH_SERVER_SHIM_PATH = 'zitejs-auth-server-shim';
249
+ const INTEGRATIONS_SHIM_PATH = 'zitejs-integrations-shim';
250
+ const VIRTUAL_MODULES = {
251
+ [AUTH_SERVER_SHIM_PATH]: 'export const ziteAuth = (config) => config;',
252
+ [INTEGRATIONS_SHIM_PATH]: `export const integrations = {
253
+ get(name) {
254
+ const sdkCall = globalThis.__wrapSdkCall;
255
+ if (!sdkCall) throw new Error(${JSON.stringify(sdkCall_js_1.SDK_NOT_INITIALIZED_MESSAGE)});
256
+ return sdkCall(${JSON.stringify(client_js_1.INTEGRATIONS_SDK_INTEGRATION_ID)}, ${JSON.stringify(client_js_1.INTEGRATIONS_CLASS_NAME)}, 'get', { name });
257
+ },
258
+ };`,
259
+ };
245
260
  function createAliasPlugin(opts) {
246
261
  return {
247
262
  name: 'zite-alias',
@@ -293,14 +308,18 @@ function createAliasPlugin(opts) {
293
308
  }
294
309
  return unresolvedAlias('zitejs/api', `${opts.baseDir}/.zite/api.ts`);
295
310
  });
296
- // Resolve zitejs/integrations to .zite/integrations/airtable.ts
311
+ // zitejs/integrations: the generated index (the integrations client plus
312
+ // any Airtable clients), else Airtable alone from an older generate, else
313
+ // this bundler's own client, whatever zitejs the project pins.
297
314
  build.onResolve({ filter: /^zitejs\/integrations$/ }, () => {
298
315
  if (opts.baseDir) {
299
- const intPath = path.resolve(opts.baseDir, '.zite/integrations/airtable.ts');
300
- if (fs.existsSync(intPath))
301
- return { path: intPath };
316
+ for (const file of ['index.ts', 'airtable.ts']) {
317
+ const intPath = path.resolve(opts.baseDir, '.zite/integrations', file);
318
+ if (fs.existsSync(intPath))
319
+ return { path: intPath };
320
+ }
302
321
  }
303
- return unresolvedAlias('zitejs/integrations', `${opts.baseDir}/.zite/integrations/airtable.ts`);
322
+ return { path: INTEGRATIONS_SHIM_PATH, namespace: 'zite-virtual' };
304
323
  });
305
324
  // Resolve zitejs/email to .zite/integrations/email.ts
306
325
  build.onResolve({ filter: /^zitejs\/email$/ }, () => {
@@ -314,11 +333,11 @@ function createAliasPlugin(opts) {
314
333
  // zitejs/auth/server is types + an identity wrapper — inline a shim so
315
334
  // zite.auth.ts bundles without resolving the installed package.
316
335
  build.onResolve({ filter: /^zitejs\/auth\/server$/ }, () => ({
317
- path: 'zitejs-auth-server-shim',
336
+ path: AUTH_SERVER_SHIM_PATH,
318
337
  namespace: 'zite-virtual',
319
338
  }));
320
- build.onLoad({ filter: /.*/, namespace: 'zite-virtual' }, () => ({
321
- contents: 'export const ziteAuth = (config) => config;',
339
+ build.onLoad({ filter: /.*/, namespace: 'zite-virtual' }, (args) => ({
340
+ contents: VIRTUAL_MODULES[args.path],
322
341
  loader: 'js',
323
342
  }));
324
343
  // zitejs/runtime is NOT in PREBUNDLED_LIBS — it's a thin fetch()
@@ -1,2 +1,7 @@
1
+ /**
2
+ * Whether the zitejs that `fromDir` resolves, nearest first up to the project root,
3
+ * has the integrations client: the CLI running generate can be newer than that pin.
4
+ */
5
+ export declare function projectRuntimeHasIntegrationsClient(fromDir: string, projectRoot?: string): boolean;
1
6
  export declare function runGenerate(): Promise<void>;
2
7
  export declare function runDev(): Promise<void>;
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.projectRuntimeHasIntegrationsClient = projectRuntimeHasIntegrationsClient;
3
4
  exports.runGenerate = runGenerate;
4
5
  exports.runDev = runDev;
5
6
  const fs_1 = require("fs");
@@ -8,6 +9,7 @@ const path_1 = require("path");
8
9
  const sourceRoots_js_1 = require("../sourceRoots.js");
9
10
  const index_js_1 = require("../sync/index.js");
10
11
  const lib_js_1 = require("../sync/lib.js");
12
+ const rules_js_1 = require("../integrations/rules.js");
11
13
  const debounceTimers = new Map();
12
14
  function debounce(key, fn, ms) {
13
15
  const existing = debounceTimers.get(key);
@@ -39,6 +41,48 @@ const readJsonFile = (path) => {
39
41
  function getEmailIntegrationId(appDir) {
40
42
  return (0, lib_js_1.findEmailIntegrationId)(readJsonFile((0, path_1.join)(appDir.path, "zite.config.json")), readJsonFile("zite.config.json"));
41
43
  }
44
+ // `{}` with no file; undefined when unreadable, so a failed read keeps the old file.
45
+ const readConfigIntegrations = (path) => {
46
+ if (!(0, fs_2.existsSync)(path))
47
+ return {};
48
+ const config = readJsonFile(path);
49
+ if (typeof config !== "object" || config === null)
50
+ return undefined;
51
+ const { integrations } = config;
52
+ if (integrations == null)
53
+ return {};
54
+ return typeof integrations === "object" && !Array.isArray(integrations)
55
+ ? integrations
56
+ : undefined;
57
+ };
58
+ /**
59
+ * Whether the zitejs that `fromDir` resolves, nearest first up to the project root,
60
+ * has the integrations client: the CLI running generate can be newer than that pin.
61
+ */
62
+ function projectRuntimeHasIntegrationsClient(fromDir, projectRoot = process.cwd()) {
63
+ const root = (0, path_1.resolve)(projectRoot);
64
+ for (let dir = (0, path_1.resolve)(fromDir);; dir = (0, path_1.dirname)(dir)) {
65
+ const pkg = readJsonFile((0, path_1.join)(dir, "node_modules", "zitejs", "package.json"));
66
+ if (pkg)
67
+ return pkg.exports?.["./integrations"] !== undefined;
68
+ if (dir === root || (0, path_1.dirname)(dir) === dir)
69
+ return false;
70
+ }
71
+ }
72
+ // Runs after the Airtable step, so the index re-exports its clients when they exist.
73
+ function regenerateAppIntegrationsIndex(appDir) {
74
+ if (!projectRuntimeHasIntegrationsClient(appDir.path))
75
+ return;
76
+ const root = readConfigIntegrations("zite.config.json");
77
+ const own = readConfigIntegrations((0, path_1.join)(appDir.path, "zite.config.json"));
78
+ if (!root || !own)
79
+ return;
80
+ const intDir = (0, path_1.join)(appDir.path, ".zite", "integrations");
81
+ (0, fs_2.mkdirSync)(intDir, { recursive: true });
82
+ (0, fs_2.writeFileSync)((0, path_1.join)(intDir, "index.ts"), (0, lib_js_1.generateIntegrationsIndex)((0, rules_js_1.gettableIntegrations)(root, own), {
83
+ reexportAirtable: (0, fs_2.existsSync)((0, path_1.join)(intDir, "airtable.ts")),
84
+ }));
85
+ }
42
86
  function getDeclaredEnvVarNames(appDir) {
43
87
  try {
44
88
  const configPath = (0, path_1.join)(appDir.path, "zite.config.json");
@@ -153,6 +197,7 @@ async function runGenerate() {
153
197
  regenerateAppApiTs(app);
154
198
  regenerateAppTypedWrappers(app);
155
199
  regenerateAppAirtableSdk(app);
200
+ regenerateAppIntegrationsIndex(app);
156
201
  }
157
202
  console.log("Done!");
158
203
  }
@@ -173,6 +218,7 @@ async function runDev() {
173
218
  for (const app of appDirs) {
174
219
  regenerateAppApiTs(app);
175
220
  regenerateAppTypedWrappers(app);
221
+ regenerateAppIntegrationsIndex(app);
176
222
  }
177
223
  // 3. Watch each dir's src/api/ for endpoint changes
178
224
  let watchingAny = false;
@@ -1,3 +1,5 @@
1
1
  export { Zite } from "./client/index.js";
2
2
  export type { Record, RecordListOutput, RecordListOptions, FieldCreateInput, FieldUpdateInput, TableCreateInput, TableUpdateInput, DatabaseCreateInput, DatabaseListOutput, } from "./client/index.js";
3
3
  export * from "./types/index.js";
4
+ export { CREDENTIAL_FIELDS, NON_CREDENTIAL_SERVICE_TYPES, gettableIntegrations, isCredentialServiceType, normalizeIntegrationServiceType, } from "./integrations/rules.js";
5
+ export type { ConfigIntegrations, CredentialServiceType, GettableIntegration, } from "./integrations/rules.js";
package/dist/cjs/index.js CHANGED
@@ -14,7 +14,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.Zite = void 0;
17
+ exports.normalizeIntegrationServiceType = exports.isCredentialServiceType = exports.gettableIntegrations = exports.NON_CREDENTIAL_SERVICE_TYPES = exports.CREDENTIAL_FIELDS = exports.Zite = void 0;
18
18
  var index_js_1 = require("./client/index.js");
19
19
  Object.defineProperty(exports, "Zite", { enumerable: true, get: function () { return index_js_1.Zite; } });
20
20
  __exportStar(require("./types/index.js"), exports);
21
+ var rules_js_1 = require("./integrations/rules.js");
22
+ Object.defineProperty(exports, "CREDENTIAL_FIELDS", { enumerable: true, get: function () { return rules_js_1.CREDENTIAL_FIELDS; } });
23
+ Object.defineProperty(exports, "NON_CREDENTIAL_SERVICE_TYPES", { enumerable: true, get: function () { return rules_js_1.NON_CREDENTIAL_SERVICE_TYPES; } });
24
+ Object.defineProperty(exports, "gettableIntegrations", { enumerable: true, get: function () { return rules_js_1.gettableIntegrations; } });
25
+ Object.defineProperty(exports, "isCredentialServiceType", { enumerable: true, get: function () { return rules_js_1.isCredentialServiceType; } });
26
+ Object.defineProperty(exports, "normalizeIntegrationServiceType", { enumerable: true, get: function () { return rules_js_1.normalizeIntegrationServiceType; } });
@@ -0,0 +1,25 @@
1
+ export declare const INTEGRATIONS_SDK_INTEGRATION_ID = "__connections__";
2
+ export declare const INTEGRATIONS_CLASS_NAME = "Connections";
3
+ /**
4
+ * `accessToken` is the service's primary credential (for Twilio the account SID).
5
+ * Call `get` where the value is used: a token refreshed mid-run is what the next call returns.
6
+ */
7
+ export type Connected<Extra = {}> = {
8
+ status: "connected";
9
+ accessToken: string;
10
+ } & Extra;
11
+ /** No account behind the entry, or its token could not be refreshed. `connectUrl` is where a person fixes that. */
12
+ export type NeedsConnect = {
13
+ status: "missing" | "expired";
14
+ connectUrl: string;
15
+ };
16
+ export interface IntegrationsClient<ByName extends Record<string, unknown>> {
17
+ /** The credentials of the `zite.config.json` integration entry named `name`. */
18
+ get<Name extends keyof ByName & string>(name: Name): Promise<ByName[Name]>;
19
+ }
20
+ /**
21
+ * `ByName` maps each entry name to its answer, e.g.
22
+ * `{ crm: Connected<{ instanceUrl: string }> | NeedsConnect }`; `zitejs generate`
23
+ * writes it per app into `.zite/integrations/index.ts`.
24
+ */
25
+ export declare function createIntegrationsClient<ByName extends Record<string, unknown>>(): IntegrationsClient<ByName>;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.INTEGRATIONS_CLASS_NAME = exports.INTEGRATIONS_SDK_INTEGRATION_ID = void 0;
4
+ exports.createIntegrationsClient = createIntegrationsClient;
5
+ const sdkCall_js_1 = require("../internal/sdkCall.js");
6
+ // The worker and runner answer this call under its original name; renaming the
7
+ // wire protocol would break every deployed bundle for no user-visible gain.
8
+ exports.INTEGRATIONS_SDK_INTEGRATION_ID = "__connections__";
9
+ exports.INTEGRATIONS_CLASS_NAME = "Connections";
10
+ /**
11
+ * `ByName` maps each entry name to its answer, e.g.
12
+ * `{ crm: Connected<{ instanceUrl: string }> | NeedsConnect }`; `zitejs generate`
13
+ * writes it per app into `.zite/integrations/index.ts`.
14
+ */
15
+ function createIntegrationsClient() {
16
+ return {
17
+ get(name) {
18
+ return (0, sdkCall_js_1.getSdkCall)()(exports.INTEGRATIONS_SDK_INTEGRATION_ID, exports.INTEGRATIONS_CLASS_NAME, "get", { name });
19
+ },
20
+ };
21
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const client_js_1 = require("./client.js");
5
+ const index_js_1 = require("./index.js");
6
+ const index_js_2 = require("../index.js");
7
+ (0, vitest_1.describe)("createIntegrationsClient", () => {
8
+ const client = (0, client_js_1.createIntegrationsClient)();
9
+ (0, vitest_1.it)("types each name's answer", () => {
10
+ (0, vitest_1.expectTypeOf)(client.get("crm")).resolves.toEqualTypeOf();
11
+ });
12
+ (0, vitest_1.it)("rejects a name the app cannot see", () => {
13
+ // @ts-expect-error not a visible entry
14
+ void client.get("nope");
15
+ });
16
+ // What `.zite/integrations/index.ts` emits when nothing is visible.
17
+ (0, vitest_1.it)("accepts an empty map, naming nothing", () => {
18
+ const none = (0, client_js_1.createIntegrationsClient)();
19
+ (0, vitest_1.expectTypeOf)().toEqualTypeOf();
20
+ });
21
+ (0, vitest_1.it)("narrows to the connected fields on status", async () => {
22
+ const crm = await client.get("crm");
23
+ if (crm.status === "connected") {
24
+ (0, vitest_1.expectTypeOf)(crm.instanceUrl).toEqualTypeOf();
25
+ }
26
+ else {
27
+ (0, vitest_1.expectTypeOf)(crm.connectUrl).toEqualTypeOf();
28
+ }
29
+ });
30
+ });
31
+ (0, vitest_1.describe)("the untyped zitejs/integrations client", () => {
32
+ (0, vitest_1.it)("takes any name; only accessToken is certain", async () => {
33
+ const entry = await index_js_1.integrations.get("anything");
34
+ if (entry.status === "connected") {
35
+ (0, vitest_1.expectTypeOf)(entry.accessToken).toEqualTypeOf();
36
+ (0, vitest_1.expectTypeOf)(entry.instanceUrl).toEqualTypeOf();
37
+ }
38
+ });
39
+ });
40
+ (0, vitest_1.describe)("CREDENTIAL_FIELDS", () => {
41
+ (0, vitest_1.it)("is keyed by service type, and a string narrows to one", () => {
42
+ (0, vitest_1.expectTypeOf)(index_js_2.CREDENTIAL_FIELDS.salesforce).toEqualTypeOf();
43
+ const type = "salesforce";
44
+ // @ts-expect-error a plain string is not a service type
45
+ void index_js_2.CREDENTIAL_FIELDS[type];
46
+ if ((0, index_js_2.isCredentialServiceType)(type)) {
47
+ (0, vitest_1.expectTypeOf)(index_js_2.CREDENTIAL_FIELDS[type]).toEqualTypeOf();
48
+ }
49
+ });
50
+ });
@@ -0,0 +1,3 @@
1
+ import { type Connected, type NeedsConnect } from "./client.js";
2
+ export type { Connected, NeedsConnect } from "./client.js";
3
+ export declare const integrations: import("./client.js").IntegrationsClient<Record<string, NeedsConnect | Connected<Partial<Record<string, string>>>>>;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.integrations = void 0;
4
+ const client_js_1 = require("./client.js");
5
+ // What code with no generated `.zite/integrations/index.ts` gets, e.g. a repo-root script.
6
+ exports.integrations = (0, client_js_1.createIntegrationsClient)();
@@ -0,0 +1,67 @@
1
+ declare const FIELDS_BY_TYPE: {
2
+ googleCalendar: readonly string[];
3
+ googleDrive: readonly string[];
4
+ gmail: readonly string[];
5
+ googleDocs: readonly string[];
6
+ hubspot: readonly string[];
7
+ salesforce: readonly string[];
8
+ twilio: readonly string[];
9
+ slack: readonly string[];
10
+ linear: readonly string[];
11
+ openai: readonly string[];
12
+ googlesheets: readonly string[];
13
+ microsoftTeams: readonly string[];
14
+ onedrive: readonly string[];
15
+ outlook: readonly string[];
16
+ intercom: readonly string[];
17
+ mailchimp: readonly string[];
18
+ anthropic: readonly string[];
19
+ gemini: readonly string[];
20
+ stripe: readonly string[];
21
+ trello: readonly string[];
22
+ notion: readonly string[];
23
+ facebookPages: readonly string[];
24
+ monday: readonly string[];
25
+ resend: readonly string[];
26
+ clickhouse: readonly string[];
27
+ amplitude: readonly string[];
28
+ elevenlabs: readonly string[];
29
+ brevo: readonly string[];
30
+ calendly: readonly string[];
31
+ asana: readonly string[];
32
+ xero: readonly string[];
33
+ googleForms: readonly string[];
34
+ linkedin: readonly string[];
35
+ github: readonly string[];
36
+ quickbooks: readonly string[];
37
+ firecrawl: readonly string[];
38
+ jira: readonly string[];
39
+ typeform: readonly string[];
40
+ apollo: readonly string[];
41
+ attio: readonly string[];
42
+ };
43
+ /** A service type `integrations.get` serves: one used through its npm package with a token. */
44
+ export type CredentialServiceType = keyof typeof FIELDS_BY_TYPE;
45
+ /** Per service type: `accessToken`, then its extra labels sorted (Salesforce `instanceUrl`). */
46
+ export declare const CREDENTIAL_FIELDS: Readonly<Record<CredentialServiceType, readonly string[]>>;
47
+ /**
48
+ * Types the runtime never serves: those with a generated client (Airtable, email,
49
+ * the project database, Fillout) and those whose key is a frontend value (Maps, Analytics).
50
+ */
51
+ export declare const NON_CREDENTIAL_SERVICE_TYPES: readonly string[];
52
+ export declare const normalizeIntegrationServiceType: (type: string) => string;
53
+ export declare const isCredentialServiceType: (type: string) => type is CredentialServiceType;
54
+ /** One entry `integrations.get` can name from a source dir. */
55
+ export type GettableIntegration = {
56
+ name: string;
57
+ serviceType: CredentialServiceType;
58
+ };
59
+ export type ConfigIntegrations = Readonly<Record<string, {
60
+ type?: unknown;
61
+ } | undefined>>;
62
+ /**
63
+ * The entries a source dir can name, by name: its own, then the workspace's under
64
+ * keys it has not taken. An entry whose type the runtime would not serve is dropped.
65
+ */
66
+ export declare const gettableIntegrations: (rootIntegrations: ConfigIntegrations | undefined, appIntegrations?: ConfigIntegrations) => GettableIntegration[];
67
+ export {};
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ // Which `zite.config.json` entries `integrations.get` can name, and the fields
3
+ // each answers with. No imports, so the platform applies these same rules.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.gettableIntegrations = exports.isCredentialServiceType = exports.normalizeIntegrationServiceType = exports.NON_CREDENTIAL_SERVICE_TYPES = exports.CREDENTIAL_FIELDS = void 0;
6
+ const extras = (...labels) => [
7
+ "accessToken",
8
+ ...[...labels].sort(),
9
+ ];
10
+ const FIELDS_BY_TYPE = {
11
+ googleCalendar: extras(),
12
+ googleDrive: extras(),
13
+ gmail: extras(),
14
+ googleDocs: extras(),
15
+ hubspot: extras(),
16
+ salesforce: extras("instanceUrl"),
17
+ twilio: extras("authToken"),
18
+ slack: extras(),
19
+ linear: extras(),
20
+ openai: extras(),
21
+ googlesheets: extras(),
22
+ microsoftTeams: extras(),
23
+ onedrive: extras(),
24
+ outlook: extras(),
25
+ intercom: extras(),
26
+ mailchimp: extras("server"),
27
+ anthropic: extras(),
28
+ gemini: extras(),
29
+ stripe: extras(),
30
+ trello: extras("clientApiKey"),
31
+ notion: extras(),
32
+ facebookPages: extras(),
33
+ monday: extras(),
34
+ resend: extras(),
35
+ clickhouse: extras("url", "username"),
36
+ amplitude: extras("apiKey"),
37
+ elevenlabs: extras(),
38
+ brevo: extras(),
39
+ calendly: extras(),
40
+ asana: extras(),
41
+ xero: extras("tenantId"),
42
+ googleForms: extras(),
43
+ linkedin: extras("personUrn"),
44
+ github: extras(),
45
+ quickbooks: extras("realmId", "apiBaseUrl"),
46
+ firecrawl: extras(),
47
+ jira: extras("cloudId", "siteUrl"),
48
+ typeform: extras(),
49
+ apollo: extras(),
50
+ attio: extras(),
51
+ };
52
+ /** Per service type: `accessToken`, then its extra labels sorted (Salesforce `instanceUrl`). */
53
+ exports.CREDENTIAL_FIELDS = FIELDS_BY_TYPE;
54
+ /**
55
+ * Types the runtime never serves: those with a generated client (Airtable, email,
56
+ * the project database, Fillout) and those whose key is a frontend value (Maps, Analytics).
57
+ */
58
+ exports.NON_CREDENTIAL_SERVICE_TYPES = [
59
+ "airtable",
60
+ "databases",
61
+ "email",
62
+ "fillout",
63
+ "googleAnalytics",
64
+ "googlemaps",
65
+ ];
66
+ /** Spellings older configs, or an agent writing the entry's slug, put in `type`. */
67
+ const LEGACY_SERVICE_TYPES = {
68
+ googlecalendar: "googleCalendar",
69
+ "google-drive": "googleDrive",
70
+ "google-docs": "googleDocs",
71
+ "google-calendar": "googleCalendar",
72
+ "google-sheets": "googlesheets",
73
+ "google-analytics": "googleAnalytics",
74
+ "google-maps": "googlemaps",
75
+ "microsoft-teams": "microsoftTeams",
76
+ "one-drive": "onedrive",
77
+ };
78
+ // Own keys only: a name like `constructor` must not match Object.prototype.
79
+ const hasOwn = (record, key) => Object.prototype.hasOwnProperty.call(record, key);
80
+ const normalizeIntegrationServiceType = (type) => hasOwn(LEGACY_SERVICE_TYPES, type) ? LEGACY_SERVICE_TYPES[type] : type;
81
+ exports.normalizeIntegrationServiceType = normalizeIntegrationServiceType;
82
+ const isCredentialServiceType = (type) => hasOwn(FIELDS_BY_TYPE, type);
83
+ exports.isCredentialServiceType = isCredentialServiceType;
84
+ /**
85
+ * The entries a source dir can name, by name: its own, then the workspace's under
86
+ * keys it has not taken. An entry whose type the runtime would not serve is dropped.
87
+ */
88
+ const gettableIntegrations = (rootIntegrations, appIntegrations) => {
89
+ const own = appIntegrations ?? {};
90
+ const workspace = rootIntegrations ?? {};
91
+ const visible = [];
92
+ for (const [name, entry] of [
93
+ ...Object.entries(own),
94
+ ...Object.entries(workspace).filter(([name]) => !hasOwn(own, name)),
95
+ ]) {
96
+ if (typeof entry?.type !== "string")
97
+ continue;
98
+ const serviceType = (0, exports.normalizeIntegrationServiceType)(entry.type);
99
+ if ((0, exports.isCredentialServiceType)(serviceType))
100
+ visible.push({ name, serviceType });
101
+ }
102
+ return visible.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
103
+ };
104
+ exports.gettableIntegrations = gettableIntegrations;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const index_js_1 = require("../index.js");
5
+ (0, vitest_1.describe)("CREDENTIAL_FIELDS", () => {
6
+ (0, vitest_1.it)("answers accessToken, then the service's extras sorted", () => {
7
+ (0, vitest_1.expect)(index_js_1.CREDENTIAL_FIELDS.slack).toEqual(["accessToken"]);
8
+ (0, vitest_1.expect)(index_js_1.CREDENTIAL_FIELDS.salesforce).toEqual(["accessToken", "instanceUrl"]);
9
+ (0, vitest_1.expect)(index_js_1.CREDENTIAL_FIELDS.clickhouse).toEqual([
10
+ "accessToken",
11
+ "url",
12
+ "username",
13
+ ]);
14
+ (0, vitest_1.expect)(index_js_1.CREDENTIAL_FIELDS.quickbooks).toEqual([
15
+ "accessToken",
16
+ "apiBaseUrl",
17
+ "realmId",
18
+ ]);
19
+ (0, vitest_1.expect)(index_js_1.CREDENTIAL_FIELDS.jira).toEqual(["accessToken", "cloudId", "siteUrl"]);
20
+ });
21
+ (0, vitest_1.it)("has no type the runtime never serves", () => {
22
+ for (const type of index_js_1.NON_CREDENTIAL_SERVICE_TYPES) {
23
+ (0, vitest_1.expect)((0, index_js_1.isCredentialServiceType)(type)).toBe(false);
24
+ }
25
+ });
26
+ (0, vitest_1.it)("does not treat Object.prototype names as service types", () => {
27
+ (0, vitest_1.expect)((0, index_js_1.isCredentialServiceType)("toString")).toBe(false);
28
+ (0, vitest_1.expect)((0, index_js_1.normalizeIntegrationServiceType)("constructor")).toBe("constructor");
29
+ });
30
+ });
31
+ (0, vitest_1.describe)("normalizeIntegrationServiceType", () => {
32
+ vitest_1.it.each([
33
+ ["googlecalendar", "googleCalendar"],
34
+ ["google-drive", "googleDrive"],
35
+ ["google-sheets", "googlesheets"],
36
+ ["microsoft-teams", "microsoftTeams"],
37
+ ["one-drive", "onedrive"],
38
+ ])("maps %s to %s", (legacy, canonical) => {
39
+ (0, vitest_1.expect)((0, index_js_1.normalizeIntegrationServiceType)(legacy)).toBe(canonical);
40
+ (0, vitest_1.expect)((0, index_js_1.isCredentialServiceType)(canonical)).toBe(true);
41
+ });
42
+ (0, vitest_1.it)("leaves a canonical type alone", () => {
43
+ (0, vitest_1.expect)((0, index_js_1.normalizeIntegrationServiceType)("slack")).toBe("slack");
44
+ });
45
+ });
46
+ (0, vitest_1.describe)("gettableIntegrations", () => {
47
+ (0, vitest_1.it)("lists the app's entries, then the workspace's under untaken keys, by name", () => {
48
+ (0, vitest_1.expect)((0, index_js_1.gettableIntegrations)({ crm: { type: "salesforce" }, team: { type: "slack" } }, { billing: { type: "stripe" }, team: { type: "microsoftTeams" } })).toEqual([
49
+ { name: "billing", serviceType: "stripe" },
50
+ { name: "crm", serviceType: "salesforce" },
51
+ { name: "team", serviceType: "microsoftTeams" },
52
+ ]);
53
+ });
54
+ (0, vitest_1.it)("lets an app entry of a generated-client type shadow a workspace credential entry", () => {
55
+ (0, vitest_1.expect)((0, index_js_1.gettableIntegrations)({ mail: { type: "gmail" } }, { mail: { type: "email" } })).toEqual([]);
56
+ });
57
+ (0, vitest_1.it)("drops types the runtime never serves and entries without a type", () => {
58
+ (0, vitest_1.expect)((0, index_js_1.gettableIntegrations)({
59
+ base: { type: "airtable" },
60
+ mail: { type: "email" },
61
+ db: { type: "databases" },
62
+ form: { type: "fillout" },
63
+ map: { type: "google-maps" },
64
+ ga: { type: "googleAnalytics" },
65
+ broken: {},
66
+ numeric: { type: 7 },
67
+ gone: undefined,
68
+ })).toEqual([]);
69
+ });
70
+ (0, vitest_1.it)("normalizes legacy type spellings", () => {
71
+ (0, vitest_1.expect)((0, index_js_1.gettableIntegrations)({ cal: { type: "google-calendar" } })).toEqual([
72
+ { name: "cal", serviceType: "googleCalendar" },
73
+ ]);
74
+ });
75
+ (0, vitest_1.it)("drops a type it does not know, as the runtime does", () => {
76
+ (0, vitest_1.expect)((0, index_js_1.gettableIntegrations)({ next: { type: "someNewService" } })).toEqual([]);
77
+ });
78
+ (0, vitest_1.it)("shadows by own keys only", () => {
79
+ (0, vitest_1.expect)((0, index_js_1.gettableIntegrations)({ constructor: { type: "slack" } }, {})).toEqual([
80
+ { name: "constructor", serviceType: "slack" },
81
+ ]);
82
+ });
83
+ (0, vitest_1.it)("works with no configs", () => {
84
+ (0, vitest_1.expect)((0, index_js_1.gettableIntegrations)(undefined)).toEqual([]);
85
+ });
86
+ });
@@ -1,2 +1,3 @@
1
1
  export type SdkCall = (integrationId: string, className: string, methodName: string, params?: unknown) => Promise<unknown>;
2
+ export declare const SDK_NOT_INITIALIZED_MESSAGE = "Zite SDK runtime not initialized. Endpoints must run inside the Zite worker.";
2
3
  export declare function getSdkCall(): SdkCall;
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SDK_NOT_INITIALIZED_MESSAGE = void 0;
3
4
  exports.getSdkCall = getSdkCall;
5
+ exports.SDK_NOT_INITIALIZED_MESSAGE = 'Zite SDK runtime not initialized. Endpoints must run inside the Zite worker.';
4
6
  function getSdkCall() {
5
7
  const fn = globalThis.__wrapSdkCall;
6
8
  if (!fn) {
7
- throw new Error('Zite SDK runtime not initialized. Endpoints must run inside the Zite worker.');
9
+ throw new Error(exports.SDK_NOT_INITIALIZED_MESSAGE);
8
10
  }
9
11
  return fn;
10
12
  }
@@ -332,5 +332,6 @@ export interface EmailClient {
332
332
  * app's connected email integration key.
333
333
  */
334
334
  export declare function createEmailClient(integrationId: string): EmailClient;
335
+ export { createIntegrationsClient, type Connected, type IntegrationsClient, type NeedsConnect, } from "../integrations/client.js";
335
336
  export { createCaller } from "../caller/index.js";
336
337
  export type { EndpointConfig } from "../caller/index.js";