@saasicat/ui-vue 0.26.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +90 -201
- package/README.md +23 -0
- package/dist/{catalog-Dch1Ryw0.d.cts → catalog-Dv2twuNi.d.cts} +205 -4
- package/dist/{catalog-Dch1Ryw0.d.ts → catalog-Dv2twuNi.d.ts} +205 -4
- package/dist/{chunk-BPF2BMCQ.js → chunk-4IZWT4UY.js} +414 -2
- package/dist/{chunk-O3J3ITF2.js → chunk-LK6YJDXC.js} +1 -1
- package/dist/{chunk-NEXTZZRQ.js → chunk-NRVF3JJJ.js} +2 -2
- package/dist/client/index.cjs +426 -5
- package/dist/client/index.d.cts +70 -4
- package/dist/client/index.d.ts +70 -4
- package/dist/client/index.js +22 -4
- package/dist/index.cjs +429 -8
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +23 -5
- package/dist/quasar/index.cjs +411 -2
- package/dist/quasar/index.d.cts +2 -2
- package/dist/quasar/index.d.ts +2 -2
- package/dist/quasar/index.js +2 -2
- package/dist/{resource-registry-D7Xjs-5f.d.cts → resource-registry-BxFpnzHY.d.cts} +1 -1
- package/dist/{resource-registry-TaR7rtq0.d.ts → resource-registry-Cn1Gy2LE.d.ts} +1 -1
- package/package.json +5 -4
- package/src/client/admin-error.ts +18 -1
- package/src/client/attach-cause.ts +21 -0
- package/src/client/nav-builder.ts +3 -1
- package/src/client/resources/bundles.resource.ts +145 -0
- package/src/client/resources/catalog.resource.ts +160 -0
- package/src/client/resources/discovery.resource.ts +108 -0
- package/src/client/resources/index.ts +52 -14
- package/src/client/resources/marketing.resource.ts +121 -0
- package/src/client/resources/promo-codes.resource.ts +63 -0
- package/src/client/resources/promotions.resource.ts +44 -0
- package/src/client/resources/subscriptions.resource.ts +19 -0
- package/src/client/resources/tenants.resource.ts +35 -9
- package/src/client/resources/users.resource.ts +31 -0
- package/src/pages-standard/SuperAdminSetupWizard.vue +7 -4
package/dist/index.js
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
resolveLoginBranding,
|
|
28
28
|
resolvePlans,
|
|
29
29
|
todayIsoDate
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-NRVF3JJJ.js";
|
|
31
31
|
import {
|
|
32
32
|
SA_COLOR_SCHEMES,
|
|
33
33
|
SA_LOCALE_STORAGE_KEY,
|
|
@@ -55,7 +55,7 @@ import {
|
|
|
55
55
|
useSaMessages,
|
|
56
56
|
useSaTheme,
|
|
57
57
|
useSuperAdminI18n
|
|
58
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-LK6YJDXC.js";
|
|
59
59
|
import {
|
|
60
60
|
AdminError,
|
|
61
61
|
BootLoadError,
|
|
@@ -75,6 +75,9 @@ import {
|
|
|
75
75
|
adminErrorMessage,
|
|
76
76
|
auditResource,
|
|
77
77
|
bindResource,
|
|
78
|
+
bundleVersionsResource,
|
|
79
|
+
bundlesResource,
|
|
80
|
+
catalogResource,
|
|
78
81
|
clampListPage,
|
|
79
82
|
clampListPageSize,
|
|
80
83
|
createFetchHttpClient,
|
|
@@ -84,6 +87,7 @@ import {
|
|
|
84
87
|
defineListOp,
|
|
85
88
|
defineMessages,
|
|
86
89
|
defineResource,
|
|
90
|
+
discoveryResource,
|
|
87
91
|
filterQueryString,
|
|
88
92
|
formatCurrency,
|
|
89
93
|
formatMessage,
|
|
@@ -99,11 +103,14 @@ import {
|
|
|
99
103
|
markEmptyResponse,
|
|
100
104
|
markPlatformError,
|
|
101
105
|
markTransportFailure,
|
|
106
|
+
marketingResource,
|
|
102
107
|
mergeMessages,
|
|
103
108
|
planVersionsResource,
|
|
104
109
|
plansResource,
|
|
105
110
|
platformResources,
|
|
106
111
|
postJson,
|
|
112
|
+
promoCodesResource,
|
|
113
|
+
promotionsResource,
|
|
107
114
|
readErrorCode,
|
|
108
115
|
readErrorDetail,
|
|
109
116
|
readListPage,
|
|
@@ -111,10 +118,12 @@ import {
|
|
|
111
118
|
requestJsonBody,
|
|
112
119
|
requireServerAnswer,
|
|
113
120
|
resolveMessages,
|
|
121
|
+
subscriptionsResource,
|
|
114
122
|
tenantsResource,
|
|
115
123
|
toAdminError,
|
|
116
|
-
trimTrailingSlashes
|
|
117
|
-
|
|
124
|
+
trimTrailingSlashes,
|
|
125
|
+
usersResource
|
|
126
|
+
} from "./chunk-4IZWT4UY.js";
|
|
118
127
|
|
|
119
128
|
// src/vue/use-super-admin-context.ts
|
|
120
129
|
import { inject } from "vue";
|
|
@@ -3232,6 +3241,9 @@ export {
|
|
|
3232
3241
|
buildQuotaRegistry,
|
|
3233
3242
|
buildRoutes,
|
|
3234
3243
|
buildSidebar,
|
|
3244
|
+
bundleVersionsResource,
|
|
3245
|
+
bundlesResource,
|
|
3246
|
+
catalogResource,
|
|
3235
3247
|
clampListPage,
|
|
3236
3248
|
clampListPageSize,
|
|
3237
3249
|
countPlans,
|
|
@@ -3255,6 +3267,7 @@ export {
|
|
|
3255
3267
|
defineListOp,
|
|
3256
3268
|
defineMessages,
|
|
3257
3269
|
defineResource,
|
|
3270
|
+
discoveryResource,
|
|
3258
3271
|
filterQueryString,
|
|
3259
3272
|
formatCurrency,
|
|
3260
3273
|
formatMessage,
|
|
@@ -3277,12 +3290,15 @@ export {
|
|
|
3277
3290
|
markEmptyResponse,
|
|
3278
3291
|
markPlatformError,
|
|
3279
3292
|
markTransportFailure,
|
|
3293
|
+
marketingResource,
|
|
3280
3294
|
mergeMessages,
|
|
3281
3295
|
planChangeWizardI18n,
|
|
3282
3296
|
planVersionsResource,
|
|
3283
3297
|
plansResource,
|
|
3284
3298
|
platformResources,
|
|
3285
3299
|
postJson,
|
|
3300
|
+
promoCodesResource,
|
|
3301
|
+
promotionsResource,
|
|
3286
3302
|
provideEntitlement,
|
|
3287
3303
|
readErrorCode,
|
|
3288
3304
|
readErrorDetail,
|
|
@@ -3295,6 +3311,7 @@ export {
|
|
|
3295
3311
|
resolveMessages,
|
|
3296
3312
|
resolvePlans,
|
|
3297
3313
|
resolveSuperAdminEndpoints,
|
|
3314
|
+
subscriptionsResource,
|
|
3298
3315
|
tenantsResource,
|
|
3299
3316
|
toAdminError,
|
|
3300
3317
|
todayIsoDate,
|
|
@@ -3342,5 +3359,6 @@ export {
|
|
|
3342
3359
|
useTenantBillingCatalog,
|
|
3343
3360
|
useTenantManifest,
|
|
3344
3361
|
useTenantSubscriptionBundles,
|
|
3345
|
-
useTenants
|
|
3362
|
+
useTenants,
|
|
3363
|
+
usersResource
|
|
3346
3364
|
};
|
package/dist/quasar/index.cjs
CHANGED
|
@@ -38,6 +38,16 @@ var import_quasar4 = require("quasar");
|
|
|
38
38
|
var import_pinia = require("pinia");
|
|
39
39
|
var import_vue_router = require("vue-router");
|
|
40
40
|
|
|
41
|
+
// src/client/attach-cause.ts
|
|
42
|
+
function attachCause(error, cause) {
|
|
43
|
+
Object.defineProperty(error, "cause", {
|
|
44
|
+
value: cause,
|
|
45
|
+
configurable: true,
|
|
46
|
+
writable: true
|
|
47
|
+
});
|
|
48
|
+
return error;
|
|
49
|
+
}
|
|
50
|
+
|
|
41
51
|
// src/client/i18n/format.ts
|
|
42
52
|
var import_types = require("@saasicat/types");
|
|
43
53
|
|
|
@@ -86,7 +96,8 @@ var AdminError = class extends Error {
|
|
|
86
96
|
/** The request never reached the server. See `AdminErrorInit`. */
|
|
87
97
|
transportFailure;
|
|
88
98
|
constructor(init = {}) {
|
|
89
|
-
super(init.message ?? describe(init)
|
|
99
|
+
super(init.message ?? describe(init));
|
|
100
|
+
if (init.cause !== void 0) attachCause(this, init.cause);
|
|
90
101
|
this.name = "AdminError";
|
|
91
102
|
this.status = init.status ?? 0;
|
|
92
103
|
this.code = init.code;
|
|
@@ -375,6 +386,12 @@ function appendFilter(params, filter) {
|
|
|
375
386
|
params.set(key, String(value));
|
|
376
387
|
}
|
|
377
388
|
}
|
|
389
|
+
function filterQueryString(filter) {
|
|
390
|
+
const params = new URLSearchParams();
|
|
391
|
+
appendFilter(params, filter);
|
|
392
|
+
const query = params.toString();
|
|
393
|
+
return query ? `?${query}` : "";
|
|
394
|
+
}
|
|
378
395
|
function listUrl(endpoint, query = {}) {
|
|
379
396
|
const params = new URLSearchParams();
|
|
380
397
|
params.set("page", String(query.page ?? LIST_FIRST_PAGE));
|
|
@@ -487,9 +504,392 @@ var planVersionsResource = defineResource("planVersions", {
|
|
|
487
504
|
)
|
|
488
505
|
});
|
|
489
506
|
|
|
507
|
+
// src/client/resources/bundles.resource.ts
|
|
508
|
+
function bundlesUrl(ctx) {
|
|
509
|
+
return `${ctx.apiBase}/catalog/bundles`;
|
|
510
|
+
}
|
|
511
|
+
function bundleVersionsUrl(ctx) {
|
|
512
|
+
return `${ctx.apiBase}/catalog/bundle-versions`;
|
|
513
|
+
}
|
|
514
|
+
function scoped2(url, ctx) {
|
|
515
|
+
return `${url}?projectKey=${encodeURIComponent(ctx.projectKey)}`;
|
|
516
|
+
}
|
|
517
|
+
var bundlesResource = defineResource(
|
|
518
|
+
"bundles",
|
|
519
|
+
{
|
|
520
|
+
list: async (http, ctx) => await requestJson(http, scoped2(bundlesUrl(ctx), ctx)) ?? [],
|
|
521
|
+
create: (http, ctx, data) => requestJsonBody(http, bundlesUrl(ctx), "Create returned no body", {
|
|
522
|
+
method: "POST",
|
|
523
|
+
body: { ...data, projectKey: ctx.projectKey }
|
|
524
|
+
}),
|
|
525
|
+
update: (http, ctx, bundleId, data) => requestJsonBody(
|
|
526
|
+
http,
|
|
527
|
+
`${bundlesUrl(ctx)}/${bundleId}`,
|
|
528
|
+
"Update returned no body",
|
|
529
|
+
{ method: "PATCH", body: data }
|
|
530
|
+
),
|
|
531
|
+
/** Marks the bundle deleted. */
|
|
532
|
+
softDelete: async (http, ctx, bundleId) => {
|
|
533
|
+
await requestJson(http, `${bundlesUrl(ctx)}/${bundleId}`, { method: "DELETE" });
|
|
534
|
+
}
|
|
535
|
+
},
|
|
536
|
+
{ projectScoped: true }
|
|
537
|
+
);
|
|
538
|
+
var bundleVersionsResource = defineResource("bundleVersions", {
|
|
539
|
+
listForBundle: async (http, ctx, bundleId) => await requestJson(http, `${bundlesUrl(ctx)}/${bundleId}/versions`) ?? [],
|
|
540
|
+
createDraft: (http, ctx, bundleId, data) => requestJsonBody(
|
|
541
|
+
http,
|
|
542
|
+
`${bundlesUrl(ctx)}/${bundleId}/versions`,
|
|
543
|
+
"CreateDraft returned no body",
|
|
544
|
+
{ method: "POST", body: data }
|
|
545
|
+
),
|
|
546
|
+
updateDraft: (http, ctx, versionId, data) => requestJsonBody(
|
|
547
|
+
http,
|
|
548
|
+
`${bundleVersionsUrl(ctx)}/${versionId}`,
|
|
549
|
+
"UpdateDraft returned no body",
|
|
550
|
+
{ method: "PATCH", body: data }
|
|
551
|
+
),
|
|
552
|
+
publish: (http, ctx, versionId, options = {}) => requestJsonBody(
|
|
553
|
+
http,
|
|
554
|
+
`${bundleVersionsUrl(ctx)}/${versionId}/publish`,
|
|
555
|
+
"Publish returned no body",
|
|
556
|
+
{ method: "POST", body: options }
|
|
557
|
+
),
|
|
558
|
+
/**
|
|
559
|
+
* Discards a draft. A published version cannot be discarded — the API
|
|
560
|
+
* answers 422 `BUNDLE_VERSION_ALREADY_PUBLISHED`.
|
|
561
|
+
*/
|
|
562
|
+
discardDraft: async (http, ctx, versionId) => {
|
|
563
|
+
await requestJson(http, `${bundleVersionsUrl(ctx)}/${versionId}`, { method: "DELETE" });
|
|
564
|
+
}
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
// src/client/resources/catalog.resource.ts
|
|
568
|
+
function catalogUrl(ctx) {
|
|
569
|
+
return `${ctx.apiBase}/catalog`;
|
|
570
|
+
}
|
|
571
|
+
function scoped3(url, ctx) {
|
|
572
|
+
return `${url}?projectKey=${encodeURIComponent(ctx.projectKey)}`;
|
|
573
|
+
}
|
|
574
|
+
var catalogResource = defineResource(
|
|
575
|
+
"catalog",
|
|
576
|
+
{
|
|
577
|
+
capabilities: async (http, ctx) => await requestJson(
|
|
578
|
+
http,
|
|
579
|
+
scoped3(`${catalogUrl(ctx)}/capabilities`, ctx)
|
|
580
|
+
) ?? [],
|
|
581
|
+
features: async (http, ctx) => await requestJson(
|
|
582
|
+
http,
|
|
583
|
+
scoped3(`${catalogUrl(ctx)}/features`, ctx)
|
|
584
|
+
) ?? [],
|
|
585
|
+
quotas: async (http, ctx) => await requestJson(
|
|
586
|
+
http,
|
|
587
|
+
scoped3(`${catalogUrl(ctx)}/quotas`, ctx)
|
|
588
|
+
) ?? [],
|
|
589
|
+
reviewFeature: (http, ctx, featureKey, data) => requestJsonBody(
|
|
590
|
+
http,
|
|
591
|
+
scoped3(`${catalogUrl(ctx)}/features/${encodeURIComponent(featureKey)}/review`, ctx),
|
|
592
|
+
"Review returned no body",
|
|
593
|
+
{ method: "PATCH", body: data }
|
|
594
|
+
),
|
|
595
|
+
reviewQuota: (http, ctx, quotaKey, data) => requestJsonBody(
|
|
596
|
+
http,
|
|
597
|
+
scoped3(`${catalogUrl(ctx)}/quotas/${encodeURIComponent(quotaKey)}/review`, ctx),
|
|
598
|
+
"Review returned no body",
|
|
599
|
+
{ method: "PATCH", body: data }
|
|
600
|
+
),
|
|
601
|
+
/** The translations are wrapped in `{ i18n }` here, not by the caller. */
|
|
602
|
+
setFeatureI18n: (http, ctx, featureKey, i18n) => requestJsonBody(
|
|
603
|
+
http,
|
|
604
|
+
scoped3(`${catalogUrl(ctx)}/features/${encodeURIComponent(featureKey)}/i18n`, ctx),
|
|
605
|
+
"i18n returned no body",
|
|
606
|
+
{ method: "PATCH", body: { i18n } }
|
|
607
|
+
),
|
|
608
|
+
setQuotaI18n: (http, ctx, quotaKey, i18n) => requestJsonBody(
|
|
609
|
+
http,
|
|
610
|
+
scoped3(`${catalogUrl(ctx)}/quotas/${encodeURIComponent(quotaKey)}/i18n`, ctx),
|
|
611
|
+
"i18n returned no body",
|
|
612
|
+
{ method: "PATCH", body: { i18n } }
|
|
613
|
+
),
|
|
614
|
+
setFeatureBase: (http, ctx, featureKey, data) => requestJsonBody(
|
|
615
|
+
http,
|
|
616
|
+
scoped3(`${catalogUrl(ctx)}/features/${encodeURIComponent(featureKey)}`, ctx),
|
|
617
|
+
"Base returned no body",
|
|
618
|
+
{ method: "PATCH", body: data }
|
|
619
|
+
),
|
|
620
|
+
setQuotaBase: (http, ctx, quotaKey, data) => requestJsonBody(
|
|
621
|
+
http,
|
|
622
|
+
scoped3(`${catalogUrl(ctx)}/quotas/${encodeURIComponent(quotaKey)}`, ctx),
|
|
623
|
+
"Base returned no body",
|
|
624
|
+
{ method: "PATCH", body: data }
|
|
625
|
+
),
|
|
626
|
+
/**
|
|
627
|
+
* Writes a discovery snapshot into the catalogue.
|
|
628
|
+
*
|
|
629
|
+
* The request only. `useCatalogEntries.syncDiscovery` reloads the three
|
|
630
|
+
* lists afterwards, which is that composable keeping its refs true —
|
|
631
|
+
* not part of the call, and not something an override should inherit
|
|
632
|
+
* invisibly.
|
|
633
|
+
*/
|
|
634
|
+
syncDiscovery: (http, ctx, snapshot) => requestJsonBody(
|
|
635
|
+
http,
|
|
636
|
+
`${catalogUrl(ctx)}/discovery/sync`,
|
|
637
|
+
"Sync returned no body",
|
|
638
|
+
{ method: "POST", body: { snapshot } }
|
|
639
|
+
)
|
|
640
|
+
},
|
|
641
|
+
{ projectScoped: true }
|
|
642
|
+
);
|
|
643
|
+
|
|
644
|
+
// src/client/resources/discovery.resource.ts
|
|
645
|
+
function discoveryUrl(ctx) {
|
|
646
|
+
return `${ctx.apiBase}/discovery`;
|
|
647
|
+
}
|
|
648
|
+
function fail(status, method, url, message) {
|
|
649
|
+
return new AdminError({ status, url, method, message });
|
|
650
|
+
}
|
|
651
|
+
var discoveryResource = defineResource("discovery", {
|
|
652
|
+
/**
|
|
653
|
+
* Reads the snapshot, revalidating against `etag` when one is passed.
|
|
654
|
+
*
|
|
655
|
+
* Pass `null` (or nothing) to force a full read — that is what
|
|
656
|
+
* `useDiscovery.reload()` does when the operator asks for fresh data.
|
|
657
|
+
*/
|
|
658
|
+
read: async (http, ctx, etag = null) => {
|
|
659
|
+
const url = discoveryUrl(ctx);
|
|
660
|
+
const headers = {};
|
|
661
|
+
if (etag) headers["If-None-Match"] = etag;
|
|
662
|
+
const response = await http(url, { method: "GET", headers });
|
|
663
|
+
requireServerAnswer(
|
|
664
|
+
response.status,
|
|
665
|
+
"GET",
|
|
666
|
+
url,
|
|
667
|
+
(diagnostic) => fail(response.status, "GET", url, diagnostic)
|
|
668
|
+
);
|
|
669
|
+
if (response.status === 304) return { status: "unchanged" };
|
|
670
|
+
if (response.status !== 200) {
|
|
671
|
+
throw fail(
|
|
672
|
+
response.status,
|
|
673
|
+
"GET",
|
|
674
|
+
url,
|
|
675
|
+
`Discovery endpoint responded with HTTP ${response.status}`
|
|
676
|
+
);
|
|
677
|
+
}
|
|
678
|
+
return {
|
|
679
|
+
status: "loaded",
|
|
680
|
+
snapshot: await response.json(),
|
|
681
|
+
etag: response.headers.get("ETag")
|
|
682
|
+
};
|
|
683
|
+
},
|
|
684
|
+
/**
|
|
685
|
+
* Re-runs the scan and returns what it found.
|
|
686
|
+
*
|
|
687
|
+
* Unconditional by construction: a rescan asks the server to look again,
|
|
688
|
+
* so revalidating against a tag the previous scan produced would answer
|
|
689
|
+
* with the snapshot the rescan was meant to replace.
|
|
690
|
+
*/
|
|
691
|
+
rescan: async (http, ctx) => {
|
|
692
|
+
const url = `${discoveryUrl(ctx)}/rescan`;
|
|
693
|
+
const response = await http(url, {
|
|
694
|
+
method: "POST",
|
|
695
|
+
headers: { "content-type": "application/json" }
|
|
696
|
+
});
|
|
697
|
+
requireServerAnswer(
|
|
698
|
+
response.status,
|
|
699
|
+
"POST",
|
|
700
|
+
url,
|
|
701
|
+
(diagnostic) => fail(response.status, "POST", url, diagnostic)
|
|
702
|
+
);
|
|
703
|
+
if (response.status !== 200 && response.status !== 201) {
|
|
704
|
+
throw fail(
|
|
705
|
+
response.status,
|
|
706
|
+
"POST",
|
|
707
|
+
url,
|
|
708
|
+
`Discovery rescan responded with HTTP ${response.status}`
|
|
709
|
+
);
|
|
710
|
+
}
|
|
711
|
+
return {
|
|
712
|
+
snapshot: await response.json(),
|
|
713
|
+
etag: response.headers.get("ETag")
|
|
714
|
+
};
|
|
715
|
+
}
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
// src/client/resources/marketing.resource.ts
|
|
719
|
+
function projectionsUrl(ctx) {
|
|
720
|
+
return `${ctx.apiBase}/catalog/marketing-projections`;
|
|
721
|
+
}
|
|
722
|
+
function settingsUrl(ctx) {
|
|
723
|
+
return `${ctx.apiBase}/catalog/marketing-settings`;
|
|
724
|
+
}
|
|
725
|
+
var marketingResource = defineResource(
|
|
726
|
+
"marketing",
|
|
727
|
+
{
|
|
728
|
+
listProjections: async (http, ctx, filter = {}) => {
|
|
729
|
+
const params = new URLSearchParams();
|
|
730
|
+
params.set("projectKey", ctx.projectKey);
|
|
731
|
+
if (filter.targetType) params.set("targetType", filter.targetType);
|
|
732
|
+
if (filter.targetVersionId) params.set("targetVersionId", filter.targetVersionId);
|
|
733
|
+
if (filter.locale) params.set("locale", filter.locale);
|
|
734
|
+
return await requestJson(
|
|
735
|
+
http,
|
|
736
|
+
`${projectionsUrl(ctx)}?${params.toString()}`
|
|
737
|
+
) ?? [];
|
|
738
|
+
},
|
|
739
|
+
/**
|
|
740
|
+
* The request only. `useMarketingProjections.create` reloads the list
|
|
741
|
+
* afterwards because a unique-tuple insert can change what the filter
|
|
742
|
+
* matches — that is the composable keeping its refs true, not part of
|
|
743
|
+
* the call.
|
|
744
|
+
*/
|
|
745
|
+
createProjection: (http, ctx, data) => requestJsonBody(
|
|
746
|
+
http,
|
|
747
|
+
projectionsUrl(ctx),
|
|
748
|
+
"Create returned no body",
|
|
749
|
+
{ method: "POST", body: data }
|
|
750
|
+
),
|
|
751
|
+
updateProjection: (http, ctx, id, data) => requestJsonBody(
|
|
752
|
+
http,
|
|
753
|
+
`${projectionsUrl(ctx)}/${id}`,
|
|
754
|
+
"Update returned no body",
|
|
755
|
+
{ method: "PATCH", body: data }
|
|
756
|
+
),
|
|
757
|
+
deleteProjection: async (http, ctx, id) => {
|
|
758
|
+
await requestJson(http, `${projectionsUrl(ctx)}/${id}`, { method: "DELETE" });
|
|
759
|
+
},
|
|
760
|
+
/**
|
|
761
|
+
* The activated locale subset, or `null` when none was ever stored.
|
|
762
|
+
*
|
|
763
|
+
* `null` means the full pool is active — the server's answer for "no
|
|
764
|
+
* row", and the state the page falls back to.
|
|
765
|
+
*/
|
|
766
|
+
settings: (http, ctx) => requestJson(
|
|
767
|
+
http,
|
|
768
|
+
`${settingsUrl(ctx)}?projectKey=${encodeURIComponent(ctx.projectKey)}`
|
|
769
|
+
),
|
|
770
|
+
/** `PUT`, not `PATCH`: the endpoint replaces the set it is given. */
|
|
771
|
+
saveSettings: async (http, ctx, activeLocales) => {
|
|
772
|
+
await requestJson(http, settingsUrl(ctx), {
|
|
773
|
+
method: "PUT",
|
|
774
|
+
body: { projectKey: ctx.projectKey, activeLocales }
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
},
|
|
778
|
+
{ projectScoped: true }
|
|
779
|
+
);
|
|
780
|
+
|
|
781
|
+
// src/client/resources/promo-codes.resource.ts
|
|
782
|
+
function promoCodesUrl(ctx) {
|
|
783
|
+
return `${ctx.apiBase}/promo-codes`;
|
|
784
|
+
}
|
|
785
|
+
var promoCodesResource = defineResource("promoCodes", {
|
|
786
|
+
list: async (http, ctx, filter = {}) => await requestJson(
|
|
787
|
+
http,
|
|
788
|
+
`${promoCodesUrl(ctx)}${filterQueryString({
|
|
789
|
+
search: filter.search,
|
|
790
|
+
status: filter.status
|
|
791
|
+
})}`
|
|
792
|
+
) ?? [],
|
|
793
|
+
/**
|
|
794
|
+
* Returns nothing, matching `createAdminResourceClient.createPromo`.
|
|
795
|
+
*
|
|
796
|
+
* The endpoint does answer with the created record, but the page it feeds
|
|
797
|
+
* reloads the list rather than reading it, and promising a body a caller
|
|
798
|
+
* would then have to trust is a wider contract than anything holds today.
|
|
799
|
+
*/
|
|
800
|
+
create: async (http, ctx, payload) => {
|
|
801
|
+
await requestJson(http, promoCodesUrl(ctx), { method: "POST", body: payload });
|
|
802
|
+
},
|
|
803
|
+
update: async (http, ctx, id, payload) => {
|
|
804
|
+
await requestJson(http, `${promoCodesUrl(ctx)}/${encodeURIComponent(id)}`, {
|
|
805
|
+
method: "PATCH",
|
|
806
|
+
body: payload
|
|
807
|
+
});
|
|
808
|
+
},
|
|
809
|
+
remove: async (http, ctx, id) => {
|
|
810
|
+
await requestJson(http, `${promoCodesUrl(ctx)}/${encodeURIComponent(id)}`, {
|
|
811
|
+
method: "DELETE"
|
|
812
|
+
});
|
|
813
|
+
}
|
|
814
|
+
});
|
|
815
|
+
|
|
816
|
+
// src/client/resources/promotions.resource.ts
|
|
817
|
+
function promotionsUrl(ctx) {
|
|
818
|
+
return `${ctx.apiBase}/catalog/promotions`;
|
|
819
|
+
}
|
|
820
|
+
var promotionsResource = defineResource(
|
|
821
|
+
"promotions",
|
|
822
|
+
{
|
|
823
|
+
list: async (http, ctx) => await requestJson(
|
|
824
|
+
http,
|
|
825
|
+
`${promotionsUrl(ctx)}?projectKey=${encodeURIComponent(ctx.projectKey)}`
|
|
826
|
+
) ?? [],
|
|
827
|
+
create: (http, ctx, data) => requestJsonBody(http, promotionsUrl(ctx), "Create returned no body", {
|
|
828
|
+
method: "POST",
|
|
829
|
+
body: data
|
|
830
|
+
}),
|
|
831
|
+
update: (http, ctx, id, data) => requestJsonBody(
|
|
832
|
+
http,
|
|
833
|
+
`${promotionsUrl(ctx)}/${id}`,
|
|
834
|
+
"Update returned no body",
|
|
835
|
+
{ method: "PATCH", body: data }
|
|
836
|
+
),
|
|
837
|
+
remove: async (http, ctx, id) => {
|
|
838
|
+
await requestJson(http, `${promotionsUrl(ctx)}/${id}`, { method: "DELETE" });
|
|
839
|
+
}
|
|
840
|
+
},
|
|
841
|
+
{ projectScoped: true }
|
|
842
|
+
);
|
|
843
|
+
|
|
490
844
|
// src/client/resources/tenants.resource.ts
|
|
845
|
+
function tenantsUrl(ctx) {
|
|
846
|
+
return `${ctx.apiBase}/tenants`;
|
|
847
|
+
}
|
|
848
|
+
function tenantUrl(ctx, slug) {
|
|
849
|
+
return `${tenantsUrl(ctx)}/${encodeURIComponent(slug)}`;
|
|
850
|
+
}
|
|
491
851
|
var tenantsResource = defineResource("tenants", {
|
|
492
|
-
list: defineListOp((ctx) =>
|
|
852
|
+
list: defineListOp((ctx) => tenantsUrl(ctx)),
|
|
853
|
+
detail: async (http, ctx, slug) => requestJson(http, tenantUrl(ctx, slug)),
|
|
854
|
+
/**
|
|
855
|
+
* Suspends a tenant. The reason is recorded on the audit trail, so it is a
|
|
856
|
+
* required argument rather than an option with a default.
|
|
857
|
+
*/
|
|
858
|
+
suspend: async (http, ctx, slug, reason) => {
|
|
859
|
+
await requestJson(http, `${tenantUrl(ctx, slug)}/suspend`, {
|
|
860
|
+
method: "POST",
|
|
861
|
+
body: { reason }
|
|
862
|
+
});
|
|
863
|
+
},
|
|
864
|
+
reactivate: async (http, ctx, slug) => {
|
|
865
|
+
await requestJson(http, `${tenantUrl(ctx, slug)}/reactivate`, { method: "POST" });
|
|
866
|
+
}
|
|
867
|
+
});
|
|
868
|
+
|
|
869
|
+
// src/client/resources/users.resource.ts
|
|
870
|
+
function usersUrl(ctx) {
|
|
871
|
+
return `${ctx.apiBase}/users`;
|
|
872
|
+
}
|
|
873
|
+
var usersResource = defineResource("users", {
|
|
874
|
+
/**
|
|
875
|
+
* `q` searches name and mail, `tenant` narrows to one tenant's members.
|
|
876
|
+
*
|
|
877
|
+
* Both are dropped when empty rather than sent as `q=` — see
|
|
878
|
+
* `isSentInQuery`; an empty search that reached the server would filter
|
|
879
|
+
* every row away on an endpoint that treats the parameter as a substring.
|
|
880
|
+
*/
|
|
881
|
+
list: async (http, ctx, filter = {}) => await requestJson(
|
|
882
|
+
http,
|
|
883
|
+
`${usersUrl(ctx)}${filterQueryString({ q: filter.q, tenant: filter.tenant })}`
|
|
884
|
+
) ?? []
|
|
885
|
+
});
|
|
886
|
+
|
|
887
|
+
// src/client/resources/subscriptions.resource.ts
|
|
888
|
+
function subscriptionsUrl(ctx) {
|
|
889
|
+
return `${ctx.apiBase}/subscriptions`;
|
|
890
|
+
}
|
|
891
|
+
var subscriptionsResource = defineResource("subscriptions", {
|
|
892
|
+
list: async (http, ctx) => await requestJson(http, subscriptionsUrl(ctx)) ?? []
|
|
493
893
|
});
|
|
494
894
|
|
|
495
895
|
// src/client/resources/audit.resource.ts
|
|
@@ -501,7 +901,16 @@ var auditResource = defineResource("audit", {
|
|
|
501
901
|
var platformResources = {
|
|
502
902
|
plans: plansResource,
|
|
503
903
|
planVersions: planVersionsResource,
|
|
904
|
+
bundles: bundlesResource,
|
|
905
|
+
bundleVersions: bundleVersionsResource,
|
|
906
|
+
catalog: catalogResource,
|
|
907
|
+
discovery: discoveryResource,
|
|
908
|
+
marketing: marketingResource,
|
|
909
|
+
promoCodes: promoCodesResource,
|
|
910
|
+
promotions: promotionsResource,
|
|
504
911
|
tenants: tenantsResource,
|
|
912
|
+
users: usersResource,
|
|
913
|
+
subscriptions: subscriptionsResource,
|
|
505
914
|
audit: auditResource
|
|
506
915
|
};
|
|
507
916
|
|
package/dist/quasar/index.d.cts
CHANGED
|
@@ -2,8 +2,8 @@ import { Component, App, WatchStopHandle } from 'vue';
|
|
|
2
2
|
import { QuasarPluginOptions, QDialogOptions } from 'quasar';
|
|
3
3
|
import { Pinia } from 'pinia';
|
|
4
4
|
import { RouteRecordRaw, RouterHistory, Router } from 'vue-router';
|
|
5
|
-
import { p as platformResources, H as HttpClient } from '../catalog-
|
|
6
|
-
import { S as SuperAdminGuardOptions, a as SuperAdminBrand, b as SuperAdminEndpoints, E as ExtensionsMap, A as ActionsMap, c as SuperAdminLoginAdapter, U as UiNotify, d as UiConfirm, R as ResourceOverrides, I as InstallPlugin, e as SuperAdminI18nOptions, f as SaThemeOptions, g as SuperAdminI18n, h as SaTheme, i as UiConfirmRequest } from '../resource-registry-
|
|
5
|
+
import { p as platformResources, H as HttpClient } from '../catalog-Dv2twuNi.cjs';
|
|
6
|
+
import { S as SuperAdminGuardOptions, a as SuperAdminBrand, b as SuperAdminEndpoints, E as ExtensionsMap, A as ActionsMap, c as SuperAdminLoginAdapter, U as UiNotify, d as UiConfirm, R as ResourceOverrides, I as InstallPlugin, e as SuperAdminI18nOptions, f as SaThemeOptions, g as SuperAdminI18n, h as SaTheme, i as UiConfirmRequest } from '../resource-registry-BxFpnzHY.cjs';
|
|
7
7
|
import '@saasicat/types';
|
|
8
8
|
|
|
9
9
|
interface CreateSuperAdminAppOptions extends SuperAdminGuardOptions {
|
package/dist/quasar/index.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { Component, App, WatchStopHandle } from 'vue';
|
|
|
2
2
|
import { QuasarPluginOptions, QDialogOptions } from 'quasar';
|
|
3
3
|
import { Pinia } from 'pinia';
|
|
4
4
|
import { RouteRecordRaw, RouterHistory, Router } from 'vue-router';
|
|
5
|
-
import { p as platformResources, H as HttpClient } from '../catalog-
|
|
6
|
-
import { S as SuperAdminGuardOptions, a as SuperAdminBrand, b as SuperAdminEndpoints, E as ExtensionsMap, A as ActionsMap, c as SuperAdminLoginAdapter, U as UiNotify, d as UiConfirm, R as ResourceOverrides, I as InstallPlugin, e as SuperAdminI18nOptions, f as SaThemeOptions, g as SuperAdminI18n, h as SaTheme, i as UiConfirmRequest } from '../resource-registry-
|
|
5
|
+
import { p as platformResources, H as HttpClient } from '../catalog-Dv2twuNi.js';
|
|
6
|
+
import { S as SuperAdminGuardOptions, a as SuperAdminBrand, b as SuperAdminEndpoints, E as ExtensionsMap, A as ActionsMap, c as SuperAdminLoginAdapter, U as UiNotify, d as UiConfirm, R as ResourceOverrides, I as InstallPlugin, e as SuperAdminI18nOptions, f as SaThemeOptions, g as SuperAdminI18n, h as SaTheme, i as UiConfirmRequest } from '../resource-registry-Cn1Gy2LE.js';
|
|
7
7
|
import '@saasicat/types';
|
|
8
8
|
|
|
9
9
|
interface CreateSuperAdminAppOptions extends SuperAdminGuardOptions {
|
package/dist/quasar/index.js
CHANGED
|
@@ -17,11 +17,11 @@ import {
|
|
|
17
17
|
createSaTheme,
|
|
18
18
|
createSuperAdminI18n,
|
|
19
19
|
resolveSuperAdminEndpoints
|
|
20
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-LK6YJDXC.js";
|
|
21
21
|
import {
|
|
22
22
|
defaultHttpClient,
|
|
23
23
|
platformResources
|
|
24
|
-
} from "../chunk-
|
|
24
|
+
} from "../chunk-4IZWT4UY.js";
|
|
25
25
|
|
|
26
26
|
// src/quasar/create-super-admin-app.ts
|
|
27
27
|
import { createApp } from "vue";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Component, App, InjectionKey, Ref, ComputedRef } from 'vue';
|
|
2
2
|
import { NavigationGuardWithThis } from 'vue-router';
|
|
3
3
|
import { ActionKey, ComponentKey, AdminManifest } from '@saasicat/types';
|
|
4
|
-
import { A as ActionHandler, H as HttpClient, S as SaLocale, a as SaMessages, b as SaLocaleOption, c as SaLocaleDefinition, d as SaMessagesOverrides, K as KvStore, R as ResourceDef, e as ResourceOps, f as ResourceContext, B as Bound, P as PlatformResources } from './catalog-
|
|
4
|
+
import { A as ActionHandler, H as HttpClient, S as SaLocale, a as SaMessages, b as SaLocaleOption, c as SaLocaleDefinition, d as SaMessagesOverrides, K as KvStore, R as ResourceDef, e as ResourceOps, f as ResourceContext, B as Bound, P as PlatformResources } from './catalog-Dv2twuNi.cjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* App-specific branding data that the platform `AdminLayout` and other
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Component, App, InjectionKey, Ref, ComputedRef } from 'vue';
|
|
2
2
|
import { NavigationGuardWithThis } from 'vue-router';
|
|
3
3
|
import { ActionKey, ComponentKey, AdminManifest } from '@saasicat/types';
|
|
4
|
-
import { A as ActionHandler, H as HttpClient, S as SaLocale, a as SaMessages, b as SaLocaleOption, c as SaLocaleDefinition, d as SaMessagesOverrides, K as KvStore, R as ResourceDef, e as ResourceOps, f as ResourceContext, B as Bound, P as PlatformResources } from './catalog-
|
|
4
|
+
import { A as ActionHandler, H as HttpClient, S as SaLocale, a as SaMessages, b as SaLocaleOption, c as SaLocaleDefinition, d as SaMessagesOverrides, K as KvStore, R as ResourceDef, e as ResourceOps, f as ResourceContext, B as Bound, P as PlatformResources } from './catalog-Dv2twuNi.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* App-specific branding data that the platform `AdminLayout` and other
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saasicat/ui-vue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"description": "Vue 3 components, resource clients and composables for the SuperAdmin UI shell. Provides boot and manifest loaders, navigation, actions and standard pages.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"src"
|
|
62
62
|
],
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@saasicat/types": "^0.
|
|
64
|
+
"@saasicat/types": "^0.27.0"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
67
|
"pinia": "^2.0.0 || ^3.0.0",
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
"vue-router": "^5.0.0",
|
|
100
100
|
"vue-tsc": "^3.3.3"
|
|
101
101
|
},
|
|
102
|
-
"license": "
|
|
102
|
+
"license": "PolyForm-Shield-1.0.0",
|
|
103
103
|
"author": "Taci Uelker",
|
|
104
104
|
"homepage": "https://github.com/uelker70/saasicat",
|
|
105
105
|
"repository": {
|
|
@@ -121,6 +121,7 @@
|
|
|
121
121
|
"test:component": "vitest run --config vitest.config.ts",
|
|
122
122
|
"test:e2e": "playwright test",
|
|
123
123
|
"test:visual": "playwright test --project=visual",
|
|
124
|
-
"test:visual:update": "playwright test --project=visual --update-snapshots"
|
|
124
|
+
"test:visual:update": "playwright test --project=visual --update-snapshots",
|
|
125
|
+
"test:shipped-source": "node scripts/check-shipped-source.mjs"
|
|
125
126
|
}
|
|
126
127
|
}
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
// `adminErrorMessage()` is what turns an error into user-facing text; it is
|
|
20
20
|
// the only place that decides between `detail` and a translated fallback.
|
|
21
21
|
|
|
22
|
+
import { attachCause } from './attach-cause.js';
|
|
22
23
|
import { formatMessage } from './i18n/format.js';
|
|
23
24
|
import type { SaMessages } from './i18n/messages.js';
|
|
24
25
|
|
|
@@ -234,9 +235,25 @@ export class AdminError extends Error {
|
|
|
234
235
|
readonly emptyResponse: boolean;
|
|
235
236
|
/** The request never reached the server. See `AdminErrorInit`. */
|
|
236
237
|
readonly transportFailure: boolean;
|
|
238
|
+
/**
|
|
239
|
+
* The error this one was raised from, when `AdminErrorInit` carried one.
|
|
240
|
+
*
|
|
241
|
+
* `declare` because the property is real but not emitted here: `attachCause`
|
|
242
|
+
* defines it, exactly as the ES2022 `Error` constructor would. The
|
|
243
|
+
* declaration is what makes it *readable* — `Error.cause` lives in
|
|
244
|
+
* `lib.es2022.error.d.ts`, and this package supports consumers on ES2021,
|
|
245
|
+
* where taking a cause in and never being able to read it out would be a
|
|
246
|
+
* one-way public API.
|
|
247
|
+
*
|
|
248
|
+
* Not `readonly`, unlike its siblings: the inherited `Error.cause` is
|
|
249
|
+
* writable, and narrowing that in a patch release would reject assignments
|
|
250
|
+
* a consumer can make today on ES2022.
|
|
251
|
+
*/
|
|
252
|
+
declare cause?: unknown;
|
|
237
253
|
|
|
238
254
|
constructor(init: AdminErrorInit = {}) {
|
|
239
|
-
super(init.message ?? describe(init)
|
|
255
|
+
super(init.message ?? describe(init));
|
|
256
|
+
if (init.cause !== undefined) attachCause(this, init.cause);
|
|
240
257
|
this.name = 'AdminError';
|
|
241
258
|
this.status = init.status ?? 0;
|
|
242
259
|
this.code = init.code;
|