@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
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { c as CapabilityMap, F as FrameworkConfigOverrides, a as FrameworkConfig } from './framework-config-types-DeUbx4bu.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Feature capability system for enterprise SPRING deployments.
|
|
5
|
+
*
|
|
6
|
+
* Capabilities allow framework consumers to enable/disable features
|
|
7
|
+
* per client deployment. Plugins can declare required capabilities
|
|
8
|
+
* and the framework checks them at registration time.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* // In project-config.ts:
|
|
13
|
+
* configureCapabilities({
|
|
14
|
+
* charts: true,
|
|
15
|
+
* advancedFiltering: true,
|
|
16
|
+
* bulkOperations: false,
|
|
17
|
+
* export: { enabled: true, formats: ["xlsx", "pdf"] },
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* // In a plugin:
|
|
21
|
+
* if (hasCapability("advancedFiltering")) {
|
|
22
|
+
* registerMiddleware("list:beforeLoad", advancedFilterMiddleware);
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* // In a component:
|
|
26
|
+
* const canExport = hasCapability("export");
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @module capabilities
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
type CapabilityStore = Partial<CapabilityMap> & Record<string, unknown>;
|
|
33
|
+
/**
|
|
34
|
+
* Configure feature capabilities for this deployment.
|
|
35
|
+
* Merges with existing capabilities (does not replace).
|
|
36
|
+
*/
|
|
37
|
+
declare function configureCapabilities(capabilities: Partial<CapabilityMap> & Record<string, unknown>): void;
|
|
38
|
+
/**
|
|
39
|
+
* Check if a capability is enabled.
|
|
40
|
+
* Returns false for unknown/unconfigured capabilities.
|
|
41
|
+
*/
|
|
42
|
+
declare function hasCapability<K extends keyof CapabilityMap>(name: K): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Get the full capability configuration for a feature.
|
|
45
|
+
* Returns undefined if the capability is not configured.
|
|
46
|
+
*/
|
|
47
|
+
declare function getCapability<K extends keyof CapabilityMap>(name: K): CapabilityMap[K] | undefined;
|
|
48
|
+
/** Get all configured capabilities. */
|
|
49
|
+
declare function getCapabilities(): Readonly<CapabilityStore>;
|
|
50
|
+
/**
|
|
51
|
+
* Get the names of all currently registered (configured) capabilities.
|
|
52
|
+
* Useful for introspection and for validating that plugin capability
|
|
53
|
+
* references point to actually-configured features.
|
|
54
|
+
*/
|
|
55
|
+
declare function getRegisteredCapabilityNames(): string[];
|
|
56
|
+
/** Reset all capabilities. For testing only. */
|
|
57
|
+
declare function clearCapabilities(): void;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Centralized framework configuration.
|
|
61
|
+
* Each project sets its own values via configureFramework().
|
|
62
|
+
* The framework reads from getFrameworkConfig().
|
|
63
|
+
* @module framework-config
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Default framework configuration. Exported as the single source of truth
|
|
68
|
+
* for both configureFramework() and createSpringInstance().
|
|
69
|
+
* Deep-frozen to prevent accidental mutation of shared defaults.
|
|
70
|
+
*/
|
|
71
|
+
declare const DEFAULT_FRAMEWORK_CONFIG: FrameworkConfig;
|
|
72
|
+
interface ConfigValidationResult {
|
|
73
|
+
valid: boolean;
|
|
74
|
+
errors: string[];
|
|
75
|
+
warnings: string[];
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Validate a framework configuration and return structured results.
|
|
79
|
+
* Also callable standalone for CI/testing: `validateFrameworkConfig(config)`.
|
|
80
|
+
*/
|
|
81
|
+
declare function validateFrameworkConfig(cfg: FrameworkConfig): ConfigValidationResult;
|
|
82
|
+
declare function createFrameworkConfig(overrides?: FrameworkConfigOverrides): FrameworkConfig;
|
|
83
|
+
declare function configureFramework(overrides: FrameworkConfigOverrides): void;
|
|
84
|
+
declare function getFrameworkConfig(): FrameworkConfig;
|
|
85
|
+
/**
|
|
86
|
+
* Reset framework config to immutable defaults.
|
|
87
|
+
* Intended for test/integration teardown.
|
|
88
|
+
*/
|
|
89
|
+
declare function clearFrameworkConfig(): void;
|
|
90
|
+
/** Max file size for upload — reads from framework config limits.maxFileSize */
|
|
91
|
+
declare function getMaxFileSize(): number;
|
|
92
|
+
/** Debounce delay for autocomplete search — reads from framework config limits.autocompleteDebounceMs */
|
|
93
|
+
declare function getAutocompleteDebounceMs(): number;
|
|
94
|
+
/** Idle timeout for SignalR hub disconnect — reads from framework config limits.signalrIdleTimeoutMs */
|
|
95
|
+
declare function getSignalrIdleTimeoutMs(): number;
|
|
96
|
+
/** SignalR server timeout — reads from framework config limits.signalrServerTimeoutMs */
|
|
97
|
+
declare function getSignalrServerTimeoutMs(): number;
|
|
98
|
+
/** SignalR keep-alive interval — reads from framework config limits.signalrKeepAliveIntervalMs */
|
|
99
|
+
declare function getSignalrKeepAliveIntervalMs(): number;
|
|
100
|
+
/** SignalR reconnect delay sequence — reads from framework config limits.signalrReconnectDelaysMs */
|
|
101
|
+
declare function getSignalrReconnectDelaysMs(): readonly number[];
|
|
102
|
+
/** Idle session timeout — reads from framework config limits.idleSessionTimeoutMs */
|
|
103
|
+
declare function getIdleSessionTimeoutMs(): number;
|
|
104
|
+
/** API request timeout — reads from framework config api.timeoutMs */
|
|
105
|
+
declare function getApiTimeoutMs(): number;
|
|
106
|
+
/** Default list page size — reads from framework config api.defaultPageSize */
|
|
107
|
+
declare function getApiDefaultPageSize(): number;
|
|
108
|
+
declare function getSessionCookieName(prefix: string): string;
|
|
109
|
+
declare function getSecureSessionCookieName(prefix: string): string;
|
|
110
|
+
/**
|
|
111
|
+
* Apply the fallback config to a SpringInstance.
|
|
112
|
+
* Called by SpringProvider after instance creation to pick up early configureFramework() calls.
|
|
113
|
+
*/
|
|
114
|
+
declare function applyFallbackConfig(instance: {
|
|
115
|
+
core: {
|
|
116
|
+
config: FrameworkConfig;
|
|
117
|
+
};
|
|
118
|
+
}): void;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Runtime environment variable keys injected on the client.
|
|
122
|
+
* Values are read from `window.__RUNTIME_ENV__`.
|
|
123
|
+
*
|
|
124
|
+
* Consumers can register additional keys via `registerRuntimeEnvKeys()`.
|
|
125
|
+
* @module runtime-env-config
|
|
126
|
+
*/
|
|
127
|
+
/** Default framework runtime env keys. */
|
|
128
|
+
declare const RUNTIME_ENV_KEYS: readonly ["IMAGE_TAG", "ENVIRONMENT", "BUILD_NUM", "BUILD_DATE"];
|
|
129
|
+
type RuntimeEnvKey = (typeof RUNTIME_ENV_KEYS)[number];
|
|
130
|
+
type RuntimeEnv = Partial<Record<string, string>>;
|
|
131
|
+
/**
|
|
132
|
+
* Register additional runtime environment keys.
|
|
133
|
+
* Call this before runtime env payload is consumed by the app bootstrap.
|
|
134
|
+
*/
|
|
135
|
+
declare function registerRuntimeEnvKeys(...keys: string[]): void;
|
|
136
|
+
/** Returns all registered runtime env keys (defaults + consumer-registered). */
|
|
137
|
+
declare function getRuntimeEnvKeys(): readonly string[];
|
|
138
|
+
/** Clear consumer-registered runtime env keys. For testing only. */
|
|
139
|
+
declare function clearRuntimeEnvKeys(): void;
|
|
140
|
+
declare global {
|
|
141
|
+
interface Window {
|
|
142
|
+
__RUNTIME_ENV__?: RuntimeEnv;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
declare function getRuntimeVar(key: string): string;
|
|
146
|
+
declare function getImageTag(): string;
|
|
147
|
+
|
|
148
|
+
export { getSignalrReconnectDelaysMs as A, getSignalrServerTimeoutMs as B, type ConfigValidationResult as C, DEFAULT_FRAMEWORK_CONFIG as D, registerRuntimeEnvKeys as E, validateFrameworkConfig as F, RUNTIME_ENV_KEYS as R, configureFramework as a, getCapability as b, configureCapabilities as c, getFrameworkConfig as d, type RuntimeEnv as e, type RuntimeEnvKey as f, getCapabilities as g, hasCapability as h, applyFallbackConfig as i, clearCapabilities as j, clearFrameworkConfig as k, clearRuntimeEnvKeys as l, createFrameworkConfig as m, getApiDefaultPageSize as n, getApiTimeoutMs as o, getAutocompleteDebounceMs as p, getIdleSessionTimeoutMs as q, getImageTag as r, getMaxFileSize as s, getRegisteredCapabilityNames as t, getRuntimeEnvKeys as u, getRuntimeVar as v, getSecureSessionCookieName as w, getSessionCookieName as x, getSignalrIdleTimeoutMs as y, getSignalrKeepAliveIntervalMs as z };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type SecurityLogScalar = string | number | boolean | null;
|
|
2
|
+
interface SecurityLogData {
|
|
3
|
+
[key: string]: SecurityLogValue;
|
|
4
|
+
}
|
|
5
|
+
type SecurityLogValue = SecurityLogScalar | SecurityLogData | SecurityLogValue[];
|
|
6
|
+
declare function isSensitiveSecurityKey(key: string): boolean;
|
|
7
|
+
declare function sanitizeSecurityData(data?: SecurityLogData): SecurityLogData | undefined;
|
|
8
|
+
|
|
9
|
+
export { type SecurityLogData as S, type SecurityLogScalar as a, type SecurityLogValue as b, isSensitiveSecurityKey as i, sanitizeSecurityData as s };
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { a as FrameworkConfig } from './framework-config-types-DeUbx4bu.js';
|
|
2
|
+
import { M as MiddlewareSlot, b as MiddlewareEntry } from './middleware-types-DVG9C1qJ.js';
|
|
3
|
+
import { V as ValidatorFn } from './form-types-D3MdGpjA.js';
|
|
4
|
+
import { S as SecurityLogData } from './security-sanitize-Bb0PExM6.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* SpringInstance — central state container for the SPRING framework.
|
|
8
|
+
* Replaces module-level singletons with a per-instance state tree.
|
|
9
|
+
*
|
|
10
|
+
* IMPORTANT: This file imports only from type-only or non-circular modules.
|
|
11
|
+
* Type imports from config/framework-config-types.ts are safe (pure type file).
|
|
12
|
+
* @module spring-instance
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** Content resolution adapter (i18n) */
|
|
16
|
+
interface InstanceContentAdapter {
|
|
17
|
+
getRes(key: string): string;
|
|
18
|
+
}
|
|
19
|
+
/** Notification adapter (toast/snackbar) */
|
|
20
|
+
interface InstanceNotificationAdapter {
|
|
21
|
+
error(msg: string): void;
|
|
22
|
+
success(msg: string): void;
|
|
23
|
+
warning(msg: string): void;
|
|
24
|
+
info(msg: string): void;
|
|
25
|
+
}
|
|
26
|
+
/** Security event types emitted by the framework. Extensible via `string & {}`. */
|
|
27
|
+
type SecurityEventType = "login" | "logout" | "password_change" | "session_timeout" | "rate_limit_exceeded" | "auth_failed" | "session_expired" | "csrf_mismatch" | "token_refresh_failed" | (string & {});
|
|
28
|
+
/** Log adapter (error/warn/security) */
|
|
29
|
+
type BivariantCallback<TArgs extends unknown[], TResult = void> = {
|
|
30
|
+
bivarianceHack: (...args: TArgs) => TResult;
|
|
31
|
+
}["bivarianceHack"];
|
|
32
|
+
interface InstanceLogAdapter {
|
|
33
|
+
onError?: (context: string, error?: unknown) => void;
|
|
34
|
+
onWarn?: (context: string, message?: string) => void;
|
|
35
|
+
onSecurityEvent?: BivariantCallback<[event: SecurityEventType, data?: SecurityLogData]>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Instance lifecycle state.
|
|
39
|
+
* - `creating`: Instance is being constructed (before init)
|
|
40
|
+
* - `ready`: Instance is fully initialized and operational
|
|
41
|
+
* - `disposing`: Instance is in cleanup process
|
|
42
|
+
* - `disposed`: Instance has been disposed and should not be used
|
|
43
|
+
*/
|
|
44
|
+
type InstanceLifecycleState = "creating" | "ready" | "disposing" | "disposed";
|
|
45
|
+
/** Built-in logout reasons. Extensible via `string & {}` to allow custom reasons from plugins. */
|
|
46
|
+
type LogoutReason = "unauthorized" | "proxy_error" | "token_missing" | "manual" | (string & {});
|
|
47
|
+
type LogoutHandler = (reason: LogoutReason) => void | Promise<void>;
|
|
48
|
+
type EventHandler<T = unknown> = (payload: T) => void | Promise<void>;
|
|
49
|
+
interface HandlerEntry<T = unknown> {
|
|
50
|
+
handler: EventHandler<T>;
|
|
51
|
+
once: boolean;
|
|
52
|
+
}
|
|
53
|
+
interface RequestHook {
|
|
54
|
+
(url: string, config: {
|
|
55
|
+
method: string;
|
|
56
|
+
headers: Record<string, string>;
|
|
57
|
+
}): void;
|
|
58
|
+
}
|
|
59
|
+
interface ResponseHook {
|
|
60
|
+
(url: string, status: number, data: unknown): void;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Extensible UI state interface for SpringInstance.
|
|
64
|
+
* Plugins and packages can extend this via declaration merging:
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* declare module "@spring-systems/core/instance" {
|
|
69
|
+
* interface SpringUIState {
|
|
70
|
+
* myPlugin: { count: number };
|
|
71
|
+
* }
|
|
72
|
+
* }
|
|
73
|
+
* ```
|
|
74
|
+
*
|
|
75
|
+
* The base interface includes an index signature to support dynamic
|
|
76
|
+
* registry keys (slots, renderers, etc.) stored with string/symbol keys.
|
|
77
|
+
*/
|
|
78
|
+
interface SpringUIState {
|
|
79
|
+
[key: string | symbol]: unknown;
|
|
80
|
+
}
|
|
81
|
+
/** Core framework state — config, adapters, logging, auth, middleware, validation */
|
|
82
|
+
interface SpringCoreState {
|
|
83
|
+
/** Framework configuration — fully typed via FrameworkConfig from framework-config-types.ts */
|
|
84
|
+
config: FrameworkConfig;
|
|
85
|
+
contentAdapter: InstanceContentAdapter;
|
|
86
|
+
notificationAdapter: InstanceNotificationAdapter;
|
|
87
|
+
logAdapter: InstanceLogAdapter;
|
|
88
|
+
logoutHandler: LogoutHandler | null;
|
|
89
|
+
authenticated: boolean;
|
|
90
|
+
logoutInFlight: Promise<void> | null;
|
|
91
|
+
/** Event bus listeners map — keyed by event name. Readonly ref — mutate contents via Map methods, never reassign. */
|
|
92
|
+
readonly eventListeners: Map<string, HandlerEntry[]>;
|
|
93
|
+
readonly middlewareRegistry: Map<MiddlewareSlot, MiddlewareEntry<any>[]>;
|
|
94
|
+
readonly validatorRegistry: Map<string, ValidatorFn>;
|
|
95
|
+
}
|
|
96
|
+
/** API client state — auth tokens, request tracking, hooks */
|
|
97
|
+
interface SpringApiState {
|
|
98
|
+
authToken: string | null;
|
|
99
|
+
/** Readonly ref — mutate contents via Set methods, never reassign. */
|
|
100
|
+
readonly requestControllers: Set<AbortController>;
|
|
101
|
+
requestHook: RequestHook | null;
|
|
102
|
+
responseHook: ResponseHook | null;
|
|
103
|
+
apiPrefix: string;
|
|
104
|
+
sessionExpiredCodes: Set<string> | undefined;
|
|
105
|
+
}
|
|
106
|
+
/** Central framework instance. All mutable state lives here. */
|
|
107
|
+
interface SpringInstance {
|
|
108
|
+
readonly id: string;
|
|
109
|
+
/** Current lifecycle state of this instance */
|
|
110
|
+
readonly state: InstanceLifecycleState;
|
|
111
|
+
readonly core: SpringCoreState;
|
|
112
|
+
readonly api: SpringApiState;
|
|
113
|
+
/** Extensible UI state — plugins extend via declaration merging on SpringUIState */
|
|
114
|
+
readonly ui: SpringUIState;
|
|
115
|
+
/** Dispose this instance — clears all state, aborts requests, runs plugin cleanups */
|
|
116
|
+
dispose(): void;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export type { HandlerEntry as H, InstanceContentAdapter as I, LogoutHandler as L, RequestHook as R, SecurityEventType as S, LogoutReason as a, InstanceNotificationAdapter as b, InstanceLogAdapter as c, SpringInstance as d, InstanceLifecycleState as e, ResponseHook as f, SpringApiState as g, SpringCoreState as h, SpringUIState as i };
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { F as FrameworkConfigOverrides } from '../framework-config-types-DeUbx4bu.js';
|
|
2
|
+
import { I as InstanceContentAdapter, b as InstanceNotificationAdapter, c as InstanceLogAdapter, d as SpringInstance } from '../spring-instance-EbUh4mQb.js';
|
|
3
|
+
import { SpringPlugin } from '../plugins/index.js';
|
|
4
|
+
import { S as SecurityLogData } from '../security-sanitize-Bb0PExM6.js';
|
|
5
|
+
import '../middleware-types-DVG9C1qJ.js';
|
|
6
|
+
import '../form-types-D3MdGpjA.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Testing utilities for SPRING framework consumers and plugin authors.
|
|
10
|
+
*
|
|
11
|
+
* Provides factory functions to create isolated SpringInstances for tests
|
|
12
|
+
* with pre-configured mocks and adapters.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { createTestInstance, mockAdapters } from "@spring-systems/core/testing";
|
|
17
|
+
*
|
|
18
|
+
* describe("my plugin", () => {
|
|
19
|
+
* let instance: SpringInstance;
|
|
20
|
+
*
|
|
21
|
+
* beforeEach(() => {
|
|
22
|
+
* instance = createTestInstance({
|
|
23
|
+
* config: { app: { name: "Test" } },
|
|
24
|
+
* plugins: [myPlugin],
|
|
25
|
+
* });
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* afterEach(() => {
|
|
29
|
+
* instance.dispose();
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* it("registers middleware", () => {
|
|
33
|
+
* expect(getMiddlewareRunner("form:beforeSave")).toBeDefined();
|
|
34
|
+
* });
|
|
35
|
+
* });
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @module test-utils
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
interface CreateTestInstanceOptions {
|
|
42
|
+
/** Framework config overrides for this test instance */
|
|
43
|
+
config?: FrameworkConfigOverrides;
|
|
44
|
+
/** Plugins to apply to the test instance */
|
|
45
|
+
plugins?: SpringPlugin[];
|
|
46
|
+
/** Whether to set this as the global current instance (default: true) */
|
|
47
|
+
setGlobal?: boolean;
|
|
48
|
+
/** Custom content adapter (defaults to identity function) */
|
|
49
|
+
contentAdapter?: InstanceContentAdapter;
|
|
50
|
+
/** Custom notification adapter (defaults to no-op) */
|
|
51
|
+
notificationAdapter?: InstanceNotificationAdapter;
|
|
52
|
+
/** Custom log adapter (defaults to no-op) */
|
|
53
|
+
logAdapter?: InstanceLogAdapter;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Create an isolated SpringInstance for testing.
|
|
57
|
+
* Automatically sets it as the global current instance (unless setGlobal: false).
|
|
58
|
+
* Call `instance.dispose()` in afterEach to clean up.
|
|
59
|
+
*/
|
|
60
|
+
declare function createTestInstance(options?: CreateTestInstanceOptions): SpringInstance;
|
|
61
|
+
/** Pre-built mock adapters for testing */
|
|
62
|
+
declare const mockAdapters: {
|
|
63
|
+
/** Content adapter that returns the key itself (identity) */
|
|
64
|
+
readonly content: () => InstanceContentAdapter;
|
|
65
|
+
/** Content adapter that returns a custom mapping */
|
|
66
|
+
readonly contentWithMessages: (messages: Record<string, string>) => InstanceContentAdapter;
|
|
67
|
+
/** Notification adapter that collects all notifications for assertions */
|
|
68
|
+
readonly notificationCollector: () => {
|
|
69
|
+
adapter: {
|
|
70
|
+
error: (msg: string) => number;
|
|
71
|
+
success: (msg: string) => number;
|
|
72
|
+
warning: (msg: string) => number;
|
|
73
|
+
info: (msg: string) => number;
|
|
74
|
+
};
|
|
75
|
+
calls: {
|
|
76
|
+
type: "error" | "success" | "warning" | "info";
|
|
77
|
+
msg: string;
|
|
78
|
+
}[];
|
|
79
|
+
clear: () => void;
|
|
80
|
+
};
|
|
81
|
+
/** Log adapter that collects all log entries for assertions */
|
|
82
|
+
readonly logCollector: () => {
|
|
83
|
+
adapter: {
|
|
84
|
+
onError: (ctx: string, err?: unknown) => number;
|
|
85
|
+
onWarn: (ctx: string, msg?: string) => number;
|
|
86
|
+
onSecurityEvent: (evt: unknown, data?: SecurityLogData) => number;
|
|
87
|
+
};
|
|
88
|
+
errors: {
|
|
89
|
+
context: string;
|
|
90
|
+
error?: unknown;
|
|
91
|
+
}[];
|
|
92
|
+
warnings: {
|
|
93
|
+
context: string;
|
|
94
|
+
message?: string;
|
|
95
|
+
}[];
|
|
96
|
+
securityEvents: {
|
|
97
|
+
event: unknown;
|
|
98
|
+
data?: SecurityLogData;
|
|
99
|
+
}[];
|
|
100
|
+
};
|
|
101
|
+
/** Silent no-op adapters (suppress all output) */
|
|
102
|
+
readonly silent: {
|
|
103
|
+
readonly content: {
|
|
104
|
+
getRes: (key: string) => string;
|
|
105
|
+
};
|
|
106
|
+
readonly notification: {
|
|
107
|
+
error: (_msg: string) => void;
|
|
108
|
+
success: (_msg: string) => void;
|
|
109
|
+
warning: (_msg: string) => void;
|
|
110
|
+
info: (_msg: string) => void;
|
|
111
|
+
};
|
|
112
|
+
readonly log: {};
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
/** Boundary cast for tests — replaces the `as unknown as X` pattern in a single place.
|
|
116
|
+
* Usage: `castTo<FormStoreApi>({ getState: vi.fn() })` instead of `{ getState: vi.fn() } as unknown as FormStoreApi`
|
|
117
|
+
*/
|
|
118
|
+
declare function castTo<T>(value: unknown): T;
|
|
119
|
+
/** Runtime assertion that a value is defined. Returns the value with a non-nullable type.
|
|
120
|
+
* Usage: `assertDefined(arr[0]).field` instead of `arr[0]!.field`
|
|
121
|
+
*/
|
|
122
|
+
declare function assertDefined<T>(val: T | undefined | null, msg?: string): T;
|
|
123
|
+
/**
|
|
124
|
+
* Resets singleton/fallback runtime state across core modules.
|
|
125
|
+
* Useful in integration tests that run multiple app lifecycles in one process.
|
|
126
|
+
*/
|
|
127
|
+
declare function resetCoreRuntimeState(): void;
|
|
128
|
+
|
|
129
|
+
export { type CreateTestInstanceOptions, assertDefined, castTo, createTestInstance, mockAdapters, resetCoreRuntimeState };
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createSpringInstance
|
|
3
|
+
} from "../chunk-F2SIMWZ5.js";
|
|
4
|
+
import {
|
|
5
|
+
applyPlugins,
|
|
6
|
+
disposePlugins
|
|
7
|
+
} from "../chunk-GXU75LQX.js";
|
|
8
|
+
import {
|
|
9
|
+
eventBus
|
|
10
|
+
} from "../chunk-OSSX443T.js";
|
|
11
|
+
import {
|
|
12
|
+
clearAllMiddleware
|
|
13
|
+
} from "../chunk-MEWPYTWC.js";
|
|
14
|
+
import {
|
|
15
|
+
clearRuntimeEnvKeys
|
|
16
|
+
} from "../chunk-UDT2RPX2.js";
|
|
17
|
+
import {
|
|
18
|
+
clearCapabilities
|
|
19
|
+
} from "../chunk-S7MKRNMI.js";
|
|
20
|
+
import {
|
|
21
|
+
clearFrameworkConfig
|
|
22
|
+
} from "../chunk-F7WUQJH7.js";
|
|
23
|
+
import {
|
|
24
|
+
clearValidators
|
|
25
|
+
} from "../chunk-RRWKDFAB.js";
|
|
26
|
+
import "../chunk-QAVWXARR.js";
|
|
27
|
+
import {
|
|
28
|
+
clearAuthState
|
|
29
|
+
} from "../chunk-HFELOXDQ.js";
|
|
30
|
+
import {
|
|
31
|
+
clearHttpAdapter,
|
|
32
|
+
clearLicenseAdapter,
|
|
33
|
+
clearNotificationAdapter
|
|
34
|
+
} from "../chunk-GON7Q32Q.js";
|
|
35
|
+
import {
|
|
36
|
+
clearTelemetryAdapter
|
|
37
|
+
} from "../chunk-S6RPCN5H.js";
|
|
38
|
+
import {
|
|
39
|
+
clearContentAdapter
|
|
40
|
+
} from "../chunk-NQQIVCLX.js";
|
|
41
|
+
import "../chunk-N2L4TUC4.js";
|
|
42
|
+
import "../chunk-RUCXSQEY.js";
|
|
43
|
+
import {
|
|
44
|
+
clearLogAdapter,
|
|
45
|
+
resetLogLevel
|
|
46
|
+
} from "../chunk-KX32MU3I.js";
|
|
47
|
+
import {
|
|
48
|
+
clearSpringInstance,
|
|
49
|
+
setSpringInstance
|
|
50
|
+
} from "../chunk-EFUBAQCV.js";
|
|
51
|
+
import "../chunk-PT4DIYUK.js";
|
|
52
|
+
|
|
53
|
+
// src/testing/test-utils.ts
|
|
54
|
+
function createTestInstance(options = {}) {
|
|
55
|
+
const instance = createSpringInstance(options.config);
|
|
56
|
+
if (options.contentAdapter) {
|
|
57
|
+
instance.core.contentAdapter = options.contentAdapter;
|
|
58
|
+
}
|
|
59
|
+
if (options.notificationAdapter) {
|
|
60
|
+
instance.core.notificationAdapter = options.notificationAdapter;
|
|
61
|
+
}
|
|
62
|
+
if (options.logAdapter) {
|
|
63
|
+
instance.core.logAdapter = options.logAdapter;
|
|
64
|
+
}
|
|
65
|
+
if (options.setGlobal !== false) {
|
|
66
|
+
setSpringInstance(instance);
|
|
67
|
+
}
|
|
68
|
+
if (options.plugins && options.plugins.length > 0) {
|
|
69
|
+
applyPlugins(instance, options.plugins);
|
|
70
|
+
}
|
|
71
|
+
const originalDispose = instance.dispose.bind(instance);
|
|
72
|
+
instance.dispose = () => {
|
|
73
|
+
disposePlugins(instance);
|
|
74
|
+
originalDispose();
|
|
75
|
+
if (options.setGlobal !== false) {
|
|
76
|
+
clearSpringInstance();
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
return instance;
|
|
80
|
+
}
|
|
81
|
+
var mockAdapters = {
|
|
82
|
+
/** Content adapter that returns the key itself (identity) */
|
|
83
|
+
content: () => ({
|
|
84
|
+
getRes: (key) => key
|
|
85
|
+
}),
|
|
86
|
+
/** Content adapter that returns a custom mapping */
|
|
87
|
+
contentWithMessages: (messages) => ({
|
|
88
|
+
getRes: (key) => messages[key] ?? `[${key}]`
|
|
89
|
+
}),
|
|
90
|
+
/** Notification adapter that collects all notifications for assertions */
|
|
91
|
+
notificationCollector: () => {
|
|
92
|
+
const calls = [];
|
|
93
|
+
return {
|
|
94
|
+
adapter: {
|
|
95
|
+
error: (msg) => calls.push({ type: "error", msg }),
|
|
96
|
+
success: (msg) => calls.push({ type: "success", msg }),
|
|
97
|
+
warning: (msg) => calls.push({ type: "warning", msg }),
|
|
98
|
+
info: (msg) => calls.push({ type: "info", msg })
|
|
99
|
+
},
|
|
100
|
+
calls,
|
|
101
|
+
clear: () => {
|
|
102
|
+
calls.length = 0;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
},
|
|
106
|
+
/** Log adapter that collects all log entries for assertions */
|
|
107
|
+
logCollector: () => {
|
|
108
|
+
const errors = [];
|
|
109
|
+
const warnings = [];
|
|
110
|
+
const securityEvents = [];
|
|
111
|
+
return {
|
|
112
|
+
adapter: {
|
|
113
|
+
onError: (ctx, err) => errors.push({ context: ctx, error: err }),
|
|
114
|
+
onWarn: (ctx, msg) => warnings.push({ context: ctx, message: msg }),
|
|
115
|
+
onSecurityEvent: (evt, data) => securityEvents.push({ event: evt, data })
|
|
116
|
+
},
|
|
117
|
+
errors,
|
|
118
|
+
warnings,
|
|
119
|
+
securityEvents
|
|
120
|
+
};
|
|
121
|
+
},
|
|
122
|
+
/** Silent no-op adapters (suppress all output) */
|
|
123
|
+
silent: {
|
|
124
|
+
content: { getRes: (key) => key },
|
|
125
|
+
notification: {
|
|
126
|
+
error: (_msg) => {
|
|
127
|
+
},
|
|
128
|
+
success: (_msg) => {
|
|
129
|
+
},
|
|
130
|
+
warning: (_msg) => {
|
|
131
|
+
},
|
|
132
|
+
info: (_msg) => {
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
log: {}
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
function castTo(value) {
|
|
139
|
+
return value;
|
|
140
|
+
}
|
|
141
|
+
function assertDefined(val, msg) {
|
|
142
|
+
if (val === void 0 || val === null) {
|
|
143
|
+
throw new Error(msg ?? "Expected value to be defined, but got " + String(val));
|
|
144
|
+
}
|
|
145
|
+
return val;
|
|
146
|
+
}
|
|
147
|
+
function resetCoreRuntimeState() {
|
|
148
|
+
eventBus.clearAll();
|
|
149
|
+
clearAllMiddleware();
|
|
150
|
+
clearValidators();
|
|
151
|
+
clearCapabilities();
|
|
152
|
+
clearFrameworkConfig();
|
|
153
|
+
clearRuntimeEnvKeys();
|
|
154
|
+
clearAuthState();
|
|
155
|
+
clearContentAdapter();
|
|
156
|
+
clearNotificationAdapter();
|
|
157
|
+
clearHttpAdapter();
|
|
158
|
+
clearLicenseAdapter();
|
|
159
|
+
clearTelemetryAdapter();
|
|
160
|
+
clearLogAdapter();
|
|
161
|
+
resetLogLevel();
|
|
162
|
+
clearSpringInstance();
|
|
163
|
+
}
|
|
164
|
+
export {
|
|
165
|
+
assertDefined,
|
|
166
|
+
castTo,
|
|
167
|
+
createTestInstance,
|
|
168
|
+
mockAdapters,
|
|
169
|
+
resetCoreRuntimeState
|
|
170
|
+
};
|
|
171
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/testing/test-utils.ts"],"sourcesContent":["/**\n * Testing utilities for SPRING framework consumers and plugin authors.\n *\n * Provides factory functions to create isolated SpringInstances for tests\n * with pre-configured mocks and adapters.\n *\n * @example\n * ```ts\n * import { createTestInstance, mockAdapters } from \"@spring-systems/core/testing\";\n *\n * describe(\"my plugin\", () => {\n * let instance: SpringInstance;\n *\n * beforeEach(() => {\n * instance = createTestInstance({\n * config: { app: { name: \"Test\" } },\n * plugins: [myPlugin],\n * });\n * });\n *\n * afterEach(() => {\n * instance.dispose();\n * });\n *\n * it(\"registers middleware\", () => {\n * expect(getMiddlewareRunner(\"form:beforeSave\")).toBeDefined();\n * });\n * });\n * ```\n *\n * @module test-utils\n */\n\nimport {\n clearContentAdapter,\n clearHttpAdapter,\n clearLicenseAdapter,\n clearNotificationAdapter,\n clearTelemetryAdapter,\n} from \"../adapters\";\nimport { clearAuthState } from \"../auth/auth-handler\";\nimport { clearCapabilities } from \"../config/capabilities\";\nimport { clearFrameworkConfig } from \"../config/framework-config\";\nimport type { FrameworkConfigOverrides } from \"../config/framework-config-types\";\nimport { clearRuntimeEnvKeys } from \"../config/runtime-env-config\";\nimport { eventBus } from \"../events/event-bus\";\nimport { createSpringInstance } from \"../instance/create-instance\";\nimport { clearSpringInstance,setSpringInstance } from \"../instance/current-instance\";\nimport type { InstanceContentAdapter, InstanceLogAdapter,InstanceNotificationAdapter,SpringInstance } from \"../instance/spring-instance\";\nimport { clearLogAdapter, resetLogLevel } from \"../logger/logger\";\nimport { clearAllMiddleware } from \"../middleware/middleware-registry\";\nimport type { SpringPlugin } from \"../plugins/plugin\";\nimport { applyPlugins, disposePlugins } from \"../plugins/plugin\";\nimport type { SecurityLogData } from \"../utils/security-sanitize\";\nimport { clearValidators } from \"../validation/validations\";\n\nexport interface CreateTestInstanceOptions {\n /** Framework config overrides for this test instance */\n config?: FrameworkConfigOverrides;\n /** Plugins to apply to the test instance */\n plugins?: SpringPlugin[];\n /** Whether to set this as the global current instance (default: true) */\n setGlobal?: boolean;\n /** Custom content adapter (defaults to identity function) */\n contentAdapter?: InstanceContentAdapter;\n /** Custom notification adapter (defaults to no-op) */\n notificationAdapter?: InstanceNotificationAdapter;\n /** Custom log adapter (defaults to no-op) */\n logAdapter?: InstanceLogAdapter;\n}\n\n/**\n * Create an isolated SpringInstance for testing.\n * Automatically sets it as the global current instance (unless setGlobal: false).\n * Call `instance.dispose()` in afterEach to clean up.\n */\nexport function createTestInstance(options: CreateTestInstanceOptions = {}): SpringInstance {\n const instance = createSpringInstance(options.config);\n\n // Apply mock adapters\n if (options.contentAdapter) {\n instance.core.contentAdapter = options.contentAdapter;\n }\n if (options.notificationAdapter) {\n instance.core.notificationAdapter = options.notificationAdapter;\n }\n if (options.logAdapter) {\n instance.core.logAdapter = options.logAdapter;\n }\n\n // Set as global if requested\n if (options.setGlobal !== false) {\n setSpringInstance(instance);\n }\n\n // Apply plugins\n if (options.plugins && options.plugins.length > 0) {\n applyPlugins(instance, options.plugins);\n }\n\n // Augment dispose to also clear global and dispose plugins\n const originalDispose = instance.dispose.bind(instance);\n instance.dispose = () => {\n disposePlugins(instance);\n originalDispose();\n if (options.setGlobal !== false) {\n clearSpringInstance();\n }\n };\n\n return instance;\n}\n\n/** Pre-built mock adapters for testing */\nexport const mockAdapters = {\n /** Content adapter that returns the key itself (identity) */\n content: (): InstanceContentAdapter => ({\n getRes: (key: string) => key,\n }),\n\n /** Content adapter that returns a custom mapping */\n contentWithMessages: (messages: Record<string, string>): InstanceContentAdapter => ({\n getRes: (key: string) => messages[key] ?? `[${key}]`,\n }),\n\n /** Notification adapter that collects all notifications for assertions */\n notificationCollector: () => {\n const calls: Array<{ type: \"error\" | \"success\" | \"warning\" | \"info\"; msg: string }> = [];\n return {\n adapter: {\n error: (msg: string) => calls.push({ type: \"error\", msg }),\n success: (msg: string) => calls.push({ type: \"success\", msg }),\n warning: (msg: string) => calls.push({ type: \"warning\", msg }),\n info: (msg: string) => calls.push({ type: \"info\", msg }),\n } satisfies InstanceNotificationAdapter,\n calls,\n clear: () => { calls.length = 0; },\n };\n },\n\n /** Log adapter that collects all log entries for assertions */\n logCollector: () => {\n const errors: Array<{ context: string; error?: unknown }> = [];\n const warnings: Array<{ context: string; message?: string }> = [];\n const securityEvents: Array<{ event: unknown; data?: SecurityLogData }> = [];\n return {\n adapter: {\n onError: (ctx: string, err?: unknown) => errors.push({ context: ctx, error: err }),\n onWarn: (ctx: string, msg?: string) => warnings.push({ context: ctx, message: msg }),\n onSecurityEvent: (evt: unknown, data?: SecurityLogData) => securityEvents.push({ event: evt, data }),\n } satisfies InstanceLogAdapter,\n errors,\n warnings,\n securityEvents,\n };\n },\n\n /** Silent no-op adapters (suppress all output) */\n silent: {\n content: { getRes: (key: string) => key } satisfies InstanceContentAdapter,\n notification: {\n error: (_msg: string) => {},\n success: (_msg: string) => {},\n warning: (_msg: string) => {},\n info: (_msg: string) => {},\n } satisfies InstanceNotificationAdapter,\n log: {} satisfies InstanceLogAdapter,\n },\n} as const;\n\n/** Boundary cast for tests — replaces the `as unknown as X` pattern in a single place.\n * Usage: `castTo<FormStoreApi>({ getState: vi.fn() })` instead of `{ getState: vi.fn() } as unknown as FormStoreApi`\n */\nexport function castTo<T>(value: unknown): T {\n return value as T;\n}\n\n/** Runtime assertion that a value is defined. Returns the value with a non-nullable type.\n * Usage: `assertDefined(arr[0]).field` instead of `arr[0]!.field`\n */\nexport function assertDefined<T>(val: T | undefined | null, msg?: string): T {\n if (val === undefined || val === null) {\n throw new Error(msg ?? \"Expected value to be defined, but got \" + String(val));\n }\n return val;\n}\n\n/**\n * Resets singleton/fallback runtime state across core modules.\n * Useful in integration tests that run multiple app lifecycles in one process.\n */\nexport function resetCoreRuntimeState(): void {\n eventBus.clearAll();\n clearAllMiddleware();\n clearValidators();\n clearCapabilities();\n clearFrameworkConfig();\n clearRuntimeEnvKeys();\n\n clearAuthState();\n clearContentAdapter();\n clearNotificationAdapter();\n clearHttpAdapter();\n clearLicenseAdapter();\n clearTelemetryAdapter();\n clearLogAdapter();\n resetLogLevel();\n\n clearSpringInstance();\n}\n"],"mappings":"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","names":[]}
|