@saasicat/ui-vue 0.5.0 → 0.7.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 (186) hide show
  1. package/README.md +17 -0
  2. package/dist/{chunk-EH7TOD4H.js → chunk-A3W2N26K.js} +73 -77
  3. package/dist/{chunk-3YP2ZAOD.js → chunk-QZOSDCNP.js} +36 -1
  4. package/dist/chunk-X5SQ5HMB.js +3231 -0
  5. package/dist/client/index.cjs +3279 -76
  6. package/dist/client/index.d.cts +31 -5
  7. package/dist/client/index.d.ts +31 -5
  8. package/dist/client/index.js +23 -5
  9. package/dist/index.cjs +3709 -465
  10. package/dist/index.d.cts +37 -54
  11. package/dist/index.d.ts +37 -54
  12. package/dist/index.js +347 -311
  13. package/dist/messages-7b0P8W75.d.cts +1652 -0
  14. package/dist/messages-7b0P8W75.d.ts +1652 -0
  15. package/dist/quasar/index.cjs +3185 -4
  16. package/dist/quasar/index.d.cts +11 -2
  17. package/dist/quasar/index.d.ts +11 -2
  18. package/dist/quasar/index.js +8 -3
  19. package/dist/testing-e2e/admin-pages-suite.cjs +14 -11
  20. package/dist/testing-e2e/admin-pages-suite.js +14 -11
  21. package/dist/{ui-notify-COUzXEQ4.d.ts → use-super-admin-i18n-B3v3-SWZ.d.ts} +35 -3
  22. package/dist/{ui-notify-D_eAAwRh.d.cts → use-super-admin-i18n-DMktRVEt.d.cts} +35 -3
  23. package/package.json +2 -2
  24. package/src/client/action-registry.ts +4 -4
  25. package/src/client/batch-column-fetcher.ts +4 -4
  26. package/src/client/boot-loader.ts +3 -3
  27. package/src/client/i18n/currency.ts +42 -0
  28. package/src/client/i18n/define.ts +59 -0
  29. package/src/client/i18n/format.ts +12 -0
  30. package/src/client/i18n/index.ts +14 -0
  31. package/src/client/i18n/locale.ts +15 -0
  32. package/src/client/i18n/messages/audit.ts +42 -0
  33. package/src/client/i18n/messages/bundles.ts +459 -0
  34. package/src/client/i18n/messages/common.ts +147 -0
  35. package/src/client/i18n/messages/dashboard.ts +16 -0
  36. package/src/client/i18n/messages/discovery.ts +229 -0
  37. package/src/client/i18n/messages/email.ts +125 -0
  38. package/src/client/i18n/messages/marketing.ts +270 -0
  39. package/src/client/i18n/messages/nav.ts +72 -0
  40. package/src/client/i18n/messages/pilots.ts +192 -0
  41. package/src/client/i18n/messages/plan-detail.ts +266 -0
  42. package/src/client/i18n/messages/plan-editor.ts +177 -0
  43. package/src/client/i18n/messages/plan-versions.ts +251 -0
  44. package/src/client/i18n/messages/plans.ts +503 -0
  45. package/src/client/i18n/messages/promos.ts +202 -0
  46. package/src/client/i18n/messages/shell.ts +145 -0
  47. package/src/client/i18n/messages/tenants.ts +104 -0
  48. package/src/client/i18n/messages/users.ts +78 -0
  49. package/src/client/i18n/messages.ts +84 -0
  50. package/src/client/index.ts +2 -0
  51. package/src/client/manifest-loader.ts +4 -4
  52. package/src/client/nav-builder.ts +44 -51
  53. package/src/client/plan-versions-catalog.ts +42 -30
  54. package/src/components/BundleVersionPublishDialog.vue +35 -24
  55. package/src/components/MarketingPromotionsTab.vue +112 -59
  56. package/src/components/MfaPromptDialog.vue +11 -11
  57. package/src/components/TenantActionConfirmDialog.vue +19 -17
  58. package/src/components/VersionDiffPreview.vue +72 -43
  59. package/src/components/bundle-editor/BundleCreatePanel.vue +76 -63
  60. package/src/components/bundle-editor/BundleFeaturesEditor.vue +13 -6
  61. package/src/components/bundle-editor/BundlePlanCompatPicker.vue +19 -14
  62. package/src/components/bundle-editor/BundleQuotasEditor.vue +7 -4
  63. package/src/components/bundle-editor/BundleStatusBanner.vue +36 -19
  64. package/src/components/bundle-editor/BundleVersionInlineEditor.vue +51 -35
  65. package/src/components/bundle-editor/BundleVersionStrip.vue +24 -12
  66. package/src/components/bundle-editor/bundle-version-status.ts +29 -29
  67. package/src/components/dialogs/PilotCreateDialog.vue +58 -63
  68. package/src/components/dialogs/PilotEditDialog.vue +40 -34
  69. package/src/components/dialogs/PromoCodeCreateDialog.vue +89 -63
  70. package/src/components/dialogs/PromoCodeEditDialog.vue +98 -66
  71. package/src/components/dialogs/types.ts +3 -13
  72. package/src/components/plan/PlanCycleToggle.vue +20 -9
  73. package/src/components/plan-cockpit/PlanCockpit.vue +34 -15
  74. package/src/components/plan-cockpit/PlanCockpitAuditLog.vue +13 -6
  75. package/src/components/plan-cockpit/PlanCockpitDiffPanel.vue +18 -9
  76. package/src/components/plan-cockpit/PlanCockpitHeader.vue +9 -6
  77. package/src/components/plan-cockpit/PlanCockpitImpactPanel.vue +24 -11
  78. package/src/components/plan-cockpit/PlanCockpitKpis.vue +28 -17
  79. package/src/components/plan-cockpit/PlanCockpitVersions.vue +50 -25
  80. package/src/components/plan-create-dialog/PlanCreateDialog.vue +45 -35
  81. package/src/components/plan-detail/PlanAuditLog.vue +11 -6
  82. package/src/components/plan-detail/PlanDetail.vue +21 -23
  83. package/src/components/plan-detail/PlanDetailHeader.vue +20 -11
  84. package/src/components/plan-detail/PlanDetailKpis.vue +30 -17
  85. package/src/components/plan-detail/PlanTerminateDialog.vue +22 -9
  86. package/src/components/plan-detail/PlanVersionDiffPanel.vue +61 -27
  87. package/src/components/plan-detail/PlanVersionsPanel.vue +71 -36
  88. package/src/components/plan-list/PlanList.vue +99 -57
  89. package/src/components/plan-matrix/PlanMatrix.vue +85 -38
  90. package/src/components/plan-review/PlanReview.vue +105 -80
  91. package/src/components/plan-version-editor/PlanCatalogPreview.vue +43 -20
  92. package/src/components/plan-version-editor/PlanComponentPool.vue +15 -7
  93. package/src/components/plan-version-editor/PlanVersionBasket.vue +45 -24
  94. package/src/components/plan-version-editor/PlanVersionDiffDialog.vue +8 -7
  95. package/src/components/plan-version-editor/PlanVersionEditor.vue +74 -40
  96. package/src/components/plan-version-editor/PlanVersionEditorHeader.vue +24 -12
  97. package/src/index.ts +1 -1
  98. package/src/pages-standard/AdminLayout.vue +42 -17
  99. package/src/pages-standard/AdminManifestErrorPage.vue +10 -10
  100. package/src/pages-standard/AuditPage.vue +58 -19
  101. package/src/pages-standard/BundlesPage.vue +29 -18
  102. package/src/pages-standard/DashboardPage.vue +29 -15
  103. package/src/pages-standard/DiscoveryPage.vue +40 -28
  104. package/src/pages-standard/EmailHistoryPage.vue +92 -59
  105. package/src/pages-standard/MarketingCatalogPage.vue +35 -16
  106. package/src/pages-standard/PilotsPage.vue +57 -41
  107. package/src/pages-standard/PlanVersionsPage.vue +7 -3
  108. package/src/pages-standard/PlansPage.vue +89 -57
  109. package/src/pages-standard/PlatformEmailPage.vue +115 -50
  110. package/src/pages-standard/PromoCodeDetailPage.vue +66 -63
  111. package/src/pages-standard/PromoCodesPage.vue +46 -35
  112. package/src/pages-standard/SubscriptionsPage.vue +14 -9
  113. package/src/pages-standard/SuperAdminLoginPage.vue +16 -13
  114. package/src/pages-standard/SuperAdminSetupWizard.vue +51 -47
  115. package/src/pages-standard/TenantDetailPage.vue +50 -36
  116. package/src/pages-standard/TenantsPage.vue +54 -41
  117. package/src/pages-standard/UsersPage.vue +66 -42
  118. package/src/pages-standard/bundles-page/BundleAccordionList.vue +20 -8
  119. package/src/pages-standard/bundles-page/BundleDetailPanel.vue +28 -18
  120. package/src/pages-standard/bundles-page/BundlesFilterBar.vue +4 -1
  121. package/src/pages-standard/bundles-page/BundlesHeader.vue +9 -8
  122. package/src/pages-standard/bundles-page/BundlesKpis.vue +29 -11
  123. package/src/pages-standard/discovery-page/CatalogEntryTransPanel.vue +20 -8
  124. package/src/pages-standard/discovery-page/DiscoveryCapList.vue +5 -3
  125. package/src/pages-standard/discovery-page/DiscoveryFeatureCard.vue +43 -24
  126. package/src/pages-standard/discovery-page/DiscoveryHeader.vue +7 -4
  127. package/src/pages-standard/discovery-page/DiscoveryKpis.vue +28 -15
  128. package/src/pages-standard/discovery-page/DiscoveryQuotaCard.vue +20 -10
  129. package/src/pages-standard/discovery-page/DiscoveryStatusControl.vue +9 -6
  130. package/src/pages-standard/discovery-page/discovery-ui.ts +40 -52
  131. package/src/pages-standard/marketing-catalog/MarketingCatalogAdmin.vue +81 -49
  132. package/src/pages-standard/marketing-catalog/MarketingCatalogHeader.vue +13 -10
  133. package/src/pages-standard/marketing-catalog/MarketingCatalogPreview.vue +24 -20
  134. package/src/pages-standard/marketing-catalog/MarketingCatalogToolbar.vue +6 -3
  135. package/src/pages-standard/plan-versions/PlanDiffCard.vue +16 -6
  136. package/src/pages-standard/plan-versions/PlanVersionHeader.vue +41 -25
  137. package/src/pages-standard/plan-versions/PlanVersionsAudit.vue +45 -26
  138. package/src/pages-standard/plan-versions/PlanVersionsDiff.vue +7 -5
  139. package/src/pages-standard/plan-versions/PlanVersionsList.vue +39 -16
  140. package/src/pages-standard/plan-versions/PlanVersionsTimeline.vue +24 -12
  141. package/src/pages-standard/plan-versions/format.ts +33 -17
  142. package/src/pages-standard/plans-page/PlanArchiveDialog.vue +12 -8
  143. package/src/pages-standard/plans-page/PlanBundleOverview.vue +15 -6
  144. package/src/pages-standard/plans-page/PlanDiscardDraftDialog.vue +18 -7
  145. package/src/pages-standard/plans-page/PlanPublishDialog.vue +23 -12
  146. package/src/pages-standard/tenants/format.ts +3 -2
  147. package/src/pages-tenant/MySubscriptionBundlesPage.vue +72 -37
  148. package/src/pages-tenant/PlanChangeWizard.vue +8 -4
  149. package/src/pages-tenant/TenantPlanSection.vue +17 -13
  150. package/src/pages-tenant/default-i18n.ts +217 -1
  151. package/src/pages-tenant/tenant-plan-section/BundlePreviewDialog.vue +8 -6
  152. package/src/pages-tenant/tenant-plan-section/TenantBundleStore.vue +9 -10
  153. package/src/pages-tenant/tenant-plan-section/TenantFeatureMatrix.vue +4 -1
  154. package/src/quasar/create-super-admin-app.ts +19 -0
  155. package/src/testing-e2e/admin-pages-suite.ts +14 -11
  156. package/src/vue/project-page-host.ts +5 -3
  157. package/src/vue/use-audit-entries.ts +3 -3
  158. package/src/vue/use-bulk-publish.ts +6 -4
  159. package/src/vue/use-bundle-versions-map.ts +6 -4
  160. package/src/vue/use-bundles.ts +13 -13
  161. package/src/vue/use-catalog-entries.ts +13 -10
  162. package/src/vue/use-discovery.ts +8 -5
  163. package/src/vue/use-entitlement.ts +3 -3
  164. package/src/vue/use-live-plan-versions.ts +4 -4
  165. package/src/vue/use-marketing-projections.ts +9 -6
  166. package/src/vue/use-nav.ts +8 -2
  167. package/src/vue/use-plan-editor.ts +2 -2
  168. package/src/vue/use-plan-versions.ts +3 -3
  169. package/src/vue/use-plans.ts +12 -12
  170. package/src/vue/use-platform-tenant-actions.ts +9 -6
  171. package/src/vue/use-promotions.ts +9 -10
  172. package/src/vue/use-subscription-draft.ts +2 -3
  173. package/src/vue/use-super-admin-context.ts +3 -3
  174. package/src/vue/use-super-admin-i18n.ts +82 -0
  175. package/src/vue/use-tenant-action-flow.ts +11 -6
  176. package/src/vue/use-tenant-manifest.ts +1 -3
  177. package/src/vue/use-tenant-subscription-bundles.ts +4 -4
  178. package/src/vue/use-tenants.ts +3 -3
  179. package/dist/action-registry-CQ2wL3R-.d.cts +0 -85
  180. package/dist/action-registry-CQ2wL3R-.d.ts +0 -85
  181. package/dist/chunk-LVGUSD3T.js +0 -26
  182. package/src/components/BusinessTypeVersionEditorDialog.vue +0 -417
  183. package/src/components/BusinessTypeVersionPublishDialog.vue +0 -258
  184. package/src/pages-standard/BusinessTypesPage.vue +0 -662
  185. package/src/pages-standard/plan-versions/VersionDiffPreview.vue +0 -167
  186. package/src/vue/use-business-types.ts +0 -269
@@ -14,7 +14,9 @@
14
14
  import { computed, type ComputedRef, type Ref } from 'vue';
15
15
  import type { AdminManifest, TenantActionDef, TenantDto } from '@saasicat/types';
16
16
  import { ActionRegistry } from '../client/action-registry.js';
17
+ import { formatMessage } from '../client/i18n/format.js';
17
18
  import { useSuperAdminActions } from './use-super-admin-context.js';
19
+ import { useSaMessages } from './use-super-admin-i18n.js';
18
20
 
19
21
  /**
20
22
  * Input the app-side handler receives. `mfaCode` is populated when
@@ -125,6 +127,7 @@ export function useTenantActionFlow<TRow extends TenantDto = TenantDto>(
125
127
  providers: TenantActionFlowProviders<TRow> = {},
126
128
  ): UseTenantActionFlowResult<TRow> {
127
129
  const handlers = useSuperAdminActions();
130
+ const msg = useSaMessages('tenants');
128
131
  const registry = computed<ActionRegistry | null>(() => {
129
132
  if (!manifest.value) return null;
130
133
  return new ActionRegistry(manifest.value, handlers);
@@ -151,7 +154,8 @@ export function useTenantActionFlow<TRow extends TenantDto = TenantDto>(
151
154
  .filter((def) => !providers.visibleForRow || providers.visibleForRow(def, row))
152
155
  .map((def) => ({
153
156
  def,
154
- invoke: (r: TRow) => runFlow(def, r ?? row, reg, providers),
157
+ invoke: (r: TRow) =>
158
+ runFlow(def, r ?? row, reg, providers, msg.value.actions.successNotify),
155
159
  }));
156
160
  }
157
161
 
@@ -184,6 +188,7 @@ async function runFlow<TRow extends TenantDto>(
184
188
  row: TRow,
185
189
  registry: ActionRegistry,
186
190
  providers: TenantActionFlowProviders<TRow>,
191
+ successTemplate: string,
187
192
  ): Promise<unknown> {
188
193
  let reason: string | null = null;
189
194
  let extras: Record<string, unknown> = {};
@@ -191,8 +196,8 @@ async function runFlow<TRow extends TenantDto>(
191
196
  if (def.confirmType && def.confirmType !== 'none') {
192
197
  if (!providers.confirm) {
193
198
  throw new Error(
194
- `useTenantActionFlow: Action "${def.id}" verlangt confirmType="${def.confirmType}", ` +
195
- `aber kein \`confirm\`-Provider übergeben.`,
199
+ `useTenantActionFlow: action "${def.id}" requires confirmType="${def.confirmType}", ` +
200
+ `but no \`confirm\` provider was supplied.`,
196
201
  );
197
202
  }
198
203
  const c = await providers.confirm(def, { row });
@@ -205,8 +210,8 @@ async function runFlow<TRow extends TenantDto>(
205
210
  if (def.requiresMfa) {
206
211
  if (!providers.mfa) {
207
212
  throw new Error(
208
- `useTenantActionFlow: Action "${def.id}" verlangt MFA, aber kein ` +
209
- `\`mfa\`-Provider übergeben.`,
213
+ `useTenantActionFlow: action "${def.id}" requires MFA, but no ` +
214
+ `\`mfa\` provider was supplied.`,
210
215
  );
211
216
  }
212
217
  mfaCode = await providers.mfa(def, { row });
@@ -225,7 +230,7 @@ async function runFlow<TRow extends TenantDto>(
225
230
  try {
226
231
  const input: TenantActionInput<TRow> = { row, mfaCode, reason, extras };
227
232
  const result = await resolved.handler(input);
228
- providers.notify?.('positive', `${def.label}: erfolgreich.`);
233
+ providers.notify?.('positive', formatMessage(successTemplate, { action: def.label }));
229
234
  providers.onSuccess?.(def, { row });
230
235
  return result;
231
236
  } catch (err) {
@@ -48,9 +48,7 @@ export interface UseTenantManifestResult {
48
48
 
49
49
  export function useTenantManifest(options: UseTenantManifestOptions): UseTenantManifestResult {
50
50
  if (!options?.endpoint) {
51
- throw new Error(
52
- 'useTenantManifest: `endpoint` ist Pflicht (z. B. "/api/tenant/manifest").',
53
- );
51
+ throw new Error('useTenantManifest: `endpoint` is required (e.g. "/api/tenant/manifest").');
54
52
  }
55
53
  const http = options.http ?? defaultHttpClient();
56
54
  const manifest = ref<TenantManifestShape | null>(null);
@@ -48,7 +48,7 @@ export function useTenantSubscriptionBundles(
48
48
  ): UseTenantSubscriptionBundlesResult {
49
49
  if (!options?.billingEndpoint) {
50
50
  throw new Error(
51
- 'useTenantSubscriptionBundles: `billingEndpoint` ist Pflicht (z. B. "/api/v1").',
51
+ 'useTenantSubscriptionBundles: `billingEndpoint` is required (e.g. "/api/v1").',
52
52
  );
53
53
  }
54
54
  const http = options.http ?? defaultHttpClient();
@@ -75,7 +75,7 @@ export function useTenantSubscriptionBundles(
75
75
  throw new TenantSubscriptionBundlesApiError(
76
76
  res.status,
77
77
  body,
78
- `SubscriptionBundle-API antwortete mit HTTP ${res.status}`,
78
+ `SubscriptionBundle API responded with HTTP ${res.status}`,
79
79
  );
80
80
  }
81
81
  return body as T;
@@ -103,7 +103,7 @@ export function useTenantSubscriptionBundles(
103
103
  body: JSON.stringify(data),
104
104
  });
105
105
  if (!result) {
106
- throw new TenantSubscriptionBundlesApiError(0, null, 'add gab keinen Body zurück');
106
+ throw new TenantSubscriptionBundlesApiError(0, null, 'add returned no body');
107
107
  }
108
108
  const hydrated = rehydrateDates(result);
109
109
  bundles.value = [hydrated, ...bundles.value];
@@ -119,7 +119,7 @@ export function useTenantSubscriptionBundles(
119
119
  { method: 'DELETE', body: JSON.stringify(opts) },
120
120
  );
121
121
  if (!result) {
122
- throw new TenantSubscriptionBundlesApiError(0, null, 'cancel gab keinen Body zurück');
122
+ throw new TenantSubscriptionBundlesApiError(0, null, 'cancel returned no body');
123
123
  }
124
124
  const hydrated = rehydrateDates(result);
125
125
  bundles.value = bundles.value.map((b) => (b.id === subscriptionBundleId ? hydrated : b));
@@ -44,9 +44,9 @@ export function useTenants<T extends TenantDto = TenantDto>(
44
44
  ): UseTenantsResult<T> {
45
45
  if (!options?.endpoint) {
46
46
  throw new Error(
47
- 'useTenants: `endpoint` ist Pflicht (z. B. "/api/v1/admin/tenants" oder ' +
48
- '"/api/admin/tenants"). Plattform hat keinen Default, weil Apps ' +
49
- 'unterschiedliche globalPrefix-Konventionen haben.',
47
+ 'useTenants: `endpoint` is required (e.g. "/api/v1/admin/tenants" or ' +
48
+ '"/api/admin/tenants"). The platform has no default because apps ' +
49
+ 'use different globalPrefix conventions.',
50
50
  );
51
51
  }
52
52
  const filter = options.filter ?? ref<TenantListFilter>({});
@@ -1,85 +0,0 @@
1
- import { AdminManifest, TenantActionDef } from '@saasicat/types';
2
-
3
- /**
4
- * Minimal abstraction over `fetch`. Consumers may pass their own
5
- * implementation (e.g. an axios wrapper that already injects auth headers
6
- * and tenant headers).
7
- */
8
- type HttpClient = (url: string, init?: {
9
- method?: string;
10
- headers?: Record<string, string>;
11
- body?: string;
12
- }) => Promise<HttpResponse>;
13
- interface HttpResponse {
14
- status: number;
15
- headers: {
16
- get(name: string): string | null;
17
- };
18
- json(): Promise<unknown>;
19
- text(): Promise<string>;
20
- }
21
- /** Simple persistence adapter; default is `localStorage`. */
22
- interface KvStore {
23
- get(key: string): string | null;
24
- set(key: string, value: string): void;
25
- remove(key: string): void;
26
- }
27
- /**
28
- * Returns a `KvStore` wrapper around `localStorage` (or `null` under SSR).
29
- * Tests may pass an in-memory stub.
30
- */
31
- declare function defaultKvStore(): KvStore;
32
- /**
33
- * Default `HttpClient` over `fetch`. Consumers pass their own variant
34
- * through when they need auth headers / tenant headers / retry logic.
35
- */
36
- declare function defaultHttpClient(): HttpClient;
37
-
38
- /** Consumer implementation; receives the action inputs as a generic object. */
39
- type ActionHandler<TInput = unknown, TResult = unknown> = (input: TInput) => Promise<TResult>;
40
- interface ResolvedAction<TInput = unknown, TResult = unknown> {
41
- def: TenantActionDef;
42
- handler: ActionHandler<TInput, TResult>;
43
- }
44
- declare class MissingHandlerError extends Error {
45
- constructor(actionKey: string);
46
- }
47
- declare class ActionDefNotInManifestError extends Error {
48
- constructor(actionKey: string);
49
- }
50
- declare class ActionRegistry {
51
- private readonly defs;
52
- private readonly handlers;
53
- constructor(manifest: AdminManifest, handlers?: Record<string, ActionHandler>);
54
- /**
55
- * Registers a handler after the fact (e.g. when consumer code loads
56
- * lazily). Throws `ActionDefNotInManifestError` if the `actionKey` is not
57
- * declared in the manifest — prevents dead registrations.
58
- */
59
- register<TInput, TResult>(actionKey: string, handler: ActionHandler<TInput, TResult>): void;
60
- /**
61
- * Returns the `{def, handler}` pair. Throws if the key is missing from
62
- * the manifest or no handler is registered. The shell's UI layer calls
63
- * the method, checks `def.requiresMfa` / `def.confirmType` for the
64
- * pre-flow, and then calls `handler(input)`.
65
- */
66
- get<TInput = unknown, TResult = unknown>(actionKey: string): ResolvedAction<TInput, TResult>;
67
- /**
68
- * Convenience: `get(key).handler(input)`. UI convenience for actions
69
- * that need neither MFA nor confirm.
70
- */
71
- dispatch<TInput, TResult>(actionKey: string, input: TInput): Promise<TResult>;
72
- /**
73
- * List of actionKeys that are declared in the manifest but have no
74
- * handler. Consumers use this in a doctor check to detect drift between
75
- * the manifest and the shell build.
76
- */
77
- listOrphanedDefs(): string[];
78
- /**
79
- * List of registered handlers that are missing from the manifest. Drift
80
- * in the other direction.
81
- */
82
- listOrphanedHandlers(): string[];
83
- }
84
-
85
- export { type ActionHandler as A, type HttpClient as H, type KvStore as K, MissingHandlerError as M, type ResolvedAction as R, ActionRegistry as a, ActionDefNotInManifestError as b, type HttpResponse as c, defaultHttpClient as d, defaultKvStore as e };
@@ -1,85 +0,0 @@
1
- import { AdminManifest, TenantActionDef } from '@saasicat/types';
2
-
3
- /**
4
- * Minimal abstraction over `fetch`. Consumers may pass their own
5
- * implementation (e.g. an axios wrapper that already injects auth headers
6
- * and tenant headers).
7
- */
8
- type HttpClient = (url: string, init?: {
9
- method?: string;
10
- headers?: Record<string, string>;
11
- body?: string;
12
- }) => Promise<HttpResponse>;
13
- interface HttpResponse {
14
- status: number;
15
- headers: {
16
- get(name: string): string | null;
17
- };
18
- json(): Promise<unknown>;
19
- text(): Promise<string>;
20
- }
21
- /** Simple persistence adapter; default is `localStorage`. */
22
- interface KvStore {
23
- get(key: string): string | null;
24
- set(key: string, value: string): void;
25
- remove(key: string): void;
26
- }
27
- /**
28
- * Returns a `KvStore` wrapper around `localStorage` (or `null` under SSR).
29
- * Tests may pass an in-memory stub.
30
- */
31
- declare function defaultKvStore(): KvStore;
32
- /**
33
- * Default `HttpClient` over `fetch`. Consumers pass their own variant
34
- * through when they need auth headers / tenant headers / retry logic.
35
- */
36
- declare function defaultHttpClient(): HttpClient;
37
-
38
- /** Consumer implementation; receives the action inputs as a generic object. */
39
- type ActionHandler<TInput = unknown, TResult = unknown> = (input: TInput) => Promise<TResult>;
40
- interface ResolvedAction<TInput = unknown, TResult = unknown> {
41
- def: TenantActionDef;
42
- handler: ActionHandler<TInput, TResult>;
43
- }
44
- declare class MissingHandlerError extends Error {
45
- constructor(actionKey: string);
46
- }
47
- declare class ActionDefNotInManifestError extends Error {
48
- constructor(actionKey: string);
49
- }
50
- declare class ActionRegistry {
51
- private readonly defs;
52
- private readonly handlers;
53
- constructor(manifest: AdminManifest, handlers?: Record<string, ActionHandler>);
54
- /**
55
- * Registers a handler after the fact (e.g. when consumer code loads
56
- * lazily). Throws `ActionDefNotInManifestError` if the `actionKey` is not
57
- * declared in the manifest — prevents dead registrations.
58
- */
59
- register<TInput, TResult>(actionKey: string, handler: ActionHandler<TInput, TResult>): void;
60
- /**
61
- * Returns the `{def, handler}` pair. Throws if the key is missing from
62
- * the manifest or no handler is registered. The shell's UI layer calls
63
- * the method, checks `def.requiresMfa` / `def.confirmType` for the
64
- * pre-flow, and then calls `handler(input)`.
65
- */
66
- get<TInput = unknown, TResult = unknown>(actionKey: string): ResolvedAction<TInput, TResult>;
67
- /**
68
- * Convenience: `get(key).handler(input)`. UI convenience for actions
69
- * that need neither MFA nor confirm.
70
- */
71
- dispatch<TInput, TResult>(actionKey: string, input: TInput): Promise<TResult>;
72
- /**
73
- * List of actionKeys that are declared in the manifest but have no
74
- * handler. Consumers use this in a doctor check to detect drift between
75
- * the manifest and the shell build.
76
- */
77
- listOrphanedDefs(): string[];
78
- /**
79
- * List of registered handlers that are missing from the manifest. Drift
80
- * in the other direction.
81
- */
82
- listOrphanedHandlers(): string[];
83
- }
84
-
85
- export { type ActionHandler as A, type HttpClient as H, type KvStore as K, MissingHandlerError as M, type ResolvedAction as R, ActionRegistry as a, ActionDefNotInManifestError as b, type HttpResponse as c, defaultHttpClient as d, defaultKvStore as e };
@@ -1,26 +0,0 @@
1
- // src/client/types.ts
2
- function defaultKvStore() {
3
- if (typeof globalThis.localStorage === "undefined") {
4
- return {
5
- get: () => null,
6
- set: () => {
7
- },
8
- remove: () => {
9
- }
10
- };
11
- }
12
- const ls = globalThis.localStorage;
13
- return {
14
- get: (k) => ls.getItem(k),
15
- set: (k, v) => ls.setItem(k, v),
16
- remove: (k) => ls.removeItem(k)
17
- };
18
- }
19
- function defaultHttpClient() {
20
- return (url, init) => fetch(url, init);
21
- }
22
-
23
- export {
24
- defaultKvStore,
25
- defaultHttpClient
26
- };