@spring-systems/core 0.8.6 → 0.8.7
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 +1 -0
- package/dist/utils/index.js +1 -772
- package/dist/validation/index.js +1 -147
- package/package.json +137 -136
- 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-S7MKRNMI.js
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
registerFallbackMigration
|
|
3
|
-
} from "./chunk-RUCXSQEY.js";
|
|
4
|
-
import {
|
|
5
|
-
tryGetSpringInstance
|
|
6
|
-
} from "./chunk-EFUBAQCV.js";
|
|
7
|
-
|
|
8
|
-
// src/config/capabilities.ts
|
|
9
|
-
var UI_KEY = /* @__PURE__ */ Symbol.for("spring:capabilities");
|
|
10
|
-
function cloneValue(value, seen = /* @__PURE__ */ new WeakMap()) {
|
|
11
|
-
if (value === null || typeof value !== "object") {
|
|
12
|
-
return value;
|
|
13
|
-
}
|
|
14
|
-
const obj = value;
|
|
15
|
-
if (seen.has(obj)) return seen.get(obj);
|
|
16
|
-
if (value instanceof Date) {
|
|
17
|
-
return new Date(value.getTime());
|
|
18
|
-
}
|
|
19
|
-
if (value instanceof RegExp) {
|
|
20
|
-
return new RegExp(value.source, value.flags);
|
|
21
|
-
}
|
|
22
|
-
if (value instanceof Map) {
|
|
23
|
-
const cloned = /* @__PURE__ */ new Map();
|
|
24
|
-
seen.set(obj, cloned);
|
|
25
|
-
for (const [k, v] of value.entries()) {
|
|
26
|
-
cloned.set(cloneValue(k, seen), cloneValue(v, seen));
|
|
27
|
-
}
|
|
28
|
-
return cloned;
|
|
29
|
-
}
|
|
30
|
-
if (value instanceof Set) {
|
|
31
|
-
const cloned = /* @__PURE__ */ new Set();
|
|
32
|
-
seen.set(obj, cloned);
|
|
33
|
-
for (const item of value.values()) {
|
|
34
|
-
cloned.add(cloneValue(item, seen));
|
|
35
|
-
}
|
|
36
|
-
return cloned;
|
|
37
|
-
}
|
|
38
|
-
if (Array.isArray(value)) {
|
|
39
|
-
const cloned = [];
|
|
40
|
-
seen.set(obj, cloned);
|
|
41
|
-
for (const item of value) {
|
|
42
|
-
cloned.push(cloneValue(item, seen));
|
|
43
|
-
}
|
|
44
|
-
return cloned;
|
|
45
|
-
}
|
|
46
|
-
const proto = Object.getPrototypeOf(value);
|
|
47
|
-
const clonedObj = Object.create(proto);
|
|
48
|
-
seen.set(obj, clonedObj);
|
|
49
|
-
for (const key of Reflect.ownKeys(value)) {
|
|
50
|
-
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
51
|
-
if (!descriptor) continue;
|
|
52
|
-
if ("value" in descriptor) {
|
|
53
|
-
descriptor.value = cloneValue(descriptor.value, seen);
|
|
54
|
-
}
|
|
55
|
-
Object.defineProperty(clonedObj, key, descriptor);
|
|
56
|
-
}
|
|
57
|
-
return clonedObj;
|
|
58
|
-
}
|
|
59
|
-
function deepFreeze(value, seen = /* @__PURE__ */ new WeakSet()) {
|
|
60
|
-
if (value !== null && typeof value === "object") {
|
|
61
|
-
const obj = value;
|
|
62
|
-
if (seen.has(obj)) return value;
|
|
63
|
-
seen.add(obj);
|
|
64
|
-
if (value instanceof Map) {
|
|
65
|
-
for (const [k, v] of value.entries()) {
|
|
66
|
-
deepFreeze(k, seen);
|
|
67
|
-
deepFreeze(v, seen);
|
|
68
|
-
}
|
|
69
|
-
Object.freeze(value);
|
|
70
|
-
return value;
|
|
71
|
-
}
|
|
72
|
-
if (value instanceof Set) {
|
|
73
|
-
for (const item of value.values()) {
|
|
74
|
-
deepFreeze(item, seen);
|
|
75
|
-
}
|
|
76
|
-
Object.freeze(value);
|
|
77
|
-
return value;
|
|
78
|
-
}
|
|
79
|
-
for (const key of Reflect.ownKeys(value)) {
|
|
80
|
-
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
81
|
-
if (!descriptor || !("value" in descriptor)) continue;
|
|
82
|
-
deepFreeze(descriptor.value, seen);
|
|
83
|
-
}
|
|
84
|
-
Object.freeze(value);
|
|
85
|
-
}
|
|
86
|
-
return value;
|
|
87
|
-
}
|
|
88
|
-
function getStore() {
|
|
89
|
-
const instance = tryGetSpringInstance();
|
|
90
|
-
if (instance) {
|
|
91
|
-
if (!instance.ui[UI_KEY]) {
|
|
92
|
-
const emptyStore = {};
|
|
93
|
-
instance.ui[UI_KEY] = emptyStore;
|
|
94
|
-
}
|
|
95
|
-
return instance.ui[UI_KEY];
|
|
96
|
-
}
|
|
97
|
-
return fallbackStore;
|
|
98
|
-
}
|
|
99
|
-
var fallbackStore = {};
|
|
100
|
-
registerFallbackMigration((instance) => {
|
|
101
|
-
if (Object.keys(fallbackStore).length === 0) return;
|
|
102
|
-
const existing = instance.ui[UI_KEY];
|
|
103
|
-
if (!existing || typeof existing !== "object") {
|
|
104
|
-
instance.ui[UI_KEY] = { ...fallbackStore };
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
const instanceStore = existing;
|
|
108
|
-
for (const [key, value] of Object.entries(fallbackStore)) {
|
|
109
|
-
if (!(key in instanceStore)) {
|
|
110
|
-
instanceStore[key] = value;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
function configureCapabilities(capabilities) {
|
|
115
|
-
const store = getStore();
|
|
116
|
-
Object.assign(store, capabilities);
|
|
117
|
-
}
|
|
118
|
-
function hasCapability(name) {
|
|
119
|
-
const store = getStore();
|
|
120
|
-
const value = store[name];
|
|
121
|
-
if (value === void 0 || value === null) return false;
|
|
122
|
-
if (typeof value === "boolean") return value;
|
|
123
|
-
if (typeof value === "object" && value !== null && "enabled" in value) {
|
|
124
|
-
return !!value.enabled;
|
|
125
|
-
}
|
|
126
|
-
return !!value;
|
|
127
|
-
}
|
|
128
|
-
function getCapability(name) {
|
|
129
|
-
return getStore()[name];
|
|
130
|
-
}
|
|
131
|
-
function getCapabilities() {
|
|
132
|
-
return deepFreeze(cloneValue(getStore()));
|
|
133
|
-
}
|
|
134
|
-
function getRegisteredCapabilityNames() {
|
|
135
|
-
return Object.keys(getStore());
|
|
136
|
-
}
|
|
137
|
-
function clearCapabilities() {
|
|
138
|
-
const instance = tryGetSpringInstance();
|
|
139
|
-
if (instance) {
|
|
140
|
-
instance.ui[UI_KEY] = {};
|
|
141
|
-
}
|
|
142
|
-
fallbackStore = {};
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export {
|
|
146
|
-
configureCapabilities,
|
|
147
|
-
hasCapability,
|
|
148
|
-
getCapability,
|
|
149
|
-
getCapabilities,
|
|
150
|
-
getRegisteredCapabilityNames,
|
|
151
|
-
clearCapabilities
|
|
152
|
-
};
|
|
153
|
-
//# sourceMappingURL=chunk-S7MKRNMI.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config/capabilities.ts"],"sourcesContent":["/**\n * Feature capability system for enterprise SPRING deployments.\n *\n * Capabilities allow framework consumers to enable/disable features\n * per client deployment. Plugins can declare required capabilities\n * and the framework checks them at registration time.\n *\n * @example\n * ```ts\n * // In project-config.ts:\n * configureCapabilities({\n * charts: true,\n * advancedFiltering: true,\n * bulkOperations: false,\n * export: { enabled: true, formats: [\"xlsx\", \"pdf\"] },\n * });\n *\n * // In a plugin:\n * if (hasCapability(\"advancedFiltering\")) {\n * registerMiddleware(\"list:beforeLoad\", advancedFilterMiddleware);\n * }\n *\n * // In a component:\n * const canExport = hasCapability(\"export\");\n * ```\n *\n * @module capabilities\n */\n\nimport { tryGetSpringInstance } from \"../instance/current-instance\";\nimport { registerFallbackMigration } from \"../instance/fallback-bridge\";\nimport type { CapabilityMap } from \"./capability-types\";\n\nexport type { CapabilityMap } from \"./capability-types\";\n\n/**\n * Extensible capability map. Consumers and plugins extend via declaration merging:\n *\n * @example\n * ```ts\n * declare module \"@spring-systems/core/config\" {\n * interface CapabilityMap {\n * \"myPlugin:feature\": boolean;\n * }\n * }\n * ```\n */\nconst UI_KEY = Symbol.for(\"spring:capabilities\");\n\ntype CapabilityStore = Partial<CapabilityMap> & Record<string, unknown>;\n\nfunction cloneValue<T>(value: T, seen = new WeakMap<object, unknown>()): T {\n if (value === null || typeof value !== \"object\") {\n return value;\n }\n\n const obj = value as object;\n if (seen.has(obj)) return seen.get(obj) as T;\n\n if (value instanceof Date) {\n return new Date(value.getTime()) as T;\n }\n if (value instanceof RegExp) {\n return new RegExp(value.source, value.flags) as T;\n }\n if (value instanceof Map) {\n const cloned = new Map<unknown, unknown>();\n seen.set(obj, cloned);\n for (const [k, v] of value.entries()) {\n cloned.set(cloneValue(k, seen), cloneValue(v, seen));\n }\n return cloned as T;\n }\n if (value instanceof Set) {\n const cloned = new Set<unknown>();\n seen.set(obj, cloned);\n for (const item of value.values()) {\n cloned.add(cloneValue(item, seen));\n }\n return cloned as T;\n }\n if (Array.isArray(value)) {\n const cloned: unknown[] = [];\n seen.set(obj, cloned);\n for (const item of value) {\n cloned.push(cloneValue(item, seen));\n }\n return cloned as T;\n }\n\n const proto = Object.getPrototypeOf(value);\n const clonedObj = Object.create(proto) as Record<PropertyKey, unknown>;\n seen.set(obj, clonedObj);\n for (const key of Reflect.ownKeys(value)) {\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n if (!descriptor) continue;\n if (\"value\" in descriptor) {\n descriptor.value = cloneValue(descriptor.value, seen);\n }\n Object.defineProperty(clonedObj, key, descriptor);\n }\n return clonedObj as T;\n}\n\nfunction deepFreeze<T>(value: T, seen = new WeakSet<object>()): T {\n if (value !== null && typeof value === \"object\") {\n const obj = value as object;\n if (seen.has(obj)) return value;\n seen.add(obj);\n\n if (value instanceof Map) {\n for (const [k, v] of value.entries()) {\n deepFreeze(k, seen);\n deepFreeze(v, seen);\n }\n Object.freeze(value);\n return value;\n }\n\n if (value instanceof Set) {\n for (const item of value.values()) {\n deepFreeze(item, seen);\n }\n Object.freeze(value);\n return value;\n }\n\n for (const key of Reflect.ownKeys(value)) {\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n if (!descriptor || !(\"value\" in descriptor)) continue;\n deepFreeze(descriptor.value, seen);\n }\n Object.freeze(value);\n }\n return value;\n}\n\nfunction getStore(): CapabilityStore {\n const instance = tryGetSpringInstance();\n if (instance) {\n if (!instance.ui[UI_KEY]) {\n const emptyStore: CapabilityStore = {};\n instance.ui[UI_KEY] = emptyStore;\n }\n return instance.ui[UI_KEY] as CapabilityStore;\n }\n return fallbackStore;\n}\n\nlet fallbackStore: CapabilityStore = {};\n\n// Migrate fallback capabilities to SpringInstance when SpringProvider mounts.\n// Merge is non-destructive: explicit instance values win over fallback values.\nregisterFallbackMigration((instance) => {\n if (Object.keys(fallbackStore).length === 0) return;\n\n const existing = instance.ui[UI_KEY];\n if (!existing || typeof existing !== \"object\") {\n instance.ui[UI_KEY] = { ...fallbackStore };\n return;\n }\n\n const instanceStore = existing as CapabilityStore;\n for (const [key, value] of Object.entries(fallbackStore)) {\n if (!(key in instanceStore)) {\n instanceStore[key] = value;\n }\n }\n});\n\n/**\n * Configure feature capabilities for this deployment.\n * Merges with existing capabilities (does not replace).\n */\nexport function configureCapabilities(capabilities: Partial<CapabilityMap> & Record<string, unknown>): void {\n const store = getStore();\n Object.assign(store, capabilities);\n}\n\n/**\n * Check if a capability is enabled.\n * Returns false for unknown/unconfigured capabilities.\n */\nexport function hasCapability<K extends keyof CapabilityMap>(name: K): boolean {\n const store = getStore();\n const value = store[name];\n if (value === undefined || value === null) return false;\n if (typeof value === \"boolean\") return value;\n if (typeof value === \"object\" && value !== null && \"enabled\" in value) {\n return !!(value as { enabled: boolean }).enabled;\n }\n return !!value;\n}\n\n/**\n * Get the full capability configuration for a feature.\n * Returns undefined if the capability is not configured.\n */\nexport function getCapability<K extends keyof CapabilityMap>(name: K): CapabilityMap[K] | undefined {\n return getStore()[name] as CapabilityMap[K] | undefined;\n}\n\n/** Get all configured capabilities. */\nexport function getCapabilities(): Readonly<CapabilityStore> {\n return deepFreeze(cloneValue(getStore()));\n}\n\n/**\n * Get the names of all currently registered (configured) capabilities.\n * Useful for introspection and for validating that plugin capability\n * references point to actually-configured features.\n */\nexport function getRegisteredCapabilityNames(): string[] {\n return Object.keys(getStore());\n}\n\n/** Reset all capabilities. For testing only. */\nexport function clearCapabilities(): void {\n const instance = tryGetSpringInstance();\n if (instance) {\n instance.ui[UI_KEY] = {};\n }\n fallbackStore = {};\n}\n"],"mappings":"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","names":[]}
|
package/dist/chunk-SQB4F3EF.js
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
registerMiddleware
|
|
3
|
-
} from "./chunk-MEWPYTWC.js";
|
|
4
|
-
import {
|
|
5
|
-
logWarn
|
|
6
|
-
} from "./chunk-KX32MU3I.js";
|
|
7
|
-
|
|
8
|
-
// src/middleware/audit-middleware.ts
|
|
9
|
-
async function invokeAuditHandler(handler, event) {
|
|
10
|
-
try {
|
|
11
|
-
await Promise.resolve(handler(event));
|
|
12
|
-
} catch (err) {
|
|
13
|
-
logWarn(
|
|
14
|
-
"AuditMiddleware",
|
|
15
|
-
`Handler error for ${event.action} ${event.entity}#${event.entityId}: ${err instanceof Error ? err.message : String(err)}`
|
|
16
|
-
);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
function createAuditMiddleware(handler, options) {
|
|
20
|
-
const saveMiddleware = async (ctx, next) => {
|
|
21
|
-
await next();
|
|
22
|
-
if (ctx.aborted) return;
|
|
23
|
-
await invokeAuditHandler(handler, {
|
|
24
|
-
action: ctx.isNew ? "create" : "update",
|
|
25
|
-
entity: ctx.entity,
|
|
26
|
-
entityId: ctx.id,
|
|
27
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
28
|
-
url: ctx.url,
|
|
29
|
-
fields: ctx.fields
|
|
30
|
-
});
|
|
31
|
-
};
|
|
32
|
-
const deleteMiddleware = async (ctx, next) => {
|
|
33
|
-
await next();
|
|
34
|
-
if (ctx.aborted) return;
|
|
35
|
-
await invokeAuditHandler(handler, {
|
|
36
|
-
action: "delete",
|
|
37
|
-
entity: ctx.entity,
|
|
38
|
-
entityId: ctx.id,
|
|
39
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
40
|
-
url: ctx.url,
|
|
41
|
-
fields: {}
|
|
42
|
-
});
|
|
43
|
-
};
|
|
44
|
-
const unregisterSave = registerMiddleware("form:afterSave", saveMiddleware, options);
|
|
45
|
-
const unregisterDelete = registerMiddleware("form:afterDelete", deleteMiddleware, options);
|
|
46
|
-
return () => {
|
|
47
|
-
unregisterSave();
|
|
48
|
-
unregisterDelete();
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export {
|
|
53
|
-
createAuditMiddleware
|
|
54
|
-
};
|
|
55
|
-
//# sourceMappingURL=chunk-SQB4F3EF.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/middleware/audit-middleware.ts"],"sourcesContent":["/**\n * Audit middleware — standardized audit event creation for form mutations.\n *\n * Provides a typed `AuditEvent` and factory functions that hook into\n * `form:afterSave` and `form:afterDelete` to produce audit events for every\n * successful create, update, or delete operation.\n *\n * @example\n * ```ts\n * import { createAuditMiddleware } from \"@spring-systems/core/middleware\";\n *\n * // Send audit events to your backend:\n * const unregister = createAuditMiddleware(async (event) => {\n * await fetch(\"/api/audit\", {\n * method: \"POST\",\n * headers: { \"Content-Type\": \"application/json\" },\n * body: JSON.stringify(event),\n * });\n * });\n *\n * // Or log to console during development:\n * createAuditMiddleware((event) => {\n * console.log(`[Audit] ${event.action} ${event.entity}#${event.entityId}`, event);\n * });\n * ```\n *\n * @module audit-middleware\n */\n\nimport { logWarn } from \"../logger/logger\";\nimport type { MiddlewareOptions } from \"./middleware-registry\";\nimport { registerMiddleware } from \"./middleware-registry\";\nimport type { FormDeleteContext, FormSaveContext, MiddlewareFn } from \"./middleware-types\";\n\nexport interface AuditEvent {\n /** Mutation type */\n action: \"create\" | \"update\" | \"delete\";\n /** Entity type name (e.g. \"partner\", \"user\") */\n entity: string;\n /** Entity record identifier */\n entityId: string;\n /** ISO 8601 timestamp of the event */\n timestamp: string;\n /** API endpoint URL used for the operation */\n url: string;\n /** Field values included in the save payload (empty object for deletes) */\n fields: Record<string, unknown>;\n}\n\nexport type AuditEventHandler = (event: AuditEvent) => void | Promise<void>;\n\nasync function invokeAuditHandler(handler: AuditEventHandler, event: AuditEvent): Promise<void> {\n try {\n await Promise.resolve(handler(event));\n } catch (err: unknown) {\n logWarn(\n \"AuditMiddleware\",\n `Handler error for ${event.action} ${event.entity}#${event.entityId}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n}\n\n/**\n * Create and register audit middleware that emits `AuditEvent` for every\n * successful form save (create or update) and delete operation.\n *\n * The middleware hooks into both `form:afterSave` and `form:afterDelete` slots.\n * Aborted operations are silently skipped.\n *\n * @param handler - Callback that receives the audit event. Can be sync or async.\n * Async errors are caught and logged to prevent audit failures\n * from breaking the operation flow.\n * @param options - Optional middleware options (e.g. `{ priority: 10 }`)\n * @returns An unregister function that removes both audit middleware registrations.\n */\nexport function createAuditMiddleware(\n handler: AuditEventHandler,\n options?: MiddlewareOptions,\n): () => void {\n const saveMiddleware: MiddlewareFn<FormSaveContext> = async (ctx, next) => {\n await next();\n\n if (ctx.aborted) return;\n\n await invokeAuditHandler(handler, {\n action: ctx.isNew ? \"create\" : \"update\",\n entity: ctx.entity,\n entityId: ctx.id,\n timestamp: new Date().toISOString(),\n url: ctx.url,\n fields: ctx.fields,\n });\n };\n\n const deleteMiddleware: MiddlewareFn<FormDeleteContext> = async (ctx, next) => {\n await next();\n\n if (ctx.aborted) return;\n\n await invokeAuditHandler(handler, {\n action: \"delete\",\n entity: ctx.entity,\n entityId: ctx.id,\n timestamp: new Date().toISOString(),\n url: ctx.url,\n fields: {},\n });\n };\n\n const unregisterSave = registerMiddleware(\"form:afterSave\", saveMiddleware, options);\n const unregisterDelete = registerMiddleware(\"form:afterDelete\", deleteMiddleware, options);\n\n return () => {\n unregisterSave();\n unregisterDelete();\n };\n}\n"],"mappings":";;;;;;;;AAmDA,eAAe,mBAAmB,SAA4B,OAAkC;AAC5F,MAAI;AACA,UAAM,QAAQ,QAAQ,QAAQ,KAAK,CAAC;AAAA,EACxC,SAAS,KAAc;AACnB;AAAA,MACI;AAAA,MACA,qBAAqB,MAAM,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,QAAQ,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IAC5H;AAAA,EACJ;AACJ;AAeO,SAAS,sBACZ,SACA,SACU;AACV,QAAM,iBAAgD,OAAO,KAAK,SAAS;AACvE,UAAM,KAAK;AAEX,QAAI,IAAI,QAAS;AAEjB,UAAM,mBAAmB,SAAS;AAAA,MAC9B,QAAQ,IAAI,QAAQ,WAAW;AAAA,MAC/B,QAAQ,IAAI;AAAA,MACZ,UAAU,IAAI;AAAA,MACd,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,KAAK,IAAI;AAAA,MACT,QAAQ,IAAI;AAAA,IAChB,CAAC;AAAA,EACL;AAEA,QAAM,mBAAoD,OAAO,KAAK,SAAS;AAC3E,UAAM,KAAK;AAEX,QAAI,IAAI,QAAS;AAEjB,UAAM,mBAAmB,SAAS;AAAA,MAC9B,QAAQ;AAAA,MACR,QAAQ,IAAI;AAAA,MACZ,UAAU,IAAI;AAAA,MACd,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,KAAK,IAAI;AAAA,MACT,QAAQ,CAAC;AAAA,IACb,CAAC;AAAA,EACL;AAEA,QAAM,iBAAiB,mBAAmB,kBAAkB,gBAAgB,OAAO;AACnF,QAAM,mBAAmB,mBAAmB,oBAAoB,kBAAkB,OAAO;AAEzF,SAAO,MAAM;AACT,mBAAe;AACf,qBAAiB;AAAA,EACrB;AACJ;","names":[]}
|
package/dist/chunk-UDT2RPX2.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
// src/config/runtime-env-config.ts
|
|
2
|
-
var RUNTIME_ENV_KEYS = ["IMAGE_TAG", "ENVIRONMENT", "BUILD_NUM", "BUILD_DATE"];
|
|
3
|
-
var extraKeys = [];
|
|
4
|
-
function registerRuntimeEnvKeys(...keys) {
|
|
5
|
-
for (const key of keys) {
|
|
6
|
-
if (!extraKeys.includes(key) && !RUNTIME_ENV_KEYS.includes(key)) {
|
|
7
|
-
extraKeys.push(key);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
function getRuntimeEnvKeys() {
|
|
12
|
-
if (extraKeys.length === 0) return RUNTIME_ENV_KEYS;
|
|
13
|
-
return [...RUNTIME_ENV_KEYS, ...extraKeys];
|
|
14
|
-
}
|
|
15
|
-
function clearRuntimeEnvKeys() {
|
|
16
|
-
extraKeys.length = 0;
|
|
17
|
-
}
|
|
18
|
-
function getEnv() {
|
|
19
|
-
if (typeof window === "undefined") {
|
|
20
|
-
return {};
|
|
21
|
-
}
|
|
22
|
-
return window.__RUNTIME_ENV__ ?? {};
|
|
23
|
-
}
|
|
24
|
-
function getRuntimeVar(key) {
|
|
25
|
-
const env = getEnv();
|
|
26
|
-
const v = env[key];
|
|
27
|
-
return typeof v === "string" ? v : "";
|
|
28
|
-
}
|
|
29
|
-
function getImageTag() {
|
|
30
|
-
const v = getEnv().IMAGE_TAG;
|
|
31
|
-
if (!v) return "";
|
|
32
|
-
return v;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export {
|
|
36
|
-
RUNTIME_ENV_KEYS,
|
|
37
|
-
registerRuntimeEnvKeys,
|
|
38
|
-
getRuntimeEnvKeys,
|
|
39
|
-
clearRuntimeEnvKeys,
|
|
40
|
-
getRuntimeVar,
|
|
41
|
-
getImageTag
|
|
42
|
-
};
|
|
43
|
-
//# sourceMappingURL=chunk-UDT2RPX2.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config/runtime-env-config.ts"],"sourcesContent":["/**\n * Runtime environment variable keys injected on the client.\n * Values are read from `window.__RUNTIME_ENV__`.\n *\n * Consumers can register additional keys via `registerRuntimeEnvKeys()`.\n * @module runtime-env-config\n */\n\n/** Default framework runtime env keys. */\nexport const RUNTIME_ENV_KEYS = [\"IMAGE_TAG\", \"ENVIRONMENT\", \"BUILD_NUM\", \"BUILD_DATE\"] as const;\nexport type RuntimeEnvKey = (typeof RUNTIME_ENV_KEYS)[number];\nexport type RuntimeEnv = Partial<Record<string, string>>;\n\nconst extraKeys: string[] = [];\n\n/**\n * Register additional runtime environment keys.\n * Call this before runtime env payload is consumed by the app bootstrap.\n */\nexport function registerRuntimeEnvKeys(...keys: string[]): void {\n for (const key of keys) {\n if (!extraKeys.includes(key) && !(RUNTIME_ENV_KEYS as readonly string[]).includes(key)) {\n extraKeys.push(key);\n }\n }\n}\n\n/** Returns all registered runtime env keys (defaults + consumer-registered). */\nexport function getRuntimeEnvKeys(): readonly string[] {\n if (extraKeys.length === 0) return RUNTIME_ENV_KEYS;\n return [...RUNTIME_ENV_KEYS, ...extraKeys];\n}\n\n/** Clear consumer-registered runtime env keys. For testing only. */\nexport function clearRuntimeEnvKeys(): void {\n extraKeys.length = 0;\n}\n\ndeclare global {\n interface Window {\n __RUNTIME_ENV__?: RuntimeEnv;\n }\n}\n\nfunction getEnv(): RuntimeEnv {\n if (typeof window === \"undefined\") {\n return {};\n }\n return window.__RUNTIME_ENV__ ?? {};\n}\n\nexport function getRuntimeVar(key: string): string {\n const env = getEnv();\n const v = env[key];\n return typeof v === \"string\" ? v : \"\";\n}\n\nexport function getImageTag(): string {\n const v = getEnv().IMAGE_TAG;\n if (!v) return \"\";\n return v;\n}\n"],"mappings":";AASO,IAAM,mBAAmB,CAAC,aAAa,eAAe,aAAa,YAAY;AAItF,IAAM,YAAsB,CAAC;AAMtB,SAAS,0BAA0B,MAAsB;AAC5D,aAAW,OAAO,MAAM;AACpB,QAAI,CAAC,UAAU,SAAS,GAAG,KAAK,CAAE,iBAAuC,SAAS,GAAG,GAAG;AACpF,gBAAU,KAAK,GAAG;AAAA,IACtB;AAAA,EACJ;AACJ;AAGO,SAAS,oBAAuC;AACnD,MAAI,UAAU,WAAW,EAAG,QAAO;AACnC,SAAO,CAAC,GAAG,kBAAkB,GAAG,SAAS;AAC7C;AAGO,SAAS,sBAA4B;AACxC,YAAU,SAAS;AACvB;AAQA,SAAS,SAAqB;AAC1B,MAAI,OAAO,WAAW,aAAa;AAC/B,WAAO,CAAC;AAAA,EACZ;AACA,SAAO,OAAO,mBAAmB,CAAC;AACtC;AAEO,SAAS,cAAc,KAAqB;AAC/C,QAAM,MAAM,OAAO;AACnB,QAAM,IAAI,IAAI,GAAG;AACjB,SAAO,OAAO,MAAM,WAAW,IAAI;AACvC;AAEO,SAAS,cAAsB;AAClC,QAAM,IAAI,OAAO,EAAE;AACnB,MAAI,CAAC,EAAG,QAAO;AACf,SAAO;AACX;","names":[]}
|
package/dist/chunk-VRMVN2UM.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
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
|
-
DARK_MODE: "darkMode"
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export {
|
|
12
|
-
emptyGuid,
|
|
13
|
-
DIALOG_CONTENT_SELECTOR,
|
|
14
|
-
DND_TOUCH_CONSTRAINT,
|
|
15
|
-
STORAGE_KEYS
|
|
16
|
-
};
|
|
17
|
-
//# sourceMappingURL=chunk-VRMVN2UM.js.map
|
|
@@ -1 +0,0 @@
|
|
|
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 DARK_MODE: \"darkMode\",\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;AAAA,EACb,WAAW;AACf;","names":[]}
|
package/dist/config/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/devtools/inspect.ts"],"sourcesContent":["/**\n * Lightweight dev-mode introspection utility for SpringInstance.\n * Zero production cost — all functions are no-ops when `__DEV__` is false.\n *\n * Usage in browser console: `window.__SPRING_INSPECT__()`\n *\n * @module devtools/inspect\n */\n\nimport { tryGetSpringInstance } from \"../instance/current-instance\";\nimport type { SpringInstance } from \"../instance/spring-instance\";\nimport { __DEV__ } from \"../utils/dev-warnings\";\n\ninterface InspectResult {\n id: string;\n state: string;\n config: {\n appName: string;\n defaultRoute: string;\n apiTimeoutMs: number | undefined;\n languages: number;\n };\n plugins: ReadonlyArray<{ name: string; version?: string }>;\n capabilities: Record<string, unknown>;\n middleware: string[];\n slots: string[];\n fieldTypes: string[];\n columnTypes: string[];\n validators: string[];\n adapters: {\n route: boolean;\n ui: boolean;\n http: boolean;\n telemetry: boolean;\n };\n auth: {\n authenticated: boolean;\n hasToken: boolean;\n };\n}\n\nfunction collectRegistryKeys(instance: SpringInstance, uiKey: symbol): string[] {\n const registry = instance.ui[uiKey];\n if (registry instanceof Map) return Array.from(registry.keys()) as string[];\n return [];\n}\n\n/**\n * Inspect the current SpringInstance state. Returns a structured summary\n * of all framework registrations, adapters, and configuration.\n *\n * Only works in dev mode — returns `undefined` in production.\n */\nexport function inspectInstance(instance?: SpringInstance): InspectResult | undefined {\n if (!__DEV__) return undefined;\n\n const inst = instance ?? tryGetSpringInstance();\n if (!inst) {\n console.warn(\"[SPRING DevTools] No SpringInstance found. Is SpringProvider mounted?\");\n return undefined;\n }\n\n const config = inst.core.config;\n const loadedPlugins = (inst.ui[Symbol.for(\"spring:loadedPlugins\")] ?? []) as ReadonlyArray<{ name: string; version?: string }>;\n const capabilities = (inst.ui[Symbol.for(\"spring:capabilities\")] ?? {}) as Record<string, unknown>;\n\n const middlewareSlots = Array.from(inst.core.middlewareRegistry.entries())\n .filter(([, list]) => list.length > 0)\n .map(([slot, list]) => `${slot} (${list.length})`);\n\n const result: InspectResult = {\n id: inst.id,\n state: inst.state,\n config: {\n appName: config.app.name,\n defaultRoute: config.app.defaultRoute,\n apiTimeoutMs: config.api?.timeoutMs,\n languages: config.i18n.languages.length,\n },\n plugins: loadedPlugins,\n capabilities,\n middleware: middlewareSlots,\n slots: collectRegistryKeys(inst, Symbol.for(\"spring:slotRegistry\")),\n fieldTypes: collectRegistryKeys(inst, Symbol.for(\"spring:fieldRendererRegistry\")),\n columnTypes: collectRegistryKeys(inst, Symbol.for(\"spring:columnRendererRegistry\")),\n validators: Array.from(inst.core.validatorRegistry.keys()),\n adapters: {\n route: !!inst.ui[Symbol.for(\"spring:routeAdapter\")],\n ui: !!inst.ui[Symbol.for(\"spring:uiAdapter\")],\n http: !!inst.ui[Symbol.for(\"spring:httpAdapter\")],\n telemetry: !!inst.ui[Symbol.for(\"spring:telemetryAdapter\")],\n },\n auth: {\n authenticated: inst.core.authenticated,\n hasToken: !!inst.api.authToken,\n },\n };\n\n console.info(`SPRING Instance: ${inst.id} [${inst.state}]`);\n console.info(\"App:\", config.app.name);\n console.info(\"Plugins:\", loadedPlugins.length > 0 ? loadedPlugins : \"(none)\");\n console.info(\"Middleware:\", middlewareSlots.length > 0 ? middlewareSlots : \"(none)\");\n console.info(\"Slots:\", result.slots.length > 0 ? result.slots : \"(none)\");\n console.info(\"Capabilities:\", Object.keys(capabilities).length > 0 ? capabilities : \"(none)\");\n console.info(\"Adapters:\", result.adapters);\n console.info(\"Auth:\", result.auth);\n\n return result;\n}\n\n// Register global shortcut for browser console\nif (__DEV__ && typeof window !== \"undefined\") {\n (window as unknown as Record<string, unknown>).__SPRING_INSPECT__ = inspectInstance;\n}\n"],"mappings":";;;;;;;AAyCA,SAAS,oBAAoB,UAA0B,OAAyB;AAC5E,QAAM,WAAW,SAAS,GAAG,KAAK;AAClC,MAAI,oBAAoB,IAAK,QAAO,MAAM,KAAK,SAAS,KAAK,CAAC;AAC9D,SAAO,CAAC;AACZ;AAQO,SAAS,gBAAgB,UAAsD;AAClF,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,OAAO,YAAY,qBAAqB;AAC9C,MAAI,CAAC,MAAM;AACP,YAAQ,KAAK,uEAAuE;AACpF,WAAO;AAAA,EACX;AAEA,QAAM,SAAS,KAAK,KAAK;AACzB,QAAM,gBAAiB,KAAK,GAAG,uBAAO,IAAI,sBAAsB,CAAC,KAAK,CAAC;AACvE,QAAM,eAAgB,KAAK,GAAG,uBAAO,IAAI,qBAAqB,CAAC,KAAK,CAAC;AAErE,QAAM,kBAAkB,MAAM,KAAK,KAAK,KAAK,mBAAmB,QAAQ,CAAC,EACpE,OAAO,CAAC,CAAC,EAAE,IAAI,MAAM,KAAK,SAAS,CAAC,EACpC,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM,GAAG,IAAI,KAAK,KAAK,MAAM,GAAG;AAErD,QAAM,SAAwB;AAAA,IAC1B,IAAI,KAAK;AAAA,IACT,OAAO,KAAK;AAAA,IACZ,QAAQ;AAAA,MACJ,SAAS,OAAO,IAAI;AAAA,MACpB,cAAc,OAAO,IAAI;AAAA,MACzB,cAAc,OAAO,KAAK;AAAA,MAC1B,WAAW,OAAO,KAAK,UAAU;AAAA,IACrC;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA,YAAY;AAAA,IACZ,OAAO,oBAAoB,MAAM,uBAAO,IAAI,qBAAqB,CAAC;AAAA,IAClE,YAAY,oBAAoB,MAAM,uBAAO,IAAI,8BAA8B,CAAC;AAAA,IAChF,aAAa,oBAAoB,MAAM,uBAAO,IAAI,+BAA+B,CAAC;AAAA,IAClF,YAAY,MAAM,KAAK,KAAK,KAAK,kBAAkB,KAAK,CAAC;AAAA,IACzD,UAAU;AAAA,MACN,OAAO,CAAC,CAAC,KAAK,GAAG,uBAAO,IAAI,qBAAqB,CAAC;AAAA,MAClD,IAAI,CAAC,CAAC,KAAK,GAAG,uBAAO,IAAI,kBAAkB,CAAC;AAAA,MAC5C,MAAM,CAAC,CAAC,KAAK,GAAG,uBAAO,IAAI,oBAAoB,CAAC;AAAA,MAChD,WAAW,CAAC,CAAC,KAAK,GAAG,uBAAO,IAAI,yBAAyB,CAAC;AAAA,IAC9D;AAAA,IACA,MAAM;AAAA,MACF,eAAe,KAAK,KAAK;AAAA,MACzB,UAAU,CAAC,CAAC,KAAK,IAAI;AAAA,IACzB;AAAA,EACJ;AAEA,UAAQ,KAAK,oBAAoB,KAAK,EAAE,KAAK,KAAK,KAAK,GAAG;AAC1D,UAAQ,KAAK,QAAQ,OAAO,IAAI,IAAI;AACpC,UAAQ,KAAK,YAAY,cAAc,SAAS,IAAI,gBAAgB,QAAQ;AAC5E,UAAQ,KAAK,eAAe,gBAAgB,SAAS,IAAI,kBAAkB,QAAQ;AACnF,UAAQ,KAAK,UAAU,OAAO,MAAM,SAAS,IAAI,OAAO,QAAQ,QAAQ;AACxE,UAAQ,KAAK,iBAAiB,OAAO,KAAK,YAAY,EAAE,SAAS,IAAI,eAAe,QAAQ;AAC5F,UAAQ,KAAK,aAAa,OAAO,QAAQ;AACzC,UAAQ,KAAK,SAAS,OAAO,IAAI;AAEjC,SAAO;AACX;AAGA,IAAI,WAAW,OAAO,WAAW,aAAa;AAC1C,EAAC,OAA8C,qBAAqB;AACxE;","names":[]}
|
package/dist/errors/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/events/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/i18n/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// @spring-systems/core\n// Core types, utilities, and configuration for Spring Systems SPRING.\n// Use sub-path imports for tree-shaking: @spring-systems/core/config, /utils, /types, etc.\n//\n// Convenience re-exports for the most commonly used APIs:\nexport {\n configureCapabilities,\n configureFramework,\n getCapabilities,\n getCapability,\n getFrameworkConfig,\n hasCapability,\n} from \"./config\";\nexport { eventBus } from \"./events/event-bus\";\nexport { getMiddlewareRunner, registerMiddleware } from \"./middleware\";\n\ndeclare const __VERSION__: string;\nexport const SPRING_CORE_VERSION: string = typeof __VERSION__ !== \"undefined\" ? __VERSION__ : \"0.0.0-dev\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiBO,IAAM,sBAA8B,OAAqC,UAAc;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/logger/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
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":[]}
|
package/dist/types/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/types/branded.ts","../../src/types/grid-types.ts","../../src/types/list-types.ts"],"sourcesContent":["/**\n * Branded types for nominal type safety.\n * Prevents accidental interchange of structurally identical string types.\n * @module branded\n */\n\ndeclare const __brand: unique symbol;\n\n/** Brands a base type `T` with a nominal tag `B`. */\nexport type Brand<T, B extends string> = T & { readonly [__brand]: B };\n\n/** A GUID / UUID string. */\nexport type Guid = Brand<string, \"Guid\">;\n\n/** A public entity identifier. */\nexport type IdPublic = Brand<string, \"IdPublic\">;\n\n/** A resource/translation key. */\nexport type ResourceKey = Brand<string, \"ResourceKey\">;\n\n/** An API route path. */\nexport type ApiRoute = Brand<string, \"ApiRoute\">;\n\n/** Cast a plain string to a Guid (boundary cast). */\nexport function toGuid(value: string): Guid {\n return value as Guid;\n}\n\n/** Cast a plain string to an IdPublic (boundary cast). */\nexport function toIdPublic(value: string): IdPublic {\n return value as IdPublic;\n}\n\n/** Cast a plain string to a ResourceKey (boundary cast). */\nexport function toResourceKey(value: string): ResourceKey {\n return value as ResourceKey;\n}\n\n/** Cast a plain string to an ApiRoute (boundary cast). */\nexport function toApiRoute(value: string): ApiRoute {\n return value as ApiRoute;\n}\n","/**\n * Shared types used by both List and TreeList grids.\n * Single source of truth — re-exported from lists.ts and treelists.ts.\n * @module grid-types\n */\n\nexport interface Permission {\n delete: boolean;\n insert: boolean;\n list: boolean;\n read: boolean;\n update: boolean;\n /** Allows projects to add custom permission fields (e.g., { export: true, approve: false }) */\n [key: string]: boolean;\n}\n\nexport type LogicOperator = \"and\" | \"or\";\n\n/** Node structure for tree-based filter. */\nexport interface FilterNode {\n field?: string;\n operator?: string;\n value?: string | number | boolean | null;\n logic?: LogicOperator;\n filters?: FilterNode[];\n negate?: boolean;\n}\n\n/** Simple key-value system filter (normalized into FilterNode by the engine). */\nexport interface SystemFilterRecord {\n [key: string]: string | number | boolean | Date | null | undefined;\n}\n\nexport type ColumnType = \"string\" | \"number\" | \"date\" | \"datetime\" | \"time\" | \"boolean\" | \"object\" | \"color\";\n\n/** Column layout for saving into user settings. */\nexport interface ColumnLayout {\n key: string;\n order: number;\n width?: number;\n show: boolean;\n}\n\nexport interface DefaultFilter {\n domain_name: string;\n id_public: string;\n is_default: boolean;\n json_data: string;\n name: string;\n user_setting_type_code: \"user\" | \"fixed\" | \"layout\";\n version: number;\n}\n\nexport interface SavedLayout {\n domain_name: string;\n id_public: string;\n is_default: boolean;\n json_data: string;\n name: string;\n user_setting_type_code: \"layout\";\n version: number;\n}\n\n/** Combined structure for json_data in user-settings — filter + layout in one JSON. */\nexport interface CombinedSettingData {\n user_filter?: FilterNode | null;\n layout?: ColumnLayout[];\n}\n\n/** Type guard for FilterNode — checks for tree-filter or leaf-filter shape. */\nexport function isFilterNode(val: unknown): val is FilterNode {\n if (typeof val !== \"object\" || val === null || Array.isArray(val)) return false;\n return (\"logic\" in val && \"filters\" in val) || (\"field\" in val && \"operator\" in val);\n}\n\n/** Type guard for CombinedSettingData — checks for user_filter or layout property. */\nexport function isCombinedSettingData(val: unknown): val is CombinedSettingData {\n if (typeof val !== \"object\" || val === null || Array.isArray(val)) return false;\n return \"user_filter\" in val || \"layout\" in val;\n}\n\n/** Type guard for Permission — checks for all 5 required CRUD boolean keys. */\nexport function isPermission(val: unknown): val is Permission {\n if (typeof val !== \"object\" || val === null || Array.isArray(val)) return false;\n const obj = val as Record<string, unknown>;\n return (\n typeof obj.read === \"boolean\" &&\n typeof obj.list === \"boolean\" &&\n typeof obj.delete === \"boolean\" &&\n typeof obj.insert === \"boolean\" &&\n typeof obj.update === \"boolean\"\n );\n}\n\n/** Type guard for ColumnLayout — checks for required key, order, show properties. */\nexport function isColumnLayout(val: unknown): val is ColumnLayout {\n if (typeof val !== \"object\" || val === null || Array.isArray(val)) return false;\n const obj = val as Record<string, unknown>;\n return typeof obj.key === \"string\" && typeof obj.order === \"number\" && typeof obj.show === \"boolean\";\n}\n","/**\n * List types — pure type definitions extracted from shared/lists/lists.ts.\n * @module list-types\n */\n\nimport type { FormStoreState } from \"./form-types\";\nimport type { Permission } from \"./grid-types\";\n\n/** Comparison operators used in format conditions (conditional formatting). */\nexport type FormatOperator = \"==\" | \"===\" | \"!=\" | \"!==\" | \">\" | \">=\" | \"<\" | \"<=\";\n\nexport interface FormatCondition {\n value?: string | number | boolean | null;\n background?: string;\n color?: string;\n column?: string;\n field: string;\n operator?: FormatOperator;\n className?: string;\n}\n\nexport const FormatType = {\n Badge: 1,\n Color: 2,\n Background: 3,\n RowBackground: 4,\n Icon: 5,\n Detail: 6,\n} as const;\nexport type FormatType = (typeof FormatType)[keyof typeof FormatType];\n\nexport interface Pagination {\n page?: number;\n per_page?: number;\n object_count: number;\n}\n\nexport interface ListResponse<T> {\n data: T[];\n message: string | null;\n pagination: Pagination;\n permissions?: Permission;\n format_conditions: FormatCondition[];\n params?: FormStoreState;\n}\n"],"mappings":";;;;;;;;;;;AAwBO,SAAS,OAAO,OAAqB;AACxC,SAAO;AACX;AAGO,SAAS,WAAW,OAAyB;AAChD,SAAO;AACX;AAGO,SAAS,cAAc,OAA4B;AACtD,SAAO;AACX;AAGO,SAAS,WAAW,OAAyB;AAChD,SAAO;AACX;;;AC6BO,SAAS,aAAa,KAAiC;AAC1D,MAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,MAAM,QAAQ,GAAG,EAAG,QAAO;AAC1E,SAAQ,WAAW,OAAO,aAAa,OAAS,WAAW,OAAO,cAAc;AACpF;AAGO,SAAS,sBAAsB,KAA0C;AAC5E,MAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,MAAM,QAAQ,GAAG,EAAG,QAAO;AAC1E,SAAO,iBAAiB,OAAO,YAAY;AAC/C;AAGO,SAAS,aAAa,KAAiC;AAC1D,MAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,MAAM,QAAQ,GAAG,EAAG,QAAO;AAC1E,QAAM,MAAM;AACZ,SACI,OAAO,IAAI,SAAS,aACpB,OAAO,IAAI,SAAS,aACpB,OAAO,IAAI,WAAW,aACtB,OAAO,IAAI,WAAW,aACtB,OAAO,IAAI,WAAW;AAE9B;AAGO,SAAS,eAAe,KAAmC;AAC9D,MAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,MAAM,QAAQ,GAAG,EAAG,QAAO;AAC1E,QAAM,MAAM;AACZ,SAAO,OAAO,IAAI,QAAQ,YAAY,OAAO,IAAI,UAAU,YAAY,OAAO,IAAI,SAAS;AAC/F;;;AC9EO,IAAM,aAAa;AAAA,EACtB,OAAO;AAAA,EACP,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,MAAM;AAAA,EACN,QAAQ;AACZ;","names":[]}
|
package/dist/utils/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/a11y.ts","../../src/utils/color.ts","../../src/utils/data-utils.ts","../../src/utils/date.ts","../../src/utils/deprecation.ts","../../src/utils/filter-utils.ts","../../src/utils/format-utils.ts","../../src/utils/tree-utils.ts"],"sourcesContent":["interface KeyActivateEvent {\n key: string;\n preventDefault(): void;\n}\n\nexport function onKeyActivate<E extends KeyActivateEvent = KeyActivateEvent>(\n handler?: ((e: E) => void) | (() => void) | null,\n) {\n if (!handler) return undefined;\n return (e: E) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n (handler as (e: E) => void)(e);\n }\n };\n}\n\nexport function prefersReducedMotion(): boolean {\n if (typeof window === \"undefined\") return false;\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n}\n","export function getBrightness(r: number, g: number, b: number): number {\n return (r * 299 + g * 587 + b * 114) / 1000;\n}\n\nexport function hexToRgb(hex: string): [number, number, number] {\n const bigint = parseInt(hex.slice(1), 16);\n const r = (bigint >> 16) & 255;\n const g = (bigint >> 8) & 255;\n const b = bigint & 255;\n return [r, g, b];\n}\n\nexport function rgbToHex(rgb: string): string {\n const match = rgb.match(/\\d+/g);\n if (!match) return \"#000000\";\n const result = match.map((x) => parseInt(x).toString(16).padStart(2, \"0\")).join(\"\");\n return `#${result}`;\n}\n\nexport function getContrastYIQ(hex: string): string {\n const [r, g, b] = hexToRgb(hex);\n const brightness = getBrightness(r, g, b);\n return brightness > 150 ? \"black\" : \"white\";\n}\n","import dayjs from \"dayjs\";\nimport customParseFormat from \"dayjs/plugin/customParseFormat\";\n\nimport { emptyGuid } from \"../config/constants\";\nimport { SpringValidationError } from \"../errors/errors\";\nimport type { FormDataValue, FormStoreState, Indexable, IndexedFormData } from \"../types/form-types\";\n\ndayjs.extend(customParseFormat);\n\nconst UNSAFE_MERGE_KEYS = new Set([\"__proto__\", \"prototype\", \"constructor\"]);\n\nexport function isValueNotEmpty(value: string | number | boolean | null | undefined | FormDataValue[]): boolean {\n return (\n value !== 0 &&\n value !== null &&\n value !== undefined &&\n value !== false &&\n value !== \"\" &&\n !(Array.isArray(value) && value.length === 0)\n );\n}\n\n/** Returns a deep copy of an object, removing unwanted references. */\nexport function deepCopy<T>(obj: T, hash?: WeakMap<WeakKey, unknown>): T {\n // Fast path: use native structuredClone on top-level calls (handles Date, RegExp, circular refs natively).\n // Falls back to manual implementation when structuredClone fails (e.g. objects containing functions).\n if (!hash && typeof structuredClone === \"function\") {\n try {\n return structuredClone(obj);\n } catch {\n // structuredClone cannot handle functions — fall through to manual copy\n }\n }\n\n const map = hash ?? new WeakMap();\n\n if (typeof obj === \"object\" && obj !== null && map.has(obj)) return map.get(obj) as T;\n\n if (obj instanceof Date) return new Date(obj.getTime()) as T;\n if (obj instanceof RegExp) return new RegExp(obj.source, obj.flags) as T;\n if (obj === null || typeof obj !== \"object\") return obj;\n\n const result = (Array.isArray(obj) ? [] : {}) as Indexable;\n map.set(obj, result);\n\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n result[key] = deepCopy((obj as Indexable)[key], map);\n }\n }\n\n return result as T;\n}\n\n/**\n * Performs deep comparison of two objects.\n * Treats `null` and `\"\"` as equivalent — this is intentional because the backend\n * API returns `null` for empty fields while form inputs produce `\"\"`.\n */\nexport function deepEqual(a: FormDataValue | FormStoreState, b: FormDataValue | FormStoreState): boolean {\n if (a === b) return true;\n\n if ((a === null && b === \"\") || (a === \"\" && b === null)) return true;\n\n if (\n a == null ||\n b == null ||\n (typeof a !== \"object\" && typeof a !== \"function\") ||\n (typeof b !== \"object\" && typeof b !== \"function\")\n ) {\n return false;\n }\n\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n\n const objA = a as IndexedFormData;\n const objB = b as IndexedFormData;\n const keysA = Object.keys(objA);\n const keysB = Object.keys(objB);\n\n if (keysA.length !== keysB.length) {\n return false;\n }\n\n const keysBSet = new Set(keysB);\n for (const key of keysA) {\n if (!keysBSet.has(key) || !deepEqual(objA[key], objB[key])) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function deepMerge<T extends Indexable>(target: T, source: Partial<T>): T {\n const result = { ...target };\n Object.keys(source).forEach((key) => {\n if (UNSAFE_MERGE_KEYS.has(key)) {\n return;\n }\n const k = key as keyof T;\n if (source[k] && typeof source[k] === \"object\" && !Array.isArray(source[k])) {\n result[k] = deepMerge(\n (target[k] && typeof target[k] === \"object\" ? target[k] : {}) as T[keyof T] & Indexable,\n source[k] as Partial<T[keyof T] & Indexable>,\n ) as T[keyof T];\n } else {\n result[k] = source[k] as T[keyof T];\n }\n });\n return result;\n}\n\nexport function getValueByPath(obj: FormStoreState, path: string): FormDataValue {\n const keys = path.split(\".\");\n let current: FormDataValue | FormStoreState = obj;\n\n for (const key of keys) {\n if (current == null || typeof current !== \"object\" || current instanceof Date) {\n return undefined;\n }\n if (Array.isArray(current)) return undefined;\n current = (current as IndexedFormData)[key];\n }\n\n return current as FormDataValue;\n}\n\n/** Normalizes a string for comparison without diacritics, in lowercase */\nexport function normalizeString(str: string): string {\n return str\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .toLowerCase();\n}\n\nexport function generateGUID(): string {\n const cryptoApi = globalThis.crypto;\n if (cryptoApi && typeof cryptoApi.randomUUID === \"function\") {\n return cryptoApi.randomUUID();\n }\n\n if (cryptoApi && typeof cryptoApi.getRandomValues === \"function\") {\n const bytes = new Uint8Array(16);\n cryptoApi.getRandomValues(bytes);\n // RFC 4122 version 4 bits\n const b6 = bytes[6] ?? 0;\n const b8 = bytes[8] ?? 0;\n bytes[6] = (b6 & 0x0f) | 0x40;\n bytes[8] = (b8 & 0x3f) | 0x80;\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n }\n\n throw new SpringValidationError(\n \"generateGUID(): secure random source unavailable. Provide Web Crypto (crypto.randomUUID or crypto.getRandomValues).\",\n \"generateGUID\",\n );\n}\n\nexport function setDefaultStructure(\n data: { field?: string; type?: string }[],\n): Record<string, string | number | boolean | null | undefined> {\n const result: Record<string, string | number | boolean | null | undefined> = {\n id_public: emptyGuid,\n };\n\n const defaultValue = (type: string | undefined) => {\n switch (type) {\n case \"boolean\":\n return false;\n case \"string\":\n return \"\";\n case \"number\":\n return \"\";\n case \"object\":\n case \"date\":\n case \"datetime\":\n case \"time\":\n return null;\n default:\n return undefined;\n }\n };\n\n data.forEach((item: { field?: string; type?: string }) => {\n if (item.field) {\n result[item.field] = defaultValue(item.type);\n }\n });\n\n return result;\n}\n\nexport function parseJSONSafely(\n value: string | number | boolean | null | undefined | object,\n): string | number | boolean | null | undefined | object {\n if (typeof value === \"string\") {\n if (value.toLowerCase() === \"true\") {\n return true;\n } else if (value.toLowerCase() === \"false\") {\n return false;\n }\n\n try {\n return JSON.parse(value);\n } catch (_e: unknown) {\n return value;\n }\n }\n\n return value;\n}\n\nexport type ValueType = \"string\" | \"date\" | \"number\" | \"boolean\" | \"object\";\n\nexport function getValueType(value: string | number | boolean | null | undefined | object): ValueType {\n const v = parseJSONSafely(value);\n\n if (v === null || v === undefined) {\n return \"string\";\n }\n\n if (v instanceof Date) {\n return \"date\";\n }\n\n if (typeof v === \"string\") {\n const trimmed = v.trim();\n\n const looksLikeDate = /[0-9]/.test(trimmed) && /[-./]/.test(trimmed) && trimmed.length >= 6;\n\n if (looksLikeDate) {\n const formats = [\n \"D.M.YYYY\",\n \"DD.MM.YYYY\",\n \"D. M. YYYY\",\n \"DD. MM. YYYY\",\n \"DD.MM.YYYY HH:mm\",\n \"D.M.YYYY HH:mm\",\n \"DD.MM.YYYY H:mm\",\n \"D.M.YYYY H:mm\",\n \"YYYY-MM-DD\",\n \"YYYY-MM-DDTHH:mm:ss\",\n \"YYYY-MM-DDTHH:mm:ss.SSS\",\n \"YYYY-MM-DDTHH:mm:ssZ\",\n \"YYYY-MM-DDTHH:mm:ss.SSSZ\",\n ];\n\n if (dayjs(trimmed, formats as string[], true).isValid()) {\n return \"date\";\n }\n\n if (dayjs(trimmed).isValid() && /^\\d{4}-\\d{2}-\\d{2}/.test(trimmed)) {\n return \"date\";\n }\n }\n }\n\n if (Array.isArray(v)) {\n if (v.length === 0) {\n return \"object\";\n }\n return getValueType(v[0]);\n }\n\n const t = typeof v;\n\n if (t === \"number\") {\n return \"number\";\n }\n\n if (t === \"boolean\") {\n return \"boolean\";\n }\n\n if (t === \"object\") {\n return \"object\";\n }\n\n return \"string\";\n}\n","import dayjs from \"dayjs\";\n// Consumer must import their locale (e.g., import \"dayjs/locale/cs\") before using dateManager\nimport customParseFormat from \"dayjs/plugin/customParseFormat\";\nimport isBetweenPlugin from \"dayjs/plugin/isBetween\";\n\nimport { type DateFormatConfig, getFrameworkConfig } from \"../config/framework-config\";\n\ndayjs.extend(customParseFormat);\ndayjs.extend(isBetweenPlugin);\n\nlet activeLocale: string | null = null;\n\nfunction ensureLocale(): void {\n const locale = getFrameworkConfig().i18n.dayjsLocale;\n if (locale && locale !== activeLocale) {\n dayjs.locale(locale);\n activeLocale = locale;\n }\n}\n\n/**\n * Set the dayjs locale at runtime.\n * The locale package must be imported before calling this (e.g., `import \"dayjs/locale/en\"`).\n */\nexport function setDateLocale(locale: string): void {\n activeLocale = locale;\n dayjs.locale(locale);\n}\n\nfunction fmt(): DateFormatConfig {\n ensureLocale();\n return getFrameworkConfig().i18n.dateFormats;\n}\n\nexport const dateManager = {\n formatDateCustom(value: Date | null, format: string) {\n if (!value) {\n return \"\";\n } else {\n return dayjs(value).format(format);\n }\n },\n formatDate(value: Date | null) {\n if (!value) {\n return \"\";\n } else {\n return dayjs(value).format(fmt().date);\n }\n },\n formatDateTime(value: Date | null) {\n if (!value) {\n return \"\";\n } else {\n return dayjs(value).format(fmt().dateTime);\n }\n },\n formatTime(value: Date | null) {\n if (!value) {\n return \"\";\n } else {\n return dayjs(value).format(fmt().time);\n }\n },\n formatDateRange(dateFrom: Date, dateTo: Date, format = fmt().date) {\n const from = dayjs(dateFrom);\n const to = dayjs(dateTo);\n const dtFmt = fmt().dateTime;\n\n if (from.isSame(to, \"day\")) {\n if (format.includes(\"H\") || format.includes(\"h\")) {\n return `${from.format(dtFmt)}-${to.format(fmt().time)}`;\n } else if (format === fmt().time) {\n return `${from.format(fmt().time)}-${to.format(fmt().time)}`;\n }\n return from.format(format);\n }\n\n if (format.includes(\"H\") || format.includes(\"h\")) {\n return `${from.format(dtFmt)} - ${to.format(dtFmt)}`;\n } else if (format === fmt().time) {\n return `${from.format(fmt().time)} - ${to.format(fmt().time)}`;\n }\n\n return `${from.format(fmt().date)} - ${to.format(fmt().date)}`;\n },\n formatDateTimeWithSeconds(value: Date | null) {\n if (!value) {\n return \"\";\n } else {\n return dayjs(value).format(fmt().dateTimeSeconds);\n }\n },\n /** Formats a value as date with time, or time only if it is today */\n formatDateTimeShort(value: Date | null) {\n if (!value) {\n return \"\";\n } else if (dayjs(value).isSame(Date.now(), \"day\")) {\n return dayjs(value).format(fmt().time);\n } else {\n return this.formatDateTime(value);\n }\n },\n getAgeFromDate(value: Date) {\n return dayjs().diff(value, \"years\");\n },\n formatMonthName(value: Date, format: string) {\n return dayjs(value).format(format);\n },\n formatMonthNumber(value: Date) {\n return dayjs(value).month() + 1;\n },\n getPreviousMonth(date: Date, numberOfMonth: number) {\n return dayjs(date).subtract(numberOfMonth, \"months\").toDate();\n },\n setTimeFromString(date: Date, time: string, onlyMinutes?: boolean) {\n const setDate = dayjs(date).toDate();\n const split = time.split(\":\");\n if (!onlyMinutes) {\n setDate.setHours(Number(split[0] ?? 0));\n } else {\n setDate.setSeconds(0);\n }\n setDate.setMinutes(Number(split[1] ?? 0));\n return setDate;\n },\n formatDateString(value: string) {\n if (!value) {\n return null;\n } else {\n if (value.split(\"-\")[0]?.length === 4) {\n return dayjs(value).toDate();\n }\n if (value.split(\".\")[0]?.length === 4 || value.split(\"/\")[0]?.length === 4) {\n return dayjs(value, \"YYYY. M. D.\").toDate();\n }\n return dayjs(value, \"D. M. YYYY\").toDate();\n }\n },\n getDuration(date: Date | null, date2: Date | null, type: dayjs.ManipulateType) {\n if (!date || !date2) {\n return null;\n } else {\n const value = dayjs(date);\n const value2 = dayjs(date2);\n const result = value2.diff(value, type);\n return result;\n }\n },\n getStartOfDate(date: Date, unitOfTime: dayjs.OpUnitType) {\n return dayjs(date).startOf(unitOfTime).toDate();\n },\n getEndOfDay(date: Date) {\n return dayjs(date).endOf(\"day\").toDate();\n },\n getDateRange(date: Date, unitOfTime: dayjs.OpUnitType) {\n const startDate = dayjs(date).startOf(unitOfTime).toDate();\n const endDate = dayjs(date).endOf(unitOfTime).toDate();\n return { dateFrom: startDate, dateTo: endDate };\n },\n isDateInRange(startDate: Date, endDate: Date, dateToCheck: Date) {\n if (!endDate) {\n return dayjs(dateToCheck).isSame(startDate, \"day\");\n }\n return dayjs(dateToCheck).isBetween(startDate, endDate, null, \"[]\");\n },\n /** Adds a number of days (or other unit) to a date */\n add(value: Date, count: number, type?: dayjs.ManipulateType) {\n return dayjs(value)\n .add(count, type ? type : \"days\")\n .toDate();\n },\n substractDaysFromDate(numberOfDays: number, date: Date) {\n const result = dayjs(date).subtract(numberOfDays, \"days\").toDate();\n return result;\n },\n};\n","/**\n * Runtime deprecation warnings for the SPRING framework.\n * Warns once per session per deprecation to avoid console spam.\n * @module deprecation\n */\n\nconst warned = new Set<string>();\n\nexport function springDeprecate(name: string, alternative: string, removeVersion?: string): void {\n const key = `${name}:${alternative}`;\n if (warned.has(key)) return;\n warned.add(key);\n\n const versionNote = removeVersion ? ` It will be removed in v${removeVersion}.` : \"\";\n console.warn(`[SPRING Deprecation] \"${name}\" is deprecated. Use ${alternative} instead.${versionNote}`);\n}\n\n/** Clear all tracked deprecation warnings. Intended for testing. */\nexport function clearDeprecationWarnings(): void {\n warned.clear();\n}\n","import type { FilterFieldValue } from \"../types/form-types\";\nimport type { FilterNode } from \"../types/grid-types\";\nimport { getValueType } from \"./data-utils\";\n\nexport function parseFilter(value: string | number | boolean | Date | null | undefined | FilterFieldValue[] | object): string | boolean {\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n if (Array.isArray(value)) {\n return JSON.stringify(value);\n }\n\n if (typeof value === \"boolean\") {\n return value;\n }\n\n return value != null ? value.toString() : \"\";\n}\n\n/** Normalizes system filter — string/object to FilterNode. */\nexport function normalizeSystemFilter(\n input: Record<string, string | number | boolean | Date | null | undefined> | FilterNode | null | undefined\n): FilterNode | null {\n if (!input) return null;\n if (typeof input === \"object\" && input !== null && (\"logic\" in input || \"field\" in input)) {\n return input as FilterNode;\n }\n\n if (typeof input === \"object\" && input !== null) {\n const entries = Object.entries(input).filter(([k, v]) => k && v !== undefined && v !== null && v !== \"\");\n const filters: FilterNode[] = entries.map(([k, v]) => {\n const val = parseFilter(v);\n return {\n field: k,\n operator: \"eq\",\n value: val,\n };\n });\n\n if (filters.length === 0) {\n return null;\n }\n\n return {\n logic: \"and\",\n filters,\n };\n }\n\n return null;\n}\n\nexport function getFilterFieldType(\n fieldKey: string,\n defaultListFilter: Record<string, { type?: string }> | null | undefined,\n value: string | number | boolean | null | undefined | object\n): string {\n const fieldDef = defaultListFilter && defaultListFilter[fieldKey];\n\n if (fieldDef && typeof fieldDef.type === \"string\") {\n return fieldDef.type;\n }\n\n return getValueType(value);\n}\n","import sanitizeHtml from \"sanitize-html\";\n\nimport { getContentRes } from \"../adapters/content-adapter\";\nimport { getFrameworkConfig } from \"../config/framework-config\";\nimport type { FormStoreState } from \"../types/form-types\";\nimport type { ColumnType } from \"../types/grid-types\";\nimport { dateManager } from \"./date\";\n\ninterface FormatColumn<T> {\n field: string & keyof T;\n type: ColumnType;\n decimals?: number;\n textField?: string;\n}\n\n/** Strips all HTML tags from content */\nexport function sanitizeContent(content: string): string {\n if (!content) {\n return \"\";\n }\n const clean = sanitizeHtml(content, {\n allowedTags: [],\n allowedAttributes: {},\n });\n return clean;\n}\n\nconst editorAllowedTags = [\n \"p\", \"br\", \"div\", \"ul\", \"ol\", \"li\", \"b\", \"i\", \"em\", \"strong\", \"u\", \"s\",\n \"sub\", \"sup\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"span\", \"a\",\n \"table\", \"thead\", \"tbody\", \"tr\", \"th\", \"td\",\n];\nconst editorAllowedAttributes: sanitizeHtml.IOptions[\"allowedAttributes\"] = {\n a: [\"href\", \"title\", \"target\", \"rel\"],\n td: [\"colspan\", \"rowspan\"],\n th: [\"colspan\", \"rowspan\"],\n span: [\"style\"],\n};\nconst SAFE_TEXT_DECORATION_PATTERN = /^(?!.*(?:url|expression)\\s*\\()[a-z0-9#(),.%\\s-]{1,80}$/i;\nconst SAFE_LINK_TARGETS = new Set([\"_blank\", \"_self\", \"_parent\", \"_top\"]);\n\nfunction normalizeRelTokens(rel: string | undefined): string[] {\n if (!rel) return [];\n const seen = new Set<string>();\n const tokens: string[] = [];\n for (const raw of rel.split(/\\s+/)) {\n const token = raw.trim().toLowerCase();\n if (!token || token === \"opener\" || seen.has(token)) continue;\n seen.add(token);\n tokens.push(token);\n }\n return tokens;\n}\n\nconst editorTransformTags: sanitizeHtml.IOptions[\"transformTags\"] = {\n a: (tagName, attribs) => {\n const nextAttribs: Record<string, string> = { ...attribs };\n\n if (typeof nextAttribs.target === \"string\") {\n const normalizedTarget = nextAttribs.target.trim().toLowerCase();\n if (SAFE_LINK_TARGETS.has(normalizedTarget)) {\n nextAttribs.target = normalizedTarget;\n } else {\n delete nextAttribs.target;\n }\n }\n\n if (nextAttribs.target === \"_blank\") {\n const relTokens = normalizeRelTokens(nextAttribs.rel);\n if (!relTokens.includes(\"noopener\")) relTokens.push(\"noopener\");\n if (!relTokens.includes(\"noreferrer\")) relTokens.push(\"noreferrer\");\n nextAttribs.rel = relTokens.join(\" \");\n }\n\n return { tagName, attribs: nextAttribs };\n },\n};\n\nconst editorAllowedStyles: sanitizeHtml.IOptions[\"allowedStyles\"] = {\n span: {\n \"text-decoration\": [SAFE_TEXT_DECORATION_PATTERN],\n },\n};\n\n/** Sanitizes HTML output from WYSIWYG editor — allows formatting tags, removes scripts */\nexport function sanitizeEditorContent(content: string): string {\n if (!content) {\n return \"\";\n }\n return sanitizeHtml(content, {\n allowedTags: editorAllowedTags,\n allowedAttributes: editorAllowedAttributes,\n allowedStyles: editorAllowedStyles,\n transformTags: editorTransformTags,\n allowedSchemes: [\"http\", \"https\", \"mailto\"],\n });\n}\n\nexport function truncateString(value: string, maxLength: number): string {\n if (value.length <= maxLength) {\n return value;\n } else if (maxLength < 3) {\n return value.slice(0, maxLength);\n } else {\n return value.slice(0, maxLength - 3) + \"...\";\n }\n}\n\nexport function toNumber(value: string | number, decimals?: number): string {\n const locale = getFrameworkConfig().i18n.numberLocale;\n return Number(value).toLocaleString(locale, {\n minimumFractionDigits: decimals ? decimals : 0,\n maximumFractionDigits: decimals ? decimals : 0,\n });\n}\n\nexport function setColumnBodyType<T extends FormStoreState>(item: T, obj: FormatColumn<T>): T[string & keyof T] | string | number | undefined {\n const key = obj.field;\n const rec = item;\n let result: T[string & keyof T] | string | number | undefined = rec[key];\n switch (obj.type) {\n case \"date\":\n result = dateManager.formatDate(rec[key] as Date | null);\n break;\n case \"datetime\":\n result = dateManager.formatDateTime(rec[key] as Date | null);\n break;\n case \"time\":\n result = dateManager.formatTime(rec[key] as Date | null);\n break;\n case \"boolean\":\n result = rec[key] ? getContentRes(\"admin-yes\") : getContentRes(\"admin-no\");\n break;\n case \"number\": {\n const numVal = rec[key] as string | number | undefined;\n result = numVal !== undefined ? (obj.decimals ? toNumber(numVal, obj.decimals) : numVal) : \"\";\n break;\n }\n case \"object\": {\n const objVal = rec[key] as { full_name?: string; name?: string; [k: string]: string | undefined } | null | undefined;\n result = objVal\n ? obj.textField\n ? objVal[obj.textField]\n : objVal.full_name || objVal.name || \"\"\n : \"\";\n break;\n }\n case \"string\":\n case \"color\":\n break;\n default: {\n const _exhaustive: never = obj.type;\n void _exhaustive;\n }\n }\n return result;\n}\n","/**\n * Shared utilities for tree structures (Tree and TreeList).\n * @module tree-utils\n */\n\nimport type { Indexable } from \"../types/form-types\";\n\nexport interface BaseTreeNode {\n id_public: string;\n childrenNodes?: BaseTreeNode[];\n}\n\n/** Safe access to node children — encapsulates dynamic property access + cast */\nexport function getChildren<T>(node: T, field: string): T[] | undefined {\n const val = (node as Indexable)[field];\n return Array.isArray(val) ? (val as T[]) : undefined;\n}\n\nexport function findNode<T extends BaseTreeNode>(\n nodes: T[],\n id: string,\n childrenField: string = \"childrenNodes\"\n): T | null {\n for (const node of nodes) {\n if (node.id_public === id) return node;\n const children = getChildren(node, childrenField);\n if (children && children.length > 0) {\n const found = findNode(children, id, childrenField);\n if (found) return found;\n }\n }\n return null;\n}\n\nexport function getAllIds<T extends BaseTreeNode>(nodes: T[], childrenField: string = \"childrenNodes\"): string[] {\n const ids: string[] = [];\n const collect = (items: T[]) => {\n for (const node of items) {\n ids.push(node.id_public);\n const children = getChildren(node, childrenField);\n if (children && children.length > 0) {\n collect(children);\n }\n }\n };\n collect(nodes);\n return ids;\n}\n\nexport function updateNode<T extends BaseTreeNode>(\n nodes: T[],\n id: string,\n updater: (node: T) => T,\n childrenField: string = \"childrenNodes\"\n): T[] {\n return nodes.map((node) => {\n if (node.id_public === id) {\n return updater(node);\n }\n const children = getChildren(node, childrenField);\n if (children && children.length > 0) {\n return {\n ...node,\n [childrenField]: updateNode(children, id, updater, childrenField),\n };\n }\n return node;\n });\n}\n\nexport function removeNode<T extends BaseTreeNode>(\n nodes: T[],\n id: string,\n childrenField: string = \"childrenNodes\"\n): T[] {\n return nodes\n .filter((node) => node.id_public !== id)\n .map((node) => {\n const children = getChildren(node, childrenField);\n if (children && children.length > 0) {\n return {\n ...node,\n [childrenField]: removeNode(children, id, childrenField),\n };\n }\n return node;\n });\n}\n\nexport function addNode<T extends BaseTreeNode>(\n nodes: T[],\n parentId: string | null,\n newNode: T,\n childrenField: string = \"childrenNodes\"\n): T[] {\n if (parentId === null) {\n return [...nodes, newNode];\n }\n\n return nodes.map((node) => {\n if (node.id_public === parentId) {\n const children = getChildren(node, childrenField) || [];\n return {\n ...node,\n [childrenField]: [...children, newNode],\n };\n }\n const children = getChildren(node, childrenField);\n if (children && children.length > 0) {\n return {\n ...node,\n [childrenField]: addNode(children, parentId, newNode, childrenField),\n };\n }\n return node;\n });\n}\n\nexport function findParentId<T extends BaseTreeNode>(\n nodes: T[],\n id: string,\n childrenField: string = \"childrenNodes\",\n parentId: string | null = null\n): string | null {\n for (const node of nodes) {\n if (node.id_public === id) {\n return parentId;\n }\n const children = getChildren(node, childrenField);\n if (children && children.length > 0) {\n const found = findParentId(children, id, childrenField, node.id_public);\n if (found !== null) return found;\n }\n }\n return null;\n}\n"],"mappings":"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","names":["dayjs","customParseFormat","dayjs","customParseFormat","children"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/validation/field-validators.ts"],"sourcesContent":["import { getContentRes } from \"../adapters/content-adapter\";\n\n/**\n * Validate a phone number string.\n *\n * Accepts:\n * - E.164 format: +1234567890 (7-15 digits after +)\n * - National formats: (123) 456-7890, 123-456-7890, 123.456.7890\n * - International with spaces/dashes: +420 123 456 789\n *\n * Rejects:\n * - Strings with fewer than 7 digits (too short to be valid)\n * - Strings with more than 15 digits (exceeds E.164 max)\n * - Strings that are all non-digit characters\n * - Strings with letters or invalid special characters\n */\nexport function isPhoneNumber(str: string): boolean {\n // Must contain only phone-valid characters: digits, +, (, ), -, ., space, /\n if (!/^[+]?[()/0-9. -]+$/.test(str)) return false;\n\n // Extract just the digits to validate length\n const digits = str.replace(/\\D/g, \"\");\n\n // E.164: min 7 digits, max 15 digits (ITU-T E.164)\n if (digits.length < 7 || digits.length > 15) return false;\n\n // Reject obviously invalid patterns:\n // - Leading + must be followed by digits (not more symbols)\n if (str.startsWith(\"+\") && !/^\\+\\d/.test(str)) return false;\n\n // - Multiple consecutive + signs\n if (/\\+.*\\+/.test(str)) return false;\n\n // - + sign not at the beginning\n if (!str.startsWith(\"+\") && str.includes(\"+\")) return false;\n\n return true;\n}\n\nexport function validatePhoneNumber(value: string, required: boolean = false): string {\n const input = typeof value === \"string\" ? value.trim() : \"\";\n\n if (required && input.length === 0) {\n return getContentRes(\"admin-fill-value\");\n }\n\n if (input.length === 0) {\n return \"\";\n }\n\n if (input.includes(\";\")) {\n const parts = input\n .split(\";\")\n .map((x) => x.trim())\n .filter((x) => x.length > 0);\n\n if (required && parts.length === 0) {\n return getContentRes(\"admin-fill-value\");\n }\n\n for (const part of parts) {\n if (!isPhoneNumber(part)) {\n return getContentRes(\"admin-invalid-phone-number-format\");\n }\n }\n\n return \"\";\n }\n\n if (!isPhoneNumber(input)) {\n return getContentRes(\"admin-invalid-phone-number-format\");\n }\n\n return \"\";\n}\n\n/**\n * Validate an email address string.\n *\n * Improvements over the previous regex:\n * - Supports + tags (user+tag@example.com) — already supported, kept\n * - Supports longer TLDs (.museum, .company, .international)\n * - Requires TLD to be at least 2 characters (rejects user@localhost-like)\n * - Local part: letters, digits, and . _ + - (no leading/trailing/consecutive dots)\n * - Domain: ASCII letters, digits, hyphens, dots (no leading/trailing hyphens per label)\n */\nexport function isEmailAddress(str: string): boolean {\n // Local part: alphanumeric, plus . _ + -\n // No leading/trailing dot, no consecutive dots\n // Domain: labels separated by dots, each label starts/ends with alphanum\n // TLD must be at least 2 chars (letters only)\n return /^[a-zA-Z0-9](?:[a-zA-Z0-9._+-]*[a-zA-Z0-9])?@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,}$/.test(\n str,\n );\n}\n\nexport function isMultipleEmailAddress(str: string): boolean {\n if (str == null) {\n return false;\n }\n const parts = str.split(/[,;\\s]+/).filter((p) => p.includes(\"@\"));\n return parts.length >= 2;\n}\n\nexport function validateEmailAddress(value: string, required: boolean = false): string {\n const input = typeof value === \"string\" ? value.trim() : \"\";\n\n if (required && input.length === 0) {\n return getContentRes(\"admin-fill-value\");\n }\n\n if (input.length === 0) {\n return \"\";\n }\n\n if (input.includes(\";\")) {\n const parts = input\n .split(\";\")\n .map((x) => x.trim())\n .filter((x) => x.length > 0);\n\n if (required && parts.length === 0) {\n return getContentRes(\"admin-fill-value\");\n }\n\n for (const part of parts) {\n if (isMultipleEmailAddress(part)) {\n return getContentRes(\"admin-email-contains-multiple-addresses\");\n }\n if (!isEmailAddress(part)) {\n return getContentRes(\"admin-invalid-email-format\");\n }\n }\n\n return \"\";\n }\n\n if (isMultipleEmailAddress(input)) {\n return getContentRes(\"admin-email-contains-multiple-addresses\");\n }\n if (!isEmailAddress(input)) {\n return getContentRes(\"admin-invalid-email-format\");\n }\n return \"\";\n}\n\nexport function isAbsoluteUrl(str: string): boolean {\n if (!str) return false;\n\n const s = String(str).trim();\n if (!s || /\\s/.test(s)) return false;\n\n try {\n const url = new URL(s);\n const protocolOk = url.protocol === \"http:\" || url.protocol === \"https:\";\n if (!protocolOk) return false;\n if (!url.hostname) return false;\n\n return true;\n } catch {\n return false;\n }\n}\n\nexport function validateAbsoluteUrl(value: string, required: boolean = false): string {\n const input = typeof value === \"string\" ? value.trim() : \"\";\n\n if (required && input.length === 0) {\n return getContentRes(\"admin-fill-value\");\n }\n\n if (input.length === 0) {\n return \"\";\n }\n\n if (!isAbsoluteUrl(input)) {\n return getContentRes(\"admin-invalid-url-format\");\n }\n\n return \"\";\n}\n\n/** Minimum password strength requirements: 8+ characters, uppercase + lowercase + digit + special character */\nexport function validatePasswordStrength(value: string): string {\n if (!value) return getContentRes(\"admin-fill-value\");\n if (value.length < 8) return getContentRes(\"admin-password-min-length\");\n if (!/[A-Z]/.test(value)) return getContentRes(\"admin-password-uppercase\");\n if (!/[a-z]/.test(value)) return getContentRes(\"admin-password-lowercase\");\n if (!/[0-9]/.test(value)) return getContentRes(\"admin-password-digit\");\n if (!/[^A-Za-z0-9]/.test(value)) return getContentRes(\"admin-password-special-char\");\n return \"\";\n}\n"],"mappings":"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","names":[]}
|