angular-intlayer 5.7.8 → 5.8.1-canary.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 +1 -1
- package/dist/cjs/client/useIntlayer.cjs.map +1 -1
- package/dist/cjs/editor/createSharedComposable.cjs +2 -2
- package/dist/cjs/editor/createSharedComposable.cjs.map +1 -1
- package/dist/esm/client/useIntlayer.mjs.map +1 -1
- package/dist/esm/editor/createSharedComposable.mjs +2 -2
- package/dist/esm/editor/createSharedComposable.mjs.map +1 -1
- package/dist/types/client/useIntlayer.d.ts +1 -1
- package/package.json +15 -15
package/README.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/client/useIntlayer.ts"],"sourcesContent":["import { computed, inject } from '@angular/core';\nimport type { LocalesValues } from '@intlayer/config/client';\nimport { DictionaryKeys } from '@intlayer/core';\n// @ts-ignore intlayer declared for module augmentation\nimport type { IntlayerDictionaryTypesConnector } from 'intlayer';\nimport { getIntlayer } from '../getIntlayer';\nimport { DeepTransformContent } from '../plugins';\nimport { INTLAYER_TOKEN, IntlayerProvider } from './installIntlayer';\n\n/** guard utility
|
|
1
|
+
{"version":3,"sources":["../../../src/client/useIntlayer.ts"],"sourcesContent":["import { computed, inject } from '@angular/core';\nimport type { LocalesValues } from '@intlayer/config/client';\nimport { DictionaryKeys } from '@intlayer/core';\n// @ts-ignore intlayer declared for module augmentation\nimport type { IntlayerDictionaryTypesConnector } from 'intlayer';\nimport { getIntlayer } from '../getIntlayer';\nimport { DeepTransformContent } from '../plugins';\nimport { INTLAYER_TOKEN, IntlayerProvider } from './installIntlayer';\n\n/** guard utility - true only for objects generated by `renderIntlayerNode()` */\nexport const isUpdatableNode = (\n val: unknown\n): val is { __update: (n: unknown) => void } =>\n !!val &&\n typeof val === 'object' &&\n typeof (val as any).__update === 'function';\n\nexport const useIntlayer = <T extends DictionaryKeys>(\n key: T,\n locale?: LocalesValues\n): DeepTransformContent<IntlayerDictionaryTypesConnector[T]['content']> => {\n const intlayer = inject<IntlayerProvider>(INTLAYER_TOKEN)!;\n\n /** which locale should we use right now? */\n const localeTarget = computed(() => locale ?? intlayer.locale());\n\n /** a *stable* reactive dictionary object */\n const content = computed(() => getIntlayer(key, localeTarget()));\n\n return content() as DeepTransformContent<\n IntlayerDictionaryTypesConnector[T]['content']\n >; // all consumers keep full reactivity\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiC;AAKjC,yBAA4B;AAE5B,6BAAiD;AAG1C,MAAM,kBAAkB,CAC7B,QAEA,CAAC,CAAC,OACF,OAAO,QAAQ,YACf,OAAQ,IAAY,aAAa;AAE5B,MAAM,cAAc,CACzB,KACA,WACyE;AACzE,QAAM,eAAW,oBAAyB,qCAAc;AAGxD,QAAM,mBAAe,sBAAS,MAAM,UAAU,SAAS,OAAO,CAAC;AAG/D,QAAM,cAAU,sBAAS,UAAM,gCAAY,KAAK,aAAa,CAAC,CAAC;AAE/D,SAAO,QAAQ;AAGjB;","names":[]}
|
|
@@ -47,7 +47,7 @@ const createSharedComposable = (composable) => {
|
|
|
47
47
|
cleanupFn = void 0;
|
|
48
48
|
}
|
|
49
49
|
};
|
|
50
|
-
return (...args) => {
|
|
50
|
+
return ((...args) => {
|
|
51
51
|
subscribers += 1;
|
|
52
52
|
if (!state) {
|
|
53
53
|
state = composable(...args);
|
|
@@ -58,7 +58,7 @@ const createSharedComposable = (composable) => {
|
|
|
58
58
|
tryOnScopeDispose(dispose);
|
|
59
59
|
}
|
|
60
60
|
return state;
|
|
61
|
-
};
|
|
61
|
+
});
|
|
62
62
|
};
|
|
63
63
|
// Annotate the CommonJS export names for ESM import in node:
|
|
64
64
|
0 && (module.exports = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/editor/createSharedComposable.ts"],"sourcesContent":["import { DestroyRef, inject } from '@angular/core';\n\ntype AnyFn = (...args: any[]) => any;\n\nexport type SharedComposableReturn<T extends AnyFn = AnyFn> = T;\n\n/**\n * Angular replacement for Vue's tryOnScopeDispose\n * Uses Angular's DestroyRef to handle cleanup when the injection context is destroyed\n */\nexport function tryOnScopeDispose(fn: () => void) {\n try {\n const destroyRef = inject(DestroyRef, { optional: true });\n if (destroyRef) {\n destroyRef.onDestroy(fn);\n return true;\n }\n return false;\n } catch {\n // If called outside injection context, return false\n return false;\n }\n}\n\n/**\n * Angular equivalent of Vue's createSharedComposable\n * Creates a singleton pattern for services/composables\n */\nexport const createSharedComposable = <Fn extends AnyFn>(\n composable: Fn\n): SharedComposableReturn<Fn> => {\n let subscribers = 0;\n let state: ReturnType<Fn> | undefined;\n let cleanupFn: (() => void) | undefined;\n\n const dispose = () => {\n subscribers -= 1;\n if (cleanupFn && subscribers <= 0) {\n cleanupFn();\n state = undefined;\n cleanupFn = undefined;\n }\n };\n\n return <Fn>((...args) => {\n subscribers += 1;\n if (!state) {\n state = composable(...args);\n // Set up cleanup when the first subscriber is destroyed\n if (tryOnScopeDispose(dispose)) {\n cleanupFn = dispose;\n }\n } else {\n // For additional subscribers, just set up their individual cleanup\n tryOnScopeDispose(dispose);\n }\n return state;\n });\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAmC;AAU5B,SAAS,kBAAkB,IAAgB;AAChD,MAAI;AACF,UAAM,iBAAa,oBAAO,wBAAY,EAAE,UAAU,KAAK,CAAC;AACxD,QAAI,YAAY;AACd,iBAAW,UAAU,EAAE;AACvB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAMO,MAAM,yBAAyB,CACpC,eAC+B;AAC/B,MAAI,cAAc;AAClB,MAAI;AACJ,MAAI;AAEJ,QAAM,UAAU,MAAM;AACpB,mBAAe;AACf,QAAI,aAAa,eAAe,GAAG;AACjC,gBAAU;AACV,cAAQ;AACR,kBAAY;AAAA,IACd;AAAA,EACF;AAEA,
|
|
1
|
+
{"version":3,"sources":["../../../src/editor/createSharedComposable.ts"],"sourcesContent":["import { DestroyRef, inject } from '@angular/core';\n\ntype AnyFn = (...args: any[]) => any;\n\nexport type SharedComposableReturn<T extends AnyFn = AnyFn> = T;\n\n/**\n * Angular replacement for Vue's tryOnScopeDispose\n * Uses Angular's DestroyRef to handle cleanup when the injection context is destroyed\n */\nexport function tryOnScopeDispose(fn: () => void) {\n try {\n const destroyRef = inject(DestroyRef, { optional: true });\n if (destroyRef) {\n destroyRef.onDestroy(fn);\n return true;\n }\n return false;\n } catch {\n // If called outside injection context, return false\n return false;\n }\n}\n\n/**\n * Angular equivalent of Vue's createSharedComposable\n * Creates a singleton pattern for services/composables\n */\nexport const createSharedComposable = <Fn extends AnyFn>(\n composable: Fn\n): SharedComposableReturn<Fn> => {\n let subscribers = 0;\n let state: ReturnType<Fn> | undefined;\n let cleanupFn: (() => void) | undefined;\n\n const dispose = () => {\n subscribers -= 1;\n if (cleanupFn && subscribers <= 0) {\n cleanupFn();\n state = undefined;\n cleanupFn = undefined;\n }\n };\n\n return <Fn>((...args) => {\n subscribers += 1;\n if (!state) {\n state = composable(...args);\n // Set up cleanup when the first subscriber is destroyed\n if (tryOnScopeDispose(dispose)) {\n cleanupFn = dispose;\n }\n } else {\n // For additional subscribers, just set up their individual cleanup\n tryOnScopeDispose(dispose);\n }\n return state;\n });\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAmC;AAU5B,SAAS,kBAAkB,IAAgB;AAChD,MAAI;AACF,UAAM,iBAAa,oBAAO,wBAAY,EAAE,UAAU,KAAK,CAAC;AACxD,QAAI,YAAY;AACd,iBAAW,UAAU,EAAE;AACvB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAMO,MAAM,yBAAyB,CACpC,eAC+B;AAC/B,MAAI,cAAc;AAClB,MAAI;AACJ,MAAI;AAEJ,QAAM,UAAU,MAAM;AACpB,mBAAe;AACf,QAAI,aAAa,eAAe,GAAG;AACjC,gBAAU;AACV,cAAQ;AACR,kBAAY;AAAA,IACd;AAAA,EACF;AAEA,UAAY,IAAI,SAAS;AACvB,mBAAe;AACf,QAAI,CAAC,OAAO;AACV,cAAQ,WAAW,GAAG,IAAI;AAE1B,UAAI,kBAAkB,OAAO,GAAG;AAC9B,oBAAY;AAAA,MACd;AAAA,IACF,OAAO;AAEL,wBAAkB,OAAO;AAAA,IAC3B;AACA,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/client/useIntlayer.ts"],"sourcesContent":["import { computed, inject } from '@angular/core';\nimport type { LocalesValues } from '@intlayer/config/client';\nimport { DictionaryKeys } from '@intlayer/core';\n// @ts-ignore intlayer declared for module augmentation\nimport type { IntlayerDictionaryTypesConnector } from 'intlayer';\nimport { getIntlayer } from '../getIntlayer';\nimport { DeepTransformContent } from '../plugins';\nimport { INTLAYER_TOKEN, IntlayerProvider } from './installIntlayer';\n\n/** guard utility
|
|
1
|
+
{"version":3,"sources":["../../../src/client/useIntlayer.ts"],"sourcesContent":["import { computed, inject } from '@angular/core';\nimport type { LocalesValues } from '@intlayer/config/client';\nimport { DictionaryKeys } from '@intlayer/core';\n// @ts-ignore intlayer declared for module augmentation\nimport type { IntlayerDictionaryTypesConnector } from 'intlayer';\nimport { getIntlayer } from '../getIntlayer';\nimport { DeepTransformContent } from '../plugins';\nimport { INTLAYER_TOKEN, IntlayerProvider } from './installIntlayer';\n\n/** guard utility - true only for objects generated by `renderIntlayerNode()` */\nexport const isUpdatableNode = (\n val: unknown\n): val is { __update: (n: unknown) => void } =>\n !!val &&\n typeof val === 'object' &&\n typeof (val as any).__update === 'function';\n\nexport const useIntlayer = <T extends DictionaryKeys>(\n key: T,\n locale?: LocalesValues\n): DeepTransformContent<IntlayerDictionaryTypesConnector[T]['content']> => {\n const intlayer = inject<IntlayerProvider>(INTLAYER_TOKEN)!;\n\n /** which locale should we use right now? */\n const localeTarget = computed(() => locale ?? intlayer.locale());\n\n /** a *stable* reactive dictionary object */\n const content = computed(() => getIntlayer(key, localeTarget()));\n\n return content() as DeepTransformContent<\n IntlayerDictionaryTypesConnector[T]['content']\n >; // all consumers keep full reactivity\n};\n"],"mappings":"AAAA,SAAS,UAAU,cAAc;AAKjC,SAAS,mBAAmB;AAE5B,SAAS,sBAAwC;AAG1C,MAAM,kBAAkB,CAC7B,QAEA,CAAC,CAAC,OACF,OAAO,QAAQ,YACf,OAAQ,IAAY,aAAa;AAE5B,MAAM,cAAc,CACzB,KACA,WACyE;AACzE,QAAM,WAAW,OAAyB,cAAc;AAGxD,QAAM,eAAe,SAAS,MAAM,UAAU,SAAS,OAAO,CAAC;AAG/D,QAAM,UAAU,SAAS,MAAM,YAAY,KAAK,aAAa,CAAC,CAAC;AAE/D,SAAO,QAAQ;AAGjB;","names":[]}
|
|
@@ -23,7 +23,7 @@ const createSharedComposable = (composable) => {
|
|
|
23
23
|
cleanupFn = void 0;
|
|
24
24
|
}
|
|
25
25
|
};
|
|
26
|
-
return (...args) => {
|
|
26
|
+
return ((...args) => {
|
|
27
27
|
subscribers += 1;
|
|
28
28
|
if (!state) {
|
|
29
29
|
state = composable(...args);
|
|
@@ -34,7 +34,7 @@ const createSharedComposable = (composable) => {
|
|
|
34
34
|
tryOnScopeDispose(dispose);
|
|
35
35
|
}
|
|
36
36
|
return state;
|
|
37
|
-
};
|
|
37
|
+
});
|
|
38
38
|
};
|
|
39
39
|
export {
|
|
40
40
|
createSharedComposable,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/editor/createSharedComposable.ts"],"sourcesContent":["import { DestroyRef, inject } from '@angular/core';\n\ntype AnyFn = (...args: any[]) => any;\n\nexport type SharedComposableReturn<T extends AnyFn = AnyFn> = T;\n\n/**\n * Angular replacement for Vue's tryOnScopeDispose\n * Uses Angular's DestroyRef to handle cleanup when the injection context is destroyed\n */\nexport function tryOnScopeDispose(fn: () => void) {\n try {\n const destroyRef = inject(DestroyRef, { optional: true });\n if (destroyRef) {\n destroyRef.onDestroy(fn);\n return true;\n }\n return false;\n } catch {\n // If called outside injection context, return false\n return false;\n }\n}\n\n/**\n * Angular equivalent of Vue's createSharedComposable\n * Creates a singleton pattern for services/composables\n */\nexport const createSharedComposable = <Fn extends AnyFn>(\n composable: Fn\n): SharedComposableReturn<Fn> => {\n let subscribers = 0;\n let state: ReturnType<Fn> | undefined;\n let cleanupFn: (() => void) | undefined;\n\n const dispose = () => {\n subscribers -= 1;\n if (cleanupFn && subscribers <= 0) {\n cleanupFn();\n state = undefined;\n cleanupFn = undefined;\n }\n };\n\n return <Fn>((...args) => {\n subscribers += 1;\n if (!state) {\n state = composable(...args);\n // Set up cleanup when the first subscriber is destroyed\n if (tryOnScopeDispose(dispose)) {\n cleanupFn = dispose;\n }\n } else {\n // For additional subscribers, just set up their individual cleanup\n tryOnScopeDispose(dispose);\n }\n return state;\n });\n};\n"],"mappings":"AAAA,SAAS,YAAY,cAAc;AAU5B,SAAS,kBAAkB,IAAgB;AAChD,MAAI;AACF,UAAM,aAAa,OAAO,YAAY,EAAE,UAAU,KAAK,CAAC;AACxD,QAAI,YAAY;AACd,iBAAW,UAAU,EAAE;AACvB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAMO,MAAM,yBAAyB,CACpC,eAC+B;AAC/B,MAAI,cAAc;AAClB,MAAI;AACJ,MAAI;AAEJ,QAAM,UAAU,MAAM;AACpB,mBAAe;AACf,QAAI,aAAa,eAAe,GAAG;AACjC,gBAAU;AACV,cAAQ;AACR,kBAAY;AAAA,IACd;AAAA,EACF;AAEA,
|
|
1
|
+
{"version":3,"sources":["../../../src/editor/createSharedComposable.ts"],"sourcesContent":["import { DestroyRef, inject } from '@angular/core';\n\ntype AnyFn = (...args: any[]) => any;\n\nexport type SharedComposableReturn<T extends AnyFn = AnyFn> = T;\n\n/**\n * Angular replacement for Vue's tryOnScopeDispose\n * Uses Angular's DestroyRef to handle cleanup when the injection context is destroyed\n */\nexport function tryOnScopeDispose(fn: () => void) {\n try {\n const destroyRef = inject(DestroyRef, { optional: true });\n if (destroyRef) {\n destroyRef.onDestroy(fn);\n return true;\n }\n return false;\n } catch {\n // If called outside injection context, return false\n return false;\n }\n}\n\n/**\n * Angular equivalent of Vue's createSharedComposable\n * Creates a singleton pattern for services/composables\n */\nexport const createSharedComposable = <Fn extends AnyFn>(\n composable: Fn\n): SharedComposableReturn<Fn> => {\n let subscribers = 0;\n let state: ReturnType<Fn> | undefined;\n let cleanupFn: (() => void) | undefined;\n\n const dispose = () => {\n subscribers -= 1;\n if (cleanupFn && subscribers <= 0) {\n cleanupFn();\n state = undefined;\n cleanupFn = undefined;\n }\n };\n\n return <Fn>((...args) => {\n subscribers += 1;\n if (!state) {\n state = composable(...args);\n // Set up cleanup when the first subscriber is destroyed\n if (tryOnScopeDispose(dispose)) {\n cleanupFn = dispose;\n }\n } else {\n // For additional subscribers, just set up their individual cleanup\n tryOnScopeDispose(dispose);\n }\n return state;\n });\n};\n"],"mappings":"AAAA,SAAS,YAAY,cAAc;AAU5B,SAAS,kBAAkB,IAAgB;AAChD,MAAI;AACF,UAAM,aAAa,OAAO,YAAY,EAAE,UAAU,KAAK,CAAC;AACxD,QAAI,YAAY;AACd,iBAAW,UAAU,EAAE;AACvB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAMO,MAAM,yBAAyB,CACpC,eAC+B;AAC/B,MAAI,cAAc;AAClB,MAAI;AACJ,MAAI;AAEJ,QAAM,UAAU,MAAM;AACpB,mBAAe;AACf,QAAI,aAAa,eAAe,GAAG;AACjC,gBAAU;AACV,cAAQ;AACR,kBAAY;AAAA,IACd;AAAA,EACF;AAEA,UAAY,IAAI,SAAS;AACvB,mBAAe;AACf,QAAI,CAAC,OAAO;AACV,cAAQ,WAAW,GAAG,IAAI;AAE1B,UAAI,kBAAkB,OAAO,GAAG;AAC9B,oBAAY;AAAA,MACd;AAAA,IACF,OAAO;AAEL,wBAAkB,OAAO;AAAA,IAC3B;AACA,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -2,7 +2,7 @@ import type { LocalesValues } from '@intlayer/config/client';
|
|
|
2
2
|
import { DictionaryKeys } from '@intlayer/core';
|
|
3
3
|
import type { IntlayerDictionaryTypesConnector } from 'intlayer';
|
|
4
4
|
import { DeepTransformContent } from '../plugins';
|
|
5
|
-
/** guard utility
|
|
5
|
+
/** guard utility - true only for objects generated by `renderIntlayerNode()` */
|
|
6
6
|
export declare const isUpdatableNode: (val: unknown) => val is {
|
|
7
7
|
__update: (n: unknown) => void;
|
|
8
8
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "angular-intlayer",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.8.1-canary.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Easily internationalize i18n your Angular applications with type-safe multilingual content management.",
|
|
6
6
|
"keywords": [
|
|
@@ -64,27 +64,27 @@
|
|
|
64
64
|
"deepmerge": "^4.3.1",
|
|
65
65
|
"js-cookie": "^3.0.5",
|
|
66
66
|
"uuid": "^11.1.0",
|
|
67
|
-
"@intlayer/
|
|
68
|
-
"@intlayer/
|
|
69
|
-
"@intlayer/
|
|
70
|
-
"@intlayer/
|
|
71
|
-
"@intlayer/
|
|
72
|
-
"@intlayer/
|
|
67
|
+
"@intlayer/core": "5.8.1-canary.0",
|
|
68
|
+
"@intlayer/chokidar": "5.8.1-canary.0",
|
|
69
|
+
"@intlayer/dictionaries-entry": "5.8.1-canary.0",
|
|
70
|
+
"@intlayer/config": "5.8.1-canary.0",
|
|
71
|
+
"@intlayer/editor": "5.8.1-canary.0",
|
|
72
|
+
"@intlayer/webpack": "5.8.1-canary.0"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
|
-
"@types/node": "^
|
|
75
|
+
"@types/node": "^24.2.1",
|
|
76
76
|
"@types/webpack": "^5.28.5",
|
|
77
77
|
"@typescript-eslint/parser": "^8.33.1",
|
|
78
78
|
"concurrently": "^9.1.2",
|
|
79
|
-
"eslint": "^9.
|
|
79
|
+
"eslint": "^9.33.0",
|
|
80
80
|
"prettier": "^3.5.3",
|
|
81
81
|
"rimraf": "^6.0.1",
|
|
82
82
|
"tsc-alias": "^1.8.16",
|
|
83
83
|
"tsup": "^8.5.0",
|
|
84
|
-
"typescript": "^5.
|
|
84
|
+
"typescript": "^5.9.2",
|
|
85
85
|
"vitest": "^3.2.2",
|
|
86
|
-
"@utils/ts-config": "1.0.4",
|
|
87
86
|
"@utils/eslint-config": "1.0.4",
|
|
87
|
+
"@utils/ts-config": "1.0.4",
|
|
88
88
|
"@utils/ts-config-types": "1.0.4",
|
|
89
89
|
"@utils/tsup-config": "1.0.4"
|
|
90
90
|
},
|
|
@@ -92,10 +92,10 @@
|
|
|
92
92
|
"@angular/common": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0",
|
|
93
93
|
"@angular/core": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0",
|
|
94
94
|
"rxjs": "^6.0.0 || ^7.0.0",
|
|
95
|
-
"@intlayer/chokidar": "5.
|
|
96
|
-
"@intlayer/config": "5.
|
|
97
|
-
"@intlayer/core": "5.
|
|
98
|
-
"@intlayer/dictionaries-entry": "5.
|
|
95
|
+
"@intlayer/chokidar": "5.8.1-canary.0",
|
|
96
|
+
"@intlayer/config": "5.8.1-canary.0",
|
|
97
|
+
"@intlayer/core": "5.8.1-canary.0",
|
|
98
|
+
"@intlayer/dictionaries-entry": "5.8.1-canary.0"
|
|
99
99
|
},
|
|
100
100
|
"engines": {
|
|
101
101
|
"node": ">=14.18"
|