@spring-systems/core 0.8.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/CHANGELOG.md +33 -0
- package/LICENSE +8 -0
- package/README.md +77 -0
- package/dist/adapters/index.d.ts +246 -0
- package/dist/adapters/index.js +56 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/auth/index.d.ts +17 -0
- package/dist/auth/index.js +19 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/chunk-5D6XE7NJ.js +16 -0
- package/dist/chunk-5D6XE7NJ.js.map +1 -0
- package/dist/chunk-EFUBAQCV.js +94 -0
- package/dist/chunk-EFUBAQCV.js.map +1 -0
- package/dist/chunk-F2SIMWZ5.js +173 -0
- package/dist/chunk-F2SIMWZ5.js.map +1 -0
- package/dist/chunk-F7WUQJH7.js +399 -0
- package/dist/chunk-F7WUQJH7.js.map +1 -0
- package/dist/chunk-GON7Q32Q.js +176 -0
- package/dist/chunk-GON7Q32Q.js.map +1 -0
- package/dist/chunk-GXU75LQX.js +182 -0
- package/dist/chunk-GXU75LQX.js.map +1 -0
- package/dist/chunk-HFELOXDQ.js +110 -0
- package/dist/chunk-HFELOXDQ.js.map +1 -0
- package/dist/chunk-KX32MU3I.js +190 -0
- package/dist/chunk-KX32MU3I.js.map +1 -0
- package/dist/chunk-MEWPYTWC.js +284 -0
- package/dist/chunk-MEWPYTWC.js.map +1 -0
- package/dist/chunk-N2L4TUC4.js +34 -0
- package/dist/chunk-N2L4TUC4.js.map +1 -0
- package/dist/chunk-NQQIVCLX.js +47 -0
- package/dist/chunk-NQQIVCLX.js.map +1 -0
- package/dist/chunk-OSSX443T.js +146 -0
- package/dist/chunk-OSSX443T.js.map +1 -0
- package/dist/chunk-PT4DIYUK.js +78 -0
- package/dist/chunk-PT4DIYUK.js.map +1 -0
- package/dist/chunk-QAVWXARR.js +51 -0
- package/dist/chunk-QAVWXARR.js.map +1 -0
- package/dist/chunk-RRWKDFAB.js +143 -0
- package/dist/chunk-RRWKDFAB.js.map +1 -0
- package/dist/chunk-RUCXSQEY.js +42 -0
- package/dist/chunk-RUCXSQEY.js.map +1 -0
- package/dist/chunk-S6RPCN5H.js +64 -0
- package/dist/chunk-S6RPCN5H.js.map +1 -0
- package/dist/chunk-S7MKRNMI.js +153 -0
- package/dist/chunk-S7MKRNMI.js.map +1 -0
- package/dist/chunk-SQB4F3EF.js +55 -0
- package/dist/chunk-SQB4F3EF.js.map +1 -0
- package/dist/chunk-U5OH3GAI.js +399 -0
- package/dist/chunk-U5OH3GAI.js.map +1 -0
- package/dist/chunk-UDT2RPX2.js +43 -0
- package/dist/chunk-UDT2RPX2.js.map +1 -0
- package/dist/config/index.d.ts +63 -0
- package/dist/config/index.js +109 -0
- package/dist/config/index.js.map +1 -0
- package/dist/devtools/index.d.ts +54 -0
- package/dist/devtools/index.js +67 -0
- package/dist/devtools/index.js.map +1 -0
- package/dist/errors/index.d.ts +39 -0
- package/dist/errors/index.js +21 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/events/index.d.ts +153 -0
- package/dist/events/index.js +12 -0
- package/dist/events/index.js.map +1 -0
- package/dist/form-types-D3MdGpjA.d.ts +290 -0
- package/dist/framework-config-types-DeUbx4bu.d.ts +574 -0
- package/dist/i18n/index.d.ts +37 -0
- package/dist/i18n/index.js +7 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/instance/index.d.ts +112 -0
- package/dist/instance/index.js +37 -0
- package/dist/instance/index.js.map +1 -0
- package/dist/logger/index.d.ts +44 -0
- package/dist/logger/index.js +27 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/middleware/index.d.ts +91 -0
- package/dist/middleware/index.js +23 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware-registry-DT002qRd.d.ts +60 -0
- package/dist/middleware-types-DVG9C1qJ.d.ts +85 -0
- package/dist/plugins/index.d.ts +104 -0
- package/dist/plugins/index.js +16 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/runtime-env-config-CajOEJCP.d.ts +148 -0
- package/dist/security-sanitize-Bb0PExM6.d.ts +9 -0
- package/dist/spring-instance-EbUh4mQb.d.ts +119 -0
- package/dist/testing/index.d.ts +129 -0
- package/dist/testing/index.js +171 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/types/index.d.ts +85 -0
- package/dist/types/index.js +72 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/index.d.ts +143 -0
- package/dist/utils/index.js +786 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/validation/index.d.ts +48 -0
- package/dist/validation/index.js +147 -0
- package/dist/validation/index.js.map +1 -0
- package/package.json +142 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# @spring-systems/core
|
|
2
|
+
|
|
3
|
+
## 0.7.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Version bump for aligned release across all packages.
|
|
8
|
+
|
|
9
|
+
## 0.7.4
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Dependency updates and version alignment.
|
|
14
|
+
|
|
15
|
+
## 0.7.3
|
|
16
|
+
|
|
17
|
+
## 0.7.2
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Improve package documentation, onboarding navigation, and npm-published docs coverage.
|
|
22
|
+
|
|
23
|
+
## 0.7.1
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- Align package documentation with repository docs and enforce docs quality checks in release workflow.
|
|
28
|
+
|
|
29
|
+
## 0.7.0
|
|
30
|
+
|
|
31
|
+
### Patch Changes
|
|
32
|
+
|
|
33
|
+
- Initial npm registry release
|
package/LICENSE
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Copyright (c) 2024-2026 The Authors
|
|
2
|
+
|
|
3
|
+
All rights reserved.
|
|
4
|
+
|
|
5
|
+
This software and associated documentation are proprietary and confidential.
|
|
6
|
+
No rights are granted except as expressly agreed in writing by the copyright holder(s).
|
|
7
|
+
Use, copying, modification, distribution, sublicensing, publication, or disclosure
|
|
8
|
+
without prior written permission is prohibited.
|
package/README.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# @spring-systems/core
|
|
2
|
+
|
|
3
|
+
Core types, utilities, configuration, and runtime primitives for the Spring Systems SPRING framework. This package is intentionally React-free and exists to hold the shared contracts the rest of the stack builds on.
|
|
4
|
+
|
|
5
|
+
## When To Use It
|
|
6
|
+
|
|
7
|
+
Choose this package when the concern belongs to framework runtime rather than rendered UI.
|
|
8
|
+
|
|
9
|
+
- use it for configuration, instance lifecycle, events, middleware, plugins, validation, shared types, and utilities
|
|
10
|
+
- skip it for page rendering, browser-only component state, or Next.js request handling
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pnpm add @spring-systems/core
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
This package has minimal dependencies (`dayjs`, `sanitize-html`) and no peer dependencies.
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { createSpringInstance, markInstanceReady } from "@spring-systems/core/instance";
|
|
24
|
+
import { eventBus } from "@spring-systems/core/events";
|
|
25
|
+
import { registerMiddleware } from "@spring-systems/core/middleware";
|
|
26
|
+
|
|
27
|
+
const instance = createSpringInstance({
|
|
28
|
+
app: { name: "My SPRING", defaultRoute: "/" },
|
|
29
|
+
auth: { sessionCookiePrefix: "myspring" },
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
eventBus.on("auth:logout", () => console.log("User logged out"));
|
|
33
|
+
|
|
34
|
+
registerMiddleware("form:beforeSave", async (ctx, next) => {
|
|
35
|
+
console.log("Saving:", ctx);
|
|
36
|
+
await next();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
markInstanceReady(instance);
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Entry Points
|
|
43
|
+
|
|
44
|
+
| Import path | Use it for |
|
|
45
|
+
|---|---|
|
|
46
|
+
| `@spring-systems/core` | Convenience re-exports |
|
|
47
|
+
| `@spring-systems/core/config` | Framework configuration and theme tokens |
|
|
48
|
+
| `@spring-systems/core/instance` | `SpringInstance` factory and lifecycle |
|
|
49
|
+
| `@spring-systems/core/events` | Typed event bus |
|
|
50
|
+
| `@spring-systems/core/middleware` | Middleware registry and runner |
|
|
51
|
+
| `@spring-systems/core/plugins` | Plugin setup and disposal |
|
|
52
|
+
| `@spring-systems/core/validation` | Field validators and registry |
|
|
53
|
+
| `@spring-systems/core/auth` | Auth state helpers |
|
|
54
|
+
| `@spring-systems/core/adapters` | Adapter interfaces |
|
|
55
|
+
| `@spring-systems/core/logger` | Logging facade |
|
|
56
|
+
| `@spring-systems/core/utils` | Shared utilities |
|
|
57
|
+
| `@spring-systems/core/types` | Shared type definitions |
|
|
58
|
+
| `@spring-systems/core/errors` | Error types |
|
|
59
|
+
| `@spring-systems/core/i18n` | Default i18n messages |
|
|
60
|
+
| `@spring-systems/core/testing` | Test helpers |
|
|
61
|
+
| `@spring-systems/core/devtools` | Instance inspection helpers |
|
|
62
|
+
|
|
63
|
+
## Boundary Rules
|
|
64
|
+
|
|
65
|
+
- do not treat `SpringInstance` as a replacement for screen-local state
|
|
66
|
+
- if code needs React rendering or component composition, it likely belongs in `ui`
|
|
67
|
+
- if code needs the Next.js server boundary, it belongs in `server`
|
|
68
|
+
- for deeper ownership decisions see [ARCHITECTURE.md](https://bitbucket.org/springsystems-projects/spring-framework-frontend/blob/main/docs/ARCHITECTURE.md) in the monorepo docs
|
|
69
|
+
- for extension design see [EXTENSIBILITY_COOKBOOK.md](https://bitbucket.org/springsystems-projects/spring-framework-frontend/blob/main/docs/EXTENSIBILITY_COOKBOOK.md) in the monorepo docs
|
|
70
|
+
|
|
71
|
+
## Changelog
|
|
72
|
+
|
|
73
|
+
See [CHANGELOG.md](CHANGELOG.md) for release history and breaking changes.
|
|
74
|
+
|
|
75
|
+
## License
|
|
76
|
+
|
|
77
|
+
UNLICENSED
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content adapter — decouples API/validation layers from the i18n system (contents store).
|
|
3
|
+
* Pattern matches setLogAdapter() in logger.ts.
|
|
4
|
+
* @module content-adapter
|
|
5
|
+
*/
|
|
6
|
+
interface ContentAdapter {
|
|
7
|
+
getRes(key: string): string;
|
|
8
|
+
}
|
|
9
|
+
declare function setContentAdapter(adapter: ContentAdapter): void;
|
|
10
|
+
/** Returns translated content via the registered adapter. Replaces direct getRes() imports in core/api layers. */
|
|
11
|
+
declare function getContentRes(key: string): string;
|
|
12
|
+
/** Reset to default content adapter. For testing/integration teardown only. */
|
|
13
|
+
declare function clearContentAdapter(): void;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* HTTP adapter — decouples the framework from any specific HTTP client (axios, fetch, etc.).
|
|
17
|
+
*
|
|
18
|
+
* Consumer applications provide their own HTTP implementation by setting a custom adapter.
|
|
19
|
+
* The framework uses this adapter for all API communication (lists, forms, auth, etc.)
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* import { setHttpAdapter } from "@spring-systems/core/adapters";
|
|
24
|
+
*
|
|
25
|
+
* setHttpAdapter({
|
|
26
|
+
* async request(config) {
|
|
27
|
+
* const resp = await fetch(config.url, {
|
|
28
|
+
* method: config.method ?? "GET",
|
|
29
|
+
* body: config.data ? JSON.stringify(config.data) : undefined,
|
|
30
|
+
* headers: config.headers,
|
|
31
|
+
* signal: config.signal,
|
|
32
|
+
* });
|
|
33
|
+
* return resp.json();
|
|
34
|
+
* },
|
|
35
|
+
* async get(url, config) {
|
|
36
|
+
* return this.request({ ...config, url, method: "GET" });
|
|
37
|
+
* },
|
|
38
|
+
* async post(config) {
|
|
39
|
+
* return this.request({ ...config, method: "POST" });
|
|
40
|
+
* },
|
|
41
|
+
* async put(config) {
|
|
42
|
+
* return this.request({ ...config, method: "PUT" });
|
|
43
|
+
* },
|
|
44
|
+
* async delete(url, config) {
|
|
45
|
+
* return this.request({ ...config, url, method: "DELETE" });
|
|
46
|
+
* },
|
|
47
|
+
* });
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* @module http-adapter
|
|
51
|
+
*/
|
|
52
|
+
interface HttpRequest {
|
|
53
|
+
url: string;
|
|
54
|
+
method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
55
|
+
data?: unknown;
|
|
56
|
+
params?: Record<string, string>;
|
|
57
|
+
headers?: Record<string, string>;
|
|
58
|
+
signal?: AbortSignal;
|
|
59
|
+
/** Override the global timeout for this request (e.g. longer timeout for exports/uploads). */
|
|
60
|
+
timeoutMs?: number;
|
|
61
|
+
suppressToast?: boolean;
|
|
62
|
+
suppressRedirect?: boolean;
|
|
63
|
+
}
|
|
64
|
+
interface HttpAdapter {
|
|
65
|
+
request<TResponse>(config: HttpRequest): Promise<TResponse | undefined>;
|
|
66
|
+
get<TResponse>(url: string, config?: Partial<HttpRequest>): Promise<TResponse | undefined>;
|
|
67
|
+
post<TData, TResponse>(config: HttpRequest & {
|
|
68
|
+
data: TData;
|
|
69
|
+
}): Promise<TResponse | undefined>;
|
|
70
|
+
put<TData, TResponse>(config: HttpRequest & {
|
|
71
|
+
data: TData;
|
|
72
|
+
}): Promise<TResponse | undefined>;
|
|
73
|
+
delete<TResponse>(url: string, config?: Partial<HttpRequest>): Promise<TResponse | undefined>;
|
|
74
|
+
}
|
|
75
|
+
declare function setHttpAdapter(adapter: HttpAdapter): void;
|
|
76
|
+
declare function getHttpAdapter(): HttpAdapter;
|
|
77
|
+
/**
|
|
78
|
+
* Reset the HTTP adapter to the default noop adapter.
|
|
79
|
+
* For testing only.
|
|
80
|
+
*/
|
|
81
|
+
declare function clearHttpAdapter(): void;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* License adapter — provides a pluggable interface for enterprise license validation.
|
|
85
|
+
*
|
|
86
|
+
* Enterprise clients integrate with their license servers by providing a custom adapter.
|
|
87
|
+
* The framework checks license status at key points (startup, feature gating, etc.)
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* import { setLicenseAdapter } from "@spring-systems/core/adapters";
|
|
92
|
+
*
|
|
93
|
+
* setLicenseAdapter({
|
|
94
|
+
* async validateLicense() {
|
|
95
|
+
* const resp = await fetch("/api/license");
|
|
96
|
+
* const data = await resp.json();
|
|
97
|
+
* return { valid: data.active, expiresAt: new Date(data.expiresAt), tier: data.tier };
|
|
98
|
+
* },
|
|
99
|
+
* getLicenseInfo() {
|
|
100
|
+
* return cachedLicenseInfo;
|
|
101
|
+
* },
|
|
102
|
+
* isFeatureLicensed(feature) {
|
|
103
|
+
* return cachedLicenseInfo.features.includes(feature);
|
|
104
|
+
* },
|
|
105
|
+
* });
|
|
106
|
+
* ```
|
|
107
|
+
*
|
|
108
|
+
* @module license-adapter
|
|
109
|
+
*/
|
|
110
|
+
/** Result of a license validation call */
|
|
111
|
+
interface LicenseValidationResult {
|
|
112
|
+
/** Whether the license is currently valid */
|
|
113
|
+
valid: boolean;
|
|
114
|
+
/** When the license expires (undefined = perpetual) */
|
|
115
|
+
expiresAt?: Date;
|
|
116
|
+
/** License tier identifier (e.g. "community", "professional", "enterprise") */
|
|
117
|
+
tier?: string;
|
|
118
|
+
/** Human-readable message (e.g. "License expired", "Trial period") */
|
|
119
|
+
message?: string;
|
|
120
|
+
}
|
|
121
|
+
/** Cached license info (synchronous access) */
|
|
122
|
+
interface LicenseInfo {
|
|
123
|
+
/** License tier (e.g. "standard", "professional", "enterprise") */
|
|
124
|
+
tier: string;
|
|
125
|
+
/** List of licensed feature keys */
|
|
126
|
+
features: string[];
|
|
127
|
+
/** When the license expires */
|
|
128
|
+
expiresAt?: Date;
|
|
129
|
+
}
|
|
130
|
+
interface LicenseAdapter {
|
|
131
|
+
/**
|
|
132
|
+
* Validate the license asynchronously (e.g. call a license server).
|
|
133
|
+
* Called at application startup and periodically.
|
|
134
|
+
*/
|
|
135
|
+
validateLicense(): Promise<LicenseValidationResult>;
|
|
136
|
+
/**
|
|
137
|
+
* Get cached license info synchronously.
|
|
138
|
+
* Returns info from the last successful validation.
|
|
139
|
+
*/
|
|
140
|
+
getLicenseInfo(): LicenseInfo;
|
|
141
|
+
/**
|
|
142
|
+
* Check if a specific feature is licensed.
|
|
143
|
+
* Uses cached license info for synchronous access.
|
|
144
|
+
*/
|
|
145
|
+
isFeatureLicensed(feature: string): boolean;
|
|
146
|
+
}
|
|
147
|
+
declare function setLicenseAdapter(adapter: LicenseAdapter): void;
|
|
148
|
+
declare function getLicenseAdapter(): LicenseAdapter;
|
|
149
|
+
/**
|
|
150
|
+
* Reset the license adapter to the default noop (fail-closed) adapter.
|
|
151
|
+
* For testing only.
|
|
152
|
+
*/
|
|
153
|
+
declare function clearLicenseAdapter(): void;
|
|
154
|
+
/**
|
|
155
|
+
* Convenience: validate the license via the configured adapter.
|
|
156
|
+
*/
|
|
157
|
+
declare function validateLicense(): Promise<LicenseValidationResult>;
|
|
158
|
+
/**
|
|
159
|
+
* Convenience: check if a feature is licensed.
|
|
160
|
+
*/
|
|
161
|
+
declare function isFeatureLicensed(feature: string): boolean;
|
|
162
|
+
/**
|
|
163
|
+
* Convenience: get cached license info.
|
|
164
|
+
*/
|
|
165
|
+
declare function getLicenseInfo(): LicenseInfo;
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Notification adapter — decouples API/validation layers from the UI notification system (react-toastify).
|
|
169
|
+
* Pattern matches setLogAdapter() in logger.ts.
|
|
170
|
+
* @module notification-adapter
|
|
171
|
+
*/
|
|
172
|
+
interface NotificationAdapter {
|
|
173
|
+
error(msg: string): void;
|
|
174
|
+
success(msg: string): void;
|
|
175
|
+
warning(msg: string): void;
|
|
176
|
+
info(msg: string): void;
|
|
177
|
+
}
|
|
178
|
+
declare function setNotificationAdapter(a: NotificationAdapter): void;
|
|
179
|
+
declare function getNotificationAdapter(): NotificationAdapter;
|
|
180
|
+
/** Reset to default notification adapter. For testing/integration teardown only. */
|
|
181
|
+
declare function clearNotificationAdapter(): void;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Telemetry adapter — provides hooks for observability, monitoring, and analytics.
|
|
185
|
+
*
|
|
186
|
+
* Enterprise deployments can integrate with APM tools (DataDog, New Relic, etc.)
|
|
187
|
+
* by setting a custom telemetry adapter. The framework emits telemetry events
|
|
188
|
+
* at key lifecycle points (form loads, API calls, errors, etc.)
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```ts
|
|
192
|
+
* import { setTelemetryAdapter } from "@spring-systems/core/adapters";
|
|
193
|
+
*
|
|
194
|
+
* setTelemetryAdapter({
|
|
195
|
+
* trackEvent(name, data) {
|
|
196
|
+
* datadogRum.addAction(name, data);
|
|
197
|
+
* },
|
|
198
|
+
* trackError(error, context) {
|
|
199
|
+
* Sentry.captureException(error, { extra: context });
|
|
200
|
+
* },
|
|
201
|
+
* trackTiming(metric, durationMs, data) {
|
|
202
|
+
* performance.measure(metric, { duration: durationMs });
|
|
203
|
+
* },
|
|
204
|
+
* });
|
|
205
|
+
* ```
|
|
206
|
+
*
|
|
207
|
+
* @module telemetry-adapter
|
|
208
|
+
*/
|
|
209
|
+
interface TelemetryAdapter {
|
|
210
|
+
/**
|
|
211
|
+
* Track a named event with optional structured data.
|
|
212
|
+
* Called on form save, list load, login, navigation, etc.
|
|
213
|
+
*/
|
|
214
|
+
trackEvent(name: string, data?: Record<string, unknown>): void;
|
|
215
|
+
/**
|
|
216
|
+
* Track an error occurrence with optional context.
|
|
217
|
+
* Called on unhandled errors, API failures, middleware errors, etc.
|
|
218
|
+
*/
|
|
219
|
+
trackError(error: Error | unknown, context?: Record<string, unknown>): void;
|
|
220
|
+
/**
|
|
221
|
+
* Track a timing measurement (e.g. API latency, form render time).
|
|
222
|
+
* @param metric - Metric name (e.g. "api.response_time", "form.load_time")
|
|
223
|
+
* @param durationMs - Duration in milliseconds
|
|
224
|
+
* @param data - Optional context data
|
|
225
|
+
*/
|
|
226
|
+
trackTiming(metric: string, durationMs: number, data?: Record<string, unknown>): void;
|
|
227
|
+
}
|
|
228
|
+
declare function setTelemetryAdapter(adapter: TelemetryAdapter): void;
|
|
229
|
+
declare function getTelemetryAdapter(): TelemetryAdapter;
|
|
230
|
+
/** Reset telemetry adapter to no-op defaults. For testing/integration teardown only. */
|
|
231
|
+
declare function clearTelemetryAdapter(): void;
|
|
232
|
+
/**
|
|
233
|
+
* Convenience helper to track an event via the configured telemetry adapter.
|
|
234
|
+
* Safe to call even if no adapter is configured (no-op).
|
|
235
|
+
*/
|
|
236
|
+
declare function trackEvent(name: string, data?: Record<string, unknown>): void;
|
|
237
|
+
/**
|
|
238
|
+
* Convenience helper to track an error via the configured telemetry adapter.
|
|
239
|
+
*/
|
|
240
|
+
declare function trackError(error: Error | unknown, context?: Record<string, unknown>): void;
|
|
241
|
+
/**
|
|
242
|
+
* Convenience helper to track timing via the configured telemetry adapter.
|
|
243
|
+
*/
|
|
244
|
+
declare function trackTiming(metric: string, durationMs: number, data?: Record<string, unknown>): void;
|
|
245
|
+
|
|
246
|
+
export { type ContentAdapter, type HttpAdapter, type HttpRequest, type LicenseAdapter, type LicenseInfo, type LicenseValidationResult, type NotificationAdapter, type TelemetryAdapter, clearContentAdapter, clearHttpAdapter, clearLicenseAdapter, clearNotificationAdapter, clearTelemetryAdapter, getContentRes, getHttpAdapter, getLicenseAdapter, getLicenseInfo, getNotificationAdapter, getTelemetryAdapter, isFeatureLicensed, setContentAdapter, setHttpAdapter, setLicenseAdapter, setNotificationAdapter, setTelemetryAdapter, trackError, trackEvent, trackTiming, validateLicense };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {
|
|
2
|
+
clearHttpAdapter,
|
|
3
|
+
clearLicenseAdapter,
|
|
4
|
+
clearNotificationAdapter,
|
|
5
|
+
getHttpAdapter,
|
|
6
|
+
getLicenseAdapter,
|
|
7
|
+
getLicenseInfo,
|
|
8
|
+
getNotificationAdapter,
|
|
9
|
+
isFeatureLicensed,
|
|
10
|
+
setHttpAdapter,
|
|
11
|
+
setLicenseAdapter,
|
|
12
|
+
setNotificationAdapter,
|
|
13
|
+
validateLicense
|
|
14
|
+
} from "../chunk-GON7Q32Q.js";
|
|
15
|
+
import {
|
|
16
|
+
clearTelemetryAdapter,
|
|
17
|
+
getTelemetryAdapter,
|
|
18
|
+
setTelemetryAdapter,
|
|
19
|
+
trackError,
|
|
20
|
+
trackEvent,
|
|
21
|
+
trackTiming
|
|
22
|
+
} from "../chunk-S6RPCN5H.js";
|
|
23
|
+
import {
|
|
24
|
+
clearContentAdapter,
|
|
25
|
+
getContentRes,
|
|
26
|
+
setContentAdapter
|
|
27
|
+
} from "../chunk-NQQIVCLX.js";
|
|
28
|
+
import "../chunk-N2L4TUC4.js";
|
|
29
|
+
import "../chunk-RUCXSQEY.js";
|
|
30
|
+
import "../chunk-KX32MU3I.js";
|
|
31
|
+
import "../chunk-EFUBAQCV.js";
|
|
32
|
+
import "../chunk-PT4DIYUK.js";
|
|
33
|
+
export {
|
|
34
|
+
clearContentAdapter,
|
|
35
|
+
clearHttpAdapter,
|
|
36
|
+
clearLicenseAdapter,
|
|
37
|
+
clearNotificationAdapter,
|
|
38
|
+
clearTelemetryAdapter,
|
|
39
|
+
getContentRes,
|
|
40
|
+
getHttpAdapter,
|
|
41
|
+
getLicenseAdapter,
|
|
42
|
+
getLicenseInfo,
|
|
43
|
+
getNotificationAdapter,
|
|
44
|
+
getTelemetryAdapter,
|
|
45
|
+
isFeatureLicensed,
|
|
46
|
+
setContentAdapter,
|
|
47
|
+
setHttpAdapter,
|
|
48
|
+
setLicenseAdapter,
|
|
49
|
+
setNotificationAdapter,
|
|
50
|
+
setTelemetryAdapter,
|
|
51
|
+
trackError,
|
|
52
|
+
trackEvent,
|
|
53
|
+
trackTiming,
|
|
54
|
+
validateLicense
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { L as LogoutHandler, a as LogoutReason } from '../spring-instance-EbUh4mQb.js';
|
|
2
|
+
import '../framework-config-types-DeUbx4bu.js';
|
|
3
|
+
import '../middleware-types-DVG9C1qJ.js';
|
|
4
|
+
import '../form-types-D3MdGpjA.js';
|
|
5
|
+
import '../security-sanitize-Bb0PExM6.js';
|
|
6
|
+
|
|
7
|
+
declare function setLogoutHandler(handler: LogoutHandler): void;
|
|
8
|
+
declare function setAuthenticated(value: boolean): void;
|
|
9
|
+
declare function isAuthenticated(): boolean;
|
|
10
|
+
declare function triggerLogout(reason: LogoutReason): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Clears auth-related fallback and instance state.
|
|
13
|
+
* Intended for test/integration teardown.
|
|
14
|
+
*/
|
|
15
|
+
declare function clearAuthState(): void;
|
|
16
|
+
|
|
17
|
+
export { LogoutHandler, LogoutReason, clearAuthState, isAuthenticated, setAuthenticated, setLogoutHandler, triggerLogout };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
clearAuthState,
|
|
3
|
+
isAuthenticated,
|
|
4
|
+
setAuthenticated,
|
|
5
|
+
setLogoutHandler,
|
|
6
|
+
triggerLogout
|
|
7
|
+
} from "../chunk-HFELOXDQ.js";
|
|
8
|
+
import "../chunk-RUCXSQEY.js";
|
|
9
|
+
import "../chunk-KX32MU3I.js";
|
|
10
|
+
import "../chunk-EFUBAQCV.js";
|
|
11
|
+
import "../chunk-PT4DIYUK.js";
|
|
12
|
+
export {
|
|
13
|
+
clearAuthState,
|
|
14
|
+
isAuthenticated,
|
|
15
|
+
setAuthenticated,
|
|
16
|
+
setLogoutHandler,
|
|
17
|
+
triggerLogout
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// src/config/constants.ts
|
|
2
|
+
var emptyGuid = "00000000-0000-0000-0000-000000000000";
|
|
3
|
+
var DIALOG_CONTENT_SELECTOR = ".spring-dialog-content";
|
|
4
|
+
var DND_TOUCH_CONSTRAINT = { delay: 200, tolerance: 5 };
|
|
5
|
+
var STORAGE_KEYS = {
|
|
6
|
+
LANGUAGE: "language",
|
|
7
|
+
COLOR_THEME: "colorTheme"
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export {
|
|
11
|
+
emptyGuid,
|
|
12
|
+
DIALOG_CONTENT_SELECTOR,
|
|
13
|
+
DND_TOUCH_CONSTRAINT,
|
|
14
|
+
STORAGE_KEYS
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=chunk-5D6XE7NJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config/constants.ts"],"sourcesContent":["/** Empty GUID for new records */\nexport const emptyGuid = \"00000000-0000-0000-0000-000000000000\";\n\n/** Generic interface for select options */\nexport interface CodeList {\n id_public: string;\n name: string;\n code?: string;\n version?: number;\n}\n\n/** Interface for persons (full_name) */\nexport interface CodeListFullName {\n id_public: string;\n full_name: string;\n first_name: string;\n last_name?: string;\n}\n\nexport interface CodeListNumber {\n id_public: number;\n name: string;\n}\n\nexport type Operator = \"=\" | \">\" | \">=\" | \"<\" | \"<=\" | \"!=\" | \"in\" | \"between\";\n\n/** CSS selector for an open dialog (detection in shortcut hooks) */\nexport const DIALOG_CONTENT_SELECTOR = \".spring-dialog-content\";\n\n/** DnD TouchSensor activation constraint (delay + tolerance) */\nexport const DND_TOUCH_CONSTRAINT = { delay: 200, tolerance: 5 } as const;\n\nexport const STORAGE_KEYS = {\n LANGUAGE: \"language\",\n COLOR_THEME: \"colorTheme\",\n} as const;\n\n/** Union type of all storage key values. */\nexport type StorageKey = (typeof STORAGE_KEYS)[keyof typeof STORAGE_KEYS];\n"],"mappings":";AACO,IAAM,YAAY;AA0BlB,IAAM,0BAA0B;AAGhC,IAAM,uBAAuB,EAAE,OAAO,KAAK,WAAW,EAAE;AAExD,IAAM,eAAe;AAAA,EACxB,UAAU;AAAA,EACV,aAAa;AACjB;","names":[]}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SpringConfigError
|
|
3
|
+
} from "./chunk-PT4DIYUK.js";
|
|
4
|
+
|
|
5
|
+
// src/utils/dev-warnings.ts
|
|
6
|
+
function isDevelopmentRuntime() {
|
|
7
|
+
const processNodeEnv = typeof process !== "undefined" ? process.env?.NODE_ENV : void 0;
|
|
8
|
+
if (typeof processNodeEnv === "string") {
|
|
9
|
+
return processNodeEnv !== "production";
|
|
10
|
+
}
|
|
11
|
+
const importMetaEnv = import.meta.env;
|
|
12
|
+
if (!importMetaEnv) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
if (importMetaEnv.DEV === true) return true;
|
|
16
|
+
if (importMetaEnv.PROD === true) return false;
|
|
17
|
+
if (typeof importMetaEnv.MODE === "string") return importMetaEnv.MODE !== "production";
|
|
18
|
+
if (typeof importMetaEnv.NODE_ENV === "string") return importMetaEnv.NODE_ENV !== "production";
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
var __DEV__ = isDevelopmentRuntime();
|
|
22
|
+
function devWarn(context, message) {
|
|
23
|
+
if (__DEV__) {
|
|
24
|
+
console.warn(`[${context}] ${message}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function devThrow(context, message) {
|
|
28
|
+
const full = `[${context}] ${message}`;
|
|
29
|
+
if (__DEV__) {
|
|
30
|
+
throw new Error(full);
|
|
31
|
+
}
|
|
32
|
+
console.warn(full);
|
|
33
|
+
}
|
|
34
|
+
function devAssert(condition, context, message) {
|
|
35
|
+
if (__DEV__ && !condition) {
|
|
36
|
+
throw new Error(`[${context}] ${message}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/instance/current-instance.ts
|
|
41
|
+
var currentInstance = null;
|
|
42
|
+
function getAliveCurrentInstance() {
|
|
43
|
+
if (!currentInstance) return null;
|
|
44
|
+
if (currentInstance.state === "disposed") {
|
|
45
|
+
currentInstance = null;
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
return currentInstance;
|
|
49
|
+
}
|
|
50
|
+
function setSpringInstance(instance) {
|
|
51
|
+
const activeCurrent = getAliveCurrentInstance();
|
|
52
|
+
if (activeCurrent && activeCurrent !== instance) {
|
|
53
|
+
if (typeof window !== "undefined") {
|
|
54
|
+
devWarn(
|
|
55
|
+
"SpringInstance",
|
|
56
|
+
"Replacing an active SpringInstance. If you have multiple SpringProviders, ensure the previous one is unmounted before mounting a new one. For SSR, use React Context instead of the global singleton."
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
currentInstance = instance;
|
|
61
|
+
}
|
|
62
|
+
function getSpringInstance() {
|
|
63
|
+
const instance = getAliveCurrentInstance();
|
|
64
|
+
if (!instance) {
|
|
65
|
+
throw new SpringConfigError(
|
|
66
|
+
"SpringInstance not initialized. Ensure <SpringProvider> is mounted or call setSpringInstance() before accessing the instance."
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
return instance;
|
|
70
|
+
}
|
|
71
|
+
function tryGetSpringInstance() {
|
|
72
|
+
return getAliveCurrentInstance();
|
|
73
|
+
}
|
|
74
|
+
function clearSpringInstance() {
|
|
75
|
+
currentInstance = null;
|
|
76
|
+
}
|
|
77
|
+
function clearSpringInstanceIfCurrent(instance) {
|
|
78
|
+
if (currentInstance === instance) {
|
|
79
|
+
currentInstance = null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export {
|
|
84
|
+
__DEV__,
|
|
85
|
+
devWarn,
|
|
86
|
+
devThrow,
|
|
87
|
+
devAssert,
|
|
88
|
+
setSpringInstance,
|
|
89
|
+
getSpringInstance,
|
|
90
|
+
tryGetSpringInstance,
|
|
91
|
+
clearSpringInstance,
|
|
92
|
+
clearSpringInstanceIfCurrent
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=chunk-EFUBAQCV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/dev-warnings.ts","../src/instance/current-instance.ts"],"sourcesContent":["/**\n * Dev-mode validation helpers.\n * In development: throws errors / logs warnings for invalid usage.\n * In production: silent (no runtime cost beyond a single boolean check).\n * @module dev-warnings\n */\n\nfunction isDevelopmentRuntime(): boolean {\n const processNodeEnv = typeof process !== \"undefined\" ? process.env?.NODE_ENV : undefined;\n if (typeof processNodeEnv === \"string\") {\n return processNodeEnv !== \"production\";\n }\n\n const importMetaEnv = (import.meta as ImportMeta & { env?: Record<string, unknown> }).env;\n if (!importMetaEnv) {\n return false;\n }\n\n if (importMetaEnv.DEV === true) return true;\n if (importMetaEnv.PROD === true) return false;\n if (typeof importMetaEnv.MODE === \"string\") return importMetaEnv.MODE !== \"production\";\n if (typeof importMetaEnv.NODE_ENV === \"string\") return importMetaEnv.NODE_ENV !== \"production\";\n\n return false;\n}\n\nconst __DEV__ = isDevelopmentRuntime();\n\n/**\n * Log a warning in development mode only.\n * No-op in production.\n */\nexport function devWarn(context: string, message: string): void {\n if (__DEV__) {\n console.warn(`[${context}] ${message}`);\n }\n}\n\n/**\n * Throw an error in development mode, log a warning in production.\n * Use for invalid API usage that should be caught during development.\n */\nexport function devThrow(context: string, message: string): void {\n const full = `[${context}] ${message}`;\n if (__DEV__) {\n throw new Error(full);\n }\n console.warn(full);\n}\n\n/**\n * Assert a condition in development mode.\n * Throws if condition is false in dev, no-op in production.\n */\nexport function devAssert(condition: boolean, context: string, message: string): void {\n if (__DEV__ && !condition) {\n throw new Error(`[${context}] ${message}`);\n }\n}\n\nexport { __DEV__ };\n","/**\n * Current instance bridge — the one remaining singleton.\n * Imperative code (API calls, middleware, etc.) reads from getSpringInstance().\n * The SpringProvider in ui sets this via setSpringInstance().\n *\n * **SSR safety note:** This module uses a module-level variable, which means\n * concurrent SSR requests in the same Node.js process will share the same\n * instance. For multi-tenant SSR, use React Context instead of getSpringInstance().\n *\n * @module current-instance\n */\n\nimport { SpringConfigError } from \"../errors/errors\";\nimport { devWarn } from \"../utils/dev-warnings\";\nimport type { SpringInstance } from \"./spring-instance\";\n\nlet currentInstance: SpringInstance | null = null;\n\nfunction getAliveCurrentInstance(): SpringInstance | null {\n if (!currentInstance) return null;\n if (currentInstance.state === \"disposed\") {\n currentInstance = null;\n return null;\n }\n return currentInstance;\n}\n\n/**\n * Set the current SpringInstance. Called once by SpringProvider on mount.\n * Warns if replacing an active (non-disposed) instance — this indicates\n * either multiple SpringProviders or missing cleanup.\n */\nexport function setSpringInstance(instance: SpringInstance): void {\n const activeCurrent = getAliveCurrentInstance();\n if (activeCurrent && activeCurrent !== instance) {\n // During SSR (no `window`), the module singleton persists between requests\n // because useEffect cleanup doesn't run server-side. Only warn on the client\n // where multiple simultaneous SpringProviders indicate a real problem.\n if (typeof window !== \"undefined\") {\n devWarn(\n \"SpringInstance\",\n \"Replacing an active SpringInstance. If you have multiple SpringProviders, \" +\n \"ensure the previous one is unmounted before mounting a new one. \" +\n \"For SSR, use React Context instead of the global singleton.\",\n );\n }\n }\n currentInstance = instance;\n}\n\n/**\n * Get the current SpringInstance. Throws if not set.\n * Use this in imperative code that requires a live instance.\n */\nexport function getSpringInstance(): SpringInstance {\n const instance = getAliveCurrentInstance();\n if (!instance) {\n throw new SpringConfigError(\n \"SpringInstance not initialized. Ensure <SpringProvider> is mounted or call setSpringInstance() before accessing the instance.\",\n );\n }\n return instance;\n}\n\n/**\n * Get the current SpringInstance or null if not yet initialized.\n * Use this in code that may run before SpringProvider mounts (e.g. config setup).\n */\nexport function tryGetSpringInstance(): SpringInstance | null {\n return getAliveCurrentInstance();\n}\n\n/**\n * Clear the current instance. For testing and cleanup only.\n */\nexport function clearSpringInstance(): void {\n currentInstance = null;\n}\n\n/**\n * Clear the current instance only if it matches the provided reference.\n * Prevents disposing an old instance from clearing a newer mounted instance.\n */\nexport function clearSpringInstanceIfCurrent(instance: SpringInstance): void {\n if (currentInstance === instance) {\n currentInstance = null;\n }\n}\n"],"mappings":";;;;;AAOA,SAAS,uBAAgC;AACrC,QAAM,iBAAiB,OAAO,YAAY,cAAc,QAAQ,KAAK,WAAW;AAChF,MAAI,OAAO,mBAAmB,UAAU;AACpC,WAAO,mBAAmB;AAAA,EAC9B;AAEA,QAAM,gBAAiB,YAA+D;AACtF,MAAI,CAAC,eAAe;AAChB,WAAO;AAAA,EACX;AAEA,MAAI,cAAc,QAAQ,KAAM,QAAO;AACvC,MAAI,cAAc,SAAS,KAAM,QAAO;AACxC,MAAI,OAAO,cAAc,SAAS,SAAU,QAAO,cAAc,SAAS;AAC1E,MAAI,OAAO,cAAc,aAAa,SAAU,QAAO,cAAc,aAAa;AAElF,SAAO;AACX;AAEA,IAAM,UAAU,qBAAqB;AAM9B,SAAS,QAAQ,SAAiB,SAAuB;AAC5D,MAAI,SAAS;AACT,YAAQ,KAAK,IAAI,OAAO,KAAK,OAAO,EAAE;AAAA,EAC1C;AACJ;AAMO,SAAS,SAAS,SAAiB,SAAuB;AAC7D,QAAM,OAAO,IAAI,OAAO,KAAK,OAAO;AACpC,MAAI,SAAS;AACT,UAAM,IAAI,MAAM,IAAI;AAAA,EACxB;AACA,UAAQ,KAAK,IAAI;AACrB;AAMO,SAAS,UAAU,WAAoB,SAAiB,SAAuB;AAClF,MAAI,WAAW,CAAC,WAAW;AACvB,UAAM,IAAI,MAAM,IAAI,OAAO,KAAK,OAAO,EAAE;AAAA,EAC7C;AACJ;;;AC1CA,IAAI,kBAAyC;AAE7C,SAAS,0BAAiD;AACtD,MAAI,CAAC,gBAAiB,QAAO;AAC7B,MAAI,gBAAgB,UAAU,YAAY;AACtC,sBAAkB;AAClB,WAAO;AAAA,EACX;AACA,SAAO;AACX;AAOO,SAAS,kBAAkB,UAAgC;AAC9D,QAAM,gBAAgB,wBAAwB;AAC9C,MAAI,iBAAiB,kBAAkB,UAAU;AAI7C,QAAI,OAAO,WAAW,aAAa;AAC/B;AAAA,QACI;AAAA,QACA;AAAA,MAGJ;AAAA,IACJ;AAAA,EACJ;AACA,oBAAkB;AACtB;AAMO,SAAS,oBAAoC;AAChD,QAAM,WAAW,wBAAwB;AACzC,MAAI,CAAC,UAAU;AACX,UAAM,IAAI;AAAA,MACN;AAAA,IACJ;AAAA,EACJ;AACA,SAAO;AACX;AAMO,SAAS,uBAA8C;AAC1D,SAAO,wBAAwB;AACnC;AAKO,SAAS,sBAA4B;AACxC,oBAAkB;AACtB;AAMO,SAAS,6BAA6B,UAAgC;AACzE,MAAI,oBAAoB,UAAU;AAC9B,sBAAkB;AAAA,EACtB;AACJ;","names":[]}
|