@lichens-innovation/ts-common 1.13.0 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -36,10 +36,12 @@ Table of content
36
36
  - [Web (`@lichens-innovation/ts-common/web`)](#web-lichens-innovationts-commonweb)
37
37
  - [MIME (`@lichens-innovation/ts-common/mime`)](#mime-lichens-innovationts-commonmime)
38
38
  - [Logger (`@lichens-innovation/ts-common/logger`)](#logger-lichens-innovationts-commonlogger)
39
+ - [RJSF (`@lichens-innovation/ts-common/rjsf`)](#rjsf-lichens-innovationts-commonrjsf)
39
40
  - [Contributions](#contributions)
40
41
  - [Unit tests](#unit-tests)
41
42
  - [Library semantic versioning](#library-semantic-versioning)
42
43
  - [Project coding guidelines](#project-coding-guidelines)
44
+ - [TODOs](#todos)
43
45
  - [License](#license)
44
46
 
45
47
  ## Prerequisites
@@ -64,7 +66,7 @@ Table of content
64
66
 
65
67
  ## Optional modules
66
68
 
67
- This library provides optional subpath modules with external dependencies. Install only the dependencies you need. For more information regarding the packaging, see the [following technical explaination](docs/packaging-approach.md).
69
+ This library provides optional subpath modules with external dependencies. Install only the dependencies you need. For more information regarding the packaging, see the [following technical explanation](docs/packaging-approach.md).
68
70
 
69
71
  ### Excel (`@lichens-innovation/ts-common/excel`)
70
72
 
@@ -128,6 +130,33 @@ logger.debug("Debug", { userId: "123", action: "login" });
128
130
  logger.error("Error", { code: 500 });
129
131
  ```
130
132
 
133
+ ### RJSF (`@lichens-innovation/ts-common/rjsf`)
134
+
135
+ Utilities and hooks for [React JSON Schema Form (RJSF)](https://rjsf-team.github.io/react-jsonschema-form/) with i18n (i18next / react-i18next), localized validation (ajv-i18n), and form layout. For React apps using RJSF with translation and validation.
136
+
137
+ **Install the dependencies:**
138
+
139
+ ```bash
140
+ npm install @rjsf/utils @rjsf/validator-ajv8 ajv-i18n i18next react-i18next
141
+ ```
142
+
143
+ **Exports:** `initRjsf`, `useLocalizedForm`, `useRjsfValidator`, `useFormLayoutCols`, `translateRjsfString`, `RJSF_STRING_TO_I18N_KEY`, types (`LocalizedFormSchema`, `MetaFormSchema`, etc.).
144
+
145
+ **Usage example:**
146
+
147
+ ```ts
148
+ import { initRjsf, useLocalizedForm, useRjsfValidator } from "@lichens-innovation/ts-common/rjsf";
149
+
150
+ // After i18next is initialized (e.g. initI18N())
151
+ initRjsf();
152
+
153
+ // In a form component: localized schema from meta schema
154
+ const localizedSchema = useLocalizedForm(metaFormSchema);
155
+
156
+ // Validator with localized AJV messages (e.g. fr, en)
157
+ const validator = useRjsfValidator();
158
+ ```
159
+
131
160
  ## Contributions
132
161
 
133
162
  Contributions to the project are made by simply improving the current codebase and then creating a Pull Request. If the version field in `package.json` is incremented, the build will be automatically triggered when the PR is merged into the `main` branch, and the new version will be published to our enterprise Git repository.
@@ -150,6 +179,11 @@ Adhering to established coding guidelines is essential for developing efficient,
150
179
 
151
180
  * [Coding guidelines](https://github.com/amwebexpert/chrome-extensions-collection/blob/master/packages/coding-guide-helper/public/markdowns/table-of-content.md)
152
181
 
182
+ ## TODOs
183
+
184
+ This section list remaining tasks (not yet completed)
185
+ * RJSF-001: find a way to dynamically resolve the rjsf-i18n.utils "%1 Key" pattern
186
+
153
187
  ## License
154
188
 
155
189
  This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
package/dist/logger.cjs CHANGED
@@ -103,10 +103,12 @@ var pinoLogger = createPinoLogger();
103
103
  var setLoggerMinimumLevel = (level) => {
104
104
  pinoLogger.level = level;
105
105
  };
106
- var consoleMethodToPinoMethod = (level) => {
107
- return (...args) => {
108
- pinoLogger[level](...args);
109
- };
106
+ var consoleMethodToPinoMethod = (level) => (message, payload) => {
107
+ if (isNullish(payload)) {
108
+ pinoLogger[level](message);
109
+ } else {
110
+ pinoLogger[level](payload, message);
111
+ }
110
112
  };
111
113
  var logger = {
112
114
  trace: consoleMethodToPinoMethod("trace"),
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/types.utils.ts","../src/utils/runtime-env.utils.ts","../src/logger/logger.utils.ts"],"names":["pino"],"mappings":"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","file":"logger.cjs","sourcesContent":["export const NO_OP: () => void = () => {};\n\nexport const isNullish = (value: unknown): value is null | undefined => value === null || value === undefined;\n\nexport const isNumber = (value?: unknown | null): value is number => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'number') {\n return false;\n }\n\n if (isNaN(value)) {\n return false;\n }\n\n return true;\n};\n\nexport const isString = (value?: unknown | null): value is string => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'string') {\n return false;\n }\n\n return true;\n};\n","import { isNullish } from \"./types.utils\";\n\n/**\n * Returns true when running in Node.js.\n * Checks for process.versions.node to avoid false positives in Web Workers.\n */\nexport const isRuntimeEnvNodeJs = (): boolean => {\n if (typeof window !== \"undefined\") return false;\n if (typeof process === \"undefined\") return false;\n if (isNullish(process?.versions?.node)) return false;\n\n return true;\n};\n","import pino from \"pino\";\nimport { isRuntimeEnvNodeJs } from \"../utils/runtime-env.utils\";\nimport { isNullish } from \"../utils/types.utils\";\n\nconst LEVEL_LABELS: Record<number, string> = {\n 10: \"trace\",\n 20: \"debug\",\n 30: \"info\",\n 40: \"warn\",\n 50: \"error\",\n 60: \"fatal\",\n};\n\nconst LEVEL_COLORS: Record<string, string> = {\n trace: \"color: #94a3b8\",\n debug: \"color: #22d3ee\",\n info: \"color: #4ade80\",\n warn: \"color: #fbbf24\",\n error: \"color: #f87171\",\n fatal: \"color: #dc2626; font-weight: bold\",\n};\n\nconst MESSAGE_KEY = \"msg\";\n\ntype LogObject = Record<string, unknown> & { level?: number; time?: string; [MESSAGE_KEY]?: string };\n\nconst getLevelLabel = (levelNum: number): string => LEVEL_LABELS[levelNum] ?? \"info\";\n\nconst getLevelColor = (label: string): string => LEVEL_COLORS[label] ?? LEVEL_COLORS.info;\n\nconst getLogTimestamp = ({ time }: LogObject): string => (typeof time === \"string\" ? time : new Date().toISOString());\n\ntype ConsoleMethod = \"log\" | \"warn\" | \"error\";\nconst getConsoleMethod = (levelNum: number): ConsoleMethod => {\n if (levelNum >= 50) return \"error\";\n if (levelNum >= 40) return \"warn\";\n return \"log\";\n};\n\nconst getRestPayload = (obj: LogObject): Record<string, unknown> =>\n Object.keys(obj)\n .filter((k) => k !== \"level\" && k !== \"time\" && k !== MESSAGE_KEY)\n .reduce<Record<string, unknown>>((acc, k) => {\n acc[k] = obj[k];\n return acc;\n }, {});\n\ntype BuildMainArgsParams = {\n timestamp: string;\n label: string;\n color: string;\n msg: unknown;\n extraArgs: unknown[];\n rest: Record<string, unknown>;\n};\n\nconst buildMainArgs = ({ timestamp, label, color, msg, extraArgs, rest }: BuildMainArgsParams): unknown[] => {\n const prefix = `[${timestamp}]`;\n const levelPart = ` ${label.toUpperCase()} `;\n const hasRest = Object.keys(rest).length > 0;\n const mainArgs: unknown[] = [`${prefix}%c${levelPart}%c`, color, \"color: inherit\"];\n\n if (!isNullish(msg)) mainArgs.push(msg);\n if (extraArgs.length > 0) mainArgs.push(...extraArgs);\n if (hasRest) mainArgs.push(rest);\n\n return mainArgs;\n};\n\nconst baseOptions: pino.LoggerOptions = {\n timestamp: pino.stdTimeFunctions.isoTime,\n messageKey: MESSAGE_KEY,\n};\n\nconst browserOptions: pino.LoggerOptions = {\n ...baseOptions,\n browser: {\n write: (logObj: object, ...args: unknown[]) => {\n const obj = logObj as LogObject;\n const levelNum = obj.level ?? 30;\n const label = getLevelLabel(levelNum);\n const color = getLevelColor(label);\n const timestamp = getLogTimestamp(obj);\n const msg = obj[MESSAGE_KEY];\n const rest = getRestPayload(obj);\n const consoleMethod = getConsoleMethod(levelNum);\n const mainArgs = buildMainArgs({\n timestamp,\n label,\n color,\n msg,\n extraArgs: args,\n rest,\n });\n (console[consoleMethod] as (...a: unknown[]) => void)(...mainArgs);\n },\n },\n};\n\nconst createPinoLogger = (): pino.Logger => {\n if (isRuntimeEnvNodeJs()) {\n try {\n const transport = pino.transport({ target: \"pino-pretty\", options: { colorize: true } });\n return pino(baseOptions, transport);\n } catch (e: unknown) {\n console.warn(\"pino-pretty not installed, using default pino output\", e);\n return pino(baseOptions);\n }\n }\n\n return pino(browserOptions);\n};\n\nconst pinoLogger = createPinoLogger();\n\nexport type Level = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"fatal\";\n\nexport const setLoggerMinimumLevel = (level: Level) => {\n pinoLogger.level = level;\n};\n\ntype ConsoleLogMethod = Console[\"log\"];\n\nconst consoleMethodToPinoMethod = (level: Level): ConsoleLogMethod => {\n return (...args: unknown[]) => {\n (pinoLogger[level] as ConsoleLogMethod)(...args);\n };\n};\n\nexport const logger = {\n trace: consoleMethodToPinoMethod(\"trace\"),\n debug: consoleMethodToPinoMethod(\"debug\"),\n info: consoleMethodToPinoMethod(\"info\"),\n warn: consoleMethodToPinoMethod(\"warn\"),\n error: consoleMethodToPinoMethod(\"error\"),\n fatal: consoleMethodToPinoMethod(\"fatal\"),\n log: consoleMethodToPinoMethod(\"info\"),\n};\n"]}
1
+ {"version":3,"sources":["../src/utils/types.utils.ts","../src/utils/runtime-env.utils.ts","../src/logger/logger.utils.ts"],"names":["pino"],"mappings":"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","file":"logger.cjs","sourcesContent":["export const NO_OP: () => void = () => {};\n\nexport const isNullish = (value: unknown): value is null | undefined => value === null || value === undefined;\n\nexport const isNumber = (value?: unknown | null): value is number => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'number') {\n return false;\n }\n\n if (isNaN(value)) {\n return false;\n }\n\n return true;\n};\n\nexport const isString = (value?: unknown | null): value is string => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'string') {\n return false;\n }\n\n return true;\n};\n","import { isNullish } from \"./types.utils\";\n\n/**\n * Returns true when running in Node.js.\n * Checks for process.versions.node to avoid false positives in Web Workers.\n */\nexport const isRuntimeEnvNodeJs = (): boolean => {\n if (typeof window !== \"undefined\") return false;\n if (typeof process === \"undefined\") return false;\n if (isNullish(process?.versions?.node)) return false;\n\n return true;\n};\n","import pino from \"pino\";\nimport { isRuntimeEnvNodeJs } from \"../utils/runtime-env.utils\";\nimport { isNullish } from \"../utils/types.utils\";\n\nconst LEVEL_LABELS: Record<number, string> = {\n 10: \"trace\",\n 20: \"debug\",\n 30: \"info\",\n 40: \"warn\",\n 50: \"error\",\n 60: \"fatal\",\n};\n\nconst LEVEL_COLORS: Record<string, string> = {\n trace: \"color: #94a3b8\",\n debug: \"color: #22d3ee\",\n info: \"color: #4ade80\",\n warn: \"color: #fbbf24\",\n error: \"color: #f87171\",\n fatal: \"color: #dc2626; font-weight: bold\",\n};\n\nconst MESSAGE_KEY = \"msg\";\n\ntype LogObject = Record<string, unknown> & { level?: number; time?: string; [MESSAGE_KEY]?: string };\n\nconst getLevelLabel = (levelNum: number): string => LEVEL_LABELS[levelNum] ?? \"info\";\n\nconst getLevelColor = (label: string): string => LEVEL_COLORS[label] ?? LEVEL_COLORS.info;\n\nconst getLogTimestamp = ({ time }: LogObject): string => (typeof time === \"string\" ? time : new Date().toISOString());\n\ntype ConsoleMethod = \"log\" | \"warn\" | \"error\";\nconst getConsoleMethod = (levelNum: number): ConsoleMethod => {\n if (levelNum >= 50) return \"error\";\n if (levelNum >= 40) return \"warn\";\n return \"log\";\n};\n\nconst getRestPayload = (obj: LogObject): Record<string, unknown> =>\n Object.keys(obj)\n .filter((k) => k !== \"level\" && k !== \"time\" && k !== MESSAGE_KEY)\n .reduce<Record<string, unknown>>((acc, k) => {\n acc[k] = obj[k];\n return acc;\n }, {});\n\ntype BuildMainArgsParams = {\n timestamp: string;\n label: string;\n color: string;\n msg: unknown;\n extraArgs: unknown[];\n rest: Record<string, unknown>;\n};\n\nconst buildMainArgs = ({ timestamp, label, color, msg, extraArgs, rest }: BuildMainArgsParams): unknown[] => {\n const prefix = `[${timestamp}]`;\n const levelPart = ` ${label.toUpperCase()} `;\n const hasRest = Object.keys(rest).length > 0;\n const mainArgs: unknown[] = [`${prefix}%c${levelPart}%c`, color, \"color: inherit\"];\n\n if (!isNullish(msg)) mainArgs.push(msg);\n if (extraArgs.length > 0) mainArgs.push(...extraArgs);\n if (hasRest) mainArgs.push(rest);\n\n return mainArgs;\n};\n\nconst baseOptions: pino.LoggerOptions = {\n timestamp: pino.stdTimeFunctions.isoTime,\n messageKey: MESSAGE_KEY,\n};\n\nconst browserOptions: pino.LoggerOptions = {\n ...baseOptions,\n browser: {\n write: (logObj: object, ...args: unknown[]) => {\n const obj = logObj as LogObject;\n const levelNum = obj.level ?? 30;\n const label = getLevelLabel(levelNum);\n const color = getLevelColor(label);\n const timestamp = getLogTimestamp(obj);\n const msg = obj[MESSAGE_KEY];\n const rest = getRestPayload(obj);\n const consoleMethod = getConsoleMethod(levelNum);\n const mainArgs = buildMainArgs({\n timestamp,\n label,\n color,\n msg,\n extraArgs: args,\n rest,\n });\n (console[consoleMethod] as (...a: unknown[]) => void)(...mainArgs);\n },\n },\n};\n\nconst createPinoLogger = (): pino.Logger => {\n if (isRuntimeEnvNodeJs()) {\n try {\n const transport = pino.transport({ target: \"pino-pretty\", options: { colorize: true } });\n return pino(baseOptions, transport);\n } catch (e: unknown) {\n console.warn(\"pino-pretty not installed, using default pino output\", e);\n return pino(baseOptions);\n }\n }\n\n return pino(browserOptions);\n};\n\nconst pinoLogger = createPinoLogger();\n\nexport type Level = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"fatal\";\n\nexport const setLoggerMinimumLevel = (level: Level) => {\n pinoLogger.level = level;\n};\n\nconst consoleMethodToPinoMethod = (level: Level) => (message: string, payload?: Record<string, unknown>) => {\n if (isNullish(payload)) {\n pinoLogger[level](message);\n } else {\n pinoLogger[level](payload, message);\n }\n};\n\nexport const logger = {\n trace: consoleMethodToPinoMethod(\"trace\"),\n debug: consoleMethodToPinoMethod(\"debug\"),\n info: consoleMethodToPinoMethod(\"info\"),\n warn: consoleMethodToPinoMethod(\"warn\"),\n error: consoleMethodToPinoMethod(\"error\"),\n fatal: consoleMethodToPinoMethod(\"fatal\"),\n log: consoleMethodToPinoMethod(\"info\"),\n};\n"]}
package/dist/logger.d.cts CHANGED
@@ -1,13 +1,13 @@
1
1
  type Level = "trace" | "debug" | "info" | "warn" | "error" | "fatal";
2
2
  declare const setLoggerMinimumLevel: (level: Level) => void;
3
3
  declare const logger: {
4
- trace: (...data: any[]) => void;
5
- debug: (...data: any[]) => void;
6
- info: (...data: any[]) => void;
7
- warn: (...data: any[]) => void;
8
- error: (...data: any[]) => void;
9
- fatal: (...data: any[]) => void;
10
- log: (...data: any[]) => void;
4
+ trace: (message: string, payload?: Record<string, unknown>) => void;
5
+ debug: (message: string, payload?: Record<string, unknown>) => void;
6
+ info: (message: string, payload?: Record<string, unknown>) => void;
7
+ warn: (message: string, payload?: Record<string, unknown>) => void;
8
+ error: (message: string, payload?: Record<string, unknown>) => void;
9
+ fatal: (message: string, payload?: Record<string, unknown>) => void;
10
+ log: (message: string, payload?: Record<string, unknown>) => void;
11
11
  };
12
12
 
13
13
  export { type Level, logger, setLoggerMinimumLevel };
package/dist/logger.d.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  type Level = "trace" | "debug" | "info" | "warn" | "error" | "fatal";
2
2
  declare const setLoggerMinimumLevel: (level: Level) => void;
3
3
  declare const logger: {
4
- trace: (...data: any[]) => void;
5
- debug: (...data: any[]) => void;
6
- info: (...data: any[]) => void;
7
- warn: (...data: any[]) => void;
8
- error: (...data: any[]) => void;
9
- fatal: (...data: any[]) => void;
10
- log: (...data: any[]) => void;
4
+ trace: (message: string, payload?: Record<string, unknown>) => void;
5
+ debug: (message: string, payload?: Record<string, unknown>) => void;
6
+ info: (message: string, payload?: Record<string, unknown>) => void;
7
+ warn: (message: string, payload?: Record<string, unknown>) => void;
8
+ error: (message: string, payload?: Record<string, unknown>) => void;
9
+ fatal: (message: string, payload?: Record<string, unknown>) => void;
10
+ log: (message: string, payload?: Record<string, unknown>) => void;
11
11
  };
12
12
 
13
13
  export { type Level, logger, setLoggerMinimumLevel };
package/dist/logger.js CHANGED
@@ -97,10 +97,12 @@ var pinoLogger = createPinoLogger();
97
97
  var setLoggerMinimumLevel = (level) => {
98
98
  pinoLogger.level = level;
99
99
  };
100
- var consoleMethodToPinoMethod = (level) => {
101
- return (...args) => {
102
- pinoLogger[level](...args);
103
- };
100
+ var consoleMethodToPinoMethod = (level) => (message, payload) => {
101
+ if (isNullish(payload)) {
102
+ pinoLogger[level](message);
103
+ } else {
104
+ pinoLogger[level](payload, message);
105
+ }
104
106
  };
105
107
  var logger = {
106
108
  trace: consoleMethodToPinoMethod("trace"),
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/types.utils.ts","../src/utils/runtime-env.utils.ts","../src/logger/logger.utils.ts"],"names":[],"mappings":"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","file":"logger.js","sourcesContent":["export const NO_OP: () => void = () => {};\n\nexport const isNullish = (value: unknown): value is null | undefined => value === null || value === undefined;\n\nexport const isNumber = (value?: unknown | null): value is number => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'number') {\n return false;\n }\n\n if (isNaN(value)) {\n return false;\n }\n\n return true;\n};\n\nexport const isString = (value?: unknown | null): value is string => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'string') {\n return false;\n }\n\n return true;\n};\n","import { isNullish } from \"./types.utils\";\n\n/**\n * Returns true when running in Node.js.\n * Checks for process.versions.node to avoid false positives in Web Workers.\n */\nexport const isRuntimeEnvNodeJs = (): boolean => {\n if (typeof window !== \"undefined\") return false;\n if (typeof process === \"undefined\") return false;\n if (isNullish(process?.versions?.node)) return false;\n\n return true;\n};\n","import pino from \"pino\";\nimport { isRuntimeEnvNodeJs } from \"../utils/runtime-env.utils\";\nimport { isNullish } from \"../utils/types.utils\";\n\nconst LEVEL_LABELS: Record<number, string> = {\n 10: \"trace\",\n 20: \"debug\",\n 30: \"info\",\n 40: \"warn\",\n 50: \"error\",\n 60: \"fatal\",\n};\n\nconst LEVEL_COLORS: Record<string, string> = {\n trace: \"color: #94a3b8\",\n debug: \"color: #22d3ee\",\n info: \"color: #4ade80\",\n warn: \"color: #fbbf24\",\n error: \"color: #f87171\",\n fatal: \"color: #dc2626; font-weight: bold\",\n};\n\nconst MESSAGE_KEY = \"msg\";\n\ntype LogObject = Record<string, unknown> & { level?: number; time?: string; [MESSAGE_KEY]?: string };\n\nconst getLevelLabel = (levelNum: number): string => LEVEL_LABELS[levelNum] ?? \"info\";\n\nconst getLevelColor = (label: string): string => LEVEL_COLORS[label] ?? LEVEL_COLORS.info;\n\nconst getLogTimestamp = ({ time }: LogObject): string => (typeof time === \"string\" ? time : new Date().toISOString());\n\ntype ConsoleMethod = \"log\" | \"warn\" | \"error\";\nconst getConsoleMethod = (levelNum: number): ConsoleMethod => {\n if (levelNum >= 50) return \"error\";\n if (levelNum >= 40) return \"warn\";\n return \"log\";\n};\n\nconst getRestPayload = (obj: LogObject): Record<string, unknown> =>\n Object.keys(obj)\n .filter((k) => k !== \"level\" && k !== \"time\" && k !== MESSAGE_KEY)\n .reduce<Record<string, unknown>>((acc, k) => {\n acc[k] = obj[k];\n return acc;\n }, {});\n\ntype BuildMainArgsParams = {\n timestamp: string;\n label: string;\n color: string;\n msg: unknown;\n extraArgs: unknown[];\n rest: Record<string, unknown>;\n};\n\nconst buildMainArgs = ({ timestamp, label, color, msg, extraArgs, rest }: BuildMainArgsParams): unknown[] => {\n const prefix = `[${timestamp}]`;\n const levelPart = ` ${label.toUpperCase()} `;\n const hasRest = Object.keys(rest).length > 0;\n const mainArgs: unknown[] = [`${prefix}%c${levelPart}%c`, color, \"color: inherit\"];\n\n if (!isNullish(msg)) mainArgs.push(msg);\n if (extraArgs.length > 0) mainArgs.push(...extraArgs);\n if (hasRest) mainArgs.push(rest);\n\n return mainArgs;\n};\n\nconst baseOptions: pino.LoggerOptions = {\n timestamp: pino.stdTimeFunctions.isoTime,\n messageKey: MESSAGE_KEY,\n};\n\nconst browserOptions: pino.LoggerOptions = {\n ...baseOptions,\n browser: {\n write: (logObj: object, ...args: unknown[]) => {\n const obj = logObj as LogObject;\n const levelNum = obj.level ?? 30;\n const label = getLevelLabel(levelNum);\n const color = getLevelColor(label);\n const timestamp = getLogTimestamp(obj);\n const msg = obj[MESSAGE_KEY];\n const rest = getRestPayload(obj);\n const consoleMethod = getConsoleMethod(levelNum);\n const mainArgs = buildMainArgs({\n timestamp,\n label,\n color,\n msg,\n extraArgs: args,\n rest,\n });\n (console[consoleMethod] as (...a: unknown[]) => void)(...mainArgs);\n },\n },\n};\n\nconst createPinoLogger = (): pino.Logger => {\n if (isRuntimeEnvNodeJs()) {\n try {\n const transport = pino.transport({ target: \"pino-pretty\", options: { colorize: true } });\n return pino(baseOptions, transport);\n } catch (e: unknown) {\n console.warn(\"pino-pretty not installed, using default pino output\", e);\n return pino(baseOptions);\n }\n }\n\n return pino(browserOptions);\n};\n\nconst pinoLogger = createPinoLogger();\n\nexport type Level = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"fatal\";\n\nexport const setLoggerMinimumLevel = (level: Level) => {\n pinoLogger.level = level;\n};\n\ntype ConsoleLogMethod = Console[\"log\"];\n\nconst consoleMethodToPinoMethod = (level: Level): ConsoleLogMethod => {\n return (...args: unknown[]) => {\n (pinoLogger[level] as ConsoleLogMethod)(...args);\n };\n};\n\nexport const logger = {\n trace: consoleMethodToPinoMethod(\"trace\"),\n debug: consoleMethodToPinoMethod(\"debug\"),\n info: consoleMethodToPinoMethod(\"info\"),\n warn: consoleMethodToPinoMethod(\"warn\"),\n error: consoleMethodToPinoMethod(\"error\"),\n fatal: consoleMethodToPinoMethod(\"fatal\"),\n log: consoleMethodToPinoMethod(\"info\"),\n};\n"]}
1
+ {"version":3,"sources":["../src/utils/types.utils.ts","../src/utils/runtime-env.utils.ts","../src/logger/logger.utils.ts"],"names":[],"mappings":"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","file":"logger.js","sourcesContent":["export const NO_OP: () => void = () => {};\n\nexport const isNullish = (value: unknown): value is null | undefined => value === null || value === undefined;\n\nexport const isNumber = (value?: unknown | null): value is number => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'number') {\n return false;\n }\n\n if (isNaN(value)) {\n return false;\n }\n\n return true;\n};\n\nexport const isString = (value?: unknown | null): value is string => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'string') {\n return false;\n }\n\n return true;\n};\n","import { isNullish } from \"./types.utils\";\n\n/**\n * Returns true when running in Node.js.\n * Checks for process.versions.node to avoid false positives in Web Workers.\n */\nexport const isRuntimeEnvNodeJs = (): boolean => {\n if (typeof window !== \"undefined\") return false;\n if (typeof process === \"undefined\") return false;\n if (isNullish(process?.versions?.node)) return false;\n\n return true;\n};\n","import pino from \"pino\";\nimport { isRuntimeEnvNodeJs } from \"../utils/runtime-env.utils\";\nimport { isNullish } from \"../utils/types.utils\";\n\nconst LEVEL_LABELS: Record<number, string> = {\n 10: \"trace\",\n 20: \"debug\",\n 30: \"info\",\n 40: \"warn\",\n 50: \"error\",\n 60: \"fatal\",\n};\n\nconst LEVEL_COLORS: Record<string, string> = {\n trace: \"color: #94a3b8\",\n debug: \"color: #22d3ee\",\n info: \"color: #4ade80\",\n warn: \"color: #fbbf24\",\n error: \"color: #f87171\",\n fatal: \"color: #dc2626; font-weight: bold\",\n};\n\nconst MESSAGE_KEY = \"msg\";\n\ntype LogObject = Record<string, unknown> & { level?: number; time?: string; [MESSAGE_KEY]?: string };\n\nconst getLevelLabel = (levelNum: number): string => LEVEL_LABELS[levelNum] ?? \"info\";\n\nconst getLevelColor = (label: string): string => LEVEL_COLORS[label] ?? LEVEL_COLORS.info;\n\nconst getLogTimestamp = ({ time }: LogObject): string => (typeof time === \"string\" ? time : new Date().toISOString());\n\ntype ConsoleMethod = \"log\" | \"warn\" | \"error\";\nconst getConsoleMethod = (levelNum: number): ConsoleMethod => {\n if (levelNum >= 50) return \"error\";\n if (levelNum >= 40) return \"warn\";\n return \"log\";\n};\n\nconst getRestPayload = (obj: LogObject): Record<string, unknown> =>\n Object.keys(obj)\n .filter((k) => k !== \"level\" && k !== \"time\" && k !== MESSAGE_KEY)\n .reduce<Record<string, unknown>>((acc, k) => {\n acc[k] = obj[k];\n return acc;\n }, {});\n\ntype BuildMainArgsParams = {\n timestamp: string;\n label: string;\n color: string;\n msg: unknown;\n extraArgs: unknown[];\n rest: Record<string, unknown>;\n};\n\nconst buildMainArgs = ({ timestamp, label, color, msg, extraArgs, rest }: BuildMainArgsParams): unknown[] => {\n const prefix = `[${timestamp}]`;\n const levelPart = ` ${label.toUpperCase()} `;\n const hasRest = Object.keys(rest).length > 0;\n const mainArgs: unknown[] = [`${prefix}%c${levelPart}%c`, color, \"color: inherit\"];\n\n if (!isNullish(msg)) mainArgs.push(msg);\n if (extraArgs.length > 0) mainArgs.push(...extraArgs);\n if (hasRest) mainArgs.push(rest);\n\n return mainArgs;\n};\n\nconst baseOptions: pino.LoggerOptions = {\n timestamp: pino.stdTimeFunctions.isoTime,\n messageKey: MESSAGE_KEY,\n};\n\nconst browserOptions: pino.LoggerOptions = {\n ...baseOptions,\n browser: {\n write: (logObj: object, ...args: unknown[]) => {\n const obj = logObj as LogObject;\n const levelNum = obj.level ?? 30;\n const label = getLevelLabel(levelNum);\n const color = getLevelColor(label);\n const timestamp = getLogTimestamp(obj);\n const msg = obj[MESSAGE_KEY];\n const rest = getRestPayload(obj);\n const consoleMethod = getConsoleMethod(levelNum);\n const mainArgs = buildMainArgs({\n timestamp,\n label,\n color,\n msg,\n extraArgs: args,\n rest,\n });\n (console[consoleMethod] as (...a: unknown[]) => void)(...mainArgs);\n },\n },\n};\n\nconst createPinoLogger = (): pino.Logger => {\n if (isRuntimeEnvNodeJs()) {\n try {\n const transport = pino.transport({ target: \"pino-pretty\", options: { colorize: true } });\n return pino(baseOptions, transport);\n } catch (e: unknown) {\n console.warn(\"pino-pretty not installed, using default pino output\", e);\n return pino(baseOptions);\n }\n }\n\n return pino(browserOptions);\n};\n\nconst pinoLogger = createPinoLogger();\n\nexport type Level = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"fatal\";\n\nexport const setLoggerMinimumLevel = (level: Level) => {\n pinoLogger.level = level;\n};\n\nconst consoleMethodToPinoMethod = (level: Level) => (message: string, payload?: Record<string, unknown>) => {\n if (isNullish(payload)) {\n pinoLogger[level](message);\n } else {\n pinoLogger[level](payload, message);\n }\n};\n\nexport const logger = {\n trace: consoleMethodToPinoMethod(\"trace\"),\n debug: consoleMethodToPinoMethod(\"debug\"),\n info: consoleMethodToPinoMethod(\"info\"),\n warn: consoleMethodToPinoMethod(\"warn\"),\n error: consoleMethodToPinoMethod(\"error\"),\n fatal: consoleMethodToPinoMethod(\"fatal\"),\n log: consoleMethodToPinoMethod(\"info\"),\n};\n"]}
package/dist/rjsf.cjs ADDED
@@ -0,0 +1,216 @@
1
+ 'use strict';
2
+
3
+ var i18next = require('i18next');
4
+ var utils = require('@rjsf/utils');
5
+ var reactI18next = require('react-i18next');
6
+ var validatorAjv8 = require('@rjsf/validator-ajv8');
7
+ var localizer = require('ajv-i18n');
8
+
9
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
+
11
+ var i18next__default = /*#__PURE__*/_interopDefault(i18next);
12
+ var localizer__default = /*#__PURE__*/_interopDefault(localizer);
13
+
14
+ // src/rjsf/i18n/i18n.ts
15
+
16
+ // src/rjsf/i18n/en/rjsf.json
17
+ var rjsf_default = {
18
+ rjsf: {
19
+ add: "Add",
20
+ debugFormDataTitle: "JSON data",
21
+ addItem: "Add Item",
22
+ clear: "Clear",
23
+ errors: "Errors detected in the form",
24
+ copy: "Copy",
25
+ keyLabel: "%1 Key",
26
+ moveDown: "Move down",
27
+ moveUp: "Move up",
28
+ no: "No",
29
+ remove: "Remove",
30
+ submit: "Submit",
31
+ yes: "Yes"
32
+ }
33
+ };
34
+
35
+ // src/rjsf/i18n/fr/rjsf.json
36
+ var rjsf_default2 = {
37
+ rjsf: {
38
+ add: "Ajouter",
39
+ debugFormDataTitle: "Donn\xE9es JSON",
40
+ addItem: "Ajouter un \xE9l\xE9ment",
41
+ clear: "Effacer",
42
+ errors: "Erreurs d\xE9tect\xE9es dans le formulaire",
43
+ copy: "Copier",
44
+ keyLabel: "Cl\xE9 %1",
45
+ moveDown: "D\xE9placer vers le bas",
46
+ moveUp: "D\xE9placer vers le haut",
47
+ no: "Non",
48
+ remove: "Supprimer",
49
+ submit: "Envoyer",
50
+ yes: "Oui"
51
+ }
52
+ };
53
+
54
+ // src/rjsf/i18n/i18n.ts
55
+ var NAMESPACE = "rjsf";
56
+ var initRjsf = () => {
57
+ if (!i18next__default.default.isInitialized) {
58
+ throw new Error("[initRjsf] i18next must be initialized before calling initRjsf. Call initI18N() or i18next.init() first.");
59
+ }
60
+ if (i18next__default.default.hasResourceBundle("en", NAMESPACE)) return;
61
+ const isDeep = true;
62
+ const isOverwrite = true;
63
+ i18next__default.default.addResourceBundle("en", NAMESPACE, rjsf_default.rjsf, isDeep, isOverwrite);
64
+ i18next__default.default.addResourceBundle("fr", NAMESPACE, rjsf_default2.rjsf, isDeep, isOverwrite);
65
+ console.info("[initRjsf] RJSF i18n initialized");
66
+ };
67
+
68
+ // src/utils/types.utils.ts
69
+ var isNullish = (value) => value === null || value === void 0;
70
+
71
+ // src/utils/string.utils.ts
72
+ var isBlank = (str) => {
73
+ return isNullish(str) || str?.trim() === "";
74
+ };
75
+
76
+ // src/rjsf/utils/rjsf-i18n.utils.ts
77
+ var RJSF_STRING_TO_I18N_KEY = {
78
+ "Add Item": "rjsf:addItem",
79
+ Add: "rjsf:add",
80
+ Copy: "rjsf:copy",
81
+ "Move down": "rjsf:moveDown",
82
+ "Move up": "rjsf:moveUp",
83
+ Remove: "rjsf:remove",
84
+ "clear input": "rjsf:clear",
85
+ "%1 Key": "rjsf:keyLabel",
86
+ // TODO: RJSF-001 find a way to dynamicaly resolve the rjsf-i18n.utils "%1 Key" pattern
87
+ Yes: "rjsf:yes",
88
+ No: "rjsf:no",
89
+ Errors: "rjsf:errors"
90
+ };
91
+ var translateRjsfString = ({ stringToTranslate, params }) => {
92
+ const i18nKey = RJSF_STRING_TO_I18N_KEY[stringToTranslate];
93
+ if (isBlank(i18nKey)) {
94
+ console.warn(`[translateRjsfString] RJSF i18n: missing key: "${stringToTranslate}"`);
95
+ }
96
+ const translated = i18nKey ? i18next__default.default.t(i18nKey) : stringToTranslate;
97
+ return utils.replaceStringParameters(translated, params);
98
+ };
99
+
100
+ // src/rjsf/utils/rjsf-widgets.utils.ts
101
+ var hasRjsfErrors = (rawErrors) => Array.isArray(rawErrors) && rawErrors.length > 0;
102
+ var getRjsfDisplayLabel = ({ label, required, hideLabel }) => {
103
+ if (hideLabel) return void 0;
104
+ if (isBlank(label)) return void 0;
105
+ const requiredSuffix = required ? " *" : "";
106
+ return `${label}${requiredSuffix}`;
107
+ };
108
+ var toEnumOptionDisplay = (o) => ({
109
+ label: o?.label ?? String(o?.value ?? ""),
110
+ value: String(o?.value ?? "")
111
+ });
112
+ var mapEnumOptions = (options) => {
113
+ const enumOptions = options?.enumOptions;
114
+ if (!Array.isArray(enumOptions)) return [];
115
+ return enumOptions.map(toEnumOptionDisplay);
116
+ };
117
+ var toStringOrEmpty = (value) => isNullish(value) ? "" : String(value);
118
+ var toStringOrUndefined = (value) => isNullish(value) ? void 0 : String(value);
119
+ var getRjsfTextChangeValue = ({ text, emptyValue }) => {
120
+ if (text === "") return emptyValue;
121
+ return text;
122
+ };
123
+ var parseDateOrNull = (value) => {
124
+ if (isBlank(value)) return null;
125
+ const date = new Date(value);
126
+ const isValid = !Number.isNaN(date.getTime());
127
+ return isValid ? date : null;
128
+ };
129
+ var dateToDateOnlyString = (date) => {
130
+ const y = date.getFullYear();
131
+ const m = String(date.getMonth() + 1).padStart(2, "0");
132
+ const d = String(date.getDate()).padStart(2, "0");
133
+ return `${y}-${m}-${d}`;
134
+ };
135
+ var DATE_ONLY_REGEX = /^\d{4}-\d{2}-\d{2}$/;
136
+ var parseDateOnlyToLocalDate = (value) => {
137
+ if (isBlank(value)) return null;
138
+ const trimmed = String(value).trim();
139
+ const dateOnly = trimmed.slice(0, 10);
140
+ if (!DATE_ONLY_REGEX.test(dateOnly)) return null;
141
+ const [y, m, d] = dateOnly.split("-").map(Number);
142
+ return new Date(y, m - 1, d);
143
+ };
144
+ var formatDateOnlyForDisplay = (value) => {
145
+ if (isBlank(value)) return "";
146
+ const trimmed = String(value).trim();
147
+ const dateOnly = trimmed.slice(0, 10);
148
+ return DATE_ONLY_REGEX.test(dateOnly) ? dateOnly : "";
149
+ };
150
+ var formatDateTimeForDisplay = (value) => {
151
+ const date = parseDateOrNull(value);
152
+ return date ? date.toLocaleString() : "";
153
+ };
154
+ var DEFAULT_SPAN = 24;
155
+ var getFormLayoutCols = (formContext) => {
156
+ if (isNullish(formContext)) {
157
+ return {
158
+ labelCol: { span: DEFAULT_SPAN },
159
+ wrapperCol: { span: DEFAULT_SPAN }
160
+ };
161
+ }
162
+ const { labelCol, wrapperCol } = formContext;
163
+ return {
164
+ labelCol: labelCol ?? { span: DEFAULT_SPAN },
165
+ wrapperCol: wrapperCol ?? { span: DEFAULT_SPAN }
166
+ };
167
+ };
168
+ var DEFAULT_LANGUAGE = "fr";
169
+ var parseSimplifiedLangCode = (language) => {
170
+ if (isBlank(language)) return DEFAULT_LANGUAGE;
171
+ return language.split("-")[0];
172
+ };
173
+ var getFallbackLanguage = (metaFormSchema) => {
174
+ return Object.keys(metaFormSchema.i18n)[0] ?? DEFAULT_LANGUAGE;
175
+ };
176
+ var useLocalizedForm = (metaFormSchema) => {
177
+ const { i18n } = reactI18next.useTranslation();
178
+ const language = parseSimplifiedLangCode(i18n.language);
179
+ if (metaFormSchema.i18n[language]) {
180
+ return metaFormSchema.i18n[language];
181
+ }
182
+ const fallbackLanguage = getFallbackLanguage(metaFormSchema);
183
+ console.warn(
184
+ `Language ${language} not found in metaFormSchema ${metaFormSchema.id}. Falling back to ${fallbackLanguage}.`
185
+ );
186
+ return metaFormSchema.i18n[fallbackLanguage];
187
+ };
188
+ var customFormats = {
189
+ "phone-america": /^\(?\d{3}\)?[\s-]?\d{3}[\s-]?\d{4}$/
190
+ };
191
+ var useRjsfValidator = () => {
192
+ const { i18n } = reactI18next.useTranslation();
193
+ const appLanguage = i18n.language;
194
+ const localizerFn = localizer__default.default[appLanguage] ?? localizer__default.default.en;
195
+ return validatorAjv8.customizeValidator({ customFormats }, localizerFn);
196
+ };
197
+
198
+ exports.RJSF_STRING_TO_I18N_KEY = RJSF_STRING_TO_I18N_KEY;
199
+ exports.dateToDateOnlyString = dateToDateOnlyString;
200
+ exports.formatDateOnlyForDisplay = formatDateOnlyForDisplay;
201
+ exports.formatDateTimeForDisplay = formatDateTimeForDisplay;
202
+ exports.getFormLayoutCols = getFormLayoutCols;
203
+ exports.getRjsfDisplayLabel = getRjsfDisplayLabel;
204
+ exports.getRjsfTextChangeValue = getRjsfTextChangeValue;
205
+ exports.hasRjsfErrors = hasRjsfErrors;
206
+ exports.initRjsf = initRjsf;
207
+ exports.mapEnumOptions = mapEnumOptions;
208
+ exports.parseDateOnlyToLocalDate = parseDateOnlyToLocalDate;
209
+ exports.parseDateOrNull = parseDateOrNull;
210
+ exports.toStringOrEmpty = toStringOrEmpty;
211
+ exports.toStringOrUndefined = toStringOrUndefined;
212
+ exports.translateRjsfString = translateRjsfString;
213
+ exports.useLocalizedForm = useLocalizedForm;
214
+ exports.useRjsfValidator = useRjsfValidator;
215
+ //# sourceMappingURL=rjsf.cjs.map
216
+ //# sourceMappingURL=rjsf.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/rjsf/i18n/en/rjsf.json","../src/rjsf/i18n/fr/rjsf.json","../src/rjsf/i18n/i18n.ts","../src/utils/types.utils.ts","../src/utils/string.utils.ts","../src/rjsf/utils/rjsf-i18n.utils.ts","../src/rjsf/utils/rjsf-widgets.utils.ts","../src/rjsf/utils/use-localized-form.ts","../src/rjsf/utils/use-rjsf-validator.ts"],"names":["rjsf_default","i18next","replaceStringParameters","useTranslation","localizer","customizeValidator"],"mappings":"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","file":"rjsf.cjs","sourcesContent":["{\n \"rjsf\": {\n \"add\": \"Add\",\n \"debugFormDataTitle\": \"JSON data\",\n \"addItem\": \"Add Item\",\n \"clear\": \"Clear\",\n \"errors\": \"Errors detected in the form\",\n \"copy\": \"Copy\",\n \"keyLabel\": \"%1 Key\",\n \"moveDown\": \"Move down\",\n \"moveUp\": \"Move up\",\n \"no\": \"No\",\n \"remove\": \"Remove\",\n \"submit\": \"Submit\",\n \"yes\": \"Yes\"\n }\n}\n","{\n \"rjsf\": {\n \"add\": \"Ajouter\",\n \"debugFormDataTitle\": \"Données JSON\",\n \"addItem\": \"Ajouter un élément\",\n \"clear\": \"Effacer\",\n \"errors\": \"Erreurs détectées dans le formulaire\",\n \"copy\": \"Copier\",\n \"keyLabel\": \"Clé %1\",\n \"moveDown\": \"Déplacer vers le bas\",\n \"moveUp\": \"Déplacer vers le haut\",\n \"no\": \"Non\",\n \"remove\": \"Supprimer\",\n \"submit\": \"Envoyer\",\n \"yes\": \"Oui\"\n }\n}\n","import i18next from \"i18next\";\n\nimport en from \"./en/rjsf.json\";\nimport fr from \"./fr/rjsf.json\";\n\nconst NAMESPACE = \"rjsf\";\n\nexport const initRjsf = (): void => {\n if (!i18next.isInitialized) {\n throw new Error(\"[initRjsf] i18next must be initialized before calling initRjsf. Call initI18N() or i18next.init() first.\");\n }\n\n if (i18next.hasResourceBundle(\"en\", NAMESPACE)) return;\n\n const isDeep = true;\n const isOverwrite = true;\n\n i18next.addResourceBundle(\"en\", NAMESPACE, en.rjsf, isDeep, isOverwrite);\n i18next.addResourceBundle(\"fr\", NAMESPACE, fr.rjsf, isDeep, isOverwrite);\n\n // eslint-disable-next-line no-console\n console.info('[initRjsf] RJSF i18n initialized'); \n};\n","export const NO_OP: () => void = () => {};\n\nexport const isNullish = (value: unknown): value is null | undefined => value === null || value === undefined;\n\nexport const isNumber = (value?: unknown | null): value is number => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'number') {\n return false;\n }\n\n if (isNaN(value)) {\n return false;\n }\n\n return true;\n};\n\nexport const isString = (value?: unknown | null): value is string => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'string') {\n return false;\n }\n\n return true;\n};\n","import { REGEX_ALPHANUMERIC } from './regex';\nimport { isNullish } from './types.utils';\n\nexport const isBlank = (str?: string | null): str is null | undefined | '' => {\n return isNullish(str) || str?.trim() === '';\n};\n\nexport const isNotBlank = (str?: string | null): str is string => {\n return !isBlank(str);\n};\n\nexport const isAlphanumeric = (value: string): boolean => {\n return REGEX_ALPHANUMERIC.test(value);\n};\n\n/**\n * Removes diacritical marks (e.g., accents, umlauts) from a string.\n * This method normalizes the input string to its canonical decomposition\n * form (NFD) and removes any combining diacritical marks.\n *\n * @param {string} value - The input string to normalize.\n * @returns {string} - The normalized string with diacritical marks removed.\n *\n * @example\n * const result = removeDiacriticalMarks(\"Ça va très bien, n'est-ce pas?\");\n * console.log(result); // \"Ca va tres bien, n'est-ce pas?\"\n */\nexport const removeDiacriticalMarks = (value: string): string => {\n if (!value) {\n return '';\n }\n\n return value.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '');\n};\n\n/**\n * Capitalize the first letter of a string.\n * @param str - The input string\n * @returns The string with the first character uppercased\n */\nexport const capitalizeFirst = (str: string): string => {\n if (!str) return str;\n return str.charAt(0).toUpperCase() + str.slice(1);\n};\n\n/**\n * Count the number of words in a text string.\n * Words are separated by whitespace.\n * @param text - The text to count words in\n * @returns The number of words found\n */\nexport const countWords = (text: string): number => {\n if (!text || text.trim().length === 0) return 0;\n return text.split(/\\s+/).filter((word) => word.length > 0).length;\n};\n\n/**\n * Truncate a string to a maximum length, adding an ellipsis if truncated.\n * @param str - The string to truncate\n * @param maxLength - Maximum length before truncation\n * @param ellipsis - The ellipsis string to append (default: \"...\")\n * @returns The truncated string\n */\nexport const truncate = (str: string, maxLength: number, ellipsis = \"...\"): string => {\n if (!str || str.length <= maxLength) return str;\n return str.slice(0, maxLength - ellipsis.length) + ellipsis;\n};\n\n/**\n * Parses an optional comma-separated string into a trimmed, non-blank string array.\n */\nexport const parseCommaSeparatedList = (raw?: string | null): string[] => {\n if (isBlank(raw)) {\n return [];\n }\n\n return raw\n .split(\",\")\n .map((s: string) => s.trim())\n .filter(isNotBlank);\n};\n","import { replaceStringParameters } from \"@rjsf/utils\";\nimport i18next from \"i18next\";\nimport { isBlank } from \"~/utils/string.utils\";\n\n/** Maps RJSF TranslatableString values to our i18n keys (rjsf namespace). */\nexport const RJSF_STRING_TO_I18N_KEY: Record<string, string> = {\n \"Add Item\": \"rjsf:addItem\",\n Add: \"rjsf:add\",\n Copy: \"rjsf:copy\",\n \"Move down\": \"rjsf:moveDown\",\n \"Move up\": \"rjsf:moveUp\",\n Remove: \"rjsf:remove\",\n \"clear input\": \"rjsf:clear\",\n \"%1 Key\": \"rjsf:keyLabel\", // TODO: RJSF-001 find a way to dynamicaly resolve the rjsf-i18n.utils \"%1 Key\" pattern\n Yes: \"rjsf:yes\",\n No: \"rjsf:no\",\n Errors: \"rjsf:errors\",\n};\n\ninterface TranslateStringArgs {\n stringToTranslate: string;\n params?: string[];\n}\n\nexport const translateRjsfString = ({ stringToTranslate, params }: TranslateStringArgs): string => {\n const i18nKey = RJSF_STRING_TO_I18N_KEY[stringToTranslate];\n if (isBlank(i18nKey)) {\n // eslint-disable-next-line no-console\n console.warn(`[translateRjsfString] RJSF i18n: missing key: \"${stringToTranslate}\"`);\n }\n\n const translated = i18nKey ? i18next.t(i18nKey) : stringToTranslate;\n return replaceStringParameters(translated, params);\n};\n","import type { WidgetProps } from \"@rjsf/utils\";\nimport { isBlank } from \"~/utils/string.utils\";\nimport { isNullish } from \"~/utils/types.utils\";\n\n/**\n * Returns true when the widget has at least one validation error from RJSF.\n *\n * @param rawErrors - The rawErrors from WidgetProps (often `unknown`).\n * @returns true if rawErrors is a non-empty array.\n */\nexport const hasRjsfErrors = (rawErrors: unknown): boolean => Array.isArray(rawErrors) && rawErrors.length > 0;\n\nexport interface GetRjsfDisplayLabelArgs {\n label?: string;\n required?: boolean;\n hideLabel?: boolean;\n}\n\n/**\n * Returns the label to display for an RJSF widget, with optional required asterisk and\n * hideLabel support.\n *\n * @param label - The label to display for the widget.\n * @param required - Whether the field is required.\n * @param hideLabel - Whether to hide the label.\n *\n * @returns The label to display for the widget.\n */\nexport const getRjsfDisplayLabel = ({ label, required, hideLabel }: GetRjsfDisplayLabelArgs): string | undefined => {\n if (hideLabel) return undefined;\n if (isBlank(label)) return undefined;\n\n const requiredSuffix = required ? \" *\" : \"\";\n return `${label}${requiredSuffix}`;\n};\n\ninterface EnumOption {\n value: string;\n label: string;\n}\n\nexport type EnumOptionDisplay = { label: string; value: string };\n\nconst toEnumOptionDisplay = (o: EnumOption): EnumOptionDisplay => ({\n label: o?.label ?? String(o?.value ?? \"\"),\n value: String(o?.value ?? \"\"),\n});\n\nexport const mapEnumOptions = (options: WidgetProps[\"options\"]): EnumOptionDisplay[] => {\n const enumOptions = options?.enumOptions as EnumOption[] | undefined;\n if (!Array.isArray(enumOptions)) return [];\n return enumOptions.map(toEnumOptionDisplay);\n};\n\n/**\n * Converts a value to display string, or empty string when null/undefined.\n */\nexport const toStringOrEmpty = (value: unknown): string => (isNullish(value) ? \"\" : String(value));\n\n/**\n * Converts a value to display string, or undefined when null/undefined (e.g. for select placeholder).\n */\nexport const toStringOrUndefined = (value: unknown): string | undefined =>\n isNullish(value) ? undefined : String(value);\n\nexport interface GetRjsfTextChangeValueArgs {\n text: string;\n emptyValue?: unknown;\n}\n\n/**\n * Returns the value to pass to onChange for a text input.\n *\n * @param args.text - The current text input value.\n * @param args.emptyValue - The value to use when text is empty (e.g. options.emptyValue from WidgetProps).\n * @returns emptyValue when text is empty, otherwise text.\n */\nexport const getRjsfTextChangeValue = ({ text, emptyValue }: GetRjsfTextChangeValueArgs): unknown => {\n if (text === \"\") return emptyValue;\n return text;\n};\n\nexport const parseDateOrNull = (value?: string): Date | null => {\n if (isBlank(value)) return null;\n\n const date = new Date(value);\n const isValid = !Number.isNaN(date.getTime());\n return isValid ? date : null;\n};\n\n/** Returns YYYY-MM-DD for JSON Schema \"date\" format (form storage). */\nexport const dateToDateOnlyString = (date: Date): string => {\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, \"0\");\n const d = String(date.getDate()).padStart(2, \"0\");\n return `${y}-${m}-${d}`;\n};\n\nconst DATE_ONLY_REGEX = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/** Parses a date-only or full ISO string into a Date at local midnight (for date picker display). */\nexport const parseDateOnlyToLocalDate = (value?: string): Date | null => {\n if (isBlank(value)) return null;\n\n const trimmed = String(value).trim();\n const dateOnly = trimmed.slice(0, 10);\n if (!DATE_ONLY_REGEX.test(dateOnly)) return null;\n\n const [y, m, d] = dateOnly.split(\"-\").map(Number);\n return new Date(y, m - 1, d);\n};\n\n/** Extracts date-only YYYY-MM-DD for display from a full ISO or date-only string. */\nexport const formatDateOnlyForDisplay = (value?: string): string => {\n if (isBlank(value)) return \"\";\n\n const trimmed = String(value).trim();\n const dateOnly = trimmed.slice(0, 10);\n return DATE_ONLY_REGEX.test(dateOnly) ? dateOnly : \"\";\n};\n\n/** Formats a full ISO or date string for date-time display (locale string). */\nexport const formatDateTimeForDisplay = (value?: string): string => {\n const date = parseDateOrNull(value);\n return date ? date.toLocaleString() : \"\";\n};\n\ntype FormLayoutContext = {\n labelCol?: { span: number };\n wrapperCol?: { span: number };\n};\n\nconst DEFAULT_SPAN = 24;\n\nexport const getFormLayoutCols = (formContext?: unknown): FormLayoutContext => {\n if (isNullish(formContext)) {\n return {\n labelCol: { span: DEFAULT_SPAN },\n wrapperCol: { span: DEFAULT_SPAN },\n };\n }\n\n const { labelCol, wrapperCol } = formContext as FormLayoutContext;\n return {\n labelCol: labelCol ?? { span: DEFAULT_SPAN },\n wrapperCol: wrapperCol ?? { span: DEFAULT_SPAN },\n };\n};\n","import { isBlank } from \"~/utils/string.utils\";\nimport { useTranslation } from \"react-i18next\";\nimport type { LocalizedFormSchema, MetaFormSchema } from \"./rjsf-i18n-types\";\n\nconst DEFAULT_LANGUAGE = \"fr\";\n\n// i18n.language can be 'fr-CA', so we take the first part\nconst parseSimplifiedLangCode = (language?: string): string => {\n if (isBlank(language)) return DEFAULT_LANGUAGE;\n return language.split(\"-\")[0];\n};\n\nconst getFallbackLanguage = (metaFormSchema: MetaFormSchema): string => {\n return Object.keys(metaFormSchema.i18n)[0] ?? DEFAULT_LANGUAGE;\n};\n\nexport const useLocalizedForm = (metaFormSchema: MetaFormSchema): LocalizedFormSchema => {\n const { i18n } = useTranslation();\n const language = parseSimplifiedLangCode(i18n.language);\n\n if (metaFormSchema.i18n[language]) {\n return metaFormSchema.i18n[language];\n }\n\n const fallbackLanguage = getFallbackLanguage(metaFormSchema);\n // eslint-disable-next-line no-console\n console.warn(\n `Language ${language} not found in metaFormSchema ${metaFormSchema.id}. Falling back to ${fallbackLanguage}.`\n );\n\n return metaFormSchema.i18n[fallbackLanguage];\n};\n","import { customizeValidator, type Localizer } from \"@rjsf/validator-ajv8\";\nimport localizer from \"ajv-i18n\";\nimport { useTranslation } from \"react-i18next\";\n\nconst customFormats = {\n \"phone-america\": /^\\(?\\d{3}\\)?[\\s-]?\\d{3}[\\s-]?\\d{4}$/,\n};\n\ntype ValidationLanguages = keyof typeof localizer;\n\nexport const useRjsfValidator = () => {\n const { i18n } = useTranslation();\n const appLanguage = i18n.language as ValidationLanguages;\n const localizerFn: Localizer = localizer[appLanguage] ?? localizer.en;\n\n return customizeValidator({ customFormats }, localizerFn);\n};\n"]}
@@ -0,0 +1,101 @@
1
+ import * as _rjsf_utils from '@rjsf/utils';
2
+ import { TranslatableString, RJSFSchema, UiSchema, WidgetProps } from '@rjsf/utils';
3
+ import * as _rjsf_validator_ajv8_lib_validator_js from '@rjsf/validator-ajv8/lib/validator.js';
4
+
5
+ declare const initRjsf: () => void;
6
+
7
+ type Language = string;
8
+ /** Registry shape with translation used by RJSF template buttons. */
9
+ type RjsfRegistryWithTranslate = {
10
+ translateString: (s: TranslatableString) => string;
11
+ };
12
+ interface LocalizedFormSchema {
13
+ schema: RJSFSchema;
14
+ uiSchema: UiSchema;
15
+ }
16
+ interface MetaFormSchema {
17
+ id: string;
18
+ version: string;
19
+ i18n: Record<Language, LocalizedFormSchema>;
20
+ }
21
+
22
+ /** Maps RJSF TranslatableString values to our i18n keys (rjsf namespace). */
23
+ declare const RJSF_STRING_TO_I18N_KEY: Record<string, string>;
24
+ interface TranslateStringArgs {
25
+ stringToTranslate: string;
26
+ params?: string[];
27
+ }
28
+ declare const translateRjsfString: ({ stringToTranslate, params }: TranslateStringArgs) => string;
29
+
30
+ /**
31
+ * Returns true when the widget has at least one validation error from RJSF.
32
+ *
33
+ * @param rawErrors - The rawErrors from WidgetProps (often `unknown`).
34
+ * @returns true if rawErrors is a non-empty array.
35
+ */
36
+ declare const hasRjsfErrors: (rawErrors: unknown) => boolean;
37
+ interface GetRjsfDisplayLabelArgs {
38
+ label?: string;
39
+ required?: boolean;
40
+ hideLabel?: boolean;
41
+ }
42
+ /**
43
+ * Returns the label to display for an RJSF widget, with optional required asterisk and
44
+ * hideLabel support.
45
+ *
46
+ * @param label - The label to display for the widget.
47
+ * @param required - Whether the field is required.
48
+ * @param hideLabel - Whether to hide the label.
49
+ *
50
+ * @returns The label to display for the widget.
51
+ */
52
+ declare const getRjsfDisplayLabel: ({ label, required, hideLabel }: GetRjsfDisplayLabelArgs) => string | undefined;
53
+ type EnumOptionDisplay = {
54
+ label: string;
55
+ value: string;
56
+ };
57
+ declare const mapEnumOptions: (options: WidgetProps["options"]) => EnumOptionDisplay[];
58
+ /**
59
+ * Converts a value to display string, or empty string when null/undefined.
60
+ */
61
+ declare const toStringOrEmpty: (value: unknown) => string;
62
+ /**
63
+ * Converts a value to display string, or undefined when null/undefined (e.g. for select placeholder).
64
+ */
65
+ declare const toStringOrUndefined: (value: unknown) => string | undefined;
66
+ interface GetRjsfTextChangeValueArgs {
67
+ text: string;
68
+ emptyValue?: unknown;
69
+ }
70
+ /**
71
+ * Returns the value to pass to onChange for a text input.
72
+ *
73
+ * @param args.text - The current text input value.
74
+ * @param args.emptyValue - The value to use when text is empty (e.g. options.emptyValue from WidgetProps).
75
+ * @returns emptyValue when text is empty, otherwise text.
76
+ */
77
+ declare const getRjsfTextChangeValue: ({ text, emptyValue }: GetRjsfTextChangeValueArgs) => unknown;
78
+ declare const parseDateOrNull: (value?: string) => Date | null;
79
+ /** Returns YYYY-MM-DD for JSON Schema "date" format (form storage). */
80
+ declare const dateToDateOnlyString: (date: Date) => string;
81
+ /** Parses a date-only or full ISO string into a Date at local midnight (for date picker display). */
82
+ declare const parseDateOnlyToLocalDate: (value?: string) => Date | null;
83
+ /** Extracts date-only YYYY-MM-DD for display from a full ISO or date-only string. */
84
+ declare const formatDateOnlyForDisplay: (value?: string) => string;
85
+ /** Formats a full ISO or date string for date-time display (locale string). */
86
+ declare const formatDateTimeForDisplay: (value?: string) => string;
87
+ type FormLayoutContext = {
88
+ labelCol?: {
89
+ span: number;
90
+ };
91
+ wrapperCol?: {
92
+ span: number;
93
+ };
94
+ };
95
+ declare const getFormLayoutCols: (formContext?: unknown) => FormLayoutContext;
96
+
97
+ declare const useLocalizedForm: (metaFormSchema: MetaFormSchema) => LocalizedFormSchema;
98
+
99
+ declare const useRjsfValidator: () => _rjsf_validator_ajv8_lib_validator_js.default<any, _rjsf_utils.RJSFSchema, any>;
100
+
101
+ export { type EnumOptionDisplay, type GetRjsfDisplayLabelArgs, type GetRjsfTextChangeValueArgs, type Language, type LocalizedFormSchema, type MetaFormSchema, RJSF_STRING_TO_I18N_KEY, type RjsfRegistryWithTranslate, dateToDateOnlyString, formatDateOnlyForDisplay, formatDateTimeForDisplay, getFormLayoutCols, getRjsfDisplayLabel, getRjsfTextChangeValue, hasRjsfErrors, initRjsf, mapEnumOptions, parseDateOnlyToLocalDate, parseDateOrNull, toStringOrEmpty, toStringOrUndefined, translateRjsfString, useLocalizedForm, useRjsfValidator };
package/dist/rjsf.d.ts ADDED
@@ -0,0 +1,101 @@
1
+ import * as _rjsf_utils from '@rjsf/utils';
2
+ import { TranslatableString, RJSFSchema, UiSchema, WidgetProps } from '@rjsf/utils';
3
+ import * as _rjsf_validator_ajv8_lib_validator_js from '@rjsf/validator-ajv8/lib/validator.js';
4
+
5
+ declare const initRjsf: () => void;
6
+
7
+ type Language = string;
8
+ /** Registry shape with translation used by RJSF template buttons. */
9
+ type RjsfRegistryWithTranslate = {
10
+ translateString: (s: TranslatableString) => string;
11
+ };
12
+ interface LocalizedFormSchema {
13
+ schema: RJSFSchema;
14
+ uiSchema: UiSchema;
15
+ }
16
+ interface MetaFormSchema {
17
+ id: string;
18
+ version: string;
19
+ i18n: Record<Language, LocalizedFormSchema>;
20
+ }
21
+
22
+ /** Maps RJSF TranslatableString values to our i18n keys (rjsf namespace). */
23
+ declare const RJSF_STRING_TO_I18N_KEY: Record<string, string>;
24
+ interface TranslateStringArgs {
25
+ stringToTranslate: string;
26
+ params?: string[];
27
+ }
28
+ declare const translateRjsfString: ({ stringToTranslate, params }: TranslateStringArgs) => string;
29
+
30
+ /**
31
+ * Returns true when the widget has at least one validation error from RJSF.
32
+ *
33
+ * @param rawErrors - The rawErrors from WidgetProps (often `unknown`).
34
+ * @returns true if rawErrors is a non-empty array.
35
+ */
36
+ declare const hasRjsfErrors: (rawErrors: unknown) => boolean;
37
+ interface GetRjsfDisplayLabelArgs {
38
+ label?: string;
39
+ required?: boolean;
40
+ hideLabel?: boolean;
41
+ }
42
+ /**
43
+ * Returns the label to display for an RJSF widget, with optional required asterisk and
44
+ * hideLabel support.
45
+ *
46
+ * @param label - The label to display for the widget.
47
+ * @param required - Whether the field is required.
48
+ * @param hideLabel - Whether to hide the label.
49
+ *
50
+ * @returns The label to display for the widget.
51
+ */
52
+ declare const getRjsfDisplayLabel: ({ label, required, hideLabel }: GetRjsfDisplayLabelArgs) => string | undefined;
53
+ type EnumOptionDisplay = {
54
+ label: string;
55
+ value: string;
56
+ };
57
+ declare const mapEnumOptions: (options: WidgetProps["options"]) => EnumOptionDisplay[];
58
+ /**
59
+ * Converts a value to display string, or empty string when null/undefined.
60
+ */
61
+ declare const toStringOrEmpty: (value: unknown) => string;
62
+ /**
63
+ * Converts a value to display string, or undefined when null/undefined (e.g. for select placeholder).
64
+ */
65
+ declare const toStringOrUndefined: (value: unknown) => string | undefined;
66
+ interface GetRjsfTextChangeValueArgs {
67
+ text: string;
68
+ emptyValue?: unknown;
69
+ }
70
+ /**
71
+ * Returns the value to pass to onChange for a text input.
72
+ *
73
+ * @param args.text - The current text input value.
74
+ * @param args.emptyValue - The value to use when text is empty (e.g. options.emptyValue from WidgetProps).
75
+ * @returns emptyValue when text is empty, otherwise text.
76
+ */
77
+ declare const getRjsfTextChangeValue: ({ text, emptyValue }: GetRjsfTextChangeValueArgs) => unknown;
78
+ declare const parseDateOrNull: (value?: string) => Date | null;
79
+ /** Returns YYYY-MM-DD for JSON Schema "date" format (form storage). */
80
+ declare const dateToDateOnlyString: (date: Date) => string;
81
+ /** Parses a date-only or full ISO string into a Date at local midnight (for date picker display). */
82
+ declare const parseDateOnlyToLocalDate: (value?: string) => Date | null;
83
+ /** Extracts date-only YYYY-MM-DD for display from a full ISO or date-only string. */
84
+ declare const formatDateOnlyForDisplay: (value?: string) => string;
85
+ /** Formats a full ISO or date string for date-time display (locale string). */
86
+ declare const formatDateTimeForDisplay: (value?: string) => string;
87
+ type FormLayoutContext = {
88
+ labelCol?: {
89
+ span: number;
90
+ };
91
+ wrapperCol?: {
92
+ span: number;
93
+ };
94
+ };
95
+ declare const getFormLayoutCols: (formContext?: unknown) => FormLayoutContext;
96
+
97
+ declare const useLocalizedForm: (metaFormSchema: MetaFormSchema) => LocalizedFormSchema;
98
+
99
+ declare const useRjsfValidator: () => _rjsf_validator_ajv8_lib_validator_js.default<any, _rjsf_utils.RJSFSchema, any>;
100
+
101
+ export { type EnumOptionDisplay, type GetRjsfDisplayLabelArgs, type GetRjsfTextChangeValueArgs, type Language, type LocalizedFormSchema, type MetaFormSchema, RJSF_STRING_TO_I18N_KEY, type RjsfRegistryWithTranslate, dateToDateOnlyString, formatDateOnlyForDisplay, formatDateTimeForDisplay, getFormLayoutCols, getRjsfDisplayLabel, getRjsfTextChangeValue, hasRjsfErrors, initRjsf, mapEnumOptions, parseDateOnlyToLocalDate, parseDateOrNull, toStringOrEmpty, toStringOrUndefined, translateRjsfString, useLocalizedForm, useRjsfValidator };
package/dist/rjsf.js ADDED
@@ -0,0 +1,193 @@
1
+ import i18next from 'i18next';
2
+ import { replaceStringParameters } from '@rjsf/utils';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { customizeValidator } from '@rjsf/validator-ajv8';
5
+ import localizer from 'ajv-i18n';
6
+
7
+ // src/rjsf/i18n/i18n.ts
8
+
9
+ // src/rjsf/i18n/en/rjsf.json
10
+ var rjsf_default = {
11
+ rjsf: {
12
+ add: "Add",
13
+ debugFormDataTitle: "JSON data",
14
+ addItem: "Add Item",
15
+ clear: "Clear",
16
+ errors: "Errors detected in the form",
17
+ copy: "Copy",
18
+ keyLabel: "%1 Key",
19
+ moveDown: "Move down",
20
+ moveUp: "Move up",
21
+ no: "No",
22
+ remove: "Remove",
23
+ submit: "Submit",
24
+ yes: "Yes"
25
+ }
26
+ };
27
+
28
+ // src/rjsf/i18n/fr/rjsf.json
29
+ var rjsf_default2 = {
30
+ rjsf: {
31
+ add: "Ajouter",
32
+ debugFormDataTitle: "Donn\xE9es JSON",
33
+ addItem: "Ajouter un \xE9l\xE9ment",
34
+ clear: "Effacer",
35
+ errors: "Erreurs d\xE9tect\xE9es dans le formulaire",
36
+ copy: "Copier",
37
+ keyLabel: "Cl\xE9 %1",
38
+ moveDown: "D\xE9placer vers le bas",
39
+ moveUp: "D\xE9placer vers le haut",
40
+ no: "Non",
41
+ remove: "Supprimer",
42
+ submit: "Envoyer",
43
+ yes: "Oui"
44
+ }
45
+ };
46
+
47
+ // src/rjsf/i18n/i18n.ts
48
+ var NAMESPACE = "rjsf";
49
+ var initRjsf = () => {
50
+ if (!i18next.isInitialized) {
51
+ throw new Error("[initRjsf] i18next must be initialized before calling initRjsf. Call initI18N() or i18next.init() first.");
52
+ }
53
+ if (i18next.hasResourceBundle("en", NAMESPACE)) return;
54
+ const isDeep = true;
55
+ const isOverwrite = true;
56
+ i18next.addResourceBundle("en", NAMESPACE, rjsf_default.rjsf, isDeep, isOverwrite);
57
+ i18next.addResourceBundle("fr", NAMESPACE, rjsf_default2.rjsf, isDeep, isOverwrite);
58
+ console.info("[initRjsf] RJSF i18n initialized");
59
+ };
60
+
61
+ // src/utils/types.utils.ts
62
+ var isNullish = (value) => value === null || value === void 0;
63
+
64
+ // src/utils/string.utils.ts
65
+ var isBlank = (str) => {
66
+ return isNullish(str) || str?.trim() === "";
67
+ };
68
+
69
+ // src/rjsf/utils/rjsf-i18n.utils.ts
70
+ var RJSF_STRING_TO_I18N_KEY = {
71
+ "Add Item": "rjsf:addItem",
72
+ Add: "rjsf:add",
73
+ Copy: "rjsf:copy",
74
+ "Move down": "rjsf:moveDown",
75
+ "Move up": "rjsf:moveUp",
76
+ Remove: "rjsf:remove",
77
+ "clear input": "rjsf:clear",
78
+ "%1 Key": "rjsf:keyLabel",
79
+ // TODO: RJSF-001 find a way to dynamicaly resolve the rjsf-i18n.utils "%1 Key" pattern
80
+ Yes: "rjsf:yes",
81
+ No: "rjsf:no",
82
+ Errors: "rjsf:errors"
83
+ };
84
+ var translateRjsfString = ({ stringToTranslate, params }) => {
85
+ const i18nKey = RJSF_STRING_TO_I18N_KEY[stringToTranslate];
86
+ if (isBlank(i18nKey)) {
87
+ console.warn(`[translateRjsfString] RJSF i18n: missing key: "${stringToTranslate}"`);
88
+ }
89
+ const translated = i18nKey ? i18next.t(i18nKey) : stringToTranslate;
90
+ return replaceStringParameters(translated, params);
91
+ };
92
+
93
+ // src/rjsf/utils/rjsf-widgets.utils.ts
94
+ var hasRjsfErrors = (rawErrors) => Array.isArray(rawErrors) && rawErrors.length > 0;
95
+ var getRjsfDisplayLabel = ({ label, required, hideLabel }) => {
96
+ if (hideLabel) return void 0;
97
+ if (isBlank(label)) return void 0;
98
+ const requiredSuffix = required ? " *" : "";
99
+ return `${label}${requiredSuffix}`;
100
+ };
101
+ var toEnumOptionDisplay = (o) => ({
102
+ label: o?.label ?? String(o?.value ?? ""),
103
+ value: String(o?.value ?? "")
104
+ });
105
+ var mapEnumOptions = (options) => {
106
+ const enumOptions = options?.enumOptions;
107
+ if (!Array.isArray(enumOptions)) return [];
108
+ return enumOptions.map(toEnumOptionDisplay);
109
+ };
110
+ var toStringOrEmpty = (value) => isNullish(value) ? "" : String(value);
111
+ var toStringOrUndefined = (value) => isNullish(value) ? void 0 : String(value);
112
+ var getRjsfTextChangeValue = ({ text, emptyValue }) => {
113
+ if (text === "") return emptyValue;
114
+ return text;
115
+ };
116
+ var parseDateOrNull = (value) => {
117
+ if (isBlank(value)) return null;
118
+ const date = new Date(value);
119
+ const isValid = !Number.isNaN(date.getTime());
120
+ return isValid ? date : null;
121
+ };
122
+ var dateToDateOnlyString = (date) => {
123
+ const y = date.getFullYear();
124
+ const m = String(date.getMonth() + 1).padStart(2, "0");
125
+ const d = String(date.getDate()).padStart(2, "0");
126
+ return `${y}-${m}-${d}`;
127
+ };
128
+ var DATE_ONLY_REGEX = /^\d{4}-\d{2}-\d{2}$/;
129
+ var parseDateOnlyToLocalDate = (value) => {
130
+ if (isBlank(value)) return null;
131
+ const trimmed = String(value).trim();
132
+ const dateOnly = trimmed.slice(0, 10);
133
+ if (!DATE_ONLY_REGEX.test(dateOnly)) return null;
134
+ const [y, m, d] = dateOnly.split("-").map(Number);
135
+ return new Date(y, m - 1, d);
136
+ };
137
+ var formatDateOnlyForDisplay = (value) => {
138
+ if (isBlank(value)) return "";
139
+ const trimmed = String(value).trim();
140
+ const dateOnly = trimmed.slice(0, 10);
141
+ return DATE_ONLY_REGEX.test(dateOnly) ? dateOnly : "";
142
+ };
143
+ var formatDateTimeForDisplay = (value) => {
144
+ const date = parseDateOrNull(value);
145
+ return date ? date.toLocaleString() : "";
146
+ };
147
+ var DEFAULT_SPAN = 24;
148
+ var getFormLayoutCols = (formContext) => {
149
+ if (isNullish(formContext)) {
150
+ return {
151
+ labelCol: { span: DEFAULT_SPAN },
152
+ wrapperCol: { span: DEFAULT_SPAN }
153
+ };
154
+ }
155
+ const { labelCol, wrapperCol } = formContext;
156
+ return {
157
+ labelCol: labelCol ?? { span: DEFAULT_SPAN },
158
+ wrapperCol: wrapperCol ?? { span: DEFAULT_SPAN }
159
+ };
160
+ };
161
+ var DEFAULT_LANGUAGE = "fr";
162
+ var parseSimplifiedLangCode = (language) => {
163
+ if (isBlank(language)) return DEFAULT_LANGUAGE;
164
+ return language.split("-")[0];
165
+ };
166
+ var getFallbackLanguage = (metaFormSchema) => {
167
+ return Object.keys(metaFormSchema.i18n)[0] ?? DEFAULT_LANGUAGE;
168
+ };
169
+ var useLocalizedForm = (metaFormSchema) => {
170
+ const { i18n } = useTranslation();
171
+ const language = parseSimplifiedLangCode(i18n.language);
172
+ if (metaFormSchema.i18n[language]) {
173
+ return metaFormSchema.i18n[language];
174
+ }
175
+ const fallbackLanguage = getFallbackLanguage(metaFormSchema);
176
+ console.warn(
177
+ `Language ${language} not found in metaFormSchema ${metaFormSchema.id}. Falling back to ${fallbackLanguage}.`
178
+ );
179
+ return metaFormSchema.i18n[fallbackLanguage];
180
+ };
181
+ var customFormats = {
182
+ "phone-america": /^\(?\d{3}\)?[\s-]?\d{3}[\s-]?\d{4}$/
183
+ };
184
+ var useRjsfValidator = () => {
185
+ const { i18n } = useTranslation();
186
+ const appLanguage = i18n.language;
187
+ const localizerFn = localizer[appLanguage] ?? localizer.en;
188
+ return customizeValidator({ customFormats }, localizerFn);
189
+ };
190
+
191
+ export { RJSF_STRING_TO_I18N_KEY, dateToDateOnlyString, formatDateOnlyForDisplay, formatDateTimeForDisplay, getFormLayoutCols, getRjsfDisplayLabel, getRjsfTextChangeValue, hasRjsfErrors, initRjsf, mapEnumOptions, parseDateOnlyToLocalDate, parseDateOrNull, toStringOrEmpty, toStringOrUndefined, translateRjsfString, useLocalizedForm, useRjsfValidator };
192
+ //# sourceMappingURL=rjsf.js.map
193
+ //# sourceMappingURL=rjsf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/rjsf/i18n/en/rjsf.json","../src/rjsf/i18n/fr/rjsf.json","../src/rjsf/i18n/i18n.ts","../src/utils/types.utils.ts","../src/utils/string.utils.ts","../src/rjsf/utils/rjsf-i18n.utils.ts","../src/rjsf/utils/rjsf-widgets.utils.ts","../src/rjsf/utils/use-localized-form.ts","../src/rjsf/utils/use-rjsf-validator.ts"],"names":["rjsf_default","i18next","useTranslation"],"mappings":"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","file":"rjsf.js","sourcesContent":["{\n \"rjsf\": {\n \"add\": \"Add\",\n \"debugFormDataTitle\": \"JSON data\",\n \"addItem\": \"Add Item\",\n \"clear\": \"Clear\",\n \"errors\": \"Errors detected in the form\",\n \"copy\": \"Copy\",\n \"keyLabel\": \"%1 Key\",\n \"moveDown\": \"Move down\",\n \"moveUp\": \"Move up\",\n \"no\": \"No\",\n \"remove\": \"Remove\",\n \"submit\": \"Submit\",\n \"yes\": \"Yes\"\n }\n}\n","{\n \"rjsf\": {\n \"add\": \"Ajouter\",\n \"debugFormDataTitle\": \"Données JSON\",\n \"addItem\": \"Ajouter un élément\",\n \"clear\": \"Effacer\",\n \"errors\": \"Erreurs détectées dans le formulaire\",\n \"copy\": \"Copier\",\n \"keyLabel\": \"Clé %1\",\n \"moveDown\": \"Déplacer vers le bas\",\n \"moveUp\": \"Déplacer vers le haut\",\n \"no\": \"Non\",\n \"remove\": \"Supprimer\",\n \"submit\": \"Envoyer\",\n \"yes\": \"Oui\"\n }\n}\n","import i18next from \"i18next\";\n\nimport en from \"./en/rjsf.json\";\nimport fr from \"./fr/rjsf.json\";\n\nconst NAMESPACE = \"rjsf\";\n\nexport const initRjsf = (): void => {\n if (!i18next.isInitialized) {\n throw new Error(\"[initRjsf] i18next must be initialized before calling initRjsf. Call initI18N() or i18next.init() first.\");\n }\n\n if (i18next.hasResourceBundle(\"en\", NAMESPACE)) return;\n\n const isDeep = true;\n const isOverwrite = true;\n\n i18next.addResourceBundle(\"en\", NAMESPACE, en.rjsf, isDeep, isOverwrite);\n i18next.addResourceBundle(\"fr\", NAMESPACE, fr.rjsf, isDeep, isOverwrite);\n\n // eslint-disable-next-line no-console\n console.info('[initRjsf] RJSF i18n initialized'); \n};\n","export const NO_OP: () => void = () => {};\n\nexport const isNullish = (value: unknown): value is null | undefined => value === null || value === undefined;\n\nexport const isNumber = (value?: unknown | null): value is number => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'number') {\n return false;\n }\n\n if (isNaN(value)) {\n return false;\n }\n\n return true;\n};\n\nexport const isString = (value?: unknown | null): value is string => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'string') {\n return false;\n }\n\n return true;\n};\n","import { REGEX_ALPHANUMERIC } from './regex';\nimport { isNullish } from './types.utils';\n\nexport const isBlank = (str?: string | null): str is null | undefined | '' => {\n return isNullish(str) || str?.trim() === '';\n};\n\nexport const isNotBlank = (str?: string | null): str is string => {\n return !isBlank(str);\n};\n\nexport const isAlphanumeric = (value: string): boolean => {\n return REGEX_ALPHANUMERIC.test(value);\n};\n\n/**\n * Removes diacritical marks (e.g., accents, umlauts) from a string.\n * This method normalizes the input string to its canonical decomposition\n * form (NFD) and removes any combining diacritical marks.\n *\n * @param {string} value - The input string to normalize.\n * @returns {string} - The normalized string with diacritical marks removed.\n *\n * @example\n * const result = removeDiacriticalMarks(\"Ça va très bien, n'est-ce pas?\");\n * console.log(result); // \"Ca va tres bien, n'est-ce pas?\"\n */\nexport const removeDiacriticalMarks = (value: string): string => {\n if (!value) {\n return '';\n }\n\n return value.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '');\n};\n\n/**\n * Capitalize the first letter of a string.\n * @param str - The input string\n * @returns The string with the first character uppercased\n */\nexport const capitalizeFirst = (str: string): string => {\n if (!str) return str;\n return str.charAt(0).toUpperCase() + str.slice(1);\n};\n\n/**\n * Count the number of words in a text string.\n * Words are separated by whitespace.\n * @param text - The text to count words in\n * @returns The number of words found\n */\nexport const countWords = (text: string): number => {\n if (!text || text.trim().length === 0) return 0;\n return text.split(/\\s+/).filter((word) => word.length > 0).length;\n};\n\n/**\n * Truncate a string to a maximum length, adding an ellipsis if truncated.\n * @param str - The string to truncate\n * @param maxLength - Maximum length before truncation\n * @param ellipsis - The ellipsis string to append (default: \"...\")\n * @returns The truncated string\n */\nexport const truncate = (str: string, maxLength: number, ellipsis = \"...\"): string => {\n if (!str || str.length <= maxLength) return str;\n return str.slice(0, maxLength - ellipsis.length) + ellipsis;\n};\n\n/**\n * Parses an optional comma-separated string into a trimmed, non-blank string array.\n */\nexport const parseCommaSeparatedList = (raw?: string | null): string[] => {\n if (isBlank(raw)) {\n return [];\n }\n\n return raw\n .split(\",\")\n .map((s: string) => s.trim())\n .filter(isNotBlank);\n};\n","import { replaceStringParameters } from \"@rjsf/utils\";\nimport i18next from \"i18next\";\nimport { isBlank } from \"~/utils/string.utils\";\n\n/** Maps RJSF TranslatableString values to our i18n keys (rjsf namespace). */\nexport const RJSF_STRING_TO_I18N_KEY: Record<string, string> = {\n \"Add Item\": \"rjsf:addItem\",\n Add: \"rjsf:add\",\n Copy: \"rjsf:copy\",\n \"Move down\": \"rjsf:moveDown\",\n \"Move up\": \"rjsf:moveUp\",\n Remove: \"rjsf:remove\",\n \"clear input\": \"rjsf:clear\",\n \"%1 Key\": \"rjsf:keyLabel\", // TODO: RJSF-001 find a way to dynamicaly resolve the rjsf-i18n.utils \"%1 Key\" pattern\n Yes: \"rjsf:yes\",\n No: \"rjsf:no\",\n Errors: \"rjsf:errors\",\n};\n\ninterface TranslateStringArgs {\n stringToTranslate: string;\n params?: string[];\n}\n\nexport const translateRjsfString = ({ stringToTranslate, params }: TranslateStringArgs): string => {\n const i18nKey = RJSF_STRING_TO_I18N_KEY[stringToTranslate];\n if (isBlank(i18nKey)) {\n // eslint-disable-next-line no-console\n console.warn(`[translateRjsfString] RJSF i18n: missing key: \"${stringToTranslate}\"`);\n }\n\n const translated = i18nKey ? i18next.t(i18nKey) : stringToTranslate;\n return replaceStringParameters(translated, params);\n};\n","import type { WidgetProps } from \"@rjsf/utils\";\nimport { isBlank } from \"~/utils/string.utils\";\nimport { isNullish } from \"~/utils/types.utils\";\n\n/**\n * Returns true when the widget has at least one validation error from RJSF.\n *\n * @param rawErrors - The rawErrors from WidgetProps (often `unknown`).\n * @returns true if rawErrors is a non-empty array.\n */\nexport const hasRjsfErrors = (rawErrors: unknown): boolean => Array.isArray(rawErrors) && rawErrors.length > 0;\n\nexport interface GetRjsfDisplayLabelArgs {\n label?: string;\n required?: boolean;\n hideLabel?: boolean;\n}\n\n/**\n * Returns the label to display for an RJSF widget, with optional required asterisk and\n * hideLabel support.\n *\n * @param label - The label to display for the widget.\n * @param required - Whether the field is required.\n * @param hideLabel - Whether to hide the label.\n *\n * @returns The label to display for the widget.\n */\nexport const getRjsfDisplayLabel = ({ label, required, hideLabel }: GetRjsfDisplayLabelArgs): string | undefined => {\n if (hideLabel) return undefined;\n if (isBlank(label)) return undefined;\n\n const requiredSuffix = required ? \" *\" : \"\";\n return `${label}${requiredSuffix}`;\n};\n\ninterface EnumOption {\n value: string;\n label: string;\n}\n\nexport type EnumOptionDisplay = { label: string; value: string };\n\nconst toEnumOptionDisplay = (o: EnumOption): EnumOptionDisplay => ({\n label: o?.label ?? String(o?.value ?? \"\"),\n value: String(o?.value ?? \"\"),\n});\n\nexport const mapEnumOptions = (options: WidgetProps[\"options\"]): EnumOptionDisplay[] => {\n const enumOptions = options?.enumOptions as EnumOption[] | undefined;\n if (!Array.isArray(enumOptions)) return [];\n return enumOptions.map(toEnumOptionDisplay);\n};\n\n/**\n * Converts a value to display string, or empty string when null/undefined.\n */\nexport const toStringOrEmpty = (value: unknown): string => (isNullish(value) ? \"\" : String(value));\n\n/**\n * Converts a value to display string, or undefined when null/undefined (e.g. for select placeholder).\n */\nexport const toStringOrUndefined = (value: unknown): string | undefined =>\n isNullish(value) ? undefined : String(value);\n\nexport interface GetRjsfTextChangeValueArgs {\n text: string;\n emptyValue?: unknown;\n}\n\n/**\n * Returns the value to pass to onChange for a text input.\n *\n * @param args.text - The current text input value.\n * @param args.emptyValue - The value to use when text is empty (e.g. options.emptyValue from WidgetProps).\n * @returns emptyValue when text is empty, otherwise text.\n */\nexport const getRjsfTextChangeValue = ({ text, emptyValue }: GetRjsfTextChangeValueArgs): unknown => {\n if (text === \"\") return emptyValue;\n return text;\n};\n\nexport const parseDateOrNull = (value?: string): Date | null => {\n if (isBlank(value)) return null;\n\n const date = new Date(value);\n const isValid = !Number.isNaN(date.getTime());\n return isValid ? date : null;\n};\n\n/** Returns YYYY-MM-DD for JSON Schema \"date\" format (form storage). */\nexport const dateToDateOnlyString = (date: Date): string => {\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, \"0\");\n const d = String(date.getDate()).padStart(2, \"0\");\n return `${y}-${m}-${d}`;\n};\n\nconst DATE_ONLY_REGEX = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/** Parses a date-only or full ISO string into a Date at local midnight (for date picker display). */\nexport const parseDateOnlyToLocalDate = (value?: string): Date | null => {\n if (isBlank(value)) return null;\n\n const trimmed = String(value).trim();\n const dateOnly = trimmed.slice(0, 10);\n if (!DATE_ONLY_REGEX.test(dateOnly)) return null;\n\n const [y, m, d] = dateOnly.split(\"-\").map(Number);\n return new Date(y, m - 1, d);\n};\n\n/** Extracts date-only YYYY-MM-DD for display from a full ISO or date-only string. */\nexport const formatDateOnlyForDisplay = (value?: string): string => {\n if (isBlank(value)) return \"\";\n\n const trimmed = String(value).trim();\n const dateOnly = trimmed.slice(0, 10);\n return DATE_ONLY_REGEX.test(dateOnly) ? dateOnly : \"\";\n};\n\n/** Formats a full ISO or date string for date-time display (locale string). */\nexport const formatDateTimeForDisplay = (value?: string): string => {\n const date = parseDateOrNull(value);\n return date ? date.toLocaleString() : \"\";\n};\n\ntype FormLayoutContext = {\n labelCol?: { span: number };\n wrapperCol?: { span: number };\n};\n\nconst DEFAULT_SPAN = 24;\n\nexport const getFormLayoutCols = (formContext?: unknown): FormLayoutContext => {\n if (isNullish(formContext)) {\n return {\n labelCol: { span: DEFAULT_SPAN },\n wrapperCol: { span: DEFAULT_SPAN },\n };\n }\n\n const { labelCol, wrapperCol } = formContext as FormLayoutContext;\n return {\n labelCol: labelCol ?? { span: DEFAULT_SPAN },\n wrapperCol: wrapperCol ?? { span: DEFAULT_SPAN },\n };\n};\n","import { isBlank } from \"~/utils/string.utils\";\nimport { useTranslation } from \"react-i18next\";\nimport type { LocalizedFormSchema, MetaFormSchema } from \"./rjsf-i18n-types\";\n\nconst DEFAULT_LANGUAGE = \"fr\";\n\n// i18n.language can be 'fr-CA', so we take the first part\nconst parseSimplifiedLangCode = (language?: string): string => {\n if (isBlank(language)) return DEFAULT_LANGUAGE;\n return language.split(\"-\")[0];\n};\n\nconst getFallbackLanguage = (metaFormSchema: MetaFormSchema): string => {\n return Object.keys(metaFormSchema.i18n)[0] ?? DEFAULT_LANGUAGE;\n};\n\nexport const useLocalizedForm = (metaFormSchema: MetaFormSchema): LocalizedFormSchema => {\n const { i18n } = useTranslation();\n const language = parseSimplifiedLangCode(i18n.language);\n\n if (metaFormSchema.i18n[language]) {\n return metaFormSchema.i18n[language];\n }\n\n const fallbackLanguage = getFallbackLanguage(metaFormSchema);\n // eslint-disable-next-line no-console\n console.warn(\n `Language ${language} not found in metaFormSchema ${metaFormSchema.id}. Falling back to ${fallbackLanguage}.`\n );\n\n return metaFormSchema.i18n[fallbackLanguage];\n};\n","import { customizeValidator, type Localizer } from \"@rjsf/validator-ajv8\";\nimport localizer from \"ajv-i18n\";\nimport { useTranslation } from \"react-i18next\";\n\nconst customFormats = {\n \"phone-america\": /^\\(?\\d{3}\\)?[\\s-]?\\d{3}[\\s-]?\\d{4}$/,\n};\n\ntype ValidationLanguages = keyof typeof localizer;\n\nexport const useRjsfValidator = () => {\n const { i18n } = useTranslation();\n const appLanguage = i18n.language as ValidationLanguages;\n const localizerFn: Localizer = localizer[appLanguage] ?? localizer.en;\n\n return customizeValidator({ customFormats }, localizerFn);\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lichens-innovation/ts-common",
3
- "version": "1.13.0",
3
+ "version": "1.15.0",
4
4
  "description": "Reusable generic typescript utilities, types, constants, helpers",
5
5
  "keywords": [
6
6
  "typescript",
@@ -54,6 +54,12 @@
54
54
  "import": "./dist/logger.js",
55
55
  "require": "./dist/logger.cjs",
56
56
  "default": "./dist/logger.js"
57
+ },
58
+ "./rjsf": {
59
+ "types": "./dist/rjsf.d.ts",
60
+ "import": "./dist/rjsf.js",
61
+ "require": "./dist/rjsf.cjs",
62
+ "default": "./dist/rjsf.js"
57
63
  }
58
64
  },
59
65
  "sideEffects": false,
@@ -84,25 +90,33 @@
84
90
  "date-fns": "^4.1.0"
85
91
  },
86
92
  "peerDependencies": {
93
+ "@rjsf/utils": "*",
94
+ "@rjsf/validator-ajv8": "*",
95
+ "ajv-i18n": "*",
87
96
  "exceljs": "^4.4.0",
97
+ "i18next": "*",
88
98
  "jspdf": "^4.1.0",
89
99
  "jspdf-autotable": "^5.0.7",
90
100
  "mime": "^4.1.0",
91
101
  "papaparse": "^5.4.1",
92
102
  "pino": "^10.3.1",
93
- "pino-pretty": "^13.0.0"
103
+ "pino-pretty": "^13.0.0",
104
+ "react-i18next": "*"
94
105
  },
95
106
  "peerDependenciesMeta": {
96
- "exceljs": {
107
+ "@rjsf/utils": {
97
108
  "optional": true
98
109
  },
99
- "papaparse": {
110
+ "@rjsf/validator-ajv8": {
100
111
  "optional": true
101
112
  },
102
- "pino": {
113
+ "ajv-i18n": {
103
114
  "optional": true
104
115
  },
105
- "pino-pretty": {
116
+ "exceljs": {
117
+ "optional": true
118
+ },
119
+ "i18next": {
106
120
  "optional": true
107
121
  },
108
122
  "jspdf": {
@@ -113,22 +127,39 @@
113
127
  },
114
128
  "mime": {
115
129
  "optional": true
130
+ },
131
+ "papaparse": {
132
+ "optional": true
133
+ },
134
+ "pino": {
135
+ "optional": true
136
+ },
137
+ "pino-pretty": {
138
+ "optional": true
139
+ },
140
+ "react-i18next": {
141
+ "optional": true
116
142
  }
117
143
  },
118
144
  "engines": {
119
145
  "node": ">=20.11.0"
120
146
  },
121
147
  "devDependencies": {
122
- "@commitlint/cli": "^20.4.3",
123
- "@commitlint/config-conventional": "^20.4.3",
148
+ "@commitlint/cli": "^20.4.4",
149
+ "@rjsf/utils": "^6.4.1",
150
+ "@rjsf/validator-ajv8": "^6.4.1",
151
+ "ajv-i18n": "^4.2.0",
152
+ "i18next": "^25.8.18",
153
+ "react-i18next": "^16.5.8",
154
+ "@commitlint/config-conventional": "^20.4.4",
124
155
  "@eslint/js": "^10.0.1",
125
156
  "@faker-js/faker": "^10.3.0",
126
- "@types/node": "^25.3.5",
157
+ "@types/node": "^25.5.0",
127
158
  "@types/papaparse": "^5.5.2",
128
- "@vitest/coverage-v8": "4.0.18",
129
- "commitlint": "^20.4.3",
159
+ "@vitest/coverage-v8": "4.1.0",
160
+ "commitlint": "^20.4.4",
130
161
  "cross-env": "^10.1.0",
131
- "eslint": "^10.0.2",
162
+ "eslint": "^10.0.3",
132
163
  "exceljs": "^4.4.0",
133
164
  "globals": "^17.4.0",
134
165
  "husky": "^9.1.7",
@@ -142,9 +173,9 @@
142
173
  "rimraf": "^6.1.3",
143
174
  "tsup": "^8.5.1",
144
175
  "typescript": "~5.9.3",
145
- "typescript-eslint": "^8.56.1",
146
- "vite": "^7.3.1",
176
+ "typescript-eslint": "^8.57.0",
177
+ "vite": "^8.0.0",
147
178
  "vite-tsconfig-paths": "^6.1.1",
148
- "vitest": "^4.0.18"
179
+ "vitest": "^4.1.0"
149
180
  }
150
181
  }