intlayer-editor 2.1.0 → 2.1.2
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 +8 -8
- package/dist/cjs/client/ContentEditionLayout.cjs +19 -13
- package/dist/cjs/client/ContentEditionLayout.cjs.map +1 -1
- package/dist/cjs/client/ContentEditionLayout.d.ts +1 -0
- package/dist/cjs/client/ContentEditorProvider.cjs +47 -0
- package/dist/cjs/client/ContentEditorProvider.cjs.map +1 -0
- package/dist/cjs/client/ContentEditorProvider.d.ts +23 -0
- package/dist/cjs/client/ContentSelectorWrapper.cjs +14 -1
- package/dist/cjs/client/ContentSelectorWrapper.cjs.map +1 -1
- package/dist/cjs/client/DictionaryEditionDrawer/useEditedContentStore.d.ts +1 -1
- package/dist/cjs/client/index.cjs +3 -1
- package/dist/cjs/client/index.cjs.map +1 -1
- package/dist/cjs/client/index.d.ts +1 -0
- package/dist/cjs/server/processEdition.cjs +61 -63
- package/dist/cjs/server/processEdition.cjs.map +1 -1
- package/dist/esm/client/ContentEditionLayout.d.mts +1 -0
- package/dist/esm/client/ContentEditionLayout.mjs +19 -13
- package/dist/esm/client/ContentEditionLayout.mjs.map +1 -1
- package/dist/esm/client/ContentEditorProvider.d.mts +23 -0
- package/dist/esm/client/ContentEditorProvider.mjs +24 -0
- package/dist/esm/client/ContentEditorProvider.mjs.map +1 -0
- package/dist/esm/client/ContentSelectorWrapper.mjs +15 -2
- package/dist/esm/client/ContentSelectorWrapper.mjs.map +1 -1
- package/dist/esm/client/DictionaryEditionDrawer/useEditedContentStore.d.mts +1 -1
- package/dist/esm/client/index.d.mts +1 -0
- package/dist/esm/client/index.mjs +1 -0
- package/dist/esm/client/index.mjs.map +1 -1
- package/dist/esm/server/processEdition.mjs +61 -63
- package/dist/esm/server/processEdition.mjs.map +1 -1
- package/package.json +17 -17
package/README.md
CHANGED
|
@@ -10,19 +10,19 @@ For more details on how to install the package, see the relevant section below:
|
|
|
10
10
|
|
|
11
11
|
### Integrating with Next.js
|
|
12
12
|
|
|
13
|
-
For integration with Next.js, refer to the [setup guide](https://github.com/aypineau/intlayer/blob/main/docs/
|
|
13
|
+
For integration with Next.js, refer to the [setup guide](https://github.com/aypineau/intlayer/blob/main/docs/docs/intlayer_with_nextjs_en.md).
|
|
14
14
|
|
|
15
15
|
### Integrating with Create React App
|
|
16
16
|
|
|
17
|
-
For integration with Create React App, refer to the [setup guide](https://github.com/aypineau/intlayer/blob/main/docs/
|
|
17
|
+
For integration with Create React App, refer to the [setup guide](https://github.com/aypineau/intlayer/blob/main/docs/docs/intlayer_with_create_react_app_en.md).
|
|
18
18
|
|
|
19
19
|
### Integrating with Vite + React
|
|
20
20
|
|
|
21
|
-
For integration with Vite + React, refer to the [setup guide](https://github.com/aypineau/intlayer/blob/main/docs/intlayer_with_vite+
|
|
21
|
+
For integration with Vite + React, refer to the [setup guide](https://github.com/aypineau/intlayer/blob/main/docs/docs/intlayer_with_vite+react_en.md).
|
|
22
22
|
|
|
23
23
|
## How Intlayer Editor Works
|
|
24
24
|
|
|
25
|
-
Each time you make a change using Intlayer Editor, the server automatically inserts your changes into your [Intlayer declaration files](https://github.com/aypineau/intlayer/blob/main/docs/content_declaration/
|
|
25
|
+
Each time you make a change using Intlayer Editor, the server automatically inserts your changes into your [Intlayer declaration files](https://github.com/aypineau/intlayer/blob/main/docs/docs/content_declaration/get_started_en.md), wherever these files are declared in your project.
|
|
26
26
|
|
|
27
27
|
In this way, you don't have to worry about where the file is declared or about finding your key in your dictionary collection.
|
|
28
28
|
|
|
@@ -54,7 +54,7 @@ const config: IntlayerConfig = {
|
|
|
54
54
|
};
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
-
To see all available parameters, refer to the [configuration documentation](https://github.com/aypineau/intlayer/blob/main/docs/
|
|
57
|
+
To see all available parameters, refer to the [configuration documentation](https://github.com/aypineau/intlayer/blob/main/docs/docs/configuration_en.md).
|
|
58
58
|
|
|
59
59
|
### Start Editing
|
|
60
60
|
|
|
@@ -64,7 +64,7 @@ You can also create a custom script in your `package.json` file:
|
|
|
64
64
|
|
|
65
65
|
```json5
|
|
66
66
|
{
|
|
67
|
-
|
|
67
|
+
scripts: {
|
|
68
68
|
"start:editor": "npx intlayer-editor start",
|
|
69
69
|
},
|
|
70
70
|
}
|
|
@@ -74,8 +74,8 @@ To start both the Next.js server and the Intlayer Editor simultaneously, you can
|
|
|
74
74
|
|
|
75
75
|
```json5
|
|
76
76
|
{
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
scripts: {
|
|
78
|
+
dev: "next dev",
|
|
79
79
|
"start:editor": "npx intlayer-editor start",
|
|
80
80
|
"dev:all": "concurrently \"npm run dev:nextjs\" \"npm run dev:intlayer-editor\"",
|
|
81
81
|
},
|
|
@@ -22,25 +22,31 @@ __export(ContentEditionLayout_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(ContentEditionLayout_exports);
|
|
24
24
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
25
|
+
var import_ContentEditorProvider = require('./ContentEditorProvider.cjs');
|
|
25
26
|
var import_DictionaryEditionDrawer = require('./DictionaryEditionDrawer/index.cjs');
|
|
26
27
|
var import_DictionaryListDrawer = require('./DictionaryListDrawer/index.cjs');
|
|
27
28
|
const ContentEditionLayout = ({
|
|
28
29
|
children,
|
|
29
30
|
locale,
|
|
30
31
|
setLocale,
|
|
31
|
-
localeList
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
35
|
-
|
|
36
|
-
{
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
32
|
+
localeList,
|
|
33
|
+
editorEnabled = true
|
|
34
|
+
}) => {
|
|
35
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ContentEditorProvider.IntlayerEditorProvider, { editorEnabled, children: [
|
|
36
|
+
children,
|
|
37
|
+
editorEnabled && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
38
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
39
|
+
import_DictionaryEditionDrawer.DictionaryEditionDrawerController,
|
|
40
|
+
{
|
|
41
|
+
locale,
|
|
42
|
+
localeList,
|
|
43
|
+
setLocale
|
|
44
|
+
}
|
|
45
|
+
),
|
|
46
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_DictionaryListDrawer.DictionaryListDrawer, {})
|
|
47
|
+
] })
|
|
48
|
+
] }) });
|
|
49
|
+
};
|
|
44
50
|
// Annotate the CommonJS export names for ESM import in node:
|
|
45
51
|
0 && (module.exports = {
|
|
46
52
|
ContentEditionLayout
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/client/ContentEditionLayout.tsx"],"sourcesContent":["import type { Locales } from '@intlayer/config/client';\nimport type { FC, ReactNode } from 'react';\nimport { DictionaryEditionDrawerController } from './DictionaryEditionDrawer/index';\nimport { DictionaryListDrawer } from './DictionaryListDrawer/index';\n\nexport type ContentEditionLayoutProps = {\n children?: ReactNode;\n locale: Locales;\n localeList: Locales[];\n setLocale: (locale: Locales) => void;\n};\n\nexport const ContentEditionLayout: FC<ContentEditionLayoutProps> = ({\n children,\n locale,\n setLocale,\n localeList,\n}) => (\n
|
|
1
|
+
{"version":3,"sources":["../../../src/client/ContentEditionLayout.tsx"],"sourcesContent":["import type { Locales } from '@intlayer/config/client';\nimport type { FC, ReactNode } from 'react';\nimport { IntlayerEditorProvider } from './ContentEditorProvider';\nimport { DictionaryEditionDrawerController } from './DictionaryEditionDrawer/index';\nimport { DictionaryListDrawer } from './DictionaryListDrawer/index';\n\nexport type ContentEditionLayoutProps = {\n children?: ReactNode;\n locale: Locales;\n localeList: Locales[];\n setLocale: (locale: Locales) => void;\n editorEnabled?: boolean;\n};\n\nexport const ContentEditionLayout: FC<ContentEditionLayoutProps> = ({\n children,\n locale,\n setLocale,\n localeList,\n editorEnabled = true,\n}) => {\n return (\n <>\n <IntlayerEditorProvider editorEnabled={editorEnabled}>\n {children}\n\n {editorEnabled && (\n <>\n <DictionaryEditionDrawerController\n locale={locale}\n localeList={localeList}\n setLocale={setLocale}\n />\n <DictionaryListDrawer />\n </>\n )}\n </IntlayerEditorProvider>\n </>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA2BU;AAzBV,mCAAuC;AACvC,qCAAkD;AAClD,kCAAqC;AAU9B,MAAM,uBAAsD,CAAC;AAAA,EAClE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB;AAClB,MAAM;AACJ,SACE,2EACE,uDAAC,uDAAuB,eACrB;AAAA;AAAA,IAEA,iBACC,4EACE;AAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA;AAAA,MACF;AAAA,MACA,4CAAC,oDAAqB;AAAA,OACxB;AAAA,KAEJ,GACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
var ContentEditorProvider_exports = {};
|
|
21
|
+
__export(ContentEditorProvider_exports, {
|
|
22
|
+
IntlayerEditorContext: () => IntlayerEditorContext,
|
|
23
|
+
IntlayerEditorProvider: () => IntlayerEditorProvider,
|
|
24
|
+
useIntlayerEditorContext: () => useIntlayerEditorContext
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(ContentEditorProvider_exports);
|
|
27
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
28
|
+
var import_client = require("@intlayer/config/client");
|
|
29
|
+
var import_react = require("react");
|
|
30
|
+
const IntlayerEditorContext = (0, import_react.createContext)({
|
|
31
|
+
editorEnabled: false
|
|
32
|
+
});
|
|
33
|
+
const useIntlayerEditorContext = () => (0, import_react.useContext)(IntlayerEditorContext);
|
|
34
|
+
const {
|
|
35
|
+
editor: { enabled }
|
|
36
|
+
} = (0, import_client.getConfiguration)();
|
|
37
|
+
const IntlayerEditorProvider = ({
|
|
38
|
+
children,
|
|
39
|
+
editorEnabled = enabled
|
|
40
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IntlayerEditorContext.Provider, { value: { editorEnabled }, children });
|
|
41
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
42
|
+
0 && (module.exports = {
|
|
43
|
+
IntlayerEditorContext,
|
|
44
|
+
IntlayerEditorProvider,
|
|
45
|
+
useIntlayerEditorContext
|
|
46
|
+
});
|
|
47
|
+
//# sourceMappingURL=ContentEditorProvider.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/client/ContentEditorProvider.tsx"],"sourcesContent":["'use client';\n\nimport { getConfiguration } from '@intlayer/config/client';\nimport {\n type PropsWithChildren,\n createContext,\n useContext,\n type FC,\n} from 'react';\n\ntype IntlayerEditorValue = {\n editorEnabled: boolean;\n};\n\n/**\n * Context that store the current locale on the client side\n */\nexport const IntlayerEditorContext = createContext<IntlayerEditorValue>({\n editorEnabled: false,\n});\n\n/**\n * Hook that provides the current locale\n */\nexport const useIntlayerEditorContext = () => useContext(IntlayerEditorContext);\n\nexport type IntlayerEditorProviderProps = PropsWithChildren & {\n editorEnabled?: boolean;\n};\n\nconst {\n editor: { enabled },\n} = getConfiguration();\n\n/**\n * Provider that store the current locale on the client side\n */\nexport const IntlayerEditorProvider: FC<IntlayerEditorProviderProps> = ({\n children,\n editorEnabled = enabled,\n}) => (\n <IntlayerEditorContext.Provider value={{ editorEnabled }}>\n {children}\n </IntlayerEditorContext.Provider>\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyCE;AAvCF,oBAAiC;AACjC,mBAKO;AASA,MAAM,4BAAwB,4BAAmC;AAAA,EACtE,eAAe;AACjB,CAAC;AAKM,MAAM,2BAA2B,UAAM,yBAAW,qBAAqB;AAM9E,MAAM;AAAA,EACJ,QAAQ,EAAE,QAAQ;AACpB,QAAI,gCAAiB;AAKd,MAAM,yBAA0D,CAAC;AAAA,EACtE;AAAA,EACA,gBAAgB;AAClB,MACE,4CAAC,sBAAsB,UAAtB,EAA+B,OAAO,EAAE,cAAc,GACpD,UACH;","names":[]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { PropsWithChildren, FC } from 'react';
|
|
3
|
+
|
|
4
|
+
type IntlayerEditorValue = {
|
|
5
|
+
editorEnabled: boolean;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Context that store the current locale on the client side
|
|
9
|
+
*/
|
|
10
|
+
declare const IntlayerEditorContext: react.Context<IntlayerEditorValue>;
|
|
11
|
+
/**
|
|
12
|
+
* Hook that provides the current locale
|
|
13
|
+
*/
|
|
14
|
+
declare const useIntlayerEditorContext: () => IntlayerEditorValue;
|
|
15
|
+
type IntlayerEditorProviderProps = PropsWithChildren & {
|
|
16
|
+
editorEnabled?: boolean;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Provider that store the current locale on the client side
|
|
20
|
+
*/
|
|
21
|
+
declare const IntlayerEditorProvider: FC<IntlayerEditorProviderProps>;
|
|
22
|
+
|
|
23
|
+
export { IntlayerEditorContext, IntlayerEditorProvider, type IntlayerEditorProviderProps, useIntlayerEditorContext };
|
|
@@ -26,6 +26,7 @@ var import_jsx_runtime = require("react/jsx-runtime");
|
|
|
26
26
|
var import_core = require("@intlayer/core");
|
|
27
27
|
var import_design_system = require("@intlayer/design-system");
|
|
28
28
|
var import_react = require("react");
|
|
29
|
+
var import_ContentEditorProvider = require('./ContentEditorProvider.cjs');
|
|
29
30
|
var import_useDictionaryEditionDrawer = require('./DictionaryEditionDrawer/useDictionaryEditionDrawer.cjs');
|
|
30
31
|
const ContentSelectorWrapper = ({
|
|
31
32
|
children,
|
|
@@ -35,6 +36,7 @@ const ContentSelectorWrapper = ({
|
|
|
35
36
|
}) => {
|
|
36
37
|
const { open, getEditedContentValue, focusedContent, isOpen } = (0, import_useDictionaryEditionDrawer.useDictionaryEditionDrawer)(dictionaryId);
|
|
37
38
|
const editedValue = getEditedContentValue(dictionaryPath, keyPath);
|
|
39
|
+
const { editorEnabled } = (0, import_react.useContext)(import_ContentEditorProvider.IntlayerEditorContext);
|
|
38
40
|
const handleSelect = (0, import_react.useCallback)(
|
|
39
41
|
() => open({
|
|
40
42
|
dictionaryId,
|
|
@@ -44,7 +46,18 @@ const ContentSelectorWrapper = ({
|
|
|
44
46
|
[dictionaryId, dictionaryPath, keyPath, open]
|
|
45
47
|
);
|
|
46
48
|
const isSelected = (isOpen && (focusedContent?.keyPath?.length ?? 0) > 0 && (0, import_core.isSameKeyPath)(focusedContent?.keyPath ?? [], keyPath)) ?? false;
|
|
47
|
-
|
|
49
|
+
if (!editorEnabled) {
|
|
50
|
+
return children;
|
|
51
|
+
}
|
|
52
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
53
|
+
import_design_system.ContentSelector,
|
|
54
|
+
{
|
|
55
|
+
onSelect: handleSelect,
|
|
56
|
+
isSelecting: isSelected,
|
|
57
|
+
popoverContent: "Long press to edit",
|
|
58
|
+
children: editedValue ?? children
|
|
59
|
+
}
|
|
60
|
+
);
|
|
48
61
|
};
|
|
49
62
|
// Annotate the CommonJS export names for ESM import in node:
|
|
50
63
|
0 && (module.exports = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/client/ContentSelectorWrapper.tsx"],"sourcesContent":["'use client';\n\nimport { isSameKeyPath, type KeyPath } from '@intlayer/core';\nimport { ContentSelector } from '@intlayer/design-system';\nimport { useCallback, type FC, type ReactNode } from 'react';\nimport { useDictionaryEditionDrawer } from './DictionaryEditionDrawer/useDictionaryEditionDrawer';\n\ntype ContentSelectorWrapperProps = {\n children: ReactNode;\n dictionaryId: string;\n dictionaryPath: string;\n keyPath: KeyPath[];\n};\n\nexport const ContentSelectorWrapper: FC<ContentSelectorWrapperProps> = ({\n children,\n dictionaryId,\n dictionaryPath,\n keyPath,\n}) => {\n const { open, getEditedContentValue, focusedContent, isOpen } =\n useDictionaryEditionDrawer(dictionaryId);\n const editedValue = getEditedContentValue(dictionaryPath, keyPath);\n\n const handleSelect = useCallback(\n () =>\n open({\n dictionaryId,\n dictionaryPath,\n keyPath,\n }),\n [dictionaryId, dictionaryPath, keyPath, open]\n );\n\n const isSelected =\n (isOpen &&\n (focusedContent?.keyPath?.length ?? 0) > 0 &&\n isSameKeyPath(focusedContent?.keyPath ?? [], keyPath)) ??\n false;\n\n return (\n <ContentSelector
|
|
1
|
+
{"version":3,"sources":["../../../src/client/ContentSelectorWrapper.tsx"],"sourcesContent":["'use client';\n\nimport { isSameKeyPath, type KeyPath } from '@intlayer/core';\nimport { ContentSelector } from '@intlayer/design-system';\nimport { useCallback, useContext, type FC, type ReactNode } from 'react';\nimport { IntlayerEditorContext } from './ContentEditorProvider';\nimport { useDictionaryEditionDrawer } from './DictionaryEditionDrawer/useDictionaryEditionDrawer';\n\ntype ContentSelectorWrapperProps = {\n children: ReactNode;\n dictionaryId: string;\n dictionaryPath: string;\n keyPath: KeyPath[];\n};\n\nexport const ContentSelectorWrapper: FC<ContentSelectorWrapperProps> = ({\n children,\n dictionaryId,\n dictionaryPath,\n keyPath,\n}) => {\n const { open, getEditedContentValue, focusedContent, isOpen } =\n useDictionaryEditionDrawer(dictionaryId);\n const editedValue = getEditedContentValue(dictionaryPath, keyPath);\n const { editorEnabled } = useContext(IntlayerEditorContext);\n\n const handleSelect = useCallback(\n () =>\n open({\n dictionaryId,\n dictionaryPath,\n keyPath,\n }),\n [dictionaryId, dictionaryPath, keyPath, open]\n );\n\n const isSelected =\n (isOpen &&\n (focusedContent?.keyPath?.length ?? 0) > 0 &&\n isSameKeyPath(focusedContent?.keyPath ?? [], keyPath)) ??\n false;\n\n if (!editorEnabled) {\n return children;\n }\n\n return (\n <ContentSelector\n onSelect={handleSelect}\n isSelecting={isSelected}\n popoverContent=\"Long press to edit\"\n >\n {editedValue ?? children}\n </ContentSelector>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA+CI;AA7CJ,kBAA4C;AAC5C,2BAAgC;AAChC,mBAAiE;AACjE,mCAAsC;AACtC,wCAA2C;AASpC,MAAM,yBAA0D,CAAC;AAAA,EACtE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,EAAE,MAAM,uBAAuB,gBAAgB,OAAO,QAC1D,8DAA2B,YAAY;AACzC,QAAM,cAAc,sBAAsB,gBAAgB,OAAO;AACjE,QAAM,EAAE,cAAc,QAAI,yBAAW,kDAAqB;AAE1D,QAAM,mBAAe;AAAA,IACnB,MACE,KAAK;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,IACH,CAAC,cAAc,gBAAgB,SAAS,IAAI;AAAA,EAC9C;AAEA,QAAM,cACH,WACE,gBAAgB,SAAS,UAAU,KAAK,SACzC,2BAAc,gBAAgB,WAAW,CAAC,GAAG,OAAO,MACtD;AAEF,MAAI,CAAC,eAAe;AAClB,WAAO;AAAA,EACT;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV,aAAa;AAAA,MACb,gBAAe;AAAA,MAEd,yBAAe;AAAA;AAAA,EAClB;AAEJ;","names":[]}
|
|
@@ -17,7 +17,7 @@ declare const useEditedContentStore: zustand.UseBoundStore<Omit<zustand.StoreApi
|
|
|
17
17
|
persist: {
|
|
18
18
|
setOptions: (options: Partial<zustand_middleware.PersistOptions<EditedContentStore, EditedContentStore>>) => void;
|
|
19
19
|
clearStorage: () => void;
|
|
20
|
-
rehydrate: () => void |
|
|
20
|
+
rehydrate: () => Promise<void> | void;
|
|
21
21
|
hasHydrated: () => boolean;
|
|
22
22
|
onHydrate: (fn: (state: EditedContentStore) => void) => () => void;
|
|
23
23
|
onFinishHydration: (fn: (state: EditedContentStore) => void) => () => void;
|
|
@@ -20,12 +20,14 @@ __reExport(client_exports, require('./DictionaryListDrawer/index.cjs'), module.e
|
|
|
20
20
|
__reExport(client_exports, require('./ContentEditionLayout.cjs'), module.exports);
|
|
21
21
|
__reExport(client_exports, require('./useEditorServer.cjs'), module.exports);
|
|
22
22
|
__reExport(client_exports, require('./renderContentEditor.cjs'), module.exports);
|
|
23
|
+
__reExport(client_exports, require('./ContentEditorProvider.cjs'), module.exports);
|
|
23
24
|
// Annotate the CommonJS export names for ESM import in node:
|
|
24
25
|
0 && (module.exports = {
|
|
25
26
|
...require('./DictionaryEditionDrawer/index.cjs'),
|
|
26
27
|
...require('./DictionaryListDrawer/index.cjs'),
|
|
27
28
|
...require('./ContentEditionLayout.cjs'),
|
|
28
29
|
...require('./useEditorServer.cjs'),
|
|
29
|
-
...require('./renderContentEditor.cjs')
|
|
30
|
+
...require('./renderContentEditor.cjs'),
|
|
31
|
+
...require('./ContentEditorProvider.cjs')
|
|
30
32
|
});
|
|
31
33
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/client/index.ts"],"sourcesContent":["export * from './DictionaryEditionDrawer/index';\nexport * from './DictionaryListDrawer/index';\nexport * from './ContentEditionLayout';\nexport * from './useEditorServer';\nexport * from './renderContentEditor';\n"],"mappings":";;;;;;;;;;;;;;;AAAA;AAAA;AAAA,2BAAc,4CAAd;AACA,2BAAc,yCADd;AAEA,2BAAc,mCAFd;AAGA,2BAAc,8BAHd;AAIA,2BAAc,kCAJd;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/client/index.ts"],"sourcesContent":["export * from './DictionaryEditionDrawer/index';\nexport * from './DictionaryListDrawer/index';\nexport * from './ContentEditionLayout';\nexport * from './useEditorServer';\nexport * from './renderContentEditor';\nexport * from './ContentEditorProvider';\n"],"mappings":";;;;;;;;;;;;;;;AAAA;AAAA;AAAA,2BAAc,4CAAd;AACA,2BAAc,yCADd;AAEA,2BAAc,mCAFd;AAGA,2BAAc,8BAHd;AAIA,2BAAc,kCAJd;AAKA,2BAAc,oCALd;","names":[]}
|
|
@@ -6,6 +6,7 @@ export { dictionaryListDrawerIdentifier, useDictionaryListDrawer } from './Dicti
|
|
|
6
6
|
export { ContentEditionLayout, ContentEditionLayoutProps } from './ContentEditionLayout.js';
|
|
7
7
|
export { useEditorServer } from './useEditorServer.js';
|
|
8
8
|
export { IntlayerEditorElementProps, renderIntlayerEditor } from './renderContentEditor.js';
|
|
9
|
+
export { IntlayerEditorContext, IntlayerEditorProvider, IntlayerEditorProviderProps, useIntlayerEditorContext } from './ContentEditorProvider.js';
|
|
9
10
|
import '@intlayer/config/client';
|
|
10
11
|
import 'react';
|
|
11
12
|
import '@intlayer/core';
|
|
@@ -32,64 +32,54 @@ const { default: generate } = requireFunction("@babel/generator");
|
|
|
32
32
|
const findNestedProperty = (obj, keyPath) => {
|
|
33
33
|
let currentObj = obj;
|
|
34
34
|
for (const key of keyPath) {
|
|
35
|
-
|
|
36
|
-
if (
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
) {
|
|
40
|
-
const result = currentObj.properties.find(
|
|
41
|
-
(prop) => "key" in prop && prop.key.name === key.key
|
|
42
|
-
);
|
|
43
|
-
if (result && "value" in result) {
|
|
44
|
-
currentObj = result.value;
|
|
45
|
-
foundProperty = result;
|
|
46
|
-
} else {
|
|
47
|
-
return void 0;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
if (
|
|
51
|
-
// if the keyPath is an array, select the related node
|
|
52
|
-
key.type === "ArrayExpression"
|
|
53
|
-
) {
|
|
54
|
-
const result = currentObj.elements[key.key];
|
|
55
|
-
currentObj = result;
|
|
56
|
-
}
|
|
57
|
-
if (
|
|
58
|
-
// if the keypath is a translation or enumeration node, go across the function and select the related node
|
|
59
|
-
Object.values(import_core.NodeType).includes(
|
|
60
|
-
key.type
|
|
61
|
-
)
|
|
62
|
-
) {
|
|
63
|
-
const argument = currentObj.arguments[0];
|
|
64
|
-
const identifierResult = argument.properties.find(
|
|
65
|
-
(prop) => "key" in prop && prop.key.name === key.key
|
|
66
|
-
);
|
|
67
|
-
const stringResult = argument.properties.find(
|
|
68
|
-
(prop) => "key" in prop && prop.key.value === key.key
|
|
69
|
-
);
|
|
70
|
-
if (stringResult) {
|
|
71
|
-
if ("value" in stringResult) {
|
|
72
|
-
currentObj = stringResult.value;
|
|
73
|
-
}
|
|
74
|
-
foundProperty = stringResult;
|
|
75
|
-
} else if (identifierResult) {
|
|
76
|
-
if ("name" in identifierResult) {
|
|
77
|
-
currentObj = identifierResult.name;
|
|
78
|
-
}
|
|
79
|
-
foundProperty = identifierResult;
|
|
80
|
-
} else {
|
|
81
|
-
return void 0;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
35
|
+
const nextProperty = getNextProperty(currentObj, key);
|
|
36
|
+
if (!nextProperty)
|
|
37
|
+
throw new Error("Could not find the specified key path.");
|
|
38
|
+
currentObj = nextProperty;
|
|
84
39
|
}
|
|
85
40
|
return currentObj;
|
|
86
41
|
};
|
|
42
|
+
const getNextProperty = (obj, key) => {
|
|
43
|
+
if (key.type === "ObjectExpression") {
|
|
44
|
+
return findInObjectExpression(
|
|
45
|
+
obj,
|
|
46
|
+
key
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
if (key.type === "ArrayExpression") {
|
|
50
|
+
return obj.elements[key.key];
|
|
51
|
+
}
|
|
52
|
+
if (Object.values(import_core.NodeType).includes(key.type)) {
|
|
53
|
+
return findInTranslationOrEnumerationNode(
|
|
54
|
+
obj,
|
|
55
|
+
key
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
return void 0;
|
|
59
|
+
};
|
|
60
|
+
const findInObjectExpression = (obj, key) => {
|
|
61
|
+
const result = obj.properties.find(
|
|
62
|
+
(prop) => "key" in prop && prop.key.name === key.key
|
|
63
|
+
);
|
|
64
|
+
return result && "value" in result ? result.value : void 0;
|
|
65
|
+
};
|
|
66
|
+
const findInTranslationOrEnumerationNode = (obj, key) => {
|
|
67
|
+
const argument = obj.arguments[0];
|
|
68
|
+
const identifierResult = argument.properties.find(
|
|
69
|
+
(prop) => "key" in prop && prop.key.name === key.key
|
|
70
|
+
);
|
|
71
|
+
const stringResult = identifierResult.value;
|
|
72
|
+
return stringResult ? identifierResult : identifierResult && "name" in identifierResult ? identifierResult.name : void 0;
|
|
73
|
+
};
|
|
87
74
|
const findAndUpdate = (objExpr, keyPath, newValue) => {
|
|
88
75
|
const lastKey = keyPath[keyPath.length - 1];
|
|
89
76
|
if (lastKey) {
|
|
90
77
|
const propertyToUpdate = findNestedProperty(objExpr, keyPath);
|
|
91
|
-
if (propertyToUpdate
|
|
92
|
-
|
|
78
|
+
if (!propertyToUpdate) {
|
|
79
|
+
throw new Error("Could not find the specified key path.");
|
|
80
|
+
}
|
|
81
|
+
if ("value" in propertyToUpdate) {
|
|
82
|
+
propertyToUpdate.value.value = newValue;
|
|
93
83
|
}
|
|
94
84
|
}
|
|
95
85
|
};
|
|
@@ -135,21 +125,29 @@ const traverseNode = (node, keyPath, newValue) => {
|
|
|
135
125
|
const processEdition = async (editedContent) => {
|
|
136
126
|
for (const dictionaryPath of Object.keys(editedContent)) {
|
|
137
127
|
const fileContent = (0, import_fs.readFileSync)(dictionaryPath, "utf-8");
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
plugins: ["jsx", "typescript"]
|
|
141
|
-
});
|
|
128
|
+
const parsedBase = parseFileContent(fileContent);
|
|
129
|
+
const parsed = parseFileContent(fileContent);
|
|
142
130
|
for (const { keyPath, newValue } of editedContent[dictionaryPath]) {
|
|
143
131
|
traverseNode(parsed.program, keyPath, newValue);
|
|
144
132
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
133
|
+
await writeUpdatedContent(dictionaryPath, parsedBase, parsed);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
const parseFileContent = (fileContent) => (0, import_parser.parse)(fileContent, {
|
|
137
|
+
sourceType: "module",
|
|
138
|
+
plugins: ["jsx", "typescript"]
|
|
139
|
+
});
|
|
140
|
+
const writeUpdatedContent = async (dictionaryPath, parsedBase, parsed) => {
|
|
141
|
+
const baseContent = generate(parsedBase).code;
|
|
142
|
+
const updatedContent = generate(parsed).code;
|
|
143
|
+
if (baseContent === updatedContent) {
|
|
144
|
+
console.info(
|
|
145
|
+
`No change made on the dictionary - dictionaryPath: ${dictionaryPath}.`
|
|
146
|
+
);
|
|
147
|
+
} else {
|
|
148
|
+
const formattedContent = await (0, import_formatPrettier.format)(updatedContent);
|
|
149
|
+
(0, import_fs.writeFileSync)(dictionaryPath, formattedContent, "utf-8");
|
|
150
|
+
console.info("Updated the file successfully.");
|
|
153
151
|
}
|
|
154
152
|
};
|
|
155
153
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/server/processEdition.ts"],"sourcesContent":["/* eslint-disable sonarjs/cognitive-complexity */\nimport { readFileSync, writeFileSync } from 'fs';\nimport { createRequire } from 'module';\nimport { parse } from '@babel/parser';\nimport type {\n ObjectExpression,\n VariableDeclarator,\n Program,\n Identifier,\n StringLiteral,\n AssignmentExpression,\n ObjectProperty,\n CallExpression,\n
|
|
1
|
+
{"version":3,"sources":["../../../src/server/processEdition.ts"],"sourcesContent":["/* eslint-disable sonarjs/cognitive-complexity */\nimport { readFileSync, writeFileSync } from 'fs';\nimport { createRequire } from 'module';\nimport { parse } from '@babel/parser';\nimport type {\n ObjectExpression,\n VariableDeclarator,\n Program,\n Identifier,\n StringLiteral,\n AssignmentExpression,\n ObjectProperty,\n CallExpression,\n ArrayExpression,\n} from '@babel/types';\nimport {\n NodeType,\n type KeyPath,\n type ArrayExpressionNode,\n type ObjectExpressionNode,\n type TranslationOrEnumerationNode,\n} from '@intlayer/core';\nimport type { EditedContent } from '../client/index';\nimport { format } from './formatPrettier';\n\nconst requireFunction =\n typeof import.meta.url === 'undefined'\n ? require\n : createRequire(import.meta.url);\n\nconst { default: generate } = requireFunction('@babel/generator');\n\ntype ObjectOrArrayExpression = ObjectExpression | ArrayExpression;\n\n/**\n * Helper function to find a nested property in an ObjectExpression based on a key path\n */\nconst findNestedProperty = (\n obj: ObjectOrArrayExpression,\n keyPath: KeyPath[]\n): ObjectOrArrayExpression | undefined => {\n let currentObj: ObjectOrArrayExpression = obj;\n\n for (const key of keyPath) {\n const nextProperty = getNextProperty(currentObj, key);\n\n if (!nextProperty)\n throw new Error('Could not find the specified key path.');\n\n currentObj = nextProperty;\n }\n\n return currentObj;\n};\n\nconst getNextProperty = (\n obj: ObjectOrArrayExpression,\n key: KeyPath\n): ObjectOrArrayExpression | undefined => {\n if ((key as ObjectExpressionNode).type === 'ObjectExpression') {\n return findInObjectExpression(\n obj as ObjectExpression,\n key as ObjectExpressionNode\n );\n }\n\n if ((key as ArrayExpressionNode).type === 'ArrayExpression') {\n return (obj as ArrayExpression).elements[\n (key as ArrayExpressionNode).key\n ] as ObjectOrArrayExpression;\n }\n\n if (\n Object.values(NodeType).includes((key as TranslationOrEnumerationNode).type)\n ) {\n return findInTranslationOrEnumerationNode(\n obj as unknown as CallExpression,\n key as TranslationOrEnumerationNode\n );\n }\n\n return undefined;\n};\n\nconst findInObjectExpression = (\n obj: ObjectExpression,\n key: ObjectExpressionNode\n): ObjectOrArrayExpression | undefined => {\n const result = obj.properties.find(\n (prop) => 'key' in prop && (prop.key as Identifier).name === key.key\n );\n\n return result && 'value' in result\n ? (result.value as ObjectOrArrayExpression)\n : undefined;\n};\n\nconst findInTranslationOrEnumerationNode = (\n obj: CallExpression,\n key: TranslationOrEnumerationNode\n): ObjectOrArrayExpression | undefined => {\n const argument = obj.arguments[0] as ObjectExpression;\n const identifierResult = argument.properties.find(\n (prop) => 'key' in prop && (prop.key as Identifier).name === key.key\n ) as ObjectProperty;\n\n const stringResult = identifierResult.value as StringLiteral;\n\n return stringResult\n ? (identifierResult as unknown as ObjectOrArrayExpression)\n : identifierResult && 'name' in identifierResult\n ? (identifierResult.name as ObjectOrArrayExpression)\n : undefined;\n};\n\n/**\n * Find and update specific content based on key path\n */\nconst findAndUpdate = (\n objExpr: ObjectExpression,\n keyPath: KeyPath[],\n newValue: string\n) => {\n const lastKey = keyPath[keyPath.length - 1]; // Get the last key in the path\n\n if (lastKey) {\n const propertyToUpdate = findNestedProperty(objExpr, keyPath); // Traverse the key path\n\n if (!propertyToUpdate) {\n throw new Error('Could not find the specified key path.');\n }\n\n if ('value' in propertyToUpdate) {\n (propertyToUpdate.value as StringLiteral).value = newValue; // Update the value of the specified key\n }\n }\n};\n\n/**\n * Traverse the AST and update based on key path and new value\n */\nconst traverseNode = (node: Program, keyPath: KeyPath[], newValue: string) => {\n if (Array.isArray(node.body)) {\n node.body.forEach((subNode) =>\n traverseNode(subNode as unknown as Program, keyPath, newValue)\n );\n } else if (node.body) {\n traverseNode(node.body as Program, keyPath, newValue);\n }\n\n if (\n // For ES Module (e.g., `const variable = ...; export default variable`)\n 'declarations' in node\n ) {\n (node.declarations as VariableDeclarator[]).forEach((declaration) => {\n if (declaration.init?.type === 'ObjectExpression') {\n findAndUpdate(declaration.init, keyPath, newValue);\n }\n });\n }\n\n if (\n // For ES Module (e.g., `export default { ... }`)\n 'declaration' in node &&\n (node.declaration as ObjectExpression).type === 'ObjectExpression'\n ) {\n return findAndUpdate(\n node.declaration as ObjectExpression,\n keyPath,\n newValue\n );\n }\n\n if (\n // For CommonJS (e.g., `module.exports = ...`)\n 'expression' in node &&\n (node.expression as AssignmentExpression).right.type === 'ObjectExpression'\n ) {\n return findAndUpdate(\n (node.expression as AssignmentExpression).right as ObjectExpression,\n keyPath,\n newValue\n );\n }\n};\n\n/**\n * Edit the content of a file based on the key path and new value\n */\nexport const processEdition = async (editedContent: EditedContent) => {\n for (const dictionaryPath of Object.keys(editedContent)) {\n const fileContent = readFileSync(dictionaryPath, 'utf-8');\n const parsedBase = parseFileContent(fileContent);\n const parsed = parseFileContent(fileContent);\n\n for (const { keyPath, newValue } of editedContent[dictionaryPath]) {\n traverseNode(parsed.program, keyPath, newValue);\n }\n\n await writeUpdatedContent(dictionaryPath, parsedBase, parsed);\n }\n};\n\nconst parseFileContent = (fileContent: string) =>\n parse(fileContent, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n });\n\nconst writeUpdatedContent = async (\n dictionaryPath: string,\n parsedBase: ReturnType<typeof parseFileContent>,\n parsed: ReturnType<typeof parseFileContent>\n) => {\n const baseContent = generate(parsedBase).code;\n const updatedContent = generate(parsed).code;\n\n if (baseContent === updatedContent) {\n console.info(\n `No change made on the dictionary - dictionaryPath: ${dictionaryPath}.`\n );\n } else {\n const formattedContent = await format(updatedContent);\n writeFileSync(dictionaryPath, formattedContent, 'utf-8');\n console.info('Updated the file successfully.');\n }\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1,23 +1,29 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { IntlayerEditorProvider } from './ContentEditorProvider.mjs';
|
|
2
3
|
import { DictionaryEditionDrawerController } from './DictionaryEditionDrawer/index.mjs';
|
|
3
4
|
import { DictionaryListDrawer } from './DictionaryListDrawer/index.mjs';
|
|
4
5
|
const ContentEditionLayout = ({
|
|
5
6
|
children,
|
|
6
7
|
locale,
|
|
7
8
|
setLocale,
|
|
8
|
-
localeList
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
/* @__PURE__ */ jsx(
|
|
12
|
-
|
|
13
|
-
{
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
9
|
+
localeList,
|
|
10
|
+
editorEnabled = true
|
|
11
|
+
}) => {
|
|
12
|
+
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(IntlayerEditorProvider, { editorEnabled, children: [
|
|
13
|
+
children,
|
|
14
|
+
editorEnabled && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
15
|
+
/* @__PURE__ */ jsx(
|
|
16
|
+
DictionaryEditionDrawerController,
|
|
17
|
+
{
|
|
18
|
+
locale,
|
|
19
|
+
localeList,
|
|
20
|
+
setLocale
|
|
21
|
+
}
|
|
22
|
+
),
|
|
23
|
+
/* @__PURE__ */ jsx(DictionaryListDrawer, {})
|
|
24
|
+
] })
|
|
25
|
+
] }) });
|
|
26
|
+
};
|
|
21
27
|
export {
|
|
22
28
|
ContentEditionLayout
|
|
23
29
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/client/ContentEditionLayout.tsx"],"sourcesContent":["import type { Locales } from '@intlayer/config/client';\nimport type { FC, ReactNode } from 'react';\nimport { DictionaryEditionDrawerController } from './DictionaryEditionDrawer/index';\nimport { DictionaryListDrawer } from './DictionaryListDrawer/index';\n\nexport type ContentEditionLayoutProps = {\n children?: ReactNode;\n locale: Locales;\n localeList: Locales[];\n setLocale: (locale: Locales) => void;\n};\n\nexport const ContentEditionLayout: FC<ContentEditionLayoutProps> = ({\n children,\n locale,\n setLocale,\n localeList,\n}) => (\n
|
|
1
|
+
{"version":3,"sources":["../../../src/client/ContentEditionLayout.tsx"],"sourcesContent":["import type { Locales } from '@intlayer/config/client';\nimport type { FC, ReactNode } from 'react';\nimport { IntlayerEditorProvider } from './ContentEditorProvider';\nimport { DictionaryEditionDrawerController } from './DictionaryEditionDrawer/index';\nimport { DictionaryListDrawer } from './DictionaryListDrawer/index';\n\nexport type ContentEditionLayoutProps = {\n children?: ReactNode;\n locale: Locales;\n localeList: Locales[];\n setLocale: (locale: Locales) => void;\n editorEnabled?: boolean;\n};\n\nexport const ContentEditionLayout: FC<ContentEditionLayoutProps> = ({\n children,\n locale,\n setLocale,\n localeList,\n editorEnabled = true,\n}) => {\n return (\n <>\n <IntlayerEditorProvider editorEnabled={editorEnabled}>\n {children}\n\n {editorEnabled && (\n <>\n <DictionaryEditionDrawerController\n locale={locale}\n localeList={localeList}\n setLocale={setLocale}\n />\n <DictionaryListDrawer />\n </>\n )}\n </IntlayerEditorProvider>\n </>\n );\n};\n"],"mappings":"AA2BU,mBACE,KADF;AAzBV,SAAS,8BAA8B;AACvC,SAAS,yCAAyC;AAClD,SAAS,4BAA4B;AAU9B,MAAM,uBAAsD,CAAC;AAAA,EAClE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB;AAClB,MAAM;AACJ,SACE,gCACE,+BAAC,0BAAuB,eACrB;AAAA;AAAA,IAEA,iBACC,iCACE;AAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA;AAAA,MACF;AAAA,MACA,oBAAC,wBAAqB;AAAA,OACxB;AAAA,KAEJ,GACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { PropsWithChildren, FC } from 'react';
|
|
3
|
+
|
|
4
|
+
type IntlayerEditorValue = {
|
|
5
|
+
editorEnabled: boolean;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Context that store the current locale on the client side
|
|
9
|
+
*/
|
|
10
|
+
declare const IntlayerEditorContext: react.Context<IntlayerEditorValue>;
|
|
11
|
+
/**
|
|
12
|
+
* Hook that provides the current locale
|
|
13
|
+
*/
|
|
14
|
+
declare const useIntlayerEditorContext: () => IntlayerEditorValue;
|
|
15
|
+
type IntlayerEditorProviderProps = PropsWithChildren & {
|
|
16
|
+
editorEnabled?: boolean;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Provider that store the current locale on the client side
|
|
20
|
+
*/
|
|
21
|
+
declare const IntlayerEditorProvider: FC<IntlayerEditorProviderProps>;
|
|
22
|
+
|
|
23
|
+
export { IntlayerEditorContext, IntlayerEditorProvider, type IntlayerEditorProviderProps, useIntlayerEditorContext };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { getConfiguration } from "@intlayer/config/client";
|
|
4
|
+
import {
|
|
5
|
+
createContext,
|
|
6
|
+
useContext
|
|
7
|
+
} from "react";
|
|
8
|
+
const IntlayerEditorContext = createContext({
|
|
9
|
+
editorEnabled: false
|
|
10
|
+
});
|
|
11
|
+
const useIntlayerEditorContext = () => useContext(IntlayerEditorContext);
|
|
12
|
+
const {
|
|
13
|
+
editor: { enabled }
|
|
14
|
+
} = getConfiguration();
|
|
15
|
+
const IntlayerEditorProvider = ({
|
|
16
|
+
children,
|
|
17
|
+
editorEnabled = enabled
|
|
18
|
+
}) => /* @__PURE__ */ jsx(IntlayerEditorContext.Provider, { value: { editorEnabled }, children });
|
|
19
|
+
export {
|
|
20
|
+
IntlayerEditorContext,
|
|
21
|
+
IntlayerEditorProvider,
|
|
22
|
+
useIntlayerEditorContext
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=ContentEditorProvider.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/client/ContentEditorProvider.tsx"],"sourcesContent":["'use client';\n\nimport { getConfiguration } from '@intlayer/config/client';\nimport {\n type PropsWithChildren,\n createContext,\n useContext,\n type FC,\n} from 'react';\n\ntype IntlayerEditorValue = {\n editorEnabled: boolean;\n};\n\n/**\n * Context that store the current locale on the client side\n */\nexport const IntlayerEditorContext = createContext<IntlayerEditorValue>({\n editorEnabled: false,\n});\n\n/**\n * Hook that provides the current locale\n */\nexport const useIntlayerEditorContext = () => useContext(IntlayerEditorContext);\n\nexport type IntlayerEditorProviderProps = PropsWithChildren & {\n editorEnabled?: boolean;\n};\n\nconst {\n editor: { enabled },\n} = getConfiguration();\n\n/**\n * Provider that store the current locale on the client side\n */\nexport const IntlayerEditorProvider: FC<IntlayerEditorProviderProps> = ({\n children,\n editorEnabled = enabled,\n}) => (\n <IntlayerEditorContext.Provider value={{ editorEnabled }}>\n {children}\n </IntlayerEditorContext.Provider>\n);\n"],"mappings":";AAyCE;AAvCF,SAAS,wBAAwB;AACjC;AAAA,EAEE;AAAA,EACA;AAAA,OAEK;AASA,MAAM,wBAAwB,cAAmC;AAAA,EACtE,eAAe;AACjB,CAAC;AAKM,MAAM,2BAA2B,MAAM,WAAW,qBAAqB;AAM9E,MAAM;AAAA,EACJ,QAAQ,EAAE,QAAQ;AACpB,IAAI,iBAAiB;AAKd,MAAM,yBAA0D,CAAC;AAAA,EACtE;AAAA,EACA,gBAAgB;AAClB,MACE,oBAAC,sBAAsB,UAAtB,EAA+B,OAAO,EAAE,cAAc,GACpD,UACH;","names":[]}
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
import { isSameKeyPath } from "@intlayer/core";
|
|
4
4
|
import { ContentSelector } from "@intlayer/design-system";
|
|
5
|
-
import { useCallback } from "react";
|
|
5
|
+
import { useCallback, useContext } from "react";
|
|
6
|
+
import { IntlayerEditorContext } from './ContentEditorProvider.mjs';
|
|
6
7
|
import { useDictionaryEditionDrawer } from './DictionaryEditionDrawer/useDictionaryEditionDrawer.mjs';
|
|
7
8
|
const ContentSelectorWrapper = ({
|
|
8
9
|
children,
|
|
@@ -12,6 +13,7 @@ const ContentSelectorWrapper = ({
|
|
|
12
13
|
}) => {
|
|
13
14
|
const { open, getEditedContentValue, focusedContent, isOpen } = useDictionaryEditionDrawer(dictionaryId);
|
|
14
15
|
const editedValue = getEditedContentValue(dictionaryPath, keyPath);
|
|
16
|
+
const { editorEnabled } = useContext(IntlayerEditorContext);
|
|
15
17
|
const handleSelect = useCallback(
|
|
16
18
|
() => open({
|
|
17
19
|
dictionaryId,
|
|
@@ -21,7 +23,18 @@ const ContentSelectorWrapper = ({
|
|
|
21
23
|
[dictionaryId, dictionaryPath, keyPath, open]
|
|
22
24
|
);
|
|
23
25
|
const isSelected = (isOpen && (focusedContent?.keyPath?.length ?? 0) > 0 && isSameKeyPath(focusedContent?.keyPath ?? [], keyPath)) ?? false;
|
|
24
|
-
|
|
26
|
+
if (!editorEnabled) {
|
|
27
|
+
return children;
|
|
28
|
+
}
|
|
29
|
+
return /* @__PURE__ */ jsx(
|
|
30
|
+
ContentSelector,
|
|
31
|
+
{
|
|
32
|
+
onSelect: handleSelect,
|
|
33
|
+
isSelecting: isSelected,
|
|
34
|
+
popoverContent: "Long press to edit",
|
|
35
|
+
children: editedValue ?? children
|
|
36
|
+
}
|
|
37
|
+
);
|
|
25
38
|
};
|
|
26
39
|
export {
|
|
27
40
|
ContentSelectorWrapper
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/client/ContentSelectorWrapper.tsx"],"sourcesContent":["'use client';\n\nimport { isSameKeyPath, type KeyPath } from '@intlayer/core';\nimport { ContentSelector } from '@intlayer/design-system';\nimport { useCallback, type FC, type ReactNode } from 'react';\nimport { useDictionaryEditionDrawer } from './DictionaryEditionDrawer/useDictionaryEditionDrawer';\n\ntype ContentSelectorWrapperProps = {\n children: ReactNode;\n dictionaryId: string;\n dictionaryPath: string;\n keyPath: KeyPath[];\n};\n\nexport const ContentSelectorWrapper: FC<ContentSelectorWrapperProps> = ({\n children,\n dictionaryId,\n dictionaryPath,\n keyPath,\n}) => {\n const { open, getEditedContentValue, focusedContent, isOpen } =\n useDictionaryEditionDrawer(dictionaryId);\n const editedValue = getEditedContentValue(dictionaryPath, keyPath);\n\n const handleSelect = useCallback(\n () =>\n open({\n dictionaryId,\n dictionaryPath,\n keyPath,\n }),\n [dictionaryId, dictionaryPath, keyPath, open]\n );\n\n const isSelected =\n (isOpen &&\n (focusedContent?.keyPath?.length ?? 0) > 0 &&\n isSameKeyPath(focusedContent?.keyPath ?? [], keyPath)) ??\n false;\n\n return (\n <ContentSelector
|
|
1
|
+
{"version":3,"sources":["../../../src/client/ContentSelectorWrapper.tsx"],"sourcesContent":["'use client';\n\nimport { isSameKeyPath, type KeyPath } from '@intlayer/core';\nimport { ContentSelector } from '@intlayer/design-system';\nimport { useCallback, useContext, type FC, type ReactNode } from 'react';\nimport { IntlayerEditorContext } from './ContentEditorProvider';\nimport { useDictionaryEditionDrawer } from './DictionaryEditionDrawer/useDictionaryEditionDrawer';\n\ntype ContentSelectorWrapperProps = {\n children: ReactNode;\n dictionaryId: string;\n dictionaryPath: string;\n keyPath: KeyPath[];\n};\n\nexport const ContentSelectorWrapper: FC<ContentSelectorWrapperProps> = ({\n children,\n dictionaryId,\n dictionaryPath,\n keyPath,\n}) => {\n const { open, getEditedContentValue, focusedContent, isOpen } =\n useDictionaryEditionDrawer(dictionaryId);\n const editedValue = getEditedContentValue(dictionaryPath, keyPath);\n const { editorEnabled } = useContext(IntlayerEditorContext);\n\n const handleSelect = useCallback(\n () =>\n open({\n dictionaryId,\n dictionaryPath,\n keyPath,\n }),\n [dictionaryId, dictionaryPath, keyPath, open]\n );\n\n const isSelected =\n (isOpen &&\n (focusedContent?.keyPath?.length ?? 0) > 0 &&\n isSameKeyPath(focusedContent?.keyPath ?? [], keyPath)) ??\n false;\n\n if (!editorEnabled) {\n return children;\n }\n\n return (\n <ContentSelector\n onSelect={handleSelect}\n isSelecting={isSelected}\n popoverContent=\"Long press to edit\"\n >\n {editedValue ?? children}\n </ContentSelector>\n );\n};\n"],"mappings":";AA+CI;AA7CJ,SAAS,qBAAmC;AAC5C,SAAS,uBAAuB;AAChC,SAAS,aAAa,kBAA2C;AACjE,SAAS,6BAA6B;AACtC,SAAS,kCAAkC;AASpC,MAAM,yBAA0D,CAAC;AAAA,EACtE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,EAAE,MAAM,uBAAuB,gBAAgB,OAAO,IAC1D,2BAA2B,YAAY;AACzC,QAAM,cAAc,sBAAsB,gBAAgB,OAAO;AACjE,QAAM,EAAE,cAAc,IAAI,WAAW,qBAAqB;AAE1D,QAAM,eAAe;AAAA,IACnB,MACE,KAAK;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,IACH,CAAC,cAAc,gBAAgB,SAAS,IAAI;AAAA,EAC9C;AAEA,QAAM,cACH,WACE,gBAAgB,SAAS,UAAU,KAAK,KACzC,cAAc,gBAAgB,WAAW,CAAC,GAAG,OAAO,MACtD;AAEF,MAAI,CAAC,eAAe;AAClB,WAAO;AAAA,EACT;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV,aAAa;AAAA,MACb,gBAAe;AAAA,MAEd,yBAAe;AAAA;AAAA,EAClB;AAEJ;","names":[]}
|
|
@@ -17,7 +17,7 @@ declare const useEditedContentStore: zustand.UseBoundStore<Omit<zustand.StoreApi
|
|
|
17
17
|
persist: {
|
|
18
18
|
setOptions: (options: Partial<zustand_middleware.PersistOptions<EditedContentStore, EditedContentStore>>) => void;
|
|
19
19
|
clearStorage: () => void;
|
|
20
|
-
rehydrate: () => void |
|
|
20
|
+
rehydrate: () => Promise<void> | void;
|
|
21
21
|
hasHydrated: () => boolean;
|
|
22
22
|
onHydrate: (fn: (state: EditedContentStore) => void) => () => void;
|
|
23
23
|
onFinishHydration: (fn: (state: EditedContentStore) => void) => () => void;
|
|
@@ -6,6 +6,7 @@ export { dictionaryListDrawerIdentifier, useDictionaryListDrawer } from './Dicti
|
|
|
6
6
|
export { ContentEditionLayout, ContentEditionLayoutProps } from './ContentEditionLayout.mjs';
|
|
7
7
|
export { useEditorServer } from './useEditorServer.mjs';
|
|
8
8
|
export { IntlayerEditorElementProps, renderIntlayerEditor } from './renderContentEditor.mjs';
|
|
9
|
+
export { IntlayerEditorContext, IntlayerEditorProvider, IntlayerEditorProviderProps, useIntlayerEditorContext } from './ContentEditorProvider.mjs';
|
|
9
10
|
import '@intlayer/config/client';
|
|
10
11
|
import 'react';
|
|
11
12
|
import '@intlayer/core';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/client/index.ts"],"sourcesContent":["export * from './DictionaryEditionDrawer/index';\nexport * from './DictionaryListDrawer/index';\nexport * from './ContentEditionLayout';\nexport * from './useEditorServer';\nexport * from './renderContentEditor';\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/client/index.ts"],"sourcesContent":["export * from './DictionaryEditionDrawer/index';\nexport * from './DictionaryListDrawer/index';\nexport * from './ContentEditionLayout';\nexport * from './useEditorServer';\nexport * from './renderContentEditor';\nexport * from './ContentEditorProvider';\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|
|
@@ -10,64 +10,54 @@ const { default: generate } = requireFunction("@babel/generator");
|
|
|
10
10
|
const findNestedProperty = (obj, keyPath) => {
|
|
11
11
|
let currentObj = obj;
|
|
12
12
|
for (const key of keyPath) {
|
|
13
|
-
|
|
14
|
-
if (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
) {
|
|
18
|
-
const result = currentObj.properties.find(
|
|
19
|
-
(prop) => "key" in prop && prop.key.name === key.key
|
|
20
|
-
);
|
|
21
|
-
if (result && "value" in result) {
|
|
22
|
-
currentObj = result.value;
|
|
23
|
-
foundProperty = result;
|
|
24
|
-
} else {
|
|
25
|
-
return void 0;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
if (
|
|
29
|
-
// if the keyPath is an array, select the related node
|
|
30
|
-
key.type === "ArrayExpression"
|
|
31
|
-
) {
|
|
32
|
-
const result = currentObj.elements[key.key];
|
|
33
|
-
currentObj = result;
|
|
34
|
-
}
|
|
35
|
-
if (
|
|
36
|
-
// if the keypath is a translation or enumeration node, go across the function and select the related node
|
|
37
|
-
Object.values(NodeType).includes(
|
|
38
|
-
key.type
|
|
39
|
-
)
|
|
40
|
-
) {
|
|
41
|
-
const argument = currentObj.arguments[0];
|
|
42
|
-
const identifierResult = argument.properties.find(
|
|
43
|
-
(prop) => "key" in prop && prop.key.name === key.key
|
|
44
|
-
);
|
|
45
|
-
const stringResult = argument.properties.find(
|
|
46
|
-
(prop) => "key" in prop && prop.key.value === key.key
|
|
47
|
-
);
|
|
48
|
-
if (stringResult) {
|
|
49
|
-
if ("value" in stringResult) {
|
|
50
|
-
currentObj = stringResult.value;
|
|
51
|
-
}
|
|
52
|
-
foundProperty = stringResult;
|
|
53
|
-
} else if (identifierResult) {
|
|
54
|
-
if ("name" in identifierResult) {
|
|
55
|
-
currentObj = identifierResult.name;
|
|
56
|
-
}
|
|
57
|
-
foundProperty = identifierResult;
|
|
58
|
-
} else {
|
|
59
|
-
return void 0;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
13
|
+
const nextProperty = getNextProperty(currentObj, key);
|
|
14
|
+
if (!nextProperty)
|
|
15
|
+
throw new Error("Could not find the specified key path.");
|
|
16
|
+
currentObj = nextProperty;
|
|
62
17
|
}
|
|
63
18
|
return currentObj;
|
|
64
19
|
};
|
|
20
|
+
const getNextProperty = (obj, key) => {
|
|
21
|
+
if (key.type === "ObjectExpression") {
|
|
22
|
+
return findInObjectExpression(
|
|
23
|
+
obj,
|
|
24
|
+
key
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
if (key.type === "ArrayExpression") {
|
|
28
|
+
return obj.elements[key.key];
|
|
29
|
+
}
|
|
30
|
+
if (Object.values(NodeType).includes(key.type)) {
|
|
31
|
+
return findInTranslationOrEnumerationNode(
|
|
32
|
+
obj,
|
|
33
|
+
key
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
return void 0;
|
|
37
|
+
};
|
|
38
|
+
const findInObjectExpression = (obj, key) => {
|
|
39
|
+
const result = obj.properties.find(
|
|
40
|
+
(prop) => "key" in prop && prop.key.name === key.key
|
|
41
|
+
);
|
|
42
|
+
return result && "value" in result ? result.value : void 0;
|
|
43
|
+
};
|
|
44
|
+
const findInTranslationOrEnumerationNode = (obj, key) => {
|
|
45
|
+
const argument = obj.arguments[0];
|
|
46
|
+
const identifierResult = argument.properties.find(
|
|
47
|
+
(prop) => "key" in prop && prop.key.name === key.key
|
|
48
|
+
);
|
|
49
|
+
const stringResult = identifierResult.value;
|
|
50
|
+
return stringResult ? identifierResult : identifierResult && "name" in identifierResult ? identifierResult.name : void 0;
|
|
51
|
+
};
|
|
65
52
|
const findAndUpdate = (objExpr, keyPath, newValue) => {
|
|
66
53
|
const lastKey = keyPath[keyPath.length - 1];
|
|
67
54
|
if (lastKey) {
|
|
68
55
|
const propertyToUpdate = findNestedProperty(objExpr, keyPath);
|
|
69
|
-
if (propertyToUpdate
|
|
70
|
-
|
|
56
|
+
if (!propertyToUpdate) {
|
|
57
|
+
throw new Error("Could not find the specified key path.");
|
|
58
|
+
}
|
|
59
|
+
if ("value" in propertyToUpdate) {
|
|
60
|
+
propertyToUpdate.value.value = newValue;
|
|
71
61
|
}
|
|
72
62
|
}
|
|
73
63
|
};
|
|
@@ -113,21 +103,29 @@ const traverseNode = (node, keyPath, newValue) => {
|
|
|
113
103
|
const processEdition = async (editedContent) => {
|
|
114
104
|
for (const dictionaryPath of Object.keys(editedContent)) {
|
|
115
105
|
const fileContent = readFileSync(dictionaryPath, "utf-8");
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
plugins: ["jsx", "typescript"]
|
|
119
|
-
});
|
|
106
|
+
const parsedBase = parseFileContent(fileContent);
|
|
107
|
+
const parsed = parseFileContent(fileContent);
|
|
120
108
|
for (const { keyPath, newValue } of editedContent[dictionaryPath]) {
|
|
121
109
|
traverseNode(parsed.program, keyPath, newValue);
|
|
122
110
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
111
|
+
await writeUpdatedContent(dictionaryPath, parsedBase, parsed);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
const parseFileContent = (fileContent) => parse(fileContent, {
|
|
115
|
+
sourceType: "module",
|
|
116
|
+
plugins: ["jsx", "typescript"]
|
|
117
|
+
});
|
|
118
|
+
const writeUpdatedContent = async (dictionaryPath, parsedBase, parsed) => {
|
|
119
|
+
const baseContent = generate(parsedBase).code;
|
|
120
|
+
const updatedContent = generate(parsed).code;
|
|
121
|
+
if (baseContent === updatedContent) {
|
|
122
|
+
console.info(
|
|
123
|
+
`No change made on the dictionary - dictionaryPath: ${dictionaryPath}.`
|
|
124
|
+
);
|
|
125
|
+
} else {
|
|
126
|
+
const formattedContent = await format(updatedContent);
|
|
127
|
+
writeFileSync(dictionaryPath, formattedContent, "utf-8");
|
|
128
|
+
console.info("Updated the file successfully.");
|
|
131
129
|
}
|
|
132
130
|
};
|
|
133
131
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/server/processEdition.ts"],"sourcesContent":["/* eslint-disable sonarjs/cognitive-complexity */\nimport { readFileSync, writeFileSync } from 'fs';\nimport { createRequire } from 'module';\nimport { parse } from '@babel/parser';\nimport type {\n ObjectExpression,\n VariableDeclarator,\n Program,\n Identifier,\n StringLiteral,\n AssignmentExpression,\n ObjectProperty,\n CallExpression,\n
|
|
1
|
+
{"version":3,"sources":["../../../src/server/processEdition.ts"],"sourcesContent":["/* eslint-disable sonarjs/cognitive-complexity */\nimport { readFileSync, writeFileSync } from 'fs';\nimport { createRequire } from 'module';\nimport { parse } from '@babel/parser';\nimport type {\n ObjectExpression,\n VariableDeclarator,\n Program,\n Identifier,\n StringLiteral,\n AssignmentExpression,\n ObjectProperty,\n CallExpression,\n ArrayExpression,\n} from '@babel/types';\nimport {\n NodeType,\n type KeyPath,\n type ArrayExpressionNode,\n type ObjectExpressionNode,\n type TranslationOrEnumerationNode,\n} from '@intlayer/core';\nimport type { EditedContent } from '../client/index';\nimport { format } from './formatPrettier';\n\nconst requireFunction =\n typeof import.meta.url === 'undefined'\n ? require\n : createRequire(import.meta.url);\n\nconst { default: generate } = requireFunction('@babel/generator');\n\ntype ObjectOrArrayExpression = ObjectExpression | ArrayExpression;\n\n/**\n * Helper function to find a nested property in an ObjectExpression based on a key path\n */\nconst findNestedProperty = (\n obj: ObjectOrArrayExpression,\n keyPath: KeyPath[]\n): ObjectOrArrayExpression | undefined => {\n let currentObj: ObjectOrArrayExpression = obj;\n\n for (const key of keyPath) {\n const nextProperty = getNextProperty(currentObj, key);\n\n if (!nextProperty)\n throw new Error('Could not find the specified key path.');\n\n currentObj = nextProperty;\n }\n\n return currentObj;\n};\n\nconst getNextProperty = (\n obj: ObjectOrArrayExpression,\n key: KeyPath\n): ObjectOrArrayExpression | undefined => {\n if ((key as ObjectExpressionNode).type === 'ObjectExpression') {\n return findInObjectExpression(\n obj as ObjectExpression,\n key as ObjectExpressionNode\n );\n }\n\n if ((key as ArrayExpressionNode).type === 'ArrayExpression') {\n return (obj as ArrayExpression).elements[\n (key as ArrayExpressionNode).key\n ] as ObjectOrArrayExpression;\n }\n\n if (\n Object.values(NodeType).includes((key as TranslationOrEnumerationNode).type)\n ) {\n return findInTranslationOrEnumerationNode(\n obj as unknown as CallExpression,\n key as TranslationOrEnumerationNode\n );\n }\n\n return undefined;\n};\n\nconst findInObjectExpression = (\n obj: ObjectExpression,\n key: ObjectExpressionNode\n): ObjectOrArrayExpression | undefined => {\n const result = obj.properties.find(\n (prop) => 'key' in prop && (prop.key as Identifier).name === key.key\n );\n\n return result && 'value' in result\n ? (result.value as ObjectOrArrayExpression)\n : undefined;\n};\n\nconst findInTranslationOrEnumerationNode = (\n obj: CallExpression,\n key: TranslationOrEnumerationNode\n): ObjectOrArrayExpression | undefined => {\n const argument = obj.arguments[0] as ObjectExpression;\n const identifierResult = argument.properties.find(\n (prop) => 'key' in prop && (prop.key as Identifier).name === key.key\n ) as ObjectProperty;\n\n const stringResult = identifierResult.value as StringLiteral;\n\n return stringResult\n ? (identifierResult as unknown as ObjectOrArrayExpression)\n : identifierResult && 'name' in identifierResult\n ? (identifierResult.name as ObjectOrArrayExpression)\n : undefined;\n};\n\n/**\n * Find and update specific content based on key path\n */\nconst findAndUpdate = (\n objExpr: ObjectExpression,\n keyPath: KeyPath[],\n newValue: string\n) => {\n const lastKey = keyPath[keyPath.length - 1]; // Get the last key in the path\n\n if (lastKey) {\n const propertyToUpdate = findNestedProperty(objExpr, keyPath); // Traverse the key path\n\n if (!propertyToUpdate) {\n throw new Error('Could not find the specified key path.');\n }\n\n if ('value' in propertyToUpdate) {\n (propertyToUpdate.value as StringLiteral).value = newValue; // Update the value of the specified key\n }\n }\n};\n\n/**\n * Traverse the AST and update based on key path and new value\n */\nconst traverseNode = (node: Program, keyPath: KeyPath[], newValue: string) => {\n if (Array.isArray(node.body)) {\n node.body.forEach((subNode) =>\n traverseNode(subNode as unknown as Program, keyPath, newValue)\n );\n } else if (node.body) {\n traverseNode(node.body as Program, keyPath, newValue);\n }\n\n if (\n // For ES Module (e.g., `const variable = ...; export default variable`)\n 'declarations' in node\n ) {\n (node.declarations as VariableDeclarator[]).forEach((declaration) => {\n if (declaration.init?.type === 'ObjectExpression') {\n findAndUpdate(declaration.init, keyPath, newValue);\n }\n });\n }\n\n if (\n // For ES Module (e.g., `export default { ... }`)\n 'declaration' in node &&\n (node.declaration as ObjectExpression).type === 'ObjectExpression'\n ) {\n return findAndUpdate(\n node.declaration as ObjectExpression,\n keyPath,\n newValue\n );\n }\n\n if (\n // For CommonJS (e.g., `module.exports = ...`)\n 'expression' in node &&\n (node.expression as AssignmentExpression).right.type === 'ObjectExpression'\n ) {\n return findAndUpdate(\n (node.expression as AssignmentExpression).right as ObjectExpression,\n keyPath,\n newValue\n );\n }\n};\n\n/**\n * Edit the content of a file based on the key path and new value\n */\nexport const processEdition = async (editedContent: EditedContent) => {\n for (const dictionaryPath of Object.keys(editedContent)) {\n const fileContent = readFileSync(dictionaryPath, 'utf-8');\n const parsedBase = parseFileContent(fileContent);\n const parsed = parseFileContent(fileContent);\n\n for (const { keyPath, newValue } of editedContent[dictionaryPath]) {\n traverseNode(parsed.program, keyPath, newValue);\n }\n\n await writeUpdatedContent(dictionaryPath, parsedBase, parsed);\n }\n};\n\nconst parseFileContent = (fileContent: string) =>\n parse(fileContent, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n });\n\nconst writeUpdatedContent = async (\n dictionaryPath: string,\n parsedBase: ReturnType<typeof parseFileContent>,\n parsed: ReturnType<typeof parseFileContent>\n) => {\n const baseContent = generate(parsedBase).code;\n const updatedContent = generate(parsed).code;\n\n if (baseContent === updatedContent) {\n console.info(\n `No change made on the dictionary - dictionaryPath: ${dictionaryPath}.`\n );\n } else {\n const formattedContent = await format(updatedContent);\n writeFileSync(dictionaryPath, formattedContent, 'utf-8');\n console.info('Updated the file successfully.');\n }\n};\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "intlayer-editor",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "IntLayer Editor is a tool that allow you to edit your IntLayer declaration files using a graphical interface.",
|
|
6
6
|
"keywords": [
|
|
@@ -53,19 +53,19 @@
|
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@types/body-parser": "^1.19.5",
|
|
55
55
|
"body-parser": "^1.20.2",
|
|
56
|
-
"commander": "^12.
|
|
56
|
+
"commander": "^12.1.0",
|
|
57
57
|
"express": "^4.19.2",
|
|
58
58
|
"lucide-react": "^0.376.0",
|
|
59
59
|
"magic-regexp": "^0.8.0",
|
|
60
|
-
"react": "^18.
|
|
61
|
-
"react-dom": "^18.
|
|
62
|
-
"webpack": "^5.
|
|
60
|
+
"react": "^18.3.1",
|
|
61
|
+
"react-dom": "^18.3.1",
|
|
62
|
+
"webpack": "^5.92.1",
|
|
63
63
|
"zustand": "^4.5.2",
|
|
64
|
-
"@intlayer/config": "^2.0.
|
|
65
|
-
"@intlayer/core": "^2.0.
|
|
66
|
-
"@intlayer/design-system": "^2.0.
|
|
67
|
-
"@intlayer/dictionaries-entry": "^2.0.
|
|
68
|
-
"intlayer": "^2.0.
|
|
64
|
+
"@intlayer/config": "^2.0.3",
|
|
65
|
+
"@intlayer/core": "^2.0.3",
|
|
66
|
+
"@intlayer/design-system": "^2.0.3",
|
|
67
|
+
"@intlayer/dictionaries-entry": "^2.0.3",
|
|
68
|
+
"intlayer": "^2.0.3"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@babel/generator": "7.24.4",
|
|
@@ -75,15 +75,15 @@
|
|
|
75
75
|
"@changesets/cli": "2.27.1",
|
|
76
76
|
"@types/babel__generator": "^7.6.8",
|
|
77
77
|
"@types/express": "^4.17.21",
|
|
78
|
-
"@types/node": "^20.
|
|
79
|
-
"@types/react": "^18.
|
|
80
|
-
"@types/react-dom": "^18.
|
|
78
|
+
"@types/node": "^20.14.9",
|
|
79
|
+
"@types/react": "^18.3.3",
|
|
80
|
+
"@types/react-dom": "^18.3.0",
|
|
81
81
|
"rimraf": "5.0.5",
|
|
82
82
|
"ts-node": "^10.9.2",
|
|
83
|
-
"tsup": "^8.0
|
|
84
|
-
"typescript": "^5.
|
|
85
|
-
"@utils/eslint-config": "^1.0.
|
|
86
|
-
"@utils/ts-config": "^1.0.
|
|
83
|
+
"tsup": "^8.1.0",
|
|
84
|
+
"typescript": "^5.5.2",
|
|
85
|
+
"@utils/eslint-config": "^1.0.3",
|
|
86
|
+
"@utils/ts-config": "^1.0.3"
|
|
87
87
|
},
|
|
88
88
|
"engines": {
|
|
89
89
|
"node": ">=14.18"
|