@onexapis/cli 1.1.63 → 1.1.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,8 +1,16 @@
1
+ /**
2
+ * CLI Auth Utilities
3
+ * Token storage, refresh, and API authentication for onexthm CLI.
4
+ */
5
+ /** Supported target environments. */
6
+ type Env = "dev" | "prod";
7
+
1
8
  interface InitOptions {
2
9
  template?: string;
3
10
  noInstall?: boolean;
4
11
  git?: boolean;
5
12
  yes?: boolean;
13
+ env?: Env;
6
14
  }
7
15
  declare function initCommand(projectName?: string, options?: InitOptions): Promise<void>;
8
16
 
@@ -72,41 +80,26 @@ interface DownloadOptions {
72
80
  themeId?: string;
73
81
  version?: string;
74
82
  output?: string;
83
+ env?: Env;
75
84
  /** @deprecated kept for backwards-compat with older scripts; ignored. */
76
85
  bucket?: string;
77
- /** @deprecated kept for backwards-compat with older scripts; ignored. */
78
- environment?: "staging" | "production";
79
86
  }
80
87
  /**
81
88
  * Download a published theme via the website-api Lambda endpoints.
82
- *
83
- * This command no longer talks to S3 directly — the platform now serves
84
- * theme content through HTTP-only endpoints, so AWS credentials, bucket
85
- * names, and region settings are no longer required. The legacy
86
- * `--bucket` and `--environment` flags are accepted but ignored for
87
- * backwards compatibility with existing scripts.
88
89
  */
89
90
  declare function downloadCommand(options: DownloadOptions): Promise<void>;
90
91
 
91
92
  interface CloneOptions {
92
93
  version?: string;
93
94
  output?: string;
95
+ env?: Env;
94
96
  /** @deprecated kept for backwards-compat with older scripts; ignored. */
95
97
  bucket?: string;
96
- /** @deprecated kept for backwards-compat with older scripts; ignored. */
97
- environment?: "staging" | "production";
98
98
  install?: boolean;
99
99
  name?: string;
100
100
  }
101
101
  /**
102
102
  * Clone theme source code via the website-api.
103
- *
104
- * Calls the authenticated `/source` Lambda to get a presigned S3 URL,
105
- * downloads the source.zip, and extracts it to a local directory. Asks
106
- * the user for a new theme name to differentiate from the original.
107
- *
108
- * Requires login (`onexthm login`) — the source endpoint is JWT-gated
109
- * because cloning grants access to a developer's full theme source.
110
103
  */
111
104
  declare function cloneCommand(themeName: string, options: CloneOptions): Promise<void>;
112
105
 
package/dist/index.d.ts CHANGED
@@ -1,8 +1,16 @@
1
+ /**
2
+ * CLI Auth Utilities
3
+ * Token storage, refresh, and API authentication for onexthm CLI.
4
+ */
5
+ /** Supported target environments. */
6
+ type Env = "dev" | "prod";
7
+
1
8
  interface InitOptions {
2
9
  template?: string;
3
10
  noInstall?: boolean;
4
11
  git?: boolean;
5
12
  yes?: boolean;
13
+ env?: Env;
6
14
  }
7
15
  declare function initCommand(projectName?: string, options?: InitOptions): Promise<void>;
8
16
 
@@ -72,41 +80,26 @@ interface DownloadOptions {
72
80
  themeId?: string;
73
81
  version?: string;
74
82
  output?: string;
83
+ env?: Env;
75
84
  /** @deprecated kept for backwards-compat with older scripts; ignored. */
76
85
  bucket?: string;
77
- /** @deprecated kept for backwards-compat with older scripts; ignored. */
78
- environment?: "staging" | "production";
79
86
  }
80
87
  /**
81
88
  * Download a published theme via the website-api Lambda endpoints.
82
- *
83
- * This command no longer talks to S3 directly — the platform now serves
84
- * theme content through HTTP-only endpoints, so AWS credentials, bucket
85
- * names, and region settings are no longer required. The legacy
86
- * `--bucket` and `--environment` flags are accepted but ignored for
87
- * backwards compatibility with existing scripts.
88
89
  */
89
90
  declare function downloadCommand(options: DownloadOptions): Promise<void>;
90
91
 
91
92
  interface CloneOptions {
92
93
  version?: string;
93
94
  output?: string;
95
+ env?: Env;
94
96
  /** @deprecated kept for backwards-compat with older scripts; ignored. */
95
97
  bucket?: string;
96
- /** @deprecated kept for backwards-compat with older scripts; ignored. */
97
- environment?: "staging" | "production";
98
98
  install?: boolean;
99
99
  name?: string;
100
100
  }
101
101
  /**
102
102
  * Clone theme source code via the website-api.
103
- *
104
- * Calls the authenticated `/source` Lambda to get a presigned S3 URL,
105
- * downloads the source.zip, and extracts it to a local directory. Asks
106
- * the user for a new theme name to differentiate from the original.
107
- *
108
- * Requires login (`onexthm login`) — the source endpoint is JWT-gated
109
- * because cloning grants access to a developer's full theme source.
110
103
  */
111
104
  declare function cloneCommand(themeName: string, options: CloneOptions): Promise<void>;
112
105
 
package/dist/index.js CHANGED
@@ -1586,21 +1586,43 @@ async function installDependencies(projectPath, packageManager = "npm") {
1586
1586
  });
1587
1587
  }
1588
1588
  var AUTH_DIR = path8__default.default.join(os__default.default.homedir(), ".onexthm");
1589
- var AUTH_FILE = path8__default.default.join(AUTH_DIR, "auth.json");
1590
- function getApiUrl() {
1591
- return process.env.ONEXTHM_API_URL || "https://platform-dev.onexeos.com";
1589
+ var ENV_URLS = {
1590
+ dev: "https://platform-dev.onexeos.com",
1591
+ prod: "https://platform-staging.onexeos.com"
1592
+ };
1593
+ function getAuthFile(env = "dev") {
1594
+ const newFile = path8__default.default.join(AUTH_DIR, `auth-${env}.json`);
1595
+ if (env === "dev") {
1596
+ const legacyFile = path8__default.default.join(AUTH_DIR, "auth.json");
1597
+ if (fs__default.default.existsSync(legacyFile) && !fs__default.default.existsSync(newFile)) {
1598
+ try {
1599
+ fs__default.default.moveSync(legacyFile, newFile);
1600
+ } catch {
1601
+ try {
1602
+ fs__default.default.copySync(legacyFile, newFile);
1603
+ fs__default.default.removeSync(legacyFile);
1604
+ } catch {
1605
+ }
1606
+ }
1607
+ }
1608
+ }
1609
+ return newFile;
1592
1610
  }
1593
- async function saveAuthTokens(tokens) {
1611
+ function getApiUrl(env = "dev") {
1612
+ return process.env.ONEXTHM_API_URL || ENV_URLS[env];
1613
+ }
1614
+ async function saveAuthTokens(tokens, env = "dev") {
1594
1615
  await fs__default.default.ensureDir(AUTH_DIR);
1595
1616
  const key = getMachineKey();
1596
1617
  const data = JSON.stringify(tokens);
1597
1618
  const encrypted = encrypt(data, key);
1598
- await fs__default.default.writeFile(AUTH_FILE, encrypted, "utf-8");
1619
+ await fs__default.default.writeFile(getAuthFile(env), encrypted, "utf-8");
1599
1620
  }
1600
- function loadAuthTokens() {
1621
+ function loadAuthTokens(env = "dev") {
1601
1622
  try {
1602
- if (!fs__default.default.existsSync(AUTH_FILE)) return null;
1603
- const encrypted = fs__default.default.readFileSync(AUTH_FILE, "utf-8");
1623
+ const file = getAuthFile(env);
1624
+ if (!fs__default.default.existsSync(file)) return null;
1625
+ const encrypted = fs__default.default.readFileSync(file, "utf-8");
1604
1626
  const key = getMachineKey();
1605
1627
  const data = decrypt(encrypted, key);
1606
1628
  return JSON.parse(data);
@@ -1608,34 +1630,34 @@ function loadAuthTokens() {
1608
1630
  return null;
1609
1631
  }
1610
1632
  }
1611
- async function clearAuthTokens() {
1633
+ async function clearAuthTokens(env = "dev") {
1612
1634
  try {
1613
- await fs__default.default.remove(AUTH_FILE);
1635
+ await fs__default.default.remove(getAuthFile(env));
1614
1636
  } catch {
1615
1637
  }
1616
1638
  }
1617
1639
  function isTokenExpired(tokens) {
1618
1640
  return Date.now() / 1e3 > tokens.expiresAt - 300;
1619
1641
  }
1620
- async function getValidTokens() {
1621
- const tokens = loadAuthTokens();
1642
+ async function getValidTokens(env = "dev") {
1643
+ const tokens = loadAuthTokens(env);
1622
1644
  if (!tokens) return null;
1623
1645
  if (!isTokenExpired(tokens)) return tokens;
1624
1646
  try {
1625
- const apiUrl = getApiUrl();
1647
+ const apiUrl = getApiUrl(env);
1626
1648
  const response = await fetch(`${apiUrl}/auth/refresh`, {
1627
1649
  method: "POST",
1628
1650
  headers: { "Content-Type": "application/json" },
1629
1651
  body: JSON.stringify({ refresh_token: tokens.refreshToken })
1630
1652
  });
1631
1653
  if (!response.ok) {
1632
- await clearAuthTokens();
1654
+ await clearAuthTokens(env);
1633
1655
  return null;
1634
1656
  }
1635
1657
  const data = await response.json();
1636
1658
  const body = data.statusCode ? data.body : data;
1637
1659
  if (!body.IdToken) {
1638
- await clearAuthTokens();
1660
+ await clearAuthTokens(env);
1639
1661
  return null;
1640
1662
  }
1641
1663
  const refreshed = {
@@ -1644,17 +1666,19 @@ async function getValidTokens() {
1644
1666
  idToken: body.IdToken,
1645
1667
  expiresAt: Math.floor(Date.now() / 1e3) + (body.ExpiresIn || 3600)
1646
1668
  };
1647
- await saveAuthTokens(refreshed);
1669
+ await saveAuthTokens(refreshed, env);
1648
1670
  return refreshed;
1649
1671
  } catch {
1650
- await clearAuthTokens();
1672
+ await clearAuthTokens(env);
1651
1673
  return null;
1652
1674
  }
1653
1675
  }
1654
- async function authenticatedFetch(url, init) {
1655
- const tokens = await getValidTokens();
1676
+ async function authenticatedFetch(url, init, env = "dev") {
1677
+ const tokens = await getValidTokens(env);
1656
1678
  if (!tokens) {
1657
- throw new Error("Not logged in. Run: onexthm login");
1679
+ throw new Error(
1680
+ `Not logged in to ${env} environment. Run: onexthm login --env ${env}`
1681
+ );
1658
1682
  }
1659
1683
  const headers = new Headers(init?.headers);
1660
1684
  headers.set("Authorization", `Bearer ${tokens.idToken}`);
@@ -1729,7 +1753,7 @@ async function initCommand(projectName, options = {}) {
1729
1753
  }
1730
1754
  if (!options.yes) {
1731
1755
  try {
1732
- const apiUrl = getApiUrl();
1756
+ const apiUrl = getApiUrl(options.env ?? "dev");
1733
1757
  const controller = new AbortController();
1734
1758
  const timeout = setTimeout(() => controller.abort(), 3e3);
1735
1759
  const response = await fetch(
@@ -3041,9 +3065,7 @@ function showDownloadFailureHelp(themeId, apiUrl) {
3041
3065
  console.log();
3042
3066
  console.log(chalk4__default.default.white("2. Check API URL configuration:"));
3043
3067
  console.log(chalk4__default.default.gray(` Current API URL: ${apiUrl}`));
3044
- console.log(
3045
- chalk4__default.default.gray(" Override with NEXT_PUBLIC_API_URL or ONEXTHM_API_URL")
3046
- );
3068
+ console.log(chalk4__default.default.gray(" Override with ONEXTHM_API_URL env var if needed"));
3047
3069
  console.log();
3048
3070
  console.log(chalk4__default.default.white("3. Pin a specific version (CI/production):"));
3049
3071
  console.log(
@@ -3053,15 +3075,17 @@ function showDownloadFailureHelp(themeId, apiUrl) {
3053
3075
  }
3054
3076
  async function downloadCommand(options) {
3055
3077
  exports.logger.header("Download Theme");
3078
+ const env = options.env ?? "dev";
3079
+ const apiUrl = getApiUrl(env);
3080
+ exports.logger.info(`Environment: ${env} (${apiUrl})`);
3056
3081
  const spinner = ora__default.default("Initializing download...").start();
3057
- if (options.bucket || options.environment) {
3082
+ if (options.bucket) {
3058
3083
  spinner.stop();
3059
3084
  exports.logger.warning(
3060
- "--bucket and --environment are deprecated and ignored. Themes are now served via HTTP from the website-api Lambda."
3085
+ "--bucket is deprecated and ignored. Themes are now served via HTTP from the website-api Lambda."
3061
3086
  );
3062
3087
  spinner.start();
3063
3088
  }
3064
- const apiUrl = getApiUrl();
3065
3089
  try {
3066
3090
  const themeId = options.themeId || process.env.NEXT_PUBLIC_THEME_ID || process.env.THEME_ID;
3067
3091
  const requestedVersion = options.version || process.env.THEME_VERSION || "latest";
@@ -3118,6 +3142,7 @@ async function downloadCommand(options) {
3118
3142
  console.log(
3119
3143
  chalk4__default.default.cyan(" Theme: ") + chalk4__default.default.white(`${themeId}@${resolvedVersion}`)
3120
3144
  );
3145
+ console.log(chalk4__default.default.cyan(" Env: ") + chalk4__default.default.white(env));
3121
3146
  console.log(chalk4__default.default.cyan(" Source: ") + chalk4__default.default.white(apiUrl));
3122
3147
  console.log(chalk4__default.default.cyan(" Output: ") + chalk4__default.default.white(outputDir));
3123
3148
  console.log(chalk4__default.default.cyan(" Files: ") + chalk4__default.default.white(entries.length));
@@ -3160,11 +3185,9 @@ async function resolveLatestVersion2(apiUrl, themeId) {
3160
3185
  }
3161
3186
  return latest;
3162
3187
  }
3163
- async function fetchSourceZip(apiUrl, themeId, version) {
3188
+ async function fetchSourceZip(apiUrl, themeId, version, env) {
3164
3189
  const url = `${apiUrl}/website-api/themes/${encodeURIComponent(themeId)}/source?version=${encodeURIComponent(version)}`;
3165
- const response = await authenticatedFetch(url, {
3166
- method: "GET"
3167
- });
3190
+ const response = await authenticatedFetch(url, { method: "GET" }, env);
3168
3191
  if (!response.ok) {
3169
3192
  if (response.status === 404) {
3170
3193
  throw new Error(
@@ -3173,7 +3196,7 @@ async function fetchSourceZip(apiUrl, themeId, version) {
3173
3196
  }
3174
3197
  if (response.status === 401 || response.status === 403) {
3175
3198
  throw new Error(
3176
- `Not authorized to download source for "${themeId}". Run \`onexthm login\` first.`
3199
+ `Not authorized to download source for "${themeId}". Run \`onexthm login --env ${env}\` first.`
3177
3200
  );
3178
3201
  }
3179
3202
  throw new Error(
@@ -3292,14 +3315,19 @@ async function renameTheme(themeDir, oldName, newName) {
3292
3315
  }
3293
3316
  async function cloneCommand(themeName, options) {
3294
3317
  exports.logger.header("Clone Theme Source");
3295
- if (options.bucket || options.environment) {
3318
+ const env = options.env ?? "dev";
3319
+ const apiUrl = getApiUrl(env);
3320
+ exports.logger.info(`Environment: ${env} (${apiUrl})`);
3321
+ if (options.bucket) {
3296
3322
  exports.logger.warning(
3297
- "--bucket and --environment are deprecated and ignored. Source is now fetched via HTTP from the website-api Lambda."
3323
+ "--bucket is deprecated and ignored. Source is now fetched via HTTP from the website-api Lambda."
3298
3324
  );
3299
3325
  }
3300
- const tokens = await getValidTokens();
3326
+ const tokens = await getValidTokens(env);
3301
3327
  if (!tokens) {
3302
- exports.logger.error("Not logged in. Run: onexthm login");
3328
+ exports.logger.error(
3329
+ `Not logged in to ${env} environment. Run: onexthm login --env ${env}`
3330
+ );
3303
3331
  process.exit(1);
3304
3332
  }
3305
3333
  let newName = options.name;
@@ -3308,7 +3336,6 @@ async function cloneCommand(themeName, options) {
3308
3336
  }
3309
3337
  const spinner = ora__default.default("Initializing clone...").start();
3310
3338
  try {
3311
- const apiUrl = getApiUrl();
3312
3339
  const outputDir = options.output || path8__default.default.resolve(process.cwd(), newName);
3313
3340
  if (await fs__default.default.pathExists(outputDir)) {
3314
3341
  spinner.fail(chalk4__default.default.red(`Directory already exists: ${outputDir}`));
@@ -3328,7 +3355,7 @@ async function cloneCommand(themeName, options) {
3328
3355
  spinner.start(`Downloading source.zip for ${themeName}@${version}...`);
3329
3356
  let zipBuffer;
3330
3357
  try {
3331
- zipBuffer = await fetchSourceZip(apiUrl, themeName, version);
3358
+ zipBuffer = await fetchSourceZip(apiUrl, themeName, version, env);
3332
3359
  } catch (error) {
3333
3360
  spinner.fail(chalk4__default.default.red(error.message));
3334
3361
  console.log();
@@ -3362,7 +3389,7 @@ async function cloneCommand(themeName, options) {
3362
3389
  [
3363
3390
  "# API Configuration (enables real data in preview)",
3364
3391
  "# Get your Company ID from the OneX dashboard",
3365
- "NEXT_PUBLIC_API_URL=https://platform-dev.onexeos.com",
3392
+ `NEXT_PUBLIC_API_URL=${apiUrl}`,
3366
3393
  "NEXT_PUBLIC_COMPANY_ID=",
3367
3394
  ""
3368
3395
  ].join("\n")
@@ -3415,6 +3442,7 @@ async function cloneCommand(themeName, options) {
3415
3442
  console.log(
3416
3443
  chalk4__default.default.cyan(" Source: ") + chalk4__default.default.gray(`${themeName}@${version}`)
3417
3444
  );
3445
+ console.log(chalk4__default.default.cyan(" Env: ") + chalk4__default.default.white(env));
3418
3446
  console.log(chalk4__default.default.cyan(" Theme: ") + chalk4__default.default.white(newName));
3419
3447
  console.log(chalk4__default.default.cyan(" Location: ") + chalk4__default.default.white(outputDir));
3420
3448
  console.log(chalk4__default.default.cyan(" Files: ") + chalk4__default.default.white(entries.length));