@tailor-platform/sdk 1.69.0 → 1.70.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 (52) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/application-BakHtldG.mjs +4 -0
  3. package/dist/{application-Cr-limKC.mjs → application-Df5_I83n.mjs} +318 -78
  4. package/dist/application-Df5_I83n.mjs.map +1 -0
  5. package/dist/cli/erd-viewer-assets/app.js +279 -36
  6. package/dist/cli/erd-viewer-assets/index.html +4 -0
  7. package/dist/cli/erd-viewer-assets/styles.css +252 -5
  8. package/dist/cli/index.mjs +641 -90
  9. package/dist/cli/index.mjs.map +1 -1
  10. package/dist/cli/lib.d.mts +14 -8
  11. package/dist/cli/lib.mjs +2 -2
  12. package/dist/completion/zsh-worker.zsh +153 -2
  13. package/dist/configure/index.d.mts +5 -5
  14. package/dist/configure/index.mjs +8 -6
  15. package/dist/configure/index.mjs.map +1 -1
  16. package/dist/{index-B7VbJm0_.d.mts → index-BAEaAqmz.d.mts} +90 -40
  17. package/dist/{index-CklcVeMG.d.mts → index-C-vsbx27.d.mts} +2 -2
  18. package/dist/{index-hXoO-AOC.d.mts → index-CKI0eZP6.d.mts} +2 -2
  19. package/dist/{index-DYhnxXYR.d.mts → index-CrqOgUF2.d.mts} +2 -2
  20. package/dist/{index-DlDRSzFZ.d.mts → index-DESLU9kI.d.mts} +2 -2
  21. package/dist/plugin/builtin/enum-constants/index.d.mts +1 -1
  22. package/dist/plugin/builtin/file-utils/index.d.mts +1 -1
  23. package/dist/plugin/builtin/kysely-type/index.d.mts +1 -1
  24. package/dist/plugin/builtin/seed/index.d.mts +1 -1
  25. package/dist/plugin/index.d.mts +1 -1
  26. package/dist/{runtime-jowoN6qC.mjs → runtime-CSY0eD4_.mjs} +330 -190
  27. package/dist/runtime-CSY0eD4_.mjs.map +1 -0
  28. package/dist/{schema-1msIhXwA.mjs → schema-C4fkpWV_.mjs} +9 -15
  29. package/dist/schema-C4fkpWV_.mjs.map +1 -0
  30. package/dist/{types-2Be3wSMc.mjs → types-32lUMToj.mjs} +1 -1
  31. package/dist/{types-CmzfQP_m.mjs → types-D4QMmNWh.mjs} +1 -12
  32. package/dist/types-D4QMmNWh.mjs.map +1 -0
  33. package/dist/{types-Bzr0RQME.d.mts → types-Dynq4AJv.d.mts} +2 -2
  34. package/dist/{types-DZrtN6-H.d.mts → types-rj8YJcEe.d.mts} +5 -2
  35. package/dist/utils/test/index.d.mts +2 -2
  36. package/dist/{workflow.generated-Br9bmLdX.d.mts → workflow.generated-DJULCuRr.d.mts} +177 -172
  37. package/docs/cli/application.md +37 -2
  38. package/docs/cli/setup.md +1 -0
  39. package/docs/cli/tailordb.md +24 -0
  40. package/docs/cli/user.md +11 -1
  41. package/docs/cli/workspace.md +13 -7
  42. package/docs/cli-reference.md +6 -0
  43. package/docs/github-actions.md +27 -0
  44. package/docs/multi-environment.md +22 -0
  45. package/docs/services/aigateway.md +4 -2
  46. package/docs/services/http-adapter.md +16 -1
  47. package/package.json +1 -1
  48. package/dist/application-Br48NXBD.mjs +0 -4
  49. package/dist/application-Cr-limKC.mjs.map +0 -1
  50. package/dist/runtime-jowoN6qC.mjs.map +0 -1
  51. package/dist/schema-1msIhXwA.mjs.map +0 -1
  52. package/dist/types-CmzfQP_m.mjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @tailor-platform/sdk
2
2
 
3
+ ## 1.70.0
4
+ ### Minor Changes
5
+
6
+
7
+
8
+ - [#1547](https://github.com/tailor-platform/sdk/pull/1547) [`7bb4dd6`](https://github.com/tailor-platform/sdk/commit/7bb4dd68a2492e5b8d5051730cdf35ba4f442134) Thanks [@toiroakr](https://github.com/toiroakr)! - Route `deploy --dry-run` plan diff output to stdout so CI pipelines can capture it cleanly without `2>&1`. Add `--json` / `-j` support to `deploy`: dry-run outputs `{ summary, changes, warnings, conflicts }` and apply outputs `{ summary, status: "applied" }` to stdout for machine-readable consumption. The `warnings` array includes unmanaged resources and skipped secrets; the `conflicts` array lists owner conflicts.
9
+
10
+
11
+
12
+ - [#1579](https://github.com/tailor-platform/sdk/pull/1579) [`7522a06`](https://github.com/tailor-platform/sdk/commit/7522a06abd4b5cabbc5b7ef2e00464db65fb894d) Thanks [@dqn](https://github.com/dqn)! - Add `tailor-sdk setup --erd-preview` and `tailordb erd diff` for PR ERD viewer artifacts with current/diff previews.
13
+
14
+
15
+
16
+ - [#1575](https://github.com/tailor-platform/sdk/pull/1575) [`9857f3a`](https://github.com/tailor-platform/sdk/commit/9857f3a00dd9d8c1cd12c95a0517da1fe4c864a9) Thanks [@dqn](https://github.com/dqn)! - Add profile-level Platform connection settings so CLI profiles can switch the Platform API URL, OAuth2 login client, and Console URL together.
17
+
18
+
19
+
20
+ - [#1566](https://github.com/tailor-platform/sdk/pull/1566) [`acd85bf`](https://github.com/tailor-platform/sdk/commit/acd85bfa9e5f2b3f752f09351572a465d8624f43) Thanks [@dqn](https://github.com/dqn)! - Support `TypedDocumentNode` queries in HTTP adapters and infer `output` response data from them.
21
+
22
+
23
+ ### Patch Changes
24
+
25
+
26
+
27
+ - [#1560](https://github.com/tailor-platform/sdk/pull/1560) [`1899633`](https://github.com/tailor-platform/sdk/commit/1899633a726955d6e13443545bd8bfa6b16fb5ed) Thanks [@dragon3](https://github.com/dragon3)! - Update AI Gateway documentation to present supported models without naming backend providers
28
+
29
+
30
+
31
+ - [#1574](https://github.com/tailor-platform/sdk/pull/1574) [`0e2759d`](https://github.com/tailor-platform/sdk/commit/0e2759d41f89c6bc670149932f860f208b6b7d0b) Thanks [@dqn](https://github.com/dqn)! - Improve builder API type errors so invalid field modifier calls show actionable messages.
32
+
3
33
  ## 1.69.0
4
34
  ### Minor Changes
5
35
 
@@ -0,0 +1,4 @@
1
+
2
+ import { n as generatePluginFilesIfNeeded, r as loadApplication, t as defineApplication } from "./application-Df5_I83n.mjs";
3
+
4
+ export { defineApplication, generatePluginFilesIfNeeded };
@@ -213,35 +213,98 @@ function byName(a, b) {
213
213
 
214
214
  //#endregion
215
215
  //#region src/cli/shared/client.ts
216
- const platformBaseUrl = process.env.PLATFORM_URL ?? "https://api.tailor.tech";
217
- const oauth2ClientId = process.env.PLATFORM_OAUTH2_CLIENT_ID ?? "cpoc_0Iudir72fqSpqC6GQ58ri1cLAqcq5vJl";
216
+ const defaultPlatformBaseUrl = "https://api.tailor.tech";
217
+ const defaultConsoleBaseUrl = "https://console.tailor.tech";
218
+ const defaultOAuth2ClientId = "cpoc_0Iudir72fqSpqC6GQ58ri1cLAqcq5vJl";
218
219
  const oauth2DiscoveryEndpoint = "/.well-known/oauth-authorization-server/oauth2/platform";
220
+ const tokenPlatformConfigs = /* @__PURE__ */ new Map();
221
+ function getEnvPlatformUrl() {
222
+ return process.env.TAILOR_PLATFORM_URL ?? process.env.PLATFORM_URL;
223
+ }
224
+ function getEnvOAuth2ClientId() {
225
+ return process.env.TAILOR_PLATFORM_OAUTH2_CLIENT_ID ?? process.env.PLATFORM_OAUTH2_CLIENT_ID;
226
+ }
227
+ function normalizeBaseUrl(value) {
228
+ const url = new URL(value);
229
+ url.hash = "";
230
+ url.search = "";
231
+ return url.toString().replace(/\/$/, "");
232
+ }
233
+ function getEffectivePlatformConfig(config = {}) {
234
+ const platformUrl = config.platformUrl ?? getEnvPlatformUrl();
235
+ const oauth2ClientId = config.oauth2ClientId ?? getEnvOAuth2ClientId();
236
+ const consoleUrl = config.consoleUrl ?? process.env.TAILOR_PLATFORM_CONSOLE_URL;
237
+ const effective = {
238
+ ...platformUrl ? { platformUrl } : {},
239
+ ...oauth2ClientId ? { oauth2ClientId } : {},
240
+ ...consoleUrl ? { consoleUrl } : {}
241
+ };
242
+ return Object.keys(effective).length > 0 ? effective : void 0;
243
+ }
244
+ function rememberPlatformConfigForToken(accessToken, config) {
245
+ const effectiveConfig = getEffectivePlatformConfig(config);
246
+ if (effectiveConfig) tokenPlatformConfigs.set(accessToken, effectiveConfig);
247
+ else tokenPlatformConfigs.delete(accessToken);
248
+ }
249
+ function getPlatformConfigForToken(accessToken) {
250
+ return tokenPlatformConfigs.get(accessToken);
251
+ }
252
+ function getPlatformBaseUrl(config = {}) {
253
+ return normalizeBaseUrl(config.platformUrl ?? getEnvPlatformUrl() ?? "https://api.tailor.tech");
254
+ }
255
+ function isDefaultPlatform(config) {
256
+ return getPlatformBaseUrl(config) === normalizeBaseUrl(defaultPlatformBaseUrl);
257
+ }
258
+ function getOAuth2ClientId(config = {}) {
259
+ return config.oauth2ClientId ?? getEnvOAuth2ClientId() ?? defaultOAuth2ClientId;
260
+ }
261
+ function inferConsoleBaseUrl(platformBaseUrl) {
262
+ const platformUrl = new URL(platformBaseUrl);
263
+ if (platformUrl.hostname.startsWith("api.")) {
264
+ platformUrl.hostname = platformUrl.hostname.replace(/^api\./, "console.");
265
+ return normalizeBaseUrl(platformUrl.toString());
266
+ }
267
+ return defaultConsoleBaseUrl;
268
+ }
269
+ function getConsoleBaseUrl(config = {}) {
270
+ if (config.consoleUrl) return normalizeBaseUrl(config.consoleUrl);
271
+ if (config.platformUrl) {
272
+ const inferredUrl = inferConsoleBaseUrl(config.platformUrl);
273
+ if (inferredUrl !== "https://console.tailor.tech") return inferredUrl;
274
+ }
275
+ if (process.env.TAILOR_PLATFORM_CONSOLE_URL) return normalizeBaseUrl(process.env.TAILOR_PLATFORM_CONSOLE_URL);
276
+ return inferConsoleBaseUrl(getPlatformBaseUrl(config));
277
+ }
219
278
  /**
220
279
  * Initialize an OAuth2 client for Tailor Platform.
280
+ * @param config - Optional platform connection settings
221
281
  * @returns Configured OAuth2 client
222
282
  */
223
- function initOAuth2Client() {
283
+ function initOAuth2Client(config) {
224
284
  return new OAuth2Client({
225
- clientId: oauth2ClientId,
226
- server: platformBaseUrl,
285
+ clientId: getOAuth2ClientId(config),
286
+ server: getPlatformBaseUrl(config),
227
287
  discoveryEndpoint: oauth2DiscoveryEndpoint
228
288
  });
229
289
  }
230
290
  /**
231
291
  * Initialize an Operator client with the given access token.
232
292
  * @param accessToken - Access token for authentication
293
+ * @param config - Optional platform connection settings
233
294
  * @returns Configured Operator client
234
295
  */
235
- async function initOperatorClient(accessToken) {
296
+ async function initOperatorClient(accessToken, config) {
297
+ const platformConfig = config ?? getPlatformConfigForToken(accessToken);
236
298
  const [{ createTracingInterceptor }, { OperatorService }] = await Promise.all([import("./interceptor-DOqRkCya.mjs"), import("./service_pb-DGSmn-aF.mjs")]);
237
- return createClient(OperatorService, await createTransport(platformBaseUrl, [
299
+ const interceptors = [
238
300
  await userAgentInterceptor(),
239
301
  await bearerTokenInterceptor(accessToken),
240
302
  retryInterceptor(),
241
303
  errorHandlingInterceptor(),
242
304
  createTracingInterceptor(),
243
305
  concurrencyLimitInterceptor()
244
- ]));
306
+ ];
307
+ return createClient(OperatorService, await createTransport(getPlatformBaseUrl(platformConfig), interceptors));
245
308
  }
246
309
  /**
247
310
  * Create a Connect transport using connect-node (HTTP/2).
@@ -574,10 +637,11 @@ async function fetchPaged(fn, options) {
574
637
  /**
575
638
  * Fetch user info from the Tailor Platform userinfo endpoint.
576
639
  * @param accessToken - Access token for the current user
640
+ * @param config - Optional platform connection settings
577
641
  * @returns Parsed user info
578
642
  */
579
- async function fetchUserInfo(accessToken) {
580
- const userInfoUrl = new URL("/auth/platform/userinfo", platformBaseUrl).href;
643
+ async function fetchUserInfo(accessToken, config) {
644
+ const userInfoUrl = new URL("/auth/platform/userinfo", getPlatformBaseUrl(config)).href;
581
645
  const resp = await fetch(userInfoUrl, { headers: {
582
646
  Authorization: `Bearer ${accessToken}`,
583
647
  "User-Agent": await userAgent()
@@ -654,13 +718,14 @@ async function fetchMachineUserToken(url, clientId, clientSecret) {
654
718
  * Fetch an OAuth2 token for a platform machine user via client_credentials grant.
655
719
  * @param clientId - Client ID for the platform machine user
656
720
  * @param clientSecret - Client secret for the platform machine user
721
+ * @param config - Optional platform connection settings
657
722
  * @returns OAuth2 token
658
723
  */
659
- async function fetchPlatformMachineUserToken(clientId, clientSecret) {
724
+ async function fetchPlatformMachineUserToken(clientId, clientSecret, config) {
660
725
  return await new OAuth2Client({
661
726
  clientId,
662
727
  clientSecret,
663
- server: platformBaseUrl,
728
+ server: getPlatformBaseUrl(config),
664
729
  discoveryEndpoint: oauth2DiscoveryEndpoint
665
730
  }).clientCredentials();
666
731
  }
@@ -743,7 +808,10 @@ const pfProfileSchema = z.object({
743
808
  workspace_id: z.string(),
744
809
  readonly: z.boolean().optional(),
745
810
  machine_user: z.string().optional(),
746
- machine_user_override: z.enum(["allow", "deny"]).optional()
811
+ machine_user_override: z.enum(["allow", "deny"]).optional(),
812
+ platform_url: z.url().optional(),
813
+ oauth2_client_id: z.string().optional(),
814
+ console_url: z.url().optional()
747
815
  });
748
816
  const pfUserSchemaV1 = z.object({
749
817
  access_token: z.string(),
@@ -767,8 +835,10 @@ const pfConfigSchemaV1 = z.object({
767
835
  profiles: z.partialRecord(z.string(), pfProfileSchema),
768
836
  current_user: z.string().nullable()
769
837
  });
770
- const LATEST_CONFIG_VERSION = 2;
838
+ const V2_CONFIG_VERSION = 2;
839
+ const LATEST_CONFIG_VERSION = 3;
771
840
  const V2_MIN_SDK_VERSION = "1.29.0";
841
+ const V3_MIN_SDK_VERSION = "1.70.0";
772
842
  const semverSchema = z.templateLiteral([
773
843
  z.number().int(),
774
844
  ".",
@@ -776,8 +846,8 @@ const semverSchema = z.templateLiteral([
776
846
  ".",
777
847
  z.number().int()
778
848
  ]);
779
- const pfConfigSchemaV2 = z.object({
780
- version: z.literal(LATEST_CONFIG_VERSION),
849
+ const pfConfigSchema = z.object({
850
+ version: z.union([z.literal(V2_CONFIG_VERSION), z.literal(LATEST_CONFIG_VERSION)]),
781
851
  min_sdk_version: semverSchema,
782
852
  latest_version: z.number().int().optional(),
783
853
  latest_min_sdk_version: semverSchema.optional(),
@@ -790,6 +860,89 @@ function platformConfigPath() {
790
860
  return path.join(xdgConfig, "tailor-platform", "config.yaml");
791
861
  }
792
862
  /**
863
+ * Convert stored profile platform fields to platform client settings.
864
+ * @param profile - Profile platform settings
865
+ * @returns Platform client settings
866
+ */
867
+ function platformConfigFromProfile(profile) {
868
+ const config = {
869
+ ...profile?.platform_url ? { platformUrl: profile.platform_url } : {},
870
+ ...profile?.oauth2_client_id ? { oauth2ClientId: profile.oauth2_client_id } : {},
871
+ ...profile?.console_url ? { consoleUrl: profile.console_url } : {}
872
+ };
873
+ return Object.keys(config).length > 0 ? config : void 0;
874
+ }
875
+ function platformUserKey(user, config) {
876
+ const platformUrl = getPlatformBaseUrl(config);
877
+ if (platformUrl === normalizeBaseUrl("https://api.tailor.tech")) return user;
878
+ return `${platformUrl}|${user}`;
879
+ }
880
+ function canUseLegacyUserKey(platformUrl) {
881
+ try {
882
+ return getPlatformBaseUrl() === platformUrl;
883
+ } catch {
884
+ return false;
885
+ }
886
+ }
887
+ function findUserEntry(config, user, platformConfig, opts = {}) {
888
+ const userKey = platformUserKey(user, platformConfig);
889
+ const userEntry = config.users[userKey];
890
+ if (userEntry) return {
891
+ userKey,
892
+ userEntry
893
+ };
894
+ const platformUrl = getPlatformBaseUrl(platformConfig);
895
+ if (userKey !== user && (opts.allowLegacyUserKey === false || !canUseLegacyUserKey(platformUrl))) return {
896
+ userKey,
897
+ userEntry
898
+ };
899
+ const legacyEntry = config.users[user];
900
+ return legacyEntry ? {
901
+ userKey: user,
902
+ userEntry: legacyEntry
903
+ } : {
904
+ userKey,
905
+ userEntry
906
+ };
907
+ }
908
+ /**
909
+ * Resolve the config user key that would be used for a user on the selected platform.
910
+ * @param config - Platform config
911
+ * @param user - User name
912
+ * @param platformConfig - Optional platform connection settings
913
+ * @param opts - Token lookup options
914
+ * @returns Resolved config user key
915
+ */
916
+ function resolveUserTokenKey(config, user, platformConfig, opts) {
917
+ return findUserEntry(config, user, platformConfig, opts).userKey;
918
+ }
919
+ /**
920
+ * Check whether tokens are registered for a user on the selected platform.
921
+ * @param config - Platform config
922
+ * @param user - User name
923
+ * @param platformConfig - Optional platform connection settings
924
+ * @param opts - Token lookup options
925
+ * @returns True when the user has a registered token entry
926
+ */
927
+ function hasUserTokenEntry(config, user, platformConfig, opts) {
928
+ return findUserEntry(config, user, platformConfig, opts).userEntry !== void 0;
929
+ }
930
+ function hasUserKeyForName(users, user) {
931
+ return users[user] !== void 0 || Object.keys(users).some((key) => key.endsWith(`|${user}`));
932
+ }
933
+ /**
934
+ * Check whether any platform has tokens registered for a user.
935
+ * @param config - Platform config
936
+ * @param user - User name
937
+ * @returns True when the user has a token entry for any platform
938
+ */
939
+ function hasAnyUserTokenEntry(config, user) {
940
+ return hasUserKeyForName(config.users, user);
941
+ }
942
+ function hasCurrentUserEntry(users, currentUser) {
943
+ return hasUserKeyForName(users, currentUser);
944
+ }
945
+ /**
793
946
  * Migrate a v1 config to v2.
794
947
  * Tokens are kept in the config file (storage: "file") during migration.
795
948
  * They will be moved to the OS keyring on next login or token refresh.
@@ -808,13 +961,20 @@ function migrateV1ToV2(v1Config) {
808
961
  };
809
962
  }
810
963
  return {
811
- version: LATEST_CONFIG_VERSION,
964
+ version: V2_CONFIG_VERSION,
812
965
  min_sdk_version: V2_MIN_SDK_VERSION,
813
966
  users,
814
967
  profiles: v1Config.profiles,
815
968
  current_user: v1Config.current_user
816
969
  };
817
970
  }
971
+ async function warnIfNewerConfigAvailable(config) {
972
+ if (!config.latest_min_sdk_version) return;
973
+ if (lt((await readPackageJson()).version ?? "0.0.0", config.latest_min_sdk_version)) logger.warn(multiline`
974
+ A newer config version (${String(config.latest_version)}) is available.
975
+ Please update your SDK to >= ${config.latest_min_sdk_version}: pnpm update @tailor-platform/sdk
976
+ `);
977
+ }
818
978
  /**
819
979
  * Read Tailor Platform CLI configuration, migrating from tailorctl or v1 if necessary.
820
980
  * @returns Parsed platform configuration
@@ -844,15 +1004,10 @@ async function readPlatformConfig() {
844
1004
  ${updateHint}
845
1005
  `);
846
1006
  }
847
- const v2Result = pfConfigSchemaV2.safeParse(rawConfig);
848
- if (v2Result.success) {
849
- if (v2Result.data.latest_min_sdk_version) {
850
- if (lt((await readPackageJson()).version ?? "0.0.0", v2Result.data.latest_min_sdk_version)) logger.warn(multiline`
851
- A newer config version (${String(v2Result.data.latest_version)}) is available.
852
- Please update your SDK to >= ${v2Result.data.latest_min_sdk_version}: pnpm update @tailor-platform/sdk
853
- `);
854
- }
855
- return v2Result.data;
1007
+ const configResult = pfConfigSchema.safeParse(rawConfig);
1008
+ if (configResult.success) {
1009
+ await warnIfNewerConfigAvailable(configResult.data);
1010
+ return configResult.data;
856
1011
  }
857
1012
  const v1Result = pfConfigSchemaV1.safeParse(rawConfig);
858
1013
  if (v1Result.success) return migrateV1ToV2(v1Result.data);
@@ -871,7 +1026,7 @@ function toV1ForDisk(config) {
871
1026
  token_expires_at: entry.token_expires_at
872
1027
  };
873
1028
  }
874
- const currentUser = config.current_user && users[config.current_user] ? config.current_user : null;
1029
+ const currentUser = config.current_user && hasCurrentUserEntry(users, config.current_user) ? config.current_user : null;
875
1030
  return {
876
1031
  version: 1,
877
1032
  users,
@@ -879,15 +1034,29 @@ function toV1ForDisk(config) {
879
1034
  current_user: currentUser
880
1035
  };
881
1036
  }
1037
+ function hasProfilePlatformSettings(config) {
1038
+ return Object.values(config.profiles).some((profile) => profile?.platform_url !== void 0 || profile?.oauth2_client_id !== void 0 || profile?.console_url !== void 0);
1039
+ }
1040
+ function hasScopedUserKeys(config) {
1041
+ return Object.keys(config.users).some((userKey) => userKey.includes("|"));
1042
+ }
1043
+ function toLatestForDisk(config) {
1044
+ return {
1045
+ ...config.version === 1 ? migrateV1ToV2(config) : config,
1046
+ version: LATEST_CONFIG_VERSION,
1047
+ min_sdk_version: V3_MIN_SDK_VERSION
1048
+ };
1049
+ }
882
1050
  /**
883
1051
  * Write Tailor Platform CLI configuration to disk.
884
- * By default, V2 configs are converted to V1 for backward compatibility, so an
885
- * older SDK can still read the file. Configs containing a keyring user are kept
886
- * as V2 regardless, because the keyring storage variant is not representable in
887
- * V1 and downgrading it would silently drop the user's login. Such configs are
888
- * already V2 on disk (a keyring entry is only ever persisted with
889
- * TAILOR_USE_KEYRING set), so keeping V2 does not regress backward compatibility.
890
- * Set TAILOR_USE_KEYRING to write V2 format unconditionally.
1052
+ * By default, file-backed configs without newer fields are converted to V1 for
1053
+ * backward compatibility, so an older SDK can still read the file. Configs
1054
+ * containing a keyring user are kept in V2 or later because the keyring storage
1055
+ * variant is not representable in V1. Configs containing profile-level Platform
1056
+ * settings or platform-scoped user tokens are written in the latest
1057
+ * min-SDK-gated format because older SDKs would silently drop or misread those
1058
+ * settings.
1059
+ * Set TAILOR_USE_KEYRING to write the current in-memory format unconditionally.
891
1060
  *
892
1061
  * The config file may contain access/refresh tokens when the OS keyring is
893
1062
  * unavailable, so it is written via {@link writeSecretFile} so other users
@@ -896,8 +1065,8 @@ function toV1ForDisk(config) {
896
1065
  */
897
1066
  function writePlatformConfig(config) {
898
1067
  const configPath = platformConfigPath();
899
- const hasKeyringUser = config.version === 2 && Object.values(config.users).some((u) => u?.storage === "keyring");
900
- writeSecretFile(configPath, stringifyYAML(config.version === 2 && !process.env.TAILOR_USE_KEYRING && !hasKeyringUser ? toV1ForDisk(config) : config));
1068
+ const hasKeyringUser = config.version !== 1 && Object.values(config.users).some((u) => u?.storage === "keyring");
1069
+ writeSecretFile(configPath, stringifyYAML(hasProfilePlatformSettings(config) || hasScopedUserKeys(config) ? toLatestForDisk(config) : config.version !== 1 && !process.env.TAILOR_USE_KEYRING && !hasKeyringUser ? toV1ForDisk(config) : config));
901
1070
  }
902
1071
  const tcContextConfigSchema = z.object({
903
1072
  username: z.string().optional(),
@@ -954,9 +1123,9 @@ function validateUUID(value, source) {
954
1123
  * @returns Resolved workspace ID
955
1124
  */
956
1125
  async function loadWorkspaceId(opts) {
1126
+ const profile = opts?.profile || process.env.TAILOR_PLATFORM_PROFILE;
957
1127
  if (opts?.workspaceId) return validateUUID(opts.workspaceId, "--workspace-id option");
958
1128
  if (process.env.TAILOR_PLATFORM_WORKSPACE_ID) return validateUUID(process.env.TAILOR_PLATFORM_WORKSPACE_ID, "TAILOR_PLATFORM_WORKSPACE_ID environment variable");
959
- const profile = opts?.profile || process.env.TAILOR_PLATFORM_PROFILE;
960
1129
  if (profile) {
961
1130
  const wsId = (await readPlatformConfig()).profiles[profile]?.workspace_id;
962
1131
  if (!wsId) throw new Error(`Profile "${profile}" not found`);
@@ -1009,39 +1178,68 @@ async function loadMachineUserName(opts) {
1009
1178
  * @returns Resolved access token
1010
1179
  */
1011
1180
  async function loadAccessToken(opts) {
1012
- if (process.env.TAILOR_PLATFORM_TOKEN) return process.env.TAILOR_PLATFORM_TOKEN;
1013
- if (process.env.TAILOR_TOKEN) {
1014
- logger.warn("TAILOR_TOKEN is deprecated. Please use TAILOR_PLATFORM_TOKEN instead.");
1015
- return process.env.TAILOR_TOKEN;
1181
+ const profile = opts?.profile || process.env.TAILOR_PLATFORM_PROFILE;
1182
+ const envToken = process.env.TAILOR_PLATFORM_TOKEN ?? process.env.TAILOR_TOKEN;
1183
+ if (envToken && !process.env.TAILOR_PLATFORM_TOKEN) logger.warn("TAILOR_TOKEN is deprecated. Please use TAILOR_PLATFORM_TOKEN instead.");
1184
+ if (envToken) {
1185
+ rememberPlatformConfigForToken(envToken, await loadPlatformClientConfig({
1186
+ profile,
1187
+ allowMissingProfile: true
1188
+ }));
1189
+ return envToken;
1016
1190
  }
1017
1191
  const pfConfig = await readPlatformConfig();
1018
- let user;
1192
+ const profileEntry = profile ? pfConfig.profiles[profile] : void 0;
1193
+ if (profile && !profileEntry) throw new Error(`Profile "${profile}" not found`);
1194
+ const user = profileEntry?.user ?? pfConfig.current_user;
1195
+ if (!user) throw new Error(multiline`
1196
+ Tailor Platform token not found.
1197
+ Please specify token via TAILOR_PLATFORM_TOKEN environment variable or login using 'tailor-sdk login' command.
1198
+ `);
1199
+ return await fetchLatestToken(pfConfig, user, profileEntry ? platformConfigFromProfile(profileEntry) : void 0);
1200
+ }
1201
+ /**
1202
+ * Load platform connection settings from the active profile.
1203
+ * @param opts - Profile options
1204
+ * @returns Resolved platform connection settings, or undefined for the default environment
1205
+ */
1206
+ async function loadPlatformClientConfig(opts) {
1019
1207
  const profile = opts?.profile || process.env.TAILOR_PLATFORM_PROFILE;
1020
- if (profile) {
1021
- const u = pfConfig.profiles[profile]?.user;
1022
- if (!u) throw new Error(`Profile "${profile}" not found`);
1023
- user = u;
1024
- } else {
1025
- const u = pfConfig.current_user;
1026
- if (!u) throw new Error(multiline`
1027
- Tailor Platform token not found.
1028
- Please specify token via TAILOR_PLATFORM_TOKEN environment variable or login using 'tailor-sdk login' command.
1029
- `);
1030
- user = u;
1208
+ if (!profile) return;
1209
+ let pfConfig;
1210
+ try {
1211
+ pfConfig = await readPlatformConfig();
1212
+ } catch (error) {
1213
+ if (opts?.allowMissingProfile) return;
1214
+ throw error;
1215
+ }
1216
+ const profileEntry = pfConfig.profiles[profile];
1217
+ if (!profileEntry) {
1218
+ if (opts?.allowMissingProfile) return;
1219
+ throw new Error(`Profile "${profile}" not found`);
1031
1220
  }
1032
- return await fetchLatestToken(pfConfig, user);
1221
+ return platformConfigFromProfile(profileEntry);
1222
+ }
1223
+ /**
1224
+ * Load the Tailor Platform Console base URL from environment variables or the active profile.
1225
+ * @param opts - Profile options
1226
+ * @returns Resolved Console base URL
1227
+ */
1228
+ async function loadConsoleBaseUrl(opts) {
1229
+ return getConsoleBaseUrl(await loadPlatformClientConfig(opts));
1033
1230
  }
1034
1231
  /**
1035
1232
  * Resolve the actual token values for a user, reading from keyring or config as appropriate.
1036
1233
  * @param userEntry - User entry from the config
1037
1234
  * @param user - User identifier
1235
+ * @param label - User-facing identifier used in error messages
1038
1236
  * @returns Access token and optional refresh token
1039
1237
  */
1040
- async function resolveTokens(userEntry, user) {
1238
+ async function resolveTokens(userEntry, user, label = user) {
1041
1239
  if (userEntry.storage === "keyring") {
1042
1240
  const tokens = await loadKeyringTokens(user);
1043
1241
  if (!tokens) throw new Error(multiline`
1044
- Credentials not found in OS keyring for "${user}".
1242
+ Credentials not found in OS keyring for "${label}".
1045
1243
  Please run 'tailor-sdk login' and try again.
1046
1244
  `);
1047
1245
  return tokens;
@@ -1056,18 +1254,20 @@ async function resolveTokens(userEntry, user) {
1056
1254
  * @param config - Platform config
1057
1255
  * @param user - User identifier
1058
1256
  * @param tokens - Token data to save
1059
- * @param tokens.accessToken
1060
- * @param tokens.refreshToken
1257
+ * @param tokens.accessToken - Access token
1258
+ * @param tokens.refreshToken - Refresh token
1061
1259
  * @param expiresAt - Token expiration date
1260
+ * @param platformConfig - Optional platform connection settings
1062
1261
  */
1063
- async function saveUserTokens(config, user, tokens, expiresAt) {
1262
+ async function saveUserTokens(config, user, tokens, expiresAt, platformConfig) {
1263
+ const userKey = platformUserKey(user, platformConfig);
1064
1264
  if (process.env.TAILOR_USE_KEYRING && await isKeyringAvailable()) {
1065
- await saveKeyringTokens(user, tokens);
1066
- config.users[user] = {
1265
+ await saveKeyringTokens(userKey, tokens);
1266
+ config.users[userKey] = {
1067
1267
  token_expires_at: expiresAt,
1068
1268
  storage: "keyring"
1069
1269
  };
1070
- } else config.users[user] = {
1270
+ } else config.users[userKey] = {
1071
1271
  access_token: tokens.accessToken,
1072
1272
  refresh_token: tokens.refreshToken,
1073
1273
  token_expires_at: expiresAt,
@@ -1078,29 +1278,53 @@ async function saveUserTokens(config, user, tokens, expiresAt) {
1078
1278
  * Delete tokens for a user from keyring if applicable.
1079
1279
  * @param config - Platform config
1080
1280
  * @param user - User identifier
1281
+ * @param platformConfig - Optional platform connection settings
1282
+ * @param opts - Token lookup options
1081
1283
  */
1082
- async function deleteUserTokens(config, user) {
1083
- if (config.users[user]?.storage === "keyring") await deleteKeyringTokens(user);
1284
+ async function deleteUserTokens(config, user, platformConfig, opts) {
1285
+ const { userKey, userEntry } = findUserEntry(config, user, platformConfig, opts);
1286
+ if (userEntry?.storage === "keyring") await deleteKeyringTokens(userKey);
1287
+ delete config.users[userKey];
1288
+ }
1289
+ /**
1290
+ * Resolve stored tokens for a user on the selected platform.
1291
+ * @param config - Platform config
1292
+ * @param user - User name
1293
+ * @param platformConfig - Optional platform connection settings
1294
+ * @param opts - Token lookup options
1295
+ * @returns Stored user entry and token values, or undefined when the user is not logged in
1296
+ */
1297
+ async function loadStoredUserTokens(config, user, platformConfig, opts) {
1298
+ const { userKey, userEntry } = findUserEntry(config, user, platformConfig, opts);
1299
+ if (!userEntry) return void 0;
1300
+ return {
1301
+ userEntry,
1302
+ ...await resolveTokens(userEntry, userKey, user)
1303
+ };
1084
1304
  }
1085
1305
  /**
1086
1306
  * Fetch the latest access token, refreshing if necessary.
1087
1307
  * @param config - Platform config
1088
1308
  * @param user - User name
1309
+ * @param platformConfig - Optional platform connection settings
1089
1310
  * @returns Latest access token
1090
1311
  */
1091
- async function fetchLatestToken(config, user) {
1092
- const userEntry = config.users[user];
1312
+ async function fetchLatestToken(config, user, platformConfig) {
1313
+ const { userKey, userEntry } = findUserEntry(config, user, platformConfig);
1093
1314
  if (!userEntry) throw new Error(multiline`
1094
1315
  User "${user}" not found.
1095
1316
  Please verify your user name and login using 'tailor-sdk login' command.
1096
1317
  `);
1097
- const tokens = await resolveTokens(userEntry, user);
1098
- if (new Date(userEntry.token_expires_at) > /* @__PURE__ */ new Date()) return tokens.accessToken;
1318
+ const tokens = await resolveTokens(userEntry, userKey, user);
1319
+ if (new Date(userEntry.token_expires_at) > /* @__PURE__ */ new Date()) {
1320
+ rememberPlatformConfigForToken(tokens.accessToken, platformConfig);
1321
+ return tokens.accessToken;
1322
+ }
1099
1323
  if (!tokens.refreshToken) throw new Error(multiline`
1100
1324
  Token expired.
1101
1325
  Please run 'tailor-sdk login' and try again.
1102
1326
  `);
1103
- const client = initOAuth2Client();
1327
+ const client = initOAuth2Client(platformConfig);
1104
1328
  let resp;
1105
1329
  try {
1106
1330
  resp = await client.refreshToken({
@@ -1118,8 +1342,13 @@ async function fetchLatestToken(config, user) {
1118
1342
  await saveUserTokens(config, user, {
1119
1343
  accessToken: resp.accessToken,
1120
1344
  refreshToken: resp.refreshToken ?? void 0
1121
- }, newExpiresAt);
1345
+ }, newExpiresAt, platformConfig);
1346
+ if (userKey !== platformUserKey(user, platformConfig)) {
1347
+ if (userEntry.storage === "keyring") await deleteKeyringTokens(userKey);
1348
+ delete config.users[userKey];
1349
+ }
1122
1350
  writePlatformConfig(config);
1351
+ rememberPlatformConfigForToken(resp.accessToken, platformConfig);
1123
1352
  return resp.accessToken;
1124
1353
  }
1125
1354
  const DEFAULT_CONFIG_FILENAME = "tailor.config.ts";
@@ -4626,6 +4855,7 @@ const HttpAdapterConfigSchema = z.strictObject({
4626
4855
  //#region src/cli/services/http-adapter/bundler.ts
4627
4856
  const ADAPTER_BUNDLE_WARN_BYTES = 64 * 1024;
4628
4857
  const ADAPTER_BUNDLE_ERROR_BYTES = 256 * 1024;
4858
+ const GRAPHQL_WEB_MODULE = createRequire(import.meta.url).resolve("@0no-co/graphql.web");
4629
4859
  /**
4630
4860
  * Bundle each adapter's `input` (and `output`, if present) into a standalone
4631
4861
  * IIFE defining a global `transform(input)` entry point. `input` gets a
@@ -4673,7 +4903,7 @@ async function bundleAdapterScript(adapter, kind, outputDir, tsconfig, cache, bu
4673
4903
  tsconfig,
4674
4904
  inlineSourcemap: false,
4675
4905
  bundleLogLevel,
4676
- prefix: kind
4906
+ prefix: `${kind}:document-query-normalize-v1`
4677
4907
  });
4678
4908
  const code = await withCache({
4679
4909
  cache,
@@ -4684,8 +4914,6 @@ async function bundleAdapterScript(adapter, kind, outputDir, tsconfig, cache, bu
4684
4914
  async build(cachePlugins) {
4685
4915
  const entryPath = path.join(outputDir, `${adapter.name}.${kind}.entry.js`);
4686
4916
  const absoluteSourcePath = path.resolve(adapter.sourceFile);
4687
- const entryContent = kind === "input" ? buildInputEntry(absoluteSourcePath, adapter.methods) : buildOutputEntry(absoluteSourcePath);
4688
- fs$1.writeFileSync(entryPath, entryContent);
4689
4917
  const plugins = [
4690
4918
  {
4691
4919
  name: "http-adapter-reject-node-imports",
@@ -4712,6 +4940,8 @@ async function bundleAdapterScript(adapter, kind, outputDir, tsconfig, cache, bu
4712
4940
  ];
4713
4941
  let bundled;
4714
4942
  try {
4943
+ const entryContent = kind === "input" ? buildInputEntry(absoluteSourcePath, adapter.methods, GRAPHQL_WEB_MODULE) : buildOutputEntry(absoluteSourcePath);
4944
+ fs$1.writeFileSync(entryPath, entryContent);
4715
4945
  bundled = (await rolldown.build({
4716
4946
  input: entryPath,
4717
4947
  write: false,
@@ -4745,10 +4975,20 @@ async function bundleAdapterScript(adapter, kind, outputDir, tsconfig, cache, bu
4745
4975
  code
4746
4976
  ];
4747
4977
  }
4748
- function buildInputEntry(absoluteSourcePath, methods) {
4749
- const cases = methods.map((method) => ` case "${HTTP_METHODS[method]}": return __adapter.input.${method}(req);`).join("\n");
4978
+ function buildInputEntry(absoluteSourcePath, methods, graphqlPrinterModule) {
4979
+ const cases = methods.map((method) => {
4980
+ const expression = `__normalizeHttpAdapterGraphQLRequest(${`__adapter.input.${method}(req)`})`;
4981
+ return ` case "${HTTP_METHODS[method]}": return ${expression};`;
4982
+ }).join("\n");
4750
4983
  const supported = methods.map((m) => HTTP_METHODS[m]).join(", ");
4751
- return `import __adapter from ${JSON.stringify(absoluteSourcePath)};
4984
+ return `${`import { print as __printHttpAdapterDocument } from ${JSON.stringify(graphqlPrinterModule)};
4985
+ function __normalizeHttpAdapterGraphQLRequest(result) {
4986
+ if (!result || typeof result.query === "string") {
4987
+ return result;
4988
+ }
4989
+ return { ...result, query: __printHttpAdapterDocument(result.query) };
4990
+ }
4991
+ `}import __adapter from ${JSON.stringify(absoluteSourcePath)};
4752
4992
  globalThis.transform = function(req) {
4753
4993
  switch (req.method) {
4754
4994
  ${cases}
@@ -6188,5 +6428,5 @@ async function loadApplication(params) {
6188
6428
  }
6189
6429
 
6190
6430
  //#endregion
6191
- export { loadMachineUserName as A, fetchPlatformMachineUserToken as B, hashContent as C, fetchLatestToken as D, deleteUserTokens as E, writePlatformConfig as F, resolveStaticWebsiteUrls as G, initOAuth2Client as H, closeConnectionPool as I, byName as K, fetchAll as L, readPlatformConfig as M, resolveTokens as N, loadAccessToken as O, saveUserTokens as P, fetchMachineUserToken as R, getDistDir as S, loadConfig as T, initOperatorClient as U, fetchUserInfo as V, platformBaseUrl as W, createLogLevelTreeshakeOptions as _, WorkflowJobSchema as a, hasGenerationHooks as b, INVOKER_EXPR as c, assertUniqueLocalTailorDBTypeNames as d, assertUniqueTailorDBTypeNamesWithExternal as f, composeFunctionTreeshakeOptions as g, platformBundleDefinePlugin as h, resolveInlineSourcemap as i, loadWorkspaceId as j, loadConfigPath as k, buildExecutorArgsExpr as l, stringifyFunction as m, generatePluginFilesIfNeeded as n, ResolverSchema as o, TailorDBTypeSchema as p, loadApplication as r, HTTP_METHODS as s, defineApplication as t, buildResolverOperationHookExpr as u, resolveBundleLogLevel as v, hashFile as w, createBundleCache as x, getPluginGenerationDependencies as y, fetchPaged as z };
6192
- //# sourceMappingURL=application-Cr-limKC.mjs.map
6431
+ export { initOperatorClient as $, loadAccessToken as A, saveUserTokens as B, hashContent as C, fetchLatestToken as D, deleteUserTokens as E, loadStoredUserTokens as F, fetchMachineUserToken as G, closeConnectionPool as H, loadWorkspaceId as I, fetchUserInfo as J, fetchPaged as K, platformConfigFromProfile as L, loadConsoleBaseUrl as M, loadMachineUserName as N, hasAnyUserTokenEntry as O, loadPlatformClientConfig as P, initOAuth2Client as Q, readPlatformConfig as R, getDistDir as S, loadConfig as T, defaultPlatformBaseUrl as U, writePlatformConfig as V, fetchAll as W, getOAuth2ClientId as X, getConsoleBaseUrl as Y, getPlatformBaseUrl as Z, createLogLevelTreeshakeOptions as _, WorkflowJobSchema as a, hasGenerationHooks as b, INVOKER_EXPR as c, assertUniqueLocalTailorDBTypeNames as d, isDefaultPlatform as et, assertUniqueTailorDBTypeNamesWithExternal as f, composeFunctionTreeshakeOptions as g, platformBundleDefinePlugin as h, resolveInlineSourcemap as i, loadConfigPath as j, hasUserTokenEntry as k, buildExecutorArgsExpr as l, stringifyFunction as m, generatePluginFilesIfNeeded as n, byName as nt, ResolverSchema as o, TailorDBTypeSchema as p, fetchPlatformMachineUserToken as q, loadApplication as r, HTTP_METHODS as s, defineApplication as t, resolveStaticWebsiteUrls as tt, buildResolverOperationHookExpr as u, resolveBundleLogLevel as v, hashFile as w, createBundleCache as x, getPluginGenerationDependencies as y, resolveUserTokenKey as z };
6432
+ //# sourceMappingURL=application-Df5_I83n.mjs.map