@docyrus/docyrus 0.0.10 → 0.0.12

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 (3) hide show
  1. package/main.js +126 -15
  2. package/main.js.map +2 -2
  3. package/package.json +1 -1
package/main.js CHANGED
@@ -63633,7 +63633,7 @@ function buildInputSchema(args, env, options) {
63633
63633
  // package.json
63634
63634
  var package_default = {
63635
63635
  name: "@docyrus/docyrus",
63636
- version: "0.0.10",
63636
+ version: "0.0.12",
63637
63637
  private: false,
63638
63638
  description: "Docyrus API CLI",
63639
63639
  main: "./main.js",
@@ -63854,10 +63854,11 @@ var DEFAULT_LOGIN_SCOPES = [
63854
63854
  "Docs.ReadWrite.All",
63855
63855
  "Architect.ReadWrite.All"
63856
63856
  ].join(" ");
63857
- var AUTH_DIR_PATH = (0, import_node_path3.join)((0, import_node_os3.homedir)(), ".docyrus");
63857
+ var DOCYRUS_SETTINGS_DIR_NAME = ".docyrus";
63858
+ var AUTH_DIR_PATH = (0, import_node_path3.join)((0, import_node_os3.homedir)(), DOCYRUS_SETTINGS_DIR_NAME);
63858
63859
  var AUTH_FILE_PATH = (0, import_node_path3.join)(AUTH_DIR_PATH, "auth.json");
63859
63860
  var CONFIG_FILE_PATH = (0, import_node_path3.join)(AUTH_DIR_PATH, "config.json");
63860
- var TENANT_OPENAPI_ROOT_PATH = (0, import_node_path3.join)((0, import_node_os3.homedir)(), "docyrus", "tenans");
63861
+ var TENANT_OPENAPI_ROOT_PATH = (0, import_node_path3.join)(AUTH_DIR_PATH, "tenans");
63861
63862
  var TENANT_OPENAPI_PUBLIC_URL_TEMPLATE = "https://api.docyrus.app/storage/v1/object/public/tenant-public/{tenantId}/openapi.json";
63862
63863
  var DEFAULT_ENVIRONMENT_ID = "live";
63863
63864
  var DEFAULT_ENVIRONMENTS = [
@@ -63886,6 +63887,41 @@ var TOKEN_EXPIRY_SKEW_MS = 6e4;
63886
63887
  var DEFAULT_DEVICE_POLL_INTERVAL_SECONDS = 5;
63887
63888
  var DEVICE_POLL_SLOW_DOWN_SECONDS = 5;
63888
63889
  var DEFAULT_DEVICE_CODE_EXPIRY_SECONDS = 600;
63890
+ function getLocalDocyrusSettingsRootPath(cwd = process.cwd()) {
63891
+ return (0, import_node_path3.join)(cwd, DOCYRUS_SETTINGS_DIR_NAME);
63892
+ }
63893
+ function toDocyrusSettingsPaths(rootPath, scope) {
63894
+ return {
63895
+ scope,
63896
+ rootPath,
63897
+ authFilePath: (0, import_node_path3.join)(rootPath, "auth.json"),
63898
+ configFilePath: (0, import_node_path3.join)(rootPath, "config.json"),
63899
+ tenantOpenApiRootPath: (0, import_node_path3.join)(rootPath, "tenans")
63900
+ };
63901
+ }
63902
+ function resolveDocyrusSettingsPaths(params) {
63903
+ const cwd = params?.cwd || process.cwd();
63904
+ const localRootPath = getLocalDocyrusSettingsRootPath(cwd);
63905
+ if (params?.forceGlobal) {
63906
+ return toDocyrusSettingsPaths(AUTH_DIR_PATH, "global");
63907
+ }
63908
+ return toDocyrusSettingsPaths(localRootPath, "local");
63909
+ }
63910
+ function extractGlobalFlagFromArgv(argv) {
63911
+ let forceGlobal = false;
63912
+ const sanitizedArgs = [];
63913
+ for (const value of argv) {
63914
+ if (value === "-g" || value === "--global") {
63915
+ forceGlobal = true;
63916
+ continue;
63917
+ }
63918
+ sanitizedArgs.push(value);
63919
+ }
63920
+ return {
63921
+ forceGlobal,
63922
+ argv: sanitizedArgs
63923
+ };
63924
+ }
63889
63925
  function getContextEnvValue(contextEnv, key) {
63890
63926
  if (typeof contextEnv === "object" && contextEnv !== null && key in contextEnv) {
63891
63927
  const value = contextEnv[key];
@@ -63984,26 +64020,44 @@ function createAuthCli(dependencies) {
63984
64020
  description: "Authorize CLI using OAuth2 device flow",
63985
64021
  options: external_exports.object({
63986
64022
  clientId: external_exports.string().optional().describe("OAuth2 client id"),
63987
- scope: external_exports.string().default(DEFAULT_LOGIN_SCOPES).describe("OAuth2 scopes")
64023
+ scope: external_exports.string().default(DEFAULT_LOGIN_SCOPES).describe("OAuth2 scopes"),
64024
+ accessToken: external_exports.string().optional().describe("Manual access token; skips device flow"),
64025
+ refreshToken: external_exports.string().optional().describe("Manual refresh token used with --accessToken")
63988
64026
  }),
63989
64027
  run: async (context) => {
63990
64028
  const apiBaseUrl = await dependencies.environmentConfigService.getActiveApiBaseUrl();
64029
+ const manualAccessToken = context.options.accessToken?.trim();
64030
+ const manualRefreshToken = context.options.refreshToken?.trim();
64031
+ if (manualRefreshToken && !manualAccessToken) {
64032
+ throw new UserInputError("refreshToken requires accessToken. Pass --accessToken when using --refreshToken.");
64033
+ }
64034
+ const envClientId = getOptionalEnvValue(context.env, "DOCYRUS_API_CLIENT_ID");
63991
64035
  const configuredClientId = await dependencies.environmentConfigService.getDefaultClientId();
63992
- const clientId = context.options.clientId || getOptionalEnvValue(context.env, "DOCYRUS_API_CLIENT_ID") || configuredClientId;
64036
+ const globalConfiguredClientId = configuredClientId ? void 0 : await dependencies.globalEnvironmentConfigService?.getDefaultClientId();
64037
+ const resolvedClientId = context.options.clientId || envClientId || configuredClientId || globalConfiguredClientId;
64038
+ const clientId = resolvedClientId || (manualAccessToken ? "manual-token" : void 0);
63993
64039
  if (!clientId) {
63994
64040
  throw new UserInputError(
63995
64041
  "Client ID is required. Pass --clientId, set DOCYRUS_API_CLIENT_ID, or login once with --clientId to save it."
63996
64042
  );
63997
64043
  }
63998
64044
  const authSessionService = dependencies.createAuthSessionService(apiBaseUrl);
63999
- const profile = await authSessionService.loginWithDeviceFlow({
64045
+ const profile = manualAccessToken ? await authSessionService.loginWithManualTokens({
64046
+ clientId,
64047
+ accessToken: manualAccessToken,
64048
+ refreshToken: manualRefreshToken || void 0,
64049
+ scope: context.options.scope,
64050
+ tokenType: "Bearer"
64051
+ }) : await authSessionService.loginWithDeviceFlow({
64000
64052
  clientId,
64001
64053
  scope: context.options.scope,
64002
64054
  onVerification: (verification) => {
64003
64055
  logVerificationHint(verification, context.agent, dependencies.onMessage);
64004
64056
  }
64005
64057
  });
64006
- await dependencies.environmentConfigService.setDefaultClientId(clientId);
64058
+ if (resolvedClientId) {
64059
+ await dependencies.environmentConfigService.setDefaultClientId(resolvedClientId);
64060
+ }
64007
64061
  return await injectContext({
64008
64062
  apiBaseUrl,
64009
64063
  authStore: dependencies.authStore,
@@ -66245,6 +66299,7 @@ var ApiClient = class {
66245
66299
  };
66246
66300
 
66247
66301
  // src/services/authSession.ts
66302
+ var DEFAULT_MANUAL_ACCESS_TOKEN_EXPIRY_SECONDS = 3600;
66248
66303
  function isRecord5(value) {
66249
66304
  return typeof value === "object" && value !== null;
66250
66305
  }
@@ -66286,6 +66341,22 @@ var AuthSessionService = class {
66286
66341
  onVerification: options.onVerification
66287
66342
  });
66288
66343
  }
66344
+ async loginWithManualTokens(options) {
66345
+ const expiresIn = this.#resolveManualAccessTokenExpiresIn(options.accessToken);
66346
+ const profile = await this.#buildProfileFromToken(
66347
+ options.clientId,
66348
+ {
66349
+ accessToken: options.accessToken,
66350
+ refreshToken: options.refreshToken,
66351
+ tokenType: options.tokenType || "Bearer",
66352
+ scope: options.scope,
66353
+ expiresIn
66354
+ },
66355
+ {}
66356
+ );
66357
+ await this.#persistProfile(profile);
66358
+ return profile;
66359
+ }
66289
66360
  async getValidAccessToken() {
66290
66361
  const activeProfile = await this.params.authStore.getActiveProfile(this.#apiBaseUrl);
66291
66362
  if (!activeProfile) {
@@ -66480,9 +66551,7 @@ var AuthSessionService = class {
66480
66551
  expectedUserId: options.expectedUserId,
66481
66552
  expectedTenantId: options.expectedTenantId
66482
66553
  });
66483
- await this.params.authStore.upsertProfile(profile);
66484
- await this.#refreshTenantCatalog(profile.userId, profile.accessToken, profile.tenantId);
66485
- await this.params.authStore.setActiveAccountTenant(this.#apiBaseUrl, profile.userId, profile.tenantId);
66554
+ await this.#persistProfile(profile);
66486
66555
  return profile;
66487
66556
  } catch (error48) {
66488
66557
  if (!(error48 instanceof ApiResponseError)) {
@@ -66621,6 +66690,11 @@ var AuthSessionService = class {
66621
66690
  lastUsedAt: nowIso
66622
66691
  });
66623
66692
  }
66693
+ async #persistProfile(profile) {
66694
+ await this.params.authStore.upsertProfile(profile);
66695
+ await this.#refreshTenantCatalog(profile.userId, profile.accessToken, profile.tenantId);
66696
+ await this.params.authStore.setActiveAccountTenant(this.#apiBaseUrl, profile.userId, profile.tenantId);
66697
+ }
66624
66698
  async #ensureProfileAccessToken(profile) {
66625
66699
  if (!this.#isExpired(profile.expiresAt)) {
66626
66700
  return profile;
@@ -66736,6 +66810,32 @@ var AuthSessionService = class {
66736
66810
  #now() {
66737
66811
  return this.params.now ? this.params.now() : Date.now();
66738
66812
  }
66813
+ #resolveManualAccessTokenExpiresIn(accessToken) {
66814
+ const token = accessToken.trim();
66815
+ if (!token) {
66816
+ return DEFAULT_MANUAL_ACCESS_TOKEN_EXPIRY_SECONDS;
66817
+ }
66818
+ const parts = token.split(".");
66819
+ if (parts.length < 2) {
66820
+ return DEFAULT_MANUAL_ACCESS_TOKEN_EXPIRY_SECONDS;
66821
+ }
66822
+ try {
66823
+ const payloadSegment = parts[1].replace(/-/g, "+").replace(/_/g, "/");
66824
+ const paddingLength = payloadSegment.length % 4;
66825
+ const paddedPayload = paddingLength === 0 ? payloadSegment : payloadSegment.padEnd(payloadSegment.length + (4 - paddingLength), "=");
66826
+ const decodedPayload = Buffer.from(paddedPayload, "base64").toString("utf8");
66827
+ const parsedPayload = JSON.parse(decodedPayload);
66828
+ if (typeof parsedPayload.exp === "number" && Number.isFinite(parsedPayload.exp)) {
66829
+ const remainingSeconds = Math.floor(parsedPayload.exp - this.#now() / 1e3);
66830
+ if (remainingSeconds > 0) {
66831
+ return remainingSeconds;
66832
+ }
66833
+ }
66834
+ } catch {
66835
+ return DEFAULT_MANUAL_ACCESS_TOKEN_EXPIRY_SECONDS;
66836
+ }
66837
+ return DEFAULT_MANUAL_ACCESS_TOKEN_EXPIRY_SECONDS;
66838
+ }
66739
66839
  };
66740
66840
 
66741
66841
  // src/services/authStore.ts
@@ -67295,6 +67395,7 @@ var TenantOpenApiService = class {
67295
67395
 
67296
67396
  // src/main.ts
67297
67397
  var ROOT_HELP_COMMANDS = [
67398
+ { command: "docyrus -g <command>", description: "Force use of global ~/.docyrus settings for this run" },
67298
67399
  { command: "env", description: "Show active environment and list environments" },
67299
67400
  { command: "env use <id|name>", description: "Switch active environment" },
67300
67401
  { command: "auth login", description: "Authenticate with OAuth2 device flow" },
@@ -67313,11 +67414,17 @@ var ROOT_HELP_COMMANDS = [
67313
67414
  { command: "curl <path>", description: "Send arbitrary API requests" }
67314
67415
  ];
67315
67416
  function createDocyrusCli(params) {
67316
- const authStore = params?.authStore ?? new AuthStore();
67317
- const environmentConfigService = params?.environmentConfigService ?? new EnvironmentConfigService();
67417
+ const settingsPaths = resolveDocyrusSettingsPaths({
67418
+ forceGlobal: params?.forceGlobalSettings,
67419
+ cwd: params?.cwd
67420
+ });
67421
+ const authStore = params?.authStore ?? new AuthStore(settingsPaths.authFilePath);
67422
+ const environmentConfigService = params?.environmentConfigService ?? new EnvironmentConfigService(settingsPaths.configFilePath);
67423
+ const globalEnvironmentConfigService = new EnvironmentConfigService(CONFIG_FILE_PATH);
67318
67424
  const includeTui = params?.includeTui !== false;
67319
67425
  const tenantOpenApiService = new TenantOpenApiService({
67320
- fetchFn: params?.fetchFn
67426
+ fetchFn: params?.fetchFn,
67427
+ rootPath: settingsPaths.tenantOpenApiRootPath
67321
67428
  });
67322
67429
  const createAuthSessionService = (apiBaseUrl) => {
67323
67430
  return new AuthSessionService({
@@ -67361,6 +67468,7 @@ function createDocyrusCli(params) {
67361
67468
  createApiClient,
67362
67469
  createAuthSessionService,
67363
67470
  environmentConfigService,
67471
+ globalEnvironmentConfigService,
67364
67472
  onMessage: params?.onAuthMessage,
67365
67473
  authStore
67366
67474
  }));
@@ -67396,8 +67504,11 @@ function createDocyrusCli(params) {
67396
67504
  }));
67397
67505
  return cli2;
67398
67506
  }
67399
- var cli = createDocyrusCli();
67400
- cli.serve();
67507
+ var runtimeArgs = extractGlobalFlagFromArgv(process.argv.slice(2));
67508
+ var cli = createDocyrusCli({
67509
+ forceGlobalSettings: runtimeArgs.forceGlobal
67510
+ });
67511
+ cli.serve(runtimeArgs.argv);
67401
67512
  var main_default = cli;
67402
67513
  // Annotate the CommonJS export names for ESM import in node:
67403
67514
  0 && (module.exports = {