fresh-squeezy 0.1.13 → 0.1.15
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 +56 -12
- package/dist/cli.js +1496 -328
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +1136 -245
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +901 -73
- package/dist/index.d.ts +901 -73
- package/dist/index.js +1106 -245
- package/dist/index.js.map +1 -1
- package/package.json +7 -10
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli/main.ts
|
|
4
|
-
import { readFileSync } from "fs";
|
|
4
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
import dotenv from "dotenv";
|
|
7
7
|
|
|
@@ -9,7 +9,7 @@ import dotenv from "dotenv";
|
|
|
9
9
|
import { existsSync } from "fs";
|
|
10
10
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
11
11
|
import { dirname, resolve } from "path";
|
|
12
|
-
async
|
|
12
|
+
var runAugmentCommand = async (options = {}) => {
|
|
13
13
|
const cwd = options.cwd ?? process.cwd();
|
|
14
14
|
const outPath = resolve(cwd, options.out ?? "lemonsqueezy.augment.d.ts");
|
|
15
15
|
try {
|
|
@@ -37,8 +37,8 @@ async function runAugmentCommand(options = {}) {
|
|
|
37
37
|
`);
|
|
38
38
|
return 2;
|
|
39
39
|
}
|
|
40
|
-
}
|
|
41
|
-
async
|
|
40
|
+
};
|
|
41
|
+
var detectFlavour = async (cwd, force) => {
|
|
42
42
|
if (force) return "generic";
|
|
43
43
|
const pkgPath = resolve(cwd, "package.json");
|
|
44
44
|
if (!existsSync(pkgPath)) return "generic";
|
|
@@ -50,8 +50,8 @@ async function detectFlavour(cwd, force) {
|
|
|
50
50
|
...pkg.peerDependencies ?? {}
|
|
51
51
|
};
|
|
52
52
|
return "@lemonsqueezy/lemonsqueezy.js" in deps ? "with-sdk" : "generic";
|
|
53
|
-
}
|
|
54
|
-
|
|
53
|
+
};
|
|
54
|
+
var renderAugmentationFile = (flavour) => {
|
|
55
55
|
const header = `/**
|
|
56
56
|
* Generated by \`fresh-squeezy types:augment\` \u2014 re-run after upgrading
|
|
57
57
|
* fresh-squeezy to refresh the field set.
|
|
@@ -215,7 +215,7 @@ export type {
|
|
|
215
215
|
* }
|
|
216
216
|
*/
|
|
217
217
|
`;
|
|
218
|
-
}
|
|
218
|
+
};
|
|
219
219
|
|
|
220
220
|
// src/core/errors.ts
|
|
221
221
|
var FreshSqueezyError = class _FreshSqueezyError extends Error {
|
|
@@ -239,7 +239,7 @@ var ENV_KEYS = {
|
|
|
239
239
|
storeId: "LEMON_SQUEEZY_STORE_ID",
|
|
240
240
|
mode: "LEMON_SQUEEZY_MODE"
|
|
241
241
|
};
|
|
242
|
-
|
|
242
|
+
var resolveConfig = (input2 = {}) => {
|
|
243
243
|
const apiKey = input2.apiKey ?? process.env[ENV_KEYS.apiKey];
|
|
244
244
|
if (!apiKey) {
|
|
245
245
|
throw new FreshSqueezyError({
|
|
@@ -256,14 +256,14 @@ function resolveConfig(input2 = {}) {
|
|
|
256
256
|
baseUrl: input2.baseUrl ?? DEFAULT_BASE_URL,
|
|
257
257
|
fetch: input2.fetch ?? globalThis.fetch
|
|
258
258
|
};
|
|
259
|
-
}
|
|
260
|
-
|
|
259
|
+
};
|
|
260
|
+
var normalizeMode = (value) => {
|
|
261
261
|
if (value === "test" || value === "live") return value;
|
|
262
262
|
throw new FreshSqueezyError({
|
|
263
263
|
code: "INVALID_MODE",
|
|
264
264
|
message: `Mode must be "test" or "live", got "${value}".`
|
|
265
265
|
});
|
|
266
|
-
}
|
|
266
|
+
};
|
|
267
267
|
|
|
268
268
|
// src/core/http.ts
|
|
269
269
|
var HttpClient = class {
|
|
@@ -309,6 +309,37 @@ var HttpClient = class {
|
|
|
309
309
|
const doc = await this.request({ path: path4 });
|
|
310
310
|
return doc.data;
|
|
311
311
|
}
|
|
312
|
+
/**
|
|
313
|
+
* POST a JSON:API document and return the created `data` resource.
|
|
314
|
+
*
|
|
315
|
+
* @param path - API path starting with `/v1/...`.
|
|
316
|
+
* @param body - JSON:API create document.
|
|
317
|
+
* @returns The created resource.
|
|
318
|
+
*/
|
|
319
|
+
async postResource(path4, body) {
|
|
320
|
+
const doc = await this.request({ method: "POST", path: path4, body });
|
|
321
|
+
return doc.data;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* PATCH a JSON:API document and return the updated `data` resource.
|
|
325
|
+
*
|
|
326
|
+
* @param path - API path starting with `/v1/...`.
|
|
327
|
+
* @param body - JSON:API update document.
|
|
328
|
+
* @returns The updated resource.
|
|
329
|
+
*/
|
|
330
|
+
async patchResource(path4, body) {
|
|
331
|
+
const doc = await this.request({ method: "PATCH", path: path4, body });
|
|
332
|
+
return doc.data;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* DELETE a resource. Lemon Squeezy often returns an empty body on success.
|
|
336
|
+
*
|
|
337
|
+
* @param path - API path starting with `/v1/...`.
|
|
338
|
+
* @returns Nothing — single void return, not a multi-field bag.
|
|
339
|
+
*/
|
|
340
|
+
async deleteResource(path4) {
|
|
341
|
+
await this.request({ method: "DELETE", path: path4 });
|
|
342
|
+
}
|
|
312
343
|
/**
|
|
313
344
|
* Fetch a single page of a JSON:API collection. Most callers want
|
|
314
345
|
* `paginate()` instead — this method is kept for one-shot lookups where
|
|
@@ -356,48 +387,913 @@ var HttpClient = class {
|
|
|
356
387
|
return url.toString();
|
|
357
388
|
}
|
|
358
389
|
};
|
|
359
|
-
|
|
390
|
+
var safeJsonParse = (text) => {
|
|
360
391
|
try {
|
|
361
392
|
return JSON.parse(text);
|
|
362
393
|
} catch {
|
|
363
394
|
return text;
|
|
364
395
|
}
|
|
365
|
-
}
|
|
366
|
-
|
|
396
|
+
};
|
|
397
|
+
var toApiError = (status, body) => {
|
|
367
398
|
const errors = extractJsonApiErrors(body);
|
|
368
399
|
const first = errors[0];
|
|
369
400
|
const code = status === 401 ? "UNAUTHORIZED" : status === 404 ? "NOT_FOUND" : status === 429 ? "RATE_LIMITED" : first?.code ?? `HTTP_${status}`;
|
|
370
401
|
const message = first?.detail ?? first?.title ?? `Lemon Squeezy request failed with status ${status}`;
|
|
371
402
|
return new FreshSqueezyError({ code, status, message, detail: body });
|
|
372
|
-
}
|
|
373
|
-
|
|
403
|
+
};
|
|
404
|
+
var extractJsonApiErrors = (body) => {
|
|
374
405
|
if (!body || typeof body !== "object") return [];
|
|
375
406
|
const errors = body.errors;
|
|
376
407
|
if (!Array.isArray(errors)) return [];
|
|
377
408
|
return errors.filter(
|
|
378
409
|
(entry) => typeof entry === "object" && entry !== null
|
|
379
410
|
);
|
|
380
|
-
}
|
|
411
|
+
};
|
|
381
412
|
|
|
382
|
-
// src/
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
413
|
+
// src/resources/affiliates.ts
|
|
414
|
+
var getAffiliate = async (http, affiliateId) => {
|
|
415
|
+
return http.getResource(`/v1/affiliates/${affiliateId}`);
|
|
416
|
+
};
|
|
417
|
+
var listAffiliatesForStore = async (http, storeId) => {
|
|
418
|
+
return http.paginate("/v1/affiliates", {
|
|
419
|
+
"filter[store_id]": String(storeId)
|
|
420
|
+
});
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
// src/resources/checkouts.ts
|
|
424
|
+
var getCheckout = async (http, checkoutId) => {
|
|
425
|
+
return http.getResource(`/v1/checkouts/${checkoutId}`);
|
|
426
|
+
};
|
|
427
|
+
var listCheckoutsForStore = async (http, storeId) => {
|
|
428
|
+
return http.paginate("/v1/checkouts", {
|
|
429
|
+
"filter[store_id]": String(storeId)
|
|
430
|
+
});
|
|
431
|
+
};
|
|
432
|
+
var createCheckout = async (http, body) => {
|
|
433
|
+
return http.postResource("/v1/checkouts", body);
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
// src/resources/customers.ts
|
|
437
|
+
var getCustomer = async (http, customerId) => {
|
|
438
|
+
return http.getResource(`/v1/customers/${customerId}`);
|
|
439
|
+
};
|
|
440
|
+
var listCustomersForStore = async (http, storeId) => {
|
|
441
|
+
return http.paginate("/v1/customers", {
|
|
442
|
+
"filter[store_id]": String(storeId)
|
|
443
|
+
});
|
|
444
|
+
};
|
|
445
|
+
var createCustomer = async (http, body) => {
|
|
446
|
+
return http.postResource("/v1/customers", body);
|
|
447
|
+
};
|
|
448
|
+
var updateCustomer = async (http, customerId, body) => {
|
|
449
|
+
return http.patchResource(`/v1/customers/${customerId}`, body);
|
|
450
|
+
};
|
|
451
|
+
|
|
452
|
+
// src/resources/discountRedemptions.ts
|
|
453
|
+
var getDiscountRedemption = async (http, discountRedemptionId) => {
|
|
454
|
+
return http.getResource(
|
|
455
|
+
`/v1/discount-redemptions/${discountRedemptionId}`
|
|
456
|
+
);
|
|
457
|
+
};
|
|
458
|
+
var listDiscountRedemptionsForDiscount = async (http, discountId) => {
|
|
459
|
+
return http.paginate("/v1/discount-redemptions", {
|
|
460
|
+
"filter[discount_id]": String(discountId)
|
|
461
|
+
});
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
// src/resources/discounts.ts
|
|
465
|
+
var getDiscount = async (http, discountId) => {
|
|
466
|
+
return http.getResource(`/v1/discounts/${discountId}`);
|
|
467
|
+
};
|
|
468
|
+
var listDiscountsForStore = async (http, storeId) => {
|
|
469
|
+
return http.paginate("/v1/discounts", {
|
|
470
|
+
"filter[store_id]": String(storeId)
|
|
471
|
+
});
|
|
472
|
+
};
|
|
473
|
+
var createDiscount = async (http, body) => {
|
|
474
|
+
return http.postResource("/v1/discounts", body);
|
|
475
|
+
};
|
|
476
|
+
var deleteDiscount = async (http, discountId) => {
|
|
477
|
+
await http.deleteResource(`/v1/discounts/${discountId}`);
|
|
478
|
+
};
|
|
479
|
+
|
|
480
|
+
// src/resources/files.ts
|
|
481
|
+
var getFile = async (http, fileId) => {
|
|
482
|
+
return http.getResource(`/v1/files/${fileId}`);
|
|
483
|
+
};
|
|
484
|
+
var listFilesForVariant = async (http, variantId) => {
|
|
485
|
+
return http.paginate("/v1/files", {
|
|
486
|
+
"filter[variant_id]": String(variantId)
|
|
487
|
+
});
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
// src/resources/licenseKeyInstances.ts
|
|
491
|
+
var getLicenseKeyInstance = async (http, licenseKeyInstanceId) => {
|
|
492
|
+
return http.getResource(
|
|
493
|
+
`/v1/license-key-instances/${licenseKeyInstanceId}`
|
|
494
|
+
);
|
|
495
|
+
};
|
|
496
|
+
var listLicenseKeyInstancesForLicenseKey = async (http, licenseKeyId) => {
|
|
497
|
+
return http.paginate("/v1/license-key-instances", {
|
|
498
|
+
"filter[license_key_id]": String(licenseKeyId)
|
|
499
|
+
});
|
|
500
|
+
};
|
|
501
|
+
|
|
502
|
+
// src/resources/licenseKeys.ts
|
|
503
|
+
var getLicenseKey = async (http, licenseKeyId) => {
|
|
504
|
+
return http.getResource(`/v1/license-keys/${licenseKeyId}`);
|
|
505
|
+
};
|
|
506
|
+
var listLicenseKeysForStore = async (http, storeId) => {
|
|
507
|
+
return http.paginate("/v1/license-keys", {
|
|
508
|
+
"filter[store_id]": String(storeId)
|
|
509
|
+
});
|
|
510
|
+
};
|
|
511
|
+
var updateLicenseKey = async (http, licenseKeyId, body) => {
|
|
512
|
+
return http.patchResource(`/v1/license-keys/${licenseKeyId}`, body);
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
// src/resources/orderItems.ts
|
|
516
|
+
var getOrderItem = async (http, orderItemId) => {
|
|
517
|
+
return http.getResource(`/v1/order-items/${orderItemId}`);
|
|
518
|
+
};
|
|
519
|
+
var listOrderItemsForOrder = async (http, orderId) => {
|
|
520
|
+
return http.paginate("/v1/order-items", {
|
|
521
|
+
"filter[order_id]": String(orderId)
|
|
522
|
+
});
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
// src/resources/orders.ts
|
|
526
|
+
var getOrder = async (http, orderId) => {
|
|
527
|
+
return http.getResource(`/v1/orders/${orderId}`);
|
|
528
|
+
};
|
|
529
|
+
var listOrdersForStore = async (http, storeId) => {
|
|
530
|
+
return http.paginate("/v1/orders", {
|
|
531
|
+
"filter[store_id]": String(storeId)
|
|
532
|
+
});
|
|
533
|
+
};
|
|
534
|
+
var refundOrder = async (http, orderId, body) => {
|
|
535
|
+
return http.postResource(`/v1/orders/${orderId}/refund`, body ?? {});
|
|
536
|
+
};
|
|
537
|
+
var generateOrderInvoice = async (http, orderId, body) => {
|
|
538
|
+
return http.request({
|
|
539
|
+
method: "POST",
|
|
540
|
+
path: `/v1/orders/${orderId}/generate-invoice`,
|
|
541
|
+
body: body ?? {}
|
|
542
|
+
});
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
// src/resources/prices.ts
|
|
546
|
+
var getPrice = async (http, priceId) => {
|
|
547
|
+
return http.getResource(`/v1/prices/${priceId}`);
|
|
548
|
+
};
|
|
549
|
+
var listPricesForVariant = async (http, variantId) => {
|
|
550
|
+
return http.paginate("/v1/prices", {
|
|
551
|
+
"filter[variant_id]": String(variantId)
|
|
552
|
+
});
|
|
553
|
+
};
|
|
554
|
+
|
|
555
|
+
// src/resources/products.ts
|
|
556
|
+
var getProduct = async (http, productId) => {
|
|
557
|
+
return http.getResource(`/v1/products/${productId}`);
|
|
558
|
+
};
|
|
559
|
+
var listProducts = async (http, storeId) => {
|
|
560
|
+
return http.paginate("/v1/products", {
|
|
561
|
+
"filter[store_id]": String(storeId)
|
|
562
|
+
});
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
// src/resources/registry.ts
|
|
566
|
+
var resourceRegistry = [
|
|
567
|
+
// users
|
|
568
|
+
{ resource: "user", verb: "get", docsPath: "users/retrieve-user", body: "none", idRole: "none" },
|
|
569
|
+
// stores (read-only)
|
|
570
|
+
{ resource: "store", verb: "get", docsPath: "stores/retrieve-store", body: "none", idRole: "id" },
|
|
571
|
+
{
|
|
572
|
+
resource: "store",
|
|
573
|
+
verb: "list",
|
|
574
|
+
docsPath: "stores/list-all-stores",
|
|
575
|
+
body: "none",
|
|
576
|
+
idRole: "none"
|
|
577
|
+
},
|
|
578
|
+
// products (read-only)
|
|
579
|
+
{
|
|
580
|
+
resource: "product",
|
|
581
|
+
verb: "get",
|
|
582
|
+
docsPath: "products/retrieve-product",
|
|
583
|
+
body: "none",
|
|
584
|
+
idRole: "id"
|
|
585
|
+
},
|
|
586
|
+
{
|
|
587
|
+
resource: "product",
|
|
588
|
+
verb: "list",
|
|
589
|
+
docsPath: "products/list-all-products",
|
|
590
|
+
body: "none",
|
|
591
|
+
idRole: "store"
|
|
592
|
+
},
|
|
593
|
+
// variants (read-only)
|
|
594
|
+
{
|
|
595
|
+
resource: "variant",
|
|
596
|
+
verb: "get",
|
|
597
|
+
docsPath: "variants/retrieve-variant",
|
|
598
|
+
body: "none",
|
|
599
|
+
idRole: "id"
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
resource: "variant",
|
|
603
|
+
verb: "list",
|
|
604
|
+
docsPath: "variants/list-all-variants",
|
|
605
|
+
body: "none",
|
|
606
|
+
idRole: "parent"
|
|
607
|
+
},
|
|
608
|
+
// prices (read-only)
|
|
609
|
+
{ resource: "price", verb: "get", docsPath: "prices/retrieve-price", body: "none", idRole: "id" },
|
|
610
|
+
{
|
|
611
|
+
resource: "price",
|
|
612
|
+
verb: "list",
|
|
613
|
+
docsPath: "prices/list-all-prices",
|
|
614
|
+
body: "none",
|
|
615
|
+
idRole: "parent"
|
|
616
|
+
},
|
|
617
|
+
// files (read-only)
|
|
618
|
+
{ resource: "file", verb: "get", docsPath: "files/retrieve-file", body: "none", idRole: "id" },
|
|
619
|
+
{
|
|
620
|
+
resource: "file",
|
|
621
|
+
verb: "list",
|
|
622
|
+
docsPath: "files/list-all-files",
|
|
623
|
+
body: "none",
|
|
624
|
+
idRole: "parent"
|
|
625
|
+
},
|
|
626
|
+
// customers
|
|
627
|
+
{
|
|
628
|
+
resource: "customer",
|
|
629
|
+
verb: "get",
|
|
630
|
+
docsPath: "customers/retrieve-customer",
|
|
631
|
+
body: "none",
|
|
632
|
+
idRole: "id"
|
|
633
|
+
},
|
|
634
|
+
{
|
|
635
|
+
resource: "customer",
|
|
636
|
+
verb: "list",
|
|
637
|
+
docsPath: "customers/list-all-customers",
|
|
638
|
+
body: "none",
|
|
639
|
+
idRole: "store"
|
|
640
|
+
},
|
|
641
|
+
{
|
|
642
|
+
resource: "customer",
|
|
643
|
+
verb: "create",
|
|
644
|
+
docsPath: "customers/create-customer",
|
|
645
|
+
body: "required",
|
|
646
|
+
idRole: "none"
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
resource: "customer",
|
|
650
|
+
verb: "update",
|
|
651
|
+
docsPath: "customers/update-customer",
|
|
652
|
+
body: "required",
|
|
653
|
+
idRole: "id"
|
|
654
|
+
},
|
|
655
|
+
// orders
|
|
656
|
+
{ resource: "order", verb: "get", docsPath: "orders/retrieve-order", body: "none", idRole: "id" },
|
|
657
|
+
{
|
|
658
|
+
resource: "order",
|
|
659
|
+
verb: "list",
|
|
660
|
+
docsPath: "orders/list-all-orders",
|
|
661
|
+
body: "none",
|
|
662
|
+
idRole: "store"
|
|
663
|
+
},
|
|
664
|
+
{
|
|
665
|
+
resource: "order",
|
|
666
|
+
verb: "refund",
|
|
667
|
+
docsPath: "orders/issue-refund",
|
|
668
|
+
body: "optional",
|
|
669
|
+
destructive: true,
|
|
670
|
+
idRole: "id"
|
|
671
|
+
},
|
|
672
|
+
{
|
|
673
|
+
resource: "order",
|
|
674
|
+
verb: "generate-invoice",
|
|
675
|
+
docsPath: "orders/generate-order-invoice",
|
|
676
|
+
body: "optional",
|
|
677
|
+
idRole: "id"
|
|
678
|
+
},
|
|
679
|
+
// order-items (read-only)
|
|
680
|
+
{
|
|
681
|
+
resource: "order-item",
|
|
682
|
+
verb: "get",
|
|
683
|
+
docsPath: "order-items/retrieve-order-item",
|
|
684
|
+
body: "none",
|
|
685
|
+
idRole: "id"
|
|
686
|
+
},
|
|
687
|
+
{
|
|
688
|
+
resource: "order-item",
|
|
689
|
+
verb: "list",
|
|
690
|
+
docsPath: "order-items/list-all-order-items",
|
|
691
|
+
body: "none",
|
|
692
|
+
idRole: "parent"
|
|
693
|
+
},
|
|
694
|
+
// subscriptions
|
|
695
|
+
{
|
|
696
|
+
resource: "subscription",
|
|
697
|
+
verb: "get",
|
|
698
|
+
docsPath: "subscriptions/retrieve-subscription",
|
|
699
|
+
body: "none",
|
|
700
|
+
idRole: "id"
|
|
701
|
+
},
|
|
702
|
+
{
|
|
703
|
+
resource: "subscription",
|
|
704
|
+
verb: "list",
|
|
705
|
+
docsPath: "subscriptions/list-all-subscriptions",
|
|
706
|
+
body: "none",
|
|
707
|
+
idRole: "store"
|
|
708
|
+
},
|
|
709
|
+
{
|
|
710
|
+
resource: "subscription",
|
|
711
|
+
verb: "update",
|
|
712
|
+
docsPath: "subscriptions/update-subscription",
|
|
713
|
+
body: "required",
|
|
714
|
+
idRole: "id"
|
|
715
|
+
},
|
|
716
|
+
{
|
|
717
|
+
resource: "subscription",
|
|
718
|
+
verb: "cancel",
|
|
719
|
+
docsPath: "subscriptions/cancel-subscription",
|
|
720
|
+
body: "none",
|
|
721
|
+
destructive: true,
|
|
722
|
+
idRole: "id"
|
|
723
|
+
},
|
|
724
|
+
// subscription-items
|
|
725
|
+
{
|
|
726
|
+
resource: "subscription-item",
|
|
727
|
+
verb: "get",
|
|
728
|
+
docsPath: "subscription-items/retrieve-subscription-item",
|
|
729
|
+
body: "none",
|
|
730
|
+
idRole: "id"
|
|
731
|
+
},
|
|
732
|
+
{
|
|
733
|
+
resource: "subscription-item",
|
|
734
|
+
verb: "list",
|
|
735
|
+
docsPath: "subscription-items/list-all-subscription-items",
|
|
736
|
+
body: "none",
|
|
737
|
+
idRole: "parent"
|
|
738
|
+
},
|
|
739
|
+
{
|
|
740
|
+
resource: "subscription-item",
|
|
741
|
+
verb: "update",
|
|
742
|
+
docsPath: "subscription-items/update-subscription-item",
|
|
743
|
+
body: "required",
|
|
744
|
+
idRole: "id"
|
|
745
|
+
},
|
|
746
|
+
{
|
|
747
|
+
resource: "subscription-item",
|
|
748
|
+
verb: "current-usage",
|
|
749
|
+
docsPath: "subscription-items/retrieve-subscription-item-current-usage",
|
|
750
|
+
body: "none",
|
|
751
|
+
idRole: "id"
|
|
752
|
+
},
|
|
753
|
+
// subscription-invoices
|
|
754
|
+
{
|
|
755
|
+
resource: "subscription-invoice",
|
|
756
|
+
verb: "get",
|
|
757
|
+
docsPath: "subscription-invoices/retrieve-subscription-invoice",
|
|
758
|
+
body: "none",
|
|
759
|
+
idRole: "id"
|
|
760
|
+
},
|
|
761
|
+
{
|
|
762
|
+
resource: "subscription-invoice",
|
|
763
|
+
verb: "list",
|
|
764
|
+
docsPath: "subscription-invoices/list-all-subscription-invoices",
|
|
765
|
+
body: "none",
|
|
766
|
+
idRole: "parent"
|
|
767
|
+
},
|
|
768
|
+
{
|
|
769
|
+
resource: "subscription-invoice",
|
|
770
|
+
verb: "refund",
|
|
771
|
+
docsPath: "subscription-invoices/issue-refund",
|
|
772
|
+
body: "optional",
|
|
773
|
+
destructive: true,
|
|
774
|
+
idRole: "id"
|
|
775
|
+
},
|
|
776
|
+
{
|
|
777
|
+
resource: "subscription-invoice",
|
|
778
|
+
verb: "generate-invoice",
|
|
779
|
+
docsPath: "subscription-invoices/generate-subscription-invoice",
|
|
780
|
+
body: "optional",
|
|
781
|
+
idRole: "id"
|
|
782
|
+
},
|
|
783
|
+
// usage-records
|
|
784
|
+
{
|
|
785
|
+
resource: "usage-record",
|
|
786
|
+
verb: "get",
|
|
787
|
+
docsPath: "usage-records/retrieve-usage-record",
|
|
788
|
+
body: "none",
|
|
789
|
+
idRole: "id"
|
|
790
|
+
},
|
|
791
|
+
{
|
|
792
|
+
resource: "usage-record",
|
|
793
|
+
verb: "list",
|
|
794
|
+
docsPath: "usage-records/list-all-usage-records",
|
|
795
|
+
body: "none",
|
|
796
|
+
idRole: "parent"
|
|
797
|
+
},
|
|
798
|
+
{
|
|
799
|
+
resource: "usage-record",
|
|
800
|
+
verb: "create",
|
|
801
|
+
docsPath: "usage-records/create-usage-record",
|
|
802
|
+
body: "required",
|
|
803
|
+
idRole: "none"
|
|
804
|
+
},
|
|
805
|
+
// discounts
|
|
806
|
+
{
|
|
807
|
+
resource: "discount",
|
|
808
|
+
verb: "get",
|
|
809
|
+
docsPath: "discounts/retrieve-discount",
|
|
810
|
+
body: "none",
|
|
811
|
+
idRole: "id"
|
|
812
|
+
},
|
|
813
|
+
{
|
|
814
|
+
resource: "discount",
|
|
815
|
+
verb: "list",
|
|
816
|
+
docsPath: "discounts/list-all-discounts",
|
|
817
|
+
body: "none",
|
|
818
|
+
idRole: "store"
|
|
819
|
+
},
|
|
820
|
+
{
|
|
821
|
+
resource: "discount",
|
|
822
|
+
verb: "create",
|
|
823
|
+
docsPath: "discounts/create-discount",
|
|
824
|
+
body: "required",
|
|
825
|
+
idRole: "none"
|
|
826
|
+
},
|
|
827
|
+
{
|
|
828
|
+
resource: "discount",
|
|
829
|
+
verb: "delete",
|
|
830
|
+
docsPath: "discounts/delete-discount",
|
|
831
|
+
body: "none",
|
|
832
|
+
destructive: true,
|
|
833
|
+
idRole: "id"
|
|
834
|
+
},
|
|
835
|
+
// discount-redemptions (read-only)
|
|
836
|
+
{
|
|
837
|
+
resource: "discount-redemption",
|
|
838
|
+
verb: "get",
|
|
839
|
+
docsPath: "discount-redemptions/retrieve-discount-redemption",
|
|
840
|
+
body: "none",
|
|
841
|
+
idRole: "id"
|
|
842
|
+
},
|
|
843
|
+
{
|
|
844
|
+
resource: "discount-redemption",
|
|
845
|
+
verb: "list",
|
|
846
|
+
docsPath: "discount-redemptions/list-all-discount-redemptions",
|
|
847
|
+
body: "none",
|
|
848
|
+
idRole: "parent"
|
|
849
|
+
},
|
|
850
|
+
// license-keys
|
|
851
|
+
{
|
|
852
|
+
resource: "license-key",
|
|
853
|
+
verb: "get",
|
|
854
|
+
docsPath: "license-keys/retrieve-license-key",
|
|
855
|
+
body: "none",
|
|
856
|
+
idRole: "id"
|
|
857
|
+
},
|
|
858
|
+
{
|
|
859
|
+
resource: "license-key",
|
|
860
|
+
verb: "list",
|
|
861
|
+
docsPath: "license-keys/list-all-license-keys",
|
|
862
|
+
body: "none",
|
|
863
|
+
idRole: "store"
|
|
864
|
+
},
|
|
865
|
+
{
|
|
866
|
+
resource: "license-key",
|
|
867
|
+
verb: "update",
|
|
868
|
+
docsPath: "license-keys/update-license-key",
|
|
869
|
+
body: "required",
|
|
870
|
+
idRole: "id"
|
|
871
|
+
},
|
|
872
|
+
// license-key-instances (read-only)
|
|
873
|
+
{
|
|
874
|
+
resource: "license-key-instance",
|
|
875
|
+
verb: "get",
|
|
876
|
+
docsPath: "license-key-instances/retrieve-license-key-instance",
|
|
877
|
+
body: "none",
|
|
878
|
+
idRole: "id"
|
|
879
|
+
},
|
|
880
|
+
{
|
|
881
|
+
resource: "license-key-instance",
|
|
882
|
+
verb: "list",
|
|
883
|
+
docsPath: "license-key-instances/list-all-license-key-instances",
|
|
884
|
+
body: "none",
|
|
885
|
+
idRole: "parent"
|
|
886
|
+
},
|
|
887
|
+
// checkouts
|
|
888
|
+
{
|
|
889
|
+
resource: "checkout",
|
|
890
|
+
verb: "get",
|
|
891
|
+
docsPath: "checkouts/retrieve-checkout",
|
|
892
|
+
body: "none",
|
|
893
|
+
idRole: "id"
|
|
894
|
+
},
|
|
895
|
+
{
|
|
896
|
+
resource: "checkout",
|
|
897
|
+
verb: "list",
|
|
898
|
+
docsPath: "checkouts/list-all-checkouts",
|
|
899
|
+
body: "none",
|
|
900
|
+
idRole: "store"
|
|
901
|
+
},
|
|
902
|
+
{
|
|
903
|
+
resource: "checkout",
|
|
904
|
+
verb: "create",
|
|
905
|
+
docsPath: "checkouts/create-checkout",
|
|
906
|
+
body: "required",
|
|
907
|
+
idRole: "none"
|
|
908
|
+
},
|
|
909
|
+
// webhooks
|
|
910
|
+
{
|
|
911
|
+
resource: "webhook",
|
|
912
|
+
verb: "get",
|
|
913
|
+
docsPath: "webhooks/retrieve-webhook",
|
|
914
|
+
body: "none",
|
|
915
|
+
idRole: "id"
|
|
916
|
+
},
|
|
917
|
+
{
|
|
918
|
+
resource: "webhook",
|
|
919
|
+
verb: "list",
|
|
920
|
+
docsPath: "webhooks/list-all-webhooks",
|
|
921
|
+
body: "none",
|
|
922
|
+
idRole: "store"
|
|
923
|
+
},
|
|
924
|
+
{
|
|
925
|
+
resource: "webhook",
|
|
926
|
+
verb: "create",
|
|
927
|
+
docsPath: "webhooks/create-webhook",
|
|
928
|
+
body: "required",
|
|
929
|
+
idRole: "none"
|
|
930
|
+
},
|
|
931
|
+
{
|
|
932
|
+
resource: "webhook",
|
|
933
|
+
verb: "update",
|
|
934
|
+
docsPath: "webhooks/update-webhook",
|
|
935
|
+
body: "required",
|
|
936
|
+
idRole: "id"
|
|
937
|
+
},
|
|
938
|
+
{
|
|
939
|
+
resource: "webhook",
|
|
940
|
+
verb: "delete",
|
|
941
|
+
docsPath: "webhooks/delete-webhook",
|
|
942
|
+
body: "none",
|
|
943
|
+
destructive: true,
|
|
944
|
+
idRole: "id"
|
|
945
|
+
},
|
|
946
|
+
// affiliates (read-only)
|
|
947
|
+
{
|
|
948
|
+
resource: "affiliate",
|
|
949
|
+
verb: "get",
|
|
950
|
+
docsPath: "affiliates/retrieve-affiliate",
|
|
951
|
+
body: "none",
|
|
952
|
+
idRole: "id"
|
|
953
|
+
},
|
|
954
|
+
{
|
|
955
|
+
resource: "affiliate",
|
|
956
|
+
verb: "list",
|
|
957
|
+
docsPath: "affiliates/list-all-affiliates",
|
|
958
|
+
body: "none",
|
|
959
|
+
idRole: "store"
|
|
960
|
+
}
|
|
961
|
+
];
|
|
962
|
+
var findResourceVerb = (resource, verb) => {
|
|
963
|
+
const normalized = resource.replace(/_/g, "-").toLowerCase();
|
|
964
|
+
const singular = normalized.endsWith("s") && normalized !== "status" ? normalized.slice(0, -1) : normalized;
|
|
965
|
+
const aliases = {
|
|
966
|
+
products: "product",
|
|
967
|
+
stores: "store",
|
|
968
|
+
customers: "customer",
|
|
969
|
+
orders: "order",
|
|
970
|
+
"order-items": "order-item",
|
|
971
|
+
subscriptions: "subscription",
|
|
972
|
+
"subscription-items": "subscription-item",
|
|
973
|
+
"subscription-invoices": "subscription-invoice",
|
|
974
|
+
"usage-records": "usage-record",
|
|
975
|
+
discounts: "discount",
|
|
976
|
+
"discount-redemptions": "discount-redemption",
|
|
977
|
+
"license-keys": "license-key",
|
|
978
|
+
"license-key-instances": "license-key-instance",
|
|
979
|
+
checkouts: "checkout",
|
|
980
|
+
webhooks: "webhook",
|
|
981
|
+
affiliates: "affiliate",
|
|
982
|
+
variants: "variant",
|
|
983
|
+
prices: "price",
|
|
984
|
+
files: "file",
|
|
985
|
+
users: "user"
|
|
986
|
+
};
|
|
987
|
+
const key = aliases[normalized] ?? singular;
|
|
988
|
+
return resourceRegistry.find((entry) => entry.resource === key && entry.verb === verb);
|
|
989
|
+
};
|
|
990
|
+
var listRegisteredResources = () => {
|
|
991
|
+
return [...new Set(resourceRegistry.map((entry) => entry.resource))].sort();
|
|
992
|
+
};
|
|
388
993
|
|
|
389
994
|
// src/resources/stores.ts
|
|
390
|
-
async
|
|
995
|
+
var getStore = async (http, storeId) => {
|
|
391
996
|
return http.getResource(`/v1/stores/${storeId}`);
|
|
392
|
-
}
|
|
393
|
-
async
|
|
997
|
+
};
|
|
998
|
+
var listStores = async (http) => {
|
|
394
999
|
return http.paginate("/v1/stores");
|
|
395
|
-
}
|
|
1000
|
+
};
|
|
1001
|
+
|
|
1002
|
+
// src/resources/subscriptionInvoices.ts
|
|
1003
|
+
var getSubscriptionInvoice = async (http, subscriptionInvoiceId) => {
|
|
1004
|
+
return http.getResource(
|
|
1005
|
+
`/v1/subscription-invoices/${subscriptionInvoiceId}`
|
|
1006
|
+
);
|
|
1007
|
+
};
|
|
1008
|
+
var listSubscriptionInvoicesForSubscription = async (http, subscriptionId) => {
|
|
1009
|
+
return http.paginate("/v1/subscription-invoices", {
|
|
1010
|
+
"filter[subscription_id]": String(subscriptionId)
|
|
1011
|
+
});
|
|
1012
|
+
};
|
|
1013
|
+
var refundSubscriptionInvoice = async (http, subscriptionInvoiceId, body) => {
|
|
1014
|
+
return http.postResource(
|
|
1015
|
+
`/v1/subscription-invoices/${subscriptionInvoiceId}/refund`,
|
|
1016
|
+
body ?? {}
|
|
1017
|
+
);
|
|
1018
|
+
};
|
|
1019
|
+
var generateSubscriptionInvoice = async (http, subscriptionInvoiceId, body) => {
|
|
1020
|
+
return http.request({
|
|
1021
|
+
method: "POST",
|
|
1022
|
+
path: `/v1/subscription-invoices/${subscriptionInvoiceId}/generate-invoice`,
|
|
1023
|
+
body: body ?? {}
|
|
1024
|
+
});
|
|
1025
|
+
};
|
|
1026
|
+
|
|
1027
|
+
// src/resources/subscriptionItems.ts
|
|
1028
|
+
var getSubscriptionItem = async (http, subscriptionItemId) => {
|
|
1029
|
+
return http.getResource(
|
|
1030
|
+
`/v1/subscription-items/${subscriptionItemId}`
|
|
1031
|
+
);
|
|
1032
|
+
};
|
|
1033
|
+
var listSubscriptionItemsForSubscription = async (http, subscriptionId) => {
|
|
1034
|
+
return http.paginate("/v1/subscription-items", {
|
|
1035
|
+
"filter[subscription_id]": String(subscriptionId)
|
|
1036
|
+
});
|
|
1037
|
+
};
|
|
1038
|
+
var updateSubscriptionItem = async (http, subscriptionItemId, body) => {
|
|
1039
|
+
return http.patchResource(
|
|
1040
|
+
`/v1/subscription-items/${subscriptionItemId}`,
|
|
1041
|
+
body
|
|
1042
|
+
);
|
|
1043
|
+
};
|
|
1044
|
+
var getSubscriptionItemCurrentUsage = async (http, subscriptionItemId) => {
|
|
1045
|
+
return http.request({
|
|
1046
|
+
path: `/v1/subscription-items/${subscriptionItemId}/current-usage`
|
|
1047
|
+
});
|
|
1048
|
+
};
|
|
1049
|
+
|
|
1050
|
+
// src/resources/subscriptions.ts
|
|
1051
|
+
var getSubscription = async (http, subscriptionId) => {
|
|
1052
|
+
return http.getResource(`/v1/subscriptions/${subscriptionId}`);
|
|
1053
|
+
};
|
|
1054
|
+
var listSubscriptionsForStore = async (http, storeId) => {
|
|
1055
|
+
return http.paginate("/v1/subscriptions", {
|
|
1056
|
+
"filter[store_id]": String(storeId)
|
|
1057
|
+
});
|
|
1058
|
+
};
|
|
1059
|
+
var updateSubscription = async (http, subscriptionId, body) => {
|
|
1060
|
+
return http.patchResource(`/v1/subscriptions/${subscriptionId}`, body);
|
|
1061
|
+
};
|
|
1062
|
+
var cancelSubscription = async (http, subscriptionId) => {
|
|
1063
|
+
const doc = await http.request({
|
|
1064
|
+
method: "DELETE",
|
|
1065
|
+
path: `/v1/subscriptions/${subscriptionId}`
|
|
1066
|
+
});
|
|
1067
|
+
return doc?.data;
|
|
1068
|
+
};
|
|
1069
|
+
|
|
1070
|
+
// src/resources/usageRecords.ts
|
|
1071
|
+
var getUsageRecord = async (http, usageRecordId) => {
|
|
1072
|
+
return http.getResource(`/v1/usage-records/${usageRecordId}`);
|
|
1073
|
+
};
|
|
1074
|
+
var listUsageRecordsForSubscriptionItem = async (http, subscriptionItemId) => {
|
|
1075
|
+
return http.paginate("/v1/usage-records", {
|
|
1076
|
+
"filter[subscription_item_id]": String(subscriptionItemId)
|
|
1077
|
+
});
|
|
1078
|
+
};
|
|
1079
|
+
var createUsageRecord = async (http, body) => {
|
|
1080
|
+
return http.postResource("/v1/usage-records", body);
|
|
1081
|
+
};
|
|
396
1082
|
|
|
397
1083
|
// src/resources/users.ts
|
|
398
|
-
async
|
|
1084
|
+
var getAuthenticatedUser = async (http) => {
|
|
399
1085
|
return http.request({ path: "/v1/users/me" });
|
|
400
|
-
}
|
|
1086
|
+
};
|
|
1087
|
+
var userResource = (doc) => {
|
|
1088
|
+
return doc.data;
|
|
1089
|
+
};
|
|
1090
|
+
|
|
1091
|
+
// src/resources/variants.ts
|
|
1092
|
+
var getVariant = async (http, variantId) => {
|
|
1093
|
+
return http.getResource(`/v1/variants/${variantId}`);
|
|
1094
|
+
};
|
|
1095
|
+
var listVariantsForProduct = async (http, productId) => {
|
|
1096
|
+
return http.paginate("/v1/variants", {
|
|
1097
|
+
"filter[product_id]": String(productId)
|
|
1098
|
+
});
|
|
1099
|
+
};
|
|
1100
|
+
|
|
1101
|
+
// src/resources/webhooks.ts
|
|
1102
|
+
var getWebhook = async (http, webhookId) => {
|
|
1103
|
+
return http.getResource(`/v1/webhooks/${webhookId}`);
|
|
1104
|
+
};
|
|
1105
|
+
var listWebhooksForStore = async (http, storeId) => {
|
|
1106
|
+
return http.paginate("/v1/webhooks", {
|
|
1107
|
+
"filter[store_id]": String(storeId)
|
|
1108
|
+
});
|
|
1109
|
+
};
|
|
1110
|
+
var createWebhook = async (http, body) => {
|
|
1111
|
+
return http.postResource("/v1/webhooks", body);
|
|
1112
|
+
};
|
|
1113
|
+
var updateWebhook = async (http, webhookId, body) => {
|
|
1114
|
+
return http.patchResource(`/v1/webhooks/${webhookId}`, body);
|
|
1115
|
+
};
|
|
1116
|
+
var deleteWebhook = async (http, webhookId) => {
|
|
1117
|
+
await http.deleteResource(`/v1/webhooks/${webhookId}`);
|
|
1118
|
+
};
|
|
1119
|
+
|
|
1120
|
+
// src/resources/invokeOp.ts
|
|
1121
|
+
var invokeOp = async (http, resource, verb, args = {}) => {
|
|
1122
|
+
const spec = findResourceVerb(resource, verb);
|
|
1123
|
+
if (!spec) {
|
|
1124
|
+
throw new FreshSqueezyError({
|
|
1125
|
+
code: "UNKNOWN_OP",
|
|
1126
|
+
message: `Unknown or unsupported op: ${verb} ${resource}. Run \`fresh-squeezy ops --list\`.`
|
|
1127
|
+
});
|
|
1128
|
+
}
|
|
1129
|
+
const key = `${spec.resource}:${spec.verb}`;
|
|
1130
|
+
switch (key) {
|
|
1131
|
+
case "user:get":
|
|
1132
|
+
return userResource(await getAuthenticatedUser(http));
|
|
1133
|
+
case "store:get":
|
|
1134
|
+
return getStore(http, requireId(args, "store"));
|
|
1135
|
+
case "store:list":
|
|
1136
|
+
return listStores(http);
|
|
1137
|
+
case "product:get":
|
|
1138
|
+
return getProduct(http, requireId(args, "product"));
|
|
1139
|
+
case "product:list":
|
|
1140
|
+
return listProducts(http, requireStore(args));
|
|
1141
|
+
case "variant:get":
|
|
1142
|
+
return getVariant(http, requireId(args, "variant"));
|
|
1143
|
+
case "variant:list":
|
|
1144
|
+
return listVariantsForProduct(http, requireParent(args, "product"));
|
|
1145
|
+
case "price:get":
|
|
1146
|
+
return getPrice(http, requireId(args, "price"));
|
|
1147
|
+
case "price:list":
|
|
1148
|
+
return listPricesForVariant(http, requireParent(args, "variant"));
|
|
1149
|
+
case "file:get":
|
|
1150
|
+
return getFile(http, requireId(args, "file"));
|
|
1151
|
+
case "file:list":
|
|
1152
|
+
return listFilesForVariant(http, requireParent(args, "variant"));
|
|
1153
|
+
case "customer:get":
|
|
1154
|
+
return getCustomer(http, requireId(args, "customer"));
|
|
1155
|
+
case "customer:list":
|
|
1156
|
+
return listCustomersForStore(http, requireStore(args));
|
|
1157
|
+
case "customer:create":
|
|
1158
|
+
return createCustomer(http, requireBody(args));
|
|
1159
|
+
case "customer:update":
|
|
1160
|
+
return updateCustomer(http, requireId(args, "customer"), requireBody(args));
|
|
1161
|
+
case "order:get":
|
|
1162
|
+
return getOrder(http, requireId(args, "order"));
|
|
1163
|
+
case "order:list":
|
|
1164
|
+
return listOrdersForStore(http, requireStore(args));
|
|
1165
|
+
case "order:refund":
|
|
1166
|
+
return refundOrder(http, requireId(args, "order"), args.body);
|
|
1167
|
+
case "order:generate-invoice":
|
|
1168
|
+
return generateOrderInvoice(http, requireId(args, "order"), args.body);
|
|
1169
|
+
case "order-item:get":
|
|
1170
|
+
return getOrderItem(http, requireId(args, "order-item"));
|
|
1171
|
+
case "order-item:list":
|
|
1172
|
+
return listOrderItemsForOrder(http, requireParent(args, "order"));
|
|
1173
|
+
case "subscription:get":
|
|
1174
|
+
return getSubscription(http, requireId(args, "subscription"));
|
|
1175
|
+
case "subscription:list":
|
|
1176
|
+
return listSubscriptionsForStore(http, requireStore(args));
|
|
1177
|
+
case "subscription:update":
|
|
1178
|
+
return updateSubscription(http, requireId(args, "subscription"), requireBody(args));
|
|
1179
|
+
case "subscription:cancel":
|
|
1180
|
+
return cancelSubscription(http, requireId(args, "subscription"));
|
|
1181
|
+
case "subscription-item:get":
|
|
1182
|
+
return getSubscriptionItem(http, requireId(args, "subscription-item"));
|
|
1183
|
+
case "subscription-item:list":
|
|
1184
|
+
return listSubscriptionItemsForSubscription(http, requireParent(args, "subscription"));
|
|
1185
|
+
case "subscription-item:update":
|
|
1186
|
+
return updateSubscriptionItem(http, requireId(args, "subscription-item"), requireBody(args));
|
|
1187
|
+
case "subscription-item:current-usage":
|
|
1188
|
+
return getSubscriptionItemCurrentUsage(http, requireId(args, "subscription-item"));
|
|
1189
|
+
case "subscription-invoice:get":
|
|
1190
|
+
return getSubscriptionInvoice(http, requireId(args, "subscription-invoice"));
|
|
1191
|
+
case "subscription-invoice:list":
|
|
1192
|
+
return listSubscriptionInvoicesForSubscription(http, requireParent(args, "subscription"));
|
|
1193
|
+
case "subscription-invoice:refund":
|
|
1194
|
+
return refundSubscriptionInvoice(http, requireId(args, "subscription-invoice"), args.body);
|
|
1195
|
+
case "subscription-invoice:generate-invoice":
|
|
1196
|
+
return generateSubscriptionInvoice(http, requireId(args, "subscription-invoice"), args.body);
|
|
1197
|
+
case "usage-record:get":
|
|
1198
|
+
return getUsageRecord(http, requireId(args, "usage-record"));
|
|
1199
|
+
case "usage-record:list":
|
|
1200
|
+
return listUsageRecordsForSubscriptionItem(http, requireParent(args, "subscription-item"));
|
|
1201
|
+
case "usage-record:create":
|
|
1202
|
+
return createUsageRecord(http, requireBody(args));
|
|
1203
|
+
case "discount:get":
|
|
1204
|
+
return getDiscount(http, requireId(args, "discount"));
|
|
1205
|
+
case "discount:list":
|
|
1206
|
+
return listDiscountsForStore(http, requireStore(args));
|
|
1207
|
+
case "discount:create":
|
|
1208
|
+
return createDiscount(http, requireBody(args));
|
|
1209
|
+
case "discount:delete":
|
|
1210
|
+
await deleteDiscount(http, requireId(args, "discount"));
|
|
1211
|
+
return void 0;
|
|
1212
|
+
case "discount-redemption:get":
|
|
1213
|
+
return getDiscountRedemption(http, requireId(args, "discount-redemption"));
|
|
1214
|
+
case "discount-redemption:list":
|
|
1215
|
+
return listDiscountRedemptionsForDiscount(http, requireParent(args, "discount"));
|
|
1216
|
+
case "license-key:get":
|
|
1217
|
+
return getLicenseKey(http, requireId(args, "license-key"));
|
|
1218
|
+
case "license-key:list":
|
|
1219
|
+
return listLicenseKeysForStore(http, requireStore(args));
|
|
1220
|
+
case "license-key:update":
|
|
1221
|
+
return updateLicenseKey(http, requireId(args, "license-key"), requireBody(args));
|
|
1222
|
+
case "license-key-instance:get":
|
|
1223
|
+
return getLicenseKeyInstance(http, requireId(args, "license-key-instance"));
|
|
1224
|
+
case "license-key-instance:list":
|
|
1225
|
+
return listLicenseKeyInstancesForLicenseKey(http, requireParent(args, "license-key"));
|
|
1226
|
+
case "checkout:get":
|
|
1227
|
+
return getCheckout(http, requireId(args, "checkout"));
|
|
1228
|
+
case "checkout:list":
|
|
1229
|
+
return listCheckoutsForStore(http, requireStore(args));
|
|
1230
|
+
case "checkout:create":
|
|
1231
|
+
return createCheckout(http, requireBody(args));
|
|
1232
|
+
case "webhook:get":
|
|
1233
|
+
return getWebhook(http, requireId(args, "webhook"));
|
|
1234
|
+
case "webhook:list":
|
|
1235
|
+
return listWebhooksForStore(http, requireStore(args));
|
|
1236
|
+
case "webhook:create":
|
|
1237
|
+
return createWebhook(http, requireBody(args));
|
|
1238
|
+
case "webhook:update":
|
|
1239
|
+
return updateWebhook(http, requireId(args, "webhook"), requireBody(args));
|
|
1240
|
+
case "webhook:delete":
|
|
1241
|
+
await deleteWebhook(http, requireId(args, "webhook"));
|
|
1242
|
+
return void 0;
|
|
1243
|
+
case "affiliate:get":
|
|
1244
|
+
return getAffiliate(http, requireId(args, "affiliate"));
|
|
1245
|
+
case "affiliate:list":
|
|
1246
|
+
return listAffiliatesForStore(http, requireStore(args));
|
|
1247
|
+
default:
|
|
1248
|
+
throw new FreshSqueezyError({
|
|
1249
|
+
code: "UNKNOWN_OP",
|
|
1250
|
+
message: `Op registered but not wired: ${key}`
|
|
1251
|
+
});
|
|
1252
|
+
}
|
|
1253
|
+
};
|
|
1254
|
+
var requireId = (args, label) => {
|
|
1255
|
+
if (args.id === void 0 || args.id === "") {
|
|
1256
|
+
throw new FreshSqueezyError({
|
|
1257
|
+
code: "MISSING_ARG",
|
|
1258
|
+
message: `--id is required for this ${label} operation.`
|
|
1259
|
+
});
|
|
1260
|
+
}
|
|
1261
|
+
return args.id;
|
|
1262
|
+
};
|
|
1263
|
+
var requireStore = (args) => {
|
|
1264
|
+
if (args.storeId === void 0 || args.storeId === "") {
|
|
1265
|
+
throw new FreshSqueezyError({
|
|
1266
|
+
code: "MISSING_ARG",
|
|
1267
|
+
message: "--store-ids (or store id) is required for this list operation."
|
|
1268
|
+
});
|
|
1269
|
+
}
|
|
1270
|
+
return args.storeId;
|
|
1271
|
+
};
|
|
1272
|
+
var requireParent = (args, label) => {
|
|
1273
|
+
if (args.parentId === void 0 || args.parentId === "") {
|
|
1274
|
+
throw new FreshSqueezyError({
|
|
1275
|
+
code: "MISSING_ARG",
|
|
1276
|
+
message: `--parent-id (${label} id) is required for this list operation.`
|
|
1277
|
+
});
|
|
1278
|
+
}
|
|
1279
|
+
return args.parentId;
|
|
1280
|
+
};
|
|
1281
|
+
var requireBody = (args) => {
|
|
1282
|
+
if (args.body === void 0) {
|
|
1283
|
+
throw new FreshSqueezyError({
|
|
1284
|
+
code: "MISSING_ARG",
|
|
1285
|
+
message: "A JSON body is required (--body, --body-file, or stdin)."
|
|
1286
|
+
});
|
|
1287
|
+
}
|
|
1288
|
+
return args.body;
|
|
1289
|
+
};
|
|
1290
|
+
|
|
1291
|
+
// src/core/mode.ts
|
|
1292
|
+
var resolveActualMode = (testMode) => {
|
|
1293
|
+
if (testMode === true) return "test";
|
|
1294
|
+
if (testMode === false) return "live";
|
|
1295
|
+
return void 0;
|
|
1296
|
+
};
|
|
401
1297
|
|
|
402
1298
|
// src/validate/rules.ts
|
|
403
1299
|
var ISSUE_CODES = {
|
|
@@ -436,16 +1332,16 @@ var ISSUE_CODES = {
|
|
|
436
1332
|
NETWORK_ERROR: "NETWORK_ERROR",
|
|
437
1333
|
UNKNOWN: "UNKNOWN"
|
|
438
1334
|
};
|
|
439
|
-
|
|
1335
|
+
var issue = (code, severity, message, extras = {}) => {
|
|
440
1336
|
const base = { code, severity, message };
|
|
441
1337
|
if (extras.suggestedFix !== void 0) base.suggestedFix = extras.suggestedFix;
|
|
442
1338
|
if (extras.context !== void 0) base.context = extras.context;
|
|
443
1339
|
return base;
|
|
444
|
-
}
|
|
445
|
-
|
|
1340
|
+
};
|
|
1341
|
+
var isOk = (issues) => {
|
|
446
1342
|
return !issues.some((entry) => entry.severity === "error");
|
|
447
|
-
}
|
|
448
|
-
|
|
1343
|
+
};
|
|
1344
|
+
var buildResult = (name, mode, issues, resource, target) => {
|
|
449
1345
|
const result = {
|
|
450
1346
|
name,
|
|
451
1347
|
ok: isOk(issues),
|
|
@@ -455,10 +1351,10 @@ function buildResult(name, mode, issues, resource, target) {
|
|
|
455
1351
|
if (resource !== void 0) result.resource = resource;
|
|
456
1352
|
if (target !== void 0) result.target = target;
|
|
457
1353
|
return result;
|
|
458
|
-
}
|
|
1354
|
+
};
|
|
459
1355
|
|
|
460
1356
|
// src/validate/probe.ts
|
|
461
|
-
|
|
1357
|
+
var mapErrorToIssue = (err, mapping = {}) => {
|
|
462
1358
|
if (err instanceof FreshSqueezyError) {
|
|
463
1359
|
if (mapping.unauthorized && (err.status === 401 || err.code === "UNAUTHORIZED")) {
|
|
464
1360
|
return issue(mapping.unauthorized.code, "error", mapping.unauthorized.message, {
|
|
@@ -485,8 +1381,8 @@ function mapErrorToIssue(err, mapping = {}) {
|
|
|
485
1381
|
}
|
|
486
1382
|
const message = err instanceof Error ? err.message : "Unknown error";
|
|
487
1383
|
return issue(ISSUE_CODES.UNKNOWN, "error", message);
|
|
488
|
-
}
|
|
489
|
-
async
|
|
1384
|
+
};
|
|
1385
|
+
var probeFetch = async (fetcher, options) => {
|
|
490
1386
|
return probeCollection(fetcher, {
|
|
491
1387
|
notFound: {
|
|
492
1388
|
code: options.notFoundCode,
|
|
@@ -495,15 +1391,15 @@ async function probeFetch(fetcher, options) {
|
|
|
495
1391
|
...options.notFoundContext !== void 0 ? { context: options.notFoundContext } : {}
|
|
496
1392
|
}
|
|
497
1393
|
});
|
|
498
|
-
}
|
|
499
|
-
async
|
|
1394
|
+
};
|
|
1395
|
+
var probeCollection = async (fetcher, mapping = {}) => {
|
|
500
1396
|
try {
|
|
501
1397
|
return { ok: true, resource: await fetcher() };
|
|
502
1398
|
} catch (err) {
|
|
503
1399
|
return { ok: false, issue: mapErrorToIssue(err, mapping) };
|
|
504
1400
|
}
|
|
505
|
-
}
|
|
506
|
-
|
|
1401
|
+
};
|
|
1402
|
+
var checkStoreOwnership = (check) => {
|
|
507
1403
|
const expected = String(check.expectedStoreId);
|
|
508
1404
|
const actual = String(check.actualStoreId);
|
|
509
1405
|
if (expected === actual) return null;
|
|
@@ -521,10 +1417,10 @@ function checkStoreOwnership(check) {
|
|
|
521
1417
|
context
|
|
522
1418
|
}
|
|
523
1419
|
);
|
|
524
|
-
}
|
|
1420
|
+
};
|
|
525
1421
|
|
|
526
1422
|
// src/validate/connection.ts
|
|
527
|
-
async
|
|
1423
|
+
var validateConnection = async (http, mode) => {
|
|
528
1424
|
const issues = [];
|
|
529
1425
|
const fetched = await probeCollection(
|
|
530
1426
|
async () => {
|
|
@@ -577,15 +1473,10 @@ async function validateConnection(http, mode) {
|
|
|
577
1473
|
);
|
|
578
1474
|
}
|
|
579
1475
|
return buildResult("connection", mode, issues, summary);
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
// src/resources/discounts.ts
|
|
583
|
-
async function getDiscount(http, discountId) {
|
|
584
|
-
return http.getResource(`/v1/discounts/${discountId}`);
|
|
585
|
-
}
|
|
1476
|
+
};
|
|
586
1477
|
|
|
587
1478
|
// src/validate/discount.ts
|
|
588
|
-
async
|
|
1479
|
+
var validateDiscount = async (http, mode, options) => {
|
|
589
1480
|
const issues = [];
|
|
590
1481
|
const fetched = await probeFetch(() => getDiscount(http, options.discountId), {
|
|
591
1482
|
notFoundCode: ISSUE_CODES.DISCOUNT_NOT_FOUND,
|
|
@@ -606,8 +1497,8 @@ async function validateDiscount(http, mode, options) {
|
|
|
606
1497
|
label: `${attrs.name} (${attrs.code})`,
|
|
607
1498
|
id: String(options.discountId)
|
|
608
1499
|
});
|
|
609
|
-
}
|
|
610
|
-
|
|
1500
|
+
};
|
|
1501
|
+
var checkDiscount = (attrs, options) => {
|
|
611
1502
|
const issues = [];
|
|
612
1503
|
const mismatch = checkStoreOwnership({
|
|
613
1504
|
expectedStoreId: options.storeId,
|
|
@@ -696,15 +1587,10 @@ function checkDiscount(attrs, options) {
|
|
|
696
1587
|
);
|
|
697
1588
|
}
|
|
698
1589
|
return issues;
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
// src/resources/licenseKeys.ts
|
|
702
|
-
async function getLicenseKey(http, licenseKeyId) {
|
|
703
|
-
return http.getResource(`/v1/license-keys/${licenseKeyId}`);
|
|
704
|
-
}
|
|
1590
|
+
};
|
|
705
1591
|
|
|
706
1592
|
// src/validate/licenseKey.ts
|
|
707
|
-
async
|
|
1593
|
+
var validateLicenseKey = async (http, mode, options) => {
|
|
708
1594
|
const issues = [];
|
|
709
1595
|
const fetched = await probeFetch(() => getLicenseKey(http, options.licenseKeyId), {
|
|
710
1596
|
notFoundCode: ISSUE_CODES.LICENSE_KEY_NOT_FOUND,
|
|
@@ -725,8 +1611,8 @@ async function validateLicenseKey(http, mode, options) {
|
|
|
725
1611
|
label: attrs.key_short,
|
|
726
1612
|
id: String(options.licenseKeyId)
|
|
727
1613
|
});
|
|
728
|
-
}
|
|
729
|
-
|
|
1614
|
+
};
|
|
1615
|
+
var checkLicenseKey = (attrs, options) => {
|
|
730
1616
|
const issues = [];
|
|
731
1617
|
const mismatch = checkStoreOwnership({
|
|
732
1618
|
expectedStoreId: options.storeId,
|
|
@@ -780,25 +1666,10 @@ function checkLicenseKey(attrs, options) {
|
|
|
780
1666
|
);
|
|
781
1667
|
}
|
|
782
1668
|
return issues;
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
// src/resources/products.ts
|
|
786
|
-
async function getProduct(http, productId) {
|
|
787
|
-
return http.getResource(`/v1/products/${productId}`);
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
// src/resources/variants.ts
|
|
791
|
-
async function getVariant(http, variantId) {
|
|
792
|
-
return http.getResource(`/v1/variants/${variantId}`);
|
|
793
|
-
}
|
|
794
|
-
async function listVariantsForProduct(http, productId) {
|
|
795
|
-
return http.paginate("/v1/variants", {
|
|
796
|
-
"filter[product_id]": String(productId)
|
|
797
|
-
});
|
|
798
|
-
}
|
|
1669
|
+
};
|
|
799
1670
|
|
|
800
1671
|
// src/validate/product.ts
|
|
801
|
-
async
|
|
1672
|
+
var validateProduct = async (http, mode, options) => {
|
|
802
1673
|
const issues = [];
|
|
803
1674
|
const fetched = await probeFetch(() => getProduct(http, options.productId), {
|
|
804
1675
|
notFoundCode: ISSUE_CODES.PRODUCT_NOT_FOUND,
|
|
@@ -844,8 +1715,8 @@ async function validateProduct(http, mode, options) {
|
|
|
844
1715
|
label: attrs.name,
|
|
845
1716
|
id: String(options.productId)
|
|
846
1717
|
});
|
|
847
|
-
}
|
|
848
|
-
|
|
1718
|
+
};
|
|
1719
|
+
var checkProduct = (attrs, options = {}) => {
|
|
849
1720
|
const issues = [];
|
|
850
1721
|
if (options.expectedStoreId !== void 0) {
|
|
851
1722
|
const mismatch = checkStoreOwnership({
|
|
@@ -881,10 +1752,10 @@ function checkProduct(attrs, options = {}) {
|
|
|
881
1752
|
);
|
|
882
1753
|
}
|
|
883
1754
|
return issues;
|
|
884
|
-
}
|
|
1755
|
+
};
|
|
885
1756
|
|
|
886
1757
|
// src/validate/store.ts
|
|
887
|
-
async
|
|
1758
|
+
var validateStore = async (http, mode, storeId) => {
|
|
888
1759
|
const issues = [];
|
|
889
1760
|
const fetched = await probeFetch(() => getStore(http, storeId), {
|
|
890
1761
|
notFoundCode: ISSUE_CODES.STORE_NOT_FOUND,
|
|
@@ -903,11 +1774,11 @@ async function validateStore(http, mode, storeId) {
|
|
|
903
1774
|
label: fetched.resource.attributes.name,
|
|
904
1775
|
id: String(storeId)
|
|
905
1776
|
});
|
|
906
|
-
}
|
|
1777
|
+
};
|
|
907
1778
|
|
|
908
1779
|
// src/validate/subscriptionPlan.ts
|
|
909
1780
|
var VALID_INTERVALS = /* @__PURE__ */ new Set(["day", "week", "month", "year"]);
|
|
910
|
-
async
|
|
1781
|
+
var validateSubscriptionPlan = async (http, mode, options) => {
|
|
911
1782
|
const issues = [];
|
|
912
1783
|
const fetched = await probeFetch(
|
|
913
1784
|
() => getVariant(http, options.variantId),
|
|
@@ -953,8 +1824,8 @@ async function validateSubscriptionPlan(http, mode, options) {
|
|
|
953
1824
|
label: attrs.name,
|
|
954
1825
|
id: String(options.variantId)
|
|
955
1826
|
});
|
|
956
|
-
}
|
|
957
|
-
|
|
1827
|
+
};
|
|
1828
|
+
var checkSubscriptionPlan = (attrs, options) => {
|
|
958
1829
|
const issues = [];
|
|
959
1830
|
if (!attrs.is_subscription) {
|
|
960
1831
|
issues.push(
|
|
@@ -1038,22 +1909,15 @@ function checkSubscriptionPlan(attrs, options) {
|
|
|
1038
1909
|
);
|
|
1039
1910
|
}
|
|
1040
1911
|
return issues;
|
|
1041
|
-
}
|
|
1912
|
+
};
|
|
1042
1913
|
|
|
1043
1914
|
// src/core/equality.ts
|
|
1044
|
-
|
|
1915
|
+
var sameWebhookUrl = (a, b) => {
|
|
1045
1916
|
return normalizeWebhookUrl(a) === normalizeWebhookUrl(b);
|
|
1046
|
-
}
|
|
1047
|
-
|
|
1917
|
+
};
|
|
1918
|
+
var normalizeWebhookUrl = (raw) => {
|
|
1048
1919
|
return raw.replace(/\/+$/, "").toLowerCase();
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
// src/resources/webhooks.ts
|
|
1052
|
-
async function listWebhooksForStore(http, storeId) {
|
|
1053
|
-
return http.paginate("/v1/webhooks", {
|
|
1054
|
-
"filter[store_id]": String(storeId)
|
|
1055
|
-
});
|
|
1056
|
-
}
|
|
1920
|
+
};
|
|
1057
1921
|
|
|
1058
1922
|
// src/support/manifest.ts
|
|
1059
1923
|
var RECOMMENDED_WEBHOOK_EVENTS = [
|
|
@@ -1075,7 +1939,7 @@ var OPTIONAL_WEBHOOK_EVENTS = [
|
|
|
1075
1939
|
];
|
|
1076
1940
|
|
|
1077
1941
|
// src/validate/webhook.ts
|
|
1078
|
-
async
|
|
1942
|
+
var validateWebhook = async (http, mode, options) => {
|
|
1079
1943
|
const issues = [];
|
|
1080
1944
|
const fetched = await probeCollection(() => listWebhooksForStore(http, options.storeId));
|
|
1081
1945
|
if (!fetched.ok) {
|
|
@@ -1135,7 +1999,7 @@ async function validateWebhook(http, mode, options) {
|
|
|
1135
1999
|
id: match.id,
|
|
1136
2000
|
url: match.attributes.url
|
|
1137
2001
|
});
|
|
1138
|
-
}
|
|
2002
|
+
};
|
|
1139
2003
|
|
|
1140
2004
|
// src/validate/doctor.ts
|
|
1141
2005
|
var DEFAULT_VALIDATORS = {
|
|
@@ -1147,7 +2011,7 @@ var DEFAULT_VALIDATORS = {
|
|
|
1147
2011
|
licenseKey: validateLicenseKey,
|
|
1148
2012
|
subscriptionPlan: validateSubscriptionPlan
|
|
1149
2013
|
};
|
|
1150
|
-
async
|
|
2014
|
+
var doctor = async (http, mode, options = {}, validators = DEFAULT_VALIDATORS) => {
|
|
1151
2015
|
assertOptionsCoherent(options);
|
|
1152
2016
|
const results = [];
|
|
1153
2017
|
const productIds = collectValues(options.productId, options.productIds);
|
|
@@ -1213,8 +2077,8 @@ async function doctor(http, mode, options = {}, validators = DEFAULT_VALIDATORS)
|
|
|
1213
2077
|
}
|
|
1214
2078
|
const ok = results.every((result) => result.ok);
|
|
1215
2079
|
return { ok, mode, results };
|
|
1216
|
-
}
|
|
1217
|
-
|
|
2080
|
+
};
|
|
2081
|
+
var assertOptionsCoherent = (options) => {
|
|
1218
2082
|
if (options.storeId !== void 0) return;
|
|
1219
2083
|
const dependent = [];
|
|
1220
2084
|
if (hasAny(options.webhookUrl, options.webhookUrls)) dependent.push("webhookUrl");
|
|
@@ -1226,23 +2090,24 @@ function assertOptionsCoherent(options) {
|
|
|
1226
2090
|
code: "DOCTOR_OPTIONS_INVALID",
|
|
1227
2091
|
message: `doctor() received ${dependent.join(", ")} without storeId. These validators cannot run without a store; pass \`storeId\` or remove the dependent options.`
|
|
1228
2092
|
});
|
|
1229
|
-
}
|
|
1230
|
-
|
|
2093
|
+
};
|
|
2094
|
+
var collectValues = (single, many) => {
|
|
1231
2095
|
const values2 = /* @__PURE__ */ new Set();
|
|
1232
2096
|
if (single !== void 0) values2.add(single);
|
|
1233
2097
|
for (const value of many ?? []) {
|
|
1234
2098
|
if (value !== void 0) values2.add(value);
|
|
1235
2099
|
}
|
|
1236
2100
|
return Array.from(values2);
|
|
1237
|
-
}
|
|
1238
|
-
|
|
2101
|
+
};
|
|
2102
|
+
var hasAny = (single, many) => {
|
|
1239
2103
|
return single !== void 0 || (many?.length ?? 0) > 0;
|
|
1240
|
-
}
|
|
2104
|
+
};
|
|
1241
2105
|
|
|
1242
2106
|
// src/createFreshSqueezy.ts
|
|
1243
|
-
|
|
2107
|
+
var createFreshSqueezy = (config = {}) => {
|
|
1244
2108
|
const resolved = resolveConfig(config);
|
|
1245
2109
|
const http = new HttpClient(resolved);
|
|
2110
|
+
const op = (resource, verb, args = {}) => invokeOp(http, resource, verb, args);
|
|
1246
2111
|
return {
|
|
1247
2112
|
mode: resolved.mode,
|
|
1248
2113
|
request: (options) => http.request(options),
|
|
@@ -1265,12 +2130,109 @@ function createFreshSqueezy(config = {}) {
|
|
|
1265
2130
|
licenseKeyIds: options?.licenseKeyIds,
|
|
1266
2131
|
variantId: options?.variantId,
|
|
1267
2132
|
variantIds: options?.variantIds
|
|
1268
|
-
})
|
|
2133
|
+
}),
|
|
2134
|
+
users: {
|
|
2135
|
+
me: () => op("user", "get")
|
|
2136
|
+
},
|
|
2137
|
+
stores: {
|
|
2138
|
+
get: (id) => op("store", "get", { id }),
|
|
2139
|
+
list: () => op("store", "list")
|
|
2140
|
+
},
|
|
2141
|
+
products: {
|
|
2142
|
+
get: (id) => op("product", "get", { id }),
|
|
2143
|
+
list: (storeId) => op("product", "list", { storeId })
|
|
2144
|
+
},
|
|
2145
|
+
variants: {
|
|
2146
|
+
get: (id) => op("variant", "get", { id }),
|
|
2147
|
+
list: (productId) => op("variant", "list", { parentId: productId })
|
|
2148
|
+
},
|
|
2149
|
+
prices: {
|
|
2150
|
+
get: (id) => op("price", "get", { id }),
|
|
2151
|
+
list: (variantId) => op("price", "list", { parentId: variantId })
|
|
2152
|
+
},
|
|
2153
|
+
files: {
|
|
2154
|
+
get: (id) => op("file", "get", { id }),
|
|
2155
|
+
list: (variantId) => op("file", "list", { parentId: variantId })
|
|
2156
|
+
},
|
|
2157
|
+
customers: {
|
|
2158
|
+
get: (id) => op("customer", "get", { id }),
|
|
2159
|
+
list: (storeId) => op("customer", "list", { storeId }),
|
|
2160
|
+
create: (body) => op("customer", "create", { body }),
|
|
2161
|
+
update: (id, body) => op("customer", "update", { id, body })
|
|
2162
|
+
},
|
|
2163
|
+
orders: {
|
|
2164
|
+
get: (id) => op("order", "get", { id }),
|
|
2165
|
+
list: (storeId) => op("order", "list", { storeId }),
|
|
2166
|
+
refund: (id, body) => op("order", "refund", { id, body }),
|
|
2167
|
+
generateInvoice: (id, body) => op("order", "generate-invoice", { id, body })
|
|
2168
|
+
},
|
|
2169
|
+
orderItems: {
|
|
2170
|
+
get: (id) => op("order-item", "get", { id }),
|
|
2171
|
+
list: (orderId) => op("order-item", "list", { parentId: orderId })
|
|
2172
|
+
},
|
|
2173
|
+
subscriptions: {
|
|
2174
|
+
get: (id) => op("subscription", "get", { id }),
|
|
2175
|
+
list: (storeId) => op("subscription", "list", { storeId }),
|
|
2176
|
+
update: (id, body) => op("subscription", "update", { id, body }),
|
|
2177
|
+
cancel: (id) => op("subscription", "cancel", { id })
|
|
2178
|
+
},
|
|
2179
|
+
subscriptionItems: {
|
|
2180
|
+
get: (id) => op("subscription-item", "get", { id }),
|
|
2181
|
+
list: (subscriptionId) => op("subscription-item", "list", { parentId: subscriptionId }),
|
|
2182
|
+
update: (id, body) => op("subscription-item", "update", { id, body }),
|
|
2183
|
+
currentUsage: (id) => op("subscription-item", "current-usage", { id })
|
|
2184
|
+
},
|
|
2185
|
+
subscriptionInvoices: {
|
|
2186
|
+
get: (id) => op("subscription-invoice", "get", { id }),
|
|
2187
|
+
list: (subscriptionId) => op("subscription-invoice", "list", { parentId: subscriptionId }),
|
|
2188
|
+
refund: (id, body) => op("subscription-invoice", "refund", { id, body }),
|
|
2189
|
+
generateInvoice: (id, body) => op("subscription-invoice", "generate-invoice", { id, body })
|
|
2190
|
+
},
|
|
2191
|
+
usageRecords: {
|
|
2192
|
+
get: (id) => op("usage-record", "get", { id }),
|
|
2193
|
+
list: (subscriptionItemId) => op("usage-record", "list", { parentId: subscriptionItemId }),
|
|
2194
|
+
create: (body) => op("usage-record", "create", { body })
|
|
2195
|
+
},
|
|
2196
|
+
discounts: {
|
|
2197
|
+
get: (id) => op("discount", "get", { id }),
|
|
2198
|
+
list: (storeId) => op("discount", "list", { storeId }),
|
|
2199
|
+
create: (body) => op("discount", "create", { body }),
|
|
2200
|
+
delete: (id) => op("discount", "delete", { id })
|
|
2201
|
+
},
|
|
2202
|
+
discountRedemptions: {
|
|
2203
|
+
get: (id) => op("discount-redemption", "get", { id }),
|
|
2204
|
+
list: (discountId) => op("discount-redemption", "list", { parentId: discountId })
|
|
2205
|
+
},
|
|
2206
|
+
licenseKeys: {
|
|
2207
|
+
get: (id) => op("license-key", "get", { id }),
|
|
2208
|
+
list: (storeId) => op("license-key", "list", { storeId }),
|
|
2209
|
+
update: (id, body) => op("license-key", "update", { id, body })
|
|
2210
|
+
},
|
|
2211
|
+
licenseKeyInstances: {
|
|
2212
|
+
get: (id) => op("license-key-instance", "get", { id }),
|
|
2213
|
+
list: (licenseKeyId) => op("license-key-instance", "list", { parentId: licenseKeyId })
|
|
2214
|
+
},
|
|
2215
|
+
checkouts: {
|
|
2216
|
+
get: (id) => op("checkout", "get", { id }),
|
|
2217
|
+
list: (storeId) => op("checkout", "list", { storeId }),
|
|
2218
|
+
create: (body) => op("checkout", "create", { body })
|
|
2219
|
+
},
|
|
2220
|
+
webhooks: {
|
|
2221
|
+
get: (id) => op("webhook", "get", { id }),
|
|
2222
|
+
list: (storeId) => op("webhook", "list", { storeId }),
|
|
2223
|
+
create: (body) => op("webhook", "create", { body }),
|
|
2224
|
+
update: (id, body) => op("webhook", "update", { id, body }),
|
|
2225
|
+
delete: (id) => op("webhook", "delete", { id })
|
|
2226
|
+
},
|
|
2227
|
+
affiliates: {
|
|
2228
|
+
get: (id) => op("affiliate", "get", { id }),
|
|
2229
|
+
list: (storeId) => op("affiliate", "list", { storeId })
|
|
2230
|
+
}
|
|
1269
2231
|
};
|
|
1270
|
-
}
|
|
2232
|
+
};
|
|
1271
2233
|
|
|
1272
2234
|
// src/cli/errors.ts
|
|
1273
|
-
|
|
2235
|
+
var renderCliError = (message, hints = []) => {
|
|
1274
2236
|
const lines = [`fresh-squeezy: ${message}`];
|
|
1275
2237
|
if (hints.length > 0) {
|
|
1276
2238
|
lines.push("", "Try:");
|
|
@@ -1280,8 +2242,8 @@ function renderCliError(message, hints = []) {
|
|
|
1280
2242
|
}
|
|
1281
2243
|
return `${lines.join("\n")}
|
|
1282
2244
|
`;
|
|
1283
|
-
}
|
|
1284
|
-
|
|
2245
|
+
};
|
|
2246
|
+
var getDoctorHints = (err) => {
|
|
1285
2247
|
if (!isFreshSqueezyError(err)) return [];
|
|
1286
2248
|
if (err.code === "MISSING_API_KEY") {
|
|
1287
2249
|
return ["fresh-squeezy init", `export ${ENV_KEYS.apiKey}=ls_live_or_test_key`];
|
|
@@ -1293,8 +2255,8 @@ function getDoctorHints(err) {
|
|
|
1293
2255
|
return ["Check that the API key belongs to an account with a Lemon Squeezy store."];
|
|
1294
2256
|
}
|
|
1295
2257
|
return [];
|
|
1296
|
-
}
|
|
1297
|
-
|
|
2258
|
+
};
|
|
2259
|
+
var getValidateHints = (err, target) => {
|
|
1298
2260
|
if (!isFreshSqueezyError(err)) return [];
|
|
1299
2261
|
if (err.code === "MISSING_API_KEY") {
|
|
1300
2262
|
return ["fresh-squeezy init", `export ${ENV_KEYS.apiKey}=ls_live_or_test_key`];
|
|
@@ -1309,8 +2271,8 @@ function getValidateHints(err, target) {
|
|
|
1309
2271
|
return getMissingArgHints(target);
|
|
1310
2272
|
}
|
|
1311
2273
|
return [];
|
|
1312
|
-
}
|
|
1313
|
-
|
|
2274
|
+
};
|
|
2275
|
+
var getMissingArgHints = (target) => {
|
|
1314
2276
|
if (target === "connection") {
|
|
1315
2277
|
return ["fresh-squeezy validate connection"];
|
|
1316
2278
|
}
|
|
@@ -1336,14 +2298,14 @@ function getMissingArgHints(target) {
|
|
|
1336
2298
|
return ["fresh-squeezy validate license-key --store-ids 12 --license-key-id 123"];
|
|
1337
2299
|
}
|
|
1338
2300
|
return ["fresh-squeezy validate subscription-plan --store-ids 12 --variant-id 123"];
|
|
1339
|
-
}
|
|
1340
|
-
|
|
2301
|
+
};
|
|
2302
|
+
var isFreshSqueezyError = (err) => {
|
|
1341
2303
|
return err instanceof FreshSqueezyError;
|
|
1342
|
-
}
|
|
2304
|
+
};
|
|
1343
2305
|
|
|
1344
2306
|
// src/cli/render.ts
|
|
1345
2307
|
import chalk from "chalk";
|
|
1346
|
-
|
|
2308
|
+
var renderResult = (result) => {
|
|
1347
2309
|
const lines = [];
|
|
1348
2310
|
const badge = result.ok ? chalk.green("PASS") : chalk.red("FAIL");
|
|
1349
2311
|
const mode = chalk.dim(`[${result.mode}]`);
|
|
@@ -1357,15 +2319,15 @@ function renderResult(result) {
|
|
|
1357
2319
|
}
|
|
1358
2320
|
}
|
|
1359
2321
|
return lines.join("\n");
|
|
1360
|
-
}
|
|
1361
|
-
|
|
2322
|
+
};
|
|
2323
|
+
var renderTarget = (target) => {
|
|
1362
2324
|
if (!target) return "";
|
|
1363
2325
|
const parts = [target.label];
|
|
1364
2326
|
if (target.id) parts.push(`id ${target.id}`);
|
|
1365
2327
|
if (target.url && target.url !== target.label) parts.push(target.url);
|
|
1366
2328
|
return parts.join(" - ");
|
|
1367
|
-
}
|
|
1368
|
-
|
|
2329
|
+
};
|
|
2330
|
+
var renderReport = (report) => {
|
|
1369
2331
|
const header = report.ok ? chalk.green.bold("fresh-squeezy doctor: OK") : chalk.red.bold("fresh-squeezy doctor: FAILED");
|
|
1370
2332
|
const failed = report.results.filter((result) => !result.ok).length;
|
|
1371
2333
|
const summary = failed === 0 ? chalk.dim(`${report.results.length} checks passed`) : chalk.dim(`${failed}/${report.results.length} checks failed`);
|
|
@@ -1374,11 +2336,11 @@ function renderReport(report) {
|
|
|
1374
2336
|
${summary}
|
|
1375
2337
|
|
|
1376
2338
|
${body}`;
|
|
1377
|
-
}
|
|
1378
|
-
|
|
2339
|
+
};
|
|
2340
|
+
var renderIssueLine = (issue2) => {
|
|
1379
2341
|
const label = issue2.severity === "error" ? chalk.red("\u2717 error") : issue2.severity === "warning" ? chalk.yellow("! warn ") : chalk.blue("i info ");
|
|
1380
2342
|
return `${label} ${chalk.gray(`[${issue2.code}]`)} ${issue2.message}`;
|
|
1381
|
-
}
|
|
2343
|
+
};
|
|
1382
2344
|
|
|
1383
2345
|
// src/cli/prompts.ts
|
|
1384
2346
|
import path from "path";
|
|
@@ -1392,7 +2354,7 @@ var EMPTY_INIT_RESOURCE_CHOICES = {
|
|
|
1392
2354
|
licenseKeys: { choices: [] },
|
|
1393
2355
|
subscriptionPlans: { choices: [] }
|
|
1394
2356
|
};
|
|
1395
|
-
async
|
|
2357
|
+
var discoverInitResourceChoices = async (client, storeId, targets) => {
|
|
1396
2358
|
const choices = {
|
|
1397
2359
|
products: { choices: [] },
|
|
1398
2360
|
webhooks: { choices: [] },
|
|
@@ -1439,8 +2401,8 @@ async function discoverInitResourceChoices(client, storeId, targets) {
|
|
|
1439
2401
|
}
|
|
1440
2402
|
}
|
|
1441
2403
|
return choices;
|
|
1442
|
-
}
|
|
1443
|
-
async
|
|
2404
|
+
};
|
|
2405
|
+
var discoverSubscriptionPlans = async (client, products) => {
|
|
1444
2406
|
const discovered = [];
|
|
1445
2407
|
for (const product of products) {
|
|
1446
2408
|
const result = await discover(
|
|
@@ -1458,8 +2420,8 @@ async function discoverSubscriptionPlans(client, products) {
|
|
|
1458
2420
|
}
|
|
1459
2421
|
}
|
|
1460
2422
|
return { choices: discovered };
|
|
1461
|
-
}
|
|
1462
|
-
async
|
|
2423
|
+
};
|
|
2424
|
+
var paginate = async (client, path4, query) => {
|
|
1463
2425
|
const all = [];
|
|
1464
2426
|
let pageNumber = Number(query?.["page[number]"] ?? 1);
|
|
1465
2427
|
while (true) {
|
|
@@ -1472,45 +2434,45 @@ async function paginate(client, path4, query) {
|
|
|
1472
2434
|
if (lastPage === void 0 || pageNumber >= lastPage) return all;
|
|
1473
2435
|
pageNumber += 1;
|
|
1474
2436
|
}
|
|
1475
|
-
}
|
|
1476
|
-
async
|
|
2437
|
+
};
|
|
2438
|
+
var discover = async (load) => {
|
|
1477
2439
|
try {
|
|
1478
2440
|
return { ok: true, value: await load() };
|
|
1479
2441
|
} catch (err) {
|
|
1480
2442
|
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
1481
2443
|
}
|
|
1482
|
-
}
|
|
1483
|
-
|
|
2444
|
+
};
|
|
2445
|
+
var toProductChoice = (product) => {
|
|
1484
2446
|
return {
|
|
1485
2447
|
value: product.id,
|
|
1486
2448
|
label: `${product.attributes.name} (${product.attributes.status}) - id ${product.id}`
|
|
1487
2449
|
};
|
|
1488
|
-
}
|
|
1489
|
-
|
|
2450
|
+
};
|
|
2451
|
+
var toWebhookChoice = (webhook) => {
|
|
1490
2452
|
return {
|
|
1491
2453
|
value: webhook.attributes.url,
|
|
1492
2454
|
label: `${webhook.attributes.url} - id ${webhook.id}`
|
|
1493
2455
|
};
|
|
1494
|
-
}
|
|
1495
|
-
|
|
2456
|
+
};
|
|
2457
|
+
var toDiscountChoice = (discount) => {
|
|
1496
2458
|
return {
|
|
1497
2459
|
value: discount.id,
|
|
1498
2460
|
label: `${discount.attributes.name} (${discount.attributes.code}) - id ${discount.id}`
|
|
1499
2461
|
};
|
|
1500
|
-
}
|
|
1501
|
-
|
|
2462
|
+
};
|
|
2463
|
+
var toLicenseKeyChoice = (licenseKey) => {
|
|
1502
2464
|
return {
|
|
1503
2465
|
value: licenseKey.id,
|
|
1504
2466
|
label: `${licenseKey.attributes.key_short} (${licenseKey.attributes.status}) - id ${licenseKey.id}`
|
|
1505
2467
|
};
|
|
1506
|
-
}
|
|
1507
|
-
|
|
2468
|
+
};
|
|
2469
|
+
var toSubscriptionPlanChoice = (variant, productName) => {
|
|
1508
2470
|
const interval = variant.attributes.interval ? `${variant.attributes.interval_count ?? 1}/${variant.attributes.interval}` : "no interval";
|
|
1509
2471
|
return {
|
|
1510
2472
|
value: variant.id,
|
|
1511
2473
|
label: `${productName} / ${variant.attributes.name} (${interval}) - id ${variant.id}`
|
|
1512
2474
|
};
|
|
1513
|
-
}
|
|
2475
|
+
};
|
|
1514
2476
|
|
|
1515
2477
|
// src/cli/prompts.ts
|
|
1516
2478
|
var PROMPT_THEME = {
|
|
@@ -1519,7 +2481,7 @@ var PROMPT_THEME = {
|
|
|
1519
2481
|
done: "\u2713"
|
|
1520
2482
|
}
|
|
1521
2483
|
};
|
|
1522
|
-
async
|
|
2484
|
+
var pickLauncherAction = async () => {
|
|
1523
2485
|
return select({
|
|
1524
2486
|
message: "What do you want to do?",
|
|
1525
2487
|
theme: PROMPT_THEME,
|
|
@@ -1542,8 +2504,8 @@ async function pickLauncherAction() {
|
|
|
1542
2504
|
}
|
|
1543
2505
|
]
|
|
1544
2506
|
});
|
|
1545
|
-
}
|
|
1546
|
-
async
|
|
2507
|
+
};
|
|
2508
|
+
var askForApiKey = async () => {
|
|
1547
2509
|
const apiKey = await password({
|
|
1548
2510
|
message: "Paste your Lemon Squeezy API key:",
|
|
1549
2511
|
mask: false,
|
|
@@ -1551,8 +2513,8 @@ async function askForApiKey() {
|
|
|
1551
2513
|
validate: (value) => value.trim().length > 0 ? true : "API key is required."
|
|
1552
2514
|
});
|
|
1553
2515
|
return { apiKey: apiKey.trim() };
|
|
1554
|
-
}
|
|
1555
|
-
async
|
|
2516
|
+
};
|
|
2517
|
+
var pickStore = async (choices) => {
|
|
1556
2518
|
return select({
|
|
1557
2519
|
message: "Pick a store to validate against:",
|
|
1558
2520
|
theme: PROMPT_THEME,
|
|
@@ -1561,8 +2523,8 @@ async function pickStore(choices) {
|
|
|
1561
2523
|
value: entry.id
|
|
1562
2524
|
}))
|
|
1563
2525
|
});
|
|
1564
|
-
}
|
|
1565
|
-
async
|
|
2526
|
+
};
|
|
2527
|
+
var pickStores = async (choices) => {
|
|
1566
2528
|
return checkbox({
|
|
1567
2529
|
message: "Pick one or more stores (space to toggle, enter to confirm):",
|
|
1568
2530
|
theme: PROMPT_THEME,
|
|
@@ -1573,8 +2535,8 @@ async function pickStores(choices) {
|
|
|
1573
2535
|
})),
|
|
1574
2536
|
validate: (selected) => selected.length > 0 ? true : "Pick at least one store."
|
|
1575
2537
|
});
|
|
1576
|
-
}
|
|
1577
|
-
async
|
|
2538
|
+
};
|
|
2539
|
+
var selectDoctorTargets = async () => {
|
|
1578
2540
|
return checkbox({
|
|
1579
2541
|
message: "Add resource checks to this doctor run?",
|
|
1580
2542
|
theme: PROMPT_THEME,
|
|
@@ -1586,8 +2548,8 @@ async function selectDoctorTargets() {
|
|
|
1586
2548
|
{ name: "Subscription plan", value: "subscription-plan" }
|
|
1587
2549
|
]
|
|
1588
2550
|
});
|
|
1589
|
-
}
|
|
1590
|
-
async
|
|
2551
|
+
};
|
|
2552
|
+
var askForDoctorTargetValues = async (targets, choices = EMPTY_INIT_RESOURCE_CHOICES) => {
|
|
1591
2553
|
if (targets.length === 0) return {};
|
|
1592
2554
|
const answers = {};
|
|
1593
2555
|
const manualQuestions = [];
|
|
@@ -1665,22 +2627,29 @@ async function askForDoctorTargetValues(targets, choices = EMPTY_INIT_RESOURCE_C
|
|
|
1665
2627
|
licenseKeyIds: cleanList(answers.licenseKeyIds),
|
|
1666
2628
|
variantIds: cleanList(answers.variantIds)
|
|
1667
2629
|
};
|
|
1668
|
-
}
|
|
1669
|
-
async
|
|
2630
|
+
};
|
|
2631
|
+
var confirmLiveModeRun = async () => {
|
|
1670
2632
|
return confirm({
|
|
1671
2633
|
message: "This is a live-mode key. Continue with live checks?",
|
|
1672
2634
|
default: false,
|
|
1673
2635
|
theme: PROMPT_THEME
|
|
1674
2636
|
});
|
|
1675
|
-
}
|
|
1676
|
-
async
|
|
2637
|
+
};
|
|
2638
|
+
var confirmWriteEnvFile = async (filePath) => {
|
|
1677
2639
|
return confirm({
|
|
1678
2640
|
message: `Write these values to ${formatPromptPath(filePath)}?`,
|
|
1679
2641
|
default: true,
|
|
1680
2642
|
theme: PROMPT_THEME
|
|
1681
2643
|
});
|
|
1682
|
-
}
|
|
1683
|
-
async
|
|
2644
|
+
};
|
|
2645
|
+
var confirmResourceOp = async (message) => {
|
|
2646
|
+
return confirm({
|
|
2647
|
+
message,
|
|
2648
|
+
default: false,
|
|
2649
|
+
theme: PROMPT_THEME
|
|
2650
|
+
});
|
|
2651
|
+
};
|
|
2652
|
+
var resolveTargetValue = async (input2) => {
|
|
1684
2653
|
if (input2.group.choices.length === 0) {
|
|
1685
2654
|
input2.manualQuestions.push({
|
|
1686
2655
|
field: input2.field,
|
|
@@ -1709,8 +2678,8 @@ async function resolveTargetValue(input2) {
|
|
|
1709
2678
|
validate: input2.validate
|
|
1710
2679
|
});
|
|
1711
2680
|
}
|
|
1712
|
-
}
|
|
1713
|
-
async
|
|
2681
|
+
};
|
|
2682
|
+
var askEmptyTargetAction = async (message) => {
|
|
1714
2683
|
return select({
|
|
1715
2684
|
message,
|
|
1716
2685
|
theme: PROMPT_THEME,
|
|
@@ -1719,18 +2688,18 @@ async function askEmptyTargetAction(message) {
|
|
|
1719
2688
|
{ name: "Skip this check", value: "skip" }
|
|
1720
2689
|
]
|
|
1721
2690
|
});
|
|
1722
|
-
}
|
|
1723
|
-
|
|
2691
|
+
};
|
|
2692
|
+
var required = (label) => {
|
|
1724
2693
|
return (value) => value.trim().length > 0 ? true : `${label} is required.`;
|
|
1725
|
-
}
|
|
1726
|
-
|
|
2694
|
+
};
|
|
2695
|
+
var optional = (label) => {
|
|
1727
2696
|
return (value) => {
|
|
1728
2697
|
const trimmed = value.trim();
|
|
1729
2698
|
if (trimmed.length === 0) return true;
|
|
1730
2699
|
return required(label)(trimmed);
|
|
1731
2700
|
};
|
|
1732
|
-
}
|
|
1733
|
-
|
|
2701
|
+
};
|
|
2702
|
+
var validateWebhookUrl = (value) => {
|
|
1734
2703
|
const trimmed = value.trim();
|
|
1735
2704
|
if (trimmed.length === 0) return "Webhook URL is required.";
|
|
1736
2705
|
try {
|
|
@@ -1739,32 +2708,32 @@ function validateWebhookUrl(value) {
|
|
|
1739
2708
|
} catch {
|
|
1740
2709
|
return "Enter a valid webhook URL.";
|
|
1741
2710
|
}
|
|
1742
|
-
}
|
|
1743
|
-
|
|
2711
|
+
};
|
|
2712
|
+
var optionalWebhookUrls = (value) => {
|
|
1744
2713
|
const values2 = splitManualValues(value);
|
|
1745
2714
|
if (values2.length === 0) return true;
|
|
1746
2715
|
return values2.every((entry) => validateWebhookUrl(entry) === true) ? true : "Enter valid webhook URLs.";
|
|
1747
|
-
}
|
|
1748
|
-
|
|
2716
|
+
};
|
|
2717
|
+
var cleanList = (value) => {
|
|
1749
2718
|
const values2 = Array.isArray(value) ? value : splitManualValues(value);
|
|
1750
2719
|
const cleanValues = Array.from(new Set(values2.map((entry) => entry.trim()).filter(Boolean)));
|
|
1751
2720
|
return cleanValues.length > 0 ? cleanValues : void 0;
|
|
1752
|
-
}
|
|
1753
|
-
|
|
2721
|
+
};
|
|
2722
|
+
var splitManualValues = (value) => {
|
|
1754
2723
|
return (value ?? "").split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
1755
|
-
}
|
|
1756
|
-
|
|
2724
|
+
};
|
|
2725
|
+
var formatPromptPath = (filePath) => {
|
|
1757
2726
|
const relative = path.relative(process.cwd(), filePath);
|
|
1758
2727
|
if (relative && !relative.startsWith("..") && !path.isAbsolute(relative)) return relative;
|
|
1759
2728
|
return path.basename(filePath);
|
|
1760
|
-
}
|
|
1761
|
-
|
|
2729
|
+
};
|
|
2730
|
+
var isPromptCancel = (error) => {
|
|
1762
2731
|
if (!(error instanceof Error)) return false;
|
|
1763
2732
|
return error.name === "ExitPromptError" || error.message.includes("User force closed");
|
|
1764
|
-
}
|
|
2733
|
+
};
|
|
1765
2734
|
|
|
1766
2735
|
// src/cli/resolveStores.ts
|
|
1767
|
-
async
|
|
2736
|
+
var resolveStores = async (client, input2) => {
|
|
1768
2737
|
if (input2.storeIds && input2.storeIds.length > 0) {
|
|
1769
2738
|
return { storeIds: dedupe(input2.storeIds), skipped: false };
|
|
1770
2739
|
}
|
|
@@ -1809,8 +2778,8 @@ async function resolveStores(client, input2) {
|
|
|
1809
2778
|
});
|
|
1810
2779
|
}
|
|
1811
2780
|
return { storeIds: picked, skipped: false };
|
|
1812
|
-
}
|
|
1813
|
-
async
|
|
2781
|
+
};
|
|
2782
|
+
var fetchReachableStoreIds = async (client) => {
|
|
1814
2783
|
const connection = await client.validateConnection();
|
|
1815
2784
|
if (!connection.ok) {
|
|
1816
2785
|
const authIssue = connection.issues.find((entry) => entry.code === "AUTH_FAILED");
|
|
@@ -1822,10 +2791,10 @@ async function fetchReachableStoreIds(client) {
|
|
|
1822
2791
|
}
|
|
1823
2792
|
}
|
|
1824
2793
|
return connection.resource?.storeIds ?? [];
|
|
1825
|
-
}
|
|
1826
|
-
|
|
2794
|
+
};
|
|
2795
|
+
var dedupe = (values2) => {
|
|
1827
2796
|
return Array.from(new Set(values2.map((value) => value.trim()).filter(Boolean)));
|
|
1828
|
-
}
|
|
2797
|
+
};
|
|
1829
2798
|
|
|
1830
2799
|
// src/cli/commands/doctor.ts
|
|
1831
2800
|
var ALL_RESOURCE_TARGETS = [
|
|
@@ -1835,7 +2804,7 @@ var ALL_RESOURCE_TARGETS = [
|
|
|
1835
2804
|
"license-key",
|
|
1836
2805
|
"subscription-plan"
|
|
1837
2806
|
];
|
|
1838
|
-
async
|
|
2807
|
+
var runDoctorCommand = async (options) => {
|
|
1839
2808
|
try {
|
|
1840
2809
|
const client = createFreshSqueezy({ mode: options.mode });
|
|
1841
2810
|
const resolved = await resolveStores(client, {
|
|
@@ -1874,8 +2843,8 @@ async function runDoctorCommand(options) {
|
|
|
1874
2843
|
writeFatal(err, options.json ?? false);
|
|
1875
2844
|
return 2;
|
|
1876
2845
|
}
|
|
1877
|
-
}
|
|
1878
|
-
async
|
|
2846
|
+
};
|
|
2847
|
+
var resolveDoctorTargets = async (client, storeId, options) => {
|
|
1879
2848
|
const explicit = {
|
|
1880
2849
|
productIds: one(options.productId),
|
|
1881
2850
|
webhookUrls: one(options.webhookUrl),
|
|
@@ -1899,8 +2868,8 @@ async function resolveDoctorTargets(client, storeId, options) {
|
|
|
1899
2868
|
licenseKeyIds: mergeValues(explicit.licenseKeyIds, values(discovered.licenseKeys)),
|
|
1900
2869
|
variantIds: mergeValues(explicit.variantIds, values(discovered.subscriptionPlans))
|
|
1901
2870
|
};
|
|
1902
|
-
}
|
|
1903
|
-
|
|
2871
|
+
};
|
|
2872
|
+
var formatDiscoveryCounts = (choices) => {
|
|
1904
2873
|
return [
|
|
1905
2874
|
countLabel("products", choices.products.choices.length),
|
|
1906
2875
|
countLabel("webhooks", choices.webhooks.choices.length),
|
|
@@ -1908,11 +2877,11 @@ function formatDiscoveryCounts(choices) {
|
|
|
1908
2877
|
countLabel("license keys", choices.licenseKeys.choices.length),
|
|
1909
2878
|
countLabel("subscription plans", choices.subscriptionPlans.choices.length)
|
|
1910
2879
|
].join(", ");
|
|
1911
|
-
}
|
|
1912
|
-
|
|
2880
|
+
};
|
|
2881
|
+
var countLabel = (label, count) => {
|
|
1913
2882
|
return `${label} ${count}`;
|
|
1914
|
-
}
|
|
1915
|
-
|
|
2883
|
+
};
|
|
2884
|
+
var reportDiscoveryErrors = (choices) => {
|
|
1916
2885
|
const errors = [
|
|
1917
2886
|
choices.products.error && `products: ${choices.products.error}`,
|
|
1918
2887
|
choices.webhooks.error && `webhooks: ${choices.webhooks.error}`,
|
|
@@ -1924,23 +2893,23 @@ function reportDiscoveryErrors(choices) {
|
|
|
1924
2893
|
process.stderr.write(`fresh-squeezy: discovery skipped ${error}
|
|
1925
2894
|
`);
|
|
1926
2895
|
}
|
|
1927
|
-
}
|
|
1928
|
-
|
|
2896
|
+
};
|
|
2897
|
+
var values = (group) => {
|
|
1929
2898
|
return group.choices.length > 0 ? group.choices.map((choice) => choice.value) : void 0;
|
|
1930
|
-
}
|
|
1931
|
-
|
|
2899
|
+
};
|
|
2900
|
+
var one = (value) => {
|
|
1932
2901
|
return value ? [value] : void 0;
|
|
1933
|
-
}
|
|
1934
|
-
|
|
2902
|
+
};
|
|
2903
|
+
var mergeValues = (explicit, discovered) => {
|
|
1935
2904
|
const merged = Array.from(/* @__PURE__ */ new Set([...explicit ?? [], ...discovered ?? []]));
|
|
1936
2905
|
return merged.length > 0 ? merged : void 0;
|
|
1937
|
-
}
|
|
1938
|
-
|
|
2906
|
+
};
|
|
2907
|
+
var hasExplicitResourceSelection = (options) => {
|
|
1939
2908
|
return Boolean(
|
|
1940
2909
|
options.productId || options.webhookUrl || options.discountId || options.licenseKeyId || options.variantId
|
|
1941
2910
|
);
|
|
1942
|
-
}
|
|
1943
|
-
async
|
|
2911
|
+
};
|
|
2912
|
+
var runConnectionOnly = async (client, options) => {
|
|
1944
2913
|
const connection = await client.validateConnection();
|
|
1945
2914
|
const report = {
|
|
1946
2915
|
ok: connection.ok,
|
|
@@ -1959,8 +2928,8 @@ async function runConnectionOnly(client, options) {
|
|
|
1959
2928
|
`);
|
|
1960
2929
|
}
|
|
1961
2930
|
return connection.ok ? 0 : 1;
|
|
1962
|
-
}
|
|
1963
|
-
|
|
2931
|
+
};
|
|
2932
|
+
var writeFatal = (err, asJson) => {
|
|
1964
2933
|
if (asJson) {
|
|
1965
2934
|
const payload = err instanceof FreshSqueezyError ? { ok: false, error: { code: err.code, message: err.message, status: err.status ?? null } } : {
|
|
1966
2935
|
ok: false,
|
|
@@ -1972,7 +2941,7 @@ function writeFatal(err, asJson) {
|
|
|
1972
2941
|
}
|
|
1973
2942
|
const message = err instanceof Error ? err.message : String(err);
|
|
1974
2943
|
process.stderr.write(renderCliError(message, getDoctorHints(err)));
|
|
1975
|
-
}
|
|
2944
|
+
};
|
|
1976
2945
|
|
|
1977
2946
|
// src/cli/commands/init.ts
|
|
1978
2947
|
import fs from "fs/promises";
|
|
@@ -1983,24 +2952,24 @@ import chalk3 from "chalk";
|
|
|
1983
2952
|
import chalk2 from "chalk";
|
|
1984
2953
|
var brand = chalk2.green.bold("fresh-squeezy");
|
|
1985
2954
|
var divider = chalk2.dim("\u2022");
|
|
1986
|
-
|
|
2955
|
+
var renderBrandHeader = (title, subtitle) => {
|
|
1987
2956
|
const lines = [`${brand} ${divider} ${chalk2.bold(title)}`];
|
|
1988
2957
|
if (subtitle) lines.push(chalk2.dim(subtitle));
|
|
1989
2958
|
lines.push("");
|
|
1990
2959
|
return lines.join("\n");
|
|
1991
|
-
}
|
|
1992
|
-
|
|
2960
|
+
};
|
|
2961
|
+
var renderStep = (index, total, title, detail) => {
|
|
1993
2962
|
const suffix = detail ? ` ${chalk2.dim(detail)}` : "";
|
|
1994
2963
|
const prefix = index > 1 ? "\n" : "";
|
|
1995
2964
|
return `${prefix}${chalk2.yellow("\u25CF")} ${chalk2.dim(`${index}/${total}`)} ${chalk2.bold(title)}${suffix}
|
|
1996
2965
|
`;
|
|
1997
|
-
}
|
|
1998
|
-
|
|
2966
|
+
};
|
|
2967
|
+
var renderDetected = (label, value, source) => {
|
|
1999
2968
|
const suffix = source ? ` ${chalk2.dim(`from ${source}`)}` : "";
|
|
2000
2969
|
return ` ${chalk2.green("\u2713")} ${chalk2.bold(label)} ${value}${suffix}
|
|
2001
2970
|
`;
|
|
2002
|
-
}
|
|
2003
|
-
|
|
2971
|
+
};
|
|
2972
|
+
var renderCommandExamples = () => {
|
|
2004
2973
|
return [
|
|
2005
2974
|
renderBrandHeader("Command examples", "Direct commands stay stable for scripts and CI."),
|
|
2006
2975
|
`${chalk2.bold("Guided setup")}`,
|
|
@@ -2018,14 +2987,14 @@ function renderCommandExamples() {
|
|
|
2018
2987
|
" fresh-squeezy doctor --all-stores --json",
|
|
2019
2988
|
""
|
|
2020
2989
|
].join("\n");
|
|
2021
|
-
}
|
|
2022
|
-
|
|
2990
|
+
};
|
|
2991
|
+
var renderCancelMessage = () => {
|
|
2023
2992
|
return `${chalk2.dim("fresh-squeezy cancelled.")}
|
|
2024
2993
|
`;
|
|
2025
|
-
}
|
|
2994
|
+
};
|
|
2026
2995
|
|
|
2027
2996
|
// src/cli/commands/init.ts
|
|
2028
|
-
async
|
|
2997
|
+
var runInitCommand = async (options = {}) => {
|
|
2029
2998
|
try {
|
|
2030
2999
|
return await runInitFlow(options);
|
|
2031
3000
|
} catch (err) {
|
|
@@ -2035,8 +3004,8 @@ async function runInitCommand(options = {}) {
|
|
|
2035
3004
|
}
|
|
2036
3005
|
throw err;
|
|
2037
3006
|
}
|
|
2038
|
-
}
|
|
2039
|
-
async
|
|
3007
|
+
};
|
|
3008
|
+
var runInitFlow = async (options) => {
|
|
2040
3009
|
if (options.isInteractive === false) {
|
|
2041
3010
|
process.stderr.write(
|
|
2042
3011
|
renderCliError("`fresh-squeezy init` requires an interactive terminal.", [
|
|
@@ -2113,8 +3082,8 @@ Running doctor (${checkNames.join(", ")})...
|
|
|
2113
3082
|
process.stdout.write(`${renderReport(report)}
|
|
2114
3083
|
`);
|
|
2115
3084
|
return report.ok ? 0 : 1;
|
|
2116
|
-
}
|
|
2117
|
-
async
|
|
3085
|
+
};
|
|
3086
|
+
var resolveStoreSelection = async (pickable) => {
|
|
2118
3087
|
if (pickable.length === 1) {
|
|
2119
3088
|
const store = pickable[0];
|
|
2120
3089
|
if (!store) throw new Error("Expected one reachable store.");
|
|
@@ -2124,8 +3093,8 @@ async function resolveStoreSelection(pickable) {
|
|
|
2124
3093
|
return store.id;
|
|
2125
3094
|
}
|
|
2126
3095
|
return pickStore(pickable);
|
|
2127
|
-
}
|
|
2128
|
-
async
|
|
3096
|
+
};
|
|
3097
|
+
var discoverChoices = async (client, storeId, selectedTargets) => {
|
|
2129
3098
|
if (selectedTargets.length === 0)
|
|
2130
3099
|
return {
|
|
2131
3100
|
products: { choices: [] },
|
|
@@ -2135,8 +3104,8 @@ async function discoverChoices(client, storeId, selectedTargets) {
|
|
|
2135
3104
|
subscriptionPlans: { choices: [] }
|
|
2136
3105
|
};
|
|
2137
3106
|
return discoverInitResourceChoices(client, storeId, selectedTargets);
|
|
2138
|
-
}
|
|
2139
|
-
async
|
|
3107
|
+
};
|
|
3108
|
+
var resolveApiKey = async () => {
|
|
2140
3109
|
const envApiKey = process.env[ENV_KEYS.apiKey]?.trim();
|
|
2141
3110
|
if (envApiKey) {
|
|
2142
3111
|
process.stdout.write(chalk3.dim(`Using ${ENV_KEYS.apiKey} from environment.
|
|
@@ -2145,8 +3114,8 @@ async function resolveApiKey() {
|
|
|
2145
3114
|
}
|
|
2146
3115
|
const answers = await askForApiKey();
|
|
2147
3116
|
return answers.apiKey;
|
|
2148
|
-
}
|
|
2149
|
-
async
|
|
3117
|
+
};
|
|
3118
|
+
var createDetectedClient = async (apiKey) => {
|
|
2150
3119
|
const envMode = parseEnvMode();
|
|
2151
3120
|
const initialMode = envMode ?? "test";
|
|
2152
3121
|
let client = createFreshSqueezy({ apiKey, mode: initialMode });
|
|
@@ -2174,8 +3143,8 @@ async function createDetectedClient(apiKey) {
|
|
|
2174
3143
|
}
|
|
2175
3144
|
process.stdout.write(chalk3.dim("Could not auto-detect key mode; using test mode.\n"));
|
|
2176
3145
|
return { client, mode: initialMode, connection };
|
|
2177
|
-
}
|
|
2178
|
-
|
|
3146
|
+
};
|
|
3147
|
+
var parseEnvMode = () => {
|
|
2179
3148
|
const value = process.env[ENV_KEYS.mode]?.trim();
|
|
2180
3149
|
if (value === "test" || value === "live") return value;
|
|
2181
3150
|
if (value) {
|
|
@@ -2185,8 +3154,8 @@ function parseEnvMode() {
|
|
|
2185
3154
|
);
|
|
2186
3155
|
}
|
|
2187
3156
|
return void 0;
|
|
2188
|
-
}
|
|
2189
|
-
|
|
3157
|
+
};
|
|
3158
|
+
var getDoctorCheckNames = (targets) => {
|
|
2190
3159
|
const names = ["connection", "store"];
|
|
2191
3160
|
pushCheckName(names, "product", targets.productIds);
|
|
2192
3161
|
pushCheckName(names, "webhook", targets.webhookUrls);
|
|
@@ -2194,12 +3163,12 @@ function getDoctorCheckNames(targets) {
|
|
|
2194
3163
|
pushCheckName(names, "licenseKey", targets.licenseKeyIds);
|
|
2195
3164
|
pushCheckName(names, "subscriptionPlan", targets.variantIds);
|
|
2196
3165
|
return names;
|
|
2197
|
-
}
|
|
2198
|
-
|
|
3166
|
+
};
|
|
3167
|
+
var pushCheckName = (names, name, values2) => {
|
|
2199
3168
|
if (!values2 || values2.length === 0) return;
|
|
2200
3169
|
names.push(values2.length === 1 ? name : `${name} x${values2.length}`);
|
|
2201
|
-
}
|
|
2202
|
-
|
|
3170
|
+
};
|
|
3171
|
+
var renderSetupSummary = (input2) => {
|
|
2203
3172
|
return [
|
|
2204
3173
|
renderStep(5, 5, "Ready to verify", "review before writing env"),
|
|
2205
3174
|
` ${chalk3.dim("mode")} ${input2.mode}`,
|
|
@@ -2208,8 +3177,8 @@ function renderSetupSummary(input2) {
|
|
|
2208
3177
|
` ${chalk3.dim("env")} ${input2.envPath}`,
|
|
2209
3178
|
""
|
|
2210
3179
|
].join("\n");
|
|
2211
|
-
}
|
|
2212
|
-
async
|
|
3180
|
+
};
|
|
3181
|
+
var writeEnvFile = async (envPath, values2) => {
|
|
2213
3182
|
const updates = /* @__PURE__ */ new Map([
|
|
2214
3183
|
[ENV_KEYS.apiKey, values2.apiKey],
|
|
2215
3184
|
[ENV_KEYS.storeId, values2.storeId],
|
|
@@ -2236,8 +3205,8 @@ async function writeEnvFile(envPath, values2) {
|
|
|
2236
3205
|
await fs.mkdir(path2.dirname(envPath), { recursive: true });
|
|
2237
3206
|
await fs.writeFile(envPath, `${next.join("\n").replace(/\n*$/, "")}
|
|
2238
3207
|
`, { encoding: "utf8" });
|
|
2239
|
-
}
|
|
2240
|
-
async
|
|
3208
|
+
};
|
|
3209
|
+
var readEnvFile = async (envPath) => {
|
|
2241
3210
|
try {
|
|
2242
3211
|
return await fs.readFile(envPath, "utf8");
|
|
2243
3212
|
} catch (err) {
|
|
@@ -2246,8 +3215,8 @@ async function readEnvFile(envPath) {
|
|
|
2246
3215
|
}
|
|
2247
3216
|
throw err;
|
|
2248
3217
|
}
|
|
2249
|
-
}
|
|
2250
|
-
|
|
3218
|
+
};
|
|
3219
|
+
var renderDiscoverySummary = (choices, selectedTargets) => {
|
|
2251
3220
|
if (selectedTargets.length === 0) return chalk3.dim(" No optional resource checks selected.\n");
|
|
2252
3221
|
const groups = [
|
|
2253
3222
|
["product", "Products", choices.products],
|
|
@@ -2269,7 +3238,7 @@ function renderDiscoverySummary(choices, selectedTargets) {
|
|
|
2269
3238
|
}
|
|
2270
3239
|
return `${lines.join("\n")}
|
|
2271
3240
|
`;
|
|
2272
|
-
}
|
|
3241
|
+
};
|
|
2273
3242
|
|
|
2274
3243
|
// src/cli/commands/launcher.ts
|
|
2275
3244
|
import chalk4 from "chalk";
|
|
@@ -2279,7 +3248,7 @@ import { spawn } from "child_process";
|
|
|
2279
3248
|
import fs2 from "fs/promises";
|
|
2280
3249
|
import path3 from "path";
|
|
2281
3250
|
var PACKAGE_NAME = "fresh-squeezy";
|
|
2282
|
-
async
|
|
3251
|
+
var ensureFreshSqueezyDevDependency = async (options = {}) => {
|
|
2283
3252
|
if (options.skipInstall) {
|
|
2284
3253
|
return { status: "skipped" };
|
|
2285
3254
|
}
|
|
@@ -2307,8 +3276,8 @@ async function ensureFreshSqueezyDevDependency(options = {}) {
|
|
|
2307
3276
|
throw new Error(`${command.join(" ")} failed with exit code ${code}`);
|
|
2308
3277
|
}
|
|
2309
3278
|
return { status: "installed", projectDir, packageJsonPath, packageManager, command };
|
|
2310
|
-
}
|
|
2311
|
-
async
|
|
3279
|
+
};
|
|
3280
|
+
var findPackageJson = async (cwd) => {
|
|
2312
3281
|
let current = path3.resolve(cwd);
|
|
2313
3282
|
while (true) {
|
|
2314
3283
|
const candidate = path3.join(current, "package.json");
|
|
@@ -2317,34 +3286,34 @@ async function findPackageJson(cwd) {
|
|
|
2317
3286
|
if (parent === current) return void 0;
|
|
2318
3287
|
current = parent;
|
|
2319
3288
|
}
|
|
2320
|
-
}
|
|
2321
|
-
async
|
|
3289
|
+
};
|
|
3290
|
+
var readPackageJson = async (packageJsonPath) => {
|
|
2322
3291
|
const raw = await fs2.readFile(packageJsonPath, "utf8");
|
|
2323
3292
|
return JSON.parse(raw);
|
|
2324
|
-
}
|
|
2325
|
-
async
|
|
3293
|
+
};
|
|
3294
|
+
var detectPackageManager = async (projectDir) => {
|
|
2326
3295
|
if (await pathExists(path3.join(projectDir, "pnpm-lock.yaml"))) return "pnpm";
|
|
2327
3296
|
if (await pathExists(path3.join(projectDir, "yarn.lock"))) return "yarn";
|
|
2328
3297
|
if (await pathExists(path3.join(projectDir, "bun.lock")) || await pathExists(path3.join(projectDir, "bun.lockb"))) {
|
|
2329
3298
|
return "bun";
|
|
2330
3299
|
}
|
|
2331
3300
|
return "npm";
|
|
2332
|
-
}
|
|
2333
|
-
|
|
3301
|
+
};
|
|
3302
|
+
var hasFreshSqueezy = (manifest) => {
|
|
2334
3303
|
return [
|
|
2335
3304
|
manifest.dependencies,
|
|
2336
3305
|
manifest.devDependencies,
|
|
2337
3306
|
manifest.optionalDependencies,
|
|
2338
3307
|
manifest.peerDependencies
|
|
2339
3308
|
].some((section) => section?.[PACKAGE_NAME] !== void 0);
|
|
2340
|
-
}
|
|
2341
|
-
|
|
3309
|
+
};
|
|
3310
|
+
var buildInstallCommand = (packageManager, packageSpec) => {
|
|
2342
3311
|
if (packageManager === "pnpm") return ["pnpm", "add", "-D", packageSpec];
|
|
2343
3312
|
if (packageManager === "yarn") return ["yarn", "add", "-D", packageSpec];
|
|
2344
3313
|
if (packageManager === "bun") return ["bun", "add", "-d", packageSpec];
|
|
2345
3314
|
return ["npm", "install", "--save-dev", packageSpec];
|
|
2346
|
-
}
|
|
2347
|
-
|
|
3315
|
+
};
|
|
3316
|
+
var runPackageCommand = (command, args, options) => {
|
|
2348
3317
|
return new Promise((resolve2, reject) => {
|
|
2349
3318
|
const child = spawn(command, args, {
|
|
2350
3319
|
cwd: options.cwd,
|
|
@@ -2354,18 +3323,18 @@ function runPackageCommand(command, args, options) {
|
|
|
2354
3323
|
child.on("error", reject);
|
|
2355
3324
|
child.on("close", (code) => resolve2(code ?? 1));
|
|
2356
3325
|
});
|
|
2357
|
-
}
|
|
2358
|
-
async
|
|
3326
|
+
};
|
|
3327
|
+
var pathExists = async (filePath) => {
|
|
2359
3328
|
try {
|
|
2360
3329
|
await fs2.access(filePath);
|
|
2361
3330
|
return true;
|
|
2362
3331
|
} catch {
|
|
2363
3332
|
return false;
|
|
2364
3333
|
}
|
|
2365
|
-
}
|
|
3334
|
+
};
|
|
2366
3335
|
|
|
2367
3336
|
// src/cli/commands/launcher.ts
|
|
2368
|
-
async
|
|
3337
|
+
var runLauncherCommand = async (options) => {
|
|
2369
3338
|
if (!options.isInteractive) return 2;
|
|
2370
3339
|
try {
|
|
2371
3340
|
process.stdout.write(
|
|
@@ -2396,8 +3365,8 @@ async function runLauncherCommand(options) {
|
|
|
2396
3365
|
process.stderr.write(renderCommandExamples());
|
|
2397
3366
|
return 1;
|
|
2398
3367
|
}
|
|
2399
|
-
}
|
|
2400
|
-
async
|
|
3368
|
+
};
|
|
3369
|
+
var routeLauncherAction = async (action) => {
|
|
2401
3370
|
switch (action) {
|
|
2402
3371
|
case "init":
|
|
2403
3372
|
return startGuidedSetup();
|
|
@@ -2409,14 +3378,14 @@ async function routeLauncherAction(action) {
|
|
|
2409
3378
|
case "exit":
|
|
2410
3379
|
return 0;
|
|
2411
3380
|
}
|
|
2412
|
-
}
|
|
2413
|
-
|
|
3381
|
+
};
|
|
3382
|
+
var startGuidedSetup = () => {
|
|
2414
3383
|
process.stdout.write(
|
|
2415
3384
|
renderStep(2, 2, "Guided setup", "detect credentials, stores, and resources")
|
|
2416
3385
|
);
|
|
2417
3386
|
return runInitCommand({ isInteractive: true });
|
|
2418
|
-
}
|
|
2419
|
-
|
|
3387
|
+
};
|
|
3388
|
+
var renderProjectInstallResult = (result) => {
|
|
2420
3389
|
if (result.status === "installed") {
|
|
2421
3390
|
return renderDetected(
|
|
2422
3391
|
"Dev dependency",
|
|
@@ -2434,10 +3403,150 @@ function renderProjectInstallResult(result) {
|
|
|
2434
3403
|
return chalk4.dim(" Skipped dev dependency install (--no-install).\n");
|
|
2435
3404
|
}
|
|
2436
3405
|
return chalk4.yellow(" No package.json found; running without installing a dev dependency.\n");
|
|
2437
|
-
}
|
|
3406
|
+
};
|
|
3407
|
+
|
|
3408
|
+
// src/cli/commands/resourceOps.ts
|
|
3409
|
+
import { readFileSync } from "fs";
|
|
3410
|
+
var runResourceOpCommand = async (options) => {
|
|
3411
|
+
if (options.listCatalog) {
|
|
3412
|
+
writeCatalog(options.json ?? false);
|
|
3413
|
+
return 0;
|
|
3414
|
+
}
|
|
3415
|
+
const spec = findResourceVerb(options.resource, options.verb);
|
|
3416
|
+
if (!spec) {
|
|
3417
|
+
process.stderr.write(
|
|
3418
|
+
renderCliError(`Unknown or unsupported op: ${options.verb} ${options.resource}`, [
|
|
3419
|
+
"fresh-squeezy ops --list",
|
|
3420
|
+
"fresh-squeezy get product --id 1",
|
|
3421
|
+
"fresh-squeezy list webhook --store-ids 1"
|
|
3422
|
+
])
|
|
3423
|
+
);
|
|
3424
|
+
return 2;
|
|
3425
|
+
}
|
|
3426
|
+
try {
|
|
3427
|
+
const body = readBody(options);
|
|
3428
|
+
if (spec.body === "required" && body === void 0) {
|
|
3429
|
+
throw new FreshSqueezyError({
|
|
3430
|
+
code: "MISSING_ARG",
|
|
3431
|
+
message: "This op requires a JSON body (--body, --body-file, or stdin)."
|
|
3432
|
+
});
|
|
3433
|
+
}
|
|
3434
|
+
const client = createFreshSqueezy({ mode: options.mode });
|
|
3435
|
+
const allowed = await assertWriteSafety(spec, client.mode, options);
|
|
3436
|
+
if (!allowed) return 2;
|
|
3437
|
+
const config = resolveConfig({ mode: options.mode });
|
|
3438
|
+
const http = new HttpClient(config);
|
|
3439
|
+
const data = await invokeOp(http, options.resource, options.verb, {
|
|
3440
|
+
id: options.id,
|
|
3441
|
+
storeId: options.storeIds?.[0],
|
|
3442
|
+
parentId: options.parentId,
|
|
3443
|
+
body
|
|
3444
|
+
});
|
|
3445
|
+
const payload = {
|
|
3446
|
+
ok: true,
|
|
3447
|
+
mode: client.mode,
|
|
3448
|
+
resource: spec.resource,
|
|
3449
|
+
verb: spec.verb,
|
|
3450
|
+
docs: `https://docs.lemonsqueezy.com/api/${spec.docsPath}`,
|
|
3451
|
+
data: data ?? null
|
|
3452
|
+
};
|
|
3453
|
+
if (options.json) {
|
|
3454
|
+
process.stdout.write(`${JSON.stringify(payload, null, 2)}
|
|
3455
|
+
`);
|
|
3456
|
+
} else {
|
|
3457
|
+
process.stdout.write(
|
|
3458
|
+
`${spec.verb} ${spec.resource} \u2014 ok (mode=${client.mode})
|
|
3459
|
+
${JSON.stringify(data ?? null, null, 2)}
|
|
3460
|
+
`
|
|
3461
|
+
);
|
|
3462
|
+
}
|
|
3463
|
+
return 0;
|
|
3464
|
+
} catch (err) {
|
|
3465
|
+
writeFatal2(err, options.json ?? false);
|
|
3466
|
+
return 2;
|
|
3467
|
+
}
|
|
3468
|
+
};
|
|
3469
|
+
var writeCatalog = (asJson) => {
|
|
3470
|
+
if (asJson) {
|
|
3471
|
+
process.stdout.write(
|
|
3472
|
+
`${JSON.stringify(
|
|
3473
|
+
{
|
|
3474
|
+
resources: listRegisteredResources(),
|
|
3475
|
+
ops: resourceRegistry
|
|
3476
|
+
},
|
|
3477
|
+
null,
|
|
3478
|
+
2
|
|
3479
|
+
)}
|
|
3480
|
+
`
|
|
3481
|
+
);
|
|
3482
|
+
return;
|
|
3483
|
+
}
|
|
3484
|
+
process.stdout.write("Docs-backed ops (Lemon Squeezy official API only):\n\n");
|
|
3485
|
+
for (const entry of resourceRegistry) {
|
|
3486
|
+
const flags = [
|
|
3487
|
+
entry.destructive ? "destructive" : void 0,
|
|
3488
|
+
entry.body && entry.body !== "none" ? `body=${entry.body}` : void 0
|
|
3489
|
+
].filter(Boolean).join(", ");
|
|
3490
|
+
process.stdout.write(
|
|
3491
|
+
` ${entry.verb.padEnd(18)} ${entry.resource.padEnd(22)} ${entry.docsPath}${flags ? ` (${flags})` : ""}
|
|
3492
|
+
`
|
|
3493
|
+
);
|
|
3494
|
+
}
|
|
3495
|
+
process.stdout.write(
|
|
3496
|
+
"\nCatalog resources (product, variant, price, file, store, \u2026) are read-only in the API.\n"
|
|
3497
|
+
);
|
|
3498
|
+
};
|
|
3499
|
+
var assertWriteSafety = async (spec, mode, options) => {
|
|
3500
|
+
const isWrite = spec.verb !== "get" && spec.verb !== "list" && spec.verb !== "current-usage";
|
|
3501
|
+
if (!isWrite) return true;
|
|
3502
|
+
const needsGate = Boolean(spec.destructive) || mode === "live";
|
|
3503
|
+
if (!needsGate) return true;
|
|
3504
|
+
if (options.yes) return true;
|
|
3505
|
+
if (options.isInteractive) {
|
|
3506
|
+
return confirmResourceOp(
|
|
3507
|
+
mode === "live" ? `LIVE mode: allow ${spec.verb} ${spec.resource}?` : `Confirm ${spec.verb} ${spec.resource}?`
|
|
3508
|
+
);
|
|
3509
|
+
}
|
|
3510
|
+
process.stderr.write(
|
|
3511
|
+
renderCliError(
|
|
3512
|
+
`${spec.verb} ${spec.resource} requires --yes in non-interactive ${mode} mode${spec.destructive ? " (destructive op)" : ""}`,
|
|
3513
|
+
[
|
|
3514
|
+
`fresh-squeezy ${spec.verb} ${spec.resource} --yes \u2026`,
|
|
3515
|
+
"Use test mode for safer experimentation: --mode test"
|
|
3516
|
+
]
|
|
3517
|
+
)
|
|
3518
|
+
);
|
|
3519
|
+
return false;
|
|
3520
|
+
};
|
|
3521
|
+
var readBody = (options) => {
|
|
3522
|
+
if (options.bodyFile) {
|
|
3523
|
+
const text = readFileSync(options.bodyFile, "utf8");
|
|
3524
|
+
return JSON.parse(text);
|
|
3525
|
+
}
|
|
3526
|
+
if (options.body !== void 0) {
|
|
3527
|
+
return JSON.parse(options.body);
|
|
3528
|
+
}
|
|
3529
|
+
if (!process.stdin.isTTY && !options.isInteractive) {
|
|
3530
|
+
}
|
|
3531
|
+
return void 0;
|
|
3532
|
+
};
|
|
3533
|
+
var writeFatal2 = (err, json) => {
|
|
3534
|
+
if (json) {
|
|
3535
|
+
const code = err instanceof FreshSqueezyError ? err.code : "FATAL";
|
|
3536
|
+
const message2 = err instanceof Error ? err.message : String(err);
|
|
3537
|
+
const status = err instanceof FreshSqueezyError ? err.status : void 0;
|
|
3538
|
+
process.stderr.write(
|
|
3539
|
+
`${JSON.stringify({ ok: false, error: { code, message: message2, status } }, null, 2)}
|
|
3540
|
+
`
|
|
3541
|
+
);
|
|
3542
|
+
return;
|
|
3543
|
+
}
|
|
3544
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3545
|
+
process.stderr.write(renderCliError(message, ["fresh-squeezy ops --list"]));
|
|
3546
|
+
};
|
|
2438
3547
|
|
|
2439
3548
|
// src/cli/commands/validate.ts
|
|
2440
|
-
async
|
|
3549
|
+
var runValidateCommand = async (target, options) => {
|
|
2441
3550
|
try {
|
|
2442
3551
|
const client = createFreshSqueezy({ mode: options.mode });
|
|
2443
3552
|
if (target === "connection") {
|
|
@@ -2473,8 +3582,8 @@ async function runValidateCommand(target, options) {
|
|
|
2473
3582
|
process.stderr.write(renderCliError(message, getValidateHints(err, target)));
|
|
2474
3583
|
return 2;
|
|
2475
3584
|
}
|
|
2476
|
-
}
|
|
2477
|
-
async
|
|
3585
|
+
};
|
|
3586
|
+
var resolveStoresForTarget = async (client, target, options) => {
|
|
2478
3587
|
const resolved = await resolveStores(client, {
|
|
2479
3588
|
storeIds: options.storeIds,
|
|
2480
3589
|
allStores: options.allStores,
|
|
@@ -2487,8 +3596,8 @@ async function resolveStoresForTarget(client, target, options) {
|
|
|
2487
3596
|
});
|
|
2488
3597
|
}
|
|
2489
3598
|
return resolved.storeIds;
|
|
2490
|
-
}
|
|
2491
|
-
async
|
|
3599
|
+
};
|
|
3600
|
+
var runPerStore = async (client, target, storeIds, options) => {
|
|
2492
3601
|
if (target === "store") {
|
|
2493
3602
|
return Promise.all(storeIds.map((id) => client.validateStore(id)));
|
|
2494
3603
|
}
|
|
@@ -2497,16 +3606,16 @@ async function runPerStore(client, target, storeIds, options) {
|
|
|
2497
3606
|
return Promise.all(storeIds.map((storeId) => client.validateWebhook({ storeId, url })));
|
|
2498
3607
|
}
|
|
2499
3608
|
return [];
|
|
2500
|
-
}
|
|
2501
|
-
async
|
|
3609
|
+
};
|
|
3610
|
+
var runProduct = async (client, options) => {
|
|
2502
3611
|
const productId = required2(options.productId, "--product-id is required for `validate product`.");
|
|
2503
3612
|
const expected = options.storeIds?.[0];
|
|
2504
3613
|
return client.validateProduct({
|
|
2505
3614
|
productId,
|
|
2506
3615
|
expectedStoreId: expected
|
|
2507
3616
|
});
|
|
2508
|
-
}
|
|
2509
|
-
async
|
|
3617
|
+
};
|
|
3618
|
+
var runDiscount = async (client, options) => {
|
|
2510
3619
|
const discountId = required2(
|
|
2511
3620
|
options.discountId,
|
|
2512
3621
|
"--discount-id is required for `validate discount`."
|
|
@@ -2516,8 +3625,8 @@ async function runDiscount(client, options) {
|
|
|
2516
3625
|
"--store-ids is required for `validate discount`."
|
|
2517
3626
|
);
|
|
2518
3627
|
return client.validateDiscount({ storeId, discountId });
|
|
2519
|
-
}
|
|
2520
|
-
async
|
|
3628
|
+
};
|
|
3629
|
+
var runLicenseKey = async (client, options) => {
|
|
2521
3630
|
const licenseKeyId = required2(
|
|
2522
3631
|
options.licenseKeyId,
|
|
2523
3632
|
"--license-key-id is required for `validate license-key`."
|
|
@@ -2527,8 +3636,8 @@ async function runLicenseKey(client, options) {
|
|
|
2527
3636
|
"--store-ids is required for `validate license-key`."
|
|
2528
3637
|
);
|
|
2529
3638
|
return client.validateLicenseKey({ storeId, licenseKeyId });
|
|
2530
|
-
}
|
|
2531
|
-
async
|
|
3639
|
+
};
|
|
3640
|
+
var runSubscriptionPlan = async (client, options) => {
|
|
2532
3641
|
const variantId = required2(
|
|
2533
3642
|
options.variantId,
|
|
2534
3643
|
"--variant-id is required for `validate subscription-plan`."
|
|
@@ -2538,8 +3647,8 @@ async function runSubscriptionPlan(client, options) {
|
|
|
2538
3647
|
"--store-ids is required for `validate subscription-plan`."
|
|
2539
3648
|
);
|
|
2540
3649
|
return client.validateSubscriptionPlan({ storeId, variantId });
|
|
2541
|
-
}
|
|
2542
|
-
|
|
3650
|
+
};
|
|
3651
|
+
var emit = (result, options) => {
|
|
2543
3652
|
if (options.json) {
|
|
2544
3653
|
process.stdout.write(`${JSON.stringify(result, null, 2)}
|
|
2545
3654
|
`);
|
|
@@ -2548,29 +3657,79 @@ function emit(result, options) {
|
|
|
2548
3657
|
`);
|
|
2549
3658
|
}
|
|
2550
3659
|
return result.ok ? 0 : 1;
|
|
2551
|
-
}
|
|
2552
|
-
|
|
3660
|
+
};
|
|
3661
|
+
var required2 = (value, message) => {
|
|
2553
3662
|
if (value === void 0 || value === null || value === "") {
|
|
2554
3663
|
throw new FreshSqueezyError({ code: "MISSING_ARG", message });
|
|
2555
3664
|
}
|
|
2556
3665
|
return value;
|
|
2557
|
-
}
|
|
3666
|
+
};
|
|
2558
3667
|
|
|
2559
3668
|
// src/cli/main.ts
|
|
2560
3669
|
dotenv.config();
|
|
3670
|
+
var parseMode = (value) => {
|
|
3671
|
+
if (value === "test" || value === "live") return value;
|
|
3672
|
+
throw new Error(`Mode must be "test" or "live", got "${value}"`);
|
|
3673
|
+
};
|
|
3674
|
+
var parseCsv = (value) => {
|
|
3675
|
+
return value.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
3676
|
+
};
|
|
3677
|
+
var readPackageVersion = () => {
|
|
3678
|
+
const candidates = [
|
|
3679
|
+
new URL("../package.json", import.meta.url),
|
|
3680
|
+
new URL("../../package.json", import.meta.url)
|
|
3681
|
+
];
|
|
3682
|
+
for (const candidate of candidates) {
|
|
3683
|
+
try {
|
|
3684
|
+
const payload = JSON.parse(readFileSync2(candidate, "utf8"));
|
|
3685
|
+
if (typeof payload.version === "string") return payload.version;
|
|
3686
|
+
} catch {
|
|
3687
|
+
}
|
|
3688
|
+
}
|
|
3689
|
+
return "0.0.0";
|
|
3690
|
+
};
|
|
2561
3691
|
var isInteractive = Boolean(process.stdin.isTTY);
|
|
2562
3692
|
var packageVersion = readPackageVersion();
|
|
3693
|
+
var runValidate = async (target, opts) => {
|
|
3694
|
+
const code = await runValidateCommand(target, {
|
|
3695
|
+
mode: opts.mode,
|
|
3696
|
+
storeIds: opts.storeIds,
|
|
3697
|
+
allStores: Boolean(opts.allStores),
|
|
3698
|
+
productId: opts.productId,
|
|
3699
|
+
webhookUrl: opts.webhookUrl,
|
|
3700
|
+
discountId: opts.discountId,
|
|
3701
|
+
licenseKeyId: opts.licenseKeyId,
|
|
3702
|
+
variantId: opts.variantId,
|
|
3703
|
+
json: Boolean(opts.json),
|
|
3704
|
+
isInteractive
|
|
3705
|
+
});
|
|
3706
|
+
process.exit(code);
|
|
3707
|
+
};
|
|
2563
3708
|
var program = new Command();
|
|
2564
|
-
program.name("fresh-squeezy").description(
|
|
3709
|
+
program.name("fresh-squeezy").description(
|
|
3710
|
+
"Dual-mode Lemon Squeezy CLI: doctor/validate pre-flight + docs-backed resource ops (get/list/create/\u2026)"
|
|
3711
|
+
).version(packageVersion).option("--no-install", "Skip adding fresh-squeezy to devDependencies before guided setup").showSuggestionAfterError().showHelpAfterError("\nRun `fresh-squeezy --help` for examples.");
|
|
2565
3712
|
program.addHelpText(
|
|
2566
3713
|
"after",
|
|
2567
3714
|
`
|
|
2568
|
-
Start:
|
|
3715
|
+
Start (doctor setup):
|
|
2569
3716
|
fresh-squeezy add as a dev dependency, then run guided setup
|
|
2570
3717
|
fresh-squeezy --no-install run guided setup without editing package.json
|
|
2571
3718
|
fresh-squeezy doctor --all-stores --all-resources
|
|
2572
3719
|
fresh-squeezy validate webhook --store-ids 12 --webhook-url https://app.example.com/api/webhooks/lemon-squeezy
|
|
2573
3720
|
|
|
3721
|
+
Ops (docs-backed Lemon Squeezy API only \u2014 products/variants are read-only):
|
|
3722
|
+
fresh-squeezy ops --list
|
|
3723
|
+
fresh-squeezy get product --id 42 --json
|
|
3724
|
+
fresh-squeezy list webhook --store-ids 12
|
|
3725
|
+
fresh-squeezy create webhook --body-file webhook.json --yes
|
|
3726
|
+
fresh-squeezy cancel subscription --id 9 --yes
|
|
3727
|
+
fresh-squeezy refund order --id 100 --yes
|
|
3728
|
+
fresh-squeezy generate-invoice order --id 100 --yes
|
|
3729
|
+
|
|
3730
|
+
Safety: delete/cancel/refund always need --yes (or TTY confirm); live-mode writes need --yes too.
|
|
3731
|
+
Bodies are JSON:API documents via --body or --body-file (not flat flags).
|
|
3732
|
+
|
|
2574
3733
|
Store selection:
|
|
2575
3734
|
Use --store-ids 12,34 for explicit stores, --all-stores for automation, or run in a TTY to pick stores interactively.
|
|
2576
3735
|
`
|
|
@@ -2659,46 +3818,55 @@ types.command("augment").description(
|
|
|
2659
3818
|
const code = await runAugmentCommand({ out: opts.out, force: Boolean(opts.force) });
|
|
2660
3819
|
process.exit(code);
|
|
2661
3820
|
});
|
|
3821
|
+
program.command("ops").description("List docs-backed resource ops (Lemon Squeezy official API matrix)").option("--list", "Print the full verb matrix", true).option("--json", "Emit machine-readable JSON").action(async (opts) => {
|
|
3822
|
+
const code = await runResourceOpCommand({
|
|
3823
|
+
resource: "",
|
|
3824
|
+
verb: "get",
|
|
3825
|
+
listCatalog: true,
|
|
3826
|
+
json: Boolean(opts.json)
|
|
3827
|
+
});
|
|
3828
|
+
process.exit(code);
|
|
3829
|
+
});
|
|
3830
|
+
var OP_VERBS = [
|
|
3831
|
+
"get",
|
|
3832
|
+
"list",
|
|
3833
|
+
"create",
|
|
3834
|
+
"update",
|
|
3835
|
+
"delete",
|
|
3836
|
+
"cancel",
|
|
3837
|
+
"refund",
|
|
3838
|
+
"generate-invoice",
|
|
3839
|
+
"current-usage"
|
|
3840
|
+
];
|
|
3841
|
+
for (const verb of OP_VERBS) {
|
|
3842
|
+
program.command(`${verb} <resource>`).description(`Docs-backed ${verb} for a Lemon Squeezy resource`).option("-m, --mode <mode>", "test or live", parseMode).option("--id <id>", "Resource id").option(
|
|
3843
|
+
"--store-ids <ids>",
|
|
3844
|
+
"Comma-separated store IDs (first used for list filters)",
|
|
3845
|
+
parseCsv
|
|
3846
|
+
).option(
|
|
3847
|
+
"--parent-id <id>",
|
|
3848
|
+
"Parent resource id for nested lists (product, order, subscription, \u2026)"
|
|
3849
|
+
).option("--body <json>", "JSON:API body string").option("--body-file <path>", "Path to JSON:API body file").option("--yes", "Skip confirm; required for live writes and destructive ops when non-TTY").option("--json", "Emit machine-readable JSON").action(async (resource, opts) => {
|
|
3850
|
+
const code = await runResourceOpCommand({
|
|
3851
|
+
verb,
|
|
3852
|
+
resource,
|
|
3853
|
+
mode: opts.mode,
|
|
3854
|
+
id: opts.id,
|
|
3855
|
+
storeIds: opts.storeIds,
|
|
3856
|
+
parentId: opts.parentId,
|
|
3857
|
+
body: opts.body,
|
|
3858
|
+
bodyFile: opts.bodyFile,
|
|
3859
|
+
yes: Boolean(opts.yes),
|
|
3860
|
+
json: Boolean(opts.json),
|
|
3861
|
+
isInteractive
|
|
3862
|
+
});
|
|
3863
|
+
process.exit(code);
|
|
3864
|
+
});
|
|
3865
|
+
}
|
|
2662
3866
|
program.parseAsync(process.argv).catch((err) => {
|
|
2663
3867
|
const message = err instanceof Error ? err.message : String(err);
|
|
2664
3868
|
const hints = message.includes("Mode must be") ? ["fresh-squeezy doctor --mode test", "fresh-squeezy doctor --mode live"] : ["fresh-squeezy --help"];
|
|
2665
3869
|
process.stderr.write(renderCliError(message, hints));
|
|
2666
3870
|
process.exit(2);
|
|
2667
3871
|
});
|
|
2668
|
-
function parseMode(value) {
|
|
2669
|
-
if (value === "test" || value === "live") return value;
|
|
2670
|
-
throw new Error(`Mode must be "test" or "live", got "${value}"`);
|
|
2671
|
-
}
|
|
2672
|
-
function parseCsv(value) {
|
|
2673
|
-
return value.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
2674
|
-
}
|
|
2675
|
-
function readPackageVersion() {
|
|
2676
|
-
const candidates = [
|
|
2677
|
-
new URL("../package.json", import.meta.url),
|
|
2678
|
-
new URL("../../package.json", import.meta.url)
|
|
2679
|
-
];
|
|
2680
|
-
for (const candidate of candidates) {
|
|
2681
|
-
try {
|
|
2682
|
-
const payload = JSON.parse(readFileSync(candidate, "utf8"));
|
|
2683
|
-
if (typeof payload.version === "string") return payload.version;
|
|
2684
|
-
} catch {
|
|
2685
|
-
}
|
|
2686
|
-
}
|
|
2687
|
-
return "0.0.0";
|
|
2688
|
-
}
|
|
2689
|
-
async function runValidate(target, opts) {
|
|
2690
|
-
const code = await runValidateCommand(target, {
|
|
2691
|
-
mode: opts.mode,
|
|
2692
|
-
storeIds: opts.storeIds,
|
|
2693
|
-
allStores: Boolean(opts.allStores),
|
|
2694
|
-
productId: opts.productId,
|
|
2695
|
-
webhookUrl: opts.webhookUrl,
|
|
2696
|
-
discountId: opts.discountId,
|
|
2697
|
-
licenseKeyId: opts.licenseKeyId,
|
|
2698
|
-
variantId: opts.variantId,
|
|
2699
|
-
json: Boolean(opts.json),
|
|
2700
|
-
isInteractive
|
|
2701
|
-
});
|
|
2702
|
-
process.exit(code);
|
|
2703
|
-
}
|
|
2704
3872
|
//# sourceMappingURL=cli.js.map
|