@auth-gate/billing 0.9.0 → 0.9.1

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.
@@ -223,6 +223,41 @@ function normalizeConfig(config) {
223
223
  return __spreadProps(__spreadValues({}, config), { plans });
224
224
  }
225
225
 
226
+ // src/config-loader.ts
227
+ import { resolve } from "path";
228
+ import { existsSync } from "fs";
229
+ var CONFIG_FILENAMES = [
230
+ "authgate.billing.ts",
231
+ "authgate.billing.js",
232
+ "authgate.billing.mjs"
233
+ ];
234
+ async function loadConfig(cwd) {
235
+ let configPath = null;
236
+ for (const filename of CONFIG_FILENAMES) {
237
+ const candidate = resolve(cwd, filename);
238
+ if (existsSync(candidate)) {
239
+ configPath = candidate;
240
+ break;
241
+ }
242
+ }
243
+ if (!configPath) {
244
+ throw new Error(
245
+ `No billing config found. Expected one of: ${CONFIG_FILENAMES.join(", ")}
246
+ Run \`npx @auth-gate/billing init\` to create one.`
247
+ );
248
+ }
249
+ return loadConfigFromPath(configPath, cwd);
250
+ }
251
+ async function loadConfigFromPath(configPath, cwd) {
252
+ var _a, _b;
253
+ const { createJiti } = await import("jiti");
254
+ const jiti = createJiti(cwd != null ? cwd : process.cwd(), { interopDefault: true });
255
+ const mod = await jiti.import(configPath);
256
+ const raw = (_b = (_a = mod.default) != null ? _a : mod.billing) != null ? _b : mod;
257
+ const config = raw && typeof raw === "object" && "_config" in raw ? raw._config : raw;
258
+ return validateConfig(config);
259
+ }
260
+
226
261
  // src/diff.ts
227
262
  function deepEqual(a, b) {
228
263
  if (a === b) return true;
@@ -481,6 +516,8 @@ function renderConfigAsTypeScript(result) {
481
516
  export {
482
517
  validateConfig,
483
518
  normalizeConfig,
519
+ loadConfig,
520
+ loadConfigFromPath,
484
521
  priceConfigKey,
485
522
  computeDiff,
486
523
  slugify,
package/dist/cli.cjs CHANGED
@@ -312,7 +312,6 @@ var CONFIG_FILENAMES = [
312
312
  "authgate.billing.mjs"
313
313
  ];
314
314
  async function loadConfig(cwd) {
315
- var _a, _b;
316
315
  let configPath = null;
317
316
  for (const filename of CONFIG_FILENAMES) {
318
317
  const candidate = (0, import_path.resolve)(cwd, filename);
@@ -327,8 +326,12 @@ async function loadConfig(cwd) {
327
326
  Run \`npx @auth-gate/billing init\` to create one.`
328
327
  );
329
328
  }
329
+ return loadConfigFromPath(configPath, cwd);
330
+ }
331
+ async function loadConfigFromPath(configPath, cwd) {
332
+ var _a, _b;
330
333
  const { createJiti } = await import("jiti");
331
- const jiti = createJiti(cwd, { interopDefault: true });
334
+ const jiti = createJiti(cwd != null ? cwd : process.cwd(), { interopDefault: true });
332
335
  const mod = await jiti.import(configPath);
333
336
  const raw = (_b = (_a = mod.default) != null ? _a : mod.billing) != null ? _b : mod;
334
337
  const config = raw && typeof raw === "object" && "_config" in raw ? raw._config : raw;
@@ -977,10 +980,76 @@ function generateBillingConstants(config) {
977
980
  return lines.join("\n") + "\n";
978
981
  }
979
982
 
983
+ // src/project-config-loader.ts
984
+ var import_path2 = require("path");
985
+ var import_fs2 = require("fs");
986
+ var CONFIG_FILENAMES2 = [
987
+ "authgate.config.ts",
988
+ "authgate.config.js",
989
+ "authgate.config.mjs"
990
+ ];
991
+ var AUTO_ENV_FILES = [".env", ".env.local"];
992
+ async function resolveProjectConfig(cwd) {
993
+ var _a, _b, _c;
994
+ await autoLoadEnvFiles(cwd);
995
+ const config = await loadProjectConfigFile(cwd);
996
+ if (!config) {
997
+ return {
998
+ connection: {
999
+ baseUrl: process.env.AUTHGATE_BASE_URL,
1000
+ apiKey: process.env.AUTHGATE_API_KEY
1001
+ },
1002
+ rbacConfigPath: null,
1003
+ billingConfigPath: null
1004
+ };
1005
+ }
1006
+ const rawConnection = (_a = config.connection) != null ? _a : {};
1007
+ const connection = {
1008
+ baseUrl: (_b = rawConnection.baseUrl) != null ? _b : process.env.AUTHGATE_BASE_URL,
1009
+ apiKey: (_c = rawConnection.apiKey) != null ? _c : process.env.AUTHGATE_API_KEY
1010
+ };
1011
+ return {
1012
+ connection,
1013
+ rbacConfigPath: config.rbacConfig ? (0, import_path2.resolve)(cwd, config.rbacConfig) : null,
1014
+ billingConfigPath: config.billingConfig ? (0, import_path2.resolve)(cwd, config.billingConfig) : null
1015
+ };
1016
+ }
1017
+ async function loadProjectConfigFile(cwd) {
1018
+ var _a;
1019
+ let configPath = null;
1020
+ for (const filename of CONFIG_FILENAMES2) {
1021
+ const candidate = (0, import_path2.resolve)(cwd, filename);
1022
+ if ((0, import_fs2.existsSync)(candidate)) {
1023
+ configPath = candidate;
1024
+ break;
1025
+ }
1026
+ }
1027
+ if (!configPath) return null;
1028
+ const { createJiti } = await import("jiti");
1029
+ const jiti = createJiti(cwd, { interopDefault: true });
1030
+ const mod = await jiti.import(configPath);
1031
+ const config = (_a = mod.default) != null ? _a : mod;
1032
+ return config;
1033
+ }
1034
+ async function autoLoadEnvFiles(cwd) {
1035
+ let dotenv;
1036
+ try {
1037
+ dotenv = await import("dotenv");
1038
+ } catch (e) {
1039
+ return;
1040
+ }
1041
+ for (const file of AUTO_ENV_FILES) {
1042
+ const filePath = (0, import_path2.resolve)(cwd, file);
1043
+ if ((0, import_fs2.existsSync)(filePath)) {
1044
+ dotenv.config({ path: filePath });
1045
+ }
1046
+ }
1047
+ }
1048
+
980
1049
  // src/cli.ts
981
1050
  var import_chalk2 = __toESM(require("chalk"), 1);
982
- var import_fs2 = require("fs");
983
- var import_path2 = require("path");
1051
+ var import_fs3 = require("fs");
1052
+ var import_path3 = require("path");
984
1053
  var HELP = `
985
1054
  Usage: @auth-gate/billing <command> [options]
986
1055
 
@@ -1010,10 +1079,17 @@ Options (migrate):
1010
1079
  --batch-size Number of subscribers per batch (default: 100)
1011
1080
  --dry-run Preview migration without executing
1012
1081
 
1082
+ Options (init):
1083
+ --config Generate a starter authgate.config.ts instead
1084
+
1013
1085
  Global Options:
1014
1086
  --env <name> Target environment (default: production)
1015
1087
 
1016
- Environment:
1088
+ Config file:
1089
+ If authgate.config.ts exists, env vars and connection details are
1090
+ loaded from it automatically. See defineConfig() for the API.
1091
+
1092
+ Environment (when no authgate.config.ts):
1017
1093
  AUTHGATE_API_KEY Your project API key (required)
1018
1094
  AUTHGATE_BASE_URL AuthGate instance URL (required)
1019
1095
  AUTHGATE_ENV Default environment (overridden by --env)
@@ -1037,7 +1113,8 @@ async function main() {
1037
1113
  process.exit(0);
1038
1114
  }
1039
1115
  if (command === "init") {
1040
- await runInit();
1116
+ const configFlag = args.includes("--config");
1117
+ await runInit({ config: configFlag });
1041
1118
  return;
1042
1119
  }
1043
1120
  if (command === "generate") {
@@ -1115,8 +1192,8 @@ async function runGenerate(opts) {
1115
1192
  process.exit(1);
1116
1193
  }
1117
1194
  const output = generateBillingConstants(config);
1118
- const outPath = (_a = opts.outputPath) != null ? _a : (0, import_path2.resolve)(process.cwd(), "authgate.billing.generated.ts");
1119
- (0, import_fs2.writeFileSync)(outPath, output);
1195
+ const outPath = (_a = opts.outputPath) != null ? _a : (0, import_path3.resolve)(process.cwd(), "authgate.billing.generated.ts");
1196
+ (0, import_fs3.writeFileSync)(outPath, output);
1120
1197
  console.log(import_chalk2.default.green(`Generated ${outPath}`));
1121
1198
  const planCount = Object.keys(config.plans).length;
1122
1199
  const featureCount = config.features ? Object.keys(config.features).length : 0;
@@ -1136,11 +1213,11 @@ async function runPull(opts) {
1136
1213
  const { fetchStripeState: fetchStripeState2 } = await Promise.resolve().then(() => (init_pull_from_stripe(), pull_from_stripe_exports));
1137
1214
  state = await fetchStripeState2(stripeKey);
1138
1215
  } else {
1139
- const apiKey = process.env.AUTHGATE_API_KEY;
1140
- const baseUrl = process.env.AUTHGATE_BASE_URL;
1216
+ const projectConfig = await resolveProjectConfig(process.cwd());
1217
+ const { baseUrl, apiKey } = projectConfig.connection;
1141
1218
  if (!apiKey || !baseUrl) {
1142
1219
  console.error(
1143
- import_chalk2.default.red("AUTHGATE_API_KEY and AUTHGATE_BASE_URL required")
1220
+ import_chalk2.default.red("Missing API key or base URL. Set env vars or configure authgate.config.ts.")
1144
1221
  );
1145
1222
  process.exit(1);
1146
1223
  }
@@ -1160,8 +1237,8 @@ async function runPull(opts) {
1160
1237
  if (opts.dryRun) {
1161
1238
  console.log(output);
1162
1239
  } else {
1163
- const outPath = (_a = opts.outputPath) != null ? _a : (0, import_path2.resolve)(process.cwd(), "authgate.billing.ts");
1164
- (0, import_fs2.writeFileSync)(outPath, output);
1240
+ const outPath = (_a = opts.outputPath) != null ? _a : (0, import_path3.resolve)(process.cwd(), "authgate.billing.ts");
1241
+ (0, import_fs3.writeFileSync)(outPath, output);
1165
1242
  console.log(import_chalk2.default.green(`Created ${outPath}`));
1166
1243
  }
1167
1244
  console.log(
@@ -1170,8 +1247,28 @@ async function runPull(opts) {
1170
1247
  )
1171
1248
  );
1172
1249
  }
1173
- async function runInit() {
1174
- const configPath = (0, import_path2.resolve)(process.cwd(), "authgate.billing.ts");
1250
+ async function runInit(opts) {
1251
+ if (opts.config) {
1252
+ const configPath2 = (0, import_path3.resolve)(process.cwd(), "authgate.config.ts");
1253
+ if ((0, import_fs3.existsSync)(configPath2)) {
1254
+ console.error(import_chalk2.default.yellow(`Config file already exists: ${configPath2}`));
1255
+ process.exit(1);
1256
+ }
1257
+ const template2 = `import { defineConfig } from "@auth-gate/core";
1258
+
1259
+ export default defineConfig({
1260
+ connection: {
1261
+ baseUrl: process.env.AUTHGATE_URL,
1262
+ apiKey: process.env.AUTHGATE_API_KEY,
1263
+ },
1264
+ });
1265
+ `;
1266
+ (0, import_fs3.writeFileSync)(configPath2, template2, "utf-8");
1267
+ console.log(import_chalk2.default.green(`Created ${configPath2}`));
1268
+ console.log(import_chalk2.default.dim("Edit connection details, then run: npx @auth-gate/billing sync"));
1269
+ return;
1270
+ }
1271
+ const configPath = (0, import_path3.resolve)(process.cwd(), "authgate.billing.ts");
1175
1272
  const template = `import { defineBilling } from "@auth-gate/billing";
1176
1273
 
1177
1274
  /**
@@ -1203,26 +1300,31 @@ export const billing = defineBilling({
1203
1300
  // Default export for CLI compatibility
1204
1301
  export default billing;
1205
1302
  `;
1206
- (0, import_fs2.writeFileSync)(configPath, template, "utf-8");
1303
+ (0, import_fs3.writeFileSync)(configPath, template, "utf-8");
1207
1304
  console.log(import_chalk2.default.green(`Created ${configPath}`));
1208
1305
  console.log(import_chalk2.default.dim("Edit your plans, then run: npx @auth-gate/billing sync"));
1209
1306
  }
1210
1307
  async function runSync(opts) {
1211
1308
  var _a;
1212
- const apiKey = process.env.AUTHGATE_API_KEY;
1213
- const baseUrl = process.env.AUTHGATE_BASE_URL;
1309
+ const cwd = process.cwd();
1310
+ const projectConfig = await resolveProjectConfig(cwd);
1311
+ const { baseUrl, apiKey } = projectConfig.connection;
1214
1312
  if (!apiKey) {
1215
- console.error(import_chalk2.default.red("Missing AUTHGATE_API_KEY environment variable."));
1313
+ console.error(import_chalk2.default.red(
1314
+ "Missing API key. Set AUTHGATE_API_KEY or configure connection in authgate.config.ts."
1315
+ ));
1216
1316
  process.exit(1);
1217
1317
  }
1218
1318
  if (!baseUrl) {
1219
- console.error(import_chalk2.default.red("Missing AUTHGATE_BASE_URL environment variable."));
1319
+ console.error(import_chalk2.default.red(
1320
+ "Missing base URL. Set AUTHGATE_BASE_URL or configure connection in authgate.config.ts."
1321
+ ));
1220
1322
  process.exit(1);
1221
1323
  }
1222
1324
  const environment = resolveEnvironment({ env: opts.envFlag });
1223
1325
  let config;
1224
1326
  try {
1225
- config = await loadConfig(process.cwd());
1327
+ config = projectConfig.billingConfigPath ? await loadConfigFromPath(projectConfig.billingConfigPath, cwd) : await loadConfig(cwd);
1226
1328
  } catch (err) {
1227
1329
  console.error(import_chalk2.default.red(`Config error: ${err.message}`));
1228
1330
  process.exit(1);
@@ -1314,14 +1416,18 @@ async function runMigrate(opts) {
1314
1416
  console.error(import_chalk2.default.red("Usage: migrate --id <migrationId> OR migrate <from> <to>"));
1315
1417
  process.exit(1);
1316
1418
  }
1317
- const apiKey = process.env.AUTHGATE_API_KEY;
1318
- const baseUrl = process.env.AUTHGATE_BASE_URL;
1419
+ const projectConfig = await resolveProjectConfig(process.cwd());
1420
+ const { baseUrl, apiKey } = projectConfig.connection;
1319
1421
  if (!apiKey) {
1320
- console.error(import_chalk2.default.red("Missing AUTHGATE_API_KEY environment variable."));
1422
+ console.error(import_chalk2.default.red(
1423
+ "Missing API key. Set AUTHGATE_API_KEY or configure connection in authgate.config.ts."
1424
+ ));
1321
1425
  process.exit(1);
1322
1426
  }
1323
1427
  if (!baseUrl) {
1324
- console.error(import_chalk2.default.red("Missing AUTHGATE_BASE_URL environment variable."));
1428
+ console.error(import_chalk2.default.red(
1429
+ "Missing base URL. Set AUTHGATE_BASE_URL or configure connection in authgate.config.ts."
1430
+ ));
1325
1431
  process.exit(1);
1326
1432
  }
1327
1433
  const client = new SyncClient({ baseUrl, apiKey });
package/dist/cli.mjs CHANGED
@@ -1,44 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  computeDiff,
4
+ loadConfig,
5
+ loadConfigFromPath,
4
6
  renderConfigAsTypeScript,
5
- serverStateToBillingConfig,
6
- validateConfig
7
- } from "./chunk-VLL3I4K4.mjs";
7
+ serverStateToBillingConfig
8
+ } from "./chunk-LYL3W7NC.mjs";
8
9
  import "./chunk-I4E63NIC.mjs";
9
10
 
10
- // src/config-loader.ts
11
- import { resolve } from "path";
12
- import { existsSync } from "fs";
13
- var CONFIG_FILENAMES = [
14
- "authgate.billing.ts",
15
- "authgate.billing.js",
16
- "authgate.billing.mjs"
17
- ];
18
- async function loadConfig(cwd) {
19
- var _a, _b;
20
- let configPath = null;
21
- for (const filename of CONFIG_FILENAMES) {
22
- const candidate = resolve(cwd, filename);
23
- if (existsSync(candidate)) {
24
- configPath = candidate;
25
- break;
26
- }
27
- }
28
- if (!configPath) {
29
- throw new Error(
30
- `No billing config found. Expected one of: ${CONFIG_FILENAMES.join(", ")}
31
- Run \`npx @auth-gate/billing init\` to create one.`
32
- );
33
- }
34
- const { createJiti } = await import("jiti");
35
- const jiti = createJiti(cwd, { interopDefault: true });
36
- const mod = await jiti.import(configPath);
37
- const raw = (_b = (_a = mod.default) != null ? _a : mod.billing) != null ? _b : mod;
38
- const config = raw && typeof raw === "object" && "_config" in raw ? raw._config : raw;
39
- return validateConfig(config);
40
- }
41
-
42
11
  // src/formatter.ts
43
12
  import chalk from "chalk";
44
13
  function formatAmount(cents, currency) {
@@ -426,9 +395,75 @@ function generateBillingConstants(config) {
426
395
  return lines.join("\n") + "\n";
427
396
  }
428
397
 
398
+ // src/project-config-loader.ts
399
+ import { resolve } from "path";
400
+ import { existsSync } from "fs";
401
+ var CONFIG_FILENAMES = [
402
+ "authgate.config.ts",
403
+ "authgate.config.js",
404
+ "authgate.config.mjs"
405
+ ];
406
+ var AUTO_ENV_FILES = [".env", ".env.local"];
407
+ async function resolveProjectConfig(cwd) {
408
+ var _a, _b, _c;
409
+ await autoLoadEnvFiles(cwd);
410
+ const config = await loadProjectConfigFile(cwd);
411
+ if (!config) {
412
+ return {
413
+ connection: {
414
+ baseUrl: process.env.AUTHGATE_BASE_URL,
415
+ apiKey: process.env.AUTHGATE_API_KEY
416
+ },
417
+ rbacConfigPath: null,
418
+ billingConfigPath: null
419
+ };
420
+ }
421
+ const rawConnection = (_a = config.connection) != null ? _a : {};
422
+ const connection = {
423
+ baseUrl: (_b = rawConnection.baseUrl) != null ? _b : process.env.AUTHGATE_BASE_URL,
424
+ apiKey: (_c = rawConnection.apiKey) != null ? _c : process.env.AUTHGATE_API_KEY
425
+ };
426
+ return {
427
+ connection,
428
+ rbacConfigPath: config.rbacConfig ? resolve(cwd, config.rbacConfig) : null,
429
+ billingConfigPath: config.billingConfig ? resolve(cwd, config.billingConfig) : null
430
+ };
431
+ }
432
+ async function loadProjectConfigFile(cwd) {
433
+ var _a;
434
+ let configPath = null;
435
+ for (const filename of CONFIG_FILENAMES) {
436
+ const candidate = resolve(cwd, filename);
437
+ if (existsSync(candidate)) {
438
+ configPath = candidate;
439
+ break;
440
+ }
441
+ }
442
+ if (!configPath) return null;
443
+ const { createJiti } = await import("jiti");
444
+ const jiti = createJiti(cwd, { interopDefault: true });
445
+ const mod = await jiti.import(configPath);
446
+ const config = (_a = mod.default) != null ? _a : mod;
447
+ return config;
448
+ }
449
+ async function autoLoadEnvFiles(cwd) {
450
+ let dotenv;
451
+ try {
452
+ dotenv = await import("dotenv");
453
+ } catch (e) {
454
+ return;
455
+ }
456
+ for (const file of AUTO_ENV_FILES) {
457
+ const filePath = resolve(cwd, file);
458
+ if (existsSync(filePath)) {
459
+ dotenv.config({ path: filePath });
460
+ }
461
+ }
462
+ }
463
+
429
464
  // src/cli.ts
430
465
  import chalk2 from "chalk";
431
- import { writeFileSync } from "fs";
466
+ import { writeFileSync, existsSync as existsSync2 } from "fs";
432
467
  import { resolve as resolve2 } from "path";
433
468
  var HELP = `
434
469
  Usage: @auth-gate/billing <command> [options]
@@ -459,10 +494,17 @@ Options (migrate):
459
494
  --batch-size Number of subscribers per batch (default: 100)
460
495
  --dry-run Preview migration without executing
461
496
 
497
+ Options (init):
498
+ --config Generate a starter authgate.config.ts instead
499
+
462
500
  Global Options:
463
501
  --env <name> Target environment (default: production)
464
502
 
465
- Environment:
503
+ Config file:
504
+ If authgate.config.ts exists, env vars and connection details are
505
+ loaded from it automatically. See defineConfig() for the API.
506
+
507
+ Environment (when no authgate.config.ts):
466
508
  AUTHGATE_API_KEY Your project API key (required)
467
509
  AUTHGATE_BASE_URL AuthGate instance URL (required)
468
510
  AUTHGATE_ENV Default environment (overridden by --env)
@@ -486,7 +528,8 @@ async function main() {
486
528
  process.exit(0);
487
529
  }
488
530
  if (command === "init") {
489
- await runInit();
531
+ const configFlag = args.includes("--config");
532
+ await runInit({ config: configFlag });
490
533
  return;
491
534
  }
492
535
  if (command === "generate") {
@@ -585,11 +628,11 @@ async function runPull(opts) {
585
628
  const { fetchStripeState } = await import("./pull-from-stripe-AAY6MWMX.mjs");
586
629
  state = await fetchStripeState(stripeKey);
587
630
  } else {
588
- const apiKey = process.env.AUTHGATE_API_KEY;
589
- const baseUrl = process.env.AUTHGATE_BASE_URL;
631
+ const projectConfig = await resolveProjectConfig(process.cwd());
632
+ const { baseUrl, apiKey } = projectConfig.connection;
590
633
  if (!apiKey || !baseUrl) {
591
634
  console.error(
592
- chalk2.red("AUTHGATE_API_KEY and AUTHGATE_BASE_URL required")
635
+ chalk2.red("Missing API key or base URL. Set env vars or configure authgate.config.ts.")
593
636
  );
594
637
  process.exit(1);
595
638
  }
@@ -619,7 +662,27 @@ async function runPull(opts) {
619
662
  )
620
663
  );
621
664
  }
622
- async function runInit() {
665
+ async function runInit(opts) {
666
+ if (opts.config) {
667
+ const configPath2 = resolve2(process.cwd(), "authgate.config.ts");
668
+ if (existsSync2(configPath2)) {
669
+ console.error(chalk2.yellow(`Config file already exists: ${configPath2}`));
670
+ process.exit(1);
671
+ }
672
+ const template2 = `import { defineConfig } from "@auth-gate/core";
673
+
674
+ export default defineConfig({
675
+ connection: {
676
+ baseUrl: process.env.AUTHGATE_URL,
677
+ apiKey: process.env.AUTHGATE_API_KEY,
678
+ },
679
+ });
680
+ `;
681
+ writeFileSync(configPath2, template2, "utf-8");
682
+ console.log(chalk2.green(`Created ${configPath2}`));
683
+ console.log(chalk2.dim("Edit connection details, then run: npx @auth-gate/billing sync"));
684
+ return;
685
+ }
623
686
  const configPath = resolve2(process.cwd(), "authgate.billing.ts");
624
687
  const template = `import { defineBilling } from "@auth-gate/billing";
625
688
 
@@ -658,20 +721,25 @@ export default billing;
658
721
  }
659
722
  async function runSync(opts) {
660
723
  var _a;
661
- const apiKey = process.env.AUTHGATE_API_KEY;
662
- const baseUrl = process.env.AUTHGATE_BASE_URL;
724
+ const cwd = process.cwd();
725
+ const projectConfig = await resolveProjectConfig(cwd);
726
+ const { baseUrl, apiKey } = projectConfig.connection;
663
727
  if (!apiKey) {
664
- console.error(chalk2.red("Missing AUTHGATE_API_KEY environment variable."));
728
+ console.error(chalk2.red(
729
+ "Missing API key. Set AUTHGATE_API_KEY or configure connection in authgate.config.ts."
730
+ ));
665
731
  process.exit(1);
666
732
  }
667
733
  if (!baseUrl) {
668
- console.error(chalk2.red("Missing AUTHGATE_BASE_URL environment variable."));
734
+ console.error(chalk2.red(
735
+ "Missing base URL. Set AUTHGATE_BASE_URL or configure connection in authgate.config.ts."
736
+ ));
669
737
  process.exit(1);
670
738
  }
671
739
  const environment = resolveEnvironment({ env: opts.envFlag });
672
740
  let config;
673
741
  try {
674
- config = await loadConfig(process.cwd());
742
+ config = projectConfig.billingConfigPath ? await loadConfigFromPath(projectConfig.billingConfigPath, cwd) : await loadConfig(cwd);
675
743
  } catch (err) {
676
744
  console.error(chalk2.red(`Config error: ${err.message}`));
677
745
  process.exit(1);
@@ -763,14 +831,18 @@ async function runMigrate(opts) {
763
831
  console.error(chalk2.red("Usage: migrate --id <migrationId> OR migrate <from> <to>"));
764
832
  process.exit(1);
765
833
  }
766
- const apiKey = process.env.AUTHGATE_API_KEY;
767
- const baseUrl = process.env.AUTHGATE_BASE_URL;
834
+ const projectConfig = await resolveProjectConfig(process.cwd());
835
+ const { baseUrl, apiKey } = projectConfig.connection;
768
836
  if (!apiKey) {
769
- console.error(chalk2.red("Missing AUTHGATE_API_KEY environment variable."));
837
+ console.error(chalk2.red(
838
+ "Missing API key. Set AUTHGATE_API_KEY or configure connection in authgate.config.ts."
839
+ ));
770
840
  process.exit(1);
771
841
  }
772
842
  if (!baseUrl) {
773
- console.error(chalk2.red("Missing AUTHGATE_BASE_URL environment variable."));
843
+ console.error(chalk2.red(
844
+ "Missing base URL. Set AUTHGATE_BASE_URL or configure connection in authgate.config.ts."
845
+ ));
774
846
  process.exit(1);
775
847
  }
776
848
  const client = new SyncClient({ baseUrl, apiKey });
package/dist/index.cjs CHANGED
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __defProps = Object.defineProperties;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
6
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
6
7
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
8
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
+ var __getProtoOf = Object.getPrototypeOf;
8
10
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
11
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
12
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -32,6 +34,14 @@ var __copyProps = (to, from, except, desc) => {
32
34
  }
33
35
  return to;
34
36
  };
37
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
38
+ // If the importer is in node compatibility mode or this is not an ESM
39
+ // file that has been converted to a CommonJS file using a Babel-
40
+ // compatible transform (i.e. "__esModule" has not been set), then set
41
+ // "default" to the CommonJS "module.exports" for node compatibility.
42
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
43
+ mod
44
+ ));
35
45
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
36
46
 
37
47
  // src/index.ts
@@ -39,6 +49,8 @@ var index_exports = {};
39
49
  __export(index_exports, {
40
50
  computeDiff: () => computeDiff,
41
51
  defineBilling: () => defineBilling,
52
+ defineConfig: () => import_core.defineConfig,
53
+ loadConfigFromPath: () => loadConfigFromPath,
42
54
  normalizeConfig: () => normalizeConfig,
43
55
  priceConfigKey: () => priceConfigKey,
44
56
  renderConfigAsTypeScript: () => renderConfigAsTypeScript,
@@ -268,6 +280,17 @@ function normalizeConfig(config) {
268
280
  return __spreadProps(__spreadValues({}, config), { plans });
269
281
  }
270
282
 
283
+ // src/config-loader.ts
284
+ async function loadConfigFromPath(configPath, cwd) {
285
+ var _a, _b;
286
+ const { createJiti } = await import("jiti");
287
+ const jiti = createJiti(cwd != null ? cwd : process.cwd(), { interopDefault: true });
288
+ const mod = await jiti.import(configPath);
289
+ const raw = (_b = (_a = mod.default) != null ? _a : mod.billing) != null ? _b : mod;
290
+ const config = raw && typeof raw === "object" && "_config" in raw ? raw._config : raw;
291
+ return validateConfig(config);
292
+ }
293
+
271
294
  // src/diff.ts
272
295
  function deepEqual(a, b) {
273
296
  if (a === b) return true;
@@ -524,6 +547,7 @@ function renderConfigAsTypeScript(result) {
524
547
  }
525
548
 
526
549
  // src/index.ts
550
+ var import_core = require("@auth-gate/core");
527
551
  function defineBilling(config) {
528
552
  var _a;
529
553
  const plans = {};
@@ -555,6 +579,8 @@ function defineBilling(config) {
555
579
  0 && (module.exports = {
556
580
  computeDiff,
557
581
  defineBilling,
582
+ defineConfig,
583
+ loadConfigFromPath,
558
584
  normalizeConfig,
559
585
  priceConfigKey,
560
586
  renderConfigAsTypeScript,
package/dist/index.d.cts CHANGED
@@ -1,3 +1,5 @@
1
+ export { AuthGateConnection, AuthGateProjectConfig, defineConfig } from '@auth-gate/core';
2
+
1
3
  /** A tier definition for tiered/graduated pricing. */
2
4
  interface PriceTier {
3
5
  /** Upper bound of this tier (units). Use Infinity or omit for the last tier. */
@@ -184,6 +186,12 @@ declare function validateConfig(config: unknown): BillingConfig;
184
186
  */
185
187
  declare function normalizeConfig(config: BillingConfig): BillingConfig;
186
188
 
189
+ /**
190
+ * Load billing config from a specific file path.
191
+ * Used when `authgate.config.ts` specifies `billingConfig`.
192
+ */
193
+ declare function loadConfigFromPath(configPath: string, cwd?: string): Promise<BillingConfig>;
194
+
187
195
  interface ServerProduct {
188
196
  id: string;
189
197
  configKey: string | null;
@@ -299,4 +307,4 @@ declare function renderConfigAsTypeScript(result: PullResult): string;
299
307
  */
300
308
  declare function defineBilling<const T extends BillingConfig>(config: T): TypedBilling<T>;
301
309
 
302
- export { type BillingConfig, type BillingDefinition, type DiffResult, type EntitlementValue, type FeatureConfig, type FeatureKey, type GrandfatheringStrategy, type InferFeatureKeys, type InferMeteredFeatures, type InferPlanKeys, type MeteredPriceConfig, type PerSeatPriceConfig, type PlanConfig, type PlanKey, type PlanOp, type PriceConfig, type PriceOp, type PriceTier, type PullOptions, type PullResult, type RecurringPriceConfig, type ServerPrice, type ServerProduct, type ServerState, type TieredPriceConfig, type TypedBilling, computeDiff, defineBilling, normalizeConfig, priceConfigKey, renderConfigAsTypeScript, serverStateToBillingConfig, slugify, validateConfig };
310
+ export { type BillingConfig, type BillingDefinition, type DiffResult, type EntitlementValue, type FeatureConfig, type FeatureKey, type GrandfatheringStrategy, type InferFeatureKeys, type InferMeteredFeatures, type InferPlanKeys, type MeteredPriceConfig, type PerSeatPriceConfig, type PlanConfig, type PlanKey, type PlanOp, type PriceConfig, type PriceOp, type PriceTier, type PullOptions, type PullResult, type RecurringPriceConfig, type ServerPrice, type ServerProduct, type ServerState, type TieredPriceConfig, type TypedBilling, computeDiff, defineBilling, loadConfigFromPath, normalizeConfig, priceConfigKey, renderConfigAsTypeScript, serverStateToBillingConfig, slugify, validateConfig };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export { AuthGateConnection, AuthGateProjectConfig, defineConfig } from '@auth-gate/core';
2
+
1
3
  /** A tier definition for tiered/graduated pricing. */
2
4
  interface PriceTier {
3
5
  /** Upper bound of this tier (units). Use Infinity or omit for the last tier. */
@@ -184,6 +186,12 @@ declare function validateConfig(config: unknown): BillingConfig;
184
186
  */
185
187
  declare function normalizeConfig(config: BillingConfig): BillingConfig;
186
188
 
189
+ /**
190
+ * Load billing config from a specific file path.
191
+ * Used when `authgate.config.ts` specifies `billingConfig`.
192
+ */
193
+ declare function loadConfigFromPath(configPath: string, cwd?: string): Promise<BillingConfig>;
194
+
187
195
  interface ServerProduct {
188
196
  id: string;
189
197
  configKey: string | null;
@@ -299,4 +307,4 @@ declare function renderConfigAsTypeScript(result: PullResult): string;
299
307
  */
300
308
  declare function defineBilling<const T extends BillingConfig>(config: T): TypedBilling<T>;
301
309
 
302
- export { type BillingConfig, type BillingDefinition, type DiffResult, type EntitlementValue, type FeatureConfig, type FeatureKey, type GrandfatheringStrategy, type InferFeatureKeys, type InferMeteredFeatures, type InferPlanKeys, type MeteredPriceConfig, type PerSeatPriceConfig, type PlanConfig, type PlanKey, type PlanOp, type PriceConfig, type PriceOp, type PriceTier, type PullOptions, type PullResult, type RecurringPriceConfig, type ServerPrice, type ServerProduct, type ServerState, type TieredPriceConfig, type TypedBilling, computeDiff, defineBilling, normalizeConfig, priceConfigKey, renderConfigAsTypeScript, serverStateToBillingConfig, slugify, validateConfig };
310
+ export { type BillingConfig, type BillingDefinition, type DiffResult, type EntitlementValue, type FeatureConfig, type FeatureKey, type GrandfatheringStrategy, type InferFeatureKeys, type InferMeteredFeatures, type InferPlanKeys, type MeteredPriceConfig, type PerSeatPriceConfig, type PlanConfig, type PlanKey, type PlanOp, type PriceConfig, type PriceOp, type PriceTier, type PullOptions, type PullResult, type RecurringPriceConfig, type ServerPrice, type ServerProduct, type ServerState, type TieredPriceConfig, type TypedBilling, computeDiff, defineBilling, loadConfigFromPath, normalizeConfig, priceConfigKey, renderConfigAsTypeScript, serverStateToBillingConfig, slugify, validateConfig };
package/dist/index.mjs CHANGED
@@ -1,15 +1,17 @@
1
1
  import {
2
2
  computeDiff,
3
+ loadConfigFromPath,
3
4
  normalizeConfig,
4
5
  priceConfigKey,
5
6
  renderConfigAsTypeScript,
6
7
  serverStateToBillingConfig,
7
8
  slugify,
8
9
  validateConfig
9
- } from "./chunk-VLL3I4K4.mjs";
10
+ } from "./chunk-LYL3W7NC.mjs";
10
11
  import "./chunk-I4E63NIC.mjs";
11
12
 
12
13
  // src/index.ts
14
+ import { defineConfig } from "@auth-gate/core";
13
15
  function defineBilling(config) {
14
16
  var _a;
15
17
  const plans = {};
@@ -40,6 +42,8 @@ function defineBilling(config) {
40
42
  export {
41
43
  computeDiff,
42
44
  defineBilling,
45
+ defineConfig,
46
+ loadConfigFromPath,
43
47
  normalizeConfig,
44
48
  priceConfigKey,
45
49
  renderConfigAsTypeScript,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@auth-gate/billing",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -20,7 +20,9 @@
20
20
  ],
21
21
  "dependencies": {
22
22
  "chalk": "^5.4.0",
23
- "jiti": "^2.4.0"
23
+ "dotenv": "^17.2.4",
24
+ "jiti": "^2.4.0",
25
+ "@auth-gate/core": "0.9.1"
24
26
  },
25
27
  "peerDependencies": {
26
28
  "stripe": ">=14"