@spring-systems/core 0.8.4 → 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/CHANGELOG.md +2 -0
- package/dist/adapters/index.js +1 -56
- package/dist/auth/index.d.ts +2 -2
- 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.d.ts +3 -3
- package/dist/config/index.js +1 -109
- package/dist/devtools/index.d.ts +2 -2
- package/dist/devtools/index.js +1 -67
- package/dist/errors/index.js +1 -21
- package/dist/events/index.js +1 -12
- package/dist/{framework-config-types-ClghA-zo.d.ts → framework-config-types-Cmy83YS6.d.ts} +4 -1
- package/dist/i18n/index.js +1 -7
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -42
- package/dist/instance/index.d.ts +3 -3
- package/dist/instance/index.js +1 -37
- package/dist/logger/index.d.ts +2 -2
- package/dist/logger/index.js +1 -27
- package/dist/middleware/index.js +1 -23
- package/dist/plugins/index.d.ts +2 -2
- package/dist/plugins/index.js +1 -16
- package/dist/{runtime-env-config-Bs9HwewE.d.ts → runtime-env-config-B7vf3XX5.d.ts} +1 -1
- package/dist/{spring-instance-Bijjj8Mq.d.ts → spring-instance-CZk8Ju5T.d.ts} +1 -1
- package/dist/testing/index.d.ts +2 -2
- 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 +1 -1
- package/dist/adapters/index.js.map +0 -1
- package/dist/auth/index.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/chunk-XGNQEGV7.js +0 -391
- package/dist/chunk-XGNQEGV7.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
|
@@ -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":[]}
|