@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.
- package/README.md +47 -4
- package/dist/action-registry-CQ2wL3R-.d.cts +85 -0
- package/dist/action-registry-CQ2wL3R-.d.ts +85 -0
- package/dist/chunk-3YP2ZAOD.js +63 -0
- package/dist/chunk-EH7TOD4H.js +718 -0
- package/dist/chunk-LVGUSD3T.js +26 -0
- package/dist/client/index.cjs +785 -0
- package/dist/client/index.d.cts +295 -0
- package/dist/client/index.d.ts +295 -0
- package/dist/client/index.js +52 -0
- package/dist/index.cjs +787 -834
- package/dist/index.d.cts +267 -841
- package/dist/index.d.ts +267 -841
- package/dist/index.js +284 -1059
- package/dist/quasar/index.cjs +159 -0
- package/dist/quasar/index.d.cts +86 -0
- package/dist/quasar/index.d.ts +86 -0
- package/dist/quasar/index.js +91 -0
- package/dist/ui-notify-COUzXEQ4.d.ts +178 -0
- package/dist/ui-notify-D_eAAwRh.d.cts +178 -0
- package/package.json +23 -3
- package/src/client/index.ts +25 -0
- package/src/components/FeatureGate.vue +1 -1
- package/src/components/plan/PlanCycleToggle.vue +1 -1
- package/src/components/plan/PlanGrid.vue +2 -2
- package/src/components/plan/PriceSummary.vue +1 -1
- package/src/components/plan/PromoCodeInput.vue +1 -1
- package/src/components/plan/PublicBundleGrid.vue +1 -1
- package/src/index.ts +82 -79
- package/src/pages-standard/AdminLayout.vue +2 -2
- package/src/pages-standard/DashboardPage.vue +2 -2
- package/src/pages-standard/EmailHistoryPage.vue +9 -13
- package/src/pages-standard/MarketingCatalogPage.vue +5 -5
- package/src/pages-standard/PilotsPage.vue +9 -13
- package/src/pages-standard/PlanVersionsPage.vue +2 -2
- package/src/pages-standard/PlansPage.vue +2 -2
- package/src/pages-standard/PlatformEmailPage.vue +7 -5
- package/src/pages-standard/PromoCodesPage.vue +8 -22
- package/src/pages-standard/SuperAdminLoginPage.vue +3 -3
- package/src/pages-standard/SuperAdminSetupWizard.vue +2 -2
- package/src/pages-standard/TenantDetailPage.vue +4 -4
- package/src/pages-standard/TenantsPage.vue +3 -3
- package/src/pages-standard/UsersPage.vue +6 -12
- package/src/pages-standard/plan-versions/PlanVersionHeader.vue +1 -1
- package/src/pages-standard/plan-versions/PlanVersionsAudit.vue +1 -1
- package/src/pages-standard/plan-versions/PlanVersionsDiff.vue +1 -1
- package/src/pages-standard/plan-versions/PlanVersionsList.vue +1 -1
- package/src/pages-standard/plan-versions/PlanVersionsMatrix.vue +1 -1
- package/src/pages-standard/plan-versions/PlanVersionsTimeline.vue +1 -1
- package/src/pages-tenant/MySubscriptionBundlesPage.vue +1 -1
- package/src/pages-tenant/OnboardingConfigurator.vue +3 -3
- package/src/pages-tenant/PackageSnapshotPanel.vue +1 -1
- package/src/pages-tenant/PlanChangeWizard.vue +2 -2
- package/src/pages-tenant/TenantPlanSection.vue +3 -3
- package/src/pages-tenant/tenant-plan-section/BundlePreviewDialog.vue +1 -1
- package/src/pages-tenant/tenant-plan-section/TenantBundleStore.vue +2 -2
- package/src/pages-tenant/tenant-plan-section/TenantPlanCardHeader.vue +1 -1
- package/src/pages-tenant/tenant-plan-section/TenantUsageGrid.vue +1 -1
- package/src/quasar/create-super-admin-app.ts +173 -0
- package/src/quasar/index.ts +11 -0
- package/src/quasar/notify.ts +30 -0
- package/src/{manifest-store-factory.ts → vue/manifest-store-factory.ts} +1 -1
- package/src/{platform-loaders.ts → vue/platform-loaders.ts} +4 -4
- package/src/{project-page-host.ts → vue/project-page-host.ts} +1 -1
- package/src/{create-super-admin-app.ts → vue/super-admin-context.ts} +20 -139
- package/src/vue/ui-notify.ts +30 -0
- package/src/{use-actions.ts → vue/use-actions.ts} +1 -1
- package/src/{use-api-list.ts → vue/use-api-list.ts} +1 -1
- package/src/{use-batch-columns.ts → vue/use-batch-columns.ts} +1 -1
- package/src/{use-bulk-publish.ts → vue/use-bulk-publish.ts} +1 -1
- package/src/{use-bundle-versions-map.ts → vue/use-bundle-versions-map.ts} +1 -1
- package/src/{use-bundles.ts → vue/use-bundles.ts} +1 -1
- package/src/{use-business-types.ts → vue/use-business-types.ts} +1 -1
- package/src/{use-catalog-entries.ts → vue/use-catalog-entries.ts} +1 -1
- package/src/{use-discovery.ts → vue/use-discovery.ts} +1 -1
- package/src/{use-entitlement.ts → vue/use-entitlement.ts} +1 -1
- package/src/{use-live-plan-versions.ts → vue/use-live-plan-versions.ts} +1 -1
- package/src/{use-manifest.ts → vue/use-manifest.ts} +1 -1
- package/src/{use-marketing-projections.ts → vue/use-marketing-projections.ts} +1 -1
- package/src/{use-nav.ts → vue/use-nav.ts} +1 -1
- package/src/{use-plans.ts → vue/use-plans.ts} +1 -1
- package/src/{use-promotions.ts → vue/use-promotions.ts} +1 -1
- package/src/{use-public-boot.ts → vue/use-public-boot.ts} +1 -1
- package/src/{use-super-admin-context.ts → vue/use-super-admin-context.ts} +2 -2
- package/src/{use-tenant-action-flow.ts → vue/use-tenant-action-flow.ts} +1 -1
- package/src/{use-tenant-billing-catalog.ts → vue/use-tenant-billing-catalog.ts} +2 -2
- package/src/{use-tenant-billing.ts → vue/use-tenant-billing.ts} +2 -2
- package/src/{use-tenant-manifest.ts → vue/use-tenant-manifest.ts} +1 -1
- package/src/{use-tenant-subscription-bundles.ts → vue/use-tenant-subscription-bundles.ts} +1 -1
- package/dist/testing-e2e/admin-pages-suite.d.cts +0 -37
- package/dist/testing-e2e/admin-pages-suite.d.ts +0 -37
- /package/src/{action-registry.ts → client/action-registry.ts} +0 -0
- /package/src/{batch-column-fetcher.ts → client/batch-column-fetcher.ts} +0 -0
- /package/src/{boot-loader.ts → client/boot-loader.ts} +0 -0
- /package/src/{http-json.ts → client/http-json.ts} +0 -0
- /package/src/{manifest-loader.ts → client/manifest-loader.ts} +0 -0
- /package/src/{nav-builder.ts → client/nav-builder.ts} +0 -0
- /package/src/{plan-versions-catalog.ts → client/plan-versions-catalog.ts} +0 -0
- /package/src/{types.ts → client/types.ts} +0 -0
- /package/src/{version.ts → client/version.ts} +0 -0
- /package/src/{create-admin-routes.ts → vue/create-admin-routes.ts} +0 -0
- /package/src/{entitlement-provider.ts → vue/entitlement-provider.ts} +0 -0
- /package/src/{feature-router-guard.ts → vue/feature-router-guard.ts} +0 -0
- /package/src/{use-audit-entries.ts → vue/use-audit-entries.ts} +0 -0
- /package/src/{use-plan-editor.ts → vue/use-plan-editor.ts} +0 -0
- /package/src/{use-plan-versions.ts → vue/use-plan-versions.ts} +0 -0
- /package/src/{use-platform-tenant-actions.ts → vue/use-platform-tenant-actions.ts} +0 -0
- /package/src/{use-subscription-draft.ts → vue/use-subscription-draft.ts} +0 -0
- /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
|
+
};
|