@spring-systems/core 0.8.6 → 0.8.9
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/dist/adapters/index.js +1 -56
- package/dist/auth/index.js +1 -19
- package/dist/chunk-3OMNT22N.js +1 -0
- package/dist/chunk-4KRUU6MS.js +1 -0
- package/dist/chunk-6J2VFOKL.js +1 -0
- package/dist/chunk-7P4BJDQR.js +1 -0
- package/dist/chunk-AMXSATFF.js +1 -0
- package/dist/chunk-BMIRKMVX.js +1 -0
- package/dist/chunk-EVDFSWPU.js +1 -0
- package/dist/chunk-F3VXVDPQ.js +1 -0
- package/dist/chunk-GSQE2NEY.js +1 -0
- package/dist/chunk-HUASNNWD.js +1 -0
- package/dist/chunk-ICKHSEIX.js +1 -0
- package/dist/chunk-JRHMAY5G.js +1 -0
- package/dist/chunk-MNLYYTGZ.js +7 -0
- package/dist/chunk-OOVZTF74.js +1 -0
- package/dist/chunk-PNDXLNCU.js +1 -0
- package/dist/chunk-R3XYEEGR.js +1 -0
- package/dist/chunk-RKLYBW3O.js +1 -0
- package/dist/chunk-RVQHSQYF.js +3 -0
- package/dist/chunk-UT6X6RQM.js +1 -0
- package/dist/chunk-Y6DB43IE.js +3 -0
- package/dist/chunk-YMSSF2ZU.js +1 -0
- package/dist/config/index.js +1 -109
- package/dist/devtools/index.js +1 -67
- package/dist/errors/index.js +1 -21
- package/dist/events/index.js +1 -12
- package/dist/i18n/index.js +1 -7
- package/dist/index.js +1 -42
- package/dist/instance/index.js +1 -37
- package/dist/logger/index.js +1 -27
- package/dist/middleware/index.js +1 -23
- package/dist/plugins/index.js +1 -16
- package/dist/testing/index.js +1 -171
- package/dist/types/index.js +1 -72
- package/dist/utils/index.d.ts +43 -1
- package/dist/utils/index.js +1 -772
- package/dist/validation/index.js +1 -147
- package/package.json +1 -1
- package/dist/adapters/index.js.map +0 -1
- package/dist/auth/index.js.map +0 -1
- package/dist/chunk-2PJWFA5S.js +0 -393
- package/dist/chunk-2PJWFA5S.js.map +0 -1
- package/dist/chunk-EFUBAQCV.js +0 -94
- package/dist/chunk-EFUBAQCV.js.map +0 -1
- package/dist/chunk-F2SIMWZ5.js +0 -173
- package/dist/chunk-F2SIMWZ5.js.map +0 -1
- package/dist/chunk-F7WUQJH7.js +0 -399
- package/dist/chunk-F7WUQJH7.js.map +0 -1
- package/dist/chunk-GON7Q32Q.js +0 -176
- package/dist/chunk-GON7Q32Q.js.map +0 -1
- package/dist/chunk-GXU75LQX.js +0 -182
- package/dist/chunk-GXU75LQX.js.map +0 -1
- package/dist/chunk-HFELOXDQ.js +0 -110
- package/dist/chunk-HFELOXDQ.js.map +0 -1
- package/dist/chunk-KX32MU3I.js +0 -190
- package/dist/chunk-KX32MU3I.js.map +0 -1
- package/dist/chunk-MEWPYTWC.js +0 -284
- package/dist/chunk-MEWPYTWC.js.map +0 -1
- package/dist/chunk-N2L4TUC4.js +0 -34
- package/dist/chunk-N2L4TUC4.js.map +0 -1
- package/dist/chunk-NQQIVCLX.js +0 -47
- package/dist/chunk-NQQIVCLX.js.map +0 -1
- package/dist/chunk-OSSX443T.js +0 -146
- package/dist/chunk-OSSX443T.js.map +0 -1
- package/dist/chunk-PT4DIYUK.js +0 -78
- package/dist/chunk-PT4DIYUK.js.map +0 -1
- package/dist/chunk-QAVWXARR.js +0 -51
- package/dist/chunk-QAVWXARR.js.map +0 -1
- package/dist/chunk-RRWKDFAB.js +0 -143
- package/dist/chunk-RRWKDFAB.js.map +0 -1
- package/dist/chunk-RUCXSQEY.js +0 -42
- package/dist/chunk-RUCXSQEY.js.map +0 -1
- package/dist/chunk-S6RPCN5H.js +0 -64
- package/dist/chunk-S6RPCN5H.js.map +0 -1
- package/dist/chunk-S7MKRNMI.js +0 -153
- package/dist/chunk-S7MKRNMI.js.map +0 -1
- package/dist/chunk-SQB4F3EF.js +0 -55
- package/dist/chunk-SQB4F3EF.js.map +0 -1
- package/dist/chunk-UDT2RPX2.js +0 -43
- package/dist/chunk-UDT2RPX2.js.map +0 -1
- package/dist/chunk-VRMVN2UM.js +0 -17
- package/dist/chunk-VRMVN2UM.js.map +0 -1
- package/dist/config/index.js.map +0 -1
- package/dist/devtools/index.js.map +0 -1
- package/dist/errors/index.js.map +0 -1
- package/dist/events/index.js.map +0 -1
- package/dist/i18n/index.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/instance/index.js.map +0 -1
- package/dist/logger/index.js.map +0 -1
- package/dist/middleware/index.js.map +0 -1
- package/dist/plugins/index.js.map +0 -1
- package/dist/testing/index.js.map +0 -1
- package/dist/types/index.js.map +0 -1
- package/dist/utils/index.js.map +0 -1
- package/dist/validation/index.js.map +0 -1
package/dist/chunk-GXU75LQX.js
DELETED
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getRegisteredCapabilityNames,
|
|
3
|
-
hasCapability
|
|
4
|
-
} from "./chunk-S7MKRNMI.js";
|
|
5
|
-
import {
|
|
6
|
-
logError,
|
|
7
|
-
logWarn
|
|
8
|
-
} from "./chunk-KX32MU3I.js";
|
|
9
|
-
import {
|
|
10
|
-
devThrow,
|
|
11
|
-
devWarn
|
|
12
|
-
} from "./chunk-EFUBAQCV.js";
|
|
13
|
-
import {
|
|
14
|
-
SpringPluginError
|
|
15
|
-
} from "./chunk-PT4DIYUK.js";
|
|
16
|
-
|
|
17
|
-
// src/plugins/plugin.ts
|
|
18
|
-
function isDescriptor(plugin) {
|
|
19
|
-
return typeof plugin === "object" && plugin !== null && "setup" in plugin;
|
|
20
|
-
}
|
|
21
|
-
function validateDescriptor(plugin, index) {
|
|
22
|
-
if (!plugin.name || typeof plugin.name !== "string" || plugin.name.trim().length === 0) {
|
|
23
|
-
devWarn("Plugin", `Plugin[${index}]: descriptor.name must be a non-empty string`);
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
if (typeof plugin.setup !== "function") {
|
|
27
|
-
devWarn("Plugin", `Plugin "${plugin.name}": descriptor.setup must be a function`);
|
|
28
|
-
return false;
|
|
29
|
-
}
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
function getPluginName(plugin, index) {
|
|
33
|
-
return isDescriptor(plugin) ? plugin.name : `plugin[${index}]`;
|
|
34
|
-
}
|
|
35
|
-
function topologicalSort(plugins) {
|
|
36
|
-
const descriptors = [];
|
|
37
|
-
const functions = [];
|
|
38
|
-
for (const p of plugins) {
|
|
39
|
-
if (isDescriptor(p)) {
|
|
40
|
-
descriptors.push(p);
|
|
41
|
-
} else {
|
|
42
|
-
functions.push(p);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
if (descriptors.every((d) => !d.requires || d.requires.length === 0)) {
|
|
46
|
-
return plugins;
|
|
47
|
-
}
|
|
48
|
-
const nameMap = /* @__PURE__ */ new Map();
|
|
49
|
-
for (const d of descriptors) {
|
|
50
|
-
if (nameMap.has(d.name)) {
|
|
51
|
-
throw new SpringPluginError(
|
|
52
|
-
`Duplicate plugin name "${d.name}". Each plugin must have a unique name. If you need to override a plugin, remove the original from the plugins array first.`,
|
|
53
|
-
d.name
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
nameMap.set(d.name, d);
|
|
57
|
-
}
|
|
58
|
-
const inDegree = /* @__PURE__ */ new Map();
|
|
59
|
-
const adjacency = /* @__PURE__ */ new Map();
|
|
60
|
-
for (const d of descriptors) {
|
|
61
|
-
if (!inDegree.has(d.name)) inDegree.set(d.name, 0);
|
|
62
|
-
if (!adjacency.has(d.name)) adjacency.set(d.name, []);
|
|
63
|
-
for (const req of d.requires ?? []) {
|
|
64
|
-
if (!nameMap.has(req)) {
|
|
65
|
-
devThrow("Plugin", `Plugin "${d.name}" requires "${req}" which is not registered. Add "${req}" to the plugins array.`);
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
if (!adjacency.has(req)) adjacency.set(req, []);
|
|
69
|
-
const deps = adjacency.get(req);
|
|
70
|
-
if (!deps) continue;
|
|
71
|
-
deps.push(d.name);
|
|
72
|
-
inDegree.set(d.name, (inDegree.get(d.name) ?? 0) + 1);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
const queue = [];
|
|
76
|
-
for (const [name, deg] of inDegree) {
|
|
77
|
-
if (deg === 0) queue.push(name);
|
|
78
|
-
}
|
|
79
|
-
const sorted = [];
|
|
80
|
-
while (queue.length > 0) {
|
|
81
|
-
const name = queue.shift();
|
|
82
|
-
if (!name) break;
|
|
83
|
-
const desc = nameMap.get(name);
|
|
84
|
-
if (desc) sorted.push(desc);
|
|
85
|
-
for (const neighbor of adjacency.get(name) ?? []) {
|
|
86
|
-
const deg = (inDegree.get(neighbor) ?? 1) - 1;
|
|
87
|
-
inDegree.set(neighbor, deg);
|
|
88
|
-
if (deg === 0) queue.push(neighbor);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
if (sorted.length < descriptors.length) {
|
|
92
|
-
const missing = descriptors.filter((d) => !sorted.includes(d)).map((d) => d.name);
|
|
93
|
-
throw new SpringPluginError(
|
|
94
|
-
`Circular dependency detected among plugins: ${missing.join(", ")}. Review the 'requires' arrays to break the cycle.`,
|
|
95
|
-
missing[0] ?? "unknown"
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
return [...functions, ...sorted];
|
|
99
|
-
}
|
|
100
|
-
var CLEANUP_KEY = /* @__PURE__ */ Symbol.for("spring:pluginCleanups");
|
|
101
|
-
var LOADED_KEY = /* @__PURE__ */ Symbol.for("spring:loadedPlugins");
|
|
102
|
-
function applyPlugins(instance, plugins) {
|
|
103
|
-
const sorted = topologicalSort(plugins);
|
|
104
|
-
const cleanups = [];
|
|
105
|
-
const loaded = [];
|
|
106
|
-
for (let i = 0; i < sorted.length; i++) {
|
|
107
|
-
const plugin = sorted[i];
|
|
108
|
-
if (!plugin) continue;
|
|
109
|
-
if (typeof plugin !== "function" && !isDescriptor(plugin)) {
|
|
110
|
-
devWarn("Plugin", `Plugin[${i}] is neither a function nor a valid descriptor \u2014 skipping`);
|
|
111
|
-
continue;
|
|
112
|
-
}
|
|
113
|
-
if (isDescriptor(plugin) && !validateDescriptor(plugin, i)) {
|
|
114
|
-
continue;
|
|
115
|
-
}
|
|
116
|
-
const name = getPluginName(plugin, i);
|
|
117
|
-
if (isDescriptor(plugin) && plugin.capabilities) {
|
|
118
|
-
const registeredNames = getRegisteredCapabilityNames();
|
|
119
|
-
const unregistered = plugin.capabilities.filter(
|
|
120
|
-
(c) => !registeredNames.includes(c)
|
|
121
|
-
);
|
|
122
|
-
if (unregistered.length > 0) {
|
|
123
|
-
devWarn(
|
|
124
|
-
"Plugin",
|
|
125
|
-
`Plugin "${name}" references unregistered capabilities: ${unregistered.join(", ")}. Did you forget to call configureCapabilities()? Registered: [${registeredNames.join(", ")}]`
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
const missing = plugin.capabilities.filter((c) => !hasCapability(c));
|
|
129
|
-
if (missing.length > 0) {
|
|
130
|
-
logWarn("Plugin", `Skipping "${name}" \u2014 missing capabilities: ${missing.join(", ")}`);
|
|
131
|
-
continue;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
try {
|
|
135
|
-
const setupFn = isDescriptor(plugin) ? plugin.setup : plugin;
|
|
136
|
-
const setupCleanup = setupFn(instance);
|
|
137
|
-
if (typeof setupCleanup === "function") {
|
|
138
|
-
cleanups.push(setupCleanup);
|
|
139
|
-
} else if (setupCleanup !== void 0) {
|
|
140
|
-
logWarn("Plugin", `Plugin "${name}" returned non-function cleanup; ignoring.`);
|
|
141
|
-
}
|
|
142
|
-
if (isDescriptor(plugin) && plugin.cleanup !== void 0) {
|
|
143
|
-
if (typeof plugin.cleanup === "function") {
|
|
144
|
-
cleanups.push(plugin.cleanup);
|
|
145
|
-
} else {
|
|
146
|
-
logWarn("Plugin", `Plugin "${name}" has non-function descriptor.cleanup; ignoring.`);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
loaded.push({
|
|
150
|
-
name,
|
|
151
|
-
version: isDescriptor(plugin) ? plugin.version : void 0
|
|
152
|
-
});
|
|
153
|
-
} catch (e) {
|
|
154
|
-
logError(`Plugin setup failed: ${name}`, e);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
instance.ui[CLEANUP_KEY] = cleanups;
|
|
158
|
-
instance.ui[LOADED_KEY] = loaded;
|
|
159
|
-
}
|
|
160
|
-
function disposePlugins(instance) {
|
|
161
|
-
const cleanups = instance.ui[CLEANUP_KEY];
|
|
162
|
-
if (!cleanups) return;
|
|
163
|
-
for (const cleanup of cleanups) {
|
|
164
|
-
try {
|
|
165
|
-
cleanup();
|
|
166
|
-
} catch (e) {
|
|
167
|
-
logError("Plugin cleanup failed", e);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
delete instance.ui[CLEANUP_KEY];
|
|
171
|
-
delete instance.ui[LOADED_KEY];
|
|
172
|
-
}
|
|
173
|
-
function getLoadedPlugins(instance) {
|
|
174
|
-
return instance.ui[LOADED_KEY] ?? [];
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
export {
|
|
178
|
-
applyPlugins,
|
|
179
|
-
disposePlugins,
|
|
180
|
-
getLoadedPlugins
|
|
181
|
-
};
|
|
182
|
-
//# sourceMappingURL=chunk-GXU75LQX.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/plugins/plugin.ts"],"sourcesContent":["/**\n * Plugin system for the SPRING framework.\n *\n * A plugin can be either:\n * - A simple setup function (backward compatible): `(instance) => cleanup?`\n * - A plugin descriptor with metadata: `{ name, version, setup, ... }`\n *\n * Plugin descriptors enable:\n * - Dependency declaration and topological ordering\n * - Capability requirements checking\n * - Version compatibility validation\n * - Plugin discovery and introspection\n *\n * @module plugin\n */\n\nimport { getRegisteredCapabilityNames,hasCapability } from \"../config/capabilities\";\nimport { SpringPluginError } from \"../errors/errors\";\nimport type { SpringInstance } from \"../instance/spring-instance\";\nimport { logError, logWarn } from \"../logger/logger\";\nimport type { FormDataValue, FormStoreState } from \"../types/form-types\";\nimport type { ColumnType } from \"../types/grid-types\";\nimport { devThrow, devWarn } from \"../utils/dev-warnings\";\n\n// ---------------------------------------------------------------------------\n// Types for plugin authors (column renderers)\n// ---------------------------------------------------------------------------\n\n/** Column renderer info passed to custom renderers. */\nexport interface PluginColumnRendererInfo {\n field: string;\n type: ColumnType;\n title: string;\n suffix?: string;\n decimals?: number;\n name?: string;\n}\n\n/**\n * Column renderer function signature.\n * Returns a React node (any valid JSX return value).\n */\nexport type PluginColumnRenderer = (\n value: FormDataValue,\n row: FormStoreState,\n column: PluginColumnRendererInfo,\n) => unknown;\n\n// ---------------------------------------------------------------------------\n// Plugin types\n// ---------------------------------------------------------------------------\n\n/** Simple plugin function (backward compatible) */\nexport type SpringPluginFn = (instance: SpringInstance) => void | (() => void);\n\n/**\n * Plugin descriptor with metadata for enterprise plugin management.\n *\n * @example\n * ```ts\n * const auditPlugin: SpringPluginDescriptor = {\n * name: \"@spring-systems/audit\",\n * version: \"1.0.0\",\n * requires: [\"@spring-systems/core-validators\"],\n * capabilities: [\"advancedFiltering\"],\n * setup(instance) {\n * registerMiddleware(\"form:beforeSave\", auditMiddleware);\n * return () => { cleanup(); };\n * },\n * };\n * ```\n */\nexport interface SpringPluginDescriptor {\n /** Unique plugin name. Use npm-style scoped names (e.g. \"@myorg/plugin-name\"). */\n name: string;\n /** Semver version string. */\n version?: string;\n /** Names of plugins that must be loaded before this one. */\n requires?: string[];\n /** Capability keys that must be enabled for this plugin to activate. */\n capabilities?: string[];\n /** Plugin setup function. Returns optional cleanup. */\n setup: SpringPluginFn;\n /**\n * Explicit cleanup function. Called by `disposePlugins()` alongside any\n * cleanup returned from `setup()`. Also available for direct invocation\n * by consumers who hold a reference to the descriptor.\n */\n cleanup?: () => void;\n}\n\n/** A SPRING plugin — either a simple function or a descriptor with metadata. */\nexport type SpringPlugin = SpringPluginFn | SpringPluginDescriptor;\n\nfunction isDescriptor(plugin: SpringPlugin): plugin is SpringPluginDescriptor {\n return typeof plugin === \"object\" && plugin !== null && \"setup\" in plugin;\n}\n\nfunction validateDescriptor(plugin: SpringPluginDescriptor, index: number): boolean {\n if (!plugin.name || typeof plugin.name !== \"string\" || plugin.name.trim().length === 0) {\n devWarn(\"Plugin\", `Plugin[${index}]: descriptor.name must be a non-empty string`);\n return false;\n }\n if (typeof plugin.setup !== \"function\") {\n devWarn(\"Plugin\", `Plugin \"${plugin.name}\": descriptor.setup must be a function`);\n return false;\n }\n return true;\n}\n\nfunction getPluginName(plugin: SpringPlugin, index: number): string {\n return isDescriptor(plugin) ? plugin.name : `plugin[${index}]`;\n}\n\n// ---------------------------------------------------------------------------\n// Topological sort for plugin dependencies\n// ---------------------------------------------------------------------------\n\nfunction topologicalSort(plugins: SpringPlugin[]): SpringPlugin[] {\n // Separate descriptors (with potential deps) from simple functions\n const descriptors: SpringPluginDescriptor[] = [];\n const functions: SpringPluginFn[] = [];\n\n for (const p of plugins) {\n if (isDescriptor(p)) {\n descriptors.push(p);\n } else {\n functions.push(p);\n }\n }\n\n // If no descriptors have dependencies, skip sorting\n if (descriptors.every((d) => !d.requires || d.requires.length === 0)) {\n return plugins;\n }\n\n // Build adjacency map\n const nameMap = new Map<string, SpringPluginDescriptor>();\n for (const d of descriptors) {\n if (nameMap.has(d.name)) {\n throw new SpringPluginError(\n `Duplicate plugin name \"${d.name}\". ` +\n \"Each plugin must have a unique name. If you need to override a plugin, \" +\n \"remove the original from the plugins array first.\",\n d.name,\n );\n }\n nameMap.set(d.name, d);\n }\n\n // Kahn's algorithm for topological sort\n const inDegree = new Map<string, number>();\n const adjacency = new Map<string, string[]>();\n\n for (const d of descriptors) {\n if (!inDegree.has(d.name)) inDegree.set(d.name, 0);\n if (!adjacency.has(d.name)) adjacency.set(d.name, []);\n\n for (const req of d.requires ?? []) {\n if (!nameMap.has(req)) {\n devThrow(\"Plugin\", `Plugin \"${d.name}\" requires \"${req}\" which is not registered. Add \"${req}\" to the plugins array.`);\n continue;\n }\n if (!adjacency.has(req)) adjacency.set(req, []);\n const deps = adjacency.get(req);\n if (!deps) continue;\n deps.push(d.name);\n inDegree.set(d.name, (inDegree.get(d.name) ?? 0) + 1);\n }\n }\n\n const queue: string[] = [];\n for (const [name, deg] of inDegree) {\n if (deg === 0) queue.push(name);\n }\n\n const sorted: SpringPluginDescriptor[] = [];\n while (queue.length > 0) {\n const name = queue.shift();\n if (!name) break;\n const desc = nameMap.get(name);\n if (desc) sorted.push(desc);\n for (const neighbor of adjacency.get(name) ?? []) {\n const deg = (inDegree.get(neighbor) ?? 1) - 1;\n inDegree.set(neighbor, deg);\n if (deg === 0) queue.push(neighbor);\n }\n }\n\n if (sorted.length < descriptors.length) {\n const missing = descriptors.filter((d) => !sorted.includes(d)).map((d) => d.name);\n throw new SpringPluginError(\n `Circular dependency detected among plugins: ${missing.join(\", \")}. ` +\n \"Review the 'requires' arrays to break the cycle.\",\n missing[0] ?? \"unknown\",\n );\n }\n\n // Simple functions first, then sorted descriptors\n return [...functions, ...sorted];\n}\n\n// ---------------------------------------------------------------------------\n// Plugin lifecycle\n// ---------------------------------------------------------------------------\n\nconst CLEANUP_KEY: unique symbol = Symbol.for(\"spring:pluginCleanups\");\nconst LOADED_KEY: unique symbol = Symbol.for(\"spring:loadedPlugins\");\n\ninterface LoadedPluginInfo {\n name: string;\n version?: string;\n}\n\n/**\n * Apply an array of plugins to a SpringInstance.\n * Plugins with dependencies are topologically sorted.\n * Each may return a cleanup function stored on the instance.\n *\n * Setup errors are caught and logged — a failing plugin does not block others.\n *\n * @param instance - The SpringInstance to apply plugins to\n * @param plugins - Array of plugins (simple functions or descriptors with metadata)\n */\nexport function applyPlugins(instance: SpringInstance, plugins: SpringPlugin[]): void {\n const sorted = topologicalSort(plugins);\n const cleanups: (() => void)[] = [];\n const loaded: LoadedPluginInfo[] = [];\n\n for (let i = 0; i < sorted.length; i++) {\n const plugin = sorted[i];\n if (!plugin) continue;\n\n // Validate plugin structure\n if (typeof plugin !== \"function\" && !isDescriptor(plugin)) {\n devWarn(\"Plugin\", `Plugin[${i}] is neither a function nor a valid descriptor — skipping`);\n continue;\n }\n if (isDescriptor(plugin) && !validateDescriptor(plugin, i)) {\n continue;\n }\n\n const name = getPluginName(plugin, i);\n\n // Check capability requirements\n if (isDescriptor(plugin) && plugin.capabilities) {\n // Warn about capabilities that haven't been registered at all\n const registeredNames = getRegisteredCapabilityNames();\n const unregistered = plugin.capabilities.filter(\n (c) => !registeredNames.includes(c),\n );\n if (unregistered.length > 0) {\n devWarn(\n \"Plugin\",\n `Plugin \"${name}\" references unregistered capabilities: ${unregistered.join(\", \")}. ` +\n `Did you forget to call configureCapabilities()? Registered: [${registeredNames.join(\", \")}]`,\n );\n }\n\n const missing = plugin.capabilities.filter((c) => !hasCapability(c as keyof import(\"../config/capabilities\").CapabilityMap));\n if (missing.length > 0) {\n logWarn(\"Plugin\", `Skipping \"${name}\" — missing capabilities: ${missing.join(\", \")}`);\n continue;\n }\n }\n\n try {\n const setupFn = isDescriptor(plugin) ? plugin.setup : plugin;\n const setupCleanup = setupFn(instance);\n if (typeof setupCleanup === \"function\") {\n cleanups.push(setupCleanup);\n } else if (setupCleanup !== undefined) {\n logWarn(\"Plugin\", `Plugin \"${name}\" returned non-function cleanup; ignoring.`);\n }\n if (isDescriptor(plugin) && plugin.cleanup !== undefined) {\n if (typeof plugin.cleanup === \"function\") {\n cleanups.push(plugin.cleanup);\n } else {\n logWarn(\"Plugin\", `Plugin \"${name}\" has non-function descriptor.cleanup; ignoring.`);\n }\n }\n loaded.push({\n name,\n version: isDescriptor(plugin) ? plugin.version : undefined,\n });\n } catch (e: unknown) {\n logError(`Plugin setup failed: ${name}`, e);\n }\n }\n\n instance.ui[CLEANUP_KEY] = cleanups;\n instance.ui[LOADED_KEY] = loaded;\n}\n\n/**\n * Run all cleanup functions stored by `applyPlugins()` and remove them\n * from the instance. Errors during cleanup are caught and logged.\n *\n * @param instance - The SpringInstance whose plugins should be disposed\n */\nexport function disposePlugins(instance: SpringInstance): void {\n const cleanups = instance.ui[CLEANUP_KEY] as (() => void)[] | undefined;\n if (!cleanups) return;\n for (const cleanup of cleanups) {\n try {\n cleanup();\n } catch (e: unknown) {\n logError(\"Plugin cleanup failed\", e);\n }\n }\n delete instance.ui[CLEANUP_KEY];\n delete instance.ui[LOADED_KEY];\n}\n\n/**\n * Get the list of loaded plugins for the given instance.\n * Useful for debugging and introspection.\n */\nexport function getLoadedPlugins(instance: SpringInstance): ReadonlyArray<LoadedPluginInfo> {\n return (instance.ui[LOADED_KEY] as LoadedPluginInfo[]) ?? [];\n}\n"],"mappings":"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","names":[]}
|
package/dist/chunk-HFELOXDQ.js
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
registerFallbackMigration
|
|
3
|
-
} from "./chunk-RUCXSQEY.js";
|
|
4
|
-
import {
|
|
5
|
-
logError
|
|
6
|
-
} from "./chunk-KX32MU3I.js";
|
|
7
|
-
import {
|
|
8
|
-
tryGetSpringInstance
|
|
9
|
-
} from "./chunk-EFUBAQCV.js";
|
|
10
|
-
|
|
11
|
-
// src/auth/auth-handler.ts
|
|
12
|
-
var fallbackLogoutHandler = null;
|
|
13
|
-
var fallbackAuthenticated = false;
|
|
14
|
-
var fallbackLogoutInFlight = null;
|
|
15
|
-
registerFallbackMigration((instance) => {
|
|
16
|
-
if (fallbackLogoutHandler) {
|
|
17
|
-
instance.core.logoutHandler = fallbackLogoutHandler;
|
|
18
|
-
}
|
|
19
|
-
if (fallbackAuthenticated) {
|
|
20
|
-
instance.core.authenticated = fallbackAuthenticated;
|
|
21
|
-
}
|
|
22
|
-
if (fallbackLogoutInFlight) {
|
|
23
|
-
const migratingPromise = fallbackLogoutInFlight;
|
|
24
|
-
instance.core.logoutInFlight = migratingPromise;
|
|
25
|
-
void migratingPromise.finally(() => {
|
|
26
|
-
if (instance.core.logoutInFlight === migratingPromise) {
|
|
27
|
-
instance.core.logoutInFlight = null;
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
function setLogoutHandler(handler) {
|
|
33
|
-
const instance = tryGetSpringInstance();
|
|
34
|
-
if (instance) {
|
|
35
|
-
instance.core.logoutHandler = handler;
|
|
36
|
-
} else {
|
|
37
|
-
fallbackLogoutHandler = handler;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
function setAuthenticated(value) {
|
|
41
|
-
const instance = tryGetSpringInstance();
|
|
42
|
-
if (instance) {
|
|
43
|
-
instance.core.authenticated = value;
|
|
44
|
-
} else {
|
|
45
|
-
fallbackAuthenticated = value;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
function isAuthenticated() {
|
|
49
|
-
const instance = tryGetSpringInstance();
|
|
50
|
-
return instance ? instance.core.authenticated : fallbackAuthenticated;
|
|
51
|
-
}
|
|
52
|
-
async function triggerLogout(reason) {
|
|
53
|
-
const instance = tryGetSpringInstance();
|
|
54
|
-
const getLogoutHandler = () => instance ? instance.core.logoutHandler : fallbackLogoutHandler;
|
|
55
|
-
const getLogoutInFlight = () => instance ? instance.core.logoutInFlight : fallbackLogoutInFlight;
|
|
56
|
-
const setLogoutInFlight = (p) => {
|
|
57
|
-
if (instance) {
|
|
58
|
-
instance.core.logoutInFlight = p;
|
|
59
|
-
} else {
|
|
60
|
-
fallbackLogoutInFlight = p;
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
const setAuth = (v) => {
|
|
64
|
-
if (instance) {
|
|
65
|
-
instance.core.authenticated = v;
|
|
66
|
-
} else {
|
|
67
|
-
fallbackAuthenticated = v;
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
const handler = getLogoutHandler();
|
|
71
|
-
if (!handler) return;
|
|
72
|
-
if (reason === "unauthorized" || reason === "token_missing") {
|
|
73
|
-
setAuth(false);
|
|
74
|
-
}
|
|
75
|
-
const inFlight = getLogoutInFlight();
|
|
76
|
-
if (inFlight) {
|
|
77
|
-
return inFlight;
|
|
78
|
-
}
|
|
79
|
-
const promise = (async () => {
|
|
80
|
-
try {
|
|
81
|
-
await handler(reason);
|
|
82
|
-
} catch (e) {
|
|
83
|
-
logError("Auth.logout", e);
|
|
84
|
-
} finally {
|
|
85
|
-
setLogoutInFlight(null);
|
|
86
|
-
}
|
|
87
|
-
})();
|
|
88
|
-
setLogoutInFlight(promise);
|
|
89
|
-
await promise;
|
|
90
|
-
}
|
|
91
|
-
function clearAuthState() {
|
|
92
|
-
const instance = tryGetSpringInstance();
|
|
93
|
-
if (instance) {
|
|
94
|
-
instance.core.logoutHandler = null;
|
|
95
|
-
instance.core.authenticated = false;
|
|
96
|
-
instance.core.logoutInFlight = null;
|
|
97
|
-
}
|
|
98
|
-
fallbackLogoutHandler = null;
|
|
99
|
-
fallbackAuthenticated = false;
|
|
100
|
-
fallbackLogoutInFlight = null;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export {
|
|
104
|
-
setLogoutHandler,
|
|
105
|
-
setAuthenticated,
|
|
106
|
-
isAuthenticated,
|
|
107
|
-
triggerLogout,
|
|
108
|
-
clearAuthState
|
|
109
|
-
};
|
|
110
|
-
//# sourceMappingURL=chunk-HFELOXDQ.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/auth/auth-handler.ts"],"sourcesContent":["import { tryGetSpringInstance } from \"../instance/current-instance\";\nimport { registerFallbackMigration } from \"../instance/fallback-bridge\";\nimport type { LogoutHandler,LogoutReason } from \"../instance/spring-instance\";\nimport { logError } from \"../logger/logger\";\n\nexport type { LogoutHandler,LogoutReason };\n\n// Fallback state for code that runs before SpringInstance is created\nlet fallbackLogoutHandler: LogoutHandler | null = null;\nlet fallbackAuthenticated = false;\nlet fallbackLogoutInFlight: Promise<void> | null = null;\n\n// Migrate fallback auth state to SpringInstance when SpringProvider mounts\nregisterFallbackMigration((instance) => {\n if (fallbackLogoutHandler) {\n instance.core.logoutHandler = fallbackLogoutHandler;\n }\n if (fallbackAuthenticated) {\n instance.core.authenticated = fallbackAuthenticated;\n }\n if (fallbackLogoutInFlight) {\n const migratingPromise = fallbackLogoutInFlight;\n instance.core.logoutInFlight = migratingPromise;\n void migratingPromise.finally(() => {\n if (instance.core.logoutInFlight === migratingPromise) {\n instance.core.logoutInFlight = null;\n }\n });\n }\n});\n\nexport function setLogoutHandler(handler: LogoutHandler): void {\n const instance = tryGetSpringInstance();\n if (instance) {\n instance.core.logoutHandler = handler;\n } else {\n fallbackLogoutHandler = handler;\n }\n}\n\nexport function setAuthenticated(value: boolean): void {\n const instance = tryGetSpringInstance();\n if (instance) {\n instance.core.authenticated = value;\n } else {\n fallbackAuthenticated = value;\n }\n}\n\nexport function isAuthenticated(): boolean {\n const instance = tryGetSpringInstance();\n return instance ? instance.core.authenticated : fallbackAuthenticated;\n}\n\nexport async function triggerLogout(reason: LogoutReason): Promise<void> {\n const instance = tryGetSpringInstance();\n\n const getLogoutHandler = () => instance ? instance.core.logoutHandler : fallbackLogoutHandler;\n const getLogoutInFlight = () => instance ? instance.core.logoutInFlight : fallbackLogoutInFlight;\n const setLogoutInFlight = (p: Promise<void> | null) => {\n if (instance) {\n instance.core.logoutInFlight = p;\n } else {\n fallbackLogoutInFlight = p;\n }\n };\n const setAuth = (v: boolean) => {\n if (instance) {\n instance.core.authenticated = v;\n } else {\n fallbackAuthenticated = v;\n }\n };\n\n const handler = getLogoutHandler();\n if (!handler) return;\n if (reason === \"unauthorized\" || reason === \"token_missing\") {\n setAuth(false);\n }\n const inFlight = getLogoutInFlight();\n if (inFlight) {\n return inFlight;\n }\n const promise = (async () => {\n try {\n await handler(reason);\n } catch (e: unknown) {\n logError(\"Auth.logout\", e);\n } finally {\n setLogoutInFlight(null);\n }\n })();\n setLogoutInFlight(promise);\n await promise;\n}\n\n/**\n * Clears auth-related fallback and instance state.\n * Intended for test/integration teardown.\n */\nexport function clearAuthState(): void {\n const instance = tryGetSpringInstance();\n if (instance) {\n instance.core.logoutHandler = null;\n instance.core.authenticated = false;\n instance.core.logoutInFlight = null;\n }\n\n fallbackLogoutHandler = null;\n fallbackAuthenticated = false;\n fallbackLogoutInFlight = null;\n}\n"],"mappings":";;;;;;;;;;;AAQA,IAAI,wBAA8C;AAClD,IAAI,wBAAwB;AAC5B,IAAI,yBAA+C;AAGnD,0BAA0B,CAAC,aAAa;AACpC,MAAI,uBAAuB;AACvB,aAAS,KAAK,gBAAgB;AAAA,EAClC;AACA,MAAI,uBAAuB;AACvB,aAAS,KAAK,gBAAgB;AAAA,EAClC;AACA,MAAI,wBAAwB;AACxB,UAAM,mBAAmB;AACzB,aAAS,KAAK,iBAAiB;AAC/B,SAAK,iBAAiB,QAAQ,MAAM;AAChC,UAAI,SAAS,KAAK,mBAAmB,kBAAkB;AACnD,iBAAS,KAAK,iBAAiB;AAAA,MACnC;AAAA,IACJ,CAAC;AAAA,EACL;AACJ,CAAC;AAEM,SAAS,iBAAiB,SAA8B;AAC3D,QAAM,WAAW,qBAAqB;AACtC,MAAI,UAAU;AACV,aAAS,KAAK,gBAAgB;AAAA,EAClC,OAAO;AACH,4BAAwB;AAAA,EAC5B;AACJ;AAEO,SAAS,iBAAiB,OAAsB;AACnD,QAAM,WAAW,qBAAqB;AACtC,MAAI,UAAU;AACV,aAAS,KAAK,gBAAgB;AAAA,EAClC,OAAO;AACH,4BAAwB;AAAA,EAC5B;AACJ;AAEO,SAAS,kBAA2B;AACvC,QAAM,WAAW,qBAAqB;AACtC,SAAO,WAAW,SAAS,KAAK,gBAAgB;AACpD;AAEA,eAAsB,cAAc,QAAqC;AACrE,QAAM,WAAW,qBAAqB;AAEtC,QAAM,mBAAmB,MAAM,WAAW,SAAS,KAAK,gBAAgB;AACxE,QAAM,oBAAoB,MAAM,WAAW,SAAS,KAAK,iBAAiB;AAC1E,QAAM,oBAAoB,CAAC,MAA4B;AACnD,QAAI,UAAU;AACV,eAAS,KAAK,iBAAiB;AAAA,IACnC,OAAO;AACH,+BAAyB;AAAA,IAC7B;AAAA,EACJ;AACA,QAAM,UAAU,CAAC,MAAe;AAC5B,QAAI,UAAU;AACV,eAAS,KAAK,gBAAgB;AAAA,IAClC,OAAO;AACH,8BAAwB;AAAA,IAC5B;AAAA,EACJ;AAEA,QAAM,UAAU,iBAAiB;AACjC,MAAI,CAAC,QAAS;AACd,MAAI,WAAW,kBAAkB,WAAW,iBAAiB;AACzD,YAAQ,KAAK;AAAA,EACjB;AACA,QAAM,WAAW,kBAAkB;AACnC,MAAI,UAAU;AACV,WAAO;AAAA,EACX;AACA,QAAM,WAAW,YAAY;AACzB,QAAI;AACA,YAAM,QAAQ,MAAM;AAAA,IACxB,SAAS,GAAY;AACjB,eAAS,eAAe,CAAC;AAAA,IAC7B,UAAE;AACE,wBAAkB,IAAI;AAAA,IAC1B;AAAA,EACJ,GAAG;AACH,oBAAkB,OAAO;AACzB,QAAM;AACV;AAMO,SAAS,iBAAuB;AACnC,QAAM,WAAW,qBAAqB;AACtC,MAAI,UAAU;AACV,aAAS,KAAK,gBAAgB;AAC9B,aAAS,KAAK,gBAAgB;AAC9B,aAAS,KAAK,iBAAiB;AAAA,EACnC;AAEA,0BAAwB;AACxB,0BAAwB;AACxB,2BAAyB;AAC7B;","names":[]}
|
package/dist/chunk-KX32MU3I.js
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
tryGetSpringInstance
|
|
3
|
-
} from "./chunk-EFUBAQCV.js";
|
|
4
|
-
|
|
5
|
-
// src/utils/security-sanitize.ts
|
|
6
|
-
function isSensitiveSecurityKey(key) {
|
|
7
|
-
const normalized = key.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[^a-zA-Z0-9]+/g, "_").toLowerCase();
|
|
8
|
-
const parts = new Set(normalized.split("_").filter(Boolean));
|
|
9
|
-
const has = (part) => parts.has(part);
|
|
10
|
-
if (has("token") || has("secret") || has("password") || has("cookie") || has("session")) {
|
|
11
|
-
return true;
|
|
12
|
-
}
|
|
13
|
-
if (has("authorization")) {
|
|
14
|
-
return true;
|
|
15
|
-
}
|
|
16
|
-
if (has("credential") || has("credentials")) {
|
|
17
|
-
return true;
|
|
18
|
-
}
|
|
19
|
-
if (has("api") && has("key")) {
|
|
20
|
-
return true;
|
|
21
|
-
}
|
|
22
|
-
if ((has("access") || has("refresh")) && has("token")) {
|
|
23
|
-
return true;
|
|
24
|
-
}
|
|
25
|
-
if (has("auth") && (has("token") || has("header") || has("session"))) {
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
return false;
|
|
29
|
-
}
|
|
30
|
-
function sanitizeSecurityData(data) {
|
|
31
|
-
if (!data) return void 0;
|
|
32
|
-
const visiting = /* @__PURE__ */ new WeakSet();
|
|
33
|
-
function isSensitiveStringValue(value) {
|
|
34
|
-
const trimmed = value.trim();
|
|
35
|
-
if (!trimmed) return false;
|
|
36
|
-
if (/^Bearer\s+\S+$/i.test(trimmed)) {
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
const withoutBearer = trimmed.replace(/^Bearer\s+/i, "");
|
|
40
|
-
if (withoutBearer.length >= 24 && /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(withoutBearer)) {
|
|
41
|
-
return true;
|
|
42
|
-
}
|
|
43
|
-
if (withoutBearer.length >= 40 && !/\s/.test(withoutBearer) && !/^https?:\/\//i.test(withoutBearer) && /^[A-Za-z0-9._~+/-]+=*$/.test(withoutBearer)) {
|
|
44
|
-
const uniqueChars = new Set(withoutBearer).size;
|
|
45
|
-
const hasDigit = /\d/.test(withoutBearer);
|
|
46
|
-
const hasSymbol = /[._~+/-]/.test(withoutBearer);
|
|
47
|
-
if (uniqueChars >= 6 && (hasDigit || hasSymbol)) {
|
|
48
|
-
return true;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
function sanitizeValue(key, value) {
|
|
54
|
-
if (key && isSensitiveSecurityKey(key)) {
|
|
55
|
-
return "[REDACTED]";
|
|
56
|
-
}
|
|
57
|
-
if (typeof value === "string") {
|
|
58
|
-
if (isSensitiveStringValue(value)) {
|
|
59
|
-
return "[REDACTED]";
|
|
60
|
-
}
|
|
61
|
-
if (value.length > 120) {
|
|
62
|
-
return `${value.slice(0, 117)}...`;
|
|
63
|
-
}
|
|
64
|
-
return value;
|
|
65
|
-
}
|
|
66
|
-
if (value === null || typeof value !== "object") {
|
|
67
|
-
return value;
|
|
68
|
-
}
|
|
69
|
-
if (visiting.has(value)) {
|
|
70
|
-
return "[Circular]";
|
|
71
|
-
}
|
|
72
|
-
visiting.add(value);
|
|
73
|
-
try {
|
|
74
|
-
if (Array.isArray(value)) {
|
|
75
|
-
return value.map((item) => sanitizeValue(key, item));
|
|
76
|
-
}
|
|
77
|
-
const nested = {};
|
|
78
|
-
for (const [nestedKey, nestedValue] of Object.entries(value)) {
|
|
79
|
-
nested[nestedKey] = sanitizeValue(nestedKey, nestedValue);
|
|
80
|
-
}
|
|
81
|
-
return nested;
|
|
82
|
-
} finally {
|
|
83
|
-
visiting.delete(value);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return sanitizeValue(void 0, data);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// src/logger/logger.ts
|
|
90
|
-
var logLevelPriority = {
|
|
91
|
-
debug: 0,
|
|
92
|
-
info: 1,
|
|
93
|
-
warn: 2,
|
|
94
|
-
error: 3,
|
|
95
|
-
silent: 4
|
|
96
|
-
};
|
|
97
|
-
function isProductionRuntime() {
|
|
98
|
-
const globalProcess = globalThis.process;
|
|
99
|
-
const nodeEnv = globalProcess?.env?.NODE_ENV;
|
|
100
|
-
if (nodeEnv === "production") {
|
|
101
|
-
return true;
|
|
102
|
-
}
|
|
103
|
-
if (typeof nodeEnv === "string") {
|
|
104
|
-
return false;
|
|
105
|
-
}
|
|
106
|
-
const importMetaEnv = import.meta.env;
|
|
107
|
-
if (!importMetaEnv) {
|
|
108
|
-
return true;
|
|
109
|
-
}
|
|
110
|
-
return importMetaEnv.PROD === true || importMetaEnv.MODE === "production" || importMetaEnv.NODE_ENV === "production";
|
|
111
|
-
}
|
|
112
|
-
var DEFAULT_LOG_LEVEL = isProductionRuntime() ? "info" : "debug";
|
|
113
|
-
var currentLogLevel = DEFAULT_LOG_LEVEL;
|
|
114
|
-
function setLogLevel(level) {
|
|
115
|
-
currentLogLevel = level;
|
|
116
|
-
}
|
|
117
|
-
function getLogLevel() {
|
|
118
|
-
return currentLogLevel;
|
|
119
|
-
}
|
|
120
|
-
function isLevelEnabled(level) {
|
|
121
|
-
return logLevelPriority[level] >= logLevelPriority[currentLogLevel];
|
|
122
|
-
}
|
|
123
|
-
var fallbackAdapter = {};
|
|
124
|
-
function setLogAdapter(a) {
|
|
125
|
-
const instance = tryGetSpringInstance();
|
|
126
|
-
if (instance) {
|
|
127
|
-
instance.core.logAdapter = a;
|
|
128
|
-
} else {
|
|
129
|
-
fallbackAdapter = a;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
function getAdapter() {
|
|
133
|
-
const instance = tryGetSpringInstance();
|
|
134
|
-
if (!instance) return fallbackAdapter;
|
|
135
|
-
return { ...fallbackAdapter, ...instance.core.logAdapter };
|
|
136
|
-
}
|
|
137
|
-
function clearLogAdapter() {
|
|
138
|
-
const instance = tryGetSpringInstance();
|
|
139
|
-
if (instance) {
|
|
140
|
-
instance.core.logAdapter = {};
|
|
141
|
-
}
|
|
142
|
-
fallbackAdapter = {};
|
|
143
|
-
}
|
|
144
|
-
function resetLogLevel() {
|
|
145
|
-
currentLogLevel = DEFAULT_LOG_LEVEL;
|
|
146
|
-
}
|
|
147
|
-
function timestamp() {
|
|
148
|
-
return (/* @__PURE__ */ new Date()).toISOString();
|
|
149
|
-
}
|
|
150
|
-
function logDebug(context, data) {
|
|
151
|
-
if (!isLevelEnabled("debug")) return;
|
|
152
|
-
console.debug(`[${timestamp()}] [${context}]`, data ?? "");
|
|
153
|
-
}
|
|
154
|
-
function logError(context, error) {
|
|
155
|
-
getAdapter().onError?.(context, error);
|
|
156
|
-
if (!isLevelEnabled("error")) return;
|
|
157
|
-
console.error(`[${timestamp()}] [${context}]`, error ?? "");
|
|
158
|
-
}
|
|
159
|
-
function logWarn(context, message) {
|
|
160
|
-
getAdapter().onWarn?.(context, message);
|
|
161
|
-
if (!isLevelEnabled("warn")) return;
|
|
162
|
-
console.warn(`[${timestamp()}] [${context}]`, message ?? "");
|
|
163
|
-
}
|
|
164
|
-
function logInfo(context, data) {
|
|
165
|
-
if (!isLevelEnabled("info")) return;
|
|
166
|
-
console.info(`[${timestamp()}] [${context}]`, data ?? "");
|
|
167
|
-
}
|
|
168
|
-
function logSecurityEvent(event, data) {
|
|
169
|
-
const sanitized = sanitizeSecurityData(data);
|
|
170
|
-
if (isLevelEnabled("info")) {
|
|
171
|
-
console.info(`[${timestamp()}] [SECURITY] ${event}`, sanitized ?? "");
|
|
172
|
-
}
|
|
173
|
-
getAdapter().onSecurityEvent?.(event, sanitized);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
export {
|
|
177
|
-
isSensitiveSecurityKey,
|
|
178
|
-
sanitizeSecurityData,
|
|
179
|
-
setLogLevel,
|
|
180
|
-
getLogLevel,
|
|
181
|
-
setLogAdapter,
|
|
182
|
-
clearLogAdapter,
|
|
183
|
-
resetLogLevel,
|
|
184
|
-
logDebug,
|
|
185
|
-
logError,
|
|
186
|
-
logWarn,
|
|
187
|
-
logInfo,
|
|
188
|
-
logSecurityEvent
|
|
189
|
-
};
|
|
190
|
-
//# sourceMappingURL=chunk-KX32MU3I.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/security-sanitize.ts","../src/logger/logger.ts"],"sourcesContent":["export type SecurityLogScalar = string | number | boolean | null;\nexport interface SecurityLogData {\n [key: string]: SecurityLogValue;\n}\nexport type SecurityLogValue = SecurityLogScalar | SecurityLogData | SecurityLogValue[];\n\nexport function isSensitiveSecurityKey(key: string): boolean {\n const normalized = key\n .replace(/([a-z0-9])([A-Z])/g, \"$1_$2\")\n .replace(/[^a-zA-Z0-9]+/g, \"_\")\n .toLowerCase();\n\n const parts = new Set(normalized.split(\"_\").filter(Boolean));\n const has = (part: string): boolean => parts.has(part);\n\n if (has(\"token\") || has(\"secret\") || has(\"password\") || has(\"cookie\") || has(\"session\")) {\n return true;\n }\n if (has(\"authorization\")) {\n return true;\n }\n if (has(\"credential\") || has(\"credentials\")) {\n return true;\n }\n if (has(\"api\") && has(\"key\")) {\n return true;\n }\n if ((has(\"access\") || has(\"refresh\")) && has(\"token\")) {\n return true;\n }\n if (has(\"auth\") && (has(\"token\") || has(\"header\") || has(\"session\"))) {\n return true;\n }\n\n return false;\n}\n\nexport function sanitizeSecurityData(data?: SecurityLogData): SecurityLogData | undefined {\n if (!data) return undefined;\n\n const visiting = new WeakSet<object>();\n\n function isSensitiveStringValue(value: string): boolean {\n const trimmed = value.trim();\n if (!trimmed) return false;\n\n if (/^Bearer\\s+\\S+$/i.test(trimmed)) {\n return true;\n }\n\n const withoutBearer = trimmed.replace(/^Bearer\\s+/i, \"\");\n if (\n withoutBearer.length >= 24 &&\n /^[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/.test(withoutBearer)\n ) {\n return true;\n }\n\n if (\n withoutBearer.length >= 40 &&\n !/\\s/.test(withoutBearer) &&\n !/^https?:\\/\\//i.test(withoutBearer) &&\n /^[A-Za-z0-9._~+/-]+=*$/.test(withoutBearer)\n ) {\n const uniqueChars = new Set(withoutBearer).size;\n const hasDigit = /\\d/.test(withoutBearer);\n const hasSymbol = /[._~+/-]/.test(withoutBearer);\n if (uniqueChars >= 6 && (hasDigit || hasSymbol)) {\n return true;\n }\n }\n\n return false;\n }\n\n function sanitizeValue(key: string | undefined, value: SecurityLogValue): SecurityLogValue {\n if (key && isSensitiveSecurityKey(key)) {\n return \"[REDACTED]\";\n }\n\n if (typeof value === \"string\") {\n if (isSensitiveStringValue(value)) {\n return \"[REDACTED]\";\n }\n if (value.length > 120) {\n return `${value.slice(0, 117)}...`;\n }\n return value;\n }\n\n if (value === null || typeof value !== \"object\") {\n return value;\n }\n\n if (visiting.has(value)) {\n return \"[Circular]\";\n }\n visiting.add(value);\n\n try {\n if (Array.isArray(value)) {\n return value.map((item) => sanitizeValue(key, item));\n }\n\n const nested: SecurityLogData = {};\n for (const [nestedKey, nestedValue] of Object.entries(value)) {\n nested[nestedKey] = sanitizeValue(nestedKey, nestedValue as SecurityLogValue);\n }\n return nested;\n } finally {\n visiting.delete(value);\n }\n }\n\n return sanitizeValue(undefined, data) as SecurityLogData;\n}\n","/**\n * Console wrapper with timestamp and configurable log levels.\n * @module logger\n */\n\nimport { tryGetSpringInstance } from \"../instance/current-instance\";\nimport type { SecurityEventType } from \"../instance/spring-instance\";\nimport { sanitizeSecurityData, type SecurityLogData } from \"../utils/security-sanitize\";\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\" | \"silent\";\n\ntype BivariantCallback<TArgs extends unknown[], TResult = void> = {\n bivarianceHack: (...args: TArgs) => TResult;\n}[\"bivarianceHack\"];\n\nexport interface LogAdapter {\n onError?: (context: string, error?: unknown) => void;\n onWarn?: (context: string, message?: string) => void;\n // Bivariant for backward compatibility with older narrower callback signatures.\n onSecurityEvent?: BivariantCallback<[event: SecurityEventType, data?: SecurityLogData]>;\n}\n\nconst logLevelPriority = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n silent: 4,\n} satisfies Record<LogLevel, number>;\n\nfunction isProductionRuntime(): boolean {\n const globalProcess = (globalThis as { process?: { env?: Record<string, unknown> } }).process;\n const nodeEnv = globalProcess?.env?.NODE_ENV;\n if (nodeEnv === \"production\") {\n return true;\n }\n if (typeof nodeEnv === \"string\") {\n return false;\n }\n\n const importMetaEnv = (import.meta as ImportMeta & { env?: Record<string, unknown> }).env;\n if (!importMetaEnv) {\n // Library default should be conservative when runtime env cannot be detected.\n return true;\n }\n\n return (\n importMetaEnv.PROD === true ||\n importMetaEnv.MODE === \"production\" ||\n importMetaEnv.NODE_ENV === \"production\"\n );\n}\n\nconst DEFAULT_LOG_LEVEL: LogLevel =\n isProductionRuntime() ? \"info\" : \"debug\";\n\nlet currentLogLevel: LogLevel = DEFAULT_LOG_LEVEL;\n\n/**\n * Set the minimum log level. Messages below this level are suppressed.\n * Default is \"info\" in production, \"debug\" in development.\n */\nexport function setLogLevel(level: LogLevel): void {\n currentLogLevel = level;\n}\n\n/**\n * Get the current log level.\n */\nexport function getLogLevel(): LogLevel {\n return currentLogLevel;\n}\n\nfunction isLevelEnabled(level: LogLevel): boolean {\n return logLevelPriority[level] >= logLevelPriority[currentLogLevel];\n}\n\nlet fallbackAdapter: LogAdapter = {};\n\nexport function setLogAdapter(a: LogAdapter): void {\n const instance = tryGetSpringInstance();\n if (instance) {\n instance.core.logAdapter = a;\n } else {\n fallbackAdapter = a;\n }\n}\n\nfunction getAdapter(): LogAdapter {\n const instance = tryGetSpringInstance();\n if (!instance) return fallbackAdapter;\n return { ...fallbackAdapter, ...instance.core.logAdapter };\n}\n\n/**\n * Reset adapter callbacks to defaults (no-op adapter).\n * For testing/integration teardown only.\n */\nexport function clearLogAdapter(): void {\n const instance = tryGetSpringInstance();\n if (instance) {\n instance.core.logAdapter = {};\n }\n fallbackAdapter = {};\n}\n\n/** Reset log level to runtime default (info in prod, debug otherwise). */\nexport function resetLogLevel(): void {\n currentLogLevel = DEFAULT_LOG_LEVEL;\n}\n\nfunction timestamp(): string {\n return new Date().toISOString();\n}\n\nexport function logDebug(context: string, data?: unknown): void {\n if (!isLevelEnabled(\"debug\")) return;\n console.debug(`[${timestamp()}] [${context}]`, data ?? \"\");\n}\n\nexport function logError(context: string, error?: unknown): void {\n getAdapter().onError?.(context, error);\n if (!isLevelEnabled(\"error\")) return;\n console.error(`[${timestamp()}] [${context}]`, error ?? \"\");\n}\n\nexport function logWarn(context: string, message?: string): void {\n getAdapter().onWarn?.(context, message);\n if (!isLevelEnabled(\"warn\")) return;\n console.warn(`[${timestamp()}] [${context}]`, message ?? \"\");\n}\n\nexport function logInfo(context: string, data?: unknown): void {\n if (!isLevelEnabled(\"info\")) return;\n console.info(`[${timestamp()}] [${context}]`, data ?? \"\");\n}\n\nexport function logSecurityEvent(event: SecurityEventType, data?: SecurityLogData): void {\n const sanitized = sanitizeSecurityData(data);\n // Security events always log regardless of level (they go through the adapter)\n if (isLevelEnabled(\"info\")) {\n console.info(`[${timestamp()}] [SECURITY] ${event}`, sanitized ?? \"\");\n }\n getAdapter().onSecurityEvent?.(event, sanitized);\n}\n"],"mappings":"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","names":[]}
|