@saasicat/ui-vue 0.3.0 → 0.5.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 (109) hide show
  1. package/README.md +47 -4
  2. package/dist/action-registry-CQ2wL3R-.d.cts +85 -0
  3. package/dist/action-registry-CQ2wL3R-.d.ts +85 -0
  4. package/dist/chunk-3YP2ZAOD.js +63 -0
  5. package/dist/chunk-EH7TOD4H.js +718 -0
  6. package/dist/chunk-LVGUSD3T.js +26 -0
  7. package/dist/client/index.cjs +785 -0
  8. package/dist/client/index.d.cts +295 -0
  9. package/dist/client/index.d.ts +295 -0
  10. package/dist/client/index.js +52 -0
  11. package/dist/index.cjs +787 -834
  12. package/dist/index.d.cts +267 -841
  13. package/dist/index.d.ts +267 -841
  14. package/dist/index.js +284 -1059
  15. package/dist/quasar/index.cjs +159 -0
  16. package/dist/quasar/index.d.cts +86 -0
  17. package/dist/quasar/index.d.ts +86 -0
  18. package/dist/quasar/index.js +91 -0
  19. package/dist/ui-notify-COUzXEQ4.d.ts +178 -0
  20. package/dist/ui-notify-D_eAAwRh.d.cts +178 -0
  21. package/package.json +23 -3
  22. package/src/client/index.ts +25 -0
  23. package/src/components/FeatureGate.vue +1 -1
  24. package/src/components/plan/PlanCycleToggle.vue +1 -1
  25. package/src/components/plan/PlanGrid.vue +2 -2
  26. package/src/components/plan/PriceSummary.vue +1 -1
  27. package/src/components/plan/PromoCodeInput.vue +1 -1
  28. package/src/components/plan/PublicBundleGrid.vue +1 -1
  29. package/src/index.ts +82 -79
  30. package/src/pages-standard/AdminLayout.vue +2 -2
  31. package/src/pages-standard/DashboardPage.vue +2 -2
  32. package/src/pages-standard/EmailHistoryPage.vue +9 -13
  33. package/src/pages-standard/MarketingCatalogPage.vue +5 -5
  34. package/src/pages-standard/PilotsPage.vue +9 -13
  35. package/src/pages-standard/PlanVersionsPage.vue +2 -2
  36. package/src/pages-standard/PlansPage.vue +2 -2
  37. package/src/pages-standard/PlatformEmailPage.vue +7 -5
  38. package/src/pages-standard/PromoCodesPage.vue +8 -22
  39. package/src/pages-standard/SuperAdminLoginPage.vue +3 -3
  40. package/src/pages-standard/SuperAdminSetupWizard.vue +2 -2
  41. package/src/pages-standard/TenantDetailPage.vue +4 -4
  42. package/src/pages-standard/TenantsPage.vue +3 -3
  43. package/src/pages-standard/UsersPage.vue +6 -12
  44. package/src/pages-standard/plan-versions/PlanVersionHeader.vue +1 -1
  45. package/src/pages-standard/plan-versions/PlanVersionsAudit.vue +1 -1
  46. package/src/pages-standard/plan-versions/PlanVersionsDiff.vue +1 -1
  47. package/src/pages-standard/plan-versions/PlanVersionsList.vue +1 -1
  48. package/src/pages-standard/plan-versions/PlanVersionsMatrix.vue +1 -1
  49. package/src/pages-standard/plan-versions/PlanVersionsTimeline.vue +1 -1
  50. package/src/pages-tenant/MySubscriptionBundlesPage.vue +1 -1
  51. package/src/pages-tenant/OnboardingConfigurator.vue +3 -3
  52. package/src/pages-tenant/PackageSnapshotPanel.vue +1 -1
  53. package/src/pages-tenant/PlanChangeWizard.vue +2 -2
  54. package/src/pages-tenant/TenantPlanSection.vue +3 -3
  55. package/src/pages-tenant/tenant-plan-section/BundlePreviewDialog.vue +1 -1
  56. package/src/pages-tenant/tenant-plan-section/TenantBundleStore.vue +2 -2
  57. package/src/pages-tenant/tenant-plan-section/TenantPlanCardHeader.vue +1 -1
  58. package/src/pages-tenant/tenant-plan-section/TenantUsageGrid.vue +1 -1
  59. package/src/quasar/create-super-admin-app.ts +173 -0
  60. package/src/quasar/index.ts +11 -0
  61. package/src/quasar/notify.ts +30 -0
  62. package/src/{manifest-store-factory.ts → vue/manifest-store-factory.ts} +1 -1
  63. package/src/{platform-loaders.ts → vue/platform-loaders.ts} +4 -4
  64. package/src/{project-page-host.ts → vue/project-page-host.ts} +1 -1
  65. package/src/{create-super-admin-app.ts → vue/super-admin-context.ts} +20 -139
  66. package/src/vue/ui-notify.ts +30 -0
  67. package/src/{use-actions.ts → vue/use-actions.ts} +1 -1
  68. package/src/{use-api-list.ts → vue/use-api-list.ts} +1 -1
  69. package/src/{use-batch-columns.ts → vue/use-batch-columns.ts} +1 -1
  70. package/src/{use-bulk-publish.ts → vue/use-bulk-publish.ts} +1 -1
  71. package/src/{use-bundle-versions-map.ts → vue/use-bundle-versions-map.ts} +1 -1
  72. package/src/{use-bundles.ts → vue/use-bundles.ts} +1 -1
  73. package/src/{use-business-types.ts → vue/use-business-types.ts} +1 -1
  74. package/src/{use-catalog-entries.ts → vue/use-catalog-entries.ts} +1 -1
  75. package/src/{use-discovery.ts → vue/use-discovery.ts} +1 -1
  76. package/src/{use-entitlement.ts → vue/use-entitlement.ts} +1 -1
  77. package/src/{use-live-plan-versions.ts → vue/use-live-plan-versions.ts} +1 -1
  78. package/src/{use-manifest.ts → vue/use-manifest.ts} +1 -1
  79. package/src/{use-marketing-projections.ts → vue/use-marketing-projections.ts} +1 -1
  80. package/src/{use-nav.ts → vue/use-nav.ts} +1 -1
  81. package/src/{use-plans.ts → vue/use-plans.ts} +1 -1
  82. package/src/{use-promotions.ts → vue/use-promotions.ts} +1 -1
  83. package/src/{use-public-boot.ts → vue/use-public-boot.ts} +1 -1
  84. package/src/{use-super-admin-context.ts → vue/use-super-admin-context.ts} +2 -2
  85. package/src/{use-tenant-action-flow.ts → vue/use-tenant-action-flow.ts} +1 -1
  86. package/src/{use-tenant-billing-catalog.ts → vue/use-tenant-billing-catalog.ts} +2 -2
  87. package/src/{use-tenant-billing.ts → vue/use-tenant-billing.ts} +2 -2
  88. package/src/{use-tenant-manifest.ts → vue/use-tenant-manifest.ts} +1 -1
  89. package/src/{use-tenant-subscription-bundles.ts → vue/use-tenant-subscription-bundles.ts} +1 -1
  90. package/dist/testing-e2e/admin-pages-suite.d.cts +0 -37
  91. package/dist/testing-e2e/admin-pages-suite.d.ts +0 -37
  92. /package/src/{action-registry.ts → client/action-registry.ts} +0 -0
  93. /package/src/{batch-column-fetcher.ts → client/batch-column-fetcher.ts} +0 -0
  94. /package/src/{boot-loader.ts → client/boot-loader.ts} +0 -0
  95. /package/src/{http-json.ts → client/http-json.ts} +0 -0
  96. /package/src/{manifest-loader.ts → client/manifest-loader.ts} +0 -0
  97. /package/src/{nav-builder.ts → client/nav-builder.ts} +0 -0
  98. /package/src/{plan-versions-catalog.ts → client/plan-versions-catalog.ts} +0 -0
  99. /package/src/{types.ts → client/types.ts} +0 -0
  100. /package/src/{version.ts → client/version.ts} +0 -0
  101. /package/src/{create-admin-routes.ts → vue/create-admin-routes.ts} +0 -0
  102. /package/src/{entitlement-provider.ts → vue/entitlement-provider.ts} +0 -0
  103. /package/src/{feature-router-guard.ts → vue/feature-router-guard.ts} +0 -0
  104. /package/src/{use-audit-entries.ts → vue/use-audit-entries.ts} +0 -0
  105. /package/src/{use-plan-editor.ts → vue/use-plan-editor.ts} +0 -0
  106. /package/src/{use-plan-versions.ts → vue/use-plan-versions.ts} +0 -0
  107. /package/src/{use-platform-tenant-actions.ts → vue/use-platform-tenant-actions.ts} +0 -0
  108. /package/src/{use-subscription-draft.ts → vue/use-subscription-draft.ts} +0 -0
  109. /package/src/{use-tenants.ts → vue/use-tenants.ts} +0 -0
@@ -0,0 +1,295 @@
1
+ import { H as HttpClient, K as KvStore } from '../action-registry-CQ2wL3R-.cjs';
2
+ export { b as ActionDefNotInManifestError, A as ActionHandler, a as ActionRegistry, c as HttpResponse, M as MissingHandlerError, R as ResolvedAction, d as defaultHttpClient, e as defaultKvStore } from '../action-registry-CQ2wL3R-.cjs';
3
+ import { PublicBootResponse, AdminManifest, StandardPageKey, TenantColumnDef, PlanVersionRow } from '@saasicat/types';
4
+
5
+ declare const ADMIN_UI_VERSION = "1.2.0";
6
+
7
+ /**
8
+ * Error for non-2xx responses. `code` is the machine-readable error code
9
+ * from the JSON body (`{ code }`), if present — callers map it to
10
+ * a message (e.g. via `SETUP_ERROR_CODES`).
11
+ */
12
+ declare class HttpJsonError extends Error {
13
+ readonly status: number;
14
+ readonly code?: string | undefined;
15
+ constructor(status: number, code?: string | undefined);
16
+ }
17
+ /**
18
+ * Removes trailing slashes so an API prefix can be concatenated with paths
19
+ * that start with `/`. Deliberately index-based instead of
20
+ * `replace(/\/+$/, '')`: the regex backtracks quadratically on inputs that
21
+ * end in many slashes.
22
+ */
23
+ declare function trimTrailingSlashes(url: string): string;
24
+ declare function getJson<T>(http: HttpClient, url: string): Promise<T>;
25
+ declare function postJson<T>(http: HttpClient, url: string, body: unknown): Promise<T>;
26
+
27
+ interface BootLoaderOptions {
28
+ /**
29
+ * Fully-qualified boot endpoint incl. app globalPrefix
30
+ * (`/api/admin/boot`, `/api/v1/admin/boot`, …). Mandatory.
31
+ */
32
+ endpoint: string;
33
+ /** Defaults to `defaultHttpClient()` (= `fetch`). */
34
+ http?: HttpClient;
35
+ }
36
+ declare class BootLoadError extends Error {
37
+ readonly status: number;
38
+ constructor(status: number, message: string);
39
+ }
40
+ declare class BootLoader {
41
+ private readonly endpoint;
42
+ private readonly http;
43
+ constructor(options: BootLoaderOptions);
44
+ load(): Promise<PublicBootResponse>;
45
+ }
46
+
47
+ interface ManifestLoaderOptions {
48
+ /**
49
+ * Fully-qualified manifest endpoint incl. app globalPrefix
50
+ * (`/api/admin/manifest`, `/api/v1/admin/manifest`, …). Mandatory.
51
+ */
52
+ endpoint: string;
53
+ http?: HttpClient;
54
+ storage?: KvStore;
55
+ /**
56
+ * Storage key prefix — consumers with multiple apps under one domain
57
+ * set this to e.g. `'ma:'` or `'da:'`, so that the caches
58
+ * are separated.
59
+ */
60
+ storageKeyPrefix?: string;
61
+ /**
62
+ * Auth header for `Authorization: Bearer <token>`. Sent with every
63
+ * request. The consumer supplies a function that pulls the
64
+ * current token from the auth store.
65
+ */
66
+ getAuthToken?: () => string | null;
67
+ }
68
+ declare class ManifestLoadError extends Error {
69
+ readonly status: number;
70
+ constructor(status: number, message: string);
71
+ }
72
+ interface CachedManifestEntry {
73
+ etag: string;
74
+ body: AdminManifest;
75
+ }
76
+ declare class ManifestLoader {
77
+ private readonly endpoint;
78
+ private readonly http;
79
+ private readonly storage;
80
+ private readonly bodyKey;
81
+ private readonly etagKey;
82
+ private readonly getAuthToken?;
83
+ constructor(options: ManifestLoaderOptions);
84
+ /**
85
+ * Loads the current manifest. On a cache hit (304) the cached
86
+ * body is returned — otherwise the fresh server body.
87
+ */
88
+ load(): Promise<AdminManifest>;
89
+ /** Reads the cached manifest body from storage; null if absent. */
90
+ readCachedBody(): CachedManifestEntry | null;
91
+ /** Clears the cache — e.g. on logout or after `manifest reload`. */
92
+ clearCache(): void;
93
+ }
94
+
95
+ /**
96
+ * Default routes for the platform standard pages. Consumers may override this
97
+ * via the `standardPageRoutes` option (e.g. `/admin/users` →
98
+ * `/admin/team`).
99
+ */
100
+ declare const DEFAULT_STANDARD_PAGE_ROUTES: Record<StandardPageKey, string>;
101
+ interface BuildRouteEntry {
102
+ /** Stable identifier — the key for standard pages, the `id` for project pages. */
103
+ id: string;
104
+ /** Route path (`/admin/...`). */
105
+ path: string;
106
+ /** Visible for the UI. */
107
+ label: string;
108
+ icon?: string;
109
+ /** Sort key for drawer groups. */
110
+ navSection?: string;
111
+ /** Lookup key in the `extensions:` map (project) or the platform standard map. */
112
+ componentKey: string;
113
+ /** Required capability or null. */
114
+ requiredCapability: string | null;
115
+ /** Platform standard page (`true`) or project page (`false`). */
116
+ isStandard: boolean;
117
+ /** Hint for anticipatory lazy loading. */
118
+ prefetchOnIdle?: boolean;
119
+ }
120
+ interface NavBuilderOptions {
121
+ /**
122
+ * Optional: overrides the default routes for certain standard pages.
123
+ * Consumers set this if they want an alternative URL structure.
124
+ */
125
+ standardPageRoutes?: Partial<Record<StandardPageKey, string>>;
126
+ /**
127
+ * Default labels for standard pages — consumers may localize.
128
+ */
129
+ standardPageLabels?: Partial<Record<StandardPageKey, string>>;
130
+ /** Default icons for standard pages. */
131
+ standardPageIcons?: Partial<Record<StandardPageKey, string>>;
132
+ /** Default `navSection` for standard pages. */
133
+ standardPageNavSection?: Partial<Record<StandardPageKey, string>>;
134
+ /**
135
+ * Optional: set of known `componentKey`s from the shell's `extensions:`
136
+ * map. ProjectPages whose `componentKey` is not contained here
137
+ * are filtered out — they would otherwise appear in the sidebar but on
138
+ * click be redirected by the catch-all (silent dead link).
139
+ * Consumers without an `extensions:` map omit the field → as before.
140
+ */
141
+ availableExtensions?: Set<string>;
142
+ }
143
+ declare const DEFAULT_SECTION_ORDER: readonly string[];
144
+ /**
145
+ * Returns the list of all routes defined by the current manifest —
146
+ * filtered to the capabilities that the logged-in user has.
147
+ *
148
+ * The consumer shell then builds its Vue router configuration and its
149
+ * sidebar drawer from it.
150
+ */
151
+ declare function buildRoutes(manifest: AdminManifest, options?: NavBuilderOptions): BuildRouteEntry[];
152
+ interface SidebarItem {
153
+ id: string;
154
+ path: string;
155
+ label: string;
156
+ icon?: string;
157
+ }
158
+ interface SidebarSection {
159
+ /** `null` for the default section (items without `navSection`). */
160
+ section: string | null;
161
+ items: SidebarItem[];
162
+ }
163
+ /**
164
+ * Groups the routes by `navSection` for the drawer.
165
+ *
166
+ * Section order:
167
+ * 1. Default section (`null`) — items without `navSection`.
168
+ * 2. Sections from `sectionOrder` in exactly this order.
169
+ * 3. Remaining sections alphabetically.
170
+ *
171
+ * The default order matches the plan simulation layout (Übersicht →
172
+ * Produktkatalog → Kunden → System); consumers can override it.
173
+ */
174
+ declare function buildSidebar(routes: BuildRouteEntry[], sectionOrder?: readonly string[]): SidebarSection[];
175
+ /**
176
+ * Returns the Vue component registered for the given `componentKey`.
177
+ * The consumer shell calls this function with its own `extensions:` map.
178
+ * For unknown keys → `null` (the UI then renders a fallback
179
+ * component, e.g. "Component not found in shell build").
180
+ *
181
+ * `extensions` is `Record<string, T>` — `T` is typically a
182
+ * Vue component (either imported directly or as a
183
+ * `defineAsyncComponent` wrapper).
184
+ */
185
+ declare function resolveExtension<T>(componentKey: string, extensions: Record<string, T>): T | null;
186
+
187
+ type BatchColumnValue = unknown;
188
+ /** One value per `tenantId` (freely structured). */
189
+ type BatchColumnRow = Record<string, BatchColumnValue>;
190
+ /** One `tenantId → value` map per column key. */
191
+ type BatchColumnData = Record<string, BatchColumnRow>;
192
+ type ParamStyle = 'comma' | 'repeat';
193
+ interface BatchColumnFetcherOptions {
194
+ http?: HttpClient;
195
+ /**
196
+ * How the `tenantIds` are passed to the endpoint. Default `'comma'` →
197
+ * `?tenantIds=t1,t2,t3`. `'repeat'` → `?tenantIds=t1&tenantIds=t2`.
198
+ * Consumer backends decide based on their framework (NestJS accepts
199
+ * comma-separated strings by default, or via `@Query() ids: string[]`).
200
+ */
201
+ paramStyle?: ParamStyle;
202
+ /**
203
+ * Auth-token provider for `Authorization: Bearer <token>`. The consumer
204
+ * supplies a function that pulls the current token from the auth store.
205
+ */
206
+ getAuthToken?: () => string | null;
207
+ }
208
+ declare class BatchColumnDriftError extends Error {
209
+ readonly column: TenantColumnDef;
210
+ constructor(column: TenantColumnDef, reason: string);
211
+ }
212
+ declare class BatchColumnFetcher {
213
+ private readonly http;
214
+ private readonly paramStyle;
215
+ private readonly getAuthToken?;
216
+ constructor(options?: BatchColumnFetcherOptions);
217
+ /**
218
+ * Loads the data for all columns declared in the manifest in parallel
219
+ * (one request per column, all `tenantIds` in the batch). Columns without
220
+ * a satisfied capability are ignored.
221
+ */
222
+ fetchAll(manifest: AdminManifest, tenantIds: string[]): Promise<BatchColumnData>;
223
+ /** Fetch a single column (consumers may also use this directly). */
224
+ fetchOne(column: TenantColumnDef, tenantIds: string[]): Promise<BatchColumnRow>;
225
+ /**
226
+ * Column drift against the manifest. Consumers use this for CI smoke
227
+ * tests of the manifest-vs-shell build.
228
+ */
229
+ listDriftIssues(manifest: AdminManifest): BatchColumnDriftError[];
230
+ /**
231
+ * Which columns have a satisfied `requiredCapability`? Manifest =
232
+ * discovery, so a local check is enough.
233
+ */
234
+ eligibleColumns(manifest: AdminManifest): TenantColumnDef[];
235
+ private validateBatchEndpoint;
236
+ private buildUrl;
237
+ }
238
+
239
+ type SnapshotKind = 'drafts' | 'active' | 'historical';
240
+ interface CatalogSnapshot<P extends PlanVersionRow = PlanVersionRow> {
241
+ id: string;
242
+ kind: SnapshotKind;
243
+ status: 'DRAFT' | 'ACTIVE' | 'ARCHIVED';
244
+ label: string;
245
+ title: string;
246
+ description: string;
247
+ asOf: string | null;
248
+ createdAt: string | null;
249
+ publishedAt: string | null;
250
+ authorEmail: string | null;
251
+ plans: ResolvedPlan<P>[];
252
+ /** Number of open drafts for the `drafts` snapshot, otherwise 0. */
253
+ draftCount: number;
254
+ /** Number of entities in this snapshot whose publication flagged at least
255
+ * one regression (`nonRegressive === false`). */
256
+ regressionCount: number;
257
+ }
258
+ interface ResolvedPlan<P extends PlanVersionRow = PlanVersionRow> {
259
+ /** Which PlanVersionRow was selected to represent this slot. */
260
+ source: P;
261
+ /** Live predecessor (only set when `source` is a DRAFT; otherwise null). */
262
+ liveBase: P | null;
263
+ isDraft: boolean;
264
+ planId: string;
265
+ features: string[];
266
+ /** Quota map (from `source.quotas` or legacy fields; empty if none). */
267
+ quotas: Record<string, number>;
268
+ monthlyNet: number;
269
+ yearlyNet: number;
270
+ marketed: boolean;
271
+ version: number;
272
+ /** @deprecated Read from `quotas['users']`. */
273
+ maxUsers?: number;
274
+ /** @deprecated Legacy field; read from `quotas['vehicles']`. */
275
+ maxVehicles?: number;
276
+ /** @deprecated Read from `quotas['storageGb']`. */
277
+ maxStorageGb?: number;
278
+ }
279
+ interface RawCatalogData<P extends PlanVersionRow = PlanVersionRow> {
280
+ planVersions: P[];
281
+ }
282
+ interface BuildSnapshotsOptions {
283
+ /**
284
+ * App-specific plan order, e.g. `['BASIC', 'STANDARD',
285
+ * 'PROFESSIONAL', 'BUSINESS', 'ENTERPRISE']`. Plan IDs outside the list
286
+ * end up sorted alphabetically at the back.
287
+ */
288
+ planSortOrder?: readonly string[];
289
+ }
290
+ declare function buildSnapshots<P extends PlanVersionRow>(data: RawCatalogData<P>, options?: BuildSnapshotsOptions): CatalogSnapshot<P>[];
291
+ declare function listOpenDrafts<P extends PlanVersionRow>(data: RawCatalogData<P>): {
292
+ plans: P[];
293
+ };
294
+
295
+ export { ADMIN_UI_VERSION, type BatchColumnData, BatchColumnDriftError, BatchColumnFetcher, type BatchColumnFetcherOptions, type BatchColumnRow, type BatchColumnValue, BootLoadError, BootLoader, type BootLoaderOptions, type BuildRouteEntry, type BuildSnapshotsOptions, type CachedManifestEntry, type CatalogSnapshot, DEFAULT_SECTION_ORDER, DEFAULT_STANDARD_PAGE_ROUTES, HttpClient, HttpJsonError, KvStore, ManifestLoadError, ManifestLoader, type ManifestLoaderOptions, type NavBuilderOptions, type ParamStyle, type RawCatalogData, type ResolvedPlan, type SidebarItem, type SidebarSection, type SnapshotKind, buildRoutes, buildSidebar, buildSnapshots, getJson, listOpenDrafts, postJson, resolveExtension, trimTrailingSlashes };
@@ -0,0 +1,295 @@
1
+ import { H as HttpClient, K as KvStore } from '../action-registry-CQ2wL3R-.js';
2
+ export { b as ActionDefNotInManifestError, A as ActionHandler, a as ActionRegistry, c as HttpResponse, M as MissingHandlerError, R as ResolvedAction, d as defaultHttpClient, e as defaultKvStore } from '../action-registry-CQ2wL3R-.js';
3
+ import { PublicBootResponse, AdminManifest, StandardPageKey, TenantColumnDef, PlanVersionRow } from '@saasicat/types';
4
+
5
+ declare const ADMIN_UI_VERSION = "1.2.0";
6
+
7
+ /**
8
+ * Error for non-2xx responses. `code` is the machine-readable error code
9
+ * from the JSON body (`{ code }`), if present — callers map it to
10
+ * a message (e.g. via `SETUP_ERROR_CODES`).
11
+ */
12
+ declare class HttpJsonError extends Error {
13
+ readonly status: number;
14
+ readonly code?: string | undefined;
15
+ constructor(status: number, code?: string | undefined);
16
+ }
17
+ /**
18
+ * Removes trailing slashes so an API prefix can be concatenated with paths
19
+ * that start with `/`. Deliberately index-based instead of
20
+ * `replace(/\/+$/, '')`: the regex backtracks quadratically on inputs that
21
+ * end in many slashes.
22
+ */
23
+ declare function trimTrailingSlashes(url: string): string;
24
+ declare function getJson<T>(http: HttpClient, url: string): Promise<T>;
25
+ declare function postJson<T>(http: HttpClient, url: string, body: unknown): Promise<T>;
26
+
27
+ interface BootLoaderOptions {
28
+ /**
29
+ * Fully-qualified boot endpoint incl. app globalPrefix
30
+ * (`/api/admin/boot`, `/api/v1/admin/boot`, …). Mandatory.
31
+ */
32
+ endpoint: string;
33
+ /** Defaults to `defaultHttpClient()` (= `fetch`). */
34
+ http?: HttpClient;
35
+ }
36
+ declare class BootLoadError extends Error {
37
+ readonly status: number;
38
+ constructor(status: number, message: string);
39
+ }
40
+ declare class BootLoader {
41
+ private readonly endpoint;
42
+ private readonly http;
43
+ constructor(options: BootLoaderOptions);
44
+ load(): Promise<PublicBootResponse>;
45
+ }
46
+
47
+ interface ManifestLoaderOptions {
48
+ /**
49
+ * Fully-qualified manifest endpoint incl. app globalPrefix
50
+ * (`/api/admin/manifest`, `/api/v1/admin/manifest`, …). Mandatory.
51
+ */
52
+ endpoint: string;
53
+ http?: HttpClient;
54
+ storage?: KvStore;
55
+ /**
56
+ * Storage key prefix — consumers with multiple apps under one domain
57
+ * set this to e.g. `'ma:'` or `'da:'`, so that the caches
58
+ * are separated.
59
+ */
60
+ storageKeyPrefix?: string;
61
+ /**
62
+ * Auth header for `Authorization: Bearer <token>`. Sent with every
63
+ * request. The consumer supplies a function that pulls the
64
+ * current token from the auth store.
65
+ */
66
+ getAuthToken?: () => string | null;
67
+ }
68
+ declare class ManifestLoadError extends Error {
69
+ readonly status: number;
70
+ constructor(status: number, message: string);
71
+ }
72
+ interface CachedManifestEntry {
73
+ etag: string;
74
+ body: AdminManifest;
75
+ }
76
+ declare class ManifestLoader {
77
+ private readonly endpoint;
78
+ private readonly http;
79
+ private readonly storage;
80
+ private readonly bodyKey;
81
+ private readonly etagKey;
82
+ private readonly getAuthToken?;
83
+ constructor(options: ManifestLoaderOptions);
84
+ /**
85
+ * Loads the current manifest. On a cache hit (304) the cached
86
+ * body is returned — otherwise the fresh server body.
87
+ */
88
+ load(): Promise<AdminManifest>;
89
+ /** Reads the cached manifest body from storage; null if absent. */
90
+ readCachedBody(): CachedManifestEntry | null;
91
+ /** Clears the cache — e.g. on logout or after `manifest reload`. */
92
+ clearCache(): void;
93
+ }
94
+
95
+ /**
96
+ * Default routes for the platform standard pages. Consumers may override this
97
+ * via the `standardPageRoutes` option (e.g. `/admin/users` →
98
+ * `/admin/team`).
99
+ */
100
+ declare const DEFAULT_STANDARD_PAGE_ROUTES: Record<StandardPageKey, string>;
101
+ interface BuildRouteEntry {
102
+ /** Stable identifier — the key for standard pages, the `id` for project pages. */
103
+ id: string;
104
+ /** Route path (`/admin/...`). */
105
+ path: string;
106
+ /** Visible for the UI. */
107
+ label: string;
108
+ icon?: string;
109
+ /** Sort key for drawer groups. */
110
+ navSection?: string;
111
+ /** Lookup key in the `extensions:` map (project) or the platform standard map. */
112
+ componentKey: string;
113
+ /** Required capability or null. */
114
+ requiredCapability: string | null;
115
+ /** Platform standard page (`true`) or project page (`false`). */
116
+ isStandard: boolean;
117
+ /** Hint for anticipatory lazy loading. */
118
+ prefetchOnIdle?: boolean;
119
+ }
120
+ interface NavBuilderOptions {
121
+ /**
122
+ * Optional: overrides the default routes for certain standard pages.
123
+ * Consumers set this if they want an alternative URL structure.
124
+ */
125
+ standardPageRoutes?: Partial<Record<StandardPageKey, string>>;
126
+ /**
127
+ * Default labels for standard pages — consumers may localize.
128
+ */
129
+ standardPageLabels?: Partial<Record<StandardPageKey, string>>;
130
+ /** Default icons for standard pages. */
131
+ standardPageIcons?: Partial<Record<StandardPageKey, string>>;
132
+ /** Default `navSection` for standard pages. */
133
+ standardPageNavSection?: Partial<Record<StandardPageKey, string>>;
134
+ /**
135
+ * Optional: set of known `componentKey`s from the shell's `extensions:`
136
+ * map. ProjectPages whose `componentKey` is not contained here
137
+ * are filtered out — they would otherwise appear in the sidebar but on
138
+ * click be redirected by the catch-all (silent dead link).
139
+ * Consumers without an `extensions:` map omit the field → as before.
140
+ */
141
+ availableExtensions?: Set<string>;
142
+ }
143
+ declare const DEFAULT_SECTION_ORDER: readonly string[];
144
+ /**
145
+ * Returns the list of all routes defined by the current manifest —
146
+ * filtered to the capabilities that the logged-in user has.
147
+ *
148
+ * The consumer shell then builds its Vue router configuration and its
149
+ * sidebar drawer from it.
150
+ */
151
+ declare function buildRoutes(manifest: AdminManifest, options?: NavBuilderOptions): BuildRouteEntry[];
152
+ interface SidebarItem {
153
+ id: string;
154
+ path: string;
155
+ label: string;
156
+ icon?: string;
157
+ }
158
+ interface SidebarSection {
159
+ /** `null` for the default section (items without `navSection`). */
160
+ section: string | null;
161
+ items: SidebarItem[];
162
+ }
163
+ /**
164
+ * Groups the routes by `navSection` for the drawer.
165
+ *
166
+ * Section order:
167
+ * 1. Default section (`null`) — items without `navSection`.
168
+ * 2. Sections from `sectionOrder` in exactly this order.
169
+ * 3. Remaining sections alphabetically.
170
+ *
171
+ * The default order matches the plan simulation layout (Übersicht →
172
+ * Produktkatalog → Kunden → System); consumers can override it.
173
+ */
174
+ declare function buildSidebar(routes: BuildRouteEntry[], sectionOrder?: readonly string[]): SidebarSection[];
175
+ /**
176
+ * Returns the Vue component registered for the given `componentKey`.
177
+ * The consumer shell calls this function with its own `extensions:` map.
178
+ * For unknown keys → `null` (the UI then renders a fallback
179
+ * component, e.g. "Component not found in shell build").
180
+ *
181
+ * `extensions` is `Record<string, T>` — `T` is typically a
182
+ * Vue component (either imported directly or as a
183
+ * `defineAsyncComponent` wrapper).
184
+ */
185
+ declare function resolveExtension<T>(componentKey: string, extensions: Record<string, T>): T | null;
186
+
187
+ type BatchColumnValue = unknown;
188
+ /** One value per `tenantId` (freely structured). */
189
+ type BatchColumnRow = Record<string, BatchColumnValue>;
190
+ /** One `tenantId → value` map per column key. */
191
+ type BatchColumnData = Record<string, BatchColumnRow>;
192
+ type ParamStyle = 'comma' | 'repeat';
193
+ interface BatchColumnFetcherOptions {
194
+ http?: HttpClient;
195
+ /**
196
+ * How the `tenantIds` are passed to the endpoint. Default `'comma'` →
197
+ * `?tenantIds=t1,t2,t3`. `'repeat'` → `?tenantIds=t1&tenantIds=t2`.
198
+ * Consumer backends decide based on their framework (NestJS accepts
199
+ * comma-separated strings by default, or via `@Query() ids: string[]`).
200
+ */
201
+ paramStyle?: ParamStyle;
202
+ /**
203
+ * Auth-token provider for `Authorization: Bearer <token>`. The consumer
204
+ * supplies a function that pulls the current token from the auth store.
205
+ */
206
+ getAuthToken?: () => string | null;
207
+ }
208
+ declare class BatchColumnDriftError extends Error {
209
+ readonly column: TenantColumnDef;
210
+ constructor(column: TenantColumnDef, reason: string);
211
+ }
212
+ declare class BatchColumnFetcher {
213
+ private readonly http;
214
+ private readonly paramStyle;
215
+ private readonly getAuthToken?;
216
+ constructor(options?: BatchColumnFetcherOptions);
217
+ /**
218
+ * Loads the data for all columns declared in the manifest in parallel
219
+ * (one request per column, all `tenantIds` in the batch). Columns without
220
+ * a satisfied capability are ignored.
221
+ */
222
+ fetchAll(manifest: AdminManifest, tenantIds: string[]): Promise<BatchColumnData>;
223
+ /** Fetch a single column (consumers may also use this directly). */
224
+ fetchOne(column: TenantColumnDef, tenantIds: string[]): Promise<BatchColumnRow>;
225
+ /**
226
+ * Column drift against the manifest. Consumers use this for CI smoke
227
+ * tests of the manifest-vs-shell build.
228
+ */
229
+ listDriftIssues(manifest: AdminManifest): BatchColumnDriftError[];
230
+ /**
231
+ * Which columns have a satisfied `requiredCapability`? Manifest =
232
+ * discovery, so a local check is enough.
233
+ */
234
+ eligibleColumns(manifest: AdminManifest): TenantColumnDef[];
235
+ private validateBatchEndpoint;
236
+ private buildUrl;
237
+ }
238
+
239
+ type SnapshotKind = 'drafts' | 'active' | 'historical';
240
+ interface CatalogSnapshot<P extends PlanVersionRow = PlanVersionRow> {
241
+ id: string;
242
+ kind: SnapshotKind;
243
+ status: 'DRAFT' | 'ACTIVE' | 'ARCHIVED';
244
+ label: string;
245
+ title: string;
246
+ description: string;
247
+ asOf: string | null;
248
+ createdAt: string | null;
249
+ publishedAt: string | null;
250
+ authorEmail: string | null;
251
+ plans: ResolvedPlan<P>[];
252
+ /** Number of open drafts for the `drafts` snapshot, otherwise 0. */
253
+ draftCount: number;
254
+ /** Number of entities in this snapshot whose publication flagged at least
255
+ * one regression (`nonRegressive === false`). */
256
+ regressionCount: number;
257
+ }
258
+ interface ResolvedPlan<P extends PlanVersionRow = PlanVersionRow> {
259
+ /** Which PlanVersionRow was selected to represent this slot. */
260
+ source: P;
261
+ /** Live predecessor (only set when `source` is a DRAFT; otherwise null). */
262
+ liveBase: P | null;
263
+ isDraft: boolean;
264
+ planId: string;
265
+ features: string[];
266
+ /** Quota map (from `source.quotas` or legacy fields; empty if none). */
267
+ quotas: Record<string, number>;
268
+ monthlyNet: number;
269
+ yearlyNet: number;
270
+ marketed: boolean;
271
+ version: number;
272
+ /** @deprecated Read from `quotas['users']`. */
273
+ maxUsers?: number;
274
+ /** @deprecated Legacy field; read from `quotas['vehicles']`. */
275
+ maxVehicles?: number;
276
+ /** @deprecated Read from `quotas['storageGb']`. */
277
+ maxStorageGb?: number;
278
+ }
279
+ interface RawCatalogData<P extends PlanVersionRow = PlanVersionRow> {
280
+ planVersions: P[];
281
+ }
282
+ interface BuildSnapshotsOptions {
283
+ /**
284
+ * App-specific plan order, e.g. `['BASIC', 'STANDARD',
285
+ * 'PROFESSIONAL', 'BUSINESS', 'ENTERPRISE']`. Plan IDs outside the list
286
+ * end up sorted alphabetically at the back.
287
+ */
288
+ planSortOrder?: readonly string[];
289
+ }
290
+ declare function buildSnapshots<P extends PlanVersionRow>(data: RawCatalogData<P>, options?: BuildSnapshotsOptions): CatalogSnapshot<P>[];
291
+ declare function listOpenDrafts<P extends PlanVersionRow>(data: RawCatalogData<P>): {
292
+ plans: P[];
293
+ };
294
+
295
+ export { ADMIN_UI_VERSION, type BatchColumnData, BatchColumnDriftError, BatchColumnFetcher, type BatchColumnFetcherOptions, type BatchColumnRow, type BatchColumnValue, BootLoadError, BootLoader, type BootLoaderOptions, type BuildRouteEntry, type BuildSnapshotsOptions, type CachedManifestEntry, type CatalogSnapshot, DEFAULT_SECTION_ORDER, DEFAULT_STANDARD_PAGE_ROUTES, HttpClient, HttpJsonError, KvStore, ManifestLoadError, ManifestLoader, type ManifestLoaderOptions, type NavBuilderOptions, type ParamStyle, type RawCatalogData, type ResolvedPlan, type SidebarItem, type SidebarSection, type SnapshotKind, buildRoutes, buildSidebar, buildSnapshots, getJson, listOpenDrafts, postJson, resolveExtension, trimTrailingSlashes };
@@ -0,0 +1,52 @@
1
+ import {
2
+ ADMIN_UI_VERSION,
3
+ ActionDefNotInManifestError,
4
+ ActionRegistry,
5
+ BatchColumnDriftError,
6
+ BatchColumnFetcher,
7
+ BootLoadError,
8
+ BootLoader,
9
+ DEFAULT_SECTION_ORDER,
10
+ DEFAULT_STANDARD_PAGE_ROUTES,
11
+ HttpJsonError,
12
+ ManifestLoadError,
13
+ ManifestLoader,
14
+ MissingHandlerError,
15
+ buildRoutes,
16
+ buildSidebar,
17
+ buildSnapshots,
18
+ getJson,
19
+ listOpenDrafts,
20
+ postJson,
21
+ resolveExtension,
22
+ trimTrailingSlashes
23
+ } from "../chunk-EH7TOD4H.js";
24
+ import {
25
+ defaultHttpClient,
26
+ defaultKvStore
27
+ } from "../chunk-LVGUSD3T.js";
28
+ export {
29
+ ADMIN_UI_VERSION,
30
+ ActionDefNotInManifestError,
31
+ ActionRegistry,
32
+ BatchColumnDriftError,
33
+ BatchColumnFetcher,
34
+ BootLoadError,
35
+ BootLoader,
36
+ DEFAULT_SECTION_ORDER,
37
+ DEFAULT_STANDARD_PAGE_ROUTES,
38
+ HttpJsonError,
39
+ ManifestLoadError,
40
+ ManifestLoader,
41
+ MissingHandlerError,
42
+ buildRoutes,
43
+ buildSidebar,
44
+ buildSnapshots,
45
+ defaultHttpClient,
46
+ defaultKvStore,
47
+ getJson,
48
+ listOpenDrafts,
49
+ postJson,
50
+ resolveExtension,
51
+ trimTrailingSlashes
52
+ };