@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.
Files changed (36) hide show
  1. package/LICENSE +90 -201
  2. package/README.md +23 -0
  3. package/dist/{catalog-Dch1Ryw0.d.cts → catalog-Dv2twuNi.d.cts} +205 -4
  4. package/dist/{catalog-Dch1Ryw0.d.ts → catalog-Dv2twuNi.d.ts} +205 -4
  5. package/dist/{chunk-BPF2BMCQ.js → chunk-4IZWT4UY.js} +414 -2
  6. package/dist/{chunk-O3J3ITF2.js → chunk-LK6YJDXC.js} +1 -1
  7. package/dist/{chunk-NEXTZZRQ.js → chunk-NRVF3JJJ.js} +2 -2
  8. package/dist/client/index.cjs +426 -5
  9. package/dist/client/index.d.cts +70 -4
  10. package/dist/client/index.d.ts +70 -4
  11. package/dist/client/index.js +22 -4
  12. package/dist/index.cjs +429 -8
  13. package/dist/index.d.cts +5 -5
  14. package/dist/index.d.ts +5 -5
  15. package/dist/index.js +23 -5
  16. package/dist/quasar/index.cjs +411 -2
  17. package/dist/quasar/index.d.cts +2 -2
  18. package/dist/quasar/index.d.ts +2 -2
  19. package/dist/quasar/index.js +2 -2
  20. package/dist/{resource-registry-D7Xjs-5f.d.cts → resource-registry-BxFpnzHY.d.cts} +1 -1
  21. package/dist/{resource-registry-TaR7rtq0.d.ts → resource-registry-Cn1Gy2LE.d.ts} +1 -1
  22. package/package.json +5 -4
  23. package/src/client/admin-error.ts +18 -1
  24. package/src/client/attach-cause.ts +21 -0
  25. package/src/client/nav-builder.ts +3 -1
  26. package/src/client/resources/bundles.resource.ts +145 -0
  27. package/src/client/resources/catalog.resource.ts +160 -0
  28. package/src/client/resources/discovery.resource.ts +108 -0
  29. package/src/client/resources/index.ts +52 -14
  30. package/src/client/resources/marketing.resource.ts +121 -0
  31. package/src/client/resources/promo-codes.resource.ts +63 -0
  32. package/src/client/resources/promotions.resource.ts +44 -0
  33. package/src/client/resources/subscriptions.resource.ts +19 -0
  34. package/src/client/resources/tenants.resource.ts +35 -9
  35. package/src/client/resources/users.resource.ts +31 -0
  36. package/src/pages-standard/SuperAdminSetupWizard.vue +7 -4
@@ -51,6 +51,9 @@ __export(client_exports, {
51
51
  bindResource: () => bindResource,
52
52
  buildRoutes: () => buildRoutes,
53
53
  buildSidebar: () => buildSidebar,
54
+ bundleVersionsResource: () => bundleVersionsResource,
55
+ bundlesResource: () => bundlesResource,
56
+ catalogResource: () => catalogResource,
54
57
  clampListPage: () => clampListPage,
55
58
  clampListPageSize: () => clampListPageSize,
56
59
  countPlans: () => countPlans,
@@ -64,6 +67,7 @@ __export(client_exports, {
64
67
  defineListOp: () => defineListOp,
65
68
  defineMessages: () => defineMessages,
66
69
  defineResource: () => defineResource,
70
+ discoveryResource: () => discoveryResource,
67
71
  filterQueryString: () => filterQueryString,
68
72
  formatCurrency: () => formatCurrency,
69
73
  formatMessage: () => formatMessage,
@@ -86,11 +90,14 @@ __export(client_exports, {
86
90
  markEmptyResponse: () => markEmptyResponse,
87
91
  markPlatformError: () => markPlatformError,
88
92
  markTransportFailure: () => markTransportFailure,
93
+ marketingResource: () => marketingResource,
89
94
  mergeMessages: () => mergeMessages,
90
95
  planVersionsResource: () => planVersionsResource,
91
96
  plansResource: () => plansResource,
92
97
  platformResources: () => platformResources,
93
98
  postJson: () => postJson,
99
+ promoCodesResource: () => promoCodesResource,
100
+ promotionsResource: () => promotionsResource,
94
101
  readErrorCode: () => readErrorCode,
95
102
  readErrorDetail: () => readErrorDetail,
96
103
  readListPage: () => readListPage,
@@ -101,16 +108,28 @@ __export(client_exports, {
101
108
  resolveLoginBranding: () => resolveLoginBranding,
102
109
  resolveMessages: () => resolveMessages,
103
110
  resolvePlans: () => resolvePlans,
111
+ subscriptionsResource: () => subscriptionsResource,
104
112
  tenantsResource: () => tenantsResource,
105
113
  toAdminError: () => toAdminError,
106
114
  todayIsoDate: () => todayIsoDate,
107
- trimTrailingSlashes: () => trimTrailingSlashes
115
+ trimTrailingSlashes: () => trimTrailingSlashes,
116
+ usersResource: () => usersResource
108
117
  });
109
118
  module.exports = __toCommonJS(client_exports);
110
119
 
111
120
  // src/client/version.ts
112
121
  var ADMIN_UI_VERSION = "1.2.0";
113
122
 
123
+ // src/client/attach-cause.ts
124
+ function attachCause(error, cause) {
125
+ Object.defineProperty(error, "cause", {
126
+ value: cause,
127
+ configurable: true,
128
+ writable: true
129
+ });
130
+ return error;
131
+ }
132
+
114
133
  // src/client/i18n/format.ts
115
134
  var import_types = require("@saasicat/types");
116
135
  function formatMessage(template, params) {
@@ -176,7 +195,8 @@ var AdminError = class extends Error {
176
195
  /** The request never reached the server. See `AdminErrorInit`. */
177
196
  transportFailure;
178
197
  constructor(init = {}) {
179
- super(init.message ?? describe(init), { cause: init.cause });
198
+ super(init.message ?? describe(init));
199
+ if (init.cause !== void 0) attachCause(this, init.cause);
180
200
  this.name = "AdminError";
181
201
  this.status = init.status ?? 0;
182
202
  this.code = init.code;
@@ -736,9 +756,392 @@ var planVersionsResource = defineResource("planVersions", {
736
756
  )
737
757
  });
738
758
 
759
+ // src/client/resources/bundles.resource.ts
760
+ function bundlesUrl(ctx) {
761
+ return `${ctx.apiBase}/catalog/bundles`;
762
+ }
763
+ function bundleVersionsUrl(ctx) {
764
+ return `${ctx.apiBase}/catalog/bundle-versions`;
765
+ }
766
+ function scoped2(url, ctx) {
767
+ return `${url}?projectKey=${encodeURIComponent(ctx.projectKey)}`;
768
+ }
769
+ var bundlesResource = defineResource(
770
+ "bundles",
771
+ {
772
+ list: async (http, ctx) => await requestJson(http, scoped2(bundlesUrl(ctx), ctx)) ?? [],
773
+ create: (http, ctx, data) => requestJsonBody(http, bundlesUrl(ctx), "Create returned no body", {
774
+ method: "POST",
775
+ body: { ...data, projectKey: ctx.projectKey }
776
+ }),
777
+ update: (http, ctx, bundleId, data) => requestJsonBody(
778
+ http,
779
+ `${bundlesUrl(ctx)}/${bundleId}`,
780
+ "Update returned no body",
781
+ { method: "PATCH", body: data }
782
+ ),
783
+ /** Marks the bundle deleted. */
784
+ softDelete: async (http, ctx, bundleId) => {
785
+ await requestJson(http, `${bundlesUrl(ctx)}/${bundleId}`, { method: "DELETE" });
786
+ }
787
+ },
788
+ { projectScoped: true }
789
+ );
790
+ var bundleVersionsResource = defineResource("bundleVersions", {
791
+ listForBundle: async (http, ctx, bundleId) => await requestJson(http, `${bundlesUrl(ctx)}/${bundleId}/versions`) ?? [],
792
+ createDraft: (http, ctx, bundleId, data) => requestJsonBody(
793
+ http,
794
+ `${bundlesUrl(ctx)}/${bundleId}/versions`,
795
+ "CreateDraft returned no body",
796
+ { method: "POST", body: data }
797
+ ),
798
+ updateDraft: (http, ctx, versionId, data) => requestJsonBody(
799
+ http,
800
+ `${bundleVersionsUrl(ctx)}/${versionId}`,
801
+ "UpdateDraft returned no body",
802
+ { method: "PATCH", body: data }
803
+ ),
804
+ publish: (http, ctx, versionId, options = {}) => requestJsonBody(
805
+ http,
806
+ `${bundleVersionsUrl(ctx)}/${versionId}/publish`,
807
+ "Publish returned no body",
808
+ { method: "POST", body: options }
809
+ ),
810
+ /**
811
+ * Discards a draft. A published version cannot be discarded — the API
812
+ * answers 422 `BUNDLE_VERSION_ALREADY_PUBLISHED`.
813
+ */
814
+ discardDraft: async (http, ctx, versionId) => {
815
+ await requestJson(http, `${bundleVersionsUrl(ctx)}/${versionId}`, { method: "DELETE" });
816
+ }
817
+ });
818
+
819
+ // src/client/resources/catalog.resource.ts
820
+ function catalogUrl(ctx) {
821
+ return `${ctx.apiBase}/catalog`;
822
+ }
823
+ function scoped3(url, ctx) {
824
+ return `${url}?projectKey=${encodeURIComponent(ctx.projectKey)}`;
825
+ }
826
+ var catalogResource = defineResource(
827
+ "catalog",
828
+ {
829
+ capabilities: async (http, ctx) => await requestJson(
830
+ http,
831
+ scoped3(`${catalogUrl(ctx)}/capabilities`, ctx)
832
+ ) ?? [],
833
+ features: async (http, ctx) => await requestJson(
834
+ http,
835
+ scoped3(`${catalogUrl(ctx)}/features`, ctx)
836
+ ) ?? [],
837
+ quotas: async (http, ctx) => await requestJson(
838
+ http,
839
+ scoped3(`${catalogUrl(ctx)}/quotas`, ctx)
840
+ ) ?? [],
841
+ reviewFeature: (http, ctx, featureKey, data) => requestJsonBody(
842
+ http,
843
+ scoped3(`${catalogUrl(ctx)}/features/${encodeURIComponent(featureKey)}/review`, ctx),
844
+ "Review returned no body",
845
+ { method: "PATCH", body: data }
846
+ ),
847
+ reviewQuota: (http, ctx, quotaKey, data) => requestJsonBody(
848
+ http,
849
+ scoped3(`${catalogUrl(ctx)}/quotas/${encodeURIComponent(quotaKey)}/review`, ctx),
850
+ "Review returned no body",
851
+ { method: "PATCH", body: data }
852
+ ),
853
+ /** The translations are wrapped in `{ i18n }` here, not by the caller. */
854
+ setFeatureI18n: (http, ctx, featureKey, i18n) => requestJsonBody(
855
+ http,
856
+ scoped3(`${catalogUrl(ctx)}/features/${encodeURIComponent(featureKey)}/i18n`, ctx),
857
+ "i18n returned no body",
858
+ { method: "PATCH", body: { i18n } }
859
+ ),
860
+ setQuotaI18n: (http, ctx, quotaKey, i18n) => requestJsonBody(
861
+ http,
862
+ scoped3(`${catalogUrl(ctx)}/quotas/${encodeURIComponent(quotaKey)}/i18n`, ctx),
863
+ "i18n returned no body",
864
+ { method: "PATCH", body: { i18n } }
865
+ ),
866
+ setFeatureBase: (http, ctx, featureKey, data) => requestJsonBody(
867
+ http,
868
+ scoped3(`${catalogUrl(ctx)}/features/${encodeURIComponent(featureKey)}`, ctx),
869
+ "Base returned no body",
870
+ { method: "PATCH", body: data }
871
+ ),
872
+ setQuotaBase: (http, ctx, quotaKey, data) => requestJsonBody(
873
+ http,
874
+ scoped3(`${catalogUrl(ctx)}/quotas/${encodeURIComponent(quotaKey)}`, ctx),
875
+ "Base returned no body",
876
+ { method: "PATCH", body: data }
877
+ ),
878
+ /**
879
+ * Writes a discovery snapshot into the catalogue.
880
+ *
881
+ * The request only. `useCatalogEntries.syncDiscovery` reloads the three
882
+ * lists afterwards, which is that composable keeping its refs true —
883
+ * not part of the call, and not something an override should inherit
884
+ * invisibly.
885
+ */
886
+ syncDiscovery: (http, ctx, snapshot) => requestJsonBody(
887
+ http,
888
+ `${catalogUrl(ctx)}/discovery/sync`,
889
+ "Sync returned no body",
890
+ { method: "POST", body: { snapshot } }
891
+ )
892
+ },
893
+ { projectScoped: true }
894
+ );
895
+
896
+ // src/client/resources/discovery.resource.ts
897
+ function discoveryUrl(ctx) {
898
+ return `${ctx.apiBase}/discovery`;
899
+ }
900
+ function fail(status, method, url, message) {
901
+ return new AdminError({ status, url, method, message });
902
+ }
903
+ var discoveryResource = defineResource("discovery", {
904
+ /**
905
+ * Reads the snapshot, revalidating against `etag` when one is passed.
906
+ *
907
+ * Pass `null` (or nothing) to force a full read — that is what
908
+ * `useDiscovery.reload()` does when the operator asks for fresh data.
909
+ */
910
+ read: async (http, ctx, etag = null) => {
911
+ const url = discoveryUrl(ctx);
912
+ const headers = {};
913
+ if (etag) headers["If-None-Match"] = etag;
914
+ const response = await http(url, { method: "GET", headers });
915
+ requireServerAnswer(
916
+ response.status,
917
+ "GET",
918
+ url,
919
+ (diagnostic) => fail(response.status, "GET", url, diagnostic)
920
+ );
921
+ if (response.status === 304) return { status: "unchanged" };
922
+ if (response.status !== 200) {
923
+ throw fail(
924
+ response.status,
925
+ "GET",
926
+ url,
927
+ `Discovery endpoint responded with HTTP ${response.status}`
928
+ );
929
+ }
930
+ return {
931
+ status: "loaded",
932
+ snapshot: await response.json(),
933
+ etag: response.headers.get("ETag")
934
+ };
935
+ },
936
+ /**
937
+ * Re-runs the scan and returns what it found.
938
+ *
939
+ * Unconditional by construction: a rescan asks the server to look again,
940
+ * so revalidating against a tag the previous scan produced would answer
941
+ * with the snapshot the rescan was meant to replace.
942
+ */
943
+ rescan: async (http, ctx) => {
944
+ const url = `${discoveryUrl(ctx)}/rescan`;
945
+ const response = await http(url, {
946
+ method: "POST",
947
+ headers: { "content-type": "application/json" }
948
+ });
949
+ requireServerAnswer(
950
+ response.status,
951
+ "POST",
952
+ url,
953
+ (diagnostic) => fail(response.status, "POST", url, diagnostic)
954
+ );
955
+ if (response.status !== 200 && response.status !== 201) {
956
+ throw fail(
957
+ response.status,
958
+ "POST",
959
+ url,
960
+ `Discovery rescan responded with HTTP ${response.status}`
961
+ );
962
+ }
963
+ return {
964
+ snapshot: await response.json(),
965
+ etag: response.headers.get("ETag")
966
+ };
967
+ }
968
+ });
969
+
970
+ // src/client/resources/marketing.resource.ts
971
+ function projectionsUrl(ctx) {
972
+ return `${ctx.apiBase}/catalog/marketing-projections`;
973
+ }
974
+ function settingsUrl(ctx) {
975
+ return `${ctx.apiBase}/catalog/marketing-settings`;
976
+ }
977
+ var marketingResource = defineResource(
978
+ "marketing",
979
+ {
980
+ listProjections: async (http, ctx, filter = {}) => {
981
+ const params = new URLSearchParams();
982
+ params.set("projectKey", ctx.projectKey);
983
+ if (filter.targetType) params.set("targetType", filter.targetType);
984
+ if (filter.targetVersionId) params.set("targetVersionId", filter.targetVersionId);
985
+ if (filter.locale) params.set("locale", filter.locale);
986
+ return await requestJson(
987
+ http,
988
+ `${projectionsUrl(ctx)}?${params.toString()}`
989
+ ) ?? [];
990
+ },
991
+ /**
992
+ * The request only. `useMarketingProjections.create` reloads the list
993
+ * afterwards because a unique-tuple insert can change what the filter
994
+ * matches — that is the composable keeping its refs true, not part of
995
+ * the call.
996
+ */
997
+ createProjection: (http, ctx, data) => requestJsonBody(
998
+ http,
999
+ projectionsUrl(ctx),
1000
+ "Create returned no body",
1001
+ { method: "POST", body: data }
1002
+ ),
1003
+ updateProjection: (http, ctx, id, data) => requestJsonBody(
1004
+ http,
1005
+ `${projectionsUrl(ctx)}/${id}`,
1006
+ "Update returned no body",
1007
+ { method: "PATCH", body: data }
1008
+ ),
1009
+ deleteProjection: async (http, ctx, id) => {
1010
+ await requestJson(http, `${projectionsUrl(ctx)}/${id}`, { method: "DELETE" });
1011
+ },
1012
+ /**
1013
+ * The activated locale subset, or `null` when none was ever stored.
1014
+ *
1015
+ * `null` means the full pool is active — the server's answer for "no
1016
+ * row", and the state the page falls back to.
1017
+ */
1018
+ settings: (http, ctx) => requestJson(
1019
+ http,
1020
+ `${settingsUrl(ctx)}?projectKey=${encodeURIComponent(ctx.projectKey)}`
1021
+ ),
1022
+ /** `PUT`, not `PATCH`: the endpoint replaces the set it is given. */
1023
+ saveSettings: async (http, ctx, activeLocales) => {
1024
+ await requestJson(http, settingsUrl(ctx), {
1025
+ method: "PUT",
1026
+ body: { projectKey: ctx.projectKey, activeLocales }
1027
+ });
1028
+ }
1029
+ },
1030
+ { projectScoped: true }
1031
+ );
1032
+
1033
+ // src/client/resources/promo-codes.resource.ts
1034
+ function promoCodesUrl(ctx) {
1035
+ return `${ctx.apiBase}/promo-codes`;
1036
+ }
1037
+ var promoCodesResource = defineResource("promoCodes", {
1038
+ list: async (http, ctx, filter = {}) => await requestJson(
1039
+ http,
1040
+ `${promoCodesUrl(ctx)}${filterQueryString({
1041
+ search: filter.search,
1042
+ status: filter.status
1043
+ })}`
1044
+ ) ?? [],
1045
+ /**
1046
+ * Returns nothing, matching `createAdminResourceClient.createPromo`.
1047
+ *
1048
+ * The endpoint does answer with the created record, but the page it feeds
1049
+ * reloads the list rather than reading it, and promising a body a caller
1050
+ * would then have to trust is a wider contract than anything holds today.
1051
+ */
1052
+ create: async (http, ctx, payload) => {
1053
+ await requestJson(http, promoCodesUrl(ctx), { method: "POST", body: payload });
1054
+ },
1055
+ update: async (http, ctx, id, payload) => {
1056
+ await requestJson(http, `${promoCodesUrl(ctx)}/${encodeURIComponent(id)}`, {
1057
+ method: "PATCH",
1058
+ body: payload
1059
+ });
1060
+ },
1061
+ remove: async (http, ctx, id) => {
1062
+ await requestJson(http, `${promoCodesUrl(ctx)}/${encodeURIComponent(id)}`, {
1063
+ method: "DELETE"
1064
+ });
1065
+ }
1066
+ });
1067
+
1068
+ // src/client/resources/promotions.resource.ts
1069
+ function promotionsUrl(ctx) {
1070
+ return `${ctx.apiBase}/catalog/promotions`;
1071
+ }
1072
+ var promotionsResource = defineResource(
1073
+ "promotions",
1074
+ {
1075
+ list: async (http, ctx) => await requestJson(
1076
+ http,
1077
+ `${promotionsUrl(ctx)}?projectKey=${encodeURIComponent(ctx.projectKey)}`
1078
+ ) ?? [],
1079
+ create: (http, ctx, data) => requestJsonBody(http, promotionsUrl(ctx), "Create returned no body", {
1080
+ method: "POST",
1081
+ body: data
1082
+ }),
1083
+ update: (http, ctx, id, data) => requestJsonBody(
1084
+ http,
1085
+ `${promotionsUrl(ctx)}/${id}`,
1086
+ "Update returned no body",
1087
+ { method: "PATCH", body: data }
1088
+ ),
1089
+ remove: async (http, ctx, id) => {
1090
+ await requestJson(http, `${promotionsUrl(ctx)}/${id}`, { method: "DELETE" });
1091
+ }
1092
+ },
1093
+ { projectScoped: true }
1094
+ );
1095
+
739
1096
  // src/client/resources/tenants.resource.ts
1097
+ function tenantsUrl(ctx) {
1098
+ return `${ctx.apiBase}/tenants`;
1099
+ }
1100
+ function tenantUrl(ctx, slug) {
1101
+ return `${tenantsUrl(ctx)}/${encodeURIComponent(slug)}`;
1102
+ }
740
1103
  var tenantsResource = defineResource("tenants", {
741
- list: defineListOp((ctx) => `${ctx.apiBase}/tenants`)
1104
+ list: defineListOp((ctx) => tenantsUrl(ctx)),
1105
+ detail: async (http, ctx, slug) => requestJson(http, tenantUrl(ctx, slug)),
1106
+ /**
1107
+ * Suspends a tenant. The reason is recorded on the audit trail, so it is a
1108
+ * required argument rather than an option with a default.
1109
+ */
1110
+ suspend: async (http, ctx, slug, reason) => {
1111
+ await requestJson(http, `${tenantUrl(ctx, slug)}/suspend`, {
1112
+ method: "POST",
1113
+ body: { reason }
1114
+ });
1115
+ },
1116
+ reactivate: async (http, ctx, slug) => {
1117
+ await requestJson(http, `${tenantUrl(ctx, slug)}/reactivate`, { method: "POST" });
1118
+ }
1119
+ });
1120
+
1121
+ // src/client/resources/users.resource.ts
1122
+ function usersUrl(ctx) {
1123
+ return `${ctx.apiBase}/users`;
1124
+ }
1125
+ var usersResource = defineResource("users", {
1126
+ /**
1127
+ * `q` searches name and mail, `tenant` narrows to one tenant's members.
1128
+ *
1129
+ * Both are dropped when empty rather than sent as `q=` — see
1130
+ * `isSentInQuery`; an empty search that reached the server would filter
1131
+ * every row away on an endpoint that treats the parameter as a substring.
1132
+ */
1133
+ list: async (http, ctx, filter = {}) => await requestJson(
1134
+ http,
1135
+ `${usersUrl(ctx)}${filterQueryString({ q: filter.q, tenant: filter.tenant })}`
1136
+ ) ?? []
1137
+ });
1138
+
1139
+ // src/client/resources/subscriptions.resource.ts
1140
+ function subscriptionsUrl(ctx) {
1141
+ return `${ctx.apiBase}/subscriptions`;
1142
+ }
1143
+ var subscriptionsResource = defineResource("subscriptions", {
1144
+ list: async (http, ctx) => await requestJson(http, subscriptionsUrl(ctx)) ?? []
742
1145
  });
743
1146
 
744
1147
  // src/client/resources/audit.resource.ts
@@ -750,7 +1153,16 @@ var auditResource = defineResource("audit", {
750
1153
  var platformResources = {
751
1154
  plans: plansResource,
752
1155
  planVersions: planVersionsResource,
1156
+ bundles: bundlesResource,
1157
+ bundleVersions: bundleVersionsResource,
1158
+ catalog: catalogResource,
1159
+ discovery: discoveryResource,
1160
+ marketing: marketingResource,
1161
+ promoCodes: promoCodesResource,
1162
+ promotions: promotionsResource,
753
1163
  tenants: tenantsResource,
1164
+ users: usersResource,
1165
+ subscriptions: subscriptionsResource,
754
1166
  audit: auditResource
755
1167
  };
756
1168
 
@@ -1003,7 +1415,7 @@ var DEFAULT_STANDARD_PAGE_ROUTES = {
1003
1415
  platformEmailHistory: "/admin/platform-email-history"
1004
1416
  };
1005
1417
  function isSupportedStandardPageKey(key) {
1006
- return Object.hasOwn(DEFAULT_STANDARD_PAGE_ROUTES, key);
1418
+ return Object.prototype.hasOwnProperty.call(DEFAULT_STANDARD_PAGE_ROUTES, key);
1007
1419
  }
1008
1420
  var DEFAULT_ICONS = {
1009
1421
  dashboard: "dashboard",
@@ -4579,6 +4991,9 @@ function identityChipStyle(accent) {
4579
4991
  bindResource,
4580
4992
  buildRoutes,
4581
4993
  buildSidebar,
4994
+ bundleVersionsResource,
4995
+ bundlesResource,
4996
+ catalogResource,
4582
4997
  clampListPage,
4583
4998
  clampListPageSize,
4584
4999
  countPlans,
@@ -4592,6 +5007,7 @@ function identityChipStyle(accent) {
4592
5007
  defineListOp,
4593
5008
  defineMessages,
4594
5009
  defineResource,
5010
+ discoveryResource,
4595
5011
  filterQueryString,
4596
5012
  formatCurrency,
4597
5013
  formatMessage,
@@ -4614,11 +5030,14 @@ function identityChipStyle(accent) {
4614
5030
  markEmptyResponse,
4615
5031
  markPlatformError,
4616
5032
  markTransportFailure,
5033
+ marketingResource,
4617
5034
  mergeMessages,
4618
5035
  planVersionsResource,
4619
5036
  plansResource,
4620
5037
  platformResources,
4621
5038
  postJson,
5039
+ promoCodesResource,
5040
+ promotionsResource,
4622
5041
  readErrorCode,
4623
5042
  readErrorDetail,
4624
5043
  readListPage,
@@ -4629,8 +5048,10 @@ function identityChipStyle(accent) {
4629
5048
  resolveLoginBranding,
4630
5049
  resolveMessages,
4631
5050
  resolvePlans,
5051
+ subscriptionsResource,
4632
5052
  tenantsResource,
4633
5053
  toAdminError,
4634
5054
  todayIsoDate,
4635
- trimTrailingSlashes
5055
+ trimTrailingSlashes,
5056
+ usersResource
4636
5057
  });
@@ -1,6 +1,6 @@
1
- import { H as HttpClient, a as SaMessages, K as KvStore, S as SaLocale, a9 as SaNavMessages } from '../catalog-Dch1Ryw0.cjs';
2
- export { i as ActionDefNotInManifestError, A as ActionHandler, h as ActionRegistry, j as AuditListFilter, B as Bound, D as DEFAULT_SA_LOCALE, k as DefineResourceOptions, l as HttpResponse, L as LIST_FIRST_PAGE, m as LIST_PAGE_SIZE_DEFAULT, n as LIST_PAGE_SIZE_MAX, o as LIST_PAGINATION_PARAMS, q as ListFilterOf, r as ListOp, s as ListQuery, M as MessageTree, t as MissingHandlerError, u as PartialMessages, P as PlatformResources, v as PublishPlanVersionOptions, w as ResolvedAction, f as ResourceContext, R as ResourceDef, g as ResourceListPage, x as ResourceOp, e as ResourceOps, y as SA_INTL_LOCALES, z as SA_LOCALES, C as SA_LOCALE_LABELS, E as SA_MESSAGES, F as SaBuiltinLocale, G as SaCatalog, I as SaCatalogOptions, c as SaLocaleDefinition, b as SaLocaleOption, d as SaMessagesOverrides, T as TenantsListFilter, J as TranslationOf, N as auditResource, O as bindResource, Q as clampListPage, U as clampListPageSize, V as createSaCatalog, W as defaultHttpClient, X as defaultKvStore, Y as defineListOp, Z as defineMessages, _ as defineResource, $ as filterQueryString, a0 as isSaBuiltinLocale, a1 as isSentInQuery, a2 as listUrl, a3 as mergeMessages, a4 as planVersionsResource, a5 as plansResource, p as platformResources, a6 as readListPage, a7 as resolveMessages, a8 as tenantsResource } from '../catalog-Dch1Ryw0.cjs';
3
- import { PublicBootResponse, AdminManifest, StandardPageKey, TenantColumnDef, PromoCodeRecord, AdminTenantDetail, AdminUserListFilter, AdminUserListRow, AdminAuditListFilter, AuditEntry, AdminSubscriptionListRow } from '@saasicat/types';
1
+ import { H as HttpClient, R as ResourceDef, f as ResourceContext, a as SaMessages, K as KvStore, S as SaLocale, ai as SaNavMessages } from '../catalog-Dv2twuNi.cjs';
2
+ export { i as ActionDefNotInManifestError, A as ActionHandler, h as ActionRegistry, j as AuditListFilter, B as Bound, D as DEFAULT_SA_LOCALE, k as DefineResourceOptions, l as DiscoveryRead, m as HttpResponse, L as LIST_FIRST_PAGE, n as LIST_PAGE_SIZE_DEFAULT, o as LIST_PAGE_SIZE_MAX, q as LIST_PAGINATION_PARAMS, r as ListFilterOf, s as ListOp, t as ListQuery, M as MarketingProjectionsFilter, u as MessageTree, v as MissingHandlerError, w as PartialMessages, P as PlatformResources, x as PromoCodesFilter, y as PublishBundleVersionOptions, z as PublishPlanVersionOptions, C as ResolvedAction, g as ResourceListPage, E as ResourceOp, e as ResourceOps, F as SA_INTL_LOCALES, G as SA_LOCALES, I as SA_LOCALE_LABELS, J as SA_MESSAGES, N as SaBuiltinLocale, O as SaCatalog, Q as SaCatalogOptions, c as SaLocaleDefinition, b as SaLocaleOption, d as SaMessagesOverrides, T as TenantsListFilter, U as TranslationOf, V as auditResource, W as bindResource, X as bundleVersionsResource, Y as bundlesResource, Z as clampListPage, _ as clampListPageSize, $ as createSaCatalog, a0 as defaultHttpClient, a1 as defaultKvStore, a2 as defineListOp, a3 as defineMessages, a4 as defineResource, a5 as discoveryResource, a6 as filterQueryString, a7 as isSaBuiltinLocale, a8 as isSentInQuery, a9 as listUrl, aa as marketingResource, ab as mergeMessages, ac as planVersionsResource, ad as plansResource, p as platformResources, ae as promoCodesResource, af as readListPage, ag as resolveMessages, ah as tenantsResource } from '../catalog-Dv2twuNi.cjs';
3
+ import { CapabilityCatalogEntryRow, FeatureCatalogEntryRow, QuotaCatalogEntryRow, ReviewCatalogEntryData, CatalogEntryI18n, UpdateCatalogEntryBaseData, DiscoverySnapshot, SyncDiscoveryResult, PromotionRow, CreatePromotionData, UpdatePromotionData, AdminUserListFilter, AdminUserListRow, AdminSubscriptionListRow, PublicBootResponse, AdminManifest, StandardPageKey, TenantColumnDef, PromoCodeRecord, AdminTenantDetail, AdminAuditListFilter, AuditEntry } from '@saasicat/types';
4
4
 
5
5
  declare const ADMIN_UI_VERSION = "1.2.0";
6
6
 
@@ -169,6 +169,57 @@ declare function requestJson<T>(http: HttpClient, url: string, init?: ResourceRe
169
169
  */
170
170
  declare function requestJsonBody<T>(http: HttpClient, url: string, what: string, init?: ResourceRequestInit): Promise<T>;
171
171
 
172
+ /**
173
+ * The discovered catalogue and the review decisions taken on it.
174
+ *
175
+ * Entry keys are encoded on the way into the path — that is what
176
+ * `useCatalogEntries` does, and a feature key legitimately contains characters
177
+ * (`.`, `:`) that a code scan produces.
178
+ */
179
+ declare const catalogResource: ResourceDef<{
180
+ readonly capabilities: (http: HttpClient, ctx: ResourceContext) => Promise<CapabilityCatalogEntryRow[]>;
181
+ readonly features: (http: HttpClient, ctx: ResourceContext) => Promise<FeatureCatalogEntryRow[]>;
182
+ readonly quotas: (http: HttpClient, ctx: ResourceContext) => Promise<QuotaCatalogEntryRow[]>;
183
+ readonly reviewFeature: (http: HttpClient, ctx: ResourceContext, featureKey: string, data: ReviewCatalogEntryData) => Promise<FeatureCatalogEntryRow>;
184
+ readonly reviewQuota: (http: HttpClient, ctx: ResourceContext, quotaKey: string, data: ReviewCatalogEntryData) => Promise<QuotaCatalogEntryRow>;
185
+ /** The translations are wrapped in `{ i18n }` here, not by the caller. */
186
+ readonly setFeatureI18n: (http: HttpClient, ctx: ResourceContext, featureKey: string, i18n: CatalogEntryI18n) => Promise<FeatureCatalogEntryRow>;
187
+ readonly setQuotaI18n: (http: HttpClient, ctx: ResourceContext, quotaKey: string, i18n: CatalogEntryI18n) => Promise<QuotaCatalogEntryRow>;
188
+ readonly setFeatureBase: (http: HttpClient, ctx: ResourceContext, featureKey: string, data: UpdateCatalogEntryBaseData) => Promise<FeatureCatalogEntryRow>;
189
+ readonly setQuotaBase: (http: HttpClient, ctx: ResourceContext, quotaKey: string, data: UpdateCatalogEntryBaseData) => Promise<QuotaCatalogEntryRow>;
190
+ /**
191
+ * Writes a discovery snapshot into the catalogue.
192
+ *
193
+ * The request only. `useCatalogEntries.syncDiscovery` reloads the three
194
+ * lists afterwards, which is that composable keeping its refs true —
195
+ * not part of the call, and not something an override should inherit
196
+ * invisibly.
197
+ */
198
+ readonly syncDiscovery: (http: HttpClient, ctx: ResourceContext, snapshot: DiscoverySnapshot) => Promise<SyncDiscoveryResult>;
199
+ }>;
200
+
201
+ declare const promotionsResource: ResourceDef<{
202
+ readonly list: (http: HttpClient, ctx: ResourceContext) => Promise<PromotionRow[]>;
203
+ readonly create: (http: HttpClient, ctx: ResourceContext, data: CreatePromotionData) => Promise<PromotionRow>;
204
+ readonly update: (http: HttpClient, ctx: ResourceContext, id: string, data: UpdatePromotionData) => Promise<PromotionRow>;
205
+ readonly remove: (http: HttpClient, ctx: ResourceContext, id: string) => Promise<void>;
206
+ }>;
207
+
208
+ declare const usersResource: ResourceDef<{
209
+ /**
210
+ * `q` searches name and mail, `tenant` narrows to one tenant's members.
211
+ *
212
+ * Both are dropped when empty rather than sent as `q=` — see
213
+ * `isSentInQuery`; an empty search that reached the server would filter
214
+ * every row away on an endpoint that treats the parameter as a substring.
215
+ */
216
+ readonly list: (http: HttpClient, ctx: ResourceContext, filter?: AdminUserListFilter) => Promise<AdminUserListRow[]>;
217
+ }>;
218
+
219
+ declare const subscriptionsResource: ResourceDef<{
220
+ readonly list: (http: HttpClient, ctx: ResourceContext) => Promise<AdminSubscriptionListRow[]>;
221
+ }>;
222
+
172
223
  /**
173
224
  * Marks an error as one this package raised. Called by the package's own error
174
225
  * classes in their constructors; nothing else should call it.
@@ -260,6 +311,21 @@ declare class AdminError extends Error {
260
311
  readonly emptyResponse: boolean;
261
312
  /** The request never reached the server. See `AdminErrorInit`. */
262
313
  readonly transportFailure: boolean;
314
+ /**
315
+ * The error this one was raised from, when `AdminErrorInit` carried one.
316
+ *
317
+ * `declare` because the property is real but not emitted here: `attachCause`
318
+ * defines it, exactly as the ES2022 `Error` constructor would. The
319
+ * declaration is what makes it *readable* — `Error.cause` lives in
320
+ * `lib.es2022.error.d.ts`, and this package supports consumers on ES2021,
321
+ * where taking a cause in and never being able to read it out would be a
322
+ * one-way public API.
323
+ *
324
+ * Not `readonly`, unlike its siblings: the inherited `Error.cause` is
325
+ * writable, and narrowing that in a patch release would reject assignments
326
+ * a consumer can make today on ES2022.
327
+ */
328
+ cause?: unknown;
263
329
  constructor(init?: AdminErrorInit);
264
330
  }
265
331
  /** Whether `err` is an `AdminError`, including one from another bundle copy. */
@@ -863,4 +929,4 @@ declare function identityAccentFor(key: string, overrides?: Readonly<Record<stri
863
929
  */
864
930
  declare function identityChipStyle(accent: string): Record<string, string>;
865
931
 
866
- export { ADMIN_UI_VERSION, AdminError, type AdminErrorInit, type AdminPromoListFilter, type AdminPromoListRow, type AdminResourceClientOptions, type AxiosHttpClientOptions, type AxiosLike, type AxiosLikeConfig, type AxiosLikeResponse, type AxiosLikeResponseConfig, type AxiosResponseBody, type BatchColumnData, BatchColumnDriftError, BatchColumnFetcher, type BatchColumnFetcherOptions, type BatchColumnRow, type BatchColumnValue, BootLoadError, BootLoader, type BootLoaderOptions, type BuildRouteEntry, type CachedManifestEntry, DEFAULT_STANDARD_PAGE_ROUTES, type FetchHttpClientOptions, HttpClient, HttpJsonError, IDENTITY_ACCENTS, IDENTITY_ACCENT_VALUES, IDENTITY_NEUTRAL, IDENTITY_NEUTRAL_VALUE, KvStore, type LoginBootProject, type LoginBrandFallback, type LoginBranding, ManifestLoadError, ManifestLoader, type ManifestLoaderOptions, type MessageParams, type NavBuilderOptions, type ParamStyle, type PlanCounts, type PlanRowLike, type PlanVersionLike, type ResolvePlansInput, type ResolvedPlan, type ResourceRequestInit, SaLocale, SaMessages, type SidebarItem, type SidebarSection, adminErrorMessage, buildRoutes, buildSidebar, countPlans, createAdminResourceClient, createAxiosHttpClient, createFetchHttpClient, defaultSectionOrder, formatCurrency, formatMessage, getJson, identityAccentAt, identityAccentFor, identityChipStyle, isAdminError, isAxiosNoResponseError, isCurrentlyValid, isEmptyResponse, isExpired, isFutureScheduled, isPlatformError, isProductionBoot, isTransportFailure, markEmptyResponse, markPlatformError, markTransportFailure, postJson, readErrorCode, readErrorDetail, requestJson, requestJsonBody, requireServerAnswer, resolveExtension, resolveLoginBranding, resolvePlans, toAdminError, todayIsoDate, trimTrailingSlashes };
932
+ export { ADMIN_UI_VERSION, AdminError, type AdminErrorInit, type AdminPromoListFilter, type AdminPromoListRow, type AdminResourceClientOptions, type AxiosHttpClientOptions, type AxiosLike, type AxiosLikeConfig, type AxiosLikeResponse, type AxiosLikeResponseConfig, type AxiosResponseBody, type BatchColumnData, BatchColumnDriftError, BatchColumnFetcher, type BatchColumnFetcherOptions, type BatchColumnRow, type BatchColumnValue, BootLoadError, BootLoader, type BootLoaderOptions, type BuildRouteEntry, type CachedManifestEntry, DEFAULT_STANDARD_PAGE_ROUTES, type FetchHttpClientOptions, HttpClient, HttpJsonError, IDENTITY_ACCENTS, IDENTITY_ACCENT_VALUES, IDENTITY_NEUTRAL, IDENTITY_NEUTRAL_VALUE, KvStore, type LoginBootProject, type LoginBrandFallback, type LoginBranding, ManifestLoadError, ManifestLoader, type ManifestLoaderOptions, type MessageParams, type NavBuilderOptions, type ParamStyle, type PlanCounts, type PlanRowLike, type PlanVersionLike, type ResolvePlansInput, type ResolvedPlan, ResourceContext, ResourceDef, type ResourceRequestInit, SaLocale, SaMessages, type SidebarItem, type SidebarSection, adminErrorMessage, buildRoutes, buildSidebar, catalogResource, countPlans, createAdminResourceClient, createAxiosHttpClient, createFetchHttpClient, defaultSectionOrder, formatCurrency, formatMessage, getJson, identityAccentAt, identityAccentFor, identityChipStyle, isAdminError, isAxiosNoResponseError, isCurrentlyValid, isEmptyResponse, isExpired, isFutureScheduled, isPlatformError, isProductionBoot, isTransportFailure, markEmptyResponse, markPlatformError, markTransportFailure, postJson, promotionsResource, readErrorCode, readErrorDetail, requestJson, requestJsonBody, requireServerAnswer, resolveExtension, resolveLoginBranding, resolvePlans, subscriptionsResource, toAdminError, todayIsoDate, trimTrailingSlashes, usersResource };