@insforge/cli 0.1.86 → 0.1.88-razorpay.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.
- package/README.md +424 -46
- package/dist/index.js +1555 -376
- package/package.json +4 -3
- package/dist/index.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -263,10 +263,11 @@ import * as clack4 from "@clack/prompts";
|
|
|
263
263
|
|
|
264
264
|
// src/lib/errors.ts
|
|
265
265
|
var CLIError = class extends Error {
|
|
266
|
-
constructor(message, exitCode = 1, code) {
|
|
266
|
+
constructor(message, exitCode = 1, code, statusCode) {
|
|
267
267
|
super(message);
|
|
268
268
|
this.exitCode = exitCode;
|
|
269
269
|
this.code = code;
|
|
270
|
+
this.statusCode = statusCode;
|
|
270
271
|
this.name = "CLIError";
|
|
271
272
|
}
|
|
272
273
|
};
|
|
@@ -1172,7 +1173,7 @@ import * as clack5 from "@clack/prompts";
|
|
|
1172
1173
|
|
|
1173
1174
|
// src/lib/analytics.ts
|
|
1174
1175
|
import { PostHog } from "posthog-node";
|
|
1175
|
-
var POSTHOG_API_KEY = "
|
|
1176
|
+
var POSTHOG_API_KEY = "";
|
|
1176
1177
|
var POSTHOG_HOST = process.env.POSTHOG_HOST || "https://us.i.posthog.com";
|
|
1177
1178
|
var client = null;
|
|
1178
1179
|
function getClient() {
|
|
@@ -2066,7 +2067,7 @@ ${err.nextActions}`;
|
|
|
2066
2067
|
if (res.status === 404 && isRouteLevel404 && path6.startsWith("/api/ai")) {
|
|
2067
2068
|
message = "AI Model Gateway setup is not available on this backend.\nUpgrade your InsForge project to a version with Model Gateway support, or keep using the legacy @insforge/sdk AI modules for projects that still rely on the older AI API surface.";
|
|
2068
2069
|
}
|
|
2069
|
-
throw new CLIError(message);
|
|
2070
|
+
throw new CLIError(message, 1, err.error, res.status);
|
|
2070
2071
|
}
|
|
2071
2072
|
return res;
|
|
2072
2073
|
}
|
|
@@ -7188,7 +7189,7 @@ function registerDiagnoseCommands(diagnoseCmd2) {
|
|
|
7188
7189
|
const s = !json ? clack16.spinner() : null;
|
|
7189
7190
|
s?.start("Collecting diagnostic data...");
|
|
7190
7191
|
const data2 = await collectDiagnosticData(projectId, ossMode, apiUrl);
|
|
7191
|
-
const cliVersion = "0.1.
|
|
7192
|
+
const cliVersion = "0.1.88-razorpay.0";
|
|
7192
7193
|
s?.stop("Data collected");
|
|
7193
7194
|
if (!json) {
|
|
7194
7195
|
console.log(`
|
|
@@ -7427,75 +7428,142 @@ function withQuery(path6, params) {
|
|
|
7427
7428
|
async function readJson(res) {
|
|
7428
7429
|
return await res.json();
|
|
7429
7430
|
}
|
|
7430
|
-
function
|
|
7431
|
-
return `/api/payments/${encodeURIComponent(
|
|
7431
|
+
function withProviderPath(provider, suffix) {
|
|
7432
|
+
return `/api/payments/${encodeURIComponent(provider)}${suffix}`;
|
|
7433
|
+
}
|
|
7434
|
+
function withProviderEnvironmentPath(provider, environment, suffix) {
|
|
7435
|
+
return withProviderPath(
|
|
7436
|
+
provider,
|
|
7437
|
+
`/${encodeURIComponent(environment)}${suffix}`
|
|
7438
|
+
);
|
|
7439
|
+
}
|
|
7440
|
+
async function getStripePaymentsStatus() {
|
|
7441
|
+
return readJson(await ossFetch(withProviderPath("stripe", "/status")));
|
|
7432
7442
|
}
|
|
7433
|
-
async function
|
|
7434
|
-
return readJson(await ossFetch("/
|
|
7443
|
+
async function getRazorpayPaymentsStatus() {
|
|
7444
|
+
return readJson(await ossFetch(withProviderPath("razorpay", "/status")));
|
|
7435
7445
|
}
|
|
7436
|
-
async function
|
|
7437
|
-
return readJson(await ossFetch("/
|
|
7446
|
+
async function getStripePaymentsConfig() {
|
|
7447
|
+
return readJson(await ossFetch(withProviderPath("stripe", "/config")));
|
|
7448
|
+
}
|
|
7449
|
+
async function getRazorpayPaymentsConfig() {
|
|
7450
|
+
return readJson(await ossFetch(withProviderPath("razorpay", "/config")));
|
|
7438
7451
|
}
|
|
7439
7452
|
async function setStripeSecretKey(environment, secretKey) {
|
|
7453
|
+
const request = { secretKey };
|
|
7440
7454
|
return readJson(
|
|
7441
|
-
await ossFetch(
|
|
7442
|
-
|
|
7443
|
-
|
|
7444
|
-
|
|
7455
|
+
await ossFetch(
|
|
7456
|
+
withProviderEnvironmentPath("stripe", environment, "/config"),
|
|
7457
|
+
{
|
|
7458
|
+
method: "PUT",
|
|
7459
|
+
body: JSON.stringify(request)
|
|
7460
|
+
}
|
|
7461
|
+
)
|
|
7462
|
+
);
|
|
7463
|
+
}
|
|
7464
|
+
async function setRazorpayKeys(environment, request) {
|
|
7465
|
+
return readJson(
|
|
7466
|
+
await ossFetch(
|
|
7467
|
+
withProviderEnvironmentPath("razorpay", environment, "/config"),
|
|
7468
|
+
{
|
|
7469
|
+
method: "PUT",
|
|
7470
|
+
body: JSON.stringify(request)
|
|
7471
|
+
}
|
|
7472
|
+
)
|
|
7445
7473
|
);
|
|
7446
7474
|
}
|
|
7447
7475
|
async function removeStripeSecretKey(environment) {
|
|
7448
7476
|
return readJson(
|
|
7449
|
-
await ossFetch(
|
|
7450
|
-
|
|
7451
|
-
|
|
7477
|
+
await ossFetch(
|
|
7478
|
+
withProviderEnvironmentPath("stripe", environment, "/config"),
|
|
7479
|
+
{
|
|
7480
|
+
method: "DELETE"
|
|
7481
|
+
}
|
|
7482
|
+
)
|
|
7483
|
+
);
|
|
7484
|
+
}
|
|
7485
|
+
async function removeRazorpayKeys(environment) {
|
|
7486
|
+
return readJson(
|
|
7487
|
+
await ossFetch(
|
|
7488
|
+
withProviderEnvironmentPath("razorpay", environment, "/config"),
|
|
7489
|
+
{ method: "DELETE" }
|
|
7490
|
+
)
|
|
7491
|
+
);
|
|
7492
|
+
}
|
|
7493
|
+
async function syncStripePayments(environment = "all") {
|
|
7494
|
+
return readJson(
|
|
7495
|
+
await ossFetch(
|
|
7496
|
+
environment === "all" ? withProviderPath("stripe", "/sync") : withProviderEnvironmentPath("stripe", environment, "/sync"),
|
|
7497
|
+
{ method: "POST" }
|
|
7498
|
+
)
|
|
7452
7499
|
);
|
|
7453
7500
|
}
|
|
7454
|
-
async function
|
|
7501
|
+
async function syncRazorpayPayments(environment = "all") {
|
|
7455
7502
|
return readJson(
|
|
7456
7503
|
await ossFetch(
|
|
7457
|
-
environment === "all" ? "/
|
|
7504
|
+
environment === "all" ? withProviderPath("razorpay", "/sync") : withProviderEnvironmentPath("razorpay", environment, "/sync"),
|
|
7458
7505
|
{ method: "POST" }
|
|
7459
7506
|
)
|
|
7460
7507
|
);
|
|
7461
7508
|
}
|
|
7462
|
-
async function
|
|
7509
|
+
async function configureStripeWebhook(environment) {
|
|
7510
|
+
return readJson(
|
|
7511
|
+
await ossFetch(
|
|
7512
|
+
withProviderEnvironmentPath("stripe", environment, "/webhook"),
|
|
7513
|
+
{
|
|
7514
|
+
method: "POST"
|
|
7515
|
+
}
|
|
7516
|
+
)
|
|
7517
|
+
);
|
|
7518
|
+
}
|
|
7519
|
+
async function listStripeCatalog(environment) {
|
|
7463
7520
|
return readJson(
|
|
7464
|
-
await ossFetch(
|
|
7465
|
-
|
|
7466
|
-
|
|
7521
|
+
await ossFetch(
|
|
7522
|
+
withProviderEnvironmentPath("stripe", environment, "/catalog")
|
|
7523
|
+
)
|
|
7467
7524
|
);
|
|
7468
7525
|
}
|
|
7469
|
-
async function
|
|
7470
|
-
return readJson(
|
|
7526
|
+
async function listRazorpayCatalog(environment) {
|
|
7527
|
+
return readJson(
|
|
7528
|
+
await ossFetch(
|
|
7529
|
+
withProviderEnvironmentPath("razorpay", environment, "/catalog")
|
|
7530
|
+
)
|
|
7531
|
+
);
|
|
7471
7532
|
}
|
|
7472
|
-
async function
|
|
7533
|
+
async function listStripeProducts(environment) {
|
|
7473
7534
|
return readJson(
|
|
7474
|
-
await ossFetch(
|
|
7535
|
+
await ossFetch(
|
|
7536
|
+
withProviderEnvironmentPath("stripe", environment, "/catalog/products")
|
|
7537
|
+
)
|
|
7475
7538
|
);
|
|
7476
7539
|
}
|
|
7477
|
-
async function
|
|
7540
|
+
async function getStripeProduct(environment, productId) {
|
|
7478
7541
|
return readJson(
|
|
7479
7542
|
await ossFetch(
|
|
7480
|
-
|
|
7543
|
+
withProviderEnvironmentPath(
|
|
7544
|
+
"stripe",
|
|
7481
7545
|
environment,
|
|
7482
7546
|
`/catalog/products/${encodeURIComponent(productId)}`
|
|
7483
7547
|
)
|
|
7484
7548
|
)
|
|
7485
7549
|
);
|
|
7486
7550
|
}
|
|
7487
|
-
async function
|
|
7551
|
+
async function createStripeProduct(environment, request) {
|
|
7488
7552
|
return readJson(
|
|
7489
|
-
await ossFetch(
|
|
7490
|
-
|
|
7491
|
-
|
|
7492
|
-
|
|
7553
|
+
await ossFetch(
|
|
7554
|
+
withProviderEnvironmentPath("stripe", environment, "/catalog/products"),
|
|
7555
|
+
{
|
|
7556
|
+
method: "POST",
|
|
7557
|
+
body: JSON.stringify(request)
|
|
7558
|
+
}
|
|
7559
|
+
)
|
|
7493
7560
|
);
|
|
7494
7561
|
}
|
|
7495
|
-
async function
|
|
7562
|
+
async function updateStripeProduct(environment, productId, request) {
|
|
7496
7563
|
return readJson(
|
|
7497
7564
|
await ossFetch(
|
|
7498
|
-
|
|
7565
|
+
withProviderEnvironmentPath(
|
|
7566
|
+
"stripe",
|
|
7499
7567
|
environment,
|
|
7500
7568
|
`/catalog/products/${encodeURIComponent(productId)}`
|
|
7501
7569
|
),
|
|
@@ -7506,10 +7574,11 @@ async function updatePaymentProduct(environment, productId, request) {
|
|
|
7506
7574
|
)
|
|
7507
7575
|
);
|
|
7508
7576
|
}
|
|
7509
|
-
async function
|
|
7577
|
+
async function deleteStripeProduct(environment, productId) {
|
|
7510
7578
|
return readJson(
|
|
7511
7579
|
await ossFetch(
|
|
7512
|
-
|
|
7580
|
+
withProviderEnvironmentPath(
|
|
7581
|
+
"stripe",
|
|
7513
7582
|
environment,
|
|
7514
7583
|
`/catalog/products/${encodeURIComponent(productId)}`
|
|
7515
7584
|
),
|
|
@@ -7517,37 +7586,43 @@ async function deletePaymentProduct(environment, productId) {
|
|
|
7517
7586
|
)
|
|
7518
7587
|
);
|
|
7519
7588
|
}
|
|
7520
|
-
async function
|
|
7589
|
+
async function listStripePrices(environment, productId) {
|
|
7521
7590
|
return readJson(
|
|
7522
7591
|
await ossFetch(
|
|
7523
|
-
withQuery(
|
|
7524
|
-
|
|
7525
|
-
|
|
7592
|
+
withQuery(
|
|
7593
|
+
withProviderEnvironmentPath("stripe", environment, "/catalog/prices"),
|
|
7594
|
+
{ productId }
|
|
7595
|
+
)
|
|
7526
7596
|
)
|
|
7527
7597
|
);
|
|
7528
7598
|
}
|
|
7529
|
-
async function
|
|
7599
|
+
async function getStripePrice(environment, priceId) {
|
|
7530
7600
|
return readJson(
|
|
7531
7601
|
await ossFetch(
|
|
7532
|
-
|
|
7602
|
+
withProviderEnvironmentPath(
|
|
7603
|
+
"stripe",
|
|
7533
7604
|
environment,
|
|
7534
7605
|
`/catalog/prices/${encodeURIComponent(priceId)}`
|
|
7535
7606
|
)
|
|
7536
7607
|
)
|
|
7537
7608
|
);
|
|
7538
7609
|
}
|
|
7539
|
-
async function
|
|
7610
|
+
async function createStripePrice(environment, request) {
|
|
7540
7611
|
return readJson(
|
|
7541
|
-
await ossFetch(
|
|
7542
|
-
|
|
7543
|
-
|
|
7544
|
-
|
|
7612
|
+
await ossFetch(
|
|
7613
|
+
withProviderEnvironmentPath("stripe", environment, "/catalog/prices"),
|
|
7614
|
+
{
|
|
7615
|
+
method: "POST",
|
|
7616
|
+
body: JSON.stringify(request)
|
|
7617
|
+
}
|
|
7618
|
+
)
|
|
7545
7619
|
);
|
|
7546
7620
|
}
|
|
7547
|
-
async function
|
|
7621
|
+
async function updateStripePrice(environment, priceId, request) {
|
|
7548
7622
|
return readJson(
|
|
7549
7623
|
await ossFetch(
|
|
7550
|
-
|
|
7624
|
+
withProviderEnvironmentPath(
|
|
7625
|
+
"stripe",
|
|
7551
7626
|
environment,
|
|
7552
7627
|
`/catalog/prices/${encodeURIComponent(priceId)}`
|
|
7553
7628
|
),
|
|
@@ -7558,10 +7633,11 @@ async function updatePaymentPrice(environment, priceId, request) {
|
|
|
7558
7633
|
)
|
|
7559
7634
|
);
|
|
7560
7635
|
}
|
|
7561
|
-
async function
|
|
7636
|
+
async function archiveStripePrice(environment, priceId) {
|
|
7562
7637
|
return readJson(
|
|
7563
7638
|
await ossFetch(
|
|
7564
|
-
|
|
7639
|
+
withProviderEnvironmentPath(
|
|
7640
|
+
"stripe",
|
|
7565
7641
|
environment,
|
|
7566
7642
|
`/catalog/prices/${encodeURIComponent(priceId)}`
|
|
7567
7643
|
),
|
|
@@ -7569,29 +7645,99 @@ async function archivePaymentPrice(environment, priceId) {
|
|
|
7569
7645
|
)
|
|
7570
7646
|
);
|
|
7571
7647
|
}
|
|
7572
|
-
async function
|
|
7648
|
+
async function createRazorpayItem(environment, request) {
|
|
7649
|
+
return readJson(
|
|
7650
|
+
await ossFetch(
|
|
7651
|
+
withProviderEnvironmentPath("razorpay", environment, "/catalog/items"),
|
|
7652
|
+
{
|
|
7653
|
+
method: "POST",
|
|
7654
|
+
body: JSON.stringify(request)
|
|
7655
|
+
}
|
|
7656
|
+
)
|
|
7657
|
+
);
|
|
7658
|
+
}
|
|
7659
|
+
async function updateRazorpayItem(environment, itemId, request) {
|
|
7660
|
+
return readJson(
|
|
7661
|
+
await ossFetch(
|
|
7662
|
+
withProviderEnvironmentPath(
|
|
7663
|
+
"razorpay",
|
|
7664
|
+
environment,
|
|
7665
|
+
`/catalog/items/${encodeURIComponent(itemId)}`
|
|
7666
|
+
),
|
|
7667
|
+
{
|
|
7668
|
+
method: "PATCH",
|
|
7669
|
+
body: JSON.stringify(request)
|
|
7670
|
+
}
|
|
7671
|
+
)
|
|
7672
|
+
);
|
|
7673
|
+
}
|
|
7674
|
+
async function createRazorpayPlan(environment, request) {
|
|
7675
|
+
return readJson(
|
|
7676
|
+
await ossFetch(
|
|
7677
|
+
withProviderEnvironmentPath("razorpay", environment, "/catalog/plans"),
|
|
7678
|
+
{
|
|
7679
|
+
method: "POST",
|
|
7680
|
+
body: JSON.stringify(request)
|
|
7681
|
+
}
|
|
7682
|
+
)
|
|
7683
|
+
);
|
|
7684
|
+
}
|
|
7685
|
+
async function listStripeSubscriptions(environment, request) {
|
|
7686
|
+
return readJson(
|
|
7687
|
+
await ossFetch(
|
|
7688
|
+
withQuery(
|
|
7689
|
+
withProviderEnvironmentPath("stripe", environment, "/subscriptions"),
|
|
7690
|
+
request
|
|
7691
|
+
)
|
|
7692
|
+
)
|
|
7693
|
+
);
|
|
7694
|
+
}
|
|
7695
|
+
async function listRazorpaySubscriptions(environment, request) {
|
|
7573
7696
|
return readJson(
|
|
7574
7697
|
await ossFetch(
|
|
7575
|
-
withQuery(
|
|
7698
|
+
withQuery(
|
|
7699
|
+
withProviderEnvironmentPath("razorpay", environment, "/subscriptions"),
|
|
7700
|
+
request
|
|
7701
|
+
)
|
|
7576
7702
|
)
|
|
7577
7703
|
);
|
|
7578
7704
|
}
|
|
7579
|
-
async function listPaymentCustomers(environment, request = {}) {
|
|
7705
|
+
async function listPaymentCustomers(provider, environment, request = {}) {
|
|
7580
7706
|
return readJson(
|
|
7581
7707
|
await ossFetch(
|
|
7582
|
-
withQuery(
|
|
7708
|
+
withQuery(
|
|
7709
|
+
withProviderEnvironmentPath(provider, environment, "/customers"),
|
|
7710
|
+
request
|
|
7711
|
+
)
|
|
7583
7712
|
)
|
|
7584
7713
|
);
|
|
7585
7714
|
}
|
|
7586
|
-
async function
|
|
7715
|
+
async function listPaymentTransactions(provider, environment, request) {
|
|
7587
7716
|
return readJson(
|
|
7588
7717
|
await ossFetch(
|
|
7589
|
-
withQuery(
|
|
7718
|
+
withQuery(
|
|
7719
|
+
withProviderEnvironmentPath(provider, environment, "/transactions"),
|
|
7720
|
+
request
|
|
7721
|
+
)
|
|
7590
7722
|
)
|
|
7591
7723
|
);
|
|
7592
7724
|
}
|
|
7593
7725
|
|
|
7594
7726
|
// src/commands/payments/utils.ts
|
|
7727
|
+
var MAX_TELEMETRY_ERROR_MESSAGE_LENGTH = 500;
|
|
7728
|
+
function getErrorTelemetry(error) {
|
|
7729
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7730
|
+
const truncatedMessage = message.length > MAX_TELEMETRY_ERROR_MESSAGE_LENGTH ? `${message.slice(0, MAX_TELEMETRY_ERROR_MESSAGE_LENGTH)}...` : message;
|
|
7731
|
+
return {
|
|
7732
|
+
error_name: error instanceof Error ? error.name : typeof error,
|
|
7733
|
+
error_message: truncatedMessage,
|
|
7734
|
+
...error instanceof CLIError ? {
|
|
7735
|
+
error_code: error.code,
|
|
7736
|
+
exit_code: error.exitCode,
|
|
7737
|
+
status_code: error.statusCode
|
|
7738
|
+
} : {}
|
|
7739
|
+
};
|
|
7740
|
+
}
|
|
7595
7741
|
function parseEnvironment(value) {
|
|
7596
7742
|
if (value === "test" || value === "live") return value;
|
|
7597
7743
|
throw new CLIError('Environment must be "test" or "live".');
|
|
@@ -7600,6 +7746,15 @@ function parseEnvironmentOrAll(value) {
|
|
|
7600
7746
|
if (value === "all") return value;
|
|
7601
7747
|
return parseEnvironment(value);
|
|
7602
7748
|
}
|
|
7749
|
+
function parseRazorpayPlanPeriod(value) {
|
|
7750
|
+
if (value === void 0) return void 0;
|
|
7751
|
+
if (value === "daily" || value === "weekly" || value === "monthly" || value === "yearly") {
|
|
7752
|
+
return value;
|
|
7753
|
+
}
|
|
7754
|
+
throw new CLIError(
|
|
7755
|
+
"--period must be one of: daily, weekly, monthly, yearly."
|
|
7756
|
+
);
|
|
7757
|
+
}
|
|
7603
7758
|
function parseBooleanOption(value, flagName) {
|
|
7604
7759
|
if (value === void 0) return void 0;
|
|
7605
7760
|
const normalized = value.toLowerCase();
|
|
@@ -7667,13 +7822,14 @@ function formatRecurring(interval, intervalCount) {
|
|
|
7667
7822
|
if (!interval) return "one-time";
|
|
7668
7823
|
return `${intervalCount && intervalCount > 1 ? `${intervalCount} ` : ""}${interval}`;
|
|
7669
7824
|
}
|
|
7670
|
-
async function trackPaymentUsage(subcommand, success, properties = {}) {
|
|
7825
|
+
async function trackPaymentUsage(subcommand, success, properties = {}, error) {
|
|
7671
7826
|
try {
|
|
7672
7827
|
const config = getProjectConfig();
|
|
7673
7828
|
if (config) {
|
|
7674
7829
|
trackPayments(subcommand, config, {
|
|
7675
7830
|
success,
|
|
7676
|
-
...properties
|
|
7831
|
+
...properties,
|
|
7832
|
+
...error !== void 0 ? getErrorTelemetry(error) : {}
|
|
7677
7833
|
});
|
|
7678
7834
|
}
|
|
7679
7835
|
} catch {
|
|
@@ -7683,76 +7839,138 @@ async function trackPaymentUsage(subcommand, success, properties = {}) {
|
|
|
7683
7839
|
}
|
|
7684
7840
|
|
|
7685
7841
|
// src/commands/payments/catalog.ts
|
|
7686
|
-
function registerPaymentsCatalogCommand(paymentsCmd2) {
|
|
7687
|
-
paymentsCmd2.command("catalog").description("List mirrored
|
|
7842
|
+
function registerPaymentsCatalogCommand(paymentsCmd2, provider) {
|
|
7843
|
+
paymentsCmd2.command("catalog").description("List mirrored provider catalog records for one environment").requiredOption(
|
|
7688
7844
|
"--environment <environment>",
|
|
7689
|
-
"
|
|
7845
|
+
"Payment environment: test or live"
|
|
7690
7846
|
).action(async (opts, cmd) => {
|
|
7691
7847
|
const { json } = getRootOpts(cmd);
|
|
7692
7848
|
try {
|
|
7693
7849
|
const environment = parseEnvironment(opts.environment);
|
|
7694
7850
|
await requireAuth();
|
|
7695
|
-
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
|
|
7700
|
-
|
|
7701
|
-
|
|
7702
|
-
|
|
7703
|
-
|
|
7704
|
-
|
|
7705
|
-
|
|
7706
|
-
|
|
7707
|
-
|
|
7708
|
-
|
|
7709
|
-
|
|
7710
|
-
|
|
7711
|
-
|
|
7712
|
-
product
|
|
7713
|
-
|
|
7714
|
-
|
|
7715
|
-
|
|
7851
|
+
if (provider === "stripe") {
|
|
7852
|
+
const data = await listStripeCatalog(environment);
|
|
7853
|
+
if (json) {
|
|
7854
|
+
outputJson(data);
|
|
7855
|
+
} else {
|
|
7856
|
+
if (data.products.length === 0 && data.prices.length === 0) {
|
|
7857
|
+
console.log("No Stripe catalog records found.");
|
|
7858
|
+
await trackPaymentUsage("catalog", true, {
|
|
7859
|
+
provider,
|
|
7860
|
+
environment
|
|
7861
|
+
});
|
|
7862
|
+
return;
|
|
7863
|
+
}
|
|
7864
|
+
if (data.products.length > 0) {
|
|
7865
|
+
console.log("Products");
|
|
7866
|
+
outputTable(
|
|
7867
|
+
["Env", "Product ID", "Name", "Active", "Default Price"],
|
|
7868
|
+
data.products.map((product) => [
|
|
7869
|
+
product.environment,
|
|
7870
|
+
product.productId,
|
|
7871
|
+
product.name,
|
|
7872
|
+
product.active ? "Yes" : "No",
|
|
7873
|
+
product.defaultPriceId ?? "-"
|
|
7874
|
+
])
|
|
7875
|
+
);
|
|
7876
|
+
}
|
|
7877
|
+
if (data.prices.length > 0) {
|
|
7878
|
+
console.log("Prices");
|
|
7879
|
+
outputTable(
|
|
7880
|
+
[
|
|
7881
|
+
"Env",
|
|
7882
|
+
"Price ID",
|
|
7883
|
+
"Product ID",
|
|
7884
|
+
"Amount",
|
|
7885
|
+
"Type",
|
|
7886
|
+
"Active",
|
|
7887
|
+
"Recurring"
|
|
7888
|
+
],
|
|
7889
|
+
data.prices.map((price) => [
|
|
7890
|
+
price.environment,
|
|
7891
|
+
price.priceId,
|
|
7892
|
+
price.productId ?? "-",
|
|
7893
|
+
formatAmount(price.unitAmount, price.currency),
|
|
7894
|
+
price.type,
|
|
7895
|
+
price.active ? "Yes" : "No",
|
|
7896
|
+
formatRecurring(
|
|
7897
|
+
price.recurringInterval,
|
|
7898
|
+
price.recurringIntervalCount
|
|
7899
|
+
)
|
|
7900
|
+
])
|
|
7901
|
+
);
|
|
7902
|
+
}
|
|
7716
7903
|
}
|
|
7717
|
-
|
|
7718
|
-
|
|
7719
|
-
|
|
7720
|
-
|
|
7721
|
-
|
|
7722
|
-
|
|
7723
|
-
|
|
7724
|
-
|
|
7725
|
-
|
|
7726
|
-
|
|
7727
|
-
|
|
7728
|
-
|
|
7729
|
-
|
|
7730
|
-
|
|
7731
|
-
|
|
7732
|
-
|
|
7733
|
-
|
|
7734
|
-
|
|
7735
|
-
|
|
7736
|
-
|
|
7737
|
-
|
|
7738
|
-
|
|
7739
|
-
|
|
7740
|
-
|
|
7741
|
-
|
|
7904
|
+
} else {
|
|
7905
|
+
const data = await listRazorpayCatalog(environment);
|
|
7906
|
+
if (json) {
|
|
7907
|
+
outputJson(data);
|
|
7908
|
+
} else {
|
|
7909
|
+
if (data.items.length === 0 && data.plans.length === 0) {
|
|
7910
|
+
console.log("No Razorpay catalog records found.");
|
|
7911
|
+
await trackPaymentUsage("catalog", true, {
|
|
7912
|
+
provider,
|
|
7913
|
+
environment
|
|
7914
|
+
});
|
|
7915
|
+
return;
|
|
7916
|
+
}
|
|
7917
|
+
if (data.items.length > 0) {
|
|
7918
|
+
console.log("Items");
|
|
7919
|
+
outputTable(
|
|
7920
|
+
["Env", "Item ID", "Name", "Amount", "Active", "Type"],
|
|
7921
|
+
data.items.map((item) => [
|
|
7922
|
+
item.environment,
|
|
7923
|
+
item.itemId,
|
|
7924
|
+
item.name,
|
|
7925
|
+
formatAmount(item.amount, item.currency),
|
|
7926
|
+
item.active ? "Yes" : "No",
|
|
7927
|
+
item.type ?? "-"
|
|
7928
|
+
])
|
|
7929
|
+
);
|
|
7930
|
+
}
|
|
7931
|
+
if (data.plans.length > 0) {
|
|
7932
|
+
console.log("Plans");
|
|
7933
|
+
outputTable(
|
|
7934
|
+
[
|
|
7935
|
+
"Env",
|
|
7936
|
+
"Plan ID",
|
|
7937
|
+
"Item ID",
|
|
7938
|
+
"Amount",
|
|
7939
|
+
"Period",
|
|
7940
|
+
"Interval",
|
|
7941
|
+
"Active"
|
|
7942
|
+
],
|
|
7943
|
+
data.plans.map((plan) => [
|
|
7944
|
+
plan.environment,
|
|
7945
|
+
plan.planId,
|
|
7946
|
+
plan.itemId,
|
|
7947
|
+
formatAmount(plan.amount, plan.currency),
|
|
7948
|
+
plan.period,
|
|
7949
|
+
String(plan.interval),
|
|
7950
|
+
plan.active ? "Yes" : "No"
|
|
7951
|
+
])
|
|
7952
|
+
);
|
|
7953
|
+
}
|
|
7742
7954
|
}
|
|
7743
7955
|
}
|
|
7744
|
-
await trackPaymentUsage("catalog", true, { environment });
|
|
7956
|
+
await trackPaymentUsage("catalog", true, { provider, environment });
|
|
7745
7957
|
} catch (err) {
|
|
7746
|
-
await trackPaymentUsage(
|
|
7747
|
-
|
|
7748
|
-
|
|
7958
|
+
await trackPaymentUsage(
|
|
7959
|
+
"catalog",
|
|
7960
|
+
false,
|
|
7961
|
+
{
|
|
7962
|
+
provider,
|
|
7963
|
+
environment: opts.environment
|
|
7964
|
+
},
|
|
7965
|
+
err
|
|
7966
|
+
);
|
|
7749
7967
|
handleError(err, json);
|
|
7750
7968
|
}
|
|
7751
7969
|
});
|
|
7752
7970
|
}
|
|
7753
7971
|
|
|
7754
7972
|
// src/commands/payments/config.ts
|
|
7755
|
-
function
|
|
7973
|
+
function outputStripeConfigTable(data) {
|
|
7756
7974
|
if (data.keys.length === 0) {
|
|
7757
7975
|
console.log("No Stripe keys configured.");
|
|
7758
7976
|
return;
|
|
@@ -7766,32 +7984,111 @@ function outputConfigTable(data) {
|
|
|
7766
7984
|
])
|
|
7767
7985
|
);
|
|
7768
7986
|
}
|
|
7769
|
-
function
|
|
7770
|
-
|
|
7987
|
+
function outputRazorpayConfigTable(data) {
|
|
7988
|
+
if (data.razorpayKeys.length === 0) {
|
|
7989
|
+
console.log("No Razorpay keys configured.");
|
|
7990
|
+
return;
|
|
7991
|
+
}
|
|
7992
|
+
outputTable(
|
|
7993
|
+
["Env", "Type", "Configured", "Key"],
|
|
7994
|
+
data.razorpayKeys.map((key) => [
|
|
7995
|
+
key.environment,
|
|
7996
|
+
key.keyType,
|
|
7997
|
+
key.hasKey ? "Yes" : "No",
|
|
7998
|
+
key.maskedKey ?? "-"
|
|
7999
|
+
])
|
|
8000
|
+
);
|
|
8001
|
+
}
|
|
8002
|
+
function registerPaymentsConfigCommand(paymentsCmd2, provider) {
|
|
8003
|
+
const configCmd = paymentsCmd2.command("config").description("Manage payment provider keys");
|
|
8004
|
+
configCmd.command("list").description("List configured payment provider keys").action(async (_opts, cmd) => {
|
|
7771
8005
|
const { json } = getRootOpts(cmd);
|
|
7772
8006
|
try {
|
|
7773
8007
|
await requireAuth();
|
|
7774
|
-
|
|
8008
|
+
if (provider === "stripe") {
|
|
8009
|
+
const data = await getStripePaymentsConfig();
|
|
8010
|
+
if (json) {
|
|
8011
|
+
outputJson(data);
|
|
8012
|
+
} else {
|
|
8013
|
+
outputStripeConfigTable(data);
|
|
8014
|
+
}
|
|
8015
|
+
} else {
|
|
8016
|
+
const data = await getRazorpayPaymentsConfig();
|
|
8017
|
+
if (json) {
|
|
8018
|
+
outputJson(data);
|
|
8019
|
+
} else {
|
|
8020
|
+
outputRazorpayConfigTable(data);
|
|
8021
|
+
}
|
|
8022
|
+
}
|
|
8023
|
+
await trackPaymentUsage("config", true, { provider });
|
|
8024
|
+
} catch (err) {
|
|
8025
|
+
await trackPaymentUsage("config", false, { provider }, err);
|
|
8026
|
+
handleError(err, json);
|
|
8027
|
+
}
|
|
8028
|
+
});
|
|
8029
|
+
if (provider === "stripe") {
|
|
8030
|
+
registerStripeConfigSetCommand(configCmd);
|
|
8031
|
+
} else {
|
|
8032
|
+
registerRazorpayConfigSetCommand(configCmd);
|
|
8033
|
+
}
|
|
8034
|
+
configCmd.command("remove").description("Remove configured payment provider keys").requiredOption(
|
|
8035
|
+
"--environment <environment>",
|
|
8036
|
+
"Payment environment: test or live"
|
|
8037
|
+
).action(async (opts, cmd) => {
|
|
8038
|
+
const { json, yes } = getRootOpts(cmd);
|
|
8039
|
+
try {
|
|
8040
|
+
const environment = parseEnvironment(opts.environment);
|
|
8041
|
+
await requireAuth();
|
|
8042
|
+
if (json && !yes) {
|
|
8043
|
+
throw new CLIError(
|
|
8044
|
+
"Use --yes with --json to remove payment keys non-interactively."
|
|
8045
|
+
);
|
|
8046
|
+
}
|
|
8047
|
+
if (!yes) {
|
|
8048
|
+
const confirm8 = await confirm2({
|
|
8049
|
+
message: `Remove ${provider} ${environment} keys? Payment sync and mutations for this environment will stop.`
|
|
8050
|
+
});
|
|
8051
|
+
if (isCancel2(confirm8) || !confirm8) process.exit(0);
|
|
8052
|
+
}
|
|
8053
|
+
const data = provider === "stripe" ? await removeStripeSecretKey(environment) : await removeRazorpayKeys(environment);
|
|
7775
8054
|
if (json) {
|
|
7776
8055
|
outputJson(data);
|
|
7777
8056
|
} else {
|
|
7778
|
-
|
|
8057
|
+
outputSuccess(`${provider} ${environment} keys removed.`);
|
|
7779
8058
|
}
|
|
7780
|
-
await trackPaymentUsage("config", true
|
|
8059
|
+
await trackPaymentUsage("config.remove", true, {
|
|
8060
|
+
provider,
|
|
8061
|
+
environment
|
|
8062
|
+
});
|
|
7781
8063
|
} catch (err) {
|
|
7782
|
-
await trackPaymentUsage(
|
|
8064
|
+
await trackPaymentUsage(
|
|
8065
|
+
"config.remove",
|
|
8066
|
+
false,
|
|
8067
|
+
{
|
|
8068
|
+
provider,
|
|
8069
|
+
environment: opts.environment
|
|
8070
|
+
},
|
|
8071
|
+
err
|
|
8072
|
+
);
|
|
7783
8073
|
handleError(err, json);
|
|
7784
8074
|
}
|
|
7785
8075
|
});
|
|
7786
|
-
|
|
8076
|
+
}
|
|
8077
|
+
function registerStripeConfigSetCommand(configCmd) {
|
|
8078
|
+
configCmd.command("set [secretKey]").description("Configure a Stripe secret key for test or live payments").requiredOption(
|
|
8079
|
+
"--environment <environment>",
|
|
8080
|
+
"Stripe environment: test or live"
|
|
8081
|
+
).option("--secret-key <secretKey>", "Stripe secret key").action(async (secretKeyValue, opts, cmd) => {
|
|
7787
8082
|
const { json } = getRootOpts(cmd);
|
|
7788
8083
|
try {
|
|
7789
|
-
const environment = parseEnvironment(
|
|
8084
|
+
const environment = parseEnvironment(opts.environment);
|
|
7790
8085
|
await requireAuth();
|
|
7791
|
-
let secretKey = secretKeyValue;
|
|
8086
|
+
let secretKey = opts.secretKey ?? secretKeyValue;
|
|
7792
8087
|
if (!secretKey) {
|
|
7793
8088
|
if (json) {
|
|
7794
|
-
throw new CLIError(
|
|
8089
|
+
throw new CLIError(
|
|
8090
|
+
"Provide secretKey or --secret-key when using --json."
|
|
8091
|
+
);
|
|
7795
8092
|
}
|
|
7796
8093
|
const input = await password2({
|
|
7797
8094
|
message: `Stripe ${environment} secret key`
|
|
@@ -7805,35 +8102,78 @@ function registerPaymentsConfigCommand(paymentsCmd2) {
|
|
|
7805
8102
|
} else {
|
|
7806
8103
|
outputSuccess(`Stripe ${environment} key configured.`);
|
|
7807
8104
|
}
|
|
7808
|
-
await trackPaymentUsage("config.set", true, {
|
|
8105
|
+
await trackPaymentUsage("config.set", true, {
|
|
8106
|
+
provider: "stripe",
|
|
8107
|
+
environment
|
|
8108
|
+
});
|
|
7809
8109
|
} catch (err) {
|
|
7810
|
-
await trackPaymentUsage(
|
|
8110
|
+
await trackPaymentUsage(
|
|
8111
|
+
"config.set",
|
|
8112
|
+
false,
|
|
8113
|
+
{
|
|
8114
|
+
provider: "stripe",
|
|
8115
|
+
environment: opts.environment
|
|
8116
|
+
},
|
|
8117
|
+
err
|
|
8118
|
+
);
|
|
7811
8119
|
handleError(err, json);
|
|
7812
8120
|
}
|
|
7813
8121
|
});
|
|
7814
|
-
|
|
7815
|
-
|
|
8122
|
+
}
|
|
8123
|
+
function registerRazorpayConfigSetCommand(configCmd) {
|
|
8124
|
+
configCmd.command("set").description("Configure Razorpay keys for test or live payments").requiredOption(
|
|
8125
|
+
"--environment <environment>",
|
|
8126
|
+
"Razorpay environment: test or live"
|
|
8127
|
+
).option("--key-id <keyId>", "Razorpay key id").option("--key-secret <keySecret>", "Razorpay key secret").action(async (opts, cmd) => {
|
|
8128
|
+
const { json } = getRootOpts(cmd);
|
|
7816
8129
|
try {
|
|
7817
|
-
const environment = parseEnvironment(
|
|
8130
|
+
const environment = parseEnvironment(opts.environment);
|
|
7818
8131
|
await requireAuth();
|
|
7819
|
-
|
|
7820
|
-
|
|
8132
|
+
let keyId = opts.keyId;
|
|
8133
|
+
let keySecret = opts.keySecret;
|
|
8134
|
+
if (!keyId) {
|
|
8135
|
+
if (json) {
|
|
8136
|
+
throw new CLIError("Provide --key-id when using --json.");
|
|
8137
|
+
}
|
|
8138
|
+
const input = await text2({
|
|
8139
|
+
message: `Razorpay ${environment} key id`
|
|
8140
|
+
});
|
|
8141
|
+
if (isCancel2(input)) process.exit(0);
|
|
8142
|
+
keyId = input;
|
|
7821
8143
|
}
|
|
7822
|
-
if (!
|
|
7823
|
-
|
|
7824
|
-
|
|
8144
|
+
if (!keySecret) {
|
|
8145
|
+
if (json) {
|
|
8146
|
+
throw new CLIError("Provide --key-secret when using --json.");
|
|
8147
|
+
}
|
|
8148
|
+
const input = await password2({
|
|
8149
|
+
message: `Razorpay ${environment} key secret`
|
|
7825
8150
|
});
|
|
7826
|
-
if (isCancel2(
|
|
8151
|
+
if (isCancel2(input)) process.exit(0);
|
|
8152
|
+
keySecret = input;
|
|
7827
8153
|
}
|
|
7828
|
-
const data = await
|
|
8154
|
+
const data = await setRazorpayKeys(environment, {
|
|
8155
|
+
keyId,
|
|
8156
|
+
keySecret
|
|
8157
|
+
});
|
|
7829
8158
|
if (json) {
|
|
7830
8159
|
outputJson(data);
|
|
7831
8160
|
} else {
|
|
7832
|
-
outputSuccess(`
|
|
8161
|
+
outputSuccess(`Razorpay ${environment} keys configured.`);
|
|
7833
8162
|
}
|
|
7834
|
-
await trackPaymentUsage("config.
|
|
8163
|
+
await trackPaymentUsage("config.set", true, {
|
|
8164
|
+
provider: "razorpay",
|
|
8165
|
+
environment
|
|
8166
|
+
});
|
|
7835
8167
|
} catch (err) {
|
|
7836
|
-
await trackPaymentUsage(
|
|
8168
|
+
await trackPaymentUsage(
|
|
8169
|
+
"config.set",
|
|
8170
|
+
false,
|
|
8171
|
+
{
|
|
8172
|
+
provider: "razorpay",
|
|
8173
|
+
environment: opts.environment
|
|
8174
|
+
},
|
|
8175
|
+
err
|
|
8176
|
+
);
|
|
7837
8177
|
handleError(err, json);
|
|
7838
8178
|
}
|
|
7839
8179
|
});
|
|
@@ -7852,21 +8192,23 @@ function formatPaymentMethod(customer) {
|
|
|
7852
8192
|
}
|
|
7853
8193
|
return "-";
|
|
7854
8194
|
}
|
|
7855
|
-
function registerPaymentsCustomersCommand(paymentsCmd2) {
|
|
7856
|
-
paymentsCmd2.command("customers").description("List mirrored
|
|
8195
|
+
function registerPaymentsCustomersCommand(paymentsCmd2, provider) {
|
|
8196
|
+
paymentsCmd2.command("customers").description("List mirrored payment provider customers").requiredOption(
|
|
7857
8197
|
"--environment <environment>",
|
|
7858
|
-
"
|
|
8198
|
+
"Payment environment: test or live"
|
|
7859
8199
|
).option("--limit <limit>", "Maximum rows to return (1-100)", "50").action(async (opts, cmd) => {
|
|
7860
8200
|
const { json } = getRootOpts(cmd);
|
|
7861
8201
|
try {
|
|
7862
8202
|
const environment = parseEnvironment(opts.environment);
|
|
7863
8203
|
const limit = parseIntegerOption(opts.limit, "--limit", { min: 1, max: 100 }) ?? 50;
|
|
7864
8204
|
await requireAuth();
|
|
7865
|
-
const data = await listPaymentCustomers(environment, {
|
|
8205
|
+
const data = await listPaymentCustomers(provider, environment, {
|
|
8206
|
+
limit
|
|
8207
|
+
});
|
|
7866
8208
|
if (json) {
|
|
7867
8209
|
outputJson(data);
|
|
7868
8210
|
} else if (data.customers.length === 0) {
|
|
7869
|
-
console.log(
|
|
8211
|
+
console.log(`No ${provider} customers found.`);
|
|
7870
8212
|
} else {
|
|
7871
8213
|
outputTable(
|
|
7872
8214
|
[
|
|
@@ -7880,7 +8222,7 @@ function registerPaymentsCustomersCommand(paymentsCmd2) {
|
|
|
7880
8222
|
"Country"
|
|
7881
8223
|
],
|
|
7882
8224
|
data.customers.map((customer) => [
|
|
7883
|
-
customer.
|
|
8225
|
+
customer.providerCustomerId,
|
|
7884
8226
|
customer.email ?? "-",
|
|
7885
8227
|
customer.name ?? "-",
|
|
7886
8228
|
String(customer.paymentsCount),
|
|
@@ -7891,72 +8233,312 @@ function registerPaymentsCustomersCommand(paymentsCmd2) {
|
|
|
7891
8233
|
])
|
|
7892
8234
|
);
|
|
7893
8235
|
}
|
|
7894
|
-
await trackPaymentUsage("customers", true, { environment });
|
|
8236
|
+
await trackPaymentUsage("customers", true, { provider, environment });
|
|
7895
8237
|
} catch (err) {
|
|
7896
|
-
await trackPaymentUsage(
|
|
7897
|
-
|
|
7898
|
-
|
|
8238
|
+
await trackPaymentUsage(
|
|
8239
|
+
"customers",
|
|
8240
|
+
false,
|
|
8241
|
+
{
|
|
8242
|
+
provider,
|
|
8243
|
+
environment: opts.environment
|
|
8244
|
+
},
|
|
8245
|
+
err
|
|
8246
|
+
);
|
|
7899
8247
|
handleError(err, json);
|
|
7900
8248
|
}
|
|
7901
8249
|
});
|
|
7902
8250
|
}
|
|
7903
8251
|
|
|
7904
|
-
// src/commands/payments/
|
|
7905
|
-
function
|
|
7906
|
-
|
|
8252
|
+
// src/commands/payments/items.ts
|
|
8253
|
+
function nullableString(value) {
|
|
8254
|
+
if (value === void 0) return void 0;
|
|
8255
|
+
return value === "null" ? null : value;
|
|
8256
|
+
}
|
|
8257
|
+
function outputItemsTable(items) {
|
|
8258
|
+
if (items.length === 0) {
|
|
8259
|
+
console.log("No Razorpay items found.");
|
|
8260
|
+
return;
|
|
8261
|
+
}
|
|
8262
|
+
outputTable(
|
|
8263
|
+
["Env", "Item ID", "Name", "Amount", "Active", "Type", "Synced At"],
|
|
8264
|
+
items.map((item) => [
|
|
8265
|
+
item.environment,
|
|
8266
|
+
item.itemId,
|
|
8267
|
+
item.name,
|
|
8268
|
+
formatAmount(item.amount, item.currency),
|
|
8269
|
+
item.active ? "Yes" : "No",
|
|
8270
|
+
item.type ?? "-",
|
|
8271
|
+
formatDate(item.syncedAt)
|
|
8272
|
+
])
|
|
8273
|
+
);
|
|
8274
|
+
}
|
|
8275
|
+
function registerPaymentsItemsCommand(paymentsCmd2) {
|
|
8276
|
+
const itemsCmd = paymentsCmd2.command("items").description("Manage Razorpay items");
|
|
8277
|
+
itemsCmd.command("list").description("List mirrored Razorpay items").requiredOption(
|
|
7907
8278
|
"--environment <environment>",
|
|
7908
|
-
"
|
|
7909
|
-
).
|
|
8279
|
+
"Razorpay environment: test or live"
|
|
8280
|
+
).action(async (opts, cmd) => {
|
|
7910
8281
|
const { json } = getRootOpts(cmd);
|
|
7911
8282
|
try {
|
|
7912
8283
|
const environment = parseEnvironment(opts.environment);
|
|
7913
|
-
const limit = parseIntegerOption(opts.limit, "--limit", { min: 1, max: 100 }) ?? 50;
|
|
7914
8284
|
await requireAuth();
|
|
7915
|
-
const data = await
|
|
7916
|
-
|
|
7917
|
-
|
|
7918
|
-
|
|
8285
|
+
const data = await listRazorpayCatalog(environment);
|
|
8286
|
+
if (json) {
|
|
8287
|
+
outputJson({ items: data.items });
|
|
8288
|
+
} else {
|
|
8289
|
+
outputItemsTable(data.items);
|
|
8290
|
+
}
|
|
8291
|
+
await trackPaymentUsage("items.list", true, {
|
|
8292
|
+
provider: "razorpay",
|
|
8293
|
+
environment
|
|
7919
8294
|
});
|
|
8295
|
+
} catch (err) {
|
|
8296
|
+
await trackPaymentUsage(
|
|
8297
|
+
"items.list",
|
|
8298
|
+
false,
|
|
8299
|
+
{
|
|
8300
|
+
provider: "razorpay",
|
|
8301
|
+
environment: opts.environment
|
|
8302
|
+
},
|
|
8303
|
+
err
|
|
8304
|
+
);
|
|
8305
|
+
handleError(err, json);
|
|
8306
|
+
}
|
|
8307
|
+
});
|
|
8308
|
+
itemsCmd.command("create").description("Create a Razorpay item").requiredOption(
|
|
8309
|
+
"--environment <environment>",
|
|
8310
|
+
"Razorpay environment: test or live"
|
|
8311
|
+
).requiredOption("--name <name>", "Item name").requiredOption("--amount <amount>", "Amount in the smallest currency unit").requiredOption(
|
|
8312
|
+
"--currency <currency>",
|
|
8313
|
+
"Three-letter currency code, e.g. inr"
|
|
8314
|
+
).option("--description <description>", 'Item description, or "null"').option("--metadata <json>", "Metadata JSON object with string values").action(async (opts, cmd) => {
|
|
8315
|
+
const { json } = getRootOpts(cmd);
|
|
8316
|
+
try {
|
|
8317
|
+
const environment = parseEnvironment(opts.environment);
|
|
8318
|
+
await requireAuth();
|
|
8319
|
+
const request = {
|
|
8320
|
+
name: opts.name,
|
|
8321
|
+
amount: parseIntegerOption(opts.amount, "--amount", { min: 0 }) ?? 0,
|
|
8322
|
+
currency: opts.currency
|
|
8323
|
+
};
|
|
8324
|
+
const description = nullableString(opts.description);
|
|
8325
|
+
const metadata = parseMetadataOption(opts.metadata);
|
|
8326
|
+
if (description !== void 0) request.description = description;
|
|
8327
|
+
if (metadata !== void 0) request.metadata = metadata;
|
|
8328
|
+
const data = await createRazorpayItem(environment, request);
|
|
7920
8329
|
if (json) {
|
|
7921
8330
|
outputJson(data);
|
|
7922
|
-
} else if (data.paymentHistory.length === 0) {
|
|
7923
|
-
console.log("No Stripe payment history found.");
|
|
7924
8331
|
} else {
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
|
|
7929
|
-
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
7937
|
-
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
|
|
7941
|
-
|
|
7942
|
-
|
|
7943
|
-
|
|
7944
|
-
|
|
7945
|
-
|
|
8332
|
+
outputSuccess(`Razorpay item created: ${data.item.itemId}`);
|
|
8333
|
+
}
|
|
8334
|
+
await trackPaymentUsage("items.create", true, {
|
|
8335
|
+
provider: "razorpay",
|
|
8336
|
+
environment
|
|
8337
|
+
});
|
|
8338
|
+
} catch (err) {
|
|
8339
|
+
await trackPaymentUsage(
|
|
8340
|
+
"items.create",
|
|
8341
|
+
false,
|
|
8342
|
+
{
|
|
8343
|
+
provider: "razorpay",
|
|
8344
|
+
environment: opts.environment
|
|
8345
|
+
},
|
|
8346
|
+
err
|
|
8347
|
+
);
|
|
8348
|
+
handleError(err, json);
|
|
8349
|
+
}
|
|
8350
|
+
});
|
|
8351
|
+
itemsCmd.command("update <itemId>").description("Update a Razorpay item").requiredOption(
|
|
8352
|
+
"--environment <environment>",
|
|
8353
|
+
"Razorpay environment: test or live"
|
|
8354
|
+
).option("--name <name>", "Item name").option("--description <description>", 'Item description, or "null"').option("--amount <amount>", "Amount in the smallest currency unit").option("--currency <currency>", "Three-letter currency code").option("--active <bool>", "Set active status (true/false)").option("--metadata <json>", "Metadata JSON object with string values").action(async (itemId, opts, cmd) => {
|
|
8355
|
+
const { json } = getRootOpts(cmd);
|
|
8356
|
+
try {
|
|
8357
|
+
const environment = parseEnvironment(opts.environment);
|
|
8358
|
+
await requireAuth();
|
|
8359
|
+
const request = {};
|
|
8360
|
+
const description = nullableString(opts.description);
|
|
8361
|
+
const amount = parseIntegerOption(opts.amount, "--amount", { min: 0 });
|
|
8362
|
+
const active = parseBooleanOption(opts.active, "--active");
|
|
8363
|
+
const metadata = parseMetadataOption(opts.metadata);
|
|
8364
|
+
if (opts.name !== void 0) request.name = opts.name;
|
|
8365
|
+
if (description !== void 0) request.description = description;
|
|
8366
|
+
if (amount !== void 0) request.amount = amount;
|
|
8367
|
+
if (opts.currency !== void 0) request.currency = opts.currency;
|
|
8368
|
+
if (active !== void 0) request.active = active;
|
|
8369
|
+
if (metadata !== void 0) request.metadata = metadata;
|
|
8370
|
+
if (Object.keys(request).length === 0) {
|
|
8371
|
+
throw new CLIError(
|
|
8372
|
+
"Provide at least one option to update (--name, --description, --amount, --currency, --active, --metadata)."
|
|
7946
8373
|
);
|
|
7947
8374
|
}
|
|
7948
|
-
await
|
|
8375
|
+
const data = await updateRazorpayItem(environment, itemId, request);
|
|
8376
|
+
if (json) {
|
|
8377
|
+
outputJson(data);
|
|
8378
|
+
} else {
|
|
8379
|
+
outputSuccess(`Razorpay item updated: ${data.item.itemId}`);
|
|
8380
|
+
}
|
|
8381
|
+
await trackPaymentUsage("items.update", true, {
|
|
8382
|
+
provider: "razorpay",
|
|
8383
|
+
environment
|
|
8384
|
+
});
|
|
7949
8385
|
} catch (err) {
|
|
7950
|
-
await trackPaymentUsage(
|
|
7951
|
-
|
|
8386
|
+
await trackPaymentUsage(
|
|
8387
|
+
"items.update",
|
|
8388
|
+
false,
|
|
8389
|
+
{
|
|
8390
|
+
provider: "razorpay",
|
|
8391
|
+
environment: opts.environment
|
|
8392
|
+
},
|
|
8393
|
+
err
|
|
8394
|
+
);
|
|
8395
|
+
handleError(err, json);
|
|
8396
|
+
}
|
|
8397
|
+
});
|
|
8398
|
+
}
|
|
8399
|
+
|
|
8400
|
+
// src/commands/payments/plans.ts
|
|
8401
|
+
function nullableString2(value) {
|
|
8402
|
+
if (value === void 0) return void 0;
|
|
8403
|
+
return value === "null" ? null : value;
|
|
8404
|
+
}
|
|
8405
|
+
function outputPlansTable(plans) {
|
|
8406
|
+
if (plans.length === 0) {
|
|
8407
|
+
console.log("No Razorpay plans found.");
|
|
8408
|
+
return;
|
|
8409
|
+
}
|
|
8410
|
+
outputTable(
|
|
8411
|
+
[
|
|
8412
|
+
"Env",
|
|
8413
|
+
"Plan ID",
|
|
8414
|
+
"Item ID",
|
|
8415
|
+
"Amount",
|
|
8416
|
+
"Period",
|
|
8417
|
+
"Interval",
|
|
8418
|
+
"Active",
|
|
8419
|
+
"Synced At"
|
|
8420
|
+
],
|
|
8421
|
+
plans.map((plan) => [
|
|
8422
|
+
plan.environment,
|
|
8423
|
+
plan.planId,
|
|
8424
|
+
plan.itemId,
|
|
8425
|
+
formatAmount(plan.amount, plan.currency),
|
|
8426
|
+
plan.period,
|
|
8427
|
+
String(plan.interval),
|
|
8428
|
+
plan.active ? "Yes" : "No",
|
|
8429
|
+
formatDate(plan.syncedAt)
|
|
8430
|
+
])
|
|
8431
|
+
);
|
|
8432
|
+
}
|
|
8433
|
+
function registerPaymentsPlansCommand(paymentsCmd2) {
|
|
8434
|
+
const plansCmd = paymentsCmd2.command("plans").description("Manage Razorpay plans");
|
|
8435
|
+
plansCmd.command("list").description("List mirrored Razorpay plans").requiredOption(
|
|
8436
|
+
"--environment <environment>",
|
|
8437
|
+
"Razorpay environment: test or live"
|
|
8438
|
+
).action(async (opts, cmd) => {
|
|
8439
|
+
const { json } = getRootOpts(cmd);
|
|
8440
|
+
try {
|
|
8441
|
+
const environment = parseEnvironment(opts.environment);
|
|
8442
|
+
await requireAuth();
|
|
8443
|
+
const data = await listRazorpayCatalog(environment);
|
|
8444
|
+
if (json) {
|
|
8445
|
+
outputJson({ plans: data.plans });
|
|
8446
|
+
} else {
|
|
8447
|
+
outputPlansTable(data.plans);
|
|
8448
|
+
}
|
|
8449
|
+
await trackPaymentUsage("plans.list", true, {
|
|
8450
|
+
provider: "razorpay",
|
|
8451
|
+
environment
|
|
7952
8452
|
});
|
|
8453
|
+
} catch (err) {
|
|
8454
|
+
await trackPaymentUsage(
|
|
8455
|
+
"plans.list",
|
|
8456
|
+
false,
|
|
8457
|
+
{
|
|
8458
|
+
provider: "razorpay",
|
|
8459
|
+
environment: opts.environment
|
|
8460
|
+
},
|
|
8461
|
+
err
|
|
8462
|
+
);
|
|
8463
|
+
handleError(err, json);
|
|
8464
|
+
}
|
|
8465
|
+
});
|
|
8466
|
+
plansCmd.command("create").description("Create a Razorpay subscription plan").requiredOption(
|
|
8467
|
+
"--environment <environment>",
|
|
8468
|
+
"Razorpay environment: test or live"
|
|
8469
|
+
).requiredOption(
|
|
8470
|
+
"--period <period>",
|
|
8471
|
+
"Plan period: daily, weekly, monthly, or yearly"
|
|
8472
|
+
).requiredOption("--interval <count>", "Billing interval count").requiredOption("--item-name <name>", "Plan item name").requiredOption(
|
|
8473
|
+
"--item-amount <amount>",
|
|
8474
|
+
"Plan item amount in the smallest currency unit"
|
|
8475
|
+
).requiredOption(
|
|
8476
|
+
"--item-currency <currency>",
|
|
8477
|
+
"Three-letter currency code, e.g. inr"
|
|
8478
|
+
).option(
|
|
8479
|
+
"--item-description <description>",
|
|
8480
|
+
'Plan item description, or "null"'
|
|
8481
|
+
).option("--metadata <json>", "Metadata JSON object with string values").action(async (opts, cmd) => {
|
|
8482
|
+
const { json } = getRootOpts(cmd);
|
|
8483
|
+
try {
|
|
8484
|
+
const environment = parseEnvironment(opts.environment);
|
|
8485
|
+
const period = parseRazorpayPlanPeriod(opts.period);
|
|
8486
|
+
const interval = parseIntegerOption(opts.interval, "--interval", {
|
|
8487
|
+
min: 1
|
|
8488
|
+
});
|
|
8489
|
+
const itemAmount = parseIntegerOption(
|
|
8490
|
+
opts.itemAmount,
|
|
8491
|
+
"--item-amount",
|
|
8492
|
+
{ min: 0 }
|
|
8493
|
+
);
|
|
8494
|
+
if (!period || interval === void 0 || itemAmount === void 0) {
|
|
8495
|
+
throw new CLIError(
|
|
8496
|
+
"Provide --period, --interval, and --item-amount."
|
|
8497
|
+
);
|
|
8498
|
+
}
|
|
8499
|
+
await requireAuth();
|
|
8500
|
+
const request = {
|
|
8501
|
+
period,
|
|
8502
|
+
interval,
|
|
8503
|
+
item: {
|
|
8504
|
+
name: opts.itemName,
|
|
8505
|
+
amount: itemAmount,
|
|
8506
|
+
currency: opts.itemCurrency
|
|
8507
|
+
}
|
|
8508
|
+
};
|
|
8509
|
+
const itemDescription = nullableString2(opts.itemDescription);
|
|
8510
|
+
const metadata = parseMetadataOption(opts.metadata);
|
|
8511
|
+
if (itemDescription !== void 0) {
|
|
8512
|
+
request.item.description = itemDescription;
|
|
8513
|
+
}
|
|
8514
|
+
if (metadata !== void 0) request.metadata = metadata;
|
|
8515
|
+
const data = await createRazorpayPlan(environment, request);
|
|
8516
|
+
if (json) {
|
|
8517
|
+
outputJson(data);
|
|
8518
|
+
} else {
|
|
8519
|
+
outputSuccess(`Razorpay plan created: ${data.plan.planId}`);
|
|
8520
|
+
}
|
|
8521
|
+
await trackPaymentUsage("plans.create", true, {
|
|
8522
|
+
provider: "razorpay",
|
|
8523
|
+
environment
|
|
8524
|
+
});
|
|
8525
|
+
} catch (err) {
|
|
8526
|
+
await trackPaymentUsage(
|
|
8527
|
+
"plans.create",
|
|
8528
|
+
false,
|
|
8529
|
+
{
|
|
8530
|
+
provider: "razorpay",
|
|
8531
|
+
environment: opts.environment
|
|
8532
|
+
},
|
|
8533
|
+
err
|
|
8534
|
+
);
|
|
7953
8535
|
handleError(err, json);
|
|
7954
8536
|
}
|
|
7955
8537
|
});
|
|
7956
8538
|
}
|
|
7957
8539
|
|
|
7958
8540
|
// src/commands/payments/prices.ts
|
|
7959
|
-
function
|
|
8541
|
+
function nullableString3(value) {
|
|
7960
8542
|
if (value === void 0) return void 0;
|
|
7961
8543
|
return value === "null" ? null : value;
|
|
7962
8544
|
}
|
|
@@ -7998,8 +8580,8 @@ function outputPricesTable(prices) {
|
|
|
7998
8580
|
],
|
|
7999
8581
|
prices.map((price) => [
|
|
8000
8582
|
price.environment,
|
|
8001
|
-
price.
|
|
8002
|
-
price.
|
|
8583
|
+
price.priceId,
|
|
8584
|
+
price.productId ?? "-",
|
|
8003
8585
|
formatAmount(price.unitAmount, price.currency),
|
|
8004
8586
|
price.type,
|
|
8005
8587
|
price.active ? "Yes" : "No",
|
|
@@ -8018,17 +8600,26 @@ function registerPaymentsPricesCommand(paymentsCmd2) {
|
|
|
8018
8600
|
try {
|
|
8019
8601
|
const environment = parseEnvironment(opts.environment);
|
|
8020
8602
|
await requireAuth();
|
|
8021
|
-
const data = await
|
|
8603
|
+
const data = await listStripePrices(environment, opts.product);
|
|
8022
8604
|
if (json) {
|
|
8023
8605
|
outputJson(data);
|
|
8024
8606
|
} else {
|
|
8025
8607
|
outputPricesTable(data.prices);
|
|
8026
8608
|
}
|
|
8027
|
-
await trackPaymentUsage("prices.list", true, {
|
|
8028
|
-
|
|
8029
|
-
|
|
8030
|
-
environment: opts.environment
|
|
8609
|
+
await trackPaymentUsage("prices.list", true, {
|
|
8610
|
+
provider: "stripe",
|
|
8611
|
+
environment
|
|
8031
8612
|
});
|
|
8613
|
+
} catch (err) {
|
|
8614
|
+
await trackPaymentUsage(
|
|
8615
|
+
"prices.list",
|
|
8616
|
+
false,
|
|
8617
|
+
{
|
|
8618
|
+
provider: "stripe",
|
|
8619
|
+
environment: opts.environment
|
|
8620
|
+
},
|
|
8621
|
+
err
|
|
8622
|
+
);
|
|
8032
8623
|
handleError(err, json);
|
|
8033
8624
|
}
|
|
8034
8625
|
});
|
|
@@ -8040,17 +8631,26 @@ function registerPaymentsPricesCommand(paymentsCmd2) {
|
|
|
8040
8631
|
try {
|
|
8041
8632
|
const environment = parseEnvironment(opts.environment);
|
|
8042
8633
|
await requireAuth();
|
|
8043
|
-
const data = await
|
|
8634
|
+
const data = await getStripePrice(environment, priceId);
|
|
8044
8635
|
if (json) {
|
|
8045
8636
|
outputJson(data);
|
|
8046
8637
|
} else {
|
|
8047
8638
|
outputPricesTable([data.price]);
|
|
8048
8639
|
}
|
|
8049
|
-
await trackPaymentUsage("prices.get", true, {
|
|
8050
|
-
|
|
8051
|
-
|
|
8052
|
-
environment: opts.environment
|
|
8640
|
+
await trackPaymentUsage("prices.get", true, {
|
|
8641
|
+
provider: "stripe",
|
|
8642
|
+
environment
|
|
8053
8643
|
});
|
|
8644
|
+
} catch (err) {
|
|
8645
|
+
await trackPaymentUsage(
|
|
8646
|
+
"prices.get",
|
|
8647
|
+
false,
|
|
8648
|
+
{
|
|
8649
|
+
provider: "stripe",
|
|
8650
|
+
environment: opts.environment
|
|
8651
|
+
},
|
|
8652
|
+
err
|
|
8653
|
+
);
|
|
8054
8654
|
handleError(err, json);
|
|
8055
8655
|
}
|
|
8056
8656
|
});
|
|
@@ -8081,11 +8681,11 @@ function registerPaymentsPricesCommand(paymentsCmd2) {
|
|
|
8081
8681
|
throw new CLIError("Provide --interval when using --interval-count.");
|
|
8082
8682
|
}
|
|
8083
8683
|
const request = {
|
|
8084
|
-
|
|
8684
|
+
productId: opts.product,
|
|
8085
8685
|
currency: opts.currency,
|
|
8086
8686
|
unitAmount: parseIntegerOption(opts.unitAmount, "--unit-amount", { min: 0 }) ?? 0
|
|
8087
8687
|
};
|
|
8088
|
-
const lookupKey =
|
|
8688
|
+
const lookupKey = nullableString3(opts.lookupKey);
|
|
8089
8689
|
const active = parseBooleanOption(opts.active, "--active");
|
|
8090
8690
|
const taxBehavior = parseTaxBehavior(opts.taxBehavior);
|
|
8091
8691
|
const metadata = parseMetadataOption(opts.metadata);
|
|
@@ -8102,17 +8702,26 @@ function registerPaymentsPricesCommand(paymentsCmd2) {
|
|
|
8102
8702
|
...intervalCount !== void 0 ? { intervalCount } : {}
|
|
8103
8703
|
};
|
|
8104
8704
|
}
|
|
8105
|
-
const data = await
|
|
8705
|
+
const data = await createStripePrice(environment, request);
|
|
8106
8706
|
if (json) {
|
|
8107
8707
|
outputJson(data);
|
|
8108
8708
|
} else {
|
|
8109
|
-
outputSuccess(`Stripe price created: ${data.price.
|
|
8709
|
+
outputSuccess(`Stripe price created: ${data.price.priceId}`);
|
|
8110
8710
|
}
|
|
8111
|
-
await trackPaymentUsage("prices.create", true, {
|
|
8112
|
-
|
|
8113
|
-
|
|
8114
|
-
environment: opts.environment
|
|
8711
|
+
await trackPaymentUsage("prices.create", true, {
|
|
8712
|
+
provider: "stripe",
|
|
8713
|
+
environment
|
|
8115
8714
|
});
|
|
8715
|
+
} catch (err) {
|
|
8716
|
+
await trackPaymentUsage(
|
|
8717
|
+
"prices.create",
|
|
8718
|
+
false,
|
|
8719
|
+
{
|
|
8720
|
+
provider: "stripe",
|
|
8721
|
+
environment: opts.environment
|
|
8722
|
+
},
|
|
8723
|
+
err
|
|
8724
|
+
);
|
|
8116
8725
|
handleError(err, json);
|
|
8117
8726
|
}
|
|
8118
8727
|
});
|
|
@@ -8126,7 +8735,7 @@ function registerPaymentsPricesCommand(paymentsCmd2) {
|
|
|
8126
8735
|
await requireAuth();
|
|
8127
8736
|
const request = {};
|
|
8128
8737
|
const active = parseBooleanOption(opts.active, "--active");
|
|
8129
|
-
const lookupKey =
|
|
8738
|
+
const lookupKey = nullableString3(opts.lookupKey);
|
|
8130
8739
|
const taxBehavior = parseTaxBehavior(opts.taxBehavior);
|
|
8131
8740
|
const metadata = parseMetadataOption(opts.metadata);
|
|
8132
8741
|
if (active !== void 0) request.active = active;
|
|
@@ -8138,21 +8747,30 @@ function registerPaymentsPricesCommand(paymentsCmd2) {
|
|
|
8138
8747
|
"Provide at least one option to update (--active, --lookup-key, --tax-behavior, --metadata)."
|
|
8139
8748
|
);
|
|
8140
8749
|
}
|
|
8141
|
-
const data = await
|
|
8750
|
+
const data = await updateStripePrice(environment, priceId, request);
|
|
8142
8751
|
if (json) {
|
|
8143
8752
|
outputJson(data);
|
|
8144
8753
|
} else {
|
|
8145
|
-
outputSuccess(`Stripe price updated: ${data.price.
|
|
8754
|
+
outputSuccess(`Stripe price updated: ${data.price.priceId}`);
|
|
8146
8755
|
}
|
|
8147
|
-
await trackPaymentUsage("prices.update", true, {
|
|
8148
|
-
|
|
8149
|
-
|
|
8150
|
-
environment: opts.environment
|
|
8756
|
+
await trackPaymentUsage("prices.update", true, {
|
|
8757
|
+
provider: "stripe",
|
|
8758
|
+
environment
|
|
8151
8759
|
});
|
|
8760
|
+
} catch (err) {
|
|
8761
|
+
await trackPaymentUsage(
|
|
8762
|
+
"prices.update",
|
|
8763
|
+
false,
|
|
8764
|
+
{
|
|
8765
|
+
provider: "stripe",
|
|
8766
|
+
environment: opts.environment
|
|
8767
|
+
},
|
|
8768
|
+
err
|
|
8769
|
+
);
|
|
8152
8770
|
handleError(err, json);
|
|
8153
8771
|
}
|
|
8154
8772
|
});
|
|
8155
|
-
pricesCmd.command("archive <priceId>").
|
|
8773
|
+
pricesCmd.command("archive <priceId>").description("Archive a Stripe price").requiredOption(
|
|
8156
8774
|
"--environment <environment>",
|
|
8157
8775
|
"Stripe environment: test or live"
|
|
8158
8776
|
).action(async (priceId, opts, cmd) => {
|
|
@@ -8160,24 +8778,33 @@ function registerPaymentsPricesCommand(paymentsCmd2) {
|
|
|
8160
8778
|
try {
|
|
8161
8779
|
const environment = parseEnvironment(opts.environment);
|
|
8162
8780
|
await requireAuth();
|
|
8163
|
-
const data = await
|
|
8781
|
+
const data = await archiveStripePrice(environment, priceId);
|
|
8164
8782
|
if (json) {
|
|
8165
8783
|
outputJson(data);
|
|
8166
8784
|
} else {
|
|
8167
|
-
outputSuccess(`Stripe price archived: ${data.price.
|
|
8785
|
+
outputSuccess(`Stripe price archived: ${data.price.priceId}`);
|
|
8168
8786
|
}
|
|
8169
|
-
await trackPaymentUsage("prices.archive", true, {
|
|
8170
|
-
|
|
8171
|
-
|
|
8172
|
-
environment: opts.environment
|
|
8787
|
+
await trackPaymentUsage("prices.archive", true, {
|
|
8788
|
+
provider: "stripe",
|
|
8789
|
+
environment
|
|
8173
8790
|
});
|
|
8791
|
+
} catch (err) {
|
|
8792
|
+
await trackPaymentUsage(
|
|
8793
|
+
"prices.archive",
|
|
8794
|
+
false,
|
|
8795
|
+
{
|
|
8796
|
+
provider: "stripe",
|
|
8797
|
+
environment: opts.environment
|
|
8798
|
+
},
|
|
8799
|
+
err
|
|
8800
|
+
);
|
|
8174
8801
|
handleError(err, json);
|
|
8175
8802
|
}
|
|
8176
8803
|
});
|
|
8177
8804
|
}
|
|
8178
8805
|
|
|
8179
8806
|
// src/commands/payments/products.ts
|
|
8180
|
-
function
|
|
8807
|
+
function nullableString4(value) {
|
|
8181
8808
|
if (value === void 0) return void 0;
|
|
8182
8809
|
return value === "null" ? null : value;
|
|
8183
8810
|
}
|
|
@@ -8190,7 +8817,7 @@ function outputProductsTable(products) {
|
|
|
8190
8817
|
["Env", "Product ID", "Name", "Active", "Default Price", "Synced At"],
|
|
8191
8818
|
products.map((product) => [
|
|
8192
8819
|
product.environment,
|
|
8193
|
-
product.
|
|
8820
|
+
product.productId,
|
|
8194
8821
|
product.name,
|
|
8195
8822
|
product.active ? "Yes" : "No",
|
|
8196
8823
|
product.defaultPriceId ?? "-",
|
|
@@ -8208,17 +8835,26 @@ function registerPaymentsProductsCommand(paymentsCmd2) {
|
|
|
8208
8835
|
try {
|
|
8209
8836
|
const environment = parseEnvironment(opts.environment);
|
|
8210
8837
|
await requireAuth();
|
|
8211
|
-
const data = await
|
|
8838
|
+
const data = await listStripeProducts(environment);
|
|
8212
8839
|
if (json) {
|
|
8213
8840
|
outputJson(data);
|
|
8214
8841
|
} else {
|
|
8215
8842
|
outputProductsTable(data.products);
|
|
8216
8843
|
}
|
|
8217
|
-
await trackPaymentUsage("products.list", true, {
|
|
8218
|
-
|
|
8219
|
-
|
|
8220
|
-
environment: opts.environment
|
|
8844
|
+
await trackPaymentUsage("products.list", true, {
|
|
8845
|
+
provider: "stripe",
|
|
8846
|
+
environment
|
|
8221
8847
|
});
|
|
8848
|
+
} catch (err) {
|
|
8849
|
+
await trackPaymentUsage(
|
|
8850
|
+
"products.list",
|
|
8851
|
+
false,
|
|
8852
|
+
{
|
|
8853
|
+
provider: "stripe",
|
|
8854
|
+
environment: opts.environment
|
|
8855
|
+
},
|
|
8856
|
+
err
|
|
8857
|
+
);
|
|
8222
8858
|
handleError(err, json);
|
|
8223
8859
|
}
|
|
8224
8860
|
});
|
|
@@ -8230,7 +8866,7 @@ function registerPaymentsProductsCommand(paymentsCmd2) {
|
|
|
8230
8866
|
try {
|
|
8231
8867
|
const environment = parseEnvironment(opts.environment);
|
|
8232
8868
|
await requireAuth();
|
|
8233
|
-
const data = await
|
|
8869
|
+
const data = await getStripeProduct(environment, productId);
|
|
8234
8870
|
if (json) {
|
|
8235
8871
|
outputJson(data);
|
|
8236
8872
|
} else {
|
|
@@ -8240,7 +8876,7 @@ function registerPaymentsProductsCommand(paymentsCmd2) {
|
|
|
8240
8876
|
outputTable(
|
|
8241
8877
|
["Price ID", "Amount", "Type", "Active", "Lookup Key"],
|
|
8242
8878
|
data.prices.map((price) => [
|
|
8243
|
-
price.
|
|
8879
|
+
price.priceId,
|
|
8244
8880
|
formatAmount(price.unitAmount, price.currency),
|
|
8245
8881
|
price.type,
|
|
8246
8882
|
price.active ? "Yes" : "No",
|
|
@@ -8249,11 +8885,20 @@ function registerPaymentsProductsCommand(paymentsCmd2) {
|
|
|
8249
8885
|
);
|
|
8250
8886
|
}
|
|
8251
8887
|
}
|
|
8252
|
-
await trackPaymentUsage("products.get", true, {
|
|
8253
|
-
|
|
8254
|
-
|
|
8255
|
-
environment: opts.environment
|
|
8888
|
+
await trackPaymentUsage("products.get", true, {
|
|
8889
|
+
provider: "stripe",
|
|
8890
|
+
environment
|
|
8256
8891
|
});
|
|
8892
|
+
} catch (err) {
|
|
8893
|
+
await trackPaymentUsage(
|
|
8894
|
+
"products.get",
|
|
8895
|
+
false,
|
|
8896
|
+
{
|
|
8897
|
+
provider: "stripe",
|
|
8898
|
+
environment: opts.environment
|
|
8899
|
+
},
|
|
8900
|
+
err
|
|
8901
|
+
);
|
|
8257
8902
|
handleError(err, json);
|
|
8258
8903
|
}
|
|
8259
8904
|
});
|
|
@@ -8266,7 +8911,7 @@ function registerPaymentsProductsCommand(paymentsCmd2) {
|
|
|
8266
8911
|
const environment = parseEnvironment(opts.environment);
|
|
8267
8912
|
await requireAuth();
|
|
8268
8913
|
const request = { name: opts.name };
|
|
8269
|
-
const description =
|
|
8914
|
+
const description = nullableString4(opts.description);
|
|
8270
8915
|
const active = parseBooleanOption(opts.active, "--active");
|
|
8271
8916
|
const metadata = parseMetadataOption(opts.metadata);
|
|
8272
8917
|
if (description !== void 0) request.description = description;
|
|
@@ -8275,19 +8920,26 @@ function registerPaymentsProductsCommand(paymentsCmd2) {
|
|
|
8275
8920
|
if (opts.idempotencyKey !== void 0) {
|
|
8276
8921
|
request.idempotencyKey = opts.idempotencyKey;
|
|
8277
8922
|
}
|
|
8278
|
-
const data = await
|
|
8923
|
+
const data = await createStripeProduct(environment, request);
|
|
8279
8924
|
if (json) {
|
|
8280
8925
|
outputJson(data);
|
|
8281
8926
|
} else {
|
|
8282
|
-
outputSuccess(
|
|
8283
|
-
`Stripe product created: ${data.product.stripeProductId}`
|
|
8284
|
-
);
|
|
8927
|
+
outputSuccess(`Stripe product created: ${data.product.productId}`);
|
|
8285
8928
|
}
|
|
8286
|
-
await trackPaymentUsage("products.create", true, {
|
|
8287
|
-
|
|
8288
|
-
|
|
8289
|
-
environment: opts.environment
|
|
8929
|
+
await trackPaymentUsage("products.create", true, {
|
|
8930
|
+
provider: "stripe",
|
|
8931
|
+
environment
|
|
8290
8932
|
});
|
|
8933
|
+
} catch (err) {
|
|
8934
|
+
await trackPaymentUsage(
|
|
8935
|
+
"products.create",
|
|
8936
|
+
false,
|
|
8937
|
+
{
|
|
8938
|
+
provider: "stripe",
|
|
8939
|
+
environment: opts.environment
|
|
8940
|
+
},
|
|
8941
|
+
err
|
|
8942
|
+
);
|
|
8291
8943
|
handleError(err, json);
|
|
8292
8944
|
}
|
|
8293
8945
|
});
|
|
@@ -8300,7 +8952,7 @@ function registerPaymentsProductsCommand(paymentsCmd2) {
|
|
|
8300
8952
|
const environment = parseEnvironment(opts.environment);
|
|
8301
8953
|
await requireAuth();
|
|
8302
8954
|
const request = {};
|
|
8303
|
-
const description =
|
|
8955
|
+
const description = nullableString4(opts.description);
|
|
8304
8956
|
const active = parseBooleanOption(opts.active, "--active");
|
|
8305
8957
|
const metadata = parseMetadataOption(opts.metadata);
|
|
8306
8958
|
if (opts.name !== void 0) request.name = opts.name;
|
|
@@ -8312,23 +8964,26 @@ function registerPaymentsProductsCommand(paymentsCmd2) {
|
|
|
8312
8964
|
"Provide at least one option to update (--name, --description, --active, --metadata)."
|
|
8313
8965
|
);
|
|
8314
8966
|
}
|
|
8315
|
-
const data = await
|
|
8316
|
-
environment,
|
|
8317
|
-
productId,
|
|
8318
|
-
request
|
|
8319
|
-
);
|
|
8967
|
+
const data = await updateStripeProduct(environment, productId, request);
|
|
8320
8968
|
if (json) {
|
|
8321
8969
|
outputJson(data);
|
|
8322
8970
|
} else {
|
|
8323
|
-
outputSuccess(
|
|
8324
|
-
`Stripe product updated: ${data.product.stripeProductId}`
|
|
8325
|
-
);
|
|
8971
|
+
outputSuccess(`Stripe product updated: ${data.product.productId}`);
|
|
8326
8972
|
}
|
|
8327
|
-
await trackPaymentUsage("products.update", true, {
|
|
8328
|
-
|
|
8329
|
-
|
|
8330
|
-
environment: opts.environment
|
|
8973
|
+
await trackPaymentUsage("products.update", true, {
|
|
8974
|
+
provider: "stripe",
|
|
8975
|
+
environment
|
|
8331
8976
|
});
|
|
8977
|
+
} catch (err) {
|
|
8978
|
+
await trackPaymentUsage(
|
|
8979
|
+
"products.update",
|
|
8980
|
+
false,
|
|
8981
|
+
{
|
|
8982
|
+
provider: "stripe",
|
|
8983
|
+
environment: opts.environment
|
|
8984
|
+
},
|
|
8985
|
+
err
|
|
8986
|
+
);
|
|
8332
8987
|
handleError(err, json);
|
|
8333
8988
|
}
|
|
8334
8989
|
});
|
|
@@ -8351,153 +9006,357 @@ function registerPaymentsProductsCommand(paymentsCmd2) {
|
|
|
8351
9006
|
});
|
|
8352
9007
|
if (isCancel2(confirm8) || !confirm8) process.exit(0);
|
|
8353
9008
|
}
|
|
8354
|
-
const data = await
|
|
9009
|
+
const data = await deleteStripeProduct(environment, productId);
|
|
8355
9010
|
if (json) {
|
|
8356
9011
|
outputJson(data);
|
|
8357
9012
|
} else {
|
|
8358
|
-
outputSuccess(`Stripe product deleted: ${data.
|
|
9013
|
+
outputSuccess(`Stripe product deleted: ${data.productId}`);
|
|
8359
9014
|
}
|
|
8360
|
-
await trackPaymentUsage("products.delete", true, {
|
|
8361
|
-
|
|
8362
|
-
|
|
8363
|
-
environment: opts.environment
|
|
9015
|
+
await trackPaymentUsage("products.delete", true, {
|
|
9016
|
+
provider: "stripe",
|
|
9017
|
+
environment
|
|
8364
9018
|
});
|
|
9019
|
+
} catch (err) {
|
|
9020
|
+
await trackPaymentUsage(
|
|
9021
|
+
"products.delete",
|
|
9022
|
+
false,
|
|
9023
|
+
{
|
|
9024
|
+
provider: "stripe",
|
|
9025
|
+
environment: opts.environment
|
|
9026
|
+
},
|
|
9027
|
+
err
|
|
9028
|
+
);
|
|
8365
9029
|
handleError(err, json);
|
|
8366
9030
|
}
|
|
8367
9031
|
});
|
|
8368
9032
|
}
|
|
8369
9033
|
|
|
8370
9034
|
// src/commands/payments/status.ts
|
|
8371
|
-
function registerPaymentsStatusCommand(paymentsCmd2) {
|
|
8372
|
-
paymentsCmd2.command("status").description("Show
|
|
9035
|
+
function registerPaymentsStatusCommand(paymentsCmd2, provider) {
|
|
9036
|
+
paymentsCmd2.command("status").description("Show payment connection, sync, and webhook status").action(async (opts, cmd) => {
|
|
8373
9037
|
const { json } = getRootOpts(cmd);
|
|
8374
9038
|
try {
|
|
8375
9039
|
await requireAuth();
|
|
8376
|
-
|
|
8377
|
-
|
|
8378
|
-
|
|
8379
|
-
|
|
8380
|
-
|
|
9040
|
+
if (provider === "stripe") {
|
|
9041
|
+
const data = await getStripePaymentsStatus();
|
|
9042
|
+
if (json) {
|
|
9043
|
+
outputJson(data);
|
|
9044
|
+
} else if (data.connections.length === 0) {
|
|
9045
|
+
console.log("No Stripe payment environments found.");
|
|
9046
|
+
} else {
|
|
9047
|
+
outputTable(
|
|
9048
|
+
[
|
|
9049
|
+
"Env",
|
|
9050
|
+
"Status",
|
|
9051
|
+
"Key",
|
|
9052
|
+
"Account",
|
|
9053
|
+
"Webhook",
|
|
9054
|
+
"Last Sync",
|
|
9055
|
+
"Synced At"
|
|
9056
|
+
],
|
|
9057
|
+
data.connections.map((connection) => [
|
|
9058
|
+
connection.environment,
|
|
9059
|
+
connection.status,
|
|
9060
|
+
connection.maskedKey ?? "-",
|
|
9061
|
+
connection.accountId ?? "-",
|
|
9062
|
+
connection.webhookEndpointId ? "Configured" : "-",
|
|
9063
|
+
connection.lastSyncStatus ?? "-",
|
|
9064
|
+
formatDate(connection.lastSyncedAt)
|
|
9065
|
+
])
|
|
9066
|
+
);
|
|
9067
|
+
}
|
|
8381
9068
|
} else {
|
|
8382
|
-
|
|
8383
|
-
|
|
8384
|
-
data
|
|
8385
|
-
|
|
8386
|
-
|
|
8387
|
-
|
|
8388
|
-
|
|
8389
|
-
|
|
8390
|
-
|
|
8391
|
-
|
|
8392
|
-
|
|
8393
|
-
|
|
9069
|
+
const data = await getRazorpayPaymentsStatus();
|
|
9070
|
+
if (json) {
|
|
9071
|
+
outputJson(data);
|
|
9072
|
+
} else if (data.razorpayConnections.length === 0) {
|
|
9073
|
+
console.log("No Razorpay payment environments found.");
|
|
9074
|
+
} else {
|
|
9075
|
+
outputTable(
|
|
9076
|
+
[
|
|
9077
|
+
"Env",
|
|
9078
|
+
"Status",
|
|
9079
|
+
"Key",
|
|
9080
|
+
"Account",
|
|
9081
|
+
"Merchant",
|
|
9082
|
+
"Webhook",
|
|
9083
|
+
"Last Sync",
|
|
9084
|
+
"Synced At"
|
|
9085
|
+
],
|
|
9086
|
+
data.razorpayConnections.map((connection) => [
|
|
9087
|
+
connection.environment,
|
|
9088
|
+
connection.status,
|
|
9089
|
+
connection.maskedKey ?? "-",
|
|
9090
|
+
connection.accountId ?? "-",
|
|
9091
|
+
connection.merchantName ?? "-",
|
|
9092
|
+
connection.webhookEndpointUrl ? "Manual" : "-",
|
|
9093
|
+
connection.lastSyncStatus ?? "-",
|
|
9094
|
+
formatDate(connection.lastSyncedAt)
|
|
9095
|
+
])
|
|
9096
|
+
);
|
|
9097
|
+
}
|
|
8394
9098
|
}
|
|
8395
|
-
await trackPaymentUsage("status", true);
|
|
9099
|
+
await trackPaymentUsage("status", true, { provider });
|
|
8396
9100
|
} catch (err) {
|
|
8397
|
-
await trackPaymentUsage("status", false);
|
|
9101
|
+
await trackPaymentUsage("status", false, { provider }, err);
|
|
8398
9102
|
handleError(err, json);
|
|
8399
9103
|
}
|
|
8400
9104
|
});
|
|
8401
9105
|
}
|
|
8402
9106
|
|
|
8403
9107
|
// src/commands/payments/subscriptions.ts
|
|
8404
|
-
function
|
|
8405
|
-
|
|
9108
|
+
function formatSubject(subjectType, subjectId) {
|
|
9109
|
+
return subjectType && subjectId ? `${subjectType}:${subjectId}` : "-";
|
|
9110
|
+
}
|
|
9111
|
+
function registerPaymentsSubscriptionsCommand(paymentsCmd2, provider) {
|
|
9112
|
+
paymentsCmd2.command("subscriptions").description("List mirrored payment provider subscriptions").requiredOption(
|
|
8406
9113
|
"--environment <environment>",
|
|
8407
|
-
"
|
|
8408
|
-
).option("--subject-type <type>", "Filter by billing subject type").option(
|
|
9114
|
+
"Payment environment: test or live"
|
|
9115
|
+
).option("--subject-type <type>", "Filter by app billing subject type").option(
|
|
9116
|
+
"--subject-id <id>",
|
|
9117
|
+
"Filter by app billing subject id, not provider id"
|
|
9118
|
+
).option("--limit <limit>", "Maximum rows to return (1-100)", "50").action(async (opts, cmd) => {
|
|
8409
9119
|
const { json } = getRootOpts(cmd);
|
|
8410
9120
|
try {
|
|
8411
9121
|
const environment = parseEnvironment(opts.environment);
|
|
8412
9122
|
const limit = parseIntegerOption(opts.limit, "--limit", { min: 1, max: 100 }) ?? 50;
|
|
8413
|
-
|
|
8414
|
-
const data = await listSubscriptions(environment, {
|
|
9123
|
+
const request = {
|
|
8415
9124
|
limit,
|
|
8416
9125
|
...opts.subjectType !== void 0 ? { subjectType: opts.subjectType } : {},
|
|
8417
9126
|
...opts.subjectId !== void 0 ? { subjectId: opts.subjectId } : {}
|
|
8418
|
-
}
|
|
8419
|
-
|
|
8420
|
-
|
|
8421
|
-
|
|
8422
|
-
|
|
9127
|
+
};
|
|
9128
|
+
await requireAuth();
|
|
9129
|
+
if (provider === "stripe") {
|
|
9130
|
+
const data = await listStripeSubscriptions(environment, request);
|
|
9131
|
+
if (json) {
|
|
9132
|
+
outputJson(data);
|
|
9133
|
+
} else if (data.subscriptions.length === 0) {
|
|
9134
|
+
console.log("No Stripe subscriptions found.");
|
|
9135
|
+
} else {
|
|
9136
|
+
outputTable(
|
|
9137
|
+
[
|
|
9138
|
+
"Subscription ID",
|
|
9139
|
+
"Customer",
|
|
9140
|
+
"Subject",
|
|
9141
|
+
"Status",
|
|
9142
|
+
"Items",
|
|
9143
|
+
"Period End"
|
|
9144
|
+
],
|
|
9145
|
+
data.subscriptions.map((subscription) => [
|
|
9146
|
+
subscription.subscriptionId,
|
|
9147
|
+
subscription.customerId ?? "-",
|
|
9148
|
+
formatSubject(subscription.subjectType, subscription.subjectId),
|
|
9149
|
+
subscription.status,
|
|
9150
|
+
String(subscription.items?.length ?? 0),
|
|
9151
|
+
formatDate(subscription.currentPeriodEnd)
|
|
9152
|
+
])
|
|
9153
|
+
);
|
|
9154
|
+
}
|
|
8423
9155
|
} else {
|
|
8424
|
-
|
|
8425
|
-
|
|
8426
|
-
|
|
8427
|
-
|
|
8428
|
-
|
|
8429
|
-
|
|
8430
|
-
|
|
8431
|
-
|
|
8432
|
-
|
|
8433
|
-
|
|
8434
|
-
|
|
8435
|
-
|
|
8436
|
-
|
|
8437
|
-
|
|
8438
|
-
|
|
8439
|
-
|
|
8440
|
-
|
|
8441
|
-
|
|
9156
|
+
const data = await listRazorpaySubscriptions(environment, request);
|
|
9157
|
+
if (json) {
|
|
9158
|
+
outputJson(data);
|
|
9159
|
+
} else if (data.subscriptions.length === 0) {
|
|
9160
|
+
console.log("No Razorpay subscriptions found.");
|
|
9161
|
+
} else {
|
|
9162
|
+
outputTable(
|
|
9163
|
+
[
|
|
9164
|
+
"Subscription ID",
|
|
9165
|
+
"Plan ID",
|
|
9166
|
+
"Customer",
|
|
9167
|
+
"Subject",
|
|
9168
|
+
"Status",
|
|
9169
|
+
"Paid",
|
|
9170
|
+
"Remaining",
|
|
9171
|
+
"Current End"
|
|
9172
|
+
],
|
|
9173
|
+
data.subscriptions.map((subscription) => [
|
|
9174
|
+
subscription.subscriptionId,
|
|
9175
|
+
subscription.planId,
|
|
9176
|
+
subscription.customerId ?? "-",
|
|
9177
|
+
formatSubject(subscription.subjectType, subscription.subjectId),
|
|
9178
|
+
subscription.status,
|
|
9179
|
+
String(subscription.paidCount ?? "-"),
|
|
9180
|
+
String(subscription.remainingCount ?? "-"),
|
|
9181
|
+
formatDate(subscription.currentEnd)
|
|
9182
|
+
])
|
|
9183
|
+
);
|
|
9184
|
+
}
|
|
8442
9185
|
}
|
|
8443
|
-
await trackPaymentUsage("subscriptions", true, {
|
|
8444
|
-
|
|
8445
|
-
|
|
8446
|
-
environment: opts.environment
|
|
9186
|
+
await trackPaymentUsage("subscriptions", true, {
|
|
9187
|
+
provider,
|
|
9188
|
+
environment
|
|
8447
9189
|
});
|
|
9190
|
+
} catch (err) {
|
|
9191
|
+
await trackPaymentUsage(
|
|
9192
|
+
"subscriptions",
|
|
9193
|
+
false,
|
|
9194
|
+
{
|
|
9195
|
+
provider,
|
|
9196
|
+
environment: opts.environment
|
|
9197
|
+
},
|
|
9198
|
+
err
|
|
9199
|
+
);
|
|
8448
9200
|
handleError(err, json);
|
|
8449
9201
|
}
|
|
8450
9202
|
});
|
|
8451
9203
|
}
|
|
8452
9204
|
|
|
8453
9205
|
// src/commands/payments/sync.ts
|
|
8454
|
-
function registerPaymentsSyncCommand(paymentsCmd2) {
|
|
8455
|
-
paymentsCmd2.command("sync").description(
|
|
8456
|
-
"Sync configured Stripe products, prices, customers, and subscriptions"
|
|
8457
|
-
).option(
|
|
9206
|
+
function registerPaymentsSyncCommand(paymentsCmd2, provider) {
|
|
9207
|
+
paymentsCmd2.command("sync").description("Sync configured payment provider data").option(
|
|
8458
9208
|
"--environment <environment>",
|
|
8459
|
-
"
|
|
9209
|
+
"Payment environment: test, live, or all",
|
|
8460
9210
|
"all"
|
|
8461
9211
|
).action(async (opts, cmd) => {
|
|
8462
9212
|
const { json } = getRootOpts(cmd);
|
|
8463
9213
|
try {
|
|
8464
9214
|
const environment = parseEnvironmentOrAll(opts.environment);
|
|
8465
9215
|
await requireAuth();
|
|
8466
|
-
|
|
9216
|
+
if (provider === "stripe") {
|
|
9217
|
+
const data = await syncStripePayments(environment);
|
|
9218
|
+
if (json) {
|
|
9219
|
+
outputJson(data);
|
|
9220
|
+
} else if (data.results.length === 0) {
|
|
9221
|
+
console.log("No configured Stripe environments to sync.");
|
|
9222
|
+
} else {
|
|
9223
|
+
outputTable(
|
|
9224
|
+
[
|
|
9225
|
+
"Env",
|
|
9226
|
+
"Status",
|
|
9227
|
+
"Products",
|
|
9228
|
+
"Prices",
|
|
9229
|
+
"Customers",
|
|
9230
|
+
"Subscriptions",
|
|
9231
|
+
"Unmapped",
|
|
9232
|
+
"Synced At"
|
|
9233
|
+
],
|
|
9234
|
+
data.results.map((result) => [
|
|
9235
|
+
result.environment,
|
|
9236
|
+
result.connection.lastSyncStatus ?? result.connection.status,
|
|
9237
|
+
String(result.connection.lastSyncCounts.products ?? 0),
|
|
9238
|
+
String(result.connection.lastSyncCounts.prices ?? 0),
|
|
9239
|
+
String(result.connection.lastSyncCounts.customers ?? 0),
|
|
9240
|
+
String(result.subscriptions?.synced ?? 0),
|
|
9241
|
+
String(result.subscriptions?.unmapped ?? 0),
|
|
9242
|
+
formatDate(result.connection.lastSyncedAt)
|
|
9243
|
+
])
|
|
9244
|
+
);
|
|
9245
|
+
outputSuccess("Stripe payments synced.");
|
|
9246
|
+
}
|
|
9247
|
+
} else {
|
|
9248
|
+
const data = await syncRazorpayPayments(environment);
|
|
9249
|
+
if (json) {
|
|
9250
|
+
outputJson(data);
|
|
9251
|
+
} else if (data.results.length === 0) {
|
|
9252
|
+
console.log("No configured Razorpay environments to sync.");
|
|
9253
|
+
} else {
|
|
9254
|
+
outputTable(
|
|
9255
|
+
[
|
|
9256
|
+
"Env",
|
|
9257
|
+
"Status",
|
|
9258
|
+
"Items",
|
|
9259
|
+
"Plans",
|
|
9260
|
+
"Customers",
|
|
9261
|
+
"Subscriptions",
|
|
9262
|
+
"Invoices",
|
|
9263
|
+
"Payments",
|
|
9264
|
+
"Synced At"
|
|
9265
|
+
],
|
|
9266
|
+
data.results.map((result) => [
|
|
9267
|
+
result.environment,
|
|
9268
|
+
result.status,
|
|
9269
|
+
String(result.syncCounts.items),
|
|
9270
|
+
String(result.syncCounts.plans),
|
|
9271
|
+
String(result.syncCounts.customers),
|
|
9272
|
+
String(result.syncCounts.subscriptions),
|
|
9273
|
+
String(result.syncCounts.invoices),
|
|
9274
|
+
String(result.syncCounts.payments),
|
|
9275
|
+
formatDate(result.connection.lastSyncedAt)
|
|
9276
|
+
])
|
|
9277
|
+
);
|
|
9278
|
+
outputSuccess("Razorpay payments synced.");
|
|
9279
|
+
}
|
|
9280
|
+
}
|
|
9281
|
+
await trackPaymentUsage("sync", true, { provider, environment });
|
|
9282
|
+
} catch (err) {
|
|
9283
|
+
await trackPaymentUsage(
|
|
9284
|
+
"sync",
|
|
9285
|
+
false,
|
|
9286
|
+
{
|
|
9287
|
+
provider,
|
|
9288
|
+
environment: opts.environment
|
|
9289
|
+
},
|
|
9290
|
+
err
|
|
9291
|
+
);
|
|
9292
|
+
handleError(err, json);
|
|
9293
|
+
}
|
|
9294
|
+
});
|
|
9295
|
+
}
|
|
9296
|
+
|
|
9297
|
+
// src/commands/payments/transactions.ts
|
|
9298
|
+
function registerPaymentsTransactionsCommand(paymentsCmd2, provider) {
|
|
9299
|
+
paymentsCmd2.command("transactions").description("List mirrored payment transactions").requiredOption(
|
|
9300
|
+
"--environment <environment>",
|
|
9301
|
+
"Payment environment: test or live"
|
|
9302
|
+
).option("--subject-type <type>", "Filter by app billing subject type").option(
|
|
9303
|
+
"--subject-id <id>",
|
|
9304
|
+
"Filter by app billing subject id, not provider id"
|
|
9305
|
+
).option("--limit <limit>", "Maximum rows to return (1-100)", "50").action(async (opts, cmd) => {
|
|
9306
|
+
const { json } = getRootOpts(cmd);
|
|
9307
|
+
try {
|
|
9308
|
+
const environment = parseEnvironment(opts.environment);
|
|
9309
|
+
const limit = parseIntegerOption(opts.limit, "--limit", { min: 1, max: 100 }) ?? 50;
|
|
9310
|
+
await requireAuth();
|
|
9311
|
+
const data = await listPaymentTransactions(provider, environment, {
|
|
9312
|
+
limit,
|
|
9313
|
+
...opts.subjectType !== void 0 ? { subjectType: opts.subjectType } : {},
|
|
9314
|
+
...opts.subjectId !== void 0 ? { subjectId: opts.subjectId } : {}
|
|
9315
|
+
});
|
|
8467
9316
|
if (json) {
|
|
8468
9317
|
outputJson(data);
|
|
8469
|
-
} else if (data.
|
|
8470
|
-
console.log(
|
|
9318
|
+
} else if (data.transactions.length === 0) {
|
|
9319
|
+
console.log(`No ${provider} transactions found.`);
|
|
8471
9320
|
} else {
|
|
8472
9321
|
outputTable(
|
|
8473
9322
|
[
|
|
8474
|
-
"
|
|
9323
|
+
"Type",
|
|
8475
9324
|
"Status",
|
|
8476
|
-
"
|
|
8477
|
-
"
|
|
8478
|
-
"
|
|
8479
|
-
"
|
|
8480
|
-
"
|
|
8481
|
-
"
|
|
9325
|
+
"Subject",
|
|
9326
|
+
"Amount",
|
|
9327
|
+
"Refunded",
|
|
9328
|
+
"Customer",
|
|
9329
|
+
"Provider Object",
|
|
9330
|
+
"When"
|
|
8482
9331
|
],
|
|
8483
|
-
data.
|
|
8484
|
-
|
|
8485
|
-
|
|
8486
|
-
|
|
8487
|
-
|
|
8488
|
-
|
|
8489
|
-
|
|
8490
|
-
|
|
8491
|
-
formatDate(
|
|
9332
|
+
data.transactions.map((entry) => [
|
|
9333
|
+
entry.type,
|
|
9334
|
+
entry.status,
|
|
9335
|
+
entry.subjectType && entry.subjectId ? `${entry.subjectType}:${entry.subjectId}` : "-",
|
|
9336
|
+
formatAmount(entry.amount, entry.currency),
|
|
9337
|
+
formatAmount(entry.amountRefunded, entry.currency),
|
|
9338
|
+
entry.providerCustomerId ?? entry.customerEmailSnapshot ?? "-",
|
|
9339
|
+
entry.providerReferenceType && entry.providerReferenceId ? `${entry.providerReferenceType}:${entry.providerReferenceId}` : entry.providerReferenceId ?? "-",
|
|
9340
|
+
formatDate(
|
|
9341
|
+
entry.paidAt ?? entry.failedAt ?? entry.refundedAt ?? entry.providerCreatedAt ?? entry.createdAt
|
|
9342
|
+
)
|
|
8492
9343
|
])
|
|
8493
9344
|
);
|
|
8494
|
-
outputSuccess("Stripe payments synced.");
|
|
8495
9345
|
}
|
|
8496
|
-
await trackPaymentUsage("
|
|
8497
|
-
|
|
8498
|
-
|
|
8499
|
-
environment: opts.environment
|
|
9346
|
+
await trackPaymentUsage("transactions", true, {
|
|
9347
|
+
provider,
|
|
9348
|
+
environment
|
|
8500
9349
|
});
|
|
9350
|
+
} catch (err) {
|
|
9351
|
+
await trackPaymentUsage(
|
|
9352
|
+
"transactions",
|
|
9353
|
+
false,
|
|
9354
|
+
{
|
|
9355
|
+
provider,
|
|
9356
|
+
environment: opts.environment
|
|
9357
|
+
},
|
|
9358
|
+
err
|
|
9359
|
+
);
|
|
8501
9360
|
handleError(err, json);
|
|
8502
9361
|
}
|
|
8503
9362
|
});
|
|
@@ -8505,30 +9364,46 @@ function registerPaymentsSyncCommand(paymentsCmd2) {
|
|
|
8505
9364
|
|
|
8506
9365
|
// src/commands/payments/webhooks.ts
|
|
8507
9366
|
function registerPaymentsWebhooksCommand(paymentsCmd2) {
|
|
8508
|
-
const webhooksCmd = paymentsCmd2.command("webhooks").description("Manage
|
|
8509
|
-
webhooksCmd.command("configure
|
|
9367
|
+
const webhooksCmd = paymentsCmd2.command("webhooks").description("Manage Stripe webhooks");
|
|
9368
|
+
webhooksCmd.command("configure").description("Create or recreate the managed Stripe webhook endpoint").requiredOption(
|
|
9369
|
+
"--environment <environment>",
|
|
9370
|
+
"Stripe environment: test or live"
|
|
9371
|
+
).action(async (opts, cmd) => {
|
|
8510
9372
|
const { json } = getRootOpts(cmd);
|
|
8511
9373
|
try {
|
|
8512
|
-
const environment = parseEnvironment(
|
|
9374
|
+
const environment = parseEnvironment(opts.environment);
|
|
8513
9375
|
await requireAuth();
|
|
8514
|
-
const data = await
|
|
9376
|
+
const data = await configureStripeWebhook(environment);
|
|
8515
9377
|
if (json) {
|
|
8516
9378
|
outputJson(data);
|
|
8517
9379
|
} else {
|
|
8518
9380
|
outputTable(
|
|
8519
9381
|
["Env", "Webhook ID", "URL", "Configured At"],
|
|
8520
|
-
[
|
|
8521
|
-
|
|
8522
|
-
|
|
8523
|
-
|
|
8524
|
-
|
|
8525
|
-
|
|
9382
|
+
[
|
|
9383
|
+
[
|
|
9384
|
+
data.connection.environment,
|
|
9385
|
+
data.connection.webhookEndpointId ?? "-",
|
|
9386
|
+
data.connection.webhookEndpointUrl ?? "-",
|
|
9387
|
+
formatDate(data.connection.webhookConfiguredAt)
|
|
9388
|
+
]
|
|
9389
|
+
]
|
|
8526
9390
|
);
|
|
8527
9391
|
outputSuccess(`Stripe ${environment} webhook configured.`);
|
|
8528
9392
|
}
|
|
8529
|
-
await trackPaymentUsage("webhooks.configure", true, {
|
|
9393
|
+
await trackPaymentUsage("webhooks.configure", true, {
|
|
9394
|
+
provider: "stripe",
|
|
9395
|
+
environment
|
|
9396
|
+
});
|
|
8530
9397
|
} catch (err) {
|
|
8531
|
-
await trackPaymentUsage(
|
|
9398
|
+
await trackPaymentUsage(
|
|
9399
|
+
"webhooks.configure",
|
|
9400
|
+
false,
|
|
9401
|
+
{
|
|
9402
|
+
provider: "stripe",
|
|
9403
|
+
environment: opts.environment
|
|
9404
|
+
},
|
|
9405
|
+
err
|
|
9406
|
+
);
|
|
8532
9407
|
handleError(err, json);
|
|
8533
9408
|
}
|
|
8534
9409
|
});
|
|
@@ -8536,17 +9411,28 @@ function registerPaymentsWebhooksCommand(paymentsCmd2) {
|
|
|
8536
9411
|
|
|
8537
9412
|
// src/commands/payments/index.ts
|
|
8538
9413
|
function registerPaymentsCommands(paymentsCmd2) {
|
|
8539
|
-
paymentsCmd2.description("Manage
|
|
8540
|
-
|
|
8541
|
-
|
|
8542
|
-
|
|
8543
|
-
|
|
8544
|
-
|
|
8545
|
-
|
|
8546
|
-
|
|
8547
|
-
|
|
8548
|
-
|
|
8549
|
-
|
|
9414
|
+
paymentsCmd2.description("Manage payments");
|
|
9415
|
+
const stripeCmd = paymentsCmd2.command("stripe").description("Manage Stripe payments");
|
|
9416
|
+
registerPaymentsStatusCommand(stripeCmd, "stripe");
|
|
9417
|
+
registerPaymentsConfigCommand(stripeCmd, "stripe");
|
|
9418
|
+
registerPaymentsSyncCommand(stripeCmd, "stripe");
|
|
9419
|
+
registerPaymentsWebhooksCommand(stripeCmd);
|
|
9420
|
+
registerPaymentsCatalogCommand(stripeCmd, "stripe");
|
|
9421
|
+
registerPaymentsCustomersCommand(stripeCmd, "stripe");
|
|
9422
|
+
registerPaymentsProductsCommand(stripeCmd);
|
|
9423
|
+
registerPaymentsPricesCommand(stripeCmd);
|
|
9424
|
+
registerPaymentsSubscriptionsCommand(stripeCmd, "stripe");
|
|
9425
|
+
registerPaymentsTransactionsCommand(stripeCmd, "stripe");
|
|
9426
|
+
const razorpayCmd = paymentsCmd2.command("razorpay").description("Manage Razorpay payments");
|
|
9427
|
+
registerPaymentsStatusCommand(razorpayCmd, "razorpay");
|
|
9428
|
+
registerPaymentsConfigCommand(razorpayCmd, "razorpay");
|
|
9429
|
+
registerPaymentsSyncCommand(razorpayCmd, "razorpay");
|
|
9430
|
+
registerPaymentsCatalogCommand(razorpayCmd, "razorpay");
|
|
9431
|
+
registerPaymentsCustomersCommand(razorpayCmd, "razorpay");
|
|
9432
|
+
registerPaymentsItemsCommand(razorpayCmd);
|
|
9433
|
+
registerPaymentsPlansCommand(razorpayCmd);
|
|
9434
|
+
registerPaymentsSubscriptionsCommand(razorpayCmd, "razorpay");
|
|
9435
|
+
registerPaymentsTransactionsCommand(razorpayCmd, "razorpay");
|
|
8550
9436
|
}
|
|
8551
9437
|
|
|
8552
9438
|
// src/commands/posthog/setup.ts
|
|
@@ -8950,9 +9836,47 @@ function validateConfig(input) {
|
|
|
8950
9836
|
out.project_id = obj.project_id;
|
|
8951
9837
|
}
|
|
8952
9838
|
if ("auth" in obj) out.auth = validateAuth(obj.auth);
|
|
9839
|
+
if ("storage" in obj) out.storage = validateStorage(obj.storage);
|
|
9840
|
+
if ("realtime" in obj) out.realtime = validateRetentionSection("realtime", obj.realtime);
|
|
9841
|
+
if ("schedules" in obj) out.schedules = validateRetentionSection("schedules", obj.schedules);
|
|
8953
9842
|
if ("deployments" in obj) out.deployments = validateDeployments(obj.deployments);
|
|
8954
9843
|
return out;
|
|
8955
9844
|
}
|
|
9845
|
+
function validateStorage(input) {
|
|
9846
|
+
if (input === null || typeof input !== "object" || Array.isArray(input)) {
|
|
9847
|
+
throw new ConfigValidationError("storage", "must be an object");
|
|
9848
|
+
}
|
|
9849
|
+
const obj = input;
|
|
9850
|
+
const out = {};
|
|
9851
|
+
if ("max_file_size_mb" in obj) {
|
|
9852
|
+
if (typeof obj.max_file_size_mb !== "number" || !Number.isInteger(obj.max_file_size_mb) || obj.max_file_size_mb < 1 || obj.max_file_size_mb > 200) {
|
|
9853
|
+
throw new ConfigValidationError(
|
|
9854
|
+
"storage.max_file_size_mb",
|
|
9855
|
+
"must be an integer between 1 and 200"
|
|
9856
|
+
);
|
|
9857
|
+
}
|
|
9858
|
+
out.max_file_size_mb = obj.max_file_size_mb;
|
|
9859
|
+
}
|
|
9860
|
+
return out;
|
|
9861
|
+
}
|
|
9862
|
+
function validateRetentionSection(path6, input) {
|
|
9863
|
+
if (input === null || typeof input !== "object" || Array.isArray(input)) {
|
|
9864
|
+
throw new ConfigValidationError(path6, "must be an object");
|
|
9865
|
+
}
|
|
9866
|
+
const obj = input;
|
|
9867
|
+
const out = {};
|
|
9868
|
+
if ("retention_days" in obj) {
|
|
9869
|
+
const v = obj.retention_days;
|
|
9870
|
+
if (v !== null && (typeof v !== "number" || !Number.isInteger(v) || v < 0)) {
|
|
9871
|
+
throw new ConfigValidationError(
|
|
9872
|
+
`${path6}.retention_days`,
|
|
9873
|
+
"must be a non-negative integer or null"
|
|
9874
|
+
);
|
|
9875
|
+
}
|
|
9876
|
+
out.retention_days = v;
|
|
9877
|
+
}
|
|
9878
|
+
return out;
|
|
9879
|
+
}
|
|
8956
9880
|
function validateDeployments(input) {
|
|
8957
9881
|
if (input === null || typeof input !== "object" || Array.isArray(input)) {
|
|
8958
9882
|
throw new ConfigValidationError("deployments", "must be an object");
|
|
@@ -9008,6 +9932,12 @@ function validateAuth(input) {
|
|
|
9008
9932
|
obj.reset_password_method
|
|
9009
9933
|
);
|
|
9010
9934
|
}
|
|
9935
|
+
if ("disable_signup" in obj) {
|
|
9936
|
+
if (typeof obj.disable_signup !== "boolean") {
|
|
9937
|
+
throw new ConfigValidationError("auth.disable_signup", "must be a boolean");
|
|
9938
|
+
}
|
|
9939
|
+
out.disable_signup = obj.disable_signup;
|
|
9940
|
+
}
|
|
9011
9941
|
if ("password" in obj) out.password = validatePassword(obj.password);
|
|
9012
9942
|
if ("smtp" in obj) out.smtp = validateSmtp(obj.smtp);
|
|
9013
9943
|
return out;
|
|
@@ -9143,6 +10073,21 @@ function stringifyConfigToml(config) {
|
|
|
9143
10073
|
lines.push("");
|
|
9144
10074
|
}
|
|
9145
10075
|
}
|
|
10076
|
+
if (config.storage) {
|
|
10077
|
+
lines.push("[storage]");
|
|
10078
|
+
renderStorageFields(config.storage, lines);
|
|
10079
|
+
lines.push("");
|
|
10080
|
+
}
|
|
10081
|
+
if (config.realtime) {
|
|
10082
|
+
lines.push("[realtime]");
|
|
10083
|
+
renderRetentionFields(config.realtime, lines);
|
|
10084
|
+
lines.push("");
|
|
10085
|
+
}
|
|
10086
|
+
if (config.schedules) {
|
|
10087
|
+
lines.push("[schedules]");
|
|
10088
|
+
renderRetentionFields(config.schedules, lines);
|
|
10089
|
+
lines.push("");
|
|
10090
|
+
}
|
|
9146
10091
|
if (config.deployments) {
|
|
9147
10092
|
if (typeof config.deployments.subdomain === "string" && config.deployments.subdomain !== "") {
|
|
9148
10093
|
lines.push("[deployments]");
|
|
@@ -9166,6 +10111,9 @@ function renderAuthFlatFields(auth, lines) {
|
|
|
9166
10111
|
if (auth.reset_password_method !== void 0) {
|
|
9167
10112
|
lines.push(`reset_password_method = ${JSON.stringify(auth.reset_password_method)}`);
|
|
9168
10113
|
}
|
|
10114
|
+
if (auth.disable_signup !== void 0) {
|
|
10115
|
+
lines.push(`disable_signup = ${auth.disable_signup}`);
|
|
10116
|
+
}
|
|
9169
10117
|
}
|
|
9170
10118
|
function renderPasswordFields(pw, lines) {
|
|
9171
10119
|
if (pw.min_length !== void 0) lines.push(`min_length = ${pw.min_length}`);
|
|
@@ -9202,9 +10150,19 @@ function renderSmtpFields(smtp, lines) {
|
|
|
9202
10150
|
lines.push(`min_interval_seconds = ${smtp.min_interval_seconds}`);
|
|
9203
10151
|
}
|
|
9204
10152
|
}
|
|
10153
|
+
function renderStorageFields(storage, lines) {
|
|
10154
|
+
if (storage.max_file_size_mb !== void 0) {
|
|
10155
|
+
lines.push(`max_file_size_mb = ${storage.max_file_size_mb}`);
|
|
10156
|
+
}
|
|
10157
|
+
}
|
|
10158
|
+
function renderRetentionFields(config, lines) {
|
|
10159
|
+
if ("retention_days" in config) {
|
|
10160
|
+
lines.push(`retention_days = ${config.retention_days ?? 0}`);
|
|
10161
|
+
}
|
|
10162
|
+
}
|
|
9205
10163
|
|
|
9206
10164
|
// src/lib/config-metadata.ts
|
|
9207
|
-
function liveFromMetadata(raw) {
|
|
10165
|
+
function liveFromMetadata(raw, endpointConfig = {}) {
|
|
9208
10166
|
const live = { auth: {} };
|
|
9209
10167
|
const a = isPlainObject(raw.auth) ? raw.auth : void 0;
|
|
9210
10168
|
if (a && "allowedRedirectUrls" in a) {
|
|
@@ -9219,6 +10177,9 @@ function liveFromMetadata(raw) {
|
|
|
9219
10177
|
if (a && "resetPasswordMethod" in a && (a.resetPasswordMethod === "code" || a.resetPasswordMethod === "link")) {
|
|
9220
10178
|
live.auth.reset_password_method = a.resetPasswordMethod;
|
|
9221
10179
|
}
|
|
10180
|
+
if (a && "disableSignup" in a) {
|
|
10181
|
+
live.auth.disable_signup = a.disableSignup ?? false;
|
|
10182
|
+
}
|
|
9222
10183
|
if (a && ("passwordMinLength" in a || "requireNumber" in a || "requireLowercase" in a || "requireUppercase" in a || "requireSpecialChar" in a)) {
|
|
9223
10184
|
live.auth.password = {
|
|
9224
10185
|
min_length: a.passwordMinLength ?? 8,
|
|
@@ -9247,6 +10208,18 @@ function liveFromMetadata(raw) {
|
|
|
9247
10208
|
subdomain: typeof d.customSlug === "string" && d.customSlug ? d.customSlug : null
|
|
9248
10209
|
};
|
|
9249
10210
|
}
|
|
10211
|
+
const maxFileSizeMb = asNumber(endpointConfig.storageConfig?.maxFileSizeMb);
|
|
10212
|
+
if (maxFileSizeMb !== void 0) {
|
|
10213
|
+
live.storage = { max_file_size_mb: maxFileSizeMb };
|
|
10214
|
+
}
|
|
10215
|
+
const realtimeRetention = asRetentionDays(endpointConfig.realtimeConfig?.retentionDays);
|
|
10216
|
+
if (realtimeRetention !== void 0) {
|
|
10217
|
+
live.realtime = { retention_days: realtimeRetention };
|
|
10218
|
+
}
|
|
10219
|
+
const schedulesRetention = asRetentionDays(endpointConfig.schedulesConfig?.retentionDays);
|
|
10220
|
+
if (schedulesRetention !== void 0) {
|
|
10221
|
+
live.schedules = { retention_days: schedulesRetention };
|
|
10222
|
+
}
|
|
9250
10223
|
return live;
|
|
9251
10224
|
}
|
|
9252
10225
|
function isPlainObject(v) {
|
|
@@ -9255,7 +10228,14 @@ function isPlainObject(v) {
|
|
|
9255
10228
|
function asStringArray(v) {
|
|
9256
10229
|
return Array.isArray(v) && v.every((x) => typeof x === "string") ? v : null;
|
|
9257
10230
|
}
|
|
9258
|
-
function
|
|
10231
|
+
function asNumber(v) {
|
|
10232
|
+
return typeof v === "number" && Number.isInteger(v) ? v : void 0;
|
|
10233
|
+
}
|
|
10234
|
+
function asRetentionDays(v) {
|
|
10235
|
+
if (v === null) return null;
|
|
10236
|
+
return asNumber(v);
|
|
10237
|
+
}
|
|
10238
|
+
function configFromMetadata(raw, endpointConfig = {}) {
|
|
9259
10239
|
const config = {};
|
|
9260
10240
|
const skipped = [];
|
|
9261
10241
|
const a = isPlainObject(raw.auth) ? raw.auth : void 0;
|
|
@@ -9283,6 +10263,12 @@ function configFromMetadata(raw) {
|
|
|
9283
10263
|
} else {
|
|
9284
10264
|
skipped.push("auth.reset_password_method");
|
|
9285
10265
|
}
|
|
10266
|
+
if (a && "disableSignup" in a) {
|
|
10267
|
+
config.auth = config.auth ?? {};
|
|
10268
|
+
config.auth.disable_signup = a.disableSignup ?? false;
|
|
10269
|
+
} else {
|
|
10270
|
+
skipped.push("auth.disable_signup");
|
|
10271
|
+
}
|
|
9286
10272
|
if (a && ("passwordMinLength" in a || "requireNumber" in a || "requireLowercase" in a || "requireUppercase" in a || "requireSpecialChar" in a)) {
|
|
9287
10273
|
config.auth = config.auth ?? {};
|
|
9288
10274
|
config.auth.password = {};
|
|
@@ -9326,6 +10312,24 @@ function configFromMetadata(raw) {
|
|
|
9326
10312
|
} else {
|
|
9327
10313
|
skipped.push("deployments.subdomain");
|
|
9328
10314
|
}
|
|
10315
|
+
const maxFileSizeMb = asNumber(endpointConfig.storageConfig?.maxFileSizeMb);
|
|
10316
|
+
if (maxFileSizeMb !== void 0) {
|
|
10317
|
+
config.storage = { max_file_size_mb: maxFileSizeMb };
|
|
10318
|
+
} else {
|
|
10319
|
+
skipped.push("storage.max_file_size_mb");
|
|
10320
|
+
}
|
|
10321
|
+
const realtimeRetention = asRetentionDays(endpointConfig.realtimeConfig?.retentionDays);
|
|
10322
|
+
if (realtimeRetention !== void 0) {
|
|
10323
|
+
config.realtime = { retention_days: realtimeRetention };
|
|
10324
|
+
} else {
|
|
10325
|
+
skipped.push("realtime.retention_days");
|
|
10326
|
+
}
|
|
10327
|
+
const schedulesRetention = asRetentionDays(endpointConfig.schedulesConfig?.retentionDays);
|
|
10328
|
+
if (schedulesRetention !== void 0) {
|
|
10329
|
+
config.schedules = { retention_days: schedulesRetention };
|
|
10330
|
+
} else {
|
|
10331
|
+
skipped.push("schedules.retention_days");
|
|
10332
|
+
}
|
|
9329
10333
|
return { config, skipped };
|
|
9330
10334
|
}
|
|
9331
10335
|
|
|
@@ -9363,7 +10367,16 @@ function registerConfigExportCommand(cfg) {
|
|
|
9363
10367
|
}
|
|
9364
10368
|
const res = await ossFetch("/api/metadata");
|
|
9365
10369
|
const raw = await res.json();
|
|
9366
|
-
const
|
|
10370
|
+
const [storageConfig, realtimeConfig, schedulesConfig] = await Promise.all([
|
|
10371
|
+
fetchOptionalConfig("/api/storage/config"),
|
|
10372
|
+
fetchOptionalConfig("/api/realtime/config"),
|
|
10373
|
+
fetchOptionalConfig("/api/schedules/config")
|
|
10374
|
+
]);
|
|
10375
|
+
const { config, skipped } = configFromMetadata(raw, {
|
|
10376
|
+
storageConfig,
|
|
10377
|
+
realtimeConfig,
|
|
10378
|
+
schedulesConfig
|
|
10379
|
+
});
|
|
9367
10380
|
const toml = stringifyConfigToml(config);
|
|
9368
10381
|
writeFileSync8(target, toml, "utf8");
|
|
9369
10382
|
if (json) {
|
|
@@ -9399,6 +10412,18 @@ function registerConfigExportCommand(cfg) {
|
|
|
9399
10412
|
}
|
|
9400
10413
|
});
|
|
9401
10414
|
}
|
|
10415
|
+
async function fetchOptionalConfig(path6) {
|
|
10416
|
+
try {
|
|
10417
|
+
const res = await ossFetch(path6);
|
|
10418
|
+
return await res.json();
|
|
10419
|
+
} catch (err) {
|
|
10420
|
+
if (isMissingOptionalEndpoint(err)) return void 0;
|
|
10421
|
+
throw err;
|
|
10422
|
+
}
|
|
10423
|
+
}
|
|
10424
|
+
function isMissingOptionalEndpoint(err) {
|
|
10425
|
+
return err instanceof CLIError && err.statusCode === 404 && (err.code === void 0 || err.code === "NOT_FOUND");
|
|
10426
|
+
}
|
|
9402
10427
|
|
|
9403
10428
|
// src/commands/config/plan.ts
|
|
9404
10429
|
import { readFileSync as readFileSync9 } from "fs";
|
|
@@ -9462,6 +10487,19 @@ function diffConfig({ live, file }) {
|
|
|
9462
10487
|
});
|
|
9463
10488
|
}
|
|
9464
10489
|
}
|
|
10490
|
+
if (fileAuth && "disable_signup" in fileAuth) {
|
|
10491
|
+
const fromV = liveAuth.disable_signup ?? false;
|
|
10492
|
+
const toV = fileAuth.disable_signup ?? false;
|
|
10493
|
+
if (fromV !== toV) {
|
|
10494
|
+
changes.push({
|
|
10495
|
+
section: "auth",
|
|
10496
|
+
op: "modify",
|
|
10497
|
+
key: "disable_signup",
|
|
10498
|
+
from: fromV,
|
|
10499
|
+
to: toV
|
|
10500
|
+
});
|
|
10501
|
+
}
|
|
10502
|
+
}
|
|
9465
10503
|
if (fileAuth?.password) {
|
|
9466
10504
|
diffPassword(liveAuth.password, fileAuth.password, changes);
|
|
9467
10505
|
}
|
|
@@ -9469,6 +10507,15 @@ function diffConfig({ live, file }) {
|
|
|
9469
10507
|
const smtpChange = diffSmtp(liveAuth.smtp, fileAuth.smtp);
|
|
9470
10508
|
if (smtpChange) changes.push(smtpChange);
|
|
9471
10509
|
}
|
|
10510
|
+
if (file.storage !== void 0) {
|
|
10511
|
+
diffStorage(live.storage, file.storage, changes);
|
|
10512
|
+
}
|
|
10513
|
+
if (file.realtime !== void 0) {
|
|
10514
|
+
diffRetention("realtime", live.realtime, file.realtime, changes);
|
|
10515
|
+
}
|
|
10516
|
+
if (file.schedules !== void 0) {
|
|
10517
|
+
diffRetention("schedules", live.schedules, file.schedules, changes);
|
|
10518
|
+
}
|
|
9472
10519
|
const fileDeployments = file.deployments;
|
|
9473
10520
|
const liveDeployments = live.deployments ?? {};
|
|
9474
10521
|
if (fileDeployments && "subdomain" in fileDeployments) {
|
|
@@ -9517,6 +10564,36 @@ function diffPassword(live, file, changes) {
|
|
|
9517
10564
|
}
|
|
9518
10565
|
}
|
|
9519
10566
|
}
|
|
10567
|
+
function diffStorage(live, file, changes) {
|
|
10568
|
+
if (file.max_file_size_mb === void 0) return;
|
|
10569
|
+
const fromV = live?.max_file_size_mb ?? EMPTY_STORAGE_CONFIG.max_file_size_mb;
|
|
10570
|
+
if (fromV !== file.max_file_size_mb) {
|
|
10571
|
+
changes.push({
|
|
10572
|
+
section: "storage",
|
|
10573
|
+
op: "modify",
|
|
10574
|
+
key: "max_file_size_mb",
|
|
10575
|
+
from: fromV,
|
|
10576
|
+
to: file.max_file_size_mb
|
|
10577
|
+
});
|
|
10578
|
+
}
|
|
10579
|
+
}
|
|
10580
|
+
function diffRetention(section, live, file, changes) {
|
|
10581
|
+
if (!("retention_days" in file)) return;
|
|
10582
|
+
const fromV = normalizeRetentionDays(live?.retention_days);
|
|
10583
|
+
const toV = normalizeRetentionDays(file.retention_days);
|
|
10584
|
+
if (fromV !== toV) {
|
|
10585
|
+
changes.push({
|
|
10586
|
+
section,
|
|
10587
|
+
op: "modify",
|
|
10588
|
+
key: "retention_days",
|
|
10589
|
+
from: fromV,
|
|
10590
|
+
to: toV
|
|
10591
|
+
});
|
|
10592
|
+
}
|
|
10593
|
+
}
|
|
10594
|
+
function normalizeRetentionDays(value) {
|
|
10595
|
+
return value === void 0 || value === null || value === 0 ? null : value;
|
|
10596
|
+
}
|
|
9520
10597
|
function diffSmtp(live, fileSmtp) {
|
|
9521
10598
|
const livedView = renderLiveSmtp(live);
|
|
9522
10599
|
const tomlView = renderFileSmtp(fileSmtp);
|
|
@@ -9575,6 +10652,9 @@ var EMPTY_SMTP_VIEW = {
|
|
|
9575
10652
|
sender_name: "",
|
|
9576
10653
|
min_interval_seconds: 60
|
|
9577
10654
|
};
|
|
10655
|
+
var EMPTY_STORAGE_CONFIG = {
|
|
10656
|
+
max_file_size_mb: 50
|
|
10657
|
+
};
|
|
9578
10658
|
var EMPTY_PASSWORD_POLICY = {
|
|
9579
10659
|
min_length: 8,
|
|
9580
10660
|
require_number: false,
|
|
@@ -9655,7 +10735,7 @@ function formatChange(c) {
|
|
|
9655
10735
|
}
|
|
9656
10736
|
|
|
9657
10737
|
// src/lib/config-capabilities.ts
|
|
9658
|
-
function metadataSupports(raw, change) {
|
|
10738
|
+
function metadataSupports(raw, change, endpointConfig = {}) {
|
|
9659
10739
|
if (change.section === "auth" && change.key === "allowed_redirect_urls") {
|
|
9660
10740
|
return hasAuthKey(raw, "allowedRedirectUrls");
|
|
9661
10741
|
}
|
|
@@ -9668,12 +10748,24 @@ function metadataSupports(raw, change) {
|
|
|
9668
10748
|
if (change.section === "auth" && change.key === "reset_password_method") {
|
|
9669
10749
|
return hasAuthKey(raw, "resetPasswordMethod");
|
|
9670
10750
|
}
|
|
10751
|
+
if (change.section === "auth" && change.key === "disable_signup") {
|
|
10752
|
+
return hasAuthKey(raw, "disableSignup");
|
|
10753
|
+
}
|
|
9671
10754
|
if (change.section === "auth.password") {
|
|
9672
10755
|
return hasAuthKey(raw, AUTH_PASSWORD_WIRE_KEY[change.key]);
|
|
9673
10756
|
}
|
|
9674
10757
|
if (change.section === "auth.smtp") {
|
|
9675
10758
|
return hasAuthKey(raw, "smtpConfig");
|
|
9676
10759
|
}
|
|
10760
|
+
if (change.section === "storage" && change.key === "max_file_size_mb") {
|
|
10761
|
+
return hasConfigKey(endpointConfig.storageConfig, "maxFileSizeMb");
|
|
10762
|
+
}
|
|
10763
|
+
if (change.section === "realtime" && change.key === "retention_days") {
|
|
10764
|
+
return hasConfigKey(endpointConfig.realtimeConfig, "retentionDays");
|
|
10765
|
+
}
|
|
10766
|
+
if (change.section === "schedules" && change.key === "retention_days") {
|
|
10767
|
+
return hasConfigKey(endpointConfig.schedulesConfig, "retentionDays");
|
|
10768
|
+
}
|
|
9677
10769
|
if (change.section === "deployments" && change.key === "subdomain") {
|
|
9678
10770
|
return raw?.deployments !== void 0 && raw.deployments !== null && typeof raw.deployments === "object";
|
|
9679
10771
|
}
|
|
@@ -9685,6 +10777,9 @@ function hasAuthKey(raw, key) {
|
|
|
9685
10777
|
const auth = raw?.auth;
|
|
9686
10778
|
return auth !== void 0 && auth !== null && typeof auth === "object" && key in auth;
|
|
9687
10779
|
}
|
|
10780
|
+
function hasConfigKey(slice, key) {
|
|
10781
|
+
return slice !== void 0 && slice !== null && typeof slice === "object" && key in slice;
|
|
10782
|
+
}
|
|
9688
10783
|
var AUTH_PASSWORD_WIRE_KEY = {
|
|
9689
10784
|
min_length: "passwordMinLength",
|
|
9690
10785
|
require_number: "requireNumber",
|
|
@@ -9713,9 +10808,25 @@ function registerConfigPlanCommand(cfg) {
|
|
|
9713
10808
|
const file = parseConfigToml(tomlSource);
|
|
9714
10809
|
const res = await ossFetch("/api/metadata");
|
|
9715
10810
|
const raw = await res.json();
|
|
9716
|
-
const
|
|
10811
|
+
const endpointConfig = {};
|
|
10812
|
+
if (file.storage !== void 0) {
|
|
10813
|
+
endpointConfig.storageConfig = await fetchOptionalConfig2(
|
|
10814
|
+
"/api/storage/config"
|
|
10815
|
+
);
|
|
10816
|
+
}
|
|
10817
|
+
if (file.realtime !== void 0) {
|
|
10818
|
+
endpointConfig.realtimeConfig = await fetchOptionalConfig2(
|
|
10819
|
+
"/api/realtime/config"
|
|
10820
|
+
);
|
|
10821
|
+
}
|
|
10822
|
+
if (file.schedules !== void 0) {
|
|
10823
|
+
endpointConfig.schedulesConfig = await fetchOptionalConfig2(
|
|
10824
|
+
"/api/schedules/config"
|
|
10825
|
+
);
|
|
10826
|
+
}
|
|
10827
|
+
const live = liveFromMetadata(raw, endpointConfig);
|
|
9717
10828
|
const result = diffConfig({ live, file });
|
|
9718
|
-
const skipped = result.changes.filter((c) => !metadataSupports(raw, c)).map((c) => changePath(c));
|
|
10829
|
+
const skipped = result.changes.filter((c) => !metadataSupports(raw, c, endpointConfig)).map((c) => changePath(c));
|
|
9719
10830
|
if (json) {
|
|
9720
10831
|
console.log(JSON.stringify({ ...result, skipped }, null, 2));
|
|
9721
10832
|
} else {
|
|
@@ -9751,6 +10862,18 @@ function registerConfigPlanCommand(cfg) {
|
|
|
9751
10862
|
}
|
|
9752
10863
|
});
|
|
9753
10864
|
}
|
|
10865
|
+
async function fetchOptionalConfig2(path6) {
|
|
10866
|
+
try {
|
|
10867
|
+
const res = await ossFetch(path6);
|
|
10868
|
+
return await res.json();
|
|
10869
|
+
} catch (err) {
|
|
10870
|
+
if (isMissingOptionalEndpoint2(err)) return void 0;
|
|
10871
|
+
throw err;
|
|
10872
|
+
}
|
|
10873
|
+
}
|
|
10874
|
+
function isMissingOptionalEndpoint2(err) {
|
|
10875
|
+
return err instanceof CLIError && err.statusCode === 404 && (err.code === void 0 || err.code === "NOT_FOUND");
|
|
10876
|
+
}
|
|
9754
10877
|
|
|
9755
10878
|
// src/commands/config/apply.ts
|
|
9756
10879
|
import { readFileSync as readFileSync10 } from "fs";
|
|
@@ -9769,7 +10892,23 @@ function registerConfigApplyCommand(cfg) {
|
|
|
9769
10892
|
const file = parseConfigToml(tomlSource);
|
|
9770
10893
|
const res = await ossFetch("/api/metadata");
|
|
9771
10894
|
const raw = await res.json();
|
|
9772
|
-
const
|
|
10895
|
+
const endpointConfig = {};
|
|
10896
|
+
if (file.storage !== void 0) {
|
|
10897
|
+
endpointConfig.storageConfig = await fetchOptionalConfig3(
|
|
10898
|
+
"/api/storage/config"
|
|
10899
|
+
);
|
|
10900
|
+
}
|
|
10901
|
+
if (file.realtime !== void 0) {
|
|
10902
|
+
endpointConfig.realtimeConfig = await fetchOptionalConfig3(
|
|
10903
|
+
"/api/realtime/config"
|
|
10904
|
+
);
|
|
10905
|
+
}
|
|
10906
|
+
if (file.schedules !== void 0) {
|
|
10907
|
+
endpointConfig.schedulesConfig = await fetchOptionalConfig3(
|
|
10908
|
+
"/api/schedules/config"
|
|
10909
|
+
);
|
|
10910
|
+
}
|
|
10911
|
+
const live = liveFromMetadata(raw, endpointConfig);
|
|
9773
10912
|
const result = diffConfig({ live, file });
|
|
9774
10913
|
const approved = opts.autoApprove || yes;
|
|
9775
10914
|
const sectionsChanged = Array.from(
|
|
@@ -9822,7 +10961,7 @@ function registerConfigApplyCommand(cfg) {
|
|
|
9822
10961
|
const skipped = [];
|
|
9823
10962
|
for (const change of result.changes) {
|
|
9824
10963
|
const path6 = changePath(change);
|
|
9825
|
-
if (!metadataSupports(raw, change)) {
|
|
10964
|
+
if (!metadataSupports(raw, change, endpointConfig)) {
|
|
9826
10965
|
skipped.push({
|
|
9827
10966
|
key: path6,
|
|
9828
10967
|
reason: `your backend doesn't expose ${path6} \u2014 upgrade the project to apply this section`
|
|
@@ -9873,6 +11012,18 @@ function registerConfigApplyCommand(cfg) {
|
|
|
9873
11012
|
}
|
|
9874
11013
|
});
|
|
9875
11014
|
}
|
|
11015
|
+
async function fetchOptionalConfig3(path6) {
|
|
11016
|
+
try {
|
|
11017
|
+
const res = await ossFetch(path6);
|
|
11018
|
+
return await res.json();
|
|
11019
|
+
} catch (err) {
|
|
11020
|
+
if (isMissingOptionalEndpoint3(err)) return void 0;
|
|
11021
|
+
throw err;
|
|
11022
|
+
}
|
|
11023
|
+
}
|
|
11024
|
+
function isMissingOptionalEndpoint3(err) {
|
|
11025
|
+
return err instanceof CLIError && err.statusCode === 404 && (err.code === void 0 || err.code === "NOT_FOUND");
|
|
11026
|
+
}
|
|
9876
11027
|
async function applyChange(change) {
|
|
9877
11028
|
if (change.section === "auth" && change.key === "allowed_redirect_urls") {
|
|
9878
11029
|
await ossFetch("/api/auth/config", {
|
|
@@ -9902,6 +11053,13 @@ async function applyChange(change) {
|
|
|
9902
11053
|
});
|
|
9903
11054
|
return;
|
|
9904
11055
|
}
|
|
11056
|
+
if (change.section === "auth" && change.key === "disable_signup") {
|
|
11057
|
+
await ossFetch("/api/auth/config", {
|
|
11058
|
+
method: "PUT",
|
|
11059
|
+
body: JSON.stringify({ disableSignup: change.to })
|
|
11060
|
+
});
|
|
11061
|
+
return;
|
|
11062
|
+
}
|
|
9905
11063
|
if (change.section === "auth.password") {
|
|
9906
11064
|
const wireKey = authPasswordWireKey(change.key);
|
|
9907
11065
|
await ossFetch("/api/auth/config", {
|
|
@@ -9934,6 +11092,27 @@ async function applyChange(change) {
|
|
|
9934
11092
|
});
|
|
9935
11093
|
return;
|
|
9936
11094
|
}
|
|
11095
|
+
if (change.section === "storage" && change.key === "max_file_size_mb") {
|
|
11096
|
+
await ossFetch("/api/storage/config", {
|
|
11097
|
+
method: "PUT",
|
|
11098
|
+
body: JSON.stringify({ maxFileSizeMb: change.to })
|
|
11099
|
+
});
|
|
11100
|
+
return;
|
|
11101
|
+
}
|
|
11102
|
+
if (change.section === "realtime" && change.key === "retention_days") {
|
|
11103
|
+
await ossFetch("/api/realtime/config", {
|
|
11104
|
+
method: "PATCH",
|
|
11105
|
+
body: JSON.stringify({ retentionDays: change.to })
|
|
11106
|
+
});
|
|
11107
|
+
return;
|
|
11108
|
+
}
|
|
11109
|
+
if (change.section === "schedules" && change.key === "retention_days") {
|
|
11110
|
+
await ossFetch("/api/schedules/config", {
|
|
11111
|
+
method: "PATCH",
|
|
11112
|
+
body: JSON.stringify({ retentionDays: change.to })
|
|
11113
|
+
});
|
|
11114
|
+
return;
|
|
11115
|
+
}
|
|
9937
11116
|
if (change.section === "deployments" && change.key === "subdomain") {
|
|
9938
11117
|
await ossFetch("/api/deployments/slug", {
|
|
9939
11118
|
method: "PUT",
|