@saasicat/ui-vue 0.22.2 → 0.23.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 (108) hide show
  1. package/README.md +1 -1
  2. package/dist/{chunk-LY52T4N4.js → chunk-TQQMKWN6.js} +58 -1
  3. package/dist/index.cjs +213 -159
  4. package/dist/index.d.cts +2 -2
  5. package/dist/index.d.ts +2 -2
  6. package/dist/index.js +7 -1
  7. package/dist/quasar/index.cjs +116 -20
  8. package/dist/quasar/index.d.cts +48 -3
  9. package/dist/quasar/index.d.ts +48 -3
  10. package/dist/quasar/index.js +58 -3
  11. package/dist/{use-super-admin-i18n-CgTuNi8h.d.cts → use-sa-theme-B5t7oXph.d.cts} +51 -1
  12. package/dist/{use-super-admin-i18n-CHNdsSlm.d.ts → use-sa-theme-OUBlaqgl.d.ts} +51 -1
  13. package/package.json +5 -2
  14. package/src/components/BundleVersionPublishDialog.vue +17 -17
  15. package/src/components/KvBlock.vue +6 -6
  16. package/src/components/MarketingPromotionsTab.vue +78 -78
  17. package/src/components/MfaPromptDialog.vue +2 -2
  18. package/src/components/TenantActionConfirmDialog.vue +5 -5
  19. package/src/components/VersionDiffPreview.vue +18 -18
  20. package/src/components/bundle-editor/BundleCreatePanel.vue +52 -52
  21. package/src/components/bundle-editor/BundleFeaturesEditor.vue +20 -20
  22. package/src/components/bundle-editor/BundlePlanCompatPicker.vue +33 -33
  23. package/src/components/bundle-editor/BundleQuotasEditor.vue +26 -26
  24. package/src/components/bundle-editor/BundleStatusBanner.vue +21 -21
  25. package/src/components/bundle-editor/BundleVersionInlineEditor.vue +48 -48
  26. package/src/components/bundle-editor/BundleVersionStrip.vue +30 -30
  27. package/src/components/dialogs/PilotCreateDialog.vue +20 -20
  28. package/src/components/dialogs/PilotEditDialog.vue +6 -6
  29. package/src/components/dialogs/PromoCodeCreateDialog.vue +9 -9
  30. package/src/components/dialogs/PromoCodeDialogFields.vue +61 -61
  31. package/src/components/dialogs/PromoCodeEditDialog.vue +11 -11
  32. package/src/components/dialogs/pilot-dialog.css +48 -48
  33. package/src/components/plan/PlanCycleToggle.vue +9 -16
  34. package/src/components/plan/PlanGrid.vue +30 -34
  35. package/src/components/plan/PriceSummary.vue +35 -35
  36. package/src/components/plan/PromoCodeInput.vue +26 -26
  37. package/src/components/plan/PublicBundleGrid.vue +32 -28
  38. package/src/components/plan-create-dialog/PlanCreateDialog.vue +49 -49
  39. package/src/components/plan-detail/PlanDetail.vue +172 -156
  40. package/src/components/plan-detail/PlanTitleEdit.vue +11 -11
  41. package/src/components/plan-list/PlanList.vue +98 -77
  42. package/src/components/plan-matrix/PlanMatrix.vue +89 -89
  43. package/src/components/plan-review/PlanReview.vue +60 -56
  44. package/src/components/plan-version-editor/PlanVersionEditor.vue +224 -200
  45. package/src/components/wizard-stepper/WizardStepper.vue +17 -17
  46. package/src/index.ts +1 -0
  47. package/src/pages-standard/AdminLayout.vue +58 -37
  48. package/src/pages-standard/AdminManifestErrorPage.vue +6 -6
  49. package/src/pages-standard/AuditPage.vue +3 -3
  50. package/src/pages-standard/BundlesPage.vue +36 -36
  51. package/src/pages-standard/DashboardPage.vue +17 -17
  52. package/src/pages-standard/DiscoveryPage.vue +55 -49
  53. package/src/pages-standard/EmailHistoryPage.vue +53 -71
  54. package/src/pages-standard/MarketingCatalogPage.vue +226 -218
  55. package/src/pages-standard/PilotsPage.vue +7 -6
  56. package/src/pages-standard/PlatformEmailPage.vue +18 -18
  57. package/src/pages-standard/PromoCodeDetailPage.vue +3 -3
  58. package/src/pages-standard/PromoCodesPage.vue +7 -6
  59. package/src/pages-standard/SuperAdminLoginPage.vue +39 -25
  60. package/src/pages-standard/SuperAdminSetupWizard.vue +44 -33
  61. package/src/pages-standard/TenantDetailPage.vue +7 -7
  62. package/src/pages-standard/TenantsPage.vue +11 -46
  63. package/src/pages-standard/bundles-page/BundleAccordionList.vue +13 -13
  64. package/src/pages-standard/discovery-page/CatalogEntryTransPanel.vue +24 -24
  65. package/src/pages-standard/discovery-page/DiscoveryCapList.vue +22 -22
  66. package/src/pages-standard/discovery-page/DiscoveryFeatureCard.vue +39 -39
  67. package/src/pages-standard/discovery-page/DiscoveryQuotaCard.vue +26 -26
  68. package/src/pages-standard/discovery-page/DiscoveryStatusControl.vue +1 -1
  69. package/src/pages-standard/plan-versions/PlanDiffCard.vue +16 -16
  70. package/src/pages-standard/plan-versions/PlanVersionsDiff.vue +21 -15
  71. package/src/pages-standard/plan-versions/PlanVersionsTimeline.vue +45 -45
  72. package/src/pages-standard/plans-page/PlanBundleOverview.vue +21 -15
  73. package/src/pages-standard/plans-page/PlanPublishDialog.vue +4 -4
  74. package/src/pages-standard/plans-page/PlansPageToast.vue +6 -6
  75. package/src/pages-standard/sa-theme.css +9 -687
  76. package/src/pages-standard/tenants/StatusPill.vue +13 -13
  77. package/src/pages-tenant/LimitsRow.vue +4 -4
  78. package/src/pages-tenant/MySubscriptionBundlesPage.vue +61 -61
  79. package/src/pages-tenant/OnboardingConfigurator.vue +24 -24
  80. package/src/pages-tenant/PackageSnapshotPanel.vue +10 -16
  81. package/src/pages-tenant/PendingVersionBanner.vue +12 -12
  82. package/src/pages-tenant/PlanChangeWizard.vue +20 -27
  83. package/src/pages-tenant/TenantPlanSection.vue +13 -21
  84. package/src/pages-tenant/UsageBar.vue +7 -7
  85. package/src/pages-tenant/tenant-plan-section/BundlePreviewDialog.vue +14 -14
  86. package/src/pages-tenant/tenant-plan-section/TenantBundleStore.vue +10 -10
  87. package/src/pages-tenant/tenant-plan-section/TenantFeatureMatrix.vue +2 -2
  88. package/src/quasar/create-super-admin-app.ts +96 -1
  89. package/src/quasar/dark-bridge.ts +66 -0
  90. package/src/quasar/index.ts +1 -0
  91. package/src/ui/theme/_breakpoints.scss +28 -0
  92. package/src/ui/theme/base.css +50 -0
  93. package/src/ui/theme/components/body.css +23 -0
  94. package/src/ui/theme/components/button.css +158 -0
  95. package/src/ui/theme/components/card.css +48 -0
  96. package/src/ui/theme/components/field.css +38 -0
  97. package/src/ui/theme/components/hero.css +46 -0
  98. package/src/ui/theme/components/paginator.css +63 -0
  99. package/src/ui/theme/components/section.css +67 -0
  100. package/src/ui/theme/components/statistics.css +189 -0
  101. package/src/ui/theme/components/table.css +60 -0
  102. package/src/ui/theme/index.css +42 -0
  103. package/src/ui/theme/tokens.legacy.css +147 -0
  104. package/src/ui/theme/tokens.primitive.css +108 -0
  105. package/src/ui/theme/tokens.scale.css +103 -0
  106. package/src/ui/theme/tokens.semantic.dark.css +173 -0
  107. package/src/ui/theme/tokens.semantic.light.css +212 -0
  108. package/src/vue/use-sa-theme.ts +154 -0
package/dist/index.cjs CHANGED
@@ -54,6 +54,7 @@ __export(src_exports, {
54
54
  SA_LOCALE_LABELS: () => SA_LOCALE_LABELS,
55
55
  SA_LOCALE_STORAGE_KEY: () => SA_LOCALE_STORAGE_KEY,
56
56
  SA_MESSAGES: () => SA_MESSAGES,
57
+ SA_THEME_KEY: () => SA_THEME_KEY,
57
58
  SERVER_PAGE_SIZE_OPTIONS: () => SERVER_PAGE_SIZE_OPTIONS,
58
59
  SUPER_ADMIN_ACTIONS_KEY: () => SUPER_ADMIN_ACTIONS_KEY,
59
60
  SUPER_ADMIN_BRAND_KEY: () => SUPER_ADMIN_BRAND_KEY,
@@ -79,6 +80,7 @@ __export(src_exports, {
79
80
  createPlatformLoaders: () => createPlatformLoaders,
80
81
  createProjectPageHostRoute: () => createProjectPageHostRoute,
81
82
  createSaCatalog: () => createSaCatalog,
83
+ createSaTheme: () => createSaTheme,
82
84
  createSuperAdminI18n: () => createSuperAdminI18n,
83
85
  defaultHttpClient: () => defaultHttpClient,
84
86
  defaultIconForActionKey: () => defaultIconForActionKey,
@@ -128,6 +130,7 @@ __export(src_exports, {
128
130
  usePromotions: () => usePromotions,
129
131
  usePublicBoot: () => usePublicBoot,
130
132
  useSaMessages: () => useSaMessages,
133
+ useSaTheme: () => useSaTheme,
131
134
  useSubscriptionDraft: () => useSubscriptionDraft,
132
135
  useSuperAdminActions: () => useSuperAdminActions,
133
136
  useSuperAdminBrand: () => useSuperAdminBrand,
@@ -4096,8 +4099,56 @@ function useSaMessages(namespace) {
4096
4099
  return (0, import_vue2.computed)(() => messages.value[namespace]);
4097
4100
  }
4098
4101
 
4099
- // src/vue/project-page-host.ts
4102
+ // src/vue/use-sa-theme.ts
4100
4103
  var import_vue3 = require("vue");
4104
+ var SCHEMES = ["light", "dark", "system"];
4105
+ var STORAGE_KEY = "saasicat.theme.scheme";
4106
+ function isScheme(value) {
4107
+ return typeof value === "string" && SCHEMES.includes(value);
4108
+ }
4109
+ function systemScheme() {
4110
+ const value = (0, import_vue3.ref)("light");
4111
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
4112
+ return { value, unsubscribe: () => {
4113
+ } };
4114
+ }
4115
+ const query = window.matchMedia("(prefers-color-scheme: dark)");
4116
+ value.value = query.matches ? "dark" : "light";
4117
+ const onChange = (event) => {
4118
+ value.value = event.matches ? "dark" : "light";
4119
+ };
4120
+ query.addEventListener("change", onChange);
4121
+ return { value, unsubscribe: () => query.removeEventListener("change", onChange) };
4122
+ }
4123
+ function createSaTheme(options = {}) {
4124
+ const storage = options.storage ?? defaultKvStore();
4125
+ const persist = options.persist !== false;
4126
+ const provided = options.scheme;
4127
+ const appOwnsIt = (0, import_vue3.isRef)(provided);
4128
+ const stored = persist && !appOwnsIt ? storage.get(STORAGE_KEY) : null;
4129
+ const scheme = (0, import_vue3.isRef)(provided) ? provided : (0, import_vue3.ref)(isScheme(stored) ? stored : provided ?? "system");
4130
+ const { value: system, unsubscribe } = systemScheme();
4131
+ const stopPersisting = persist && !appOwnsIt ? (0, import_vue3.watch)(scheme, (next) => storage.set(STORAGE_KEY, next)) : null;
4132
+ return {
4133
+ scheme,
4134
+ resolved: (0, import_vue3.computed)(() => scheme.value === "system" ? system.value : scheme.value),
4135
+ dispose: () => {
4136
+ unsubscribe();
4137
+ stopPersisting?.();
4138
+ }
4139
+ };
4140
+ }
4141
+ var SA_THEME_KEY = /* @__PURE__ */ Symbol.for("@saasicat/ui-vue/SA_THEME");
4142
+ var fallbackTheme = null;
4143
+ function useSaTheme() {
4144
+ const injected = (0, import_vue3.inject)(SA_THEME_KEY, null);
4145
+ if (injected) return injected;
4146
+ fallbackTheme ??= createSaTheme({ persist: false });
4147
+ return fallbackTheme;
4148
+ }
4149
+
4150
+ // src/vue/project-page-host.ts
4151
+ var import_vue4 = require("vue");
4101
4152
  var import_vue_router = require("vue-router");
4102
4153
  var asyncComponentCache = /* @__PURE__ */ new WeakMap();
4103
4154
  function resolveAsync(extensions, key) {
@@ -4110,23 +4161,23 @@ function resolveAsync(extensions, key) {
4110
4161
  if (cached) return cached;
4111
4162
  const loader = extensions[key];
4112
4163
  if (!loader) return null;
4113
- const cmp = (0, import_vue3.defineAsyncComponent)(loader);
4164
+ const cmp = (0, import_vue4.defineAsyncComponent)(loader);
4114
4165
  bucket.set(key, cmp);
4115
4166
  return cmp;
4116
4167
  }
4117
- var ProjectPageHost = (0, import_vue3.defineComponent)({
4168
+ var ProjectPageHost = (0, import_vue4.defineComponent)({
4118
4169
  name: "ProjectPageHost",
4119
4170
  setup() {
4120
4171
  const route = (0, import_vue_router.useRoute)();
4121
- const extensions = (0, import_vue3.inject)(SUPER_ADMIN_EXTENSIONS_KEY, {});
4122
- const manifestAccessor = (0, import_vue3.inject)(SUPER_ADMIN_MANIFEST_KEY, null);
4123
- const matchingPage = (0, import_vue3.computed)(() => {
4172
+ const extensions = (0, import_vue4.inject)(SUPER_ADMIN_EXTENSIONS_KEY, {});
4173
+ const manifestAccessor = (0, import_vue4.inject)(SUPER_ADMIN_MANIFEST_KEY, null);
4174
+ const matchingPage = (0, import_vue4.computed)(() => {
4124
4175
  const manifest = manifestAccessor ? manifestAccessor() : null;
4125
4176
  if (!manifest) return null;
4126
4177
  const pages = manifest.navigation?.projectPages ?? [];
4127
4178
  return pages.find((p) => p.route === route.path) ?? null;
4128
4179
  });
4129
- const resolvedComponent = (0, import_vue3.computed)(() => {
4180
+ const resolvedComponent = (0, import_vue4.computed)(() => {
4130
4181
  const page = matchingPage.value;
4131
4182
  if (!page) return null;
4132
4183
  return resolveAsync(extensions, page.componentKey);
@@ -4134,10 +4185,10 @@ var ProjectPageHost = (0, import_vue3.defineComponent)({
4134
4185
  return () => {
4135
4186
  const page = matchingPage.value;
4136
4187
  const cmp = resolvedComponent.value;
4137
- if (page && cmp) return (0, import_vue3.h)(cmp);
4138
- return (0, import_vue3.h)("div", { class: "sa-project-page-host__missing", role: "alert" }, [
4139
- (0, import_vue3.h)("h2", "Page not available"),
4140
- (0, import_vue3.h)(
4188
+ if (page && cmp) return (0, import_vue4.h)(cmp);
4189
+ return (0, import_vue4.h)("div", { class: "sa-project-page-host__missing", role: "alert" }, [
4190
+ (0, import_vue4.h)("h2", "Page not available"),
4191
+ (0, import_vue4.h)(
4141
4192
  "p",
4142
4193
  page ? `componentKey "${page.componentKey}" is not registered in the extensions: map. Apps must register the component in createSuperAdminApp({ extensions }).` : `No manifest definition for ${route.path}. Either the ProjectPage is missing from the manifest, or the capability is not active.`
4143
4194
  )
@@ -4188,15 +4239,15 @@ function createAdminRoutes(options) {
4188
4239
  }
4189
4240
 
4190
4241
  // src/vue/use-api-list.ts
4191
- var import_vue4 = require("vue");
4242
+ var import_vue5 = require("vue");
4192
4243
  function useApiList(options) {
4193
4244
  const http = options.http ?? defaultHttpClient();
4194
- const items = (0, import_vue4.ref)([]);
4195
- const page = (0, import_vue4.ref)(1);
4196
- const pageSize = (0, import_vue4.ref)(50);
4197
- const total = (0, import_vue4.ref)(0);
4198
- const loading = (0, import_vue4.ref)(false);
4199
- const error = (0, import_vue4.ref)(null);
4245
+ const items = (0, import_vue5.ref)([]);
4246
+ const page = (0, import_vue5.ref)(1);
4247
+ const pageSize = (0, import_vue5.ref)(50);
4248
+ const total = (0, import_vue5.ref)(0);
4249
+ const loading = (0, import_vue5.ref)(false);
4250
+ const error = (0, import_vue5.ref)(null);
4200
4251
  function buildUrl() {
4201
4252
  const params = new URLSearchParams();
4202
4253
  params.set("page", String(page.value));
@@ -4252,7 +4303,7 @@ function useApiList(options) {
4252
4303
  await load();
4253
4304
  }
4254
4305
  if (options.filter) {
4255
- (0, import_vue4.watch)(
4306
+ (0, import_vue5.watch)(
4256
4307
  options.filter,
4257
4308
  () => {
4258
4309
  page.value = 1;
@@ -4278,22 +4329,22 @@ function useApiList(options) {
4278
4329
  }
4279
4330
 
4280
4331
  // src/vue/use-pagination.ts
4281
- var import_vue5 = require("vue");
4332
+ var import_vue6 = require("vue");
4282
4333
  var ALL_ROWS = 0;
4283
4334
  var DEFAULT_ROWS_PER_PAGE = 10;
4284
4335
  var PAGE_SIZE_OPTIONS = [10, 25, 50, 100, ALL_ROWS];
4285
4336
  var SERVER_PAGE_SIZE_OPTIONS = [10, 25, 50, 100];
4286
4337
  function usePagination(rows, initialRowsPerPage = DEFAULT_ROWS_PER_PAGE) {
4287
- const page = (0, import_vue5.ref)(1);
4288
- const rowsPerPage = (0, import_vue5.ref)(initialRowsPerPage);
4289
- const total = (0, import_vue5.computed)(() => rows.value.length);
4290
- const pageCount = (0, import_vue5.computed)(
4338
+ const page = (0, import_vue6.ref)(1);
4339
+ const rowsPerPage = (0, import_vue6.ref)(initialRowsPerPage);
4340
+ const total = (0, import_vue6.computed)(() => rows.value.length);
4341
+ const pageCount = (0, import_vue6.computed)(
4291
4342
  () => rowsPerPage.value === ALL_ROWS ? 1 : Math.max(1, Math.ceil(total.value / rowsPerPage.value))
4292
4343
  );
4293
- (0, import_vue5.watch)(pageCount, (count) => {
4344
+ (0, import_vue6.watch)(pageCount, (count) => {
4294
4345
  if (page.value > count) page.value = count;
4295
4346
  });
4296
- const pagedRows = (0, import_vue5.computed)(() => {
4347
+ const pagedRows = (0, import_vue6.computed)(() => {
4297
4348
  if (rowsPerPage.value === ALL_ROWS) return [...rows.value];
4298
4349
  const start = (page.value - 1) * rowsPerPage.value;
4299
4350
  return rows.value.slice(start, start + rowsPerPage.value);
@@ -4302,14 +4353,14 @@ function usePagination(rows, initialRowsPerPage = DEFAULT_ROWS_PER_PAGE) {
4302
4353
  }
4303
4354
 
4304
4355
  // src/vue/use-tenants.ts
4305
- var import_vue6 = require("vue");
4356
+ var import_vue7 = require("vue");
4306
4357
  function useTenants(options) {
4307
4358
  if (!options?.endpoint) {
4308
4359
  throw new Error(
4309
4360
  'useTenants: `endpoint` is required (e.g. "/api/v1/admin/tenants" or "/api/admin/tenants"). The platform has no default because apps use different globalPrefix conventions.'
4310
4361
  );
4311
4362
  }
4312
- const filter = options.filter ?? (0, import_vue6.ref)({});
4363
+ const filter = options.filter ?? (0, import_vue7.ref)({});
4313
4364
  const list = useApiList({
4314
4365
  endpoint: options.endpoint,
4315
4366
  filter,
@@ -4321,14 +4372,14 @@ function useTenants(options) {
4321
4372
  }
4322
4373
 
4323
4374
  // src/vue/use-audit-entries.ts
4324
- var import_vue7 = require("vue");
4375
+ var import_vue8 = require("vue");
4325
4376
  function useAuditEntries(options) {
4326
4377
  if (!options?.endpoint) {
4327
4378
  throw new Error(
4328
4379
  'useAuditEntries: `endpoint` is required (e.g. "/api/admin/audit" or "/api/v1/admin/audit"). The platform has no default because apps use different globalPrefix conventions.'
4329
4380
  );
4330
4381
  }
4331
- const filter = options.filter ?? (0, import_vue7.ref)({});
4382
+ const filter = options.filter ?? (0, import_vue8.ref)({});
4332
4383
  const list = useApiList({
4333
4384
  endpoint: options.endpoint,
4334
4385
  filter,
@@ -4340,7 +4391,7 @@ function useAuditEntries(options) {
4340
4391
  }
4341
4392
 
4342
4393
  // src/vue/use-entitlement.ts
4343
- var import_vue8 = require("vue");
4394
+ var import_vue9 = require("vue");
4344
4395
  function useEntitlement(options) {
4345
4396
  if (!options?.endpoint) {
4346
4397
  throw new Error(
@@ -4349,9 +4400,9 @@ function useEntitlement(options) {
4349
4400
  }
4350
4401
  const endpoint = options.endpoint;
4351
4402
  const http = options.http ?? defaultHttpClient();
4352
- const entitlement = (0, import_vue8.ref)(null);
4353
- const loading = (0, import_vue8.ref)(false);
4354
- const error = (0, import_vue8.ref)(null);
4403
+ const entitlement = (0, import_vue9.ref)(null);
4404
+ const loading = (0, import_vue9.ref)(false);
4405
+ const error = (0, import_vue9.ref)(null);
4355
4406
  async function load() {
4356
4407
  loading.value = true;
4357
4408
  error.value = null;
@@ -4381,15 +4432,15 @@ function useEntitlement(options) {
4381
4432
  }
4382
4433
 
4383
4434
  // src/vue/use-tenant-manifest.ts
4384
- var import_vue9 = require("vue");
4435
+ var import_vue10 = require("vue");
4385
4436
  function useTenantManifest(options) {
4386
4437
  if (!options?.endpoint) {
4387
4438
  throw new Error('useTenantManifest: `endpoint` is required (e.g. "/api/tenant/manifest").');
4388
4439
  }
4389
4440
  const http = options.http ?? defaultHttpClient();
4390
- const manifest = (0, import_vue9.ref)(null);
4391
- const loading = (0, import_vue9.ref)(false);
4392
- const error = (0, import_vue9.ref)(null);
4441
+ const manifest = (0, import_vue10.ref)(null);
4442
+ const loading = (0, import_vue10.ref)(false);
4443
+ const error = (0, import_vue10.ref)(null);
4393
4444
  async function load() {
4394
4445
  loading.value = true;
4395
4446
  error.value = null;
@@ -4423,7 +4474,7 @@ function useTenantManifest(options) {
4423
4474
  }
4424
4475
 
4425
4476
  // src/vue/entitlement-provider.ts
4426
- var import_vue10 = require("vue");
4477
+ var import_vue11 = require("vue");
4427
4478
  var ENTITLEMENT_INJECTION_KEY = /* @__PURE__ */ Symbol.for(
4428
4479
  "@saasicat/ui-vue/ENTITLEMENT"
4429
4480
  );
@@ -4431,7 +4482,7 @@ function provideEntitlement(app, entitlement) {
4431
4482
  app.provide(ENTITLEMENT_INJECTION_KEY, entitlement);
4432
4483
  }
4433
4484
  function useInjectedEntitlement() {
4434
- return (0, import_vue10.inject)(ENTITLEMENT_INJECTION_KEY, null);
4485
+ return (0, import_vue11.inject)(ENTITLEMENT_INJECTION_KEY, null);
4435
4486
  }
4436
4487
 
4437
4488
  // src/vue/feature-router-guard.ts
@@ -4460,15 +4511,15 @@ function buildFeatureRouterGuard(options) {
4460
4511
  }
4461
4512
 
4462
4513
  // src/vue/use-tenant-billing-catalog.ts
4463
- var import_vue11 = require("vue");
4514
+ var import_vue12 = require("vue");
4464
4515
  function useTenantBillingCatalog(options = {}) {
4465
4516
  const apiPrefix = trimTrailingSlashes(options.apiPrefix ?? "/billing");
4466
4517
  const http = options.http ?? defaultHttpClient();
4467
- const plans = (0, import_vue11.ref)(null);
4468
- const featureRegistry = (0, import_vue11.ref)(null);
4469
- const bundles = (0, import_vue11.ref)(null);
4470
- const loading = (0, import_vue11.ref)(false);
4471
- const error = (0, import_vue11.ref)(null);
4518
+ const plans = (0, import_vue12.ref)(null);
4519
+ const featureRegistry = (0, import_vue12.ref)(null);
4520
+ const bundles = (0, import_vue12.ref)(null);
4521
+ const loading = (0, import_vue12.ref)(false);
4522
+ const error = (0, import_vue12.ref)(null);
4472
4523
  async function fetchJson(path) {
4473
4524
  const res = await http(`${apiPrefix}${path}`, { method: "GET" });
4474
4525
  if (res.status !== 200) {
@@ -4518,14 +4569,14 @@ function useTenantBillingCatalog(options = {}) {
4518
4569
  }
4519
4570
 
4520
4571
  // src/vue/use-tenant-billing.ts
4521
- var import_vue12 = require("vue");
4572
+ var import_vue13 = require("vue");
4522
4573
  function useTenantBilling(options = {}) {
4523
4574
  const apiPrefix = trimTrailingSlashes(options.apiPrefix ?? "/billing");
4524
4575
  const http = options.http ?? defaultHttpClient();
4525
- const usage = (0, import_vue12.ref)(null);
4526
- const loading = (0, import_vue12.ref)(false);
4527
- const error = (0, import_vue12.ref)(null);
4528
- const subscriptionBundles = (0, import_vue12.ref)([]);
4576
+ const usage = (0, import_vue13.ref)(null);
4577
+ const loading = (0, import_vue13.ref)(false);
4578
+ const error = (0, import_vue13.ref)(null);
4579
+ const subscriptionBundles = (0, import_vue13.ref)([]);
4529
4580
  function authHeaders() {
4530
4581
  const headers = {};
4531
4582
  const token = options.getAuthToken?.();
@@ -4659,8 +4710,8 @@ function useTenantBilling(options = {}) {
4659
4710
  }
4660
4711
 
4661
4712
  // src/vue/use-subscription-draft.ts
4662
- var import_vue13 = require("vue");
4663
- var import_types12 = require("@saasicat/types");
4713
+ var import_vue14 = require("vue");
4714
+ var import_types13 = require("@saasicat/types");
4664
4715
  var DEFAULT_YEARLY_FACTOR = 10;
4665
4716
  function unwrap(source) {
4666
4717
  if (source && typeof source === "object" && "value" in source) {
@@ -4676,35 +4727,35 @@ function priceForCycle(monthlyNet, yearlyNet, cycle, yearlyFactor) {
4676
4727
  }
4677
4728
  function useSubscriptionDraft(options) {
4678
4729
  const yearlyFactor = options.yearlyFactor ?? DEFAULT_YEARLY_FACTOR;
4679
- const plansRef = (0, import_vue13.computed)(() => unwrap(options.plans) ?? []);
4680
- const subscriptionBundlesRef = (0, import_vue13.computed)(
4730
+ const plansRef = (0, import_vue14.computed)(() => unwrap(options.plans) ?? []);
4731
+ const subscriptionBundlesRef = (0, import_vue14.computed)(
4681
4732
  () => unwrap(options.subscriptionBundles ?? null) ?? []
4682
4733
  );
4683
- const plan = (0, import_vue13.ref)(options.initialPlan ?? null);
4684
- const cycle = (0, import_vue13.ref)(options.initialCycle ?? "MONTHLY");
4685
- const selectedBundleVersionIds = (0, import_vue13.ref)(
4734
+ const plan = (0, import_vue14.ref)(options.initialPlan ?? null);
4735
+ const cycle = (0, import_vue14.ref)(options.initialCycle ?? "MONTHLY");
4736
+ const selectedBundleVersionIds = (0, import_vue14.ref)(
4686
4737
  new Set(options.initialBundleVersionIds ?? [])
4687
4738
  );
4688
- const promoCode = (0, import_vue13.ref)("");
4689
- const promoState = (0, import_vue13.ref)({ status: "idle", preview: null, message: "" });
4690
- const selectedPlan = (0, import_vue13.computed)(() => {
4739
+ const promoCode = (0, import_vue14.ref)("");
4740
+ const promoState = (0, import_vue14.ref)({ status: "idle", preview: null, message: "" });
4741
+ const selectedPlan = (0, import_vue14.computed)(() => {
4691
4742
  if (!plan.value) return null;
4692
4743
  return plansRef.value.find((p) => p.id === plan.value) ?? null;
4693
4744
  });
4694
- const selectedBundles = (0, import_vue13.computed)(
4745
+ const selectedBundles = (0, import_vue14.computed)(
4695
4746
  () => subscriptionBundlesRef.value.filter(
4696
4747
  (b) => selectedBundleVersionIds.value.has(b.bundleVersionId)
4697
4748
  )
4698
4749
  );
4699
- const chargeableBundles = (0, import_vue13.computed)(() => {
4750
+ const chargeableBundles = (0, import_vue14.computed)(() => {
4700
4751
  const planFeatures = selectedPlan.value?.features ?? [];
4701
4752
  const selected = selectedBundles.value;
4702
4753
  const keptIds = new Set(
4703
- (0, import_types12.selectChargeableBundles)(planFeatures, selected).map((b) => b.bundleVersionId)
4754
+ (0, import_types13.selectChargeableBundles)(planFeatures, selected).map((b) => b.bundleVersionId)
4704
4755
  );
4705
4756
  return selected.filter((b) => keptIds.has(b.bundleVersionId));
4706
4757
  });
4707
- const activeFeatures = (0, import_vue13.computed)(() => {
4758
+ const activeFeatures = (0, import_vue14.computed)(() => {
4708
4759
  const result = /* @__PURE__ */ new Set();
4709
4760
  const planObj = selectedPlan.value;
4710
4761
  if (planObj) {
@@ -4715,7 +4766,7 @@ function useSubscriptionDraft(options) {
4715
4766
  }
4716
4767
  return result;
4717
4768
  });
4718
- const pricing = (0, import_vue13.computed)(() => {
4769
+ const pricing = (0, import_vue14.computed)(() => {
4719
4770
  const cyc = cycle.value;
4720
4771
  const planObj = selectedPlan.value;
4721
4772
  const planNet = planObj ? priceForCycle(planObj.monthlyNet ?? 0, planObj.yearlyNet, cyc, yearlyFactor) : 0;
@@ -4775,7 +4826,7 @@ function useSubscriptionDraft(options) {
4775
4826
  }
4776
4827
  };
4777
4828
  });
4778
- const isDirty = (0, import_vue13.computed)(() => {
4829
+ const isDirty = (0, import_vue14.computed)(() => {
4779
4830
  return selectedBundleVersionIds.value.size > 0 || promoState.value.status === "valid";
4780
4831
  });
4781
4832
  function setPlan(planId) {
@@ -4851,7 +4902,7 @@ function useSubscriptionDraft(options) {
4851
4902
  }
4852
4903
 
4853
4904
  // src/vue/use-bulk-publish.ts
4854
- var import_vue14 = require("vue");
4905
+ var import_vue15 = require("vue");
4855
4906
  function useBulkPublish(options) {
4856
4907
  const msg = useSaMessages("planVersions");
4857
4908
  if (!options?.endpoints) {
@@ -4861,15 +4912,15 @@ function useBulkPublish(options) {
4861
4912
  }
4862
4913
  const http = options.http ?? defaultHttpClient();
4863
4914
  const endpoints = options.endpoints;
4864
- const items = (0, import_vue14.ref)([]);
4865
- const successCount = (0, import_vue14.computed)(() => items.value.filter((i) => i.status === "published").length);
4866
- const failureCount = (0, import_vue14.computed)(() => items.value.filter((i) => i.status === "failed").length);
4867
- const progress = (0, import_vue14.computed)(() => {
4915
+ const items = (0, import_vue15.ref)([]);
4916
+ const successCount = (0, import_vue15.computed)(() => items.value.filter((i) => i.status === "published").length);
4917
+ const failureCount = (0, import_vue15.computed)(() => items.value.filter((i) => i.status === "failed").length);
4918
+ const progress = (0, import_vue15.computed)(() => {
4868
4919
  if (items.value.length === 0) return 0;
4869
4920
  const done2 = successCount.value + failureCount.value;
4870
4921
  return done2 / items.value.length;
4871
4922
  });
4872
- const done = (0, import_vue14.computed)(
4923
+ const done = (0, import_vue15.computed)(
4873
4924
  () => items.value.length > 0 && items.value.every((i) => i.status === "published" || i.status === "failed")
4874
4925
  );
4875
4926
  function setItems(next) {
@@ -4927,7 +4978,7 @@ function useBulkPublish(options) {
4927
4978
  }
4928
4979
 
4929
4980
  // src/vue/use-plan-editor.ts
4930
- var import_vue15 = require("vue");
4981
+ var import_vue16 = require("vue");
4931
4982
  var PlannedOnlyFeatureError = class extends Error {
4932
4983
  constructor(violations) {
4933
4984
  super(
@@ -4947,10 +4998,10 @@ function tierWeight(tier) {
4947
4998
  function usePlanEditor(manifest, options = {}) {
4948
4999
  const baseSet = new Set(options.baseFeatures ?? []);
4949
5000
  const nonRegressive = options.nonRegressive ?? true;
4950
- const selectedFeatures = (0, import_vue15.ref)(new Set(options.initialFeatures ?? []));
5001
+ const selectedFeatures = (0, import_vue16.ref)(new Set(options.initialFeatures ?? []));
4951
5002
  const catalogFeatures = manifest.planCatalogSnapshot.features ?? [];
4952
5003
  const plannedOnlySet = new Set(catalogFeatures.filter((f) => f.plannedOnly).map((f) => f.key));
4953
- const availableFeatures = (0, import_vue15.computed)(() => {
5004
+ const availableFeatures = (0, import_vue16.computed)(() => {
4954
5005
  return catalogFeatures.map((def) => {
4955
5006
  const isSelected = selectedFeatures.value.has(def.key);
4956
5007
  const isPlannedOnly = !!def.plannedOnly;
@@ -4959,7 +5010,7 @@ function usePlanEditor(manifest, options = {}) {
4959
5010
  return { def, isSelected, isPlannedOnly, isInherited, canToggle };
4960
5011
  });
4961
5012
  });
4962
- const featuresByTier = (0, import_vue15.computed)(() => {
5013
+ const featuresByTier = (0, import_vue16.computed)(() => {
4963
5014
  const groups = /* @__PURE__ */ new Map();
4964
5015
  for (const row of availableFeatures.value) {
4965
5016
  const tier = row.def.tier ?? "OTHER";
@@ -5004,12 +5055,12 @@ function usePlanEditor(manifest, options = {}) {
5004
5055
  }
5005
5056
 
5006
5057
  // src/vue/use-public-boot.ts
5007
- var import_vue16 = require("vue");
5058
+ var import_vue17 = require("vue");
5008
5059
  function usePublicBoot(options) {
5009
5060
  const loader = new BootLoader(options);
5010
- const boot = (0, import_vue16.ref)(null);
5011
- const loading = (0, import_vue16.ref)(false);
5012
- const error = (0, import_vue16.ref)(null);
5061
+ const boot = (0, import_vue17.ref)(null);
5062
+ const loading = (0, import_vue17.ref)(false);
5063
+ const error = (0, import_vue17.ref)(null);
5013
5064
  async function load() {
5014
5065
  loading.value = true;
5015
5066
  error.value = null;
@@ -5026,7 +5077,7 @@ function usePublicBoot(options) {
5026
5077
  }
5027
5078
 
5028
5079
  // src/vue/use-discovery.ts
5029
- var import_vue17 = require("vue");
5080
+ var import_vue18 = require("vue");
5030
5081
  var DiscoveryLoadError = class extends Error {
5031
5082
  constructor(status, message) {
5032
5083
  super(message);
@@ -5043,10 +5094,10 @@ function useDiscovery(options) {
5043
5094
  );
5044
5095
  }
5045
5096
  const http = options.http ?? defaultHttpClient();
5046
- const snapshot = (0, import_vue17.ref)(null);
5047
- const etag = (0, import_vue17.ref)(null);
5048
- const loading = (0, import_vue17.ref)(false);
5049
- const error = (0, import_vue17.ref)(null);
5097
+ const snapshot = (0, import_vue18.ref)(null);
5098
+ const etag = (0, import_vue18.ref)(null);
5099
+ const loading = (0, import_vue18.ref)(false);
5100
+ const error = (0, import_vue18.ref)(null);
5050
5101
  async function fetchSnapshot(includeEtag) {
5051
5102
  loading.value = true;
5052
5103
  error.value = null;
@@ -5113,7 +5164,7 @@ function useDiscovery(options) {
5113
5164
  }
5114
5165
 
5115
5166
  // src/vue/use-catalog-entries.ts
5116
- var import_vue18 = require("vue");
5167
+ var import_vue19 = require("vue");
5117
5168
  var CatalogEntriesApiError = class extends Error {
5118
5169
  constructor(status, body, message) {
5119
5170
  super(message);
@@ -5133,11 +5184,11 @@ function useCatalogEntries(options) {
5133
5184
  }
5134
5185
  const msg = useSaMessages("discovery");
5135
5186
  const http = options.http ?? defaultHttpClient();
5136
- const capabilities = (0, import_vue18.ref)([]);
5137
- const features = (0, import_vue18.ref)([]);
5138
- const quotas = (0, import_vue18.ref)([]);
5139
- const loading = (0, import_vue18.ref)(false);
5140
- const error = (0, import_vue18.ref)(null);
5187
+ const capabilities = (0, import_vue19.ref)([]);
5188
+ const features = (0, import_vue19.ref)([]);
5189
+ const quotas = (0, import_vue19.ref)([]);
5190
+ const loading = (0, import_vue19.ref)(false);
5191
+ const error = (0, import_vue19.ref)(null);
5141
5192
  const base = `${options.adminEndpoint}/catalog`;
5142
5193
  const pk = encodeURIComponent(options.projectKey);
5143
5194
  function authHeaders() {
@@ -5263,7 +5314,7 @@ function useCatalogEntries(options) {
5263
5314
  }
5264
5315
 
5265
5316
  // src/vue/use-bundles.ts
5266
- var import_vue19 = require("vue");
5317
+ var import_vue20 = require("vue");
5267
5318
  var BundlesApiError = class extends Error {
5268
5319
  constructor(status, body, message) {
5269
5320
  super(message);
@@ -5284,9 +5335,9 @@ function useBundles(options) {
5284
5335
  throw new Error("useBundles: `projectKey` is required.");
5285
5336
  }
5286
5337
  const http = options.http ?? defaultHttpClient();
5287
- const bundles = (0, import_vue19.ref)([]);
5288
- const loading = (0, import_vue19.ref)(false);
5289
- const error = (0, import_vue19.ref)(null);
5338
+ const bundles = (0, import_vue20.ref)([]);
5339
+ const loading = (0, import_vue20.ref)(false);
5340
+ const error = (0, import_vue20.ref)(null);
5290
5341
  const baseUrl = `${options.adminEndpoint}/catalog/bundles`;
5291
5342
  function authHeaders() {
5292
5343
  const token = options.getAuthToken?.();
@@ -5358,9 +5409,9 @@ function useBundleVersions(options) {
5358
5409
  throw new Error("useBundleVersions: `bundleId` is required.");
5359
5410
  }
5360
5411
  const http = options.http ?? defaultHttpClient();
5361
- const versions = (0, import_vue19.ref)([]);
5362
- const loading = (0, import_vue19.ref)(false);
5363
- const error = (0, import_vue19.ref)(null);
5412
+ const versions = (0, import_vue20.ref)([]);
5413
+ const loading = (0, import_vue20.ref)(false);
5414
+ const error = (0, import_vue20.ref)(null);
5364
5415
  const bundleVersionsUrl = `${options.adminEndpoint}/catalog/bundles/${options.bundleId}/versions`;
5365
5416
  const versionUrlBase = `${options.adminEndpoint}/catalog/bundle-versions`;
5366
5417
  function authHeaders() {
@@ -5434,7 +5485,7 @@ function useBundleVersions(options) {
5434
5485
  }
5435
5486
 
5436
5487
  // src/vue/use-bundle-versions-map.ts
5437
- var import_vue20 = require("vue");
5488
+ var import_vue21 = require("vue");
5438
5489
  function useBundleVersionsMap(options) {
5439
5490
  if (!options?.adminEndpoint) {
5440
5491
  throw new Error("useBundleVersionsMap: `adminEndpoint` is required.");
@@ -5443,9 +5494,9 @@ function useBundleVersionsMap(options) {
5443
5494
  throw new Error("useBundleVersionsMap: `bundles` is required.");
5444
5495
  }
5445
5496
  const http = options.http ?? defaultHttpClient();
5446
- const versionsByBundle = (0, import_vue20.ref)({});
5447
- const loading = (0, import_vue20.ref)(false);
5448
- const error = (0, import_vue20.ref)(null);
5497
+ const versionsByBundle = (0, import_vue21.ref)({});
5498
+ const loading = (0, import_vue21.ref)(false);
5499
+ const error = (0, import_vue21.ref)(null);
5449
5500
  function authHeaders() {
5450
5501
  const token = options.getAuthToken?.();
5451
5502
  return token ? { Authorization: `Bearer ${token}` } : {};
@@ -5495,7 +5546,7 @@ function useBundleVersionsMap(options) {
5495
5546
  console.warn(`useBundleVersionsMap: refreshOne('${bundleId}') failed`, err);
5496
5547
  }
5497
5548
  }
5498
- (0, import_vue20.watch)(
5549
+ (0, import_vue21.watch)(
5499
5550
  () => options.bundles.value.map((b) => b.id).join(","),
5500
5551
  () => {
5501
5552
  if (options.bundles.value.length > 0) void refresh();
@@ -5507,7 +5558,7 @@ function useBundleVersionsMap(options) {
5507
5558
  }
5508
5559
 
5509
5560
  // src/vue/use-tenant-subscription-bundles.ts
5510
- var import_vue21 = require("vue");
5561
+ var import_vue22 = require("vue");
5511
5562
  var TenantSubscriptionBundlesApiError = class extends Error {
5512
5563
  constructor(status, body, message) {
5513
5564
  super(message);
@@ -5526,9 +5577,9 @@ function useTenantSubscriptionBundles(options) {
5526
5577
  }
5527
5578
  const http = options.http ?? defaultHttpClient();
5528
5579
  const baseUrl = `${options.billingEndpoint}/billing/subscription-bundles`;
5529
- const bundles = (0, import_vue21.ref)([]);
5530
- const loading = (0, import_vue21.ref)(false);
5531
- const error = (0, import_vue21.ref)(null);
5580
+ const bundles = (0, import_vue22.ref)([]);
5581
+ const loading = (0, import_vue22.ref)(false);
5582
+ const error = (0, import_vue22.ref)(null);
5532
5583
  function authHeaders() {
5533
5584
  const token = options.getAuthToken?.();
5534
5585
  return token ? { Authorization: `Bearer ${token}` } : {};
@@ -5602,7 +5653,7 @@ function rehydrateDates(raw) {
5602
5653
  }
5603
5654
 
5604
5655
  // src/vue/use-marketing-projections.ts
5605
- var import_vue22 = require("vue");
5656
+ var import_vue23 = require("vue");
5606
5657
  var MarketingProjectionsApiError = class extends Error {
5607
5658
  constructor(status, body, message) {
5608
5659
  super(message);
@@ -5622,10 +5673,10 @@ function useMarketingProjections(options) {
5622
5673
  }
5623
5674
  const msg = useSaMessages("marketing");
5624
5675
  const http = options.http ?? defaultHttpClient();
5625
- const projections = (0, import_vue22.ref)([]);
5626
- const filter = (0, import_vue22.ref)({ ...options.filter });
5627
- const loading = (0, import_vue22.ref)(false);
5628
- const error = (0, import_vue22.ref)(null);
5676
+ const projections = (0, import_vue23.ref)([]);
5677
+ const filter = (0, import_vue23.ref)({ ...options.filter });
5678
+ const loading = (0, import_vue23.ref)(false);
5679
+ const error = (0, import_vue23.ref)(null);
5629
5680
  const baseUrl = `${options.adminEndpoint}/catalog/marketing-projections`;
5630
5681
  function authHeaders() {
5631
5682
  const token = options.getAuthToken?.();
@@ -5706,7 +5757,7 @@ function useMarketingProjections(options) {
5706
5757
  }
5707
5758
 
5708
5759
  // src/vue/use-promotions.ts
5709
- var import_vue23 = require("vue");
5760
+ var import_vue24 = require("vue");
5710
5761
  var PromotionsApiError = class extends Error {
5711
5762
  constructor(status, body, message) {
5712
5763
  super(message);
@@ -5726,9 +5777,9 @@ function usePromotions(options) {
5726
5777
  }
5727
5778
  const msg = useSaMessages("promos");
5728
5779
  const http = options.http ?? defaultHttpClient();
5729
- const promotions = (0, import_vue23.ref)([]);
5730
- const loading = (0, import_vue23.ref)(false);
5731
- const error = (0, import_vue23.ref)(null);
5780
+ const promotions = (0, import_vue24.ref)([]);
5781
+ const loading = (0, import_vue24.ref)(false);
5782
+ const error = (0, import_vue24.ref)(null);
5732
5783
  const baseUrl = `${options.adminEndpoint}/catalog/promotions`;
5733
5784
  const pk = encodeURIComponent(options.projectKey);
5734
5785
  function authHeaders() {
@@ -5793,7 +5844,7 @@ function usePromotions(options) {
5793
5844
  }
5794
5845
 
5795
5846
  // src/vue/use-plans.ts
5796
- var import_vue24 = require("vue");
5847
+ var import_vue25 = require("vue");
5797
5848
  var PlansApiError = class extends Error {
5798
5849
  constructor(status, body, message) {
5799
5850
  super(message);
@@ -5814,10 +5865,10 @@ function usePlans(options) {
5814
5865
  throw new Error("usePlans: `projectKey` is required.");
5815
5866
  }
5816
5867
  const http = options.http ?? defaultHttpClient();
5817
- const plans = (0, import_vue24.ref)([]);
5818
- const loading = (0, import_vue24.ref)(false);
5819
- const error = (0, import_vue24.ref)(null);
5820
- const tenantCountsByPlanKey = (0, import_vue24.ref)({});
5868
+ const plans = (0, import_vue25.ref)([]);
5869
+ const loading = (0, import_vue25.ref)(false);
5870
+ const error = (0, import_vue25.ref)(null);
5871
+ const tenantCountsByPlanKey = (0, import_vue25.ref)({});
5821
5872
  const baseUrl = `${options.adminEndpoint}/catalog/plans`;
5822
5873
  function authHeaders() {
5823
5874
  const token = options.getAuthToken?.();
@@ -5918,9 +5969,9 @@ function usePlanVersions(options) {
5918
5969
  throw new Error("usePlanVersions: `planId` is required.");
5919
5970
  }
5920
5971
  const http = options.http ?? defaultHttpClient();
5921
- const versions = (0, import_vue24.ref)([]);
5922
- const loading = (0, import_vue24.ref)(false);
5923
- const error = (0, import_vue24.ref)(null);
5972
+ const versions = (0, import_vue25.ref)([]);
5973
+ const loading = (0, import_vue25.ref)(false);
5974
+ const error = (0, import_vue25.ref)(null);
5924
5975
  const planVersionsUrl = `${options.adminEndpoint}/catalog/plans/${options.planId}/versions`;
5925
5976
  const versionUrlBase = `${options.adminEndpoint}/catalog/plan-versions`;
5926
5977
  function authHeaders() {
@@ -6017,7 +6068,7 @@ function usePlanVersions(options) {
6017
6068
  }
6018
6069
 
6019
6070
  // src/vue/use-live-plan-versions.ts
6020
- var import_vue25 = require("vue");
6071
+ var import_vue26 = require("vue");
6021
6072
  function useLivePlanVersions(options) {
6022
6073
  if (!options?.adminEndpoint) {
6023
6074
  throw new Error("useLivePlanVersions: `adminEndpoint` is required.");
@@ -6026,9 +6077,9 @@ function useLivePlanVersions(options) {
6026
6077
  throw new Error("useLivePlanVersions: `plans` is required.");
6027
6078
  }
6028
6079
  const http = options.http ?? defaultHttpClient();
6029
- const livePlanVersions = (0, import_vue25.ref)({});
6030
- const loading = (0, import_vue25.ref)(false);
6031
- const error = (0, import_vue25.ref)(null);
6080
+ const livePlanVersions = (0, import_vue26.ref)({});
6081
+ const loading = (0, import_vue26.ref)(false);
6082
+ const error = (0, import_vue26.ref)(null);
6032
6083
  function authHeaders() {
6033
6084
  const token = options.getAuthToken?.();
6034
6085
  return token ? { Authorization: `Bearer ${token}` } : {};
@@ -6070,7 +6121,7 @@ function useLivePlanVersions(options) {
6070
6121
  loading.value = false;
6071
6122
  }
6072
6123
  }
6073
- (0, import_vue25.watch)(
6124
+ (0, import_vue26.watch)(
6074
6125
  () => options.plans.value.map((p) => p.id).join(","),
6075
6126
  () => {
6076
6127
  if (options.plans.value.length > 0) void refresh();
@@ -6092,12 +6143,12 @@ function findLatestLive(versions) {
6092
6143
  }
6093
6144
 
6094
6145
  // src/vue/use-manifest.ts
6095
- var import_vue26 = require("vue");
6146
+ var import_vue27 = require("vue");
6096
6147
  function useManifest(options) {
6097
6148
  const loader = new ManifestLoader(options);
6098
- const manifest = (0, import_vue26.ref)(null);
6099
- const loading = (0, import_vue26.ref)(false);
6100
- const error = (0, import_vue26.ref)(null);
6149
+ const manifest = (0, import_vue27.ref)(null);
6150
+ const loading = (0, import_vue27.ref)(false);
6151
+ const error = (0, import_vue27.ref)(null);
6101
6152
  async function load() {
6102
6153
  loading.value = true;
6103
6154
  error.value = null;
@@ -6123,24 +6174,24 @@ function useManifest(options) {
6123
6174
  }
6124
6175
 
6125
6176
  // src/vue/use-nav.ts
6126
- var import_vue27 = require("vue");
6177
+ var import_vue28 = require("vue");
6127
6178
  function useNav(manifest, options = {}) {
6128
6179
  const { locale } = useSuperAdminI18n();
6129
- const activeLocale = (0, import_vue27.computed)(() => options.locale ?? locale.value);
6130
- const routes = (0, import_vue27.computed)(() => {
6180
+ const activeLocale = (0, import_vue28.computed)(() => options.locale ?? locale.value);
6181
+ const routes = (0, import_vue28.computed)(() => {
6131
6182
  if (!manifest.value) return [];
6132
6183
  return buildRoutes(manifest.value, { ...options, locale: activeLocale.value });
6133
6184
  });
6134
- const sidebar = (0, import_vue27.computed)(
6185
+ const sidebar = (0, import_vue28.computed)(
6135
6186
  () => buildSidebar(routes.value, defaultSectionOrder(activeLocale.value))
6136
6187
  );
6137
6188
  return { routes, sidebar };
6138
6189
  }
6139
6190
 
6140
6191
  // src/vue/use-actions.ts
6141
- var import_vue28 = require("vue");
6192
+ var import_vue29 = require("vue");
6142
6193
  function useActions(manifest, actions) {
6143
- const registry = (0, import_vue28.computed)(() => {
6194
+ const registry = (0, import_vue29.computed)(() => {
6144
6195
  if (!manifest.value) return null;
6145
6196
  return new ActionRegistry(manifest.value, actions);
6146
6197
  });
@@ -6148,18 +6199,18 @@ function useActions(manifest, actions) {
6148
6199
  }
6149
6200
 
6150
6201
  // src/vue/use-tenant-action-flow.ts
6151
- var import_vue29 = require("vue");
6202
+ var import_vue30 = require("vue");
6152
6203
  function useTenantActionFlow(manifest, providers = {}) {
6153
6204
  const handlers = useSuperAdminActions();
6154
6205
  const msg = useSaMessages("tenants");
6155
- const registry = (0, import_vue29.computed)(() => {
6206
+ const registry = (0, import_vue30.computed)(() => {
6156
6207
  if (!manifest.value) return null;
6157
6208
  return new ActionRegistry(manifest.value, handlers);
6158
6209
  });
6159
- const orphanedDefs = (0, import_vue29.computed)(
6210
+ const orphanedDefs = (0, import_vue30.computed)(
6160
6211
  () => registry.value ? registry.value.listOrphanedDefs() : []
6161
6212
  );
6162
- const availableActions = (0, import_vue29.computed)(() => {
6213
+ const availableActions = (0, import_vue30.computed)(() => {
6163
6214
  const m = manifest.value;
6164
6215
  const reg = registry.value;
6165
6216
  if (!m || !reg) return [];
@@ -6232,7 +6283,7 @@ async function runFlow(def, row, registry, providers, successTemplate) {
6232
6283
  }
6233
6284
 
6234
6285
  // src/vue/use-platform-tenant-actions.ts
6235
- var import_vue30 = require("vue");
6286
+ var import_vue31 = require("vue");
6236
6287
  var DEFAULT_VISIBLE_FOR_ROW = (def, row) => {
6237
6288
  if (def.actionKey === "tenants.suspend") return row.isActive;
6238
6289
  if (def.actionKey === "tenants.reactivate") return !row.isActive;
@@ -6268,7 +6319,7 @@ function usePlatformTenantActions(options) {
6268
6319
  const iconForActionKey = options.iconForActionKey ?? DEFAULT_ICON_FOR_ACTION_KEY;
6269
6320
  const toneForActionKey = options.toneForActionKey ?? DEFAULT_TONE_FOR_ACTION_KEY;
6270
6321
  const visibleForRow = options.visibleForRow ?? DEFAULT_VISIBLE_FOR_ROW;
6271
- const mfa = (0, import_vue30.ref)({ show: false, description: "", error: "" });
6322
+ const mfa = (0, import_vue31.ref)({ show: false, description: "", error: "" });
6272
6323
  let pendingMfaResolve = null;
6273
6324
  function showMfaDialog(def, ctx) {
6274
6325
  return new Promise((resolve) => {
@@ -6293,7 +6344,7 @@ function usePlatformTenantActions(options) {
6293
6344
  pendingMfaResolve(null);
6294
6345
  }
6295
6346
  }
6296
- const confirmDialog = (0, import_vue30.ref)({
6347
+ const confirmDialog = (0, import_vue31.ref)({
6297
6348
  show: false,
6298
6349
  def: null,
6299
6350
  row: null
@@ -6335,7 +6386,7 @@ function usePlatformTenantActions(options) {
6335
6386
  },
6336
6387
  visibleForRow
6337
6388
  });
6338
- const manifestActions = (0, import_vue30.computed)(
6389
+ const manifestActions = (0, import_vue31.computed)(
6339
6390
  () => flow.availableActions.value.map((def) => ({
6340
6391
  id: def.id,
6341
6392
  label: def.label,
@@ -6349,7 +6400,7 @@ function usePlatformTenantActions(options) {
6349
6400
  }
6350
6401
  }))
6351
6402
  );
6352
- const realOrphans = (0, import_vue30.computed)(() => {
6403
+ const realOrphans = (0, import_vue31.computed)(() => {
6353
6404
  const caps = options.manifest.value?.capabilities ?? {};
6354
6405
  const defs = options.manifest.value?.tenants?.actions ?? [];
6355
6406
  const defByActionKey = new Map(defs.map((d) => [d.actionKey, d]));
@@ -6374,12 +6425,12 @@ function usePlatformTenantActions(options) {
6374
6425
  }
6375
6426
 
6376
6427
  // src/vue/use-batch-columns.ts
6377
- var import_vue31 = require("vue");
6428
+ var import_vue32 = require("vue");
6378
6429
  function useBatchColumns(manifest, tenantIds, options = {}) {
6379
6430
  const fetcher = new BatchColumnFetcher(options);
6380
- const data = (0, import_vue31.ref)({});
6381
- const loading = (0, import_vue31.ref)(false);
6382
- const error = (0, import_vue31.ref)(null);
6431
+ const data = (0, import_vue32.ref)({});
6432
+ const loading = (0, import_vue32.ref)(false);
6433
+ const error = (0, import_vue32.ref)(null);
6383
6434
  async function load() {
6384
6435
  if (!manifest.value || tenantIds.value.length === 0) {
6385
6436
  data.value = {};
@@ -6396,7 +6447,7 @@ function useBatchColumns(manifest, tenantIds, options = {}) {
6396
6447
  loading.value = false;
6397
6448
  }
6398
6449
  }
6399
- (0, import_vue31.watch)([manifest, tenantIds], () => {
6450
+ (0, import_vue32.watch)([manifest, tenantIds], () => {
6400
6451
  void load();
6401
6452
  });
6402
6453
  return { data, loading, error, reload: load };
@@ -6428,13 +6479,13 @@ function createPlatformLoaders(options) {
6428
6479
 
6429
6480
  // src/vue/manifest-store-factory.ts
6430
6481
  var import_pinia = require("pinia");
6431
- var import_vue32 = require("vue");
6482
+ var import_vue33 = require("vue");
6432
6483
  function createManifestStore(options) {
6433
6484
  return (0, import_pinia.defineStore)(options.id ?? "admin-manifest", () => {
6434
- const manifest = (0, import_vue32.ref)(null);
6435
- const loading = (0, import_vue32.ref)(false);
6436
- const error = (0, import_vue32.ref)(null);
6437
- const loaded = (0, import_vue32.ref)(false);
6485
+ const manifest = (0, import_vue33.ref)(null);
6486
+ const loading = (0, import_vue33.ref)(false);
6487
+ const error = (0, import_vue33.ref)(null);
6488
+ const loaded = (0, import_vue33.ref)(false);
6438
6489
  let inflight = null;
6439
6490
  async function load() {
6440
6491
  loading.value = true;
@@ -6848,6 +6899,7 @@ function defaultTenantPlanSectionI18n(locale) {
6848
6899
  SA_LOCALE_LABELS,
6849
6900
  SA_LOCALE_STORAGE_KEY,
6850
6901
  SA_MESSAGES,
6902
+ SA_THEME_KEY,
6851
6903
  SERVER_PAGE_SIZE_OPTIONS,
6852
6904
  SUPER_ADMIN_ACTIONS_KEY,
6853
6905
  SUPER_ADMIN_BRAND_KEY,
@@ -6873,6 +6925,7 @@ function defaultTenantPlanSectionI18n(locale) {
6873
6925
  createPlatformLoaders,
6874
6926
  createProjectPageHostRoute,
6875
6927
  createSaCatalog,
6928
+ createSaTheme,
6876
6929
  createSuperAdminI18n,
6877
6930
  defaultHttpClient,
6878
6931
  defaultIconForActionKey,
@@ -6922,6 +6975,7 @@ function defaultTenantPlanSectionI18n(locale) {
6922
6975
  usePromotions,
6923
6976
  usePublicBoot,
6924
6977
  useSaMessages,
6978
+ useSaTheme,
6925
6979
  useSubscriptionDraft,
6926
6980
  useSuperAdminActions,
6927
6981
  useSuperAdminBrand,