runid-lys 0.4.2 → 0.5.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/dist/index.js CHANGED
@@ -1,27 +1,27 @@
1
1
  import { I18nLocaleEnum } from "./types/index.js";
2
- import { c, a, b, e, l, n, t } from "./translationTools-CSKULpZZ.js";
3
- import { c as c2, e as e2, g, a as a2, b as b2, d, f, h, i, m, p, s, v } from "./routeTools-BVJY3epS.js";
4
- import { A, C, a as a3, b as b3, c as c3, E, F, G, L, d as d2, e as e3, f as f2, g as g2, P, R, S, U, W, u, h as h2, i as i2, j, k, l as l2, m as m2, n as n2, o, p as p2, q, r, s as s2, t as t2, v as v2, w, x, y } from "./constants-CgExWMDS.js";
5
- import { u as u2, a as a4 } from "./hooks-CvhFUowR.js";
6
- import { R as R2, c as c4, a as a5 } from "./RelayEnvironment-D880U9SM.js";
7
- import { P as P2 } from "./PublicAppTemplate-SRJ1HtD0.js";
8
- import { e as e4, i as i3 } from "./errors-BOacmKM0.js";
2
+ import { c, a, b, d, e, f, g, h, i, j, k, l, m, n, p, s, t, v } from "./translationTools-RWoOzX2m.js";
3
+ import { g as g2, m as m2 } from "./i18nTools-BDTofggT.js";
4
+ import { A, C, a as a2, b as b2, c as c2, E, F, G, L, d as d2, e as e2, f as f2, g as g3, P, R, S, U, W, u, h as h2, i as i2, j as j2, k as k2, l as l2, m as m3, n as n2, o, p as p2, q, r, s as s2, t as t2, v as v2, w, x, y, z } from "./constants-BLmcEnm4.js";
5
+ import { u as u2, a as a3 } from "./hooks-CvhFUowR.js";
6
+ import { R as R2, c as c3, a as a4 } from "./RelayEnvironment-D880U9SM.js";
7
+ import { P as P2 } from "./PublicAppTemplate-B93G2Smc.js";
8
+ import { e as e3, i as i3 } from "./errors-BOacmKM0.js";
9
9
  import { messagesTranslations } from "./i18n/index.js";
10
10
  export {
11
11
  A as AlertMessageProvider,
12
12
  C as ChatbotProvider,
13
- a3 as ClientProvider,
14
- b3 as ConnectedUserFragment,
15
- c3 as ConnectedUserProvider,
13
+ a2 as ClientProvider,
14
+ b2 as ConnectedUserFragment,
15
+ c2 as ConnectedUserProvider,
16
16
  E as ErrorBoundaryProvider,
17
17
  F as FilterLabelsProvider,
18
18
  G as GRAPHQL_ERROR,
19
19
  I18nLocaleEnum,
20
20
  L as LocaleProvider,
21
21
  d2 as LysDialogProvider,
22
- e3 as LysLoadingContext,
22
+ e2 as LysLoadingContext,
23
23
  f2 as LysMutationProvider,
24
- g2 as LysQueryProvider,
24
+ g3 as LysQueryProvider,
25
25
  P as PageContextProvider,
26
26
  P2 as PublicAppTemplate,
27
27
  R as RefreshSignalContext,
@@ -30,24 +30,24 @@ export {
30
30
  U as UrlQueriesProvider,
31
31
  W as WebserviceAccessProvider,
32
32
  c as checkOperationsPermission,
33
- c2 as cleanParameters,
34
- c4 as clearRelayCache,
35
- a as cn,
36
- a5 as configureRelayEndpoint,
37
- b as createComponentTranslations,
38
- e2 as emailRegex,
39
- e4 as errorTranslations,
40
- e as extractOperationNames,
41
- g as generateI18nMessage,
42
- a2 as generateRouteFromDescription,
43
- b2 as generateRouteTable,
44
- d as generateUrl,
45
- f as generateUrlByRoute,
46
- h as getNestedValue,
47
- i as isEmpty,
33
+ a as cleanParameters,
34
+ c3 as clearRelayCache,
35
+ b as cn,
36
+ a4 as configureRelayEndpoint,
37
+ d as createComponentTranslations,
38
+ e as emailRegex,
39
+ e3 as errorTranslations,
40
+ f as extractOperationNames,
41
+ g2 as generateI18nMessage,
42
+ g as generateRouteFromDescription,
43
+ h as generateRouteTable,
44
+ i as generateUrl,
45
+ j as generateUrlByRoute,
46
+ k as getNestedValue,
47
+ l as isEmpty,
48
48
  i3 as isErrorKey,
49
- l as lowerCaseFirstLetter,
50
- m as mergeI18nMessages,
49
+ m as lowerCaseFirstLetter,
50
+ m2 as mergeI18nMessages,
51
51
  messagesTranslations,
52
52
  n as numberToString,
53
53
  p as passwordRegex,
@@ -56,23 +56,24 @@ export {
56
56
  u as useAlertMessages,
57
57
  u2 as useChatbot,
58
58
  h2 as useClientId,
59
- a4 as useConnectedUserInfo,
59
+ a3 as useConnectedUserInfo,
60
60
  i2 as useDialogWithUpdates,
61
- j as useFilterLabels,
62
- k as useLocale,
61
+ j2 as useFilterLabels,
62
+ k2 as useLocale,
63
63
  l2 as useLysDialog,
64
- m2 as useLysLoadingFallback,
64
+ m3 as useLysLoadingFallback,
65
65
  n2 as useLysMutation,
66
66
  o as useLysQuery,
67
67
  p2 as usePageContext,
68
68
  q as usePermissionCheck,
69
69
  r as useRefreshSignal,
70
- s2 as useSignal,
71
- t2 as useSignalRefresh,
72
- v2 as useSignalSubscription,
73
- w as useUrlQueries,
74
- x as useWebserviceAccess,
70
+ s2 as useRestrictedLink,
71
+ t2 as useSignal,
72
+ v2 as useSignalRefresh,
73
+ w as useSignalSubscription,
74
+ x as useUrlQueries,
75
+ y as useWebserviceAccess,
75
76
  v as validators,
76
- y as webserviceAccessProviderConfig
77
+ z as webserviceAccessProviderConfig
77
78
  };
78
79
  //# sourceMappingURL=index.js.map
@@ -1,8 +1,10 @@
1
+ import { RouteInterface } from '../../types/routeTypes';
1
2
  /**
2
3
  * ClientProvider props
3
4
  */
4
5
  export interface ClientProviderProps {
5
6
  children: React.ReactNode;
7
+ routes: RouteInterface[];
6
8
  }
7
9
  /**
8
10
  * Client context value
@@ -0,0 +1,24 @@
1
+ import { RouteInterface } from '../../types/routeTypes';
2
+ export interface RestrictedLink {
3
+ hasPermission: boolean;
4
+ navigate: (() => void) | undefined;
5
+ }
6
+ /**
7
+ * Hook to check route permission and provide navigation callback.
8
+ *
9
+ * Combines permission checking (via WebserviceAccessProvider) with
10
+ * navigation (via react-router) for a given route.
11
+ *
12
+ * Usage:
13
+ * ```tsx
14
+ * const link = useRestrictedLink(route);
15
+ * if (link.hasPermission) {
16
+ * <button onClick={link.navigate}>Go</button>
17
+ * }
18
+ * ```
19
+ */
20
+ export declare function useRestrictedLink(route: RouteInterface | undefined, parameters?: {
21
+ [key: string]: string;
22
+ }, queryParameters?: {
23
+ [key: string]: string;
24
+ }): RestrictedLink;
@@ -26,6 +26,8 @@ export { useSignal, useSignalSubscription, useSignalRefresh } from './SignalProv
26
26
  export { useLysQuery } from './LysQueryProvider/hooks';
27
27
  export { useLysMutation } from './LysMutationProvider/hooks';
28
28
  export { usePermissionCheck } from './hooks/usePermissionCheck';
29
+ export { useRestrictedLink } from './hooks/useRestrictedLink';
30
+ export type { RestrictedLink } from './hooks/useRestrictedLink';
29
31
  export { useClientId } from './ClientProvider/hooks';
30
32
  export type { ClientContextValue, ClientProviderProps } from './ClientProvider/types';
31
33
  export { default as LysLoadingContext, useLysLoadingFallback } from './LysQueryProvider/LysLoadingContext';
@@ -1,4 +1,4 @@
1
- import { A, C, a, b, c, E, F, G, L, d, e, f, g, P, R, S, U, W, u, h, i, j, k, l, m, n, o, p, q, r, s, t, v, w, x, y } from "../constants-CgExWMDS.js";
1
+ import { A, C, a, b, c, E, F, G, L, d, e, f, g, P, R, S, U, W, u, h, i, j, k, l, m, n, o, p, q, r, s, t, v, w, x, y, z } from "../constants-BLmcEnm4.js";
2
2
  import { u as u2, a as a2 } from "../hooks-CvhFUowR.js";
3
3
  import { c as c2 } from "../RelayEnvironment-D880U9SM.js";
4
4
  export {
@@ -35,11 +35,12 @@ export {
35
35
  p as usePageContext,
36
36
  q as usePermissionCheck,
37
37
  r as useRefreshSignal,
38
- s as useSignal,
39
- t as useSignalRefresh,
40
- v as useSignalSubscription,
41
- w as useUrlQueries,
42
- x as useWebserviceAccess,
43
- y as webserviceAccessProviderConfig
38
+ s as useRestrictedLink,
39
+ t as useSignal,
40
+ v as useSignalRefresh,
41
+ w as useSignalSubscription,
42
+ x as useUrlQueries,
43
+ y as useWebserviceAccess,
44
+ z as webserviceAccessProviderConfig
44
45
  };
45
46
  //# sourceMappingURL=index.js.map
@@ -1,4 +1,4 @@
1
- import { P } from "../PublicAppTemplate-SRJ1HtD0.js";
1
+ import { P } from "../PublicAppTemplate-B93G2Smc.js";
2
2
  export {
3
3
  P as PublicAppTemplate
4
4
  };
@@ -1,21 +1,21 @@
1
- import { c, a, b, e, l, n, t } from "../translationTools-CSKULpZZ.js";
2
- import { c as c2, e as e2, g, a as a2, b as b2, d, f, h, i, m, p, s, v } from "../routeTools-BVJY3epS.js";
1
+ import { c, a, b, d, e, f, g, h, i, j, k, l, m, n, p, s, t, v } from "../translationTools-RWoOzX2m.js";
2
+ import { g as g2, m as m2 } from "../i18nTools-BDTofggT.js";
3
3
  export {
4
4
  c as checkOperationsPermission,
5
- c2 as cleanParameters,
6
- a as cn,
7
- b as createComponentTranslations,
8
- e2 as emailRegex,
9
- e as extractOperationNames,
10
- g as generateI18nMessage,
11
- a2 as generateRouteFromDescription,
12
- b2 as generateRouteTable,
13
- d as generateUrl,
14
- f as generateUrlByRoute,
15
- h as getNestedValue,
16
- i as isEmpty,
17
- l as lowerCaseFirstLetter,
18
- m as mergeI18nMessages,
5
+ a as cleanParameters,
6
+ b as cn,
7
+ d as createComponentTranslations,
8
+ e as emailRegex,
9
+ f as extractOperationNames,
10
+ g2 as generateI18nMessage,
11
+ g as generateRouteFromDescription,
12
+ h as generateRouteTable,
13
+ i as generateUrl,
14
+ j as generateUrlByRoute,
15
+ k as getNestedValue,
16
+ l as isEmpty,
17
+ m as lowerCaseFirstLetter,
18
+ m2 as mergeI18nMessages,
19
19
  n as numberToString,
20
20
  p as passwordRegex,
21
21
  s as setNestedValue,
@@ -1,4 +1,20 @@
1
- import { l as lowerCaseFirstLetter } from "./translationTools-CSKULpZZ.js";
1
+ import { useMemo } from "react";
2
+ import { useIntl } from "react-intl";
3
+ const lowerCaseFirstLetter = (str) => {
4
+ return str.charAt(0).toLowerCase() + str.slice(1);
5
+ };
6
+ const cn = (...classes) => {
7
+ return classes.filter(Boolean).join(" ");
8
+ };
9
+ const toSnakeCase = (str) => {
10
+ return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
11
+ };
12
+ const numberToString = (value) => {
13
+ if (value == null) return "";
14
+ const num = typeof value === "string" ? parseFloat(value) : value;
15
+ if (isNaN(num)) return "";
16
+ return num.toLocaleString("fullwide", { useGrouping: false, maximumFractionDigits: 20 });
17
+ };
2
18
  const isEmpty = (value) => {
3
19
  if (value === null || value === void 0) return true;
4
20
  if (typeof value === "string") return value.trim() === "";
@@ -139,50 +155,28 @@ const setNestedValue = (obj, path, value) => {
139
155
  });
140
156
  return newObj;
141
157
  };
142
- const generateI18nTable = (locale, table, prefix = "") => {
143
- let generatedTable = {};
144
- Object.entries(table).forEach(([key, value]) => {
145
- if (key === locale)
146
- generatedTable[prefix] = value;
147
- else if (typeof value == "object" && !isEmpty(value)) {
148
- let newPrefix;
149
- if (key !== "translation") {
150
- newPrefix = prefix ? prefix + "." + key : key;
151
- } else {
152
- newPrefix = prefix;
153
- }
154
- generatedTable = {
155
- ...generateI18nTable(locale, value, newPrefix),
156
- ...generatedTable
157
- };
158
+ function extractOperationNames(node) {
159
+ const operationNames = [];
160
+ if ("operation" in node && node.operation) {
161
+ const operation = node.operation;
162
+ if ("selections" in operation && Array.isArray(operation.selections)) {
163
+ operation.selections.forEach((selection) => {
164
+ if (selection && typeof selection === "object" && "name" in selection) {
165
+ operationNames.push(selection.name);
166
+ }
167
+ });
158
168
  }
159
- });
160
- return generatedTable;
161
- };
162
- const generateI18nMessage = (locales, table, prefix = "") => {
163
- const translationTable = {};
164
- locales.forEach((locale) => {
165
- translationTable[locale] = generateI18nTable(locale, table, prefix);
166
- });
167
- return translationTable;
168
- };
169
- const mergeI18nMessages = (locales, ...messages) => {
170
- const mergedMessage = {};
171
- locales.forEach((locale) => {
172
- messages.forEach((message) => {
173
- if (!(locale in mergedMessage)) {
174
- mergedMessage[locale] = {};
175
- }
176
- if (locale in message) {
177
- mergedMessage[locale] = {
178
- ...mergedMessage[locale],
179
- ...message[locale]
180
- };
181
- }
182
- });
183
- });
184
- return mergedMessage;
185
- };
169
+ }
170
+ return operationNames;
171
+ }
172
+ function checkOperationsPermission(operationNames, checkWebserviceAccess) {
173
+ if (!operationNames.length) {
174
+ return false;
175
+ }
176
+ return operationNames.every(
177
+ (operationName) => checkWebserviceAccess(operationName)
178
+ );
179
+ }
186
180
  const generateUrl = (path, parameters = {}, queryParameters = {}) => {
187
181
  if (!isEmpty(parameters) && !isEmpty(path)) {
188
182
  const splitPath = path.split("/");
@@ -225,19 +219,89 @@ const generateRouteTable = (appDescription, defaultTransPrefix = "lys.components
225
219
  return generateRouteFromDescription(pageDescription, defaultTransPrefix);
226
220
  });
227
221
  };
222
+ const inferComponentType = (componentName) => {
223
+ if (componentName.endsWith("Feature")) return "features";
224
+ if (componentName.endsWith("Element")) return "elements";
225
+ if (componentName.endsWith("Page")) return "pages";
226
+ if (componentName.endsWith("Restricted")) return "restrictedFeatures";
227
+ if (componentName.endsWith("Provider")) return "providers";
228
+ throw new Error(
229
+ `Cannot infer component type from "${componentName}". Component name must end with: Feature, Element, Page, Restricted, or Provider`
230
+ );
231
+ };
232
+ const toTranslationKey = (componentName) => {
233
+ return componentName.charAt(0).toLowerCase() + componentName.slice(1);
234
+ };
235
+ const createComponentTranslations = (componentName, translations, pathBase = "lys.components.") => {
236
+ const componentType = inferComponentType(componentName);
237
+ const translationKey = toTranslationKey(componentName);
238
+ const translationPath = `${pathBase}${componentType}.${translationKey}`;
239
+ return {
240
+ /**
241
+ * Configuration object for the i18n system
242
+ * Export this in your features/elements/pages/restrictedFeatures index
243
+ */
244
+ config: {
245
+ translation: translations
246
+ },
247
+ /**
248
+ * React hook to use translations in your component
249
+ * Returns an object with type-safe `t()` and `common()` functions
250
+ *
251
+ * @returns Object containing:
252
+ * - t(key, values?): Component-specific translations with optional interpolation
253
+ * - common(key, values?): Shared common translations with optional interpolation
254
+ */
255
+ useTranslations: () => {
256
+ const intl = useIntl();
257
+ return useMemo(() => {
258
+ const t = (key, options) => {
259
+ const id = `${translationPath}.${String(key)}`;
260
+ const result = intl.formatMessage({ id }, options == null ? void 0 : options.values);
261
+ if ((options == null ? void 0 : options.fallbackToKey) && result === id) {
262
+ return String(key);
263
+ }
264
+ return result;
265
+ };
266
+ const common = (key, options) => {
267
+ const id = `lys.services.i18n.common.${String(key)}`;
268
+ const result = intl.formatMessage({ id }, options == null ? void 0 : options.values);
269
+ if ((options == null ? void 0 : options.fallbackToKey) && result === id) {
270
+ return String(key);
271
+ }
272
+ return result;
273
+ };
274
+ return { t, common };
275
+ }, [intl]);
276
+ },
277
+ /**
278
+ * Generated translation path (for debugging)
279
+ */
280
+ translationPath,
281
+ /**
282
+ * Available translation keys (for reference)
283
+ */
284
+ translationKeys: Object.keys(translations)
285
+ };
286
+ };
228
287
  export {
229
- generateRouteFromDescription as a,
230
- generateRouteTable as b,
231
- cleanParameters as c,
232
- generateUrl as d,
288
+ cleanParameters as a,
289
+ cn as b,
290
+ checkOperationsPermission as c,
291
+ createComponentTranslations as d,
233
292
  emailRegex as e,
234
- generateUrlByRoute as f,
235
- generateI18nMessage as g,
236
- getNestedValue as h,
237
- isEmpty as i,
238
- mergeI18nMessages as m,
293
+ extractOperationNames as f,
294
+ generateRouteFromDescription as g,
295
+ generateRouteTable as h,
296
+ generateUrl as i,
297
+ generateUrlByRoute as j,
298
+ getNestedValue as k,
299
+ isEmpty as l,
300
+ lowerCaseFirstLetter as m,
301
+ numberToString as n,
239
302
  passwordRegex as p,
240
303
  setNestedValue as s,
304
+ toSnakeCase as t,
241
305
  validators as v
242
306
  };
243
- //# sourceMappingURL=routeTools-BVJY3epS.js.map
307
+ //# sourceMappingURL=translationTools-RWoOzX2m.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translationTools-RWoOzX2m.js","sources":["../src/tools/stringTools.ts","../src/tools/validationTools.ts","../src/tools/relayTools.ts","../src/tools/routeTools.ts","../src/tools/translationTools.ts"],"sourcesContent":["/**\n * Convert first letter of string to lowercase\n */\nexport const lowerCaseFirstLetter = (str: string) => {\n return str.charAt(0).toLowerCase() + str.slice(1);\n}\n\n/**\n * Combine multiple classnames into a single string\n * Filters out falsy values\n */\nexport const cn = (...classes: (string | undefined | null | false)[]) => {\n return classes.filter(Boolean).join(' ');\n}\n\n/**\n * Convert camelCase string to snake_case\n */\nexport const toSnakeCase = (str: string): string => {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * Convert number to string without scientific notation\n */\nexport const numberToString = (value: number | string | null | undefined): string => {\n if (value == null) return \"\";\n const num = typeof value === \"string\" ? parseFloat(value) : value;\n if (isNaN(num)) return \"\";\n return num.toLocaleString(\"fullwide\", {useGrouping: false, maximumFractionDigits: 20});\n}\n","/**\n * Validation utilities for form fields\n */\n\n/**\n * Check if a value is empty\n */\nexport const isEmpty = (value: unknown): boolean => {\n if (value === null || value === undefined) return true;\n if (typeof value === 'string') return value.trim() === '';\n if (Array.isArray(value)) return value.length === 0;\n if (typeof value === 'object') return Object.keys(value).length === 0;\n return false;\n};\n\n/**\n * Password validation regex patterns\n * Exported for reuse in other components\n */\nexport const passwordRegex = {\n lowercase: /^(?=.*[a-z]).*$/,\n uppercase: /^(?=.*[A-Z]).*$/,\n number: /^(?=.*[0-9]).*$/,\n minLength8: /^.{8,}$/,\n minLength12: /^.{12,}$/,\n specialChar: /[#?!@$%^&*-]/,\n};\n\n/**\n * Email validation regex\n */\nexport const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\n/**\n * Validator function type\n */\nexport type ValidatorFunction = (value: string | number | string[] | undefined) => boolean;\n\n/**\n * Validator with error message\n */\nexport interface Validator {\n method: ValidatorFunction;\n errorMessage: string;\n}\n\n/**\n * Pre-built validators\n */\nexport const validators = {\n /**\n * Validate that a field is not empty\n */\n required: (errorMessage: string): Validator => ({\n method: (value) => !isEmpty(value),\n errorMessage,\n }),\n\n /**\n * Validate email format\n */\n email: (errorMessage: string): Validator => ({\n method: (value) => {\n if (isEmpty(value)) return true; // Use required validator separately\n return emailRegex.test(String(value));\n },\n errorMessage,\n }),\n\n /**\n * Validate minimum length\n */\n minLength: (min: number, errorMessage: string): Validator => ({\n method: (value) => {\n if (isEmpty(value)) return true;\n return String(value).length >= min;\n },\n errorMessage,\n }),\n\n /**\n * Validate maximum length\n */\n maxLength: (max: number, errorMessage: string): Validator => ({\n method: (value) => {\n if (isEmpty(value)) return true;\n return String(value).length <= max;\n },\n errorMessage,\n }),\n\n /**\n * Validate pattern\n */\n pattern: (regex: RegExp, errorMessage: string): Validator => ({\n method: (value) => {\n if (isEmpty(value)) return true;\n return regex.test(String(value));\n },\n errorMessage,\n }),\n\n /**\n * Validate minimum value for numbers\n */\n min: (min: number, errorMessage: string): Validator => ({\n method: (value) => {\n if (isEmpty(value)) return true;\n return Number(value) >= min;\n },\n errorMessage,\n }),\n\n /**\n * Validate maximum value for numbers\n */\n max: (max: number, errorMessage: string): Validator => ({\n method: (value) => {\n if (isEmpty(value)) return true;\n return Number(value) <= max;\n },\n errorMessage,\n }),\n\n /**\n * Custom validator\n */\n custom: (method: ValidatorFunction, errorMessage: string): Validator => ({\n method,\n errorMessage,\n }),\n};\n\n/**\n * Clean parameters by trimming strings and converting empty strings to undefined\n */\nexport const cleanParameters = (parameters: Record<string, unknown>): Record<string, unknown> => {\n const newParameters: Record<string, unknown> = {};\n\n Object.keys(parameters).forEach((key) => {\n const element = parameters[key];\n if (typeof element === \"object\" && element !== null && !Array.isArray(element)) {\n newParameters[key] = cleanParameters(element as Record<string, unknown>);\n } else if (typeof element === \"string\") {\n if (isEmpty(element)) {\n newParameters[key] = undefined;\n } else {\n newParameters[key] = element.trim();\n }\n } else {\n newParameters[key] = element;\n }\n });\n\n return newParameters;\n};\n\n/**\n * Get nested value from object using dot notation\n */\nexport const getNestedValue = (\n obj: Record<string, unknown>,\n path: string\n): string | number | string[] | undefined => {\n const keys = path.split(\".\");\n let result: unknown = obj;\n\n for (const key of keys) {\n if (result !== undefined && typeof result === \"object\" && result !== null && !Array.isArray(result)) {\n result = (result as Record<string, unknown>)[key];\n } else {\n return undefined;\n }\n }\n\n return result as string | number | string[] | undefined;\n};\n\n/**\n * Set nested value in object using dot notation\n */\nexport const setNestedValue = (\n obj: Record<string, unknown>,\n path: string,\n value: unknown\n): Record<string, unknown> => {\n const keys = path.split(\".\");\n const newObj: Record<string, unknown> = { ...obj };\n let current: Record<string, unknown> = newObj;\n\n keys.forEach((key, index) => {\n if (index === keys.length - 1) {\n current[key] = value;\n } else {\n if (!current[key] || typeof current[key] !== \"object\") {\n current[key] = {};\n } else {\n current[key] = { ...(current[key] as Record<string, unknown>) };\n }\n current = current[key] as Record<string, unknown>;\n }\n });\n\n return newObj;\n};\n","import {GraphQLTaggedNode} from \"relay-runtime\";\n\n/**\n * Extract operation names from a GraphQL query or mutation\n * Used for permission checking based on webservice names\n */\nexport function extractOperationNames(node: GraphQLTaggedNode): string[] {\n const operationNames: string[] = [];\n\n if ('operation' in node && node.operation) {\n const operation = node.operation as unknown as Record<string, unknown>;\n if ('selections' in operation && Array.isArray(operation.selections)) {\n operation.selections.forEach((selection) => {\n if (selection && typeof selection === 'object' && 'name' in selection) {\n operationNames.push(selection.name as string);\n }\n });\n }\n }\n\n return operationNames;\n}\n\n/**\n * Check if user has permission to access all operations\n * Note: checkWebserviceAccess handles snake_case conversion internally\n */\nexport function checkOperationsPermission(\n operationNames: string[],\n checkWebserviceAccess: (name: string) => boolean\n): boolean {\n if (!operationNames.length) {\n return false;\n }\n\n return operationNames.every(operationName =>\n checkWebserviceAccess(operationName)\n );\n}\n","import {RouteInterface} from \"../types/routeTypes\";\nimport {PageDescriptionType} from \"../types/descriptionTypes\";\nimport {lowerCaseFirstLetter} from \"./stringTools\";\nimport {isEmpty} from \"./validationTools\";\nimport type {AppDescription} from \"../types/relayTypes\";\n\n/**\n * Generate URL by replacing path parameters with provided values\n * @param path - URL path with placeholders (e.g., \"/user/:id\")\n * @param parameters - Object with path parameter values to substitute\n * @param queryParameters - Object with query parameter values to append\n * @returns Generated URL with replaced parameters and query string\n */\nexport const generateUrl = (\n path: string,\n parameters: {[key: string]: string} = {},\n queryParameters: {[key: string]: string} = {}\n) => {\n if (!isEmpty(parameters) && !isEmpty(path)) {\n const splitPath = path.split('/');\n Object.keys(splitPath).forEach(pathKey => {\n Object.keys(parameters).forEach(key => {\n if ( splitPath[parseInt(pathKey)] === ':' + key) {\n splitPath[parseInt(pathKey)] = parameters[key];\n }\n });\n });\n path = splitPath.join('/');\n }\n\n // Append query parameters if provided\n if (!isEmpty(queryParameters)) {\n const queryString = new URLSearchParams(queryParameters).toString();\n path = `${path}?${queryString}`;\n }\n\n return path;\n}\n\n/**\n * Generate URL from route using path and query parameters\n */\nexport const generateUrlByRoute = (\n route: RouteInterface,\n parameters: {[key: string]: string} = {},\n queryParameters: {[key: string]: string} = {}\n) => {\n return generateUrl(route.path, parameters, queryParameters)\n}\n\n/**\n * Convert page description to route interface\n */\nexport const generateRouteFromDescription = (\n pageDescription: PageDescriptionType,\n defaultTransPrefix: string = \"lys.components.pages.\"\n): RouteInterface => {\n return {\n name: pageDescription.name,\n transPrefix: defaultTransPrefix + lowerCaseFirstLetter(pageDescription.name) + \".\",\n path: pageDescription.path,\n component: pageDescription.component,\n template: pageDescription.template,\n type: pageDescription.type,\n breadcrumbs: pageDescription.breadcrumbs,\n options: pageDescription.options,\n mainWebserviceName: pageDescription.mainWebserviceName,\n }\n}\n\n/**\n * Generate route table from app description\n */\nexport const generateRouteTable = (\n appDescription: AppDescription,\n defaultTransPrefix: string = \"lys.components.pages.\"\n): RouteInterface[] => {\n const pages: {[key: string]: PageDescriptionType} = appDescription?.components?.pages ?? {}\n\n return Object.keys(pages).map((pageName) => {\n const pageDescription: PageDescriptionType = pages[pageName];\n\n return generateRouteFromDescription(pageDescription, defaultTransPrefix)\n })\n}\n","import {useMemo} from \"react\";\nimport {useIntl} from \"react-intl\";\nimport {ComponentDescriptionType} from \"../types/descriptionTypes\";\nimport {TranslationType} from \"../types/i18nTypes\";\nimport {I18nLocaleEnum} from \"../types/i18nTypes\";\n\n/**\n * Infers component type from component name based on naming convention\n * - ends with \"Feature\" -> \"features\"\n * - ends with \"Element\" -> \"elements\"\n * - ends with \"Page\" -> \"pages\"\n * - ends with \"Restricted\" -> \"restrictedFeatures\"\n * - ends with \"Provider\" -> \"providers\"\n */\nconst inferComponentType = (componentName: string): string => {\n if (componentName.endsWith(\"Feature\")) return \"features\";\n if (componentName.endsWith(\"Element\")) return \"elements\";\n if (componentName.endsWith(\"Page\")) return \"pages\";\n if (componentName.endsWith(\"Restricted\")) return \"restrictedFeatures\";\n if (componentName.endsWith(\"Provider\")) return \"providers\";\n\n throw new Error(\n `Cannot infer component type from \"${componentName}\". ` +\n `Component name must end with: Feature, Element, Page, Restricted, or Provider`\n );\n};\n\n/**\n * Converts component name to translation key format\n * LoginFeature -> loginFeature\n * ButtonElement -> buttonElement\n */\nconst toTranslationKey = (componentName: string): string => {\n return componentName.charAt(0).toLowerCase() + componentName.slice(1);\n};\n\n/**\n * Creates a component translation configuration with typed helper hook\n *\n * Supports all languages defined in I18nLocaleEnum. TypeScript will enforce\n * that all translations include every language.\n *\n * @param componentName - Component name (e.g., \"LoginFeature\", \"ButtonElement\")\n * @param translations - Translation object with keys in format {key: Record<I18nLocaleEnum, string>}\n * @param pathBase - Base path for translations (default: \"lys.components.\")\n * @returns Object with config for i18n system and useTranslations hook\n *\n * @example\n * ```typescript\n * // In LoginFeature/translations.ts\n * const {config, useTranslations} = createComponentTranslations(\n * \"LoginFeature\",\n * {\n * email: {en: \"Email\", fr: \"Email\"},\n * password: {en: \"Password\", fr: \"Mot de passe\"}\n * }\n * );\n *\n * export const loginFeatureConfig = config;\n * export const useLoginTranslations = useTranslations;\n *\n * // In LoginFeature/index.tsx\n * const {t} = useLoginTranslations();\n * const label = t(\"email\"); // Type-safe!\n * ```\n */\nexport const createComponentTranslations = <\n T extends Record<string, Record<I18nLocaleEnum, string>>,\n TCommonKey extends string = string\n>(\n componentName: string,\n translations: T,\n pathBase: string = \"lys.components.\"\n) => {\n const componentType = inferComponentType(componentName);\n const translationKey = toTranslationKey(componentName);\n const translationPath = `${pathBase}${componentType}.${translationKey}`;\n\n return {\n /**\n * Configuration object for the i18n system\n * Export this in your features/elements/pages/restrictedFeatures index\n */\n config: {\n translation: translations as TranslationType\n } satisfies ComponentDescriptionType,\n\n /**\n * React hook to use translations in your component\n * Returns an object with type-safe `t()` and `common()` functions\n *\n * @returns Object containing:\n * - t(key, values?): Component-specific translations with optional interpolation\n * - common(key, values?): Shared common translations with optional interpolation\n */\n useTranslations: () => {\n const intl = useIntl();\n\n return useMemo(() => {\n /**\n * Translate a component-specific key\n * @param key - Translation key (autocompleted)\n * @param options - Optional: values for interpolation, fallbackToKey to return raw key if not found\n */\n const t = (key: keyof T, options?: {\n values?: Record<string, string | number>,\n fallbackToKey?: boolean\n }): string => {\n const id = `${translationPath}.${String(key)}`;\n const result = intl.formatMessage({id}, options?.values);\n if (options?.fallbackToKey && result === id) {\n return String(key);\n }\n return result;\n };\n\n /**\n * Translate a common/shared key\n * @param key - Common translation key (autocompleted)\n * @param options - Optional: values for interpolation, fallbackToKey to return raw key if not found\n */\n const common = (key: TCommonKey, options?: {\n values?: Record<string, string | number>,\n fallbackToKey?: boolean\n }): string => {\n const id = `lys.services.i18n.common.${String(key)}`;\n const result = intl.formatMessage({id}, options?.values);\n if (options?.fallbackToKey && result === id) {\n return String(key);\n }\n return result;\n };\n\n return {t, common};\n }, [intl]);\n },\n\n /**\n * Generated translation path (for debugging)\n */\n translationPath,\n\n /**\n * Available translation keys (for reference)\n */\n translationKeys: Object.keys(translations) as Array<keyof T>\n };\n};\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runid-lys",
3
- "version": "0.4.2",
3
+ "version": "0.5.0",
4
4
  "description": "Frontend framework library for the lys ecosystem — providers, hooks, tools, and types for React applications",
5
5
  "keywords": [
6
6
  "react",
@@ -1 +0,0 @@
1
- {"version":3,"file":"PublicAppTemplate-SRJ1HtD0.js","sources":["../src/templates/PublicAppTemplate.tsx"],"sourcesContent":["import * as React from \"react\";\nimport {useEffect} from \"react\";\nimport {useNavigate} from \"react-router-dom\";\nimport {useConnectedUserInfo} from \"../providers/ConnectedUserProvider/hooks\";\nimport {useChatbot} from \"../providers/ChatbotProvider/hooks\";\nimport {RouteInterface} from \"../types/routeTypes\";\n\ninterface PublicAppTemplateProps {\n route: RouteInterface\n defaultPrivateRoute: RouteInterface\n defaultPublicRoute: RouteInterface\n children: React.ReactNode\n}\n\n/**\n * Public app template\n * Wraps public pages and redirects authenticated users to private area\n * Unless route.options?.opened is true (public pages accessible when connected)\n */\nconst PublicAppTemplate: React.ComponentType<PublicAppTemplateProps> = (\n {\n route,\n defaultPrivateRoute,\n children\n }) => {\n\n /*******************************************************************************************************************\n * HOOKS\n ******************************************************************************************************************/\n\n const navigate = useNavigate();\n const {user} = useConnectedUserInfo();\n const {setIsChatbotEnabled} = useChatbot();\n\n /*******************************************************************************************************************\n * EFFECTS\n ******************************************************************************************************************/\n\n // Disable chatbot on public pages\n useEffect(() => {\n setIsChatbotEnabled(false);\n return () => setIsChatbotEnabled(true);\n }, [setIsChatbotEnabled]);\n\n // Redirect authenticated users to private area (unless page is opened)\n useEffect(() => {\n const isOpened = route.options?.opened === true;\n\n if (user && !isOpened) {\n navigate(defaultPrivateRoute.path);\n }\n }, [user, route.options, defaultPrivateRoute.path, navigate]);\n\n /*******************************************************************************************************************\n * RENDER\n ******************************************************************************************************************/\n\n return (\n <>\n {children}\n </>\n );\n};\n\nexport default PublicAppTemplate;\n"],"names":[],"mappings":";;;;AAmBA,MAAM,oBAAiE,CACnE;AAAA,EACI;AAAA,EACA;AAAA,EACA;AACJ,MAAM;AAMN,QAAM,WAAW,YAAA;AACjB,QAAM,EAAC,KAAA,IAAQ,qBAAA;AACf,QAAM,EAAC,oBAAA,IAAuB,WAAA;AAO9B,YAAU,MAAM;AACZ,wBAAoB,KAAK;AACzB,WAAO,MAAM,oBAAoB,IAAI;AAAA,EACzC,GAAG,CAAC,mBAAmB,CAAC;AAGxB,YAAU,MAAM;;AACZ,UAAM,aAAW,WAAM,YAAN,mBAAe,YAAW;AAE3C,QAAI,QAAQ,CAAC,UAAU;AACnB,eAAS,oBAAoB,IAAI;AAAA,IACrC;AAAA,EACJ,GAAG,CAAC,MAAM,MAAM,SAAS,oBAAoB,MAAM,QAAQ,CAAC;AAM5D,yCAES,UACL;AAER;"}