intlayer-editor 9.6.0 → 9.7.1
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/bin/intlayer-editor.mjs +29 -7
- package/client/dist/assets/CodeBlockShiki-BaQlmvsF.js +2 -0
- package/client/dist/assets/MarkDownRender-CufSxUcK.js +25 -0
- package/client/dist/assets/MarkDownRender-HV9SKc56.js +1 -0
- package/client/dist/assets/MarkdownEditor-BSbSD-tQ.js +174 -0
- package/client/dist/assets/{astro-JHDYjn39.js → astro-BZ97kZFP.js} +1 -1
- package/client/dist/assets/codeTransformer-pmm6yJGh.js +9 -0
- package/client/dist/assets/compat-BqYysBkt.js +1 -0
- package/client/dist/assets/css-BGIxQoYs.js +1 -0
- package/client/dist/assets/css-DgaLhXQH.js +1 -0
- package/client/dist/assets/dist-VBWB9uC8.js +11 -0
- package/client/dist/assets/extractUrlFromSitemap-Chj1JVpo.js +1 -0
- package/client/dist/assets/html-BCy9P6D2.js +1 -0
- package/client/dist/assets/{html-B2cKP6UN.js → html-DSw1lh5G.js} +1 -1
- package/client/dist/assets/index-65aMFXUF.css +2 -0
- package/client/dist/assets/index-MyctEsPU.js +116 -0
- package/client/dist/assets/javascript-CpIGwZ_Y.js +1 -0
- package/client/dist/assets/json-C3WlssX3.js +1 -0
- package/client/dist/assets/purify.es-Dqk5qvad.js +3 -0
- package/client/dist/assets/shikiBundle-DbyGgq42.js +12 -0
- package/client/dist/assets/{svelte-tEuLYt3E.js → svelte-CdeT-Ich.js} +1 -1
- package/client/dist/assets/tsx-CGosfAUg.js +1 -0
- package/client/dist/assets/typescript-Bb1J8qyy.js +1 -0
- package/client/dist/assets/{vue-Bg0byEaI.js → vue-jUI-lpPb.js} +1 -1
- package/client/dist/assets/wasm-inlined-4KdTHw0F.js +1 -0
- package/client/dist/index.html +3 -6
- package/package.json +37 -37
- package/server/dist/_virtual/_rolldown/runtime.cjs +1 -2
- package/server/dist/controllers/auth.controller.cjs +79 -0
- package/server/dist/controllers/auth.controller.cjs.map +1 -0
- package/server/dist/controllers/auth.controller.d.ts +34 -0
- package/server/dist/controllers/auth.controller.mjs +75 -0
- package/server/dist/controllers/auth.controller.mjs.map +1 -0
- package/server/dist/controllers/configuration.controller.cjs +10 -5
- package/server/dist/controllers/configuration.controller.cjs.map +1 -1
- package/server/dist/controllers/configuration.controller.d.ts +8 -3
- package/server/dist/controllers/configuration.controller.mjs +10 -5
- package/server/dist/controllers/configuration.controller.mjs.map +1 -1
- package/server/dist/controllers/dictionary.controller.cjs +4 -4
- package/server/dist/controllers/dictionary.controller.cjs.map +1 -1
- package/server/dist/controllers/dictionary.controller.d.ts +1 -2
- package/server/dist/controllers/dictionary.controller.mjs +3 -3
- package/server/dist/controllers/dictionary.controller.mjs.map +1 -1
- package/server/dist/export.cjs +2 -2
- package/server/dist/export.d.ts +2 -2
- package/server/dist/index.cjs +56 -19
- package/server/dist/index.cjs.map +1 -1
- package/server/dist/index.mjs +56 -19
- package/server/dist/index.mjs.map +1 -1
- package/server/dist/routes/auth.routes.cjs +34 -0
- package/server/dist/routes/auth.routes.cjs.map +1 -0
- package/server/dist/routes/auth.routes.d.ts +20 -0
- package/server/dist/routes/auth.routes.mjs +32 -0
- package/server/dist/routes/auth.routes.mjs.map +1 -0
- package/server/dist/routes/config.routes.cjs +2 -3
- package/server/dist/routes/config.routes.d.ts +0 -2
- package/server/dist/routes/config.routes.mjs +1 -2
- package/server/dist/routes/dictionary.routes.cjs +2 -3
- package/server/dist/routes/dictionary.routes.d.ts +0 -2
- package/server/dist/routes/dictionary.routes.mjs +1 -2
- package/server/dist/services/editorAuth.service.cjs +142 -0
- package/server/dist/services/editorAuth.service.cjs.map +1 -0
- package/server/dist/services/editorAuth.service.d.ts +41 -0
- package/server/dist/services/editorAuth.service.mjs +136 -0
- package/server/dist/services/editorAuth.service.mjs.map +1 -0
- package/server/dist/types/Routes.d.ts +0 -2
- package/server/dist/utils/checkPortAvailability.cjs +40 -15
- package/server/dist/utils/checkPortAvailability.cjs.map +1 -1
- package/server/dist/utils/checkPortAvailability.d.ts +14 -3
- package/server/dist/utils/checkPortAvailability.mjs +39 -15
- package/server/dist/utils/checkPortAvailability.mjs.map +1 -1
- package/server/dist/utils/httpStatusCodes.cjs +1 -2
- package/server/dist/utils/httpStatusCodes.d.ts +9 -20
- package/server/dist/utils/httpStatusCodes.mjs +1 -2
- package/server/dist/utils/responseData.cjs +2 -3
- package/server/dist/utils/responseData.d.ts +1 -2
- package/server/dist/utils/responseData.mjs +1 -2
- package/client/dist/assets/CodeBlockShiki-DtgHBhf-.js +0 -2
- package/client/dist/assets/MarkDownRender-B5rc5xdv.js +0 -25
- package/client/dist/assets/MarkDownRender-BJfBvDXr.js +0 -1
- package/client/dist/assets/MarkdownEditor-CKaCMWJN.js +0 -160
- package/client/dist/assets/codeTransformer-DVPQQcdP.js +0 -9
- package/client/dist/assets/css-CdtkT07m.js +0 -1
- package/client/dist/assets/css-LbU1hoFO.js +0 -1
- package/client/dist/assets/dist-BHukwvnD.js +0 -11
- package/client/dist/assets/dist-CcmWBeAo.js +0 -1
- package/client/dist/assets/dynamic-BG2syiTL.js +0 -41
- package/client/dist/assets/html-DYtkB_T1.js +0 -1
- package/client/dist/assets/index-BtBJMAbp.js +0 -59
- package/client/dist/assets/index-D82ZIHVs.css +0 -2
- package/client/dist/assets/javascript-Yelw-5ZN.js +0 -1
- package/client/dist/assets/json-CaljABEy.js +0 -1
- package/client/dist/assets/purify.es-Bvo9QlJ8.js +0 -3
- package/client/dist/assets/react-Cvdyeg_0.js +0 -1
- package/client/dist/assets/rolldown-runtime-hePW80VL.js +0 -1
- package/client/dist/assets/shikiBundle-vOk0aVqf.js +0 -12
- package/client/dist/assets/tsx-5f3ulCja.js +0 -1
- package/client/dist/assets/typescript-Utq2Cl8c.js +0 -1
- package/client/dist/assets/wasm-BnjxR4X6.js +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "intlayer-editor",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.7.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Integrate the Intlayer visual editor into your Intlayer projects, enabling CMS-like content management with multilingual support.",
|
|
6
6
|
"keywords": [
|
|
@@ -88,47 +88,47 @@
|
|
|
88
88
|
"typecheck": "tsc --project ./server/tsconfig.types.json --noEmit"
|
|
89
89
|
},
|
|
90
90
|
"dependencies": {
|
|
91
|
-
"@fastify/compress": "9.
|
|
92
|
-
"@fastify/cookie": "11.1.
|
|
93
|
-
"@fastify/cors": "11.
|
|
94
|
-
"@fastify/formbody": "9.0.
|
|
95
|
-
"@fastify/helmet": "13.
|
|
96
|
-
"@fastify/static": "10.1.
|
|
97
|
-
"@intlayer/
|
|
98
|
-
"@intlayer/
|
|
99
|
-
"@intlayer/
|
|
100
|
-
"
|
|
101
|
-
"
|
|
102
|
-
"
|
|
91
|
+
"@fastify/compress": "9.3.0",
|
|
92
|
+
"@fastify/cookie": "11.1.5",
|
|
93
|
+
"@fastify/cors": "11.4.0",
|
|
94
|
+
"@fastify/formbody": "9.0.1",
|
|
95
|
+
"@fastify/helmet": "13.2.0",
|
|
96
|
+
"@fastify/static": "10.1.8",
|
|
97
|
+
"@intlayer/api": "9.7.1",
|
|
98
|
+
"@intlayer/cli": "9.7.1",
|
|
99
|
+
"@intlayer/config": "9.7.1",
|
|
100
|
+
"@intlayer/dictionaries-entry": "9.7.1",
|
|
101
|
+
"@intlayer/engine": "9.7.1",
|
|
102
|
+
"fastify": "5.12.8",
|
|
103
|
+
"fastify-intlayer": "9.7.1",
|
|
104
|
+
"mime": "4.1.2",
|
|
105
|
+
"preact-intlayer": "9.7.1",
|
|
106
|
+
"react-intlayer": "9.7.1",
|
|
107
|
+
"vite-intlayer": "9.7.1"
|
|
103
108
|
},
|
|
104
109
|
"devDependencies": {
|
|
105
|
-
"@intlayer/
|
|
106
|
-
"@intlayer/
|
|
107
|
-
"@intlayer/
|
|
108
|
-
"@
|
|
109
|
-
"@
|
|
110
|
-
"@
|
|
111
|
-
"@
|
|
112
|
-
"@
|
|
110
|
+
"@intlayer/backend-contract": "9.7.1",
|
|
111
|
+
"@intlayer/core": "9.7.1",
|
|
112
|
+
"@intlayer/design-system": "9.7.1",
|
|
113
|
+
"@intlayer/editor-react": "9.7.1",
|
|
114
|
+
"@intlayer/types": "9.7.1",
|
|
115
|
+
"@preact/preset-vite": "2.10.6",
|
|
116
|
+
"@tailwindcss/vite": "4.3.4",
|
|
117
|
+
"@tanstack/react-query": "5.105.3",
|
|
118
|
+
"@types/node": "^26",
|
|
113
119
|
"@utils/ts-config": "1.0.4",
|
|
114
|
-
"
|
|
115
|
-
"
|
|
116
|
-
"framer-motion": "13.4.6",
|
|
120
|
+
"autoprefixer": "10.6.2",
|
|
121
|
+
"framer-motion": "14.9.0",
|
|
117
122
|
"fuse.js": "7.5.0",
|
|
118
|
-
"globals": "17.
|
|
119
|
-
"intlayer": "9.
|
|
120
|
-
"lucide-react": "1.
|
|
121
|
-
"
|
|
122
|
-
"
|
|
123
|
-
"
|
|
124
|
-
"react-intlayer": "9.6.0",
|
|
125
|
-
"react-router-dom": "7.18.3",
|
|
126
|
-
"tailwindcss": "4.3.3",
|
|
127
|
-
"tsdown": "0.23.0",
|
|
123
|
+
"globals": "17.14.0",
|
|
124
|
+
"intlayer": "9.7.1",
|
|
125
|
+
"lucide-react": "1.66.0",
|
|
126
|
+
"preact": "11.1.1",
|
|
127
|
+
"tailwindcss": "4.3.4",
|
|
128
|
+
"tsdown": "0.23.4",
|
|
128
129
|
"typescript": "7.0.2",
|
|
129
|
-
"vite": "8.3.
|
|
130
|
-
"
|
|
131
|
-
"vitest": "5.0.3"
|
|
130
|
+
"vite": "8.3.5",
|
|
131
|
+
"vitest": "5.1.0"
|
|
132
132
|
},
|
|
133
133
|
"engines": {
|
|
134
134
|
"node": ">=18.0.0"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// \0rolldown/runtime.js
|
|
2
2
|
var __create = Object.create;
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -24,5 +24,4 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
enumerable: true
|
|
25
25
|
}) : target, mod));
|
|
26
26
|
|
|
27
|
-
//#endregion
|
|
28
27
|
exports.__toESM = __toESM;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_services_editorAuth_service = require("../services/editorAuth.service.cjs");
|
|
3
|
+
const require_utils_httpStatusCodes = require("../utils/httpStatusCodes.cjs");
|
|
4
|
+
const require_utils_responseData = require("../utils/responseData.cjs");
|
|
5
|
+
let _intlayer_config_node = require("@intlayer/config/node");
|
|
6
|
+
|
|
7
|
+
// src/controllers/auth.controller.ts
|
|
8
|
+
const envFileOptions = {
|
|
9
|
+
env: process.env.NODE_ENV,
|
|
10
|
+
envFile: process.env.ENV_FILE
|
|
11
|
+
};
|
|
12
|
+
/** Host of an `Origin` header, `null` for an opaque origin (`null`). */
|
|
13
|
+
const getOriginHost = (origin) => {
|
|
14
|
+
try {
|
|
15
|
+
return new URL(origin).host;
|
|
16
|
+
} catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Rejects cross-site requests. The editor answers CORS with `*`, so without
|
|
22
|
+
* this guard any page open in the browser could read the bearer token from
|
|
23
|
+
* the local editor or trigger a login.
|
|
24
|
+
*/
|
|
25
|
+
const assertSameOrigin = async (request, reply) => {
|
|
26
|
+
const fetchSite = request.headers["sec-fetch-site"];
|
|
27
|
+
const { origin, host } = request.headers;
|
|
28
|
+
const isCrossSiteFetch = typeof fetchSite === "string" && fetchSite !== "same-origin" && fetchSite !== "none";
|
|
29
|
+
const isForeignOrigin = typeof origin === "string" && getOriginHost(origin) !== host;
|
|
30
|
+
if (!isCrossSiteFetch && !isForeignOrigin) return;
|
|
31
|
+
return reply.status(403).send(require_utils_responseData.formatResponse({
|
|
32
|
+
error: {
|
|
33
|
+
code: "FORBIDDEN_ORIGIN",
|
|
34
|
+
title: "Forbidden",
|
|
35
|
+
message: "The editor authentication is only available to the editor."
|
|
36
|
+
},
|
|
37
|
+
status: 403
|
|
38
|
+
}));
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Returns the CMS identity the editor client should use as bearer token.
|
|
42
|
+
*/
|
|
43
|
+
const getEditorAuth = async (_request, reply) => {
|
|
44
|
+
const auth = await require_services_editorAuth_service.resolveEditorAuth((0, _intlayer_config_node.getConfiguration)(envFileOptions));
|
|
45
|
+
return reply.send(require_utils_responseData.formatResponse({ data: {
|
|
46
|
+
auth,
|
|
47
|
+
isLoginPending: require_services_editorAuth_service.isEditorLoginPending()
|
|
48
|
+
} }));
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Opens the CMS login page in the browser, as `intlayer login` does. Answers
|
|
52
|
+
* right away: the client polls {@link getEditorAuth} until the login lands.
|
|
53
|
+
*/
|
|
54
|
+
const startLogin = async (_request, reply) => {
|
|
55
|
+
require_services_editorAuth_service.startEditorLogin((0, _intlayer_config_node.getConfiguration)(envFileOptions), envFileOptions).catch((error) => console.error(error));
|
|
56
|
+
return reply.send(require_utils_responseData.formatResponse({
|
|
57
|
+
data: { isLoginPending: true },
|
|
58
|
+
status: 202
|
|
59
|
+
}));
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Signs the editor out of its `intlayer login` session, then returns the
|
|
63
|
+
* identity left: the configured access key, if any.
|
|
64
|
+
*/
|
|
65
|
+
const logout = async (_request, reply) => {
|
|
66
|
+
const configuration = (0, _intlayer_config_node.getConfiguration)(envFileOptions);
|
|
67
|
+
await require_services_editorAuth_service.logoutEditor(configuration);
|
|
68
|
+
const auth = await require_services_editorAuth_service.resolveEditorAuth(configuration);
|
|
69
|
+
return reply.send(require_utils_responseData.formatResponse({ data: {
|
|
70
|
+
auth,
|
|
71
|
+
isLoginPending: require_services_editorAuth_service.isEditorLoginPending()
|
|
72
|
+
} }));
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
exports.assertSameOrigin = assertSameOrigin;
|
|
76
|
+
exports.getEditorAuth = getEditorAuth;
|
|
77
|
+
exports.logout = logout;
|
|
78
|
+
exports.startLogin = startLogin;
|
|
79
|
+
//# sourceMappingURL=auth.controller.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.controller.cjs","names":["formatResponse","resolveEditorAuth","getConfiguration","isEditorLoginPending","logoutEditor"],"sources":["../../src/controllers/auth.controller.ts"],"sourcesContent":["import { getConfiguration } from '@intlayer/config/node';\nimport {\n type EditorAuth,\n isEditorLoginPending,\n logoutEditor,\n resolveEditorAuth,\n startEditorLogin,\n} from '@services/editorAuth.service';\nimport { HttpStatusCodes } from '@utils/httpStatusCodes';\nimport { formatResponse, type ResponseData } from '@utils/responseData';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\n\nexport type GetEditorAuthResultData = {\n /** `null` when neither a login session nor an access key is available. */\n auth: EditorAuth | null;\n isLoginPending: boolean;\n};\nexport type GetEditorAuthResult = ResponseData<GetEditorAuthResultData>;\n\nexport type StartEditorLoginResult = ResponseData<{ isLoginPending: boolean }>;\n\nexport type LogoutEditorResult = ResponseData<GetEditorAuthResultData>;\n\nconst envFileOptions = {\n env: process.env.NODE_ENV,\n envFile: process.env.ENV_FILE,\n};\n\n/** Host of an `Origin` header, `null` for an opaque origin (`null`). */\nconst getOriginHost = (origin: string): string | null => {\n try {\n return new URL(origin).host;\n } catch {\n return null;\n }\n};\n\n/**\n * Rejects cross-site requests. The editor answers CORS with `*`, so without\n * this guard any page open in the browser could read the bearer token from\n * the local editor or trigger a login.\n */\nexport const assertSameOrigin = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n const fetchSite = request.headers['sec-fetch-site'];\n const { origin, host } = request.headers;\n\n const isCrossSiteFetch =\n typeof fetchSite === 'string' &&\n fetchSite !== 'same-origin' &&\n fetchSite !== 'none';\n\n const isForeignOrigin =\n typeof origin === 'string' && getOriginHost(origin) !== host;\n\n if (!isCrossSiteFetch && !isForeignOrigin) return;\n\n return reply.status(HttpStatusCodes.FORBIDDEN_403).send(\n formatResponse<null>({\n error: {\n code: 'FORBIDDEN_ORIGIN',\n title: 'Forbidden',\n message: 'The editor authentication is only available to the editor.',\n },\n status: HttpStatusCodes.FORBIDDEN_403,\n })\n );\n};\n\n/**\n * Returns the CMS identity the editor client should use as bearer token.\n */\nexport const getEditorAuth = async (\n _request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n const auth = await resolveEditorAuth(getConfiguration(envFileOptions));\n\n return reply.send(\n formatResponse<GetEditorAuthResultData>({\n data: { auth, isLoginPending: isEditorLoginPending() },\n })\n );\n};\n\n/**\n * Opens the CMS login page in the browser, as `intlayer login` does. Answers\n * right away: the client polls {@link getEditorAuth} until the login lands.\n */\nexport const startLogin = async (\n _request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n startEditorLogin(getConfiguration(envFileOptions), envFileOptions).catch(\n (error) => console.error(error)\n );\n\n return reply.send(\n formatResponse<{ isLoginPending: boolean }>({\n data: { isLoginPending: true },\n status: HttpStatusCodes.ACCEPTED_202,\n })\n );\n};\n\n/**\n * Signs the editor out of its `intlayer login` session, then returns the\n * identity left: the configured access key, if any.\n */\nexport const logout = async (\n _request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n const configuration = getConfiguration(envFileOptions);\n\n await logoutEditor(configuration);\n\n const auth = await resolveEditorAuth(configuration);\n\n return reply.send(\n formatResponse<GetEditorAuthResultData>({\n data: { auth, isLoginPending: isEditorLoginPending() },\n })\n );\n};\n"],"mappings":";;;;;;;AAuBA,MAAM,iBAAiB;CACrB;CACA,SAAS,QAAQ,IAAI;AACvB;;AAGA,MAAM,iBAAiB,WAAkC;CACvD,IAAI;EACF,OAAO,IAAI,IAAI,MAAM,CAAC,CAAC;CACzB,QAAQ;EACN,OAAO;CACT;AACF;;;;;;AAOA,MAAa,mBAAmB,OAC9B,SACA,UACkB;CAClB,MAAM,YAAY,QAAQ,QAAQ;CAClC,MAAM,EAAE,QAAQ,SAAS,QAAQ;CAEjC,MAAM,mBACJ,OAAO,cAAc,YACrB,cAAc,iBACd,cAAc;CAEhB,MAAM,kBACJ,OAAO,WAAW,YAAY,cAAc,MAAM,MAAM;CAE1D,IAAI,CAAC,oBAAoB,CAAC,iBAAiB;CAE3C,OAAO,MAAM,UAAoC,CAAC,CAAC,KACjDA,0CAAqB;EACnB,OAAO;GACL,MAAM;GACN,OAAO;GACP,SAAS;EACX;EACA;CACF,CAAC,CACH;AACF;;;;AAKA,MAAa,gBAAgB,OAC3B,UACA,UACkB;CAClB,MAAM,OAAO,MAAMC,0DAAkBC,wCAAiB,cAAc,CAAC;CAErE,OAAO,MAAM,KACXF,0CAAwC,EACtC,MAAM;EAAE;EAAM,gBAAgBG,yDAAqB;CAAE,EACvD,CAAC,CACH;AACF;;;;;AAMA,MAAa,aAAa,OACxB,UACA,UACkB;CAClB,yDAAiBD,wCAAiB,cAAc,GAAG,cAAc,CAAC,CAAC,OAChE,UAAU,QAAQ,MAAM,KAAK,CAChC;CAEA,OAAO,MAAM,KACXF,0CAA4C;EAC1C,MAAM,EAAE,gBAAgB,KAAK;EAC7B;CACF,CAAC,CACH;AACF;;;;;AAMA,MAAa,SAAS,OACpB,UACA,UACkB;CAClB,MAAM,oBAAgBE,wCAAiB,cAAc;CAErD,MAAME,iDAAa,aAAa;CAEhC,MAAM,OAAO,MAAMH,sDAAkB,aAAa;CAElD,OAAO,MAAM,KACXD,0CAAwC,EACtC,MAAM;EAAE;EAAM,gBAAgBG,yDAAqB;CAAE,EACvD,CAAC,CACH;AACF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { EditorAuth } from "../services/editorAuth.service.js";
|
|
2
|
+
import { ResponseData } from "../utils/responseData.js";
|
|
3
|
+
import { FastifyReply, FastifyRequest } from "fastify";
|
|
4
|
+
export type GetEditorAuthResultData = {
|
|
5
|
+
/** `null` when neither a login session nor an access key is available. */
|
|
6
|
+
auth: EditorAuth | null;
|
|
7
|
+
isLoginPending: boolean;
|
|
8
|
+
};
|
|
9
|
+
export type GetEditorAuthResult = ResponseData<GetEditorAuthResultData>;
|
|
10
|
+
export type StartEditorLoginResult = ResponseData<{
|
|
11
|
+
isLoginPending: boolean;
|
|
12
|
+
}>;
|
|
13
|
+
export type LogoutEditorResult = ResponseData<GetEditorAuthResultData>;
|
|
14
|
+
/**
|
|
15
|
+
* Rejects cross-site requests. The editor answers CORS with `*`, so without
|
|
16
|
+
* this guard any page open in the browser could read the bearer token from
|
|
17
|
+
* the local editor or trigger a login.
|
|
18
|
+
*/
|
|
19
|
+
export declare const assertSameOrigin: (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Returns the CMS identity the editor client should use as bearer token.
|
|
22
|
+
*/
|
|
23
|
+
export declare const getEditorAuth: (_request: FastifyRequest, reply: FastifyReply) => Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Opens the CMS login page in the browser, as `intlayer login` does. Answers
|
|
26
|
+
* right away: the client polls {@link getEditorAuth} until the login lands.
|
|
27
|
+
*/
|
|
28
|
+
export declare const startLogin: (_request: FastifyRequest, reply: FastifyReply) => Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Signs the editor out of its `intlayer login` session, then returns the
|
|
31
|
+
* identity left: the configured access key, if any.
|
|
32
|
+
*/
|
|
33
|
+
export declare const logout: (_request: FastifyRequest, reply: FastifyReply) => Promise<void>;
|
|
34
|
+
//# sourceMappingURL=auth.controller.d.ts.map
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { isEditorLoginPending, logoutEditor, resolveEditorAuth, startEditorLogin } from "../services/editorAuth.service.mjs";
|
|
2
|
+
import { HttpStatusCodes } from "../utils/httpStatusCodes.mjs";
|
|
3
|
+
import { formatResponse } from "../utils/responseData.mjs";
|
|
4
|
+
import { getConfiguration } from "@intlayer/config/node";
|
|
5
|
+
|
|
6
|
+
// src/controllers/auth.controller.ts
|
|
7
|
+
const envFileOptions = {
|
|
8
|
+
env: process.env.NODE_ENV,
|
|
9
|
+
envFile: process.env.ENV_FILE
|
|
10
|
+
};
|
|
11
|
+
/** Host of an `Origin` header, `null` for an opaque origin (`null`). */
|
|
12
|
+
const getOriginHost = (origin) => {
|
|
13
|
+
try {
|
|
14
|
+
return new URL(origin).host;
|
|
15
|
+
} catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Rejects cross-site requests. The editor answers CORS with `*`, so without
|
|
21
|
+
* this guard any page open in the browser could read the bearer token from
|
|
22
|
+
* the local editor or trigger a login.
|
|
23
|
+
*/
|
|
24
|
+
const assertSameOrigin = async (request, reply) => {
|
|
25
|
+
const fetchSite = request.headers["sec-fetch-site"];
|
|
26
|
+
const { origin, host } = request.headers;
|
|
27
|
+
const isCrossSiteFetch = typeof fetchSite === "string" && fetchSite !== "same-origin" && fetchSite !== "none";
|
|
28
|
+
const isForeignOrigin = typeof origin === "string" && getOriginHost(origin) !== host;
|
|
29
|
+
if (!isCrossSiteFetch && !isForeignOrigin) return;
|
|
30
|
+
return reply.status(403).send(formatResponse({
|
|
31
|
+
error: {
|
|
32
|
+
code: "FORBIDDEN_ORIGIN",
|
|
33
|
+
title: "Forbidden",
|
|
34
|
+
message: "The editor authentication is only available to the editor."
|
|
35
|
+
},
|
|
36
|
+
status: 403
|
|
37
|
+
}));
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Returns the CMS identity the editor client should use as bearer token.
|
|
41
|
+
*/
|
|
42
|
+
const getEditorAuth = async (_request, reply) => {
|
|
43
|
+
const auth = await resolveEditorAuth(getConfiguration(envFileOptions));
|
|
44
|
+
return reply.send(formatResponse({ data: {
|
|
45
|
+
auth,
|
|
46
|
+
isLoginPending: isEditorLoginPending()
|
|
47
|
+
} }));
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Opens the CMS login page in the browser, as `intlayer login` does. Answers
|
|
51
|
+
* right away: the client polls {@link getEditorAuth} until the login lands.
|
|
52
|
+
*/
|
|
53
|
+
const startLogin = async (_request, reply) => {
|
|
54
|
+
startEditorLogin(getConfiguration(envFileOptions), envFileOptions).catch((error) => console.error(error));
|
|
55
|
+
return reply.send(formatResponse({
|
|
56
|
+
data: { isLoginPending: true },
|
|
57
|
+
status: 202
|
|
58
|
+
}));
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Signs the editor out of its `intlayer login` session, then returns the
|
|
62
|
+
* identity left: the configured access key, if any.
|
|
63
|
+
*/
|
|
64
|
+
const logout = async (_request, reply) => {
|
|
65
|
+
const configuration = getConfiguration(envFileOptions);
|
|
66
|
+
await logoutEditor(configuration);
|
|
67
|
+
const auth = await resolveEditorAuth(configuration);
|
|
68
|
+
return reply.send(formatResponse({ data: {
|
|
69
|
+
auth,
|
|
70
|
+
isLoginPending: isEditorLoginPending()
|
|
71
|
+
} }));
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export { assertSameOrigin, getEditorAuth, logout, startLogin };
|
|
75
|
+
//# sourceMappingURL=auth.controller.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.controller.mjs","names":[],"sources":["../../src/controllers/auth.controller.ts"],"sourcesContent":["import { getConfiguration } from '@intlayer/config/node';\nimport {\n type EditorAuth,\n isEditorLoginPending,\n logoutEditor,\n resolveEditorAuth,\n startEditorLogin,\n} from '@services/editorAuth.service';\nimport { HttpStatusCodes } from '@utils/httpStatusCodes';\nimport { formatResponse, type ResponseData } from '@utils/responseData';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\n\nexport type GetEditorAuthResultData = {\n /** `null` when neither a login session nor an access key is available. */\n auth: EditorAuth | null;\n isLoginPending: boolean;\n};\nexport type GetEditorAuthResult = ResponseData<GetEditorAuthResultData>;\n\nexport type StartEditorLoginResult = ResponseData<{ isLoginPending: boolean }>;\n\nexport type LogoutEditorResult = ResponseData<GetEditorAuthResultData>;\n\nconst envFileOptions = {\n env: process.env.NODE_ENV,\n envFile: process.env.ENV_FILE,\n};\n\n/** Host of an `Origin` header, `null` for an opaque origin (`null`). */\nconst getOriginHost = (origin: string): string | null => {\n try {\n return new URL(origin).host;\n } catch {\n return null;\n }\n};\n\n/**\n * Rejects cross-site requests. The editor answers CORS with `*`, so without\n * this guard any page open in the browser could read the bearer token from\n * the local editor or trigger a login.\n */\nexport const assertSameOrigin = async (\n request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n const fetchSite = request.headers['sec-fetch-site'];\n const { origin, host } = request.headers;\n\n const isCrossSiteFetch =\n typeof fetchSite === 'string' &&\n fetchSite !== 'same-origin' &&\n fetchSite !== 'none';\n\n const isForeignOrigin =\n typeof origin === 'string' && getOriginHost(origin) !== host;\n\n if (!isCrossSiteFetch && !isForeignOrigin) return;\n\n return reply.status(HttpStatusCodes.FORBIDDEN_403).send(\n formatResponse<null>({\n error: {\n code: 'FORBIDDEN_ORIGIN',\n title: 'Forbidden',\n message: 'The editor authentication is only available to the editor.',\n },\n status: HttpStatusCodes.FORBIDDEN_403,\n })\n );\n};\n\n/**\n * Returns the CMS identity the editor client should use as bearer token.\n */\nexport const getEditorAuth = async (\n _request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n const auth = await resolveEditorAuth(getConfiguration(envFileOptions));\n\n return reply.send(\n formatResponse<GetEditorAuthResultData>({\n data: { auth, isLoginPending: isEditorLoginPending() },\n })\n );\n};\n\n/**\n * Opens the CMS login page in the browser, as `intlayer login` does. Answers\n * right away: the client polls {@link getEditorAuth} until the login lands.\n */\nexport const startLogin = async (\n _request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n startEditorLogin(getConfiguration(envFileOptions), envFileOptions).catch(\n (error) => console.error(error)\n );\n\n return reply.send(\n formatResponse<{ isLoginPending: boolean }>({\n data: { isLoginPending: true },\n status: HttpStatusCodes.ACCEPTED_202,\n })\n );\n};\n\n/**\n * Signs the editor out of its `intlayer login` session, then returns the\n * identity left: the configured access key, if any.\n */\nexport const logout = async (\n _request: FastifyRequest,\n reply: FastifyReply\n): Promise<void> => {\n const configuration = getConfiguration(envFileOptions);\n\n await logoutEditor(configuration);\n\n const auth = await resolveEditorAuth(configuration);\n\n return reply.send(\n formatResponse<GetEditorAuthResultData>({\n data: { auth, isLoginPending: isEditorLoginPending() },\n })\n );\n};\n"],"mappings":";;;;;;AAuBA,MAAM,iBAAiB;CACrB;CACA,SAAS,QAAQ,IAAI;AACvB;;AAGA,MAAM,iBAAiB,WAAkC;CACvD,IAAI;EACF,OAAO,IAAI,IAAI,MAAM,CAAC,CAAC;CACzB,QAAQ;EACN,OAAO;CACT;AACF;;;;;;AAOA,MAAa,mBAAmB,OAC9B,SACA,UACkB;CAClB,MAAM,YAAY,QAAQ,QAAQ;CAClC,MAAM,EAAE,QAAQ,SAAS,QAAQ;CAEjC,MAAM,mBACJ,OAAO,cAAc,YACrB,cAAc,iBACd,cAAc;CAEhB,MAAM,kBACJ,OAAO,WAAW,YAAY,cAAc,MAAM,MAAM;CAE1D,IAAI,CAAC,oBAAoB,CAAC,iBAAiB;CAE3C,OAAO,MAAM,UAAoC,CAAC,CAAC,KACjD,eAAqB;EACnB,OAAO;GACL,MAAM;GACN,OAAO;GACP,SAAS;EACX;EACA;CACF,CAAC,CACH;AACF;;;;AAKA,MAAa,gBAAgB,OAC3B,UACA,UACkB;CAClB,MAAM,OAAO,MAAM,kBAAkB,iBAAiB,cAAc,CAAC;CAErE,OAAO,MAAM,KACX,eAAwC,EACtC,MAAM;EAAE;EAAM,gBAAgB,qBAAqB;CAAE,EACvD,CAAC,CACH;AACF;;;;;AAMA,MAAa,aAAa,OACxB,UACA,UACkB;CAClB,iBAAiB,iBAAiB,cAAc,GAAG,cAAc,CAAC,CAAC,OAChE,UAAU,QAAQ,MAAM,KAAK,CAChC;CAEA,OAAO,MAAM,KACX,eAA4C;EAC1C,MAAM,EAAE,gBAAgB,KAAK;EAC7B;CACF,CAAC,CACH;AACF;;;;;AAMA,MAAa,SAAS,OACpB,UACA,UACkB;CAClB,MAAM,gBAAgB,iBAAiB,cAAc;CAErD,MAAM,aAAa,aAAa;CAEhC,MAAM,OAAO,MAAM,kBAAkB,aAAa;CAElD,OAAO,MAAM,KACX,eAAwC,EACtC,MAAM;EAAE;EAAM,gBAAgB,qBAAqB;CAAE,EACvD,CAAC,CACH;AACF"}
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const require_utils_responseData = require(
|
|
2
|
+
const require_utils_responseData = require("../utils/responseData.cjs");
|
|
3
3
|
let _intlayer_config_node = require("@intlayer/config/node");
|
|
4
|
+
let _intlayer_config_defaultValues = require("@intlayer/config/defaultValues");
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
// src/controllers/configuration.controller.ts
|
|
6
7
|
/**
|
|
7
8
|
* Get the Intlayer configuration
|
|
8
9
|
*/
|
|
9
10
|
const getConfiguration = async (_req, res) => {
|
|
10
11
|
try {
|
|
11
|
-
const config = (0, _intlayer_config_node.
|
|
12
|
-
const
|
|
12
|
+
const { configuration: config, customConfiguration } = (0, _intlayer_config_node.getConfigurationAndFilePath)();
|
|
13
|
+
const { clientSecret: _clientSecret, ...editor } = config.editor;
|
|
14
|
+
const formattedResponse = require_utils_responseData.formatResponse({ data: {
|
|
15
|
+
...config,
|
|
16
|
+
editor,
|
|
17
|
+
isApplicationEditorEnabled: customConfiguration?.editor?.enabled ?? _intlayer_config_defaultValues.IS_ENABLED
|
|
18
|
+
} });
|
|
13
19
|
return res.send(formattedResponse);
|
|
14
20
|
} catch (err) {
|
|
15
21
|
const errorMessage = err ?? {
|
|
@@ -28,6 +34,5 @@ const getConfiguration = async (_req, res) => {
|
|
|
28
34
|
}
|
|
29
35
|
};
|
|
30
36
|
|
|
31
|
-
//#endregion
|
|
32
37
|
exports.getConfiguration = getConfiguration;
|
|
33
38
|
//# sourceMappingURL=configuration.controller.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configuration.controller.cjs","names":["
|
|
1
|
+
{"version":3,"file":"configuration.controller.cjs","names":["getConfigurationAndFilePath","formatResponse","IS_ENABLED"],"sources":["../../src/controllers/configuration.controller.ts"],"sourcesContent":["import { IS_ENABLED } from '@intlayer/config/defaultValues';\nimport { getConfigurationAndFilePath } from '@intlayer/config/node';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { formatResponse, type ResponseData } from '@utils/responseData';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\n\nexport type EditorServerConfiguration = IntlayerConfig & {\n /**\n * `editor.enabled` as set in the application configuration. The editor\n * server forces `editor.enabled` on in its own process, so it cannot tell.\n */\n isApplicationEditorEnabled: boolean;\n};\n\nexport type GetConfigurationResult = ResponseData<EditorServerConfiguration>;\n\n/**\n * Get the Intlayer configuration\n */\nexport const getConfiguration = async (\n _req: FastifyRequest,\n res: FastifyReply\n): Promise<void> => {\n try {\n const { configuration: config, customConfiguration } =\n getConfigurationAndFilePath();\n\n // The client secret never leaves the server: the client authenticates\n // with the short-lived token served by the auth routes.\n const { clientSecret: _clientSecret, ...editor } = config.editor;\n\n const formattedResponse = formatResponse<EditorServerConfiguration>({\n data: {\n ...config,\n editor,\n isApplicationEditorEnabled:\n customConfiguration?.editor?.enabled ?? IS_ENABLED,\n },\n });\n\n return res.send(formattedResponse);\n } catch (err) {\n const errorMessage = (err as { message?: string; status?: number }) ?? {\n message: 'Internal Server Error',\n status: 500,\n };\n\n const formattedErrorResponse = formatResponse<EditorServerConfiguration>({\n error: {\n message: errorMessage.message ?? 'Internal Server Error',\n code: 'INTERNAL_SERVER_ERROR',\n title: 'Internal Server Error',\n },\n status: errorMessage.status ?? 500,\n });\n\n return res.send(formattedErrorResponse);\n }\n};\n"],"mappings":";;;;;;;;;AAmBA,MAAa,mBAAmB,OAC9B,MACA,QACkB;CAClB,IAAI;EACF,MAAM,EAAE,eAAe,QAAQ,4BAC7BA,mDAA4B;EAI9B,MAAM,EAAE,cAAc,eAAe,GAAG,WAAW,OAAO;EAE1D,MAAM,oBAAoBC,0CAA0C,EAClE,MAAM;GACJ,GAAG;GACH;GACA,4BACE,qBAAqB,QAAQ,WAAWC;EAC5C,EACF,CAAC;EAED,OAAO,IAAI,KAAK,iBAAiB;CACnC,SAAS,KAAK;EACZ,MAAM,eAAgB,OAAiD;GACrE,SAAS;GACT,QAAQ;EACV;EAEA,MAAM,yBAAyBD,0CAA0C;GACvE,OAAO;IACL,SAAS,aAAa,WAAW;IACjC,MAAM;IACN,OAAO;GACT;GACA,QAAQ,aAAa,UAAU;EACjC,CAAC;EAED,OAAO,IAAI,KAAK,sBAAsB;CACxC;AACF"}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { ResponseData } from "../utils/responseData.js";
|
|
2
2
|
import { IntlayerConfig } from "@intlayer/types/config";
|
|
3
3
|
import { FastifyReply, FastifyRequest } from "fastify";
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
export type EditorServerConfiguration = IntlayerConfig & {
|
|
5
|
+
/**
|
|
6
|
+
* `editor.enabled` as set in the application configuration. The editor
|
|
7
|
+
* server forces `editor.enabled` on in its own process, so it cannot tell.
|
|
8
|
+
*/
|
|
9
|
+
isApplicationEditorEnabled: boolean;
|
|
10
|
+
};
|
|
11
|
+
export type GetConfigurationResult = ResponseData<EditorServerConfiguration>;
|
|
6
12
|
/**
|
|
7
13
|
* Get the Intlayer configuration
|
|
8
14
|
*/
|
|
9
15
|
export declare const getConfiguration: (_req: FastifyRequest, res: FastifyReply) => Promise<void>;
|
|
10
|
-
//#endregion
|
|
11
16
|
//# sourceMappingURL=configuration.controller.d.ts.map
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
import { formatResponse } from "../utils/responseData.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { getConfigurationAndFilePath } from "@intlayer/config/node";
|
|
3
|
+
import { IS_ENABLED } from "@intlayer/config/defaultValues";
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
// src/controllers/configuration.controller.ts
|
|
5
6
|
/**
|
|
6
7
|
* Get the Intlayer configuration
|
|
7
8
|
*/
|
|
8
9
|
const getConfiguration = async (_req, res) => {
|
|
9
10
|
try {
|
|
10
|
-
const config =
|
|
11
|
-
const
|
|
11
|
+
const { configuration: config, customConfiguration } = getConfigurationAndFilePath();
|
|
12
|
+
const { clientSecret: _clientSecret, ...editor } = config.editor;
|
|
13
|
+
const formattedResponse = formatResponse({ data: {
|
|
14
|
+
...config,
|
|
15
|
+
editor,
|
|
16
|
+
isApplicationEditorEnabled: customConfiguration?.editor?.enabled ?? IS_ENABLED
|
|
17
|
+
} });
|
|
12
18
|
return res.send(formattedResponse);
|
|
13
19
|
} catch (err) {
|
|
14
20
|
const errorMessage = err ?? {
|
|
@@ -27,6 +33,5 @@ const getConfiguration = async (_req, res) => {
|
|
|
27
33
|
}
|
|
28
34
|
};
|
|
29
35
|
|
|
30
|
-
//#endregion
|
|
31
36
|
export { getConfiguration };
|
|
32
37
|
//# sourceMappingURL=configuration.controller.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configuration.controller.mjs","names":[
|
|
1
|
+
{"version":3,"file":"configuration.controller.mjs","names":[],"sources":["../../src/controllers/configuration.controller.ts"],"sourcesContent":["import { IS_ENABLED } from '@intlayer/config/defaultValues';\nimport { getConfigurationAndFilePath } from '@intlayer/config/node';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { formatResponse, type ResponseData } from '@utils/responseData';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\n\nexport type EditorServerConfiguration = IntlayerConfig & {\n /**\n * `editor.enabled` as set in the application configuration. The editor\n * server forces `editor.enabled` on in its own process, so it cannot tell.\n */\n isApplicationEditorEnabled: boolean;\n};\n\nexport type GetConfigurationResult = ResponseData<EditorServerConfiguration>;\n\n/**\n * Get the Intlayer configuration\n */\nexport const getConfiguration = async (\n _req: FastifyRequest,\n res: FastifyReply\n): Promise<void> => {\n try {\n const { configuration: config, customConfiguration } =\n getConfigurationAndFilePath();\n\n // The client secret never leaves the server: the client authenticates\n // with the short-lived token served by the auth routes.\n const { clientSecret: _clientSecret, ...editor } = config.editor;\n\n const formattedResponse = formatResponse<EditorServerConfiguration>({\n data: {\n ...config,\n editor,\n isApplicationEditorEnabled:\n customConfiguration?.editor?.enabled ?? IS_ENABLED,\n },\n });\n\n return res.send(formattedResponse);\n } catch (err) {\n const errorMessage = (err as { message?: string; status?: number }) ?? {\n message: 'Internal Server Error',\n status: 500,\n };\n\n const formattedErrorResponse = formatResponse<EditorServerConfiguration>({\n error: {\n message: errorMessage.message ?? 'Internal Server Error',\n code: 'INTERNAL_SERVER_ERROR',\n title: 'Internal Server Error',\n },\n status: errorMessage.status ?? 500,\n });\n\n return res.send(formattedErrorResponse);\n }\n};\n"],"mappings":";;;;;;;;AAmBA,MAAa,mBAAmB,OAC9B,MACA,QACkB;CAClB,IAAI;EACF,MAAM,EAAE,eAAe,QAAQ,wBAC7B,4BAA4B;EAI9B,MAAM,EAAE,cAAc,eAAe,GAAG,WAAW,OAAO;EAE1D,MAAM,oBAAoB,eAA0C,EAClE,MAAM;GACJ,GAAG;GACH;GACA,4BACE,qBAAqB,QAAQ,WAAW;EAC5C,EACF,CAAC;EAED,OAAO,IAAI,KAAK,iBAAiB;CACnC,SAAS,KAAK;EACZ,MAAM,eAAgB,OAAiD;GACrE,SAAS;GACT,QAAQ;EACV;EAEA,MAAM,yBAAyB,eAA0C;GACvE,OAAO;IACL,SAAS,aAAa,WAAW;IACjC,MAAM;IACN,OAAO;GACT;GACA,QAAQ,aAAa,UAAU;EACjC,CAAC;EAED,OAAO,IAAI,KAAK,sBAAsB;CACxC;AACF"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const require_utils_responseData = require(
|
|
2
|
+
const require_utils_responseData = require("../utils/responseData.cjs");
|
|
3
3
|
let node_path = require("node:path");
|
|
4
4
|
let _intlayer_config_node = require("@intlayer/config/node");
|
|
5
|
+
let _intlayer_engine_build = require("@intlayer/engine/build");
|
|
5
6
|
let _intlayer_config_utils = require("@intlayer/config/utils");
|
|
6
7
|
let _intlayer_dictionaries_entry_unmerged = require("@intlayer/dictionaries-entry/unmerged");
|
|
7
|
-
let _intlayer_engine_build = require("@intlayer/engine/build");
|
|
8
8
|
let fastify_intlayer = require("fastify-intlayer");
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
// src/controllers/dictionary.controller.ts
|
|
11
11
|
/**
|
|
12
12
|
* Get the Intlayer configuration
|
|
13
13
|
*/
|
|
@@ -39,6 +39,7 @@ const writeContentDeclaration = async (req, res) => {
|
|
|
39
39
|
const dictionaryData = req.body.dictionary;
|
|
40
40
|
const config = (0, _intlayer_config_node.getConfiguration)();
|
|
41
41
|
const result = await (0, _intlayer_engine_build.writeContentDeclaration)(dictionaryData, config);
|
|
42
|
+
if (result.status !== "up-to-date") await (0, _intlayer_engine_build.rebuildUnmergedDictionaries)(result.path, config).catch((error) => console.error(error));
|
|
42
43
|
const dictionariesPath = (0, node_path.join)(config.system.mainDir, `unmerged_dictionaries.cjs`);
|
|
43
44
|
(0, _intlayer_config_utils.clearModuleCache)(dictionariesPath);
|
|
44
45
|
let description = "";
|
|
@@ -105,7 +106,6 @@ const writeContentDeclaration = async (req, res) => {
|
|
|
105
106
|
}
|
|
106
107
|
};
|
|
107
108
|
|
|
108
|
-
//#endregion
|
|
109
109
|
exports.getDictionaries = getDictionaries;
|
|
110
110
|
exports.writeContentDeclaration = writeContentDeclaration;
|
|
111
111
|
//# sourceMappingURL=dictionary.controller.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dictionary.controller.cjs","names":["formatResponse","getUnmergedDictionaries","getConfiguration","writeContentDeclarationEditor","join","t"],"sources":["../../src/controllers/dictionary.controller.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { clearModuleCache } from '@intlayer/config/utils';\nimport {\n getUnmergedDictionaries,\n type UnmergedDictionaries,\n} from '@intlayer/dictionaries-entry/unmerged';\nimport {\n type DictionaryStatus,\n writeContentDeclaration as writeContentDeclarationEditor,\n} from '@intlayer/engine/build';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { formatResponse, type ResponseData } from '@utils/responseData';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\nimport { t } from 'fastify-intlayer';\n\nexport type GetEditorDictionariesResult = ResponseData<UnmergedDictionaries>;\n\n/**\n * Get the Intlayer configuration\n */\nexport const getDictionaries = async (\n _req: FastifyRequest,\n res: FastifyReply\n): Promise<void> => {\n try {\n const formattedResponse = formatResponse<UnmergedDictionaries>({\n data: getUnmergedDictionaries(),\n });\n\n return res.send(formattedResponse);\n } catch (err) {\n const errorMessage = (err as { message?: string; status?: number }) ?? {\n message: 'Internal Server Error',\n status: 500,\n };\n\n const formattedErrorResponse = formatResponse<UnmergedDictionaries>({\n error: {\n message: errorMessage.message ?? 'Internal Server Error',\n code: 'INTERNAL_SERVER_ERROR',\n title: 'Internal Server Error',\n },\n status: errorMessage.status ?? 500,\n });\n\n return res.send(formattedErrorResponse);\n }\n};\n\nexport type WriteContentDeclarationBody = { dictionary: Dictionary };\ntype WriteContentDeclarationResultData = {\n status: DictionaryStatus;\n path: string;\n};\nexport type WriteContentDeclarationResult =\n ResponseData<WriteContentDeclarationResultData>;\n\n/**\n * Adds a new dictionary to the database.\n */\nexport const writeContentDeclaration = async (\n req: FastifyRequest<{ Body: WriteContentDeclarationBody }>,\n res: FastifyReply\n): Promise<void> => {\n try {\n const dictionaryData = req.body.dictionary;\n\n const config = getConfiguration();\n\n const result = await writeContentDeclarationEditor(dictionaryData, config);\n\n // Clear cache to hot reload the dictionaries\n const dictionariesPath = join(\n config.system.mainDir,\n `unmerged_dictionaries.cjs`\n );\n clearModuleCache(dictionariesPath);\n\n let description = '';\n\n switch (result.status) {\n case 'created': {\n description = t({\n en: 'Content declaration created successfully',\n fr: 'Déclaration de contenu créée avec succès',\n es: 'Declaración de contenido creada con éxito',\n });\n break;\n }\n\n case 'updated': {\n description = t({\n en: 'Content declaration updated successfully',\n fr: 'Déclaration de contenu mise à jour avec succès',\n es: 'Declaración de contenido actualizada con éxito',\n });\n break;\n }\n case 'reimported in JSON': {\n description = t({\n en: 'Content declaration reimported in JSON successfully',\n fr: 'Déclaration de contenu réimportée en JSON avec succès',\n es: 'Declaración de contenido reimportada en JSON con éxito',\n });\n break;\n }\n case 'new content file': {\n description = t({\n en: 'Content declaration new content file successfully',\n fr: 'Déclaration de contenu réimportée dans un nouveau emplacement avec succès',\n es: 'Declaración de contenido reimportada en un nuevo lugar con éxito',\n });\n break;\n }\n default: {\n description = t({\n en: 'Content declaration written successfully',\n fr: 'Déclaration de contenu écrite avec succès',\n es: 'Declaración de contenido escrita con éxito',\n });\n break;\n }\n }\n\n const formattedResponse = formatResponse<WriteContentDeclarationResultData>(\n {\n data: result,\n message: t({\n en: 'Content declaration written',\n fr: 'Déclaration de contenu écrite',\n es: 'Declaración de contenido escrita',\n }),\n description,\n }\n );\n\n return res.send(formattedResponse);\n } catch (err) {\n const errorMessage = (err as { message?: string; status?: number }) ?? {\n message: 'Internal Server Error',\n status: 500,\n };\n\n console.error(errorMessage);\n\n const formattedErrorResponse =\n formatResponse<WriteContentDeclarationResultData>({\n error: {\n message: errorMessage.message ?? 'Internal Server Error',\n code: 'INTERNAL_SERVER_ERROR',\n title: 'Internal Server Error',\n },\n status: errorMessage.status ?? 500,\n });\n\n return res.send(formattedErrorResponse);\n }\n};\n"],"mappings":";;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"dictionary.controller.cjs","names":["formatResponse","getUnmergedDictionaries","getConfiguration","writeContentDeclarationEditor","rebuildUnmergedDictionaries","join","t"],"sources":["../../src/controllers/dictionary.controller.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { clearModuleCache } from '@intlayer/config/utils';\nimport {\n getUnmergedDictionaries,\n type UnmergedDictionaries,\n} from '@intlayer/dictionaries-entry/unmerged';\nimport {\n type DictionaryStatus,\n rebuildUnmergedDictionaries,\n writeContentDeclaration as writeContentDeclarationEditor,\n} from '@intlayer/engine/build';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { formatResponse, type ResponseData } from '@utils/responseData';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\nimport { t } from 'fastify-intlayer';\n\nexport type GetEditorDictionariesResult = ResponseData<UnmergedDictionaries>;\n\n/**\n * Get the Intlayer configuration\n */\nexport const getDictionaries = async (\n _req: FastifyRequest,\n res: FastifyReply\n): Promise<void> => {\n try {\n const formattedResponse = formatResponse<UnmergedDictionaries>({\n data: getUnmergedDictionaries(),\n });\n\n return res.send(formattedResponse);\n } catch (err) {\n const errorMessage = (err as { message?: string; status?: number }) ?? {\n message: 'Internal Server Error',\n status: 500,\n };\n\n const formattedErrorResponse = formatResponse<UnmergedDictionaries>({\n error: {\n message: errorMessage.message ?? 'Internal Server Error',\n code: 'INTERNAL_SERVER_ERROR',\n title: 'Internal Server Error',\n },\n status: errorMessage.status ?? 500,\n });\n\n return res.send(formattedErrorResponse);\n }\n};\n\nexport type WriteContentDeclarationBody = { dictionary: Dictionary };\ntype WriteContentDeclarationResultData = {\n status: DictionaryStatus;\n path: string;\n};\nexport type WriteContentDeclarationResult =\n ResponseData<WriteContentDeclarationResultData>;\n\n/**\n * Adds a new dictionary to the database.\n */\nexport const writeContentDeclaration = async (\n req: FastifyRequest<{ Body: WriteContentDeclarationBody }>,\n res: FastifyReply\n): Promise<void> => {\n try {\n const dictionaryData = req.body.dictionary;\n\n const config = getConfiguration();\n\n const result = await writeContentDeclarationEditor(dictionaryData, config);\n\n // Rebuild the unmerged dictionaries before answering, so a read right\n // after the write returns the new content instead of waiting for the app\n // watcher. The write itself succeeded: a failed rebuild only delays it.\n if (result.status !== 'up-to-date') {\n await rebuildUnmergedDictionaries(result.path, config).catch((error) =>\n console.error(error)\n );\n }\n\n // Clear cache to hot reload the dictionaries\n const dictionariesPath = join(\n config.system.mainDir,\n `unmerged_dictionaries.cjs`\n );\n clearModuleCache(dictionariesPath);\n\n let description = '';\n\n switch (result.status) {\n case 'created': {\n description = t({\n en: 'Content declaration created successfully',\n fr: 'Déclaration de contenu créée avec succès',\n es: 'Declaración de contenido creada con éxito',\n });\n break;\n }\n\n case 'updated': {\n description = t({\n en: 'Content declaration updated successfully',\n fr: 'Déclaration de contenu mise à jour avec succès',\n es: 'Declaración de contenido actualizada con éxito',\n });\n break;\n }\n case 'reimported in JSON': {\n description = t({\n en: 'Content declaration reimported in JSON successfully',\n fr: 'Déclaration de contenu réimportée en JSON avec succès',\n es: 'Declaración de contenido reimportada en JSON con éxito',\n });\n break;\n }\n case 'new content file': {\n description = t({\n en: 'Content declaration new content file successfully',\n fr: 'Déclaration de contenu réimportée dans un nouveau emplacement avec succès',\n es: 'Declaración de contenido reimportada en un nuevo lugar con éxito',\n });\n break;\n }\n default: {\n description = t({\n en: 'Content declaration written successfully',\n fr: 'Déclaration de contenu écrite avec succès',\n es: 'Declaración de contenido escrita con éxito',\n });\n break;\n }\n }\n\n const formattedResponse = formatResponse<WriteContentDeclarationResultData>(\n {\n data: result,\n message: t({\n en: 'Content declaration written',\n fr: 'Déclaration de contenu écrite',\n es: 'Declaración de contenido escrita',\n }),\n description,\n }\n );\n\n return res.send(formattedResponse);\n } catch (err) {\n const errorMessage = (err as { message?: string; status?: number }) ?? {\n message: 'Internal Server Error',\n status: 500,\n };\n\n console.error(errorMessage);\n\n const formattedErrorResponse =\n formatResponse<WriteContentDeclarationResultData>({\n error: {\n message: errorMessage.message ?? 'Internal Server Error',\n code: 'INTERNAL_SERVER_ERROR',\n title: 'Internal Server Error',\n },\n status: errorMessage.status ?? 500,\n });\n\n return res.send(formattedErrorResponse);\n }\n};\n"],"mappings":";;;;;;;;;;;;;AAsBA,MAAa,kBAAkB,OAC7B,MACA,QACkB;CAClB,IAAI;EACF,MAAM,oBAAoBA,0CAAqC,EAC7D,UAAMC,+DAAwB,EAChC,CAAC;EAED,OAAO,IAAI,KAAK,iBAAiB;CACnC,SAAS,KAAK;EACZ,MAAM,eAAgB,OAAiD;GACrE,SAAS;GACT,QAAQ;EACV;EAEA,MAAM,yBAAyBD,0CAAqC;GAClE,OAAO;IACL,SAAS,aAAa,WAAW;IACjC,MAAM;IACN,OAAO;GACT;GACA,QAAQ,aAAa,UAAU;EACjC,CAAC;EAED,OAAO,IAAI,KAAK,sBAAsB;CACxC;AACF;;;;AAaA,MAAa,0BAA0B,OACrC,KACA,QACkB;CAClB,IAAI;EACF,MAAM,iBAAiB,IAAI,KAAK;EAEhC,MAAM,aAASE,wCAAiB;EAEhC,MAAM,SAAS,UAAMC,gDAA8B,gBAAgB,MAAM;EAKzE,IAAI,OAAO,WAAW,cACpB,UAAMC,oDAA4B,OAAO,MAAM,MAAM,CAAC,CAAC,OAAO,UAC5D,QAAQ,MAAM,KAAK,CACrB;EAIF,MAAM,uBAAmBC,gBACvB,OAAO,OAAO,SACd,2BACF;EACA,6CAAiB,gBAAgB;EAEjC,IAAI,cAAc;EAElB,QAAQ,OAAO,QAAf;GACE,KAAK;IACH,kBAAcC,oBAAE;KACd,IAAI;KACJ,IAAI;KACJ,IAAI;IACN,CAAC;IACD;GAGF,KAAK;IACH,kBAAcA,oBAAE;KACd,IAAI;KACJ,IAAI;KACJ,IAAI;IACN,CAAC;IACD;GAEF,KAAK;IACH,kBAAcA,oBAAE;KACd,IAAI;KACJ,IAAI;KACJ,IAAI;IACN,CAAC;IACD;GAEF,KAAK;IACH,kBAAcA,oBAAE;KACd,IAAI;KACJ,IAAI;KACJ,IAAI;IACN,CAAC;IACD;GAEF,SACE,kBAAcA,oBAAE;IACd,IAAI;IACJ,IAAI;IACJ,IAAI;GACN,CAAC;EAGL;EAEA,MAAM,oBAAoBN,0CACxB;GACE,MAAM;GACN,aAASM,oBAAE;IACT,IAAI;IACJ,IAAI;IACJ,IAAI;GACN,CAAC;GACD;EACF,CACF;EAEA,OAAO,IAAI,KAAK,iBAAiB;CACnC,SAAS,KAAK;EACZ,MAAM,eAAgB,OAAiD;GACrE,SAAS;GACT,QAAQ;EACV;EAEA,QAAQ,MAAM,YAAY;EAE1B,MAAM,yBACJN,0CAAkD;GAChD,OAAO;IACL,SAAS,aAAa,WAAW;IACjC,MAAM;IACN,OAAO;GACT;GACA,QAAQ,aAAa,UAAU;EACjC,CAAC;EAEH,OAAO,IAAI,KAAK,sBAAsB;CACxC;AACF"}
|
|
@@ -3,7 +3,6 @@ import { FastifyReply, FastifyRequest } from "fastify";
|
|
|
3
3
|
import { UnmergedDictionaries } from "@intlayer/dictionaries-entry/unmerged";
|
|
4
4
|
import { DictionaryStatus } from "@intlayer/engine/build";
|
|
5
5
|
import { Dictionary } from "@intlayer/types/dictionary";
|
|
6
|
-
//#region src/controllers/dictionary.controller.d.ts
|
|
7
6
|
export type GetEditorDictionariesResult = ResponseData<UnmergedDictionaries>;
|
|
8
7
|
/**
|
|
9
8
|
* Get the Intlayer configuration
|
|
@@ -23,5 +22,5 @@ export type WriteContentDeclarationResult = ResponseData<WriteContentDeclaration
|
|
|
23
22
|
export declare const writeContentDeclaration: (req: FastifyRequest<{
|
|
24
23
|
Body: WriteContentDeclarationBody;
|
|
25
24
|
}>, res: FastifyReply) => Promise<void>;
|
|
26
|
-
|
|
25
|
+
export {};
|
|
27
26
|
//# sourceMappingURL=dictionary.controller.d.ts.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { formatResponse } from "../utils/responseData.mjs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { getConfiguration } from "@intlayer/config/node";
|
|
4
|
+
import { rebuildUnmergedDictionaries, writeContentDeclaration as writeContentDeclaration$1 } from "@intlayer/engine/build";
|
|
4
5
|
import { clearModuleCache } from "@intlayer/config/utils";
|
|
5
6
|
import { getUnmergedDictionaries } from "@intlayer/dictionaries-entry/unmerged";
|
|
6
|
-
import { writeContentDeclaration as writeContentDeclaration$1 } from "@intlayer/engine/build";
|
|
7
7
|
import { t } from "fastify-intlayer";
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
// src/controllers/dictionary.controller.ts
|
|
10
10
|
/**
|
|
11
11
|
* Get the Intlayer configuration
|
|
12
12
|
*/
|
|
@@ -38,6 +38,7 @@ const writeContentDeclaration = async (req, res) => {
|
|
|
38
38
|
const dictionaryData = req.body.dictionary;
|
|
39
39
|
const config = getConfiguration();
|
|
40
40
|
const result = await writeContentDeclaration$1(dictionaryData, config);
|
|
41
|
+
if (result.status !== "up-to-date") await rebuildUnmergedDictionaries(result.path, config).catch((error) => console.error(error));
|
|
41
42
|
const dictionariesPath = join(config.system.mainDir, `unmerged_dictionaries.cjs`);
|
|
42
43
|
clearModuleCache(dictionariesPath);
|
|
43
44
|
let description = "";
|
|
@@ -104,6 +105,5 @@ const writeContentDeclaration = async (req, res) => {
|
|
|
104
105
|
}
|
|
105
106
|
};
|
|
106
107
|
|
|
107
|
-
//#endregion
|
|
108
108
|
export { getDictionaries, writeContentDeclaration };
|
|
109
109
|
//# sourceMappingURL=dictionary.controller.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dictionary.controller.mjs","names":["writeContentDeclarationEditor"],"sources":["../../src/controllers/dictionary.controller.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { clearModuleCache } from '@intlayer/config/utils';\nimport {\n getUnmergedDictionaries,\n type UnmergedDictionaries,\n} from '@intlayer/dictionaries-entry/unmerged';\nimport {\n type DictionaryStatus,\n writeContentDeclaration as writeContentDeclarationEditor,\n} from '@intlayer/engine/build';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { formatResponse, type ResponseData } from '@utils/responseData';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\nimport { t } from 'fastify-intlayer';\n\nexport type GetEditorDictionariesResult = ResponseData<UnmergedDictionaries>;\n\n/**\n * Get the Intlayer configuration\n */\nexport const getDictionaries = async (\n _req: FastifyRequest,\n res: FastifyReply\n): Promise<void> => {\n try {\n const formattedResponse = formatResponse<UnmergedDictionaries>({\n data: getUnmergedDictionaries(),\n });\n\n return res.send(formattedResponse);\n } catch (err) {\n const errorMessage = (err as { message?: string; status?: number }) ?? {\n message: 'Internal Server Error',\n status: 500,\n };\n\n const formattedErrorResponse = formatResponse<UnmergedDictionaries>({\n error: {\n message: errorMessage.message ?? 'Internal Server Error',\n code: 'INTERNAL_SERVER_ERROR',\n title: 'Internal Server Error',\n },\n status: errorMessage.status ?? 500,\n });\n\n return res.send(formattedErrorResponse);\n }\n};\n\nexport type WriteContentDeclarationBody = { dictionary: Dictionary };\ntype WriteContentDeclarationResultData = {\n status: DictionaryStatus;\n path: string;\n};\nexport type WriteContentDeclarationResult =\n ResponseData<WriteContentDeclarationResultData>;\n\n/**\n * Adds a new dictionary to the database.\n */\nexport const writeContentDeclaration = async (\n req: FastifyRequest<{ Body: WriteContentDeclarationBody }>,\n res: FastifyReply\n): Promise<void> => {\n try {\n const dictionaryData = req.body.dictionary;\n\n const config = getConfiguration();\n\n const result = await writeContentDeclarationEditor(dictionaryData, config);\n\n // Clear cache to hot reload the dictionaries\n const dictionariesPath = join(\n config.system.mainDir,\n `unmerged_dictionaries.cjs`\n );\n clearModuleCache(dictionariesPath);\n\n let description = '';\n\n switch (result.status) {\n case 'created': {\n description = t({\n en: 'Content declaration created successfully',\n fr: 'Déclaration de contenu créée avec succès',\n es: 'Declaración de contenido creada con éxito',\n });\n break;\n }\n\n case 'updated': {\n description = t({\n en: 'Content declaration updated successfully',\n fr: 'Déclaration de contenu mise à jour avec succès',\n es: 'Declaración de contenido actualizada con éxito',\n });\n break;\n }\n case 'reimported in JSON': {\n description = t({\n en: 'Content declaration reimported in JSON successfully',\n fr: 'Déclaration de contenu réimportée en JSON avec succès',\n es: 'Declaración de contenido reimportada en JSON con éxito',\n });\n break;\n }\n case 'new content file': {\n description = t({\n en: 'Content declaration new content file successfully',\n fr: 'Déclaration de contenu réimportée dans un nouveau emplacement avec succès',\n es: 'Declaración de contenido reimportada en un nuevo lugar con éxito',\n });\n break;\n }\n default: {\n description = t({\n en: 'Content declaration written successfully',\n fr: 'Déclaration de contenu écrite avec succès',\n es: 'Declaración de contenido escrita con éxito',\n });\n break;\n }\n }\n\n const formattedResponse = formatResponse<WriteContentDeclarationResultData>(\n {\n data: result,\n message: t({\n en: 'Content declaration written',\n fr: 'Déclaration de contenu écrite',\n es: 'Declaración de contenido escrita',\n }),\n description,\n }\n );\n\n return res.send(formattedResponse);\n } catch (err) {\n const errorMessage = (err as { message?: string; status?: number }) ?? {\n message: 'Internal Server Error',\n status: 500,\n };\n\n console.error(errorMessage);\n\n const formattedErrorResponse =\n formatResponse<WriteContentDeclarationResultData>({\n error: {\n message: errorMessage.message ?? 'Internal Server Error',\n code: 'INTERNAL_SERVER_ERROR',\n title: 'Internal Server Error',\n },\n status: errorMessage.status ?? 500,\n });\n\n return res.send(formattedErrorResponse);\n }\n};\n"],"mappings":";;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"dictionary.controller.mjs","names":["writeContentDeclarationEditor"],"sources":["../../src/controllers/dictionary.controller.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { clearModuleCache } from '@intlayer/config/utils';\nimport {\n getUnmergedDictionaries,\n type UnmergedDictionaries,\n} from '@intlayer/dictionaries-entry/unmerged';\nimport {\n type DictionaryStatus,\n rebuildUnmergedDictionaries,\n writeContentDeclaration as writeContentDeclarationEditor,\n} from '@intlayer/engine/build';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { formatResponse, type ResponseData } from '@utils/responseData';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\nimport { t } from 'fastify-intlayer';\n\nexport type GetEditorDictionariesResult = ResponseData<UnmergedDictionaries>;\n\n/**\n * Get the Intlayer configuration\n */\nexport const getDictionaries = async (\n _req: FastifyRequest,\n res: FastifyReply\n): Promise<void> => {\n try {\n const formattedResponse = formatResponse<UnmergedDictionaries>({\n data: getUnmergedDictionaries(),\n });\n\n return res.send(formattedResponse);\n } catch (err) {\n const errorMessage = (err as { message?: string; status?: number }) ?? {\n message: 'Internal Server Error',\n status: 500,\n };\n\n const formattedErrorResponse = formatResponse<UnmergedDictionaries>({\n error: {\n message: errorMessage.message ?? 'Internal Server Error',\n code: 'INTERNAL_SERVER_ERROR',\n title: 'Internal Server Error',\n },\n status: errorMessage.status ?? 500,\n });\n\n return res.send(formattedErrorResponse);\n }\n};\n\nexport type WriteContentDeclarationBody = { dictionary: Dictionary };\ntype WriteContentDeclarationResultData = {\n status: DictionaryStatus;\n path: string;\n};\nexport type WriteContentDeclarationResult =\n ResponseData<WriteContentDeclarationResultData>;\n\n/**\n * Adds a new dictionary to the database.\n */\nexport const writeContentDeclaration = async (\n req: FastifyRequest<{ Body: WriteContentDeclarationBody }>,\n res: FastifyReply\n): Promise<void> => {\n try {\n const dictionaryData = req.body.dictionary;\n\n const config = getConfiguration();\n\n const result = await writeContentDeclarationEditor(dictionaryData, config);\n\n // Rebuild the unmerged dictionaries before answering, so a read right\n // after the write returns the new content instead of waiting for the app\n // watcher. The write itself succeeded: a failed rebuild only delays it.\n if (result.status !== 'up-to-date') {\n await rebuildUnmergedDictionaries(result.path, config).catch((error) =>\n console.error(error)\n );\n }\n\n // Clear cache to hot reload the dictionaries\n const dictionariesPath = join(\n config.system.mainDir,\n `unmerged_dictionaries.cjs`\n );\n clearModuleCache(dictionariesPath);\n\n let description = '';\n\n switch (result.status) {\n case 'created': {\n description = t({\n en: 'Content declaration created successfully',\n fr: 'Déclaration de contenu créée avec succès',\n es: 'Declaración de contenido creada con éxito',\n });\n break;\n }\n\n case 'updated': {\n description = t({\n en: 'Content declaration updated successfully',\n fr: 'Déclaration de contenu mise à jour avec succès',\n es: 'Declaración de contenido actualizada con éxito',\n });\n break;\n }\n case 'reimported in JSON': {\n description = t({\n en: 'Content declaration reimported in JSON successfully',\n fr: 'Déclaration de contenu réimportée en JSON avec succès',\n es: 'Declaración de contenido reimportada en JSON con éxito',\n });\n break;\n }\n case 'new content file': {\n description = t({\n en: 'Content declaration new content file successfully',\n fr: 'Déclaration de contenu réimportée dans un nouveau emplacement avec succès',\n es: 'Declaración de contenido reimportada en un nuevo lugar con éxito',\n });\n break;\n }\n default: {\n description = t({\n en: 'Content declaration written successfully',\n fr: 'Déclaration de contenu écrite avec succès',\n es: 'Declaración de contenido escrita con éxito',\n });\n break;\n }\n }\n\n const formattedResponse = formatResponse<WriteContentDeclarationResultData>(\n {\n data: result,\n message: t({\n en: 'Content declaration written',\n fr: 'Déclaration de contenu écrite',\n es: 'Declaración de contenido escrita',\n }),\n description,\n }\n );\n\n return res.send(formattedResponse);\n } catch (err) {\n const errorMessage = (err as { message?: string; status?: number }) ?? {\n message: 'Internal Server Error',\n status: 500,\n };\n\n console.error(errorMessage);\n\n const formattedErrorResponse =\n formatResponse<WriteContentDeclarationResultData>({\n error: {\n message: errorMessage.message ?? 'Internal Server Error',\n code: 'INTERNAL_SERVER_ERROR',\n title: 'Internal Server Error',\n },\n status: errorMessage.status ?? 500,\n });\n\n return res.send(formattedErrorResponse);\n }\n};\n"],"mappings":";;;;;;;;;;;;AAsBA,MAAa,kBAAkB,OAC7B,MACA,QACkB;CAClB,IAAI;EACF,MAAM,oBAAoB,eAAqC,EAC7D,MAAM,wBAAwB,EAChC,CAAC;EAED,OAAO,IAAI,KAAK,iBAAiB;CACnC,SAAS,KAAK;EACZ,MAAM,eAAgB,OAAiD;GACrE,SAAS;GACT,QAAQ;EACV;EAEA,MAAM,yBAAyB,eAAqC;GAClE,OAAO;IACL,SAAS,aAAa,WAAW;IACjC,MAAM;IACN,OAAO;GACT;GACA,QAAQ,aAAa,UAAU;EACjC,CAAC;EAED,OAAO,IAAI,KAAK,sBAAsB;CACxC;AACF;;;;AAaA,MAAa,0BAA0B,OACrC,KACA,QACkB;CAClB,IAAI;EACF,MAAM,iBAAiB,IAAI,KAAK;EAEhC,MAAM,SAAS,iBAAiB;EAEhC,MAAM,SAAS,MAAMA,0BAA8B,gBAAgB,MAAM;EAKzE,IAAI,OAAO,WAAW,cACpB,MAAM,4BAA4B,OAAO,MAAM,MAAM,CAAC,CAAC,OAAO,UAC5D,QAAQ,MAAM,KAAK,CACrB;EAIF,MAAM,mBAAmB,KACvB,OAAO,OAAO,SACd,2BACF;EACA,iBAAiB,gBAAgB;EAEjC,IAAI,cAAc;EAElB,QAAQ,OAAO,QAAf;GACE,KAAK;IACH,cAAc,EAAE;KACd,IAAI;KACJ,IAAI;KACJ,IAAI;IACN,CAAC;IACD;GAGF,KAAK;IACH,cAAc,EAAE;KACd,IAAI;KACJ,IAAI;KACJ,IAAI;IACN,CAAC;IACD;GAEF,KAAK;IACH,cAAc,EAAE;KACd,IAAI;KACJ,IAAI;KACJ,IAAI;IACN,CAAC;IACD;GAEF,KAAK;IACH,cAAc,EAAE;KACd,IAAI;KACJ,IAAI;KACJ,IAAI;IACN,CAAC;IACD;GAEF,SACE,cAAc,EAAE;IACd,IAAI;IACJ,IAAI;IACJ,IAAI;GACN,CAAC;EAGL;EAEA,MAAM,oBAAoB,eACxB;GACE,MAAM;GACN,SAAS,EAAE;IACT,IAAI;IACJ,IAAI;IACJ,IAAI;GACN,CAAC;GACD;EACF,CACF;EAEA,OAAO,IAAI,KAAK,iBAAiB;CACnC,SAAS,KAAK;EACZ,MAAM,eAAgB,OAAiD;GACrE,SAAS;GACT,QAAQ;EACV;EAEA,QAAQ,MAAM,YAAY;EAE1B,MAAM,yBACJ,eAAkD;GAChD,OAAO;IACL,SAAS,aAAa,WAAW;IACjC,MAAM;IACN,OAAO;GACT;GACA,QAAQ,aAAa,UAAU;EACjC,CAAC;EAEH,OAAO,IAAI,KAAK,sBAAsB;CACxC;AACF"}
|
package/server/dist/export.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const require_controllers_configuration_controller = require(
|
|
3
|
-
const require_controllers_dictionary_controller = require(
|
|
2
|
+
const require_controllers_configuration_controller = require("./controllers/configuration.controller.cjs");
|
|
3
|
+
const require_controllers_dictionary_controller = require("./controllers/dictionary.controller.cjs");
|
|
4
4
|
|
|
5
5
|
exports.getConfiguration = require_controllers_configuration_controller.getConfiguration;
|
|
6
6
|
exports.getDictionaries = require_controllers_dictionary_controller.getDictionaries;
|
package/server/dist/export.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { GetConfigurationResult, getConfiguration } from "./controllers/configuration.controller.js";
|
|
1
|
+
import { EditorServerConfiguration, GetConfigurationResult, getConfiguration } from "./controllers/configuration.controller.js";
|
|
2
2
|
import { GetEditorDictionariesResult, WriteContentDeclarationBody, WriteContentDeclarationResult, getDictionaries, writeContentDeclaration } from "./controllers/dictionary.controller.js";
|
|
3
|
-
export { GetConfigurationResult, GetEditorDictionariesResult, WriteContentDeclarationBody, WriteContentDeclarationResult, getConfiguration, getDictionaries, writeContentDeclaration };
|
|
3
|
+
export { EditorServerConfiguration, GetConfigurationResult, GetEditorDictionariesResult, WriteContentDeclarationBody, WriteContentDeclarationResult, getConfiguration, getDictionaries, writeContentDeclaration };
|