@tailor-platform/sdk 1.29.0 → 1.31.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.
Files changed (47) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/README.md +3 -1
  3. package/dist/{application-Dl1d7w-b.mjs → application-B2-PymMz.mjs} +2 -2
  4. package/dist/{application-Clwpv84E.mjs → application-CASjzt3W.mjs} +341 -107
  5. package/dist/application-CASjzt3W.mjs.map +1 -0
  6. package/dist/cli/index.mjs +127 -96
  7. package/dist/cli/index.mjs.map +1 -1
  8. package/dist/cli/lib.d.mts +210 -45
  9. package/dist/cli/lib.mjs +29 -29
  10. package/dist/cli/lib.mjs.map +1 -1
  11. package/dist/client-B0wrLUVK.mjs +6 -0
  12. package/dist/{client-CZmQBXAY.mjs → client-DfdgRZlQ.mjs} +25 -13
  13. package/dist/{client-CZmQBXAY.mjs.map → client-DfdgRZlQ.mjs.map} +1 -1
  14. package/dist/configure/index.d.mts +4 -4
  15. package/dist/configure/index.mjs +1 -1
  16. package/dist/{crash-report-CYrETw1c.mjs → crash-report-BMEhRxeg.mjs} +1 -1
  17. package/dist/{crash-report-DizNMVnm.mjs → crash-report-wNxS0IUJ.mjs} +2 -2
  18. package/dist/{crash-report-DizNMVnm.mjs.map → crash-report-wNxS0IUJ.mjs.map} +1 -1
  19. package/dist/{env-BuMbIknz.d.mts → env-BgdHfWDn.d.mts} +2 -2
  20. package/dist/{index-D1AM_02Y.d.mts → index-CdDzh-T2.d.mts} +2 -2
  21. package/dist/{index-CyapgSFI.d.mts → index-CxgBnxKM.d.mts} +2 -2
  22. package/dist/{index-B0Lrzywd.d.mts → index-D4Y81vh1.d.mts} +2 -2
  23. package/dist/{index-CbnLNm14.d.mts → index-FZMBoUWm.d.mts} +2 -2
  24. package/dist/{index-cD9sQLTh.d.mts → index-RXv15__b.d.mts} +4 -4
  25. package/dist/plugin/builtin/enum-constants/index.d.mts +1 -1
  26. package/dist/plugin/builtin/file-utils/index.d.mts +1 -1
  27. package/dist/plugin/builtin/kysely-type/index.d.mts +1 -1
  28. package/dist/plugin/builtin/seed/index.d.mts +1 -1
  29. package/dist/plugin/index.d.mts +2 -2
  30. package/dist/{plugin-D3a0-qe0.d.mts → plugin-DyVYXZWz.d.mts} +8 -8
  31. package/dist/{query-B1-hq2Hm.mjs → runtime-Ofe7nHEG.mjs} +667 -143
  32. package/dist/runtime-Ofe7nHEG.mjs.map +1 -0
  33. package/dist/{schema-BePzTFBV.mjs → schema-CNWt2FKQ.mjs} +3 -14
  34. package/dist/schema-CNWt2FKQ.mjs.map +1 -0
  35. package/dist/utils/test/index.d.mts +2 -2
  36. package/dist/{workflow.generated-BsgIlrH-.d.mts → workflow.generated-DMQ-cjyT.d.mts} +2 -2
  37. package/docs/cli/function.md +1 -1
  38. package/docs/cli/organization.md +426 -0
  39. package/docs/cli-reference.md +20 -2
  40. package/docs/quickstart.md +12 -0
  41. package/docs/services/resolver.md +59 -0
  42. package/docs/services/tailordb.md +78 -6
  43. package/package.json +15 -12
  44. package/dist/application-Clwpv84E.mjs.map +0 -1
  45. package/dist/client-CW4Oh3iz.mjs +0 -6
  46. package/dist/query-B1-hq2Hm.mjs.map +0 -1
  47. package/dist/schema-BePzTFBV.mjs.map +0 -1
@@ -1,6 +1,7 @@
1
1
  import { n as isSdkBranded } from "./brand-GZnI4eYb.mjs";
2
2
  import { n as logger, r as styles } from "./logger-CqezTedh.mjs";
3
- import { c as initOAuth2Client } from "./client-CZmQBXAY.mjs";
3
+ import { l as initOAuth2Client } from "./client-DfdgRZlQ.mjs";
4
+ import { t as readPackageJson } from "./package-json-D3x2nBPB.mjs";
4
5
  import { n as seedPlugin, r as isPluginGeneratedType, t as SeedGeneratorID } from "./seed-CWkIDWMb.mjs";
5
6
  import { n as enumConstantsPlugin, t as EnumConstantsGeneratorID } from "./enum-constants-D1nfn0qD.mjs";
6
7
  import { n as fileUtilsPlugin, t as FileUtilsGeneratorID } from "./file-utils-Bctuzn3x.mjs";
@@ -18,6 +19,7 @@ import * as os from "node:os";
18
19
  import { parseTOML, parseYAML, stringifyYAML } from "confbox";
19
20
  import { findUpSync } from "find-up-simple";
20
21
  import ml from "multiline-ts";
22
+ import { lt } from "semver";
21
23
  import { xdgConfig } from "xdg-basedir";
22
24
  import * as rolldown from "rolldown";
23
25
  import * as fs from "node:fs/promises";
@@ -25,18 +27,112 @@ import { parseSync } from "oxc-parser";
25
27
  import * as inflection from "inflection";
26
28
  import * as globals from "globals";
27
29
 
30
+ //#region src/cli/shared/token-store.ts
31
+ const SERVICE_NAME = "tailor-platform-cli";
32
+ let entryClass;
33
+ async function getEntryClass() {
34
+ if (entryClass !== void 0) return entryClass;
35
+ try {
36
+ const mod = await import("@napi-rs/keyring");
37
+ const probe = new mod.Entry(SERVICE_NAME, "__probe__");
38
+ probe.setPassword("probe");
39
+ probe.deletePassword();
40
+ entryClass = mod.Entry;
41
+ } catch {
42
+ logger.warn("System keyring is not available. Tokens will be stored in the config file. Set TAILOR_PLATFORM_TOKEN environment variable for CI environments.");
43
+ entryClass = false;
44
+ }
45
+ return entryClass;
46
+ }
47
+ /**
48
+ * Check whether the OS keyring is available and functional.
49
+ * @returns true if keyring is available
50
+ */
51
+ async function isKeyringAvailable() {
52
+ return await getEntryClass() !== false;
53
+ }
54
+ /**
55
+ * Load tokens from the OS keyring for a given account.
56
+ * @param account - User identifier (e.g. email or client ID)
57
+ * @returns Token data or undefined if not found or keyring unavailable
58
+ */
59
+ async function loadKeyringTokens(account) {
60
+ const Entry = await getEntryClass();
61
+ if (!Entry) return void 0;
62
+ try {
63
+ const raw = new Entry(SERVICE_NAME, account).getPassword();
64
+ if (raw === null) return void 0;
65
+ return JSON.parse(raw);
66
+ } catch {
67
+ return;
68
+ }
69
+ }
70
+ /**
71
+ * Save tokens to the OS keyring for a given account.
72
+ * @param account - User identifier (e.g. email or client ID)
73
+ * @param tokens - Token data to store
74
+ */
75
+ async function saveKeyringTokens(account, tokens) {
76
+ const Entry = await getEntryClass();
77
+ if (!Entry) return;
78
+ new Entry(SERVICE_NAME, account).setPassword(JSON.stringify(tokens));
79
+ }
80
+ /**
81
+ * Delete tokens from the OS keyring for a given account.
82
+ * @param account - User identifier (e.g. email or client ID)
83
+ */
84
+ async function deleteKeyringTokens(account) {
85
+ const Entry = await getEntryClass();
86
+ if (!Entry) return;
87
+ try {
88
+ new Entry(SERVICE_NAME, account).deletePassword();
89
+ } catch {}
90
+ }
91
+
92
+ //#endregion
28
93
  //#region src/cli/shared/context.ts
29
- const pfConfigSchema = z.object({
94
+ const pfProfileSchema = z.object({
95
+ user: z.string(),
96
+ workspace_id: z.string()
97
+ });
98
+ const pfUserSchemaV1 = z.object({
99
+ access_token: z.string(),
100
+ refresh_token: z.string().optional(),
101
+ token_expires_at: z.string()
102
+ });
103
+ const pfUserKeyringSchema = z.object({
104
+ storage: z.literal("keyring"),
105
+ token_expires_at: z.string()
106
+ });
107
+ const pfUserFileSchema = z.object({
108
+ storage: z.literal("file"),
109
+ token_expires_at: z.string(),
110
+ access_token: z.string(),
111
+ refresh_token: z.string().optional()
112
+ });
113
+ const pfUserSchemaV2 = z.discriminatedUnion("storage", [pfUserKeyringSchema, pfUserFileSchema]);
114
+ const pfConfigSchemaV1 = z.object({
30
115
  version: z.literal(1),
31
- users: z.partialRecord(z.string(), z.object({
32
- access_token: z.string(),
33
- refresh_token: z.string().optional(),
34
- token_expires_at: z.string()
35
- })),
36
- profiles: z.partialRecord(z.string(), z.object({
37
- user: z.string(),
38
- workspace_id: z.string()
39
- })),
116
+ users: z.partialRecord(z.string(), pfUserSchemaV1),
117
+ profiles: z.partialRecord(z.string(), pfProfileSchema),
118
+ current_user: z.string().nullable()
119
+ });
120
+ const LATEST_CONFIG_VERSION = 2;
121
+ const V2_MIN_SDK_VERSION = "1.29.0";
122
+ const semverSchema = z.templateLiteral([
123
+ z.number().int(),
124
+ ".",
125
+ z.number().int(),
126
+ ".",
127
+ z.number().int()
128
+ ]);
129
+ const pfConfigSchemaV2 = z.object({
130
+ version: z.literal(LATEST_CONFIG_VERSION),
131
+ min_sdk_version: semverSchema,
132
+ latest_version: z.number().int().optional(),
133
+ latest_min_sdk_version: semverSchema.optional(),
134
+ users: z.partialRecord(z.string(), pfUserSchemaV2),
135
+ profiles: z.partialRecord(z.string(), pfProfileSchema),
40
136
  current_user: z.string().nullable()
41
137
  });
42
138
  function platformConfigPath() {
@@ -44,34 +140,104 @@ function platformConfigPath() {
44
140
  return path.join(xdgConfig, "tailor-platform", "config.yaml");
45
141
  }
46
142
  /**
47
- * Read Tailor Platform CLI configuration, migrating from tailorctl if necessary.
143
+ * Migrate a v1 config to v2.
144
+ * Tokens are kept in the config file (storage: "file") during migration.
145
+ * They will be moved to the OS keyring on next login or token refresh.
146
+ * @param v1Config - v1 configuration to migrate
147
+ * @returns Migrated v2 configuration
148
+ */
149
+ function migrateV1ToV2(v1Config) {
150
+ const users = {};
151
+ for (const [name, v1User] of Object.entries(v1Config.users)) {
152
+ if (!v1User) continue;
153
+ users[name] = {
154
+ access_token: v1User.access_token,
155
+ refresh_token: v1User.refresh_token,
156
+ token_expires_at: v1User.token_expires_at,
157
+ storage: "file"
158
+ };
159
+ }
160
+ return {
161
+ version: LATEST_CONFIG_VERSION,
162
+ min_sdk_version: V2_MIN_SDK_VERSION,
163
+ users,
164
+ profiles: v1Config.profiles,
165
+ current_user: v1Config.current_user
166
+ };
167
+ }
168
+ /**
169
+ * Read Tailor Platform CLI configuration, migrating from tailorctl or v1 if necessary.
48
170
  * @returns Parsed platform configuration
49
171
  */
50
- function readPlatformConfig() {
172
+ async function readPlatformConfig() {
51
173
  const configPath = platformConfigPath();
52
174
  if (!fs$1.existsSync(configPath)) {
53
175
  logger.warn(`Config not found at ${configPath}, migrating from tailorctl config...`);
54
176
  const tcConfig = readTailorctlConfig();
55
- const pfConfig = tcConfig ? fromTailorctlConfig(tcConfig) : {
177
+ const v1Config = tcConfig ? fromTailorctlConfig(tcConfig) : {
56
178
  version: 1,
57
179
  users: {},
58
180
  profiles: {},
59
181
  current_user: null
60
182
  };
61
- writePlatformConfig(pfConfig);
62
- return pfConfig;
183
+ writePlatformConfig(v1Config);
184
+ return migrateV1ToV2(v1Config);
63
185
  }
64
186
  const rawConfig = parseYAML(fs$1.readFileSync(configPath, "utf-8"));
65
- return pfConfigSchema.parse(rawConfig);
187
+ const version = rawConfig != null && typeof rawConfig === "object" && "version" in rawConfig ? rawConfig.version : void 0;
188
+ if (typeof version === "number" && version > LATEST_CONFIG_VERSION) {
189
+ const minSdk = "min_sdk_version" in rawConfig ? String(rawConfig.min_sdk_version) : void 0;
190
+ const updateHint = minSdk ? `Please update your SDK to >= ${minSdk}: pnpm update @tailor-platform/sdk` : "Please update your SDK: pnpm update @tailor-platform/sdk";
191
+ throw new Error(ml`
192
+ Config file uses version ${String(version)}, but this SDK only supports up to version ${String(LATEST_CONFIG_VERSION)}.
193
+ ${updateHint}
194
+ `);
195
+ }
196
+ const v2Result = pfConfigSchemaV2.safeParse(rawConfig);
197
+ if (v2Result.success) {
198
+ if (v2Result.data.latest_min_sdk_version) {
199
+ if (lt((await readPackageJson()).version ?? "0.0.0", v2Result.data.latest_min_sdk_version)) logger.warn(ml`
200
+ A newer config version (${String(v2Result.data.latest_version)}) is available.
201
+ Please update your SDK to >= ${v2Result.data.latest_min_sdk_version}: pnpm update @tailor-platform/sdk
202
+ `);
203
+ }
204
+ return v2Result.data;
205
+ }
206
+ const v1Result = pfConfigSchemaV1.safeParse(rawConfig);
207
+ if (v1Result.success) return migrateV1ToV2(v1Result.data);
208
+ throw new Error(ml`
209
+ Failed to parse config file at ${configPath}.
210
+ The file may be corrupted or created by an incompatible SDK version.
211
+ `);
212
+ }
213
+ function toV1ForDisk(config) {
214
+ const users = {};
215
+ for (const [name, entry] of Object.entries(config.users)) {
216
+ if (!entry || entry.storage === "keyring") continue;
217
+ users[name] = {
218
+ access_token: entry.access_token,
219
+ refresh_token: entry.refresh_token,
220
+ token_expires_at: entry.token_expires_at
221
+ };
222
+ }
223
+ return {
224
+ version: 1,
225
+ users,
226
+ profiles: config.profiles,
227
+ current_user: config.current_user
228
+ };
66
229
  }
67
230
  /**
68
231
  * Write Tailor Platform CLI configuration to disk.
232
+ * By default, V2 configs are converted to V1 for backward compatibility.
233
+ * Set TAILOR_USE_KEYRING to write V2 format (required for keyring storage).
69
234
  * @param config - Platform configuration to write
70
235
  */
71
236
  function writePlatformConfig(config) {
72
237
  const configPath = platformConfigPath();
73
238
  fs$1.mkdirSync(path.dirname(configPath), { recursive: true });
74
- fs$1.writeFileSync(configPath, stringifyYAML(config));
239
+ const diskConfig = config.version === 2 && !process.env.TAILOR_USE_KEYRING ? toV1ForDisk(config) : config;
240
+ fs$1.writeFileSync(configPath, stringifyYAML(diskConfig));
75
241
  }
76
242
  const tcContextConfigSchema = z.object({
77
243
  username: z.string().optional(),
@@ -127,12 +293,12 @@ function validateUUID(value, source) {
127
293
  * @param opts - Workspace and profile options
128
294
  * @returns Resolved workspace ID
129
295
  */
130
- function loadWorkspaceId(opts) {
296
+ async function loadWorkspaceId(opts) {
131
297
  if (opts?.workspaceId) return validateUUID(opts.workspaceId, "--workspace-id option");
132
298
  if (process.env.TAILOR_PLATFORM_WORKSPACE_ID) return validateUUID(process.env.TAILOR_PLATFORM_WORKSPACE_ID, "TAILOR_PLATFORM_WORKSPACE_ID environment variable");
133
299
  const profile = opts?.profile || process.env.TAILOR_PLATFORM_PROFILE;
134
300
  if (profile) {
135
- const wsId = readPlatformConfig().profiles[profile]?.workspace_id;
301
+ const wsId = (await readPlatformConfig()).profiles[profile]?.workspace_id;
136
302
  if (!wsId) throw new Error(`Profile "${profile}" not found`);
137
303
  return validateUUID(wsId, `profile "${profile}"`);
138
304
  }
@@ -154,7 +320,7 @@ async function loadAccessToken(opts) {
154
320
  logger.warn("TAILOR_TOKEN is deprecated. Please use TAILOR_PLATFORM_TOKEN instead.");
155
321
  return process.env.TAILOR_TOKEN;
156
322
  }
157
- const pfConfig = readPlatformConfig();
323
+ const pfConfig = await readPlatformConfig();
158
324
  let user;
159
325
  const profile = opts?.useProfile ? opts.profile || process.env.TAILOR_PLATFORM_PROFILE : void 0;
160
326
  if (profile) {
@@ -172,19 +338,71 @@ async function loadAccessToken(opts) {
172
338
  return await fetchLatestToken(pfConfig, user);
173
339
  }
174
340
  /**
341
+ * Resolve the actual token values for a user, reading from keyring or config as appropriate.
342
+ * @param userEntry - User entry from the config
343
+ * @param user - User identifier
344
+ * @returns Access token and optional refresh token
345
+ */
346
+ async function resolveTokens(userEntry, user) {
347
+ if (userEntry.storage === "keyring") {
348
+ const tokens = await loadKeyringTokens(user);
349
+ if (!tokens) throw new Error(ml`
350
+ Credentials not found in OS keyring for "${user}".
351
+ Please run 'tailor-sdk login' and try again.
352
+ `);
353
+ return tokens;
354
+ }
355
+ return {
356
+ accessToken: userEntry.access_token,
357
+ refreshToken: userEntry.refresh_token
358
+ };
359
+ }
360
+ /**
361
+ * Save tokens for a user, writing to keyring or config as appropriate.
362
+ * @param config - Platform config
363
+ * @param user - User identifier
364
+ * @param tokens - Token data to save
365
+ * @param tokens.accessToken
366
+ * @param tokens.refreshToken
367
+ * @param expiresAt - Token expiration date
368
+ */
369
+ async function saveUserTokens(config, user, tokens, expiresAt) {
370
+ if (process.env.TAILOR_USE_KEYRING && await isKeyringAvailable()) {
371
+ await saveKeyringTokens(user, tokens);
372
+ config.users[user] = {
373
+ token_expires_at: expiresAt,
374
+ storage: "keyring"
375
+ };
376
+ } else config.users[user] = {
377
+ access_token: tokens.accessToken,
378
+ refresh_token: tokens.refreshToken,
379
+ token_expires_at: expiresAt,
380
+ storage: "file"
381
+ };
382
+ }
383
+ /**
384
+ * Delete tokens for a user from keyring if applicable.
385
+ * @param config - Platform config
386
+ * @param user - User identifier
387
+ */
388
+ async function deleteUserTokens(config, user) {
389
+ if (config.users[user]?.storage === "keyring") await deleteKeyringTokens(user);
390
+ }
391
+ /**
175
392
  * Fetch the latest access token, refreshing if necessary.
176
393
  * @param config - Platform config
177
394
  * @param user - User name
178
395
  * @returns Latest access token
179
396
  */
180
397
  async function fetchLatestToken(config, user) {
181
- const tokens = config.users[user];
182
- if (!tokens) throw new Error(ml`
398
+ const userEntry = config.users[user];
399
+ if (!userEntry) throw new Error(ml`
183
400
  User "${user}" not found.
184
401
  Please verify your user name and login using 'tailor-sdk login' command.
185
402
  `);
186
- if (new Date(tokens.token_expires_at) > /* @__PURE__ */ new Date()) return tokens.access_token;
187
- if (!tokens.refresh_token) throw new Error(ml`
403
+ const tokens = await resolveTokens(userEntry, user);
404
+ if (new Date(userEntry.token_expires_at) > /* @__PURE__ */ new Date()) return tokens.accessToken;
405
+ if (!tokens.refreshToken) throw new Error(ml`
188
406
  Token expired.
189
407
  Please run 'tailor-sdk login' and try again.
190
408
  `);
@@ -192,9 +410,9 @@ async function fetchLatestToken(config, user) {
192
410
  let resp;
193
411
  try {
194
412
  resp = await client.refreshToken({
195
- accessToken: tokens.access_token,
196
- refreshToken: tokens.refresh_token,
197
- expiresAt: Date.parse(tokens.token_expires_at)
413
+ accessToken: tokens.accessToken,
414
+ refreshToken: tokens.refreshToken,
415
+ expiresAt: Date.parse(userEntry.token_expires_at)
198
416
  });
199
417
  } catch {
200
418
  throw new Error(ml`
@@ -202,11 +420,11 @@ async function fetchLatestToken(config, user) {
202
420
  Please run 'tailor-sdk login' and try again.
203
421
  `);
204
422
  }
205
- config.users[user] = {
206
- access_token: resp.accessToken,
207
- refresh_token: resp.refreshToken,
208
- token_expires_at: new Date(resp.expiresAt).toISOString()
209
- };
423
+ const newExpiresAt = new Date(resp.expiresAt).toISOString();
424
+ await saveUserTokens(config, user, {
425
+ accessToken: resp.accessToken,
426
+ refreshToken: resp.refreshToken ?? void 0
427
+ }, newExpiresAt);
210
428
  writePlatformConfig(config);
211
429
  return resp.accessToken;
212
430
  }
@@ -324,32 +542,31 @@ function computeBundlerContextHash(params) {
324
542
  * When caching is active, attempts to restore from cache first,
325
543
  * and saves the build result (with collected dependencies) on a cache miss.
326
544
  * @param params - Cache and build parameters
545
+ * @returns The bundled code string
327
546
  */
328
547
  async function withCache(params) {
329
- const { cache, kind, name, sourceFile, outputPath, contextHash, build } = params;
330
- if (!cache) {
331
- await build([]);
332
- return;
333
- }
334
- if (cache.tryRestore({
548
+ const { cache, kind, name, sourceFile, contextHash, build } = params;
549
+ if (!cache) return await build([]);
550
+ const content = cache.tryRestore({
335
551
  kind,
336
552
  name,
337
- outputPath,
338
553
  contextHash
339
- })) {
554
+ });
555
+ if (content !== void 0) {
340
556
  logger.debug(` ${styles.dim("cached")}: ${name}`);
341
- return;
557
+ return content;
342
558
  }
343
559
  const { plugin, getResult } = createDepCollectorPlugin();
344
- await build([plugin]);
560
+ const code = await build([plugin]);
345
561
  cache.save({
346
562
  kind,
347
563
  name,
348
564
  sourceFile,
349
- outputPath,
565
+ content: code,
350
566
  dependencyPaths: getResult(),
351
567
  contextHash
352
568
  });
569
+ return code;
353
570
  }
354
571
  /**
355
572
  * Create a bundle cache backed by the given store.
@@ -360,37 +577,31 @@ function createBundleCache(store) {
360
577
  function tryRestore(params) {
361
578
  const cacheKey = buildCacheKey(params.kind, params.name);
362
579
  const entry = store.getEntry(cacheKey);
363
- if (!entry) return false;
580
+ if (!entry) return;
364
581
  let currentHash;
365
582
  try {
366
583
  currentHash = combineHash(hashFiles(entry.dependencyPaths), params.contextHash);
367
584
  } catch {
368
- return false;
585
+ return;
369
586
  }
370
- if (currentHash !== entry.inputHash) return false;
371
- return store.restoreBundleOutput(cacheKey, params.outputPath);
587
+ if (currentHash !== entry.inputHash) return;
588
+ return store.restoreBundleContent(cacheKey);
372
589
  }
373
590
  function save(params) {
374
- const { kind, name, sourceFile, outputPath, dependencyPaths, contextHash } = params;
591
+ const { kind, name, sourceFile, content, dependencyPaths, contextHash } = params;
375
592
  const cacheKey = buildCacheKey(kind, name);
376
593
  const allDeps = dependencyPaths.includes(sourceFile) ? dependencyPaths : [sourceFile, ...dependencyPaths];
377
594
  const inputHash = combineHash(hashFiles(allDeps), contextHash);
378
- const contentHash = hashFile(outputPath);
379
- store.storeBundleOutput(cacheKey, outputPath);
380
- const outputFiles = [{
381
- outputPath,
382
- contentHash
383
- }];
384
- const mapPath = `${outputPath}.map`;
385
- if (fs$1.existsSync(mapPath)) outputFiles.push({
386
- outputPath: mapPath,
387
- contentHash: hashFile(mapPath)
388
- });
595
+ const contentHash = hashContent(content);
596
+ store.storeBundleContent(cacheKey, content);
389
597
  store.setEntry(cacheKey, {
390
598
  kind: "bundle",
391
599
  inputHash,
392
600
  dependencyPaths: allDeps,
393
- outputFiles,
601
+ outputFiles: [{
602
+ outputPath: cacheKey,
603
+ contentHash
604
+ }],
394
605
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
395
606
  });
396
607
  }
@@ -1622,12 +1833,13 @@ function createTriggerTransformPlugin(triggerContext) {
1622
1833
  //#endregion
1623
1834
  //#region src/cli/services/auth/bundler.ts
1624
1835
  /**
1625
- * Bundle a single auth hook handler into dist/auth-hooks/.
1836
+ * Bundle a single auth hook handler.
1626
1837
  *
1627
1838
  * Follows the same pattern as the executor bundler:
1628
1839
  * 1. Generate an entry file that re-exports the handler as `main`
1629
1840
  * 2. Bundle with rolldown + tree-shaking
1630
1841
  * @param options - Bundle options
1842
+ * @returns Map of function name to bundled code
1631
1843
  */
1632
1844
  async function bundleAuthHooks(options) {
1633
1845
  const { configPath, authName, handlerAccessPath, triggerContext, cache, inlineSourcemap } = options;
@@ -1643,14 +1855,12 @@ async function bundleAuthHooks(options) {
1643
1855
  tsconfig = void 0;
1644
1856
  }
1645
1857
  const functionName = `auth-hook--${authName}--before-login`;
1646
- const outputPath = path.join(outputDir, `${functionName}.js`);
1647
1858
  const absoluteConfigPath = path.resolve(configPath);
1648
- await withCache({
1859
+ const code = await withCache({
1649
1860
  cache,
1650
1861
  kind: "auth-hook",
1651
1862
  name: functionName,
1652
1863
  sourceFile: absoluteConfigPath,
1653
- outputPath,
1654
1864
  contextHash: computeBundlerContextHash({
1655
1865
  sourceFile: absoluteConfigPath,
1656
1866
  serializedTriggerContext: serializeTriggerContext(triggerContext),
@@ -1668,10 +1878,10 @@ async function bundleAuthHooks(options) {
1668
1878
  const triggerPlugin = createTriggerTransformPlugin(triggerContext);
1669
1879
  const plugins = triggerPlugin ? [triggerPlugin] : [];
1670
1880
  plugins.push(...cachePlugins);
1671
- await rolldown.build(rolldown.defineConfig({
1881
+ return (await rolldown.build({
1672
1882
  input: entryPath,
1883
+ write: false,
1673
1884
  output: {
1674
- file: outputPath,
1675
1885
  format: "esm",
1676
1886
  sourcemap: inlineSourcemap ? "inline" : true,
1677
1887
  minify: inlineSourcemap ? { mangle: { keepNames: true } } : true,
@@ -1685,10 +1895,13 @@ async function bundleAuthHooks(options) {
1685
1895
  unknownGlobalSideEffects: false
1686
1896
  },
1687
1897
  logLevel: "silent"
1688
- }));
1898
+ })).output[0].code;
1689
1899
  }
1690
1900
  });
1691
1901
  logger.log(`${styles.success("Bundled")} auth hook for ${styles.info(`"${authName}"`)}`);
1902
+ const bundledCode = /* @__PURE__ */ new Map();
1903
+ bundledCode.set(functionName, code);
1904
+ return bundledCode;
1692
1905
  }
1693
1906
 
1694
1907
  //#endregion
@@ -2692,12 +2905,11 @@ async function bundleScriptTarget(args) {
2692
2905
  ${kind}: ${fnSource}`);
2693
2906
  const entryContent = buildMinimalEntryFromResolved(imports, declarations, fnSource, sourceFilePath);
2694
2907
  const entryPath = join(tempDir, `tailordb-script-${targetIndex}.entry.ts`);
2695
- const outputPath = join(tempDir, `tailordb-script-${targetIndex}.bundle.cjs`);
2696
2908
  writeFileSync(entryPath, entryContent);
2697
- await rolldown.build(rolldown.defineConfig({
2909
+ const bundledCode = (await rolldown.build({
2698
2910
  input: entryPath,
2911
+ write: false,
2699
2912
  output: {
2700
- file: outputPath,
2701
2913
  format: "cjs",
2702
2914
  sourcemap: false,
2703
2915
  minify: true,
@@ -2710,8 +2922,8 @@ async function bundleScriptTarget(args) {
2710
2922
  unknownGlobalSideEffects: false
2711
2923
  },
2712
2924
  logLevel: "silent"
2713
- }));
2714
- return buildPrecompiledExpr(readFileSync(outputPath, "utf-8"));
2925
+ })).output[0].code;
2926
+ return buildPrecompiledExpr(bundledCode);
2715
2927
  }
2716
2928
  /**
2717
2929
  * Precompile TailorDB hooks/validators into self-contained script expressions using rolldown.
@@ -3322,14 +3534,15 @@ async function loadExecutor(executorFilePath) {
3322
3534
  * 1. Creates entry file that extracts operation.body
3323
3535
  * 2. Bundles in a single step with tree-shaking
3324
3536
  * @param options - Bundle executor options
3325
- * @returns Promise that resolves when bundling completes
3537
+ * @returns Map of executor name to bundled code
3326
3538
  */
3327
3539
  async function bundleExecutors(options) {
3540
+ const bundledCode = /* @__PURE__ */ new Map();
3328
3541
  const { config, triggerContext, additionalFiles = [], cache, inlineSourcemap } = options;
3329
3542
  const files = [...loadFilesWithIgnores(config), ...additionalFiles];
3330
3543
  if (files.length === 0) {
3331
3544
  logger.warn(`No executor files found for patterns: ${config.files?.join(", ") ?? "(none)"}`);
3332
- return;
3545
+ return bundledCode;
3333
3546
  }
3334
3547
  logger.newline();
3335
3548
  logger.log(`Bundling ${styles.highlight(files.length.toString())} files for ${styles.info("\"executor\"")}`);
@@ -3351,7 +3564,7 @@ async function bundleExecutors(options) {
3351
3564
  }
3352
3565
  if (executors.length === 0) {
3353
3566
  logger.debug(" No function executors to bundle");
3354
- return;
3567
+ return bundledCode;
3355
3568
  }
3356
3569
  const outputDir = path.resolve(getDistDir(), "executors");
3357
3570
  fs$1.mkdirSync(outputDir, { recursive: true });
@@ -3362,11 +3575,12 @@ async function bundleExecutors(options) {
3362
3575
  } catch {
3363
3576
  tsconfig = void 0;
3364
3577
  }
3365
- await Promise.all(executors.map((executor) => bundleSingleExecutor(executor, outputDir, tsconfig, triggerContext, cache, inlineSourcemap)));
3578
+ const results = await Promise.all(executors.map((executor) => bundleSingleExecutor(executor, outputDir, tsconfig, triggerContext, cache, inlineSourcemap)));
3579
+ for (const [name, code] of results) bundledCode.set(name, code);
3366
3580
  logger.log(`${styles.success("Bundled")} ${styles.info("\"executor\"")}`);
3581
+ return bundledCode;
3367
3582
  }
3368
3583
  async function bundleSingleExecutor(executor, outputDir, tsconfig, triggerContext, cache, inlineSourcemap) {
3369
- const outputPath = path.join(outputDir, `${executor.name}.js`);
3370
3584
  const serializedTriggerContext = serializeTriggerContext(triggerContext);
3371
3585
  const contextHash = computeBundlerContextHash({
3372
3586
  sourceFile: executor.sourceFile,
@@ -3374,12 +3588,11 @@ async function bundleSingleExecutor(executor, outputDir, tsconfig, triggerContex
3374
3588
  tsconfig,
3375
3589
  inlineSourcemap
3376
3590
  });
3377
- await withCache({
3591
+ const code = await withCache({
3378
3592
  cache,
3379
3593
  kind: "executor",
3380
3594
  name: executor.name,
3381
3595
  sourceFile: executor.sourceFile,
3382
- outputPath,
3383
3596
  contextHash,
3384
3597
  async build(cachePlugins) {
3385
3598
  const entryPath = path.join(outputDir, `${executor.name}.entry.js`);
@@ -3394,10 +3607,10 @@ async function bundleSingleExecutor(executor, outputDir, tsconfig, triggerContex
3394
3607
  const triggerPlugin = createTriggerTransformPlugin(triggerContext);
3395
3608
  const plugins = triggerPlugin ? [triggerPlugin] : [];
3396
3609
  plugins.push(...cachePlugins);
3397
- await rolldown.build(rolldown.defineConfig({
3610
+ return (await rolldown.build({
3398
3611
  input: entryPath,
3612
+ write: false,
3399
3613
  output: {
3400
- file: outputPath,
3401
3614
  format: "esm",
3402
3615
  sourcemap: inlineSourcemap ? "inline" : true,
3403
3616
  minify: inlineSourcemap ? { mangle: { keepNames: true } } : true,
@@ -3411,9 +3624,10 @@ async function bundleSingleExecutor(executor, outputDir, tsconfig, triggerContex
3411
3624
  unknownGlobalSideEffects: false
3412
3625
  },
3413
3626
  logLevel: "silent"
3414
- }));
3627
+ })).output[0].code;
3415
3628
  }
3416
3629
  });
3630
+ return [executor.name, code];
3417
3631
  }
3418
3632
 
3419
3633
  //#endregion
@@ -3509,13 +3723,14 @@ async function loadResolver(resolverFilePath) {
3509
3723
  * @param triggerContext - Trigger context for workflow/job transformations
3510
3724
  * @param cache - Optional bundle cache for skipping unchanged builds
3511
3725
  * @param inlineSourcemap - Whether to enable inline sourcemaps
3512
- * @returns Promise that resolves when bundling completes
3726
+ * @returns Map of resolver name to bundled code
3513
3727
  */
3514
3728
  async function bundleResolvers(namespace, config, triggerContext, cache, inlineSourcemap) {
3729
+ const bundledCode = /* @__PURE__ */ new Map();
3515
3730
  const files = loadFilesWithIgnores(config);
3516
3731
  if (files.length === 0) {
3517
3732
  logger.warn(`No resolver files found for patterns: ${config.files?.join(", ") ?? "(none)"}`);
3518
- return;
3733
+ return bundledCode;
3519
3734
  }
3520
3735
  logger.newline();
3521
3736
  logger.log(`Bundling ${styles.highlight(files.length.toString())} files for ${styles.info(`"${namespace}"`)}`);
@@ -3540,11 +3755,12 @@ async function bundleResolvers(namespace, config, triggerContext, cache, inlineS
3540
3755
  } catch {
3541
3756
  tsconfig = void 0;
3542
3757
  }
3543
- await Promise.all(resolvers.map((resolver) => bundleSingleResolver(resolver, outputDir, tsconfig, triggerContext, cache, inlineSourcemap)));
3758
+ const results = await Promise.all(resolvers.map((resolver) => bundleSingleResolver(resolver, outputDir, tsconfig, triggerContext, cache, inlineSourcemap)));
3759
+ for (const [name, code] of results) bundledCode.set(name, code);
3544
3760
  logger.log(`${styles.success("Bundled")} ${styles.info(`"${namespace}"`)}`);
3761
+ return bundledCode;
3545
3762
  }
3546
3763
  async function bundleSingleResolver(resolver, outputDir, tsconfig, triggerContext, cache, inlineSourcemap) {
3547
- const outputPath = path.join(outputDir, `${resolver.name}.js`);
3548
3764
  const serializedTriggerContext = serializeTriggerContext(triggerContext);
3549
3765
  const contextHash = computeBundlerContextHash({
3550
3766
  sourceFile: resolver.sourceFile,
@@ -3552,12 +3768,11 @@ async function bundleSingleResolver(resolver, outputDir, tsconfig, triggerContex
3552
3768
  tsconfig,
3553
3769
  inlineSourcemap
3554
3770
  });
3555
- await withCache({
3771
+ const code = await withCache({
3556
3772
  cache,
3557
3773
  kind: "resolver",
3558
3774
  name: resolver.name,
3559
3775
  sourceFile: resolver.sourceFile,
3560
- outputPath,
3561
3776
  contextHash,
3562
3777
  async build(cachePlugins) {
3563
3778
  const entryPath = path.join(outputDir, `${resolver.name}.entry.js`);
@@ -3593,10 +3808,10 @@ async function bundleSingleResolver(resolver, outputDir, tsconfig, triggerContex
3593
3808
  const triggerPlugin = createTriggerTransformPlugin(triggerContext);
3594
3809
  const plugins = triggerPlugin ? [triggerPlugin] : [];
3595
3810
  plugins.push(...cachePlugins);
3596
- await rolldown.build(rolldown.defineConfig({
3811
+ return (await rolldown.build({
3597
3812
  input: entryPath,
3813
+ write: false,
3598
3814
  output: {
3599
- file: outputPath,
3600
3815
  format: "esm",
3601
3816
  sourcemap: inlineSourcemap ? "inline" : true,
3602
3817
  minify: inlineSourcemap ? { mangle: { keepNames: true } } : true,
@@ -3610,9 +3825,10 @@ async function bundleSingleResolver(resolver, outputDir, tsconfig, triggerContex
3610
3825
  unknownGlobalSideEffects: false
3611
3826
  },
3612
3827
  logLevel: "silent"
3613
- }));
3828
+ })).output[0].code;
3614
3829
  }
3615
3830
  });
3831
+ return [resolver.name, code];
3616
3832
  }
3617
3833
 
3618
3834
  //#endregion
@@ -3833,7 +4049,10 @@ function transformWorkflowSource(source, targetJobName, targetJobExportName, oth
3833
4049
  async function bundleWorkflowJobs(allJobs, mainJobNames, env = {}, triggerContext, cache, inlineSourcemap) {
3834
4050
  if (allJobs.length === 0) {
3835
4051
  logger.warn("No workflow jobs to bundle");
3836
- return { mainJobDeps: {} };
4052
+ return {
4053
+ mainJobDeps: {},
4054
+ bundledCode: /* @__PURE__ */ new Map()
4055
+ };
3837
4056
  }
3838
4057
  const { usedJobs, mainJobDeps } = await filterUsedJobs(allJobs, mainJobNames);
3839
4058
  logger.newline();
@@ -3850,9 +4069,14 @@ async function bundleWorkflowJobs(allJobs, mainJobNames, env = {}, triggerContex
3850
4069
  } catch {
3851
4070
  tsconfig = void 0;
3852
4071
  }
3853
- await Promise.all(usedJobs.map((job) => bundleSingleJob(job, usedJobs, outputDir, tsconfig, env, triggerContext, cache, inlineSourcemap)));
4072
+ const results = await Promise.all(usedJobs.map((job) => bundleSingleJob(job, usedJobs, outputDir, tsconfig, env, triggerContext, cache, inlineSourcemap)));
4073
+ const bundledCode = /* @__PURE__ */ new Map();
4074
+ for (const [name, code] of results) bundledCode.set(name, code);
3854
4075
  logger.log(`${styles.success("Bundled")} ${styles.info("\"workflow-job\"")}`);
3855
- return { mainJobDeps };
4076
+ return {
4077
+ mainJobDeps,
4078
+ bundledCode
4079
+ };
3856
4080
  }
3857
4081
  /**
3858
4082
  * Filter jobs to only include those that are actually used.
@@ -3927,7 +4151,6 @@ async function filterUsedJobs(allJobs, mainJobNames) {
3927
4151
  };
3928
4152
  }
3929
4153
  async function bundleSingleJob(job, allJobs, outputDir, tsconfig, env, triggerContext, cache, inlineSourcemap) {
3930
- const outputPath = path.join(outputDir, `${job.name}.js`);
3931
4154
  const serializedTriggerContext = serializeTriggerContext(triggerContext);
3932
4155
  const sortedEnvPrefix = JSON.stringify(Object.fromEntries(Object.entries(env).sort(([a], [b]) => a.localeCompare(b))));
3933
4156
  const contextHash = computeBundlerContextHash({
@@ -3937,12 +4160,11 @@ async function bundleSingleJob(job, allJobs, outputDir, tsconfig, env, triggerCo
3937
4160
  inlineSourcemap,
3938
4161
  prefix: sortedEnvPrefix
3939
4162
  });
3940
- await withCache({
4163
+ const code = await withCache({
3941
4164
  cache,
3942
4165
  kind: "workflow-job",
3943
4166
  name: job.name,
3944
4167
  sourceFile: job.sourceFile,
3945
- outputPath,
3946
4168
  contextHash,
3947
4169
  async build(cachePlugins) {
3948
4170
  const entryPath = path.join(outputDir, `${job.name}.entry.js`);
@@ -3971,10 +4193,10 @@ async function bundleSingleJob(job, allJobs, outputDir, tsconfig, env, triggerCo
3971
4193
  }
3972
4194
  }
3973
4195
  }, ...cachePlugins];
3974
- await rolldown.build(rolldown.defineConfig({
4196
+ return (await rolldown.build({
3975
4197
  input: entryPath,
4198
+ write: false,
3976
4199
  output: {
3977
- file: outputPath,
3978
4200
  format: "esm",
3979
4201
  sourcemap: inlineSourcemap ? "inline" : true,
3980
4202
  minify: inlineSourcemap ? { mangle: { keepNames: true } } : true,
@@ -3988,9 +4210,10 @@ async function bundleSingleJob(job, allJobs, outputDir, tsconfig, env, triggerCo
3988
4210
  unknownGlobalSideEffects: false
3989
4211
  },
3990
4212
  logLevel: "silent"
3991
- }));
4213
+ })).output[0].code;
3992
4214
  }
3993
4215
  });
4216
+ return [job.name, code];
3994
4217
  }
3995
4218
 
3996
4219
  //#endregion
@@ -4652,8 +4875,17 @@ async function loadApplication(params) {
4652
4875
  if (workflowService) await workflowService.loadWorkflows();
4653
4876
  const triggerContext = await buildTriggerContext(config.workflow);
4654
4877
  const inlineSourcemap = resolveInlineSourcemap(config.inlineSourcemap);
4655
- for (const pipeline of resolverResult.resolverServices) await bundleResolvers(pipeline.namespace, pipeline.config, triggerContext, bundleCache, inlineSourcemap);
4656
- if (executorService) await bundleExecutors({
4878
+ const bundledScripts = {
4879
+ resolvers: /* @__PURE__ */ new Map(),
4880
+ executors: /* @__PURE__ */ new Map(),
4881
+ workflowJobs: /* @__PURE__ */ new Map(),
4882
+ authHooks: /* @__PURE__ */ new Map()
4883
+ };
4884
+ for (const pipeline of resolverResult.resolverServices) {
4885
+ const resolverBundles = await bundleResolvers(pipeline.namespace, pipeline.config, triggerContext, bundleCache, inlineSourcemap);
4886
+ for (const [name, code] of resolverBundles) bundledScripts.resolvers.set(name, code);
4887
+ }
4888
+ if (executorService) bundledScripts.executors = await bundleExecutors({
4657
4889
  config: executorService.config,
4658
4890
  triggerContext,
4659
4891
  additionalFiles: [...pluginExecutorFiles],
@@ -4664,10 +4896,11 @@ async function loadApplication(params) {
4664
4896
  if (workflowService && workflowService.jobs.length > 0) {
4665
4897
  const mainJobNames = workflowService.workflowSources.map((ws) => ws.workflow.mainJob.name);
4666
4898
  workflowBuildResult = await bundleWorkflowJobs(workflowService.jobs, mainJobNames, config.env ?? {}, triggerContext, bundleCache, inlineSourcemap);
4899
+ bundledScripts.workflowJobs = workflowBuildResult.bundledCode;
4667
4900
  }
4668
4901
  if (authResult.authService?.config.hooks?.beforeLogin) {
4669
4902
  const authName = authResult.authService.config.name;
4670
- await bundleAuthHooks({
4903
+ bundledScripts.authHooks = await bundleAuthHooks({
4671
4904
  configPath: config.path,
4672
4905
  authName,
4673
4906
  handlerAccessPath: `auth.hooks.beforeLogin.handler`,
@@ -4696,10 +4929,11 @@ async function loadApplication(params) {
4696
4929
  secrets,
4697
4930
  env: config.env ?? {}
4698
4931
  }),
4699
- workflowBuildResult
4932
+ workflowBuildResult,
4933
+ bundledScripts
4700
4934
  };
4701
4935
  }
4702
4936
 
4703
4937
  //#endregion
4704
- export { writePlatformConfig as S, hashFile as _, loadConfig as a, loadWorkspaceId as b, ExecutorSchema as c, TailorDBTypeSchema as d, stringifyFunction as f, getDistDir as g, createBundleCache as h, resolveInlineSourcemap as i, OAuth2ClientSchema as l, loadFilesWithIgnores as m, generatePluginFilesIfNeeded as n, WorkflowJobSchema as o, tailorUserMap as p, loadApplication as r, createExecutorService as s, defineApplication as t, ResolverSchema as u, fetchLatestToken as v, readPlatformConfig as x, loadAccessToken as y };
4705
- //# sourceMappingURL=application-Clwpv84E.mjs.map
4938
+ export { resolveTokens as C, readPlatformConfig as S, writePlatformConfig as T, hashFile as _, loadConfig as a, loadAccessToken as b, ExecutorSchema as c, TailorDBTypeSchema as d, stringifyFunction as f, getDistDir as g, createBundleCache as h, resolveInlineSourcemap as i, OAuth2ClientSchema as l, loadFilesWithIgnores as m, generatePluginFilesIfNeeded as n, WorkflowJobSchema as o, tailorUserMap as p, loadApplication as r, createExecutorService as s, defineApplication as t, ResolverSchema as u, deleteUserTokens as v, saveUserTokens as w, loadWorkspaceId as x, fetchLatestToken as y };
4939
+ //# sourceMappingURL=application-CASjzt3W.mjs.map