intlayer-editor 5.3.2 → 5.3.4

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.
@@ -5,7 +5,7 @@
5
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>Intlayer Editor</title>
8
- <script type="module" crossorigin src="/assets/index-Ch1MCXVl.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-DHaDqrsi.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/assets/index-aawbhFi4.css">
10
10
  </head>
11
11
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "intlayer-editor",
3
- "version": "5.3.2",
3
+ "version": "5.3.4",
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": [
@@ -73,14 +73,14 @@
73
73
  "react-dom": "^19.0.0",
74
74
  "react-router-dom": "^7.1.1",
75
75
  "rimraf": "^6.0.1",
76
- "@intlayer/api": "5.3.2",
77
- "@intlayer/core": "5.3.2",
78
- "@intlayer/design-system": "5.3.2",
79
- "@intlayer/editor": "5.3.2",
80
- "@intlayer/editor-react": "5.3.2",
81
- "@intlayer/config": "5.3.2",
82
- "react-intlayer": "5.3.2",
83
- "vite-intlayer": "5.3.2"
76
+ "@intlayer/config": "5.3.4",
77
+ "@intlayer/api": "5.3.4",
78
+ "@intlayer/core": "5.3.4",
79
+ "@intlayer/design-system": "5.3.4",
80
+ "@intlayer/editor-react": "5.3.4",
81
+ "express-intlayer": "5.3.4",
82
+ "react-intlayer": "5.3.4",
83
+ "vite-intlayer": "5.3.4"
84
84
  },
85
85
  "devDependencies": {
86
86
  "@tailwindcss/vite": "^4.0.8",
@@ -101,7 +101,7 @@
101
101
  "typescript-eslint": "^8.18.2",
102
102
  "vite": "^6.0.11",
103
103
  "vitest": "^3.0.5",
104
- "@intlayer/backend": "5.3.2"
104
+ "@intlayer/backend": "5.3.3"
105
105
  },
106
106
  "peerDependencies": {
107
107
  "@types/compression": "^1.7.5",
@@ -112,14 +112,15 @@
112
112
  "react-dom": ">=16.0.0",
113
113
  "react-router-dom": ">=6.0.0",
114
114
  "tailwind-merge": "^3.0.2",
115
- "@intlayer/config": "5.3.2",
116
- "@intlayer/core": "5.3.2",
117
- "@intlayer/design-system": "5.3.2",
118
- "@intlayer/editor": "5.3.2",
119
- "@intlayer/editor-react": "5.3.2",
120
- "intlayer": "5.3.2",
121
- "react-intlayer": "5.3.2",
122
- "vite-intlayer": "5.3.2"
115
+ "@intlayer/chokidar": "5.3.4",
116
+ "@intlayer/config": "5.3.4",
117
+ "@intlayer/core": "5.3.4",
118
+ "@intlayer/design-system": "5.3.4",
119
+ "@intlayer/dictionaries-entry": "5.3.4",
120
+ "@intlayer/editor-react": "5.3.4",
121
+ "react-intlayer": "5.3.4",
122
+ "vite-intlayer": "5.3.4",
123
+ "intlayer": "5.3.4"
123
124
  },
124
125
  "engines": {
125
126
  "node": ">=14.18"
@@ -22,22 +22,69 @@ __export(dictionary_controller_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(dictionary_controller_exports);
24
24
  var import_config = require("@intlayer/config");
25
- var import_server = require("@intlayer/editor/server");
26
25
  var import_responseData = require('./../utils/responseData.cjs');
26
+ var import_chokidar = require("@intlayer/chokidar");
27
+ var import_express_intlayer = require("express-intlayer");
27
28
  const writeContentDeclaration = async (req, res, _next) => {
28
29
  try {
29
30
  const dictionaryData = req.body.dictionary;
30
31
  const config = (0, import_config.getConfiguration)();
31
- const result = await (0, import_server.writeContentDeclaration)(dictionaryData, config);
32
+ const result = await (0, import_chokidar.writeContentDeclaration)(dictionaryData, config);
33
+ let description = "";
34
+ switch (result.status) {
35
+ case "updated": {
36
+ description = (0, import_express_intlayer.t)({
37
+ en: "Content declaration updated successfully",
38
+ fr: "D\xE9claration de contenu mise \xE0 jour avec succ\xE8s",
39
+ es: "Declaraci\xF3n de contenido actualizada con \xE9xito"
40
+ });
41
+ break;
42
+ }
43
+ case "reimported in JSON": {
44
+ description = (0, import_express_intlayer.t)({
45
+ en: "Content declaration reimported in JSON successfully",
46
+ fr: "D\xE9claration de contenu r\xE9import\xE9e en JSON avec succ\xE8s",
47
+ es: "Declaraci\xF3n de contenido reimportada en JSON con \xE9xito"
48
+ });
49
+ break;
50
+ }
51
+ case "reimported in new location": {
52
+ description = (0, import_express_intlayer.t)({
53
+ en: "Content declaration reimported in new location successfully",
54
+ fr: "D\xE9claration de contenu r\xE9import\xE9e dans un nouveau emplacement avec succ\xE8s",
55
+ es: "Declaraci\xF3n de contenido reimportada en un nuevo lugar con \xE9xito"
56
+ });
57
+ break;
58
+ }
59
+ default: {
60
+ description = (0, import_express_intlayer.t)({
61
+ en: "Content declaration written successfully",
62
+ fr: "D\xE9claration de contenu \xE9crite avec succ\xE8s",
63
+ es: "Declaraci\xF3n de contenido escrita con \xE9xito"
64
+ });
65
+ break;
66
+ }
67
+ }
32
68
  const formattedResponse = (0, import_responseData.formatResponse)(
33
69
  {
34
- data: result
70
+ data: result,
71
+ message: (0, import_express_intlayer.t)({
72
+ en: "Content declaration written",
73
+ fr: "D\xE9claration de contenu \xE9crite",
74
+ es: "Declaraci\xF3n de contenido escrita"
75
+ }),
76
+ description: (0, import_express_intlayer.t)({
77
+ en: "Content declaration written successfully",
78
+ fr: "D\xE9claration de contenu \xE9crite avec succ\xE8s",
79
+ es: "Declaraci\xF3n de contenido escrita con \xE9xito"
80
+ })
35
81
  }
36
82
  );
37
83
  res.json(formattedResponse);
38
84
  return;
39
85
  } catch (err) {
40
86
  const errorMessage = err ?? "Internal Server Error";
87
+ console.error(errorMessage);
41
88
  const formattedErrorResponse = (0, import_responseData.formatResponse)({
42
89
  error: {
43
90
  message: errorMessage.message ?? "Internal Server Error",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/controllers/dictionary.controller.ts"],"sourcesContent":["import { getConfiguration } from '@intlayer/config';\nimport { type Dictionary } from '@intlayer/core';\nimport type { DictionaryStatus } from '@intlayer/editor';\nimport { writeContentDeclaration as writeContentDeclarationEditor } from '@intlayer/editor/server';\nimport { type ResponseData, formatResponse } from '@utils/responseData';\nimport type { NextFunction, Request, Response } from 'express';\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: Request<any, any, WriteContentDeclarationBody>,\n res: Response<WriteContentDeclarationResult>,\n _next: NextFunction\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 const formattedResponse = formatResponse<WriteContentDeclarationResultData>(\n {\n data: result,\n }\n );\n\n res.json(formattedResponse);\n return;\n } catch (err) {\n const errorMessage =\n (err as { message?: string; status?: number }) ?? 'Internal Server Error';\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 res.json(formattedErrorResponse);\n return;\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAiC;AAGjC,oBAAyE;AACzE,0BAAkD;AAc3C,MAAM,0BAA0B,OACrC,KACA,KACA,UACkB;AAClB,MAAI;AACF,UAAM,iBAAiB,IAAI,KAAK;AAEhC,UAAM,aAAS,gCAAiB;AAEhC,UAAM,SAAS,UAAM,cAAAA,yBAA8B,gBAAgB,MAAM;AAEzE,UAAM,wBAAoB;AAAA,MACxB;AAAA,QACE,MAAM;AAAA,MACR;AAAA,IACF;AAEA,QAAI,KAAK,iBAAiB;AAC1B;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,eACH,OAAiD;AAEpD,UAAM,6BACJ,oCAAkD;AAAA,MAChD,OAAO;AAAA,QACL,SAAS,aAAa,WAAW;AAAA,QACjC,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,MACA,QAAQ,aAAa,UAAU;AAAA,IACjC,CAAC;AAEH,QAAI,KAAK,sBAAsB;AAC/B;AAAA,EACF;AACF;","names":["writeContentDeclarationEditor"]}
1
+ {"version":3,"sources":["../../src/controllers/dictionary.controller.ts"],"sourcesContent":["import { getConfiguration } from '@intlayer/config';\nimport { type Dictionary } from '@intlayer/core';\nimport { type ResponseData, formatResponse } from '@utils/responseData';\nimport {\n writeContentDeclaration as writeContentDeclarationEditor,\n type DictionaryStatus,\n} from '@intlayer/chokidar';\nimport type { NextFunction, Request, Response } from 'express';\nimport { t } from 'express-intlayer';\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: Request<any, any, WriteContentDeclarationBody>,\n res: Response<WriteContentDeclarationResult>,\n _next: NextFunction\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 let description = '';\n\n switch (result.status) {\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 'reimported in new location': {\n description = t({\n en: 'Content declaration reimported in new location 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: 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 }\n );\n\n res.json(formattedResponse);\n return;\n } catch (err) {\n const errorMessage =\n (err as { message?: string; status?: number }) ?? 'Internal Server Error';\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 res.json(formattedErrorResponse);\n return;\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAiC;AAEjC,0BAAkD;AAClD,sBAGO;AAEP,8BAAkB;AAaX,MAAM,0BAA0B,OACrC,KACA,KACA,UACkB;AAClB,MAAI;AACF,UAAM,iBAAiB,IAAI,KAAK;AAEhC,UAAM,aAAS,gCAAiB;AAEhC,UAAM,SAAS,UAAM,gBAAAA,yBAA8B,gBAAgB,MAAM;AAEzE,QAAI,cAAc;AAElB,YAAQ,OAAO,QAAQ;AAAA,MACrB,KAAK,WAAW;AACd,0BAAc,2BAAE;AAAA,UACd,IAAI;AAAA,UACJ,IAAI;AAAA,UACJ,IAAI;AAAA,QACN,CAAC;AACD;AAAA,MACF;AAAA,MACA,KAAK,sBAAsB;AACzB,0BAAc,2BAAE;AAAA,UACd,IAAI;AAAA,UACJ,IAAI;AAAA,UACJ,IAAI;AAAA,QACN,CAAC;AACD;AAAA,MACF;AAAA,MACA,KAAK,8BAA8B;AACjC,0BAAc,2BAAE;AAAA,UACd,IAAI;AAAA,UACJ,IAAI;AAAA,UACJ,IAAI;AAAA,QACN,CAAC;AACD;AAAA,MACF;AAAA,MACA,SAAS;AACP,0BAAc,2BAAE;AAAA,UACd,IAAI;AAAA,UACJ,IAAI;AAAA,UACJ,IAAI;AAAA,QACN,CAAC;AACD;AAAA,MACF;AAAA,IACF;AAEA,UAAM,wBAAoB;AAAA,MACxB;AAAA,QACE,MAAM;AAAA,QACN,aAAS,2BAAE;AAAA,UACT,IAAI;AAAA,UACJ,IAAI;AAAA,UACJ,IAAI;AAAA,QACN,CAAC;AAAA,QACD,iBAAa,2BAAE;AAAA,UACb,IAAI;AAAA,UACJ,IAAI;AAAA,UACJ,IAAI;AAAA,QACN,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI,KAAK,iBAAiB;AAC1B;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,eACH,OAAiD;AAEpD,YAAQ,MAAM,YAAY;AAE1B,UAAM,6BACJ,oCAAkD;AAAA,MAChD,OAAO;AAAA,QACL,SAAS,aAAa,WAAW;AAAA,QACjC,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,MACA,QAAQ,aAAa,UAAU;AAAA,IACjC,CAAC;AAEH,QAAI,KAAK,sBAAsB;AAC/B;AAAA,EACF;AACF;","names":["writeContentDeclarationEditor"]}
@@ -1,20 +1,69 @@
1
1
  import { getConfiguration } from "@intlayer/config";
2
- import { writeContentDeclaration as writeContentDeclarationEditor } from "@intlayer/editor/server";
3
2
  import { formatResponse } from "./../utils/responseData.mjs";
3
+ import {
4
+ writeContentDeclaration as writeContentDeclarationEditor
5
+ } from "@intlayer/chokidar";
6
+ import { t } from "express-intlayer";
4
7
  const writeContentDeclaration = async (req, res, _next) => {
5
8
  try {
6
9
  const dictionaryData = req.body.dictionary;
7
10
  const config = getConfiguration();
8
11
  const result = await writeContentDeclarationEditor(dictionaryData, config);
12
+ let description = "";
13
+ switch (result.status) {
14
+ case "updated": {
15
+ description = t({
16
+ en: "Content declaration updated successfully",
17
+ fr: "D\xE9claration de contenu mise \xE0 jour avec succ\xE8s",
18
+ es: "Declaraci\xF3n de contenido actualizada con \xE9xito"
19
+ });
20
+ break;
21
+ }
22
+ case "reimported in JSON": {
23
+ description = t({
24
+ en: "Content declaration reimported in JSON successfully",
25
+ fr: "D\xE9claration de contenu r\xE9import\xE9e en JSON avec succ\xE8s",
26
+ es: "Declaraci\xF3n de contenido reimportada en JSON con \xE9xito"
27
+ });
28
+ break;
29
+ }
30
+ case "reimported in new location": {
31
+ description = t({
32
+ en: "Content declaration reimported in new location successfully",
33
+ fr: "D\xE9claration de contenu r\xE9import\xE9e dans un nouveau emplacement avec succ\xE8s",
34
+ es: "Declaraci\xF3n de contenido reimportada en un nuevo lugar con \xE9xito"
35
+ });
36
+ break;
37
+ }
38
+ default: {
39
+ description = t({
40
+ en: "Content declaration written successfully",
41
+ fr: "D\xE9claration de contenu \xE9crite avec succ\xE8s",
42
+ es: "Declaraci\xF3n de contenido escrita con \xE9xito"
43
+ });
44
+ break;
45
+ }
46
+ }
9
47
  const formattedResponse = formatResponse(
10
48
  {
11
- data: result
49
+ data: result,
50
+ message: t({
51
+ en: "Content declaration written",
52
+ fr: "D\xE9claration de contenu \xE9crite",
53
+ es: "Declaraci\xF3n de contenido escrita"
54
+ }),
55
+ description: t({
56
+ en: "Content declaration written successfully",
57
+ fr: "D\xE9claration de contenu \xE9crite avec succ\xE8s",
58
+ es: "Declaraci\xF3n de contenido escrita con \xE9xito"
59
+ })
12
60
  }
13
61
  );
14
62
  res.json(formattedResponse);
15
63
  return;
16
64
  } catch (err) {
17
65
  const errorMessage = err ?? "Internal Server Error";
66
+ console.error(errorMessage);
18
67
  const formattedErrorResponse = formatResponse({
19
68
  error: {
20
69
  message: errorMessage.message ?? "Internal Server Error",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/controllers/dictionary.controller.ts"],"sourcesContent":["import { getConfiguration } from '@intlayer/config';\nimport { type Dictionary } from '@intlayer/core';\nimport type { DictionaryStatus } from '@intlayer/editor';\nimport { writeContentDeclaration as writeContentDeclarationEditor } from '@intlayer/editor/server';\nimport { type ResponseData, formatResponse } from '@utils/responseData';\nimport type { NextFunction, Request, Response } from 'express';\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: Request<any, any, WriteContentDeclarationBody>,\n res: Response<WriteContentDeclarationResult>,\n _next: NextFunction\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 const formattedResponse = formatResponse<WriteContentDeclarationResultData>(\n {\n data: result,\n }\n );\n\n res.json(formattedResponse);\n return;\n } catch (err) {\n const errorMessage =\n (err as { message?: string; status?: number }) ?? 'Internal Server Error';\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 res.json(formattedErrorResponse);\n return;\n }\n};\n"],"mappings":"AAAA,SAAS,wBAAwB;AAGjC,SAAS,2BAA2B,qCAAqC;AACzE,SAA4B,sBAAsB;AAc3C,MAAM,0BAA0B,OACrC,KACA,KACA,UACkB;AAClB,MAAI;AACF,UAAM,iBAAiB,IAAI,KAAK;AAEhC,UAAM,SAAS,iBAAiB;AAEhC,UAAM,SAAS,MAAM,8BAA8B,gBAAgB,MAAM;AAEzE,UAAM,oBAAoB;AAAA,MACxB;AAAA,QACE,MAAM;AAAA,MACR;AAAA,IACF;AAEA,QAAI,KAAK,iBAAiB;AAC1B;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,eACH,OAAiD;AAEpD,UAAM,yBACJ,eAAkD;AAAA,MAChD,OAAO;AAAA,QACL,SAAS,aAAa,WAAW;AAAA,QACjC,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,MACA,QAAQ,aAAa,UAAU;AAAA,IACjC,CAAC;AAEH,QAAI,KAAK,sBAAsB;AAC/B;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/controllers/dictionary.controller.ts"],"sourcesContent":["import { getConfiguration } from '@intlayer/config';\nimport { type Dictionary } from '@intlayer/core';\nimport { type ResponseData, formatResponse } from '@utils/responseData';\nimport {\n writeContentDeclaration as writeContentDeclarationEditor,\n type DictionaryStatus,\n} from '@intlayer/chokidar';\nimport type { NextFunction, Request, Response } from 'express';\nimport { t } from 'express-intlayer';\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: Request<any, any, WriteContentDeclarationBody>,\n res: Response<WriteContentDeclarationResult>,\n _next: NextFunction\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 let description = '';\n\n switch (result.status) {\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 'reimported in new location': {\n description = t({\n en: 'Content declaration reimported in new location 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: 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 }\n );\n\n res.json(formattedResponse);\n return;\n } catch (err) {\n const errorMessage =\n (err as { message?: string; status?: number }) ?? 'Internal Server Error';\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 res.json(formattedErrorResponse);\n return;\n }\n};\n"],"mappings":"AAAA,SAAS,wBAAwB;AAEjC,SAA4B,sBAAsB;AAClD;AAAA,EACE,2BAA2B;AAAA,OAEtB;AAEP,SAAS,SAAS;AAaX,MAAM,0BAA0B,OACrC,KACA,KACA,UACkB;AAClB,MAAI;AACF,UAAM,iBAAiB,IAAI,KAAK;AAEhC,UAAM,SAAS,iBAAiB;AAEhC,UAAM,SAAS,MAAM,8BAA8B,gBAAgB,MAAM;AAEzE,QAAI,cAAc;AAElB,YAAQ,OAAO,QAAQ;AAAA,MACrB,KAAK,WAAW;AACd,sBAAc,EAAE;AAAA,UACd,IAAI;AAAA,UACJ,IAAI;AAAA,UACJ,IAAI;AAAA,QACN,CAAC;AACD;AAAA,MACF;AAAA,MACA,KAAK,sBAAsB;AACzB,sBAAc,EAAE;AAAA,UACd,IAAI;AAAA,UACJ,IAAI;AAAA,UACJ,IAAI;AAAA,QACN,CAAC;AACD;AAAA,MACF;AAAA,MACA,KAAK,8BAA8B;AACjC,sBAAc,EAAE;AAAA,UACd,IAAI;AAAA,UACJ,IAAI;AAAA,UACJ,IAAI;AAAA,QACN,CAAC;AACD;AAAA,MACF;AAAA,MACA,SAAS;AACP,sBAAc,EAAE;AAAA,UACd,IAAI;AAAA,UACJ,IAAI;AAAA,UACJ,IAAI;AAAA,QACN,CAAC;AACD;AAAA,MACF;AAAA,IACF;AAEA,UAAM,oBAAoB;AAAA,MACxB;AAAA,QACE,MAAM;AAAA,QACN,SAAS,EAAE;AAAA,UACT,IAAI;AAAA,UACJ,IAAI;AAAA,UACJ,IAAI;AAAA,QACN,CAAC;AAAA,QACD,aAAa,EAAE;AAAA,UACb,IAAI;AAAA,UACJ,IAAI;AAAA,UACJ,IAAI;AAAA,QACN,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI,KAAK,iBAAiB;AAC1B;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,eACH,OAAiD;AAEpD,YAAQ,MAAM,YAAY;AAE1B,UAAM,yBACJ,eAAkD;AAAA,MAChD,OAAO;AAAA,QACL,SAAS,aAAa,WAAW;AAAA,QACjC,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,MACA,QAAQ,aAAa,UAAU;AAAA,IACjC,CAAC;AAEH,QAAI,KAAK,sBAAsB;AAC/B;AAAA,EACF;AACF;","names":[]}
@@ -27,24 +27,39 @@ var import_node_url = require("node:url");
27
27
  var import_config = require("@intlayer/config");
28
28
  var import_config2 = require('./routes/config.routes.cjs');
29
29
  var import_dictionary = require('./routes/dictionary.routes.cjs');
30
+ var import_express_intlayer = require("express-intlayer");
30
31
  var import_compression = __toESM(require("compression"), 1);
31
32
  var import_cookie_parser = __toESM(require("cookie-parser"), 1);
32
33
  var import_cors = __toESM(require("cors"), 1);
33
34
  var import_express = __toESM(require("express"), 1);
34
35
  var import_helmet = __toESM(require("helmet"), 1);
35
36
  var import_mime = __toESM(require("mime"), 1);
37
+ var import_checkPortAvailability = require('./utils/checkPortAvailability.cjs');
36
38
  const import_meta = {};
39
+ const __dirname = (0, import_node_path.dirname)((0, import_node_url.fileURLToPath)(import_meta.url));
40
+ const envFileOptions = {
41
+ env: process.env.NODE_ENV,
42
+ envFile: process.env.ENV_FILE
43
+ };
44
+ const packageJson = JSON.parse(
45
+ (0, import_node_fs.readFileSync)((0, import_node_path.resolve)(__dirname, "../../package.json"), "utf8")
46
+ );
37
47
  const app = (0, import_express.default)();
48
+ app.use((0, import_express_intlayer.intlayer)());
38
49
  const FALLBACK_PORT = 8e3;
39
- const config = (0, import_config.getConfiguration)();
50
+ const config = (0, import_config.getConfiguration)(envFileOptions);
40
51
  const port = config.editor.port ?? FALLBACK_PORT;
41
- const __dirname = (0, import_node_path.dirname)((0, import_node_url.fileURLToPath)(import_meta.url));
42
52
  const clientDistPath = (0, import_node_path.resolve)(__dirname, "../../client/dist");
43
53
  const corsOptions = {
44
54
  origin: "*",
45
55
  credentials: true
46
56
  };
47
57
  const startServer = async (app2) => {
58
+ const isPortAvailable = await (0, import_checkPortAvailability.checkPortAvailability)(port);
59
+ if (!isPortAvailable) {
60
+ console.error(`\x1B[1;31mError: Port ${port} is already in use.\x1B[0m`);
61
+ process.exit(255);
62
+ }
48
63
  app2.disable("x-powered-by");
49
64
  app2.use(
50
65
  (0, import_helmet.default)({
@@ -70,7 +85,17 @@ const startServer = async (app2) => {
70
85
  }
71
86
  });
72
87
  app2.listen(port, () => {
73
- console.log(`Intlayer editor running at http://localhost:${port}`);
88
+ const dotEnvFilePath = (0, import_config.getEnvFilePath)(
89
+ envFileOptions.env,
90
+ envFileOptions.envFile
91
+ );
92
+ console.log(`
93
+ \x1B[1;90mINTLAYER v${packageJson.version}\x1B[0m
94
+
95
+ Editor running at: \x1B[90mhttp://localhost:${port}\x1B[0m
96
+ - Watching application at: \x1B[90m${config.editor.applicationURL}\x1B[0m
97
+ - Environment: ${dotEnvFilePath}
98
+ `);
74
99
  });
75
100
  };
76
101
  startServer(app);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { existsSync, lstatSync } from 'node:fs';\nimport path, { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { getConfiguration } from '@intlayer/config';\nimport { configurationRouter } from '@routes/config.routes';\nimport { dictionaryRouter } from '@routes/dictionary.routes';\nimport compression from 'compression';\nimport cookieParser from 'cookie-parser';\nimport cors, { type CorsOptions } from 'cors';\nimport express, { type Express } from 'express';\nimport helmet from 'helmet';\nimport mime from 'mime';\n\nconst app: Express = express();\n\nconst FALLBACK_PORT = 8000;\nconst config = getConfiguration();\nconst port = config.editor.port ?? FALLBACK_PORT;\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst clientDistPath = resolve(__dirname, '../../client/dist');\n\nconst corsOptions: CorsOptions = {\n origin: '*',\n credentials: true,\n};\n\nconst startServer = async (app: Express) => {\n app.disable('x-powered-by'); // Disabled to prevent attackers from knowing that the app is running Express\n app.use(\n helmet({\n contentSecurityPolicy: false,\n })\n );\n\n app.use(cors(corsOptions));\n\n // Compress all HTTP responses\n app.use(compression());\n\n app.use(express.json());\n\n app.use(cookieParser());\n\n // Parse incoming requests with urlencoded payloads\n app.use(express.urlencoded({ extended: true }));\n\n app.use('/api/dictionary', dictionaryRouter);\n app.use('/api/config', configurationRouter);\n\n app.use(express.static(clientDistPath));\n\n // For single-page applications, redirect all unmatched routes to index.html\n app.get(/(.*)/, (req, res) => {\n const requestedPath = path.join(clientDistPath, req.url); // Full path of the requested file\n\n if (existsSync(requestedPath) && lstatSync(requestedPath).isFile()) {\n // If the requested file exists, determine its MIME type and serve it\n const mimeType =\n mime.getType(requestedPath) ?? 'application/octet-stream';\n res.setHeader('Content-Type', mimeType);\n res.sendFile(requestedPath);\n } else {\n // Otherwise, serve the index.html for React Router fallback\n res.sendFile(resolve(clientDistPath, 'index.html'));\n }\n });\n\n app.listen(port, () => {\n console.log(`Intlayer editor running at http://localhost:${port}`);\n });\n};\n\n// Start it up!\nstartServer(app);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA,qBAAsC;AACtC,uBAAuC;AACvC,sBAA8B;AAC9B,oBAAiC;AACjC,IAAAA,iBAAoC;AACpC,wBAAiC;AACjC,yBAAwB;AACxB,2BAAyB;AACzB,kBAAuC;AACvC,qBAAsC;AACtC,oBAAmB;AACnB,kBAAiB;AAXjB;AAaA,MAAM,UAAe,eAAAC,SAAQ;AAE7B,MAAM,gBAAgB;AACtB,MAAM,aAAS,gCAAiB;AAChC,MAAM,OAAO,OAAO,OAAO,QAAQ;AAEnC,MAAM,gBAAY,8BAAQ,+BAAc,YAAY,GAAG,CAAC;AACxD,MAAM,qBAAiB,0BAAQ,WAAW,mBAAmB;AAE7D,MAAM,cAA2B;AAAA,EAC/B,QAAQ;AAAA,EACR,aAAa;AACf;AAEA,MAAM,cAAc,OAAOC,SAAiB;AAC1C,EAAAA,KAAI,QAAQ,cAAc;AAC1B,EAAAA,KAAI;AAAA,QACF,cAAAC,SAAO;AAAA,MACL,uBAAuB;AAAA,IACzB,CAAC;AAAA,EACH;AAEA,EAAAD,KAAI,QAAI,YAAAE,SAAK,WAAW,CAAC;AAGzB,EAAAF,KAAI,QAAI,mBAAAG,SAAY,CAAC;AAErB,EAAAH,KAAI,IAAI,eAAAD,QAAQ,KAAK,CAAC;AAEtB,EAAAC,KAAI,QAAI,qBAAAI,SAAa,CAAC;AAGtB,EAAAJ,KAAI,IAAI,eAAAD,QAAQ,WAAW,EAAE,UAAU,KAAK,CAAC,CAAC;AAE9C,EAAAC,KAAI,IAAI,mBAAmB,kCAAgB;AAC3C,EAAAA,KAAI,IAAI,eAAe,kCAAmB;AAE1C,EAAAA,KAAI,IAAI,eAAAD,QAAQ,OAAO,cAAc,CAAC;AAGtC,EAAAC,KAAI,IAAI,QAAQ,CAAC,KAAK,QAAQ;AAC5B,UAAM,gBAAgB,iBAAAK,QAAK,KAAK,gBAAgB,IAAI,GAAG;AAEvD,YAAI,2BAAW,aAAa,SAAK,0BAAU,aAAa,EAAE,OAAO,GAAG;AAElE,YAAM,WACJ,YAAAC,QAAK,QAAQ,aAAa,KAAK;AACjC,UAAI,UAAU,gBAAgB,QAAQ;AACtC,UAAI,SAAS,aAAa;AAAA,IAC5B,OAAO;AAEL,UAAI,aAAS,0BAAQ,gBAAgB,YAAY,CAAC;AAAA,IACpD;AAAA,EACF,CAAC;AAED,EAAAN,KAAI,OAAO,MAAM,MAAM;AACrB,YAAQ,IAAI,+CAA+C,IAAI,EAAE;AAAA,EACnE,CAAC;AACH;AAGA,YAAY,GAAG;","names":["import_config","express","app","helmet","cors","compression","cookieParser","path","mime"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { existsSync, lstatSync, readFileSync } from 'node:fs';\nimport path, { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { getConfiguration, getEnvFilePath } from '@intlayer/config';\nimport { configurationRouter } from '@routes/config.routes';\nimport { dictionaryRouter } from '@routes/dictionary.routes';\nimport { intlayer } from 'express-intlayer';\nimport compression from 'compression';\nimport cookieParser from 'cookie-parser';\nimport cors, { type CorsOptions } from 'cors';\nimport express, { type Express } from 'express';\nimport helmet from 'helmet';\nimport mime from 'mime';\nimport { checkPortAvailability } from '@utils/checkPortAvailability';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nconst envFileOptions = {\n env: process.env.NODE_ENV,\n envFile: process.env.ENV_FILE,\n};\n\n// Load package.json\nconst packageJson = JSON.parse(\n readFileSync(resolve(__dirname, '../../package.json'), 'utf8')\n);\n\nconst app: Express = express();\n\n// Load internationalization request handler\napp.use(intlayer());\n\nconst FALLBACK_PORT = 8000;\nconst config = getConfiguration(envFileOptions);\nconst port = config.editor.port ?? FALLBACK_PORT;\n\nconst clientDistPath = resolve(__dirname, '../../client/dist');\n\nconst corsOptions: CorsOptions = {\n origin: '*',\n credentials: true,\n};\n\nconst startServer = async (app: Express) => {\n const isPortAvailable = await checkPortAvailability(port);\n\n if (!isPortAvailable) {\n console.error(`\\x1b[1;31mError: Port ${port} is already in use.\\x1b[0m`);\n process.exit(255);\n }\n\n app.disable('x-powered-by'); // Disabled to prevent attackers from knowing that the app is running Express\n app.use(\n helmet({\n contentSecurityPolicy: false,\n })\n );\n\n app.use(cors(corsOptions));\n\n // Compress all HTTP responses\n app.use(compression());\n\n app.use(express.json());\n\n app.use(cookieParser());\n\n // Parse incoming requests with urlencoded payloads\n app.use(express.urlencoded({ extended: true }));\n\n app.use('/api/dictionary', dictionaryRouter);\n app.use('/api/config', configurationRouter);\n\n app.use(express.static(clientDistPath));\n\n // For single-page applications, redirect all unmatched routes to index.html\n app.get(/(.*)/, (req, res) => {\n const requestedPath = path.join(clientDistPath, req.url); // Full path of the requested file\n\n if (existsSync(requestedPath) && lstatSync(requestedPath).isFile()) {\n // If the requested file exists, determine its MIME type and serve it\n const mimeType =\n mime.getType(requestedPath) ?? 'application/octet-stream';\n res.setHeader('Content-Type', mimeType);\n res.sendFile(requestedPath);\n } else {\n // Otherwise, serve the index.html for React Router fallback\n res.sendFile(resolve(clientDistPath, 'index.html'));\n }\n });\n\n app.listen(port, () => {\n const dotEnvFilePath = getEnvFilePath(\n envFileOptions.env,\n envFileOptions.envFile\n );\n\n console.log(`\n \\x1b[1;90mINTLAYER v${packageJson.version}\\x1b[0m\n\n Editor running at: \\x1b[90mhttp://localhost:${port}\\x1b[0m\n - Watching application at: \\x1b[90m${config.editor.applicationURL}\\x1b[0m\n - Environment: ${dotEnvFilePath}\n `);\n });\n};\n\n// Start it up!\nstartServer(app);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA,qBAAoD;AACpD,uBAAuC;AACvC,sBAA8B;AAC9B,oBAAiD;AACjD,IAAAA,iBAAoC;AACpC,wBAAiC;AACjC,8BAAyB;AACzB,yBAAwB;AACxB,2BAAyB;AACzB,kBAAuC;AACvC,qBAAsC;AACtC,oBAAmB;AACnB,kBAAiB;AACjB,mCAAsC;AAbtC;AAeA,MAAM,gBAAY,8BAAQ,+BAAc,YAAY,GAAG,CAAC;AAExD,MAAM,iBAAiB;AAAA,EACrB,KAAK,QAAQ,IAAI;AAAA,EACjB,SAAS,QAAQ,IAAI;AACvB;AAGA,MAAM,cAAc,KAAK;AAAA,MACvB,iCAAa,0BAAQ,WAAW,oBAAoB,GAAG,MAAM;AAC/D;AAEA,MAAM,UAAe,eAAAC,SAAQ;AAG7B,IAAI,QAAI,kCAAS,CAAC;AAElB,MAAM,gBAAgB;AACtB,MAAM,aAAS,gCAAiB,cAAc;AAC9C,MAAM,OAAO,OAAO,OAAO,QAAQ;AAEnC,MAAM,qBAAiB,0BAAQ,WAAW,mBAAmB;AAE7D,MAAM,cAA2B;AAAA,EAC/B,QAAQ;AAAA,EACR,aAAa;AACf;AAEA,MAAM,cAAc,OAAOC,SAAiB;AAC1C,QAAM,kBAAkB,UAAM,oDAAsB,IAAI;AAExD,MAAI,CAAC,iBAAiB;AACpB,YAAQ,MAAM,yBAAyB,IAAI,4BAA4B;AACvE,YAAQ,KAAK,GAAG;AAAA,EAClB;AAEA,EAAAA,KAAI,QAAQ,cAAc;AAC1B,EAAAA,KAAI;AAAA,QACF,cAAAC,SAAO;AAAA,MACL,uBAAuB;AAAA,IACzB,CAAC;AAAA,EACH;AAEA,EAAAD,KAAI,QAAI,YAAAE,SAAK,WAAW,CAAC;AAGzB,EAAAF,KAAI,QAAI,mBAAAG,SAAY,CAAC;AAErB,EAAAH,KAAI,IAAI,eAAAD,QAAQ,KAAK,CAAC;AAEtB,EAAAC,KAAI,QAAI,qBAAAI,SAAa,CAAC;AAGtB,EAAAJ,KAAI,IAAI,eAAAD,QAAQ,WAAW,EAAE,UAAU,KAAK,CAAC,CAAC;AAE9C,EAAAC,KAAI,IAAI,mBAAmB,kCAAgB;AAC3C,EAAAA,KAAI,IAAI,eAAe,kCAAmB;AAE1C,EAAAA,KAAI,IAAI,eAAAD,QAAQ,OAAO,cAAc,CAAC;AAGtC,EAAAC,KAAI,IAAI,QAAQ,CAAC,KAAK,QAAQ;AAC5B,UAAM,gBAAgB,iBAAAK,QAAK,KAAK,gBAAgB,IAAI,GAAG;AAEvD,YAAI,2BAAW,aAAa,SAAK,0BAAU,aAAa,EAAE,OAAO,GAAG;AAElE,YAAM,WACJ,YAAAC,QAAK,QAAQ,aAAa,KAAK;AACjC,UAAI,UAAU,gBAAgB,QAAQ;AACtC,UAAI,SAAS,aAAa;AAAA,IAC5B,OAAO;AAEL,UAAI,aAAS,0BAAQ,gBAAgB,YAAY,CAAC;AAAA,IACpD;AAAA,EACF,CAAC;AAED,EAAAN,KAAI,OAAO,MAAM,MAAM;AACrB,UAAM,qBAAiB;AAAA,MACrB,eAAe;AAAA,MACf,eAAe;AAAA,IACjB;AAEA,YAAQ,IAAI;AAAA,0BACU,YAAY,OAAO;AAAA;AAAA,2DAEc,IAAI;AAAA,0CACrB,OAAO,OAAO,cAAc;AAAA,kCACpC,cAAc;AAAA,KAC3C;AAAA,EACH,CAAC;AACH;AAGA,YAAY,GAAG;","names":["import_config","express","app","helmet","cors","compression","cookieParser","path","mime"]}
@@ -1,26 +1,41 @@
1
- import { existsSync, lstatSync } from "node:fs";
1
+ import { existsSync, lstatSync, readFileSync } from "node:fs";
2
2
  import path, { dirname, resolve } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
- import { getConfiguration } from "@intlayer/config";
4
+ import { getConfiguration, getEnvFilePath } from "@intlayer/config";
5
5
  import { configurationRouter } from "./routes/config.routes.mjs";
6
6
  import { dictionaryRouter } from "./routes/dictionary.routes.mjs";
7
+ import { intlayer } from "express-intlayer";
7
8
  import compression from "compression";
8
9
  import cookieParser from "cookie-parser";
9
10
  import cors from "cors";
10
11
  import express from "express";
11
12
  import helmet from "helmet";
12
13
  import mime from "mime";
14
+ import { checkPortAvailability } from "./utils/checkPortAvailability.mjs";
15
+ const __dirname = dirname(fileURLToPath(import.meta.url));
16
+ const envFileOptions = {
17
+ env: process.env.NODE_ENV,
18
+ envFile: process.env.ENV_FILE
19
+ };
20
+ const packageJson = JSON.parse(
21
+ readFileSync(resolve(__dirname, "../../package.json"), "utf8")
22
+ );
13
23
  const app = express();
24
+ app.use(intlayer());
14
25
  const FALLBACK_PORT = 8e3;
15
- const config = getConfiguration();
26
+ const config = getConfiguration(envFileOptions);
16
27
  const port = config.editor.port ?? FALLBACK_PORT;
17
- const __dirname = dirname(fileURLToPath(import.meta.url));
18
28
  const clientDistPath = resolve(__dirname, "../../client/dist");
19
29
  const corsOptions = {
20
30
  origin: "*",
21
31
  credentials: true
22
32
  };
23
33
  const startServer = async (app2) => {
34
+ const isPortAvailable = await checkPortAvailability(port);
35
+ if (!isPortAvailable) {
36
+ console.error(`\x1B[1;31mError: Port ${port} is already in use.\x1B[0m`);
37
+ process.exit(255);
38
+ }
24
39
  app2.disable("x-powered-by");
25
40
  app2.use(
26
41
  helmet({
@@ -46,7 +61,17 @@ const startServer = async (app2) => {
46
61
  }
47
62
  });
48
63
  app2.listen(port, () => {
49
- console.log(`Intlayer editor running at http://localhost:${port}`);
64
+ const dotEnvFilePath = getEnvFilePath(
65
+ envFileOptions.env,
66
+ envFileOptions.envFile
67
+ );
68
+ console.log(`
69
+ \x1B[1;90mINTLAYER v${packageJson.version}\x1B[0m
70
+
71
+ Editor running at: \x1B[90mhttp://localhost:${port}\x1B[0m
72
+ - Watching application at: \x1B[90m${config.editor.applicationURL}\x1B[0m
73
+ - Environment: ${dotEnvFilePath}
74
+ `);
50
75
  });
51
76
  };
52
77
  startServer(app);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { existsSync, lstatSync } from 'node:fs';\nimport path, { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { getConfiguration } from '@intlayer/config';\nimport { configurationRouter } from '@routes/config.routes';\nimport { dictionaryRouter } from '@routes/dictionary.routes';\nimport compression from 'compression';\nimport cookieParser from 'cookie-parser';\nimport cors, { type CorsOptions } from 'cors';\nimport express, { type Express } from 'express';\nimport helmet from 'helmet';\nimport mime from 'mime';\n\nconst app: Express = express();\n\nconst FALLBACK_PORT = 8000;\nconst config = getConfiguration();\nconst port = config.editor.port ?? FALLBACK_PORT;\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst clientDistPath = resolve(__dirname, '../../client/dist');\n\nconst corsOptions: CorsOptions = {\n origin: '*',\n credentials: true,\n};\n\nconst startServer = async (app: Express) => {\n app.disable('x-powered-by'); // Disabled to prevent attackers from knowing that the app is running Express\n app.use(\n helmet({\n contentSecurityPolicy: false,\n })\n );\n\n app.use(cors(corsOptions));\n\n // Compress all HTTP responses\n app.use(compression());\n\n app.use(express.json());\n\n app.use(cookieParser());\n\n // Parse incoming requests with urlencoded payloads\n app.use(express.urlencoded({ extended: true }));\n\n app.use('/api/dictionary', dictionaryRouter);\n app.use('/api/config', configurationRouter);\n\n app.use(express.static(clientDistPath));\n\n // For single-page applications, redirect all unmatched routes to index.html\n app.get(/(.*)/, (req, res) => {\n const requestedPath = path.join(clientDistPath, req.url); // Full path of the requested file\n\n if (existsSync(requestedPath) && lstatSync(requestedPath).isFile()) {\n // If the requested file exists, determine its MIME type and serve it\n const mimeType =\n mime.getType(requestedPath) ?? 'application/octet-stream';\n res.setHeader('Content-Type', mimeType);\n res.sendFile(requestedPath);\n } else {\n // Otherwise, serve the index.html for React Router fallback\n res.sendFile(resolve(clientDistPath, 'index.html'));\n }\n });\n\n app.listen(port, () => {\n console.log(`Intlayer editor running at http://localhost:${port}`);\n });\n};\n\n// Start it up!\nstartServer(app);\n"],"mappings":"AAAA,SAAS,YAAY,iBAAiB;AACtC,OAAO,QAAQ,SAAS,eAAe;AACvC,SAAS,qBAAqB;AAC9B,SAAS,wBAAwB;AACjC,SAAS,2BAA2B;AACpC,SAAS,wBAAwB;AACjC,OAAO,iBAAiB;AACxB,OAAO,kBAAkB;AACzB,OAAO,UAAgC;AACvC,OAAO,aAA+B;AACtC,OAAO,YAAY;AACnB,OAAO,UAAU;AAEjB,MAAM,MAAe,QAAQ;AAE7B,MAAM,gBAAgB;AACtB,MAAM,SAAS,iBAAiB;AAChC,MAAM,OAAO,OAAO,OAAO,QAAQ;AAEnC,MAAM,YAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AACxD,MAAM,iBAAiB,QAAQ,WAAW,mBAAmB;AAE7D,MAAM,cAA2B;AAAA,EAC/B,QAAQ;AAAA,EACR,aAAa;AACf;AAEA,MAAM,cAAc,OAAOA,SAAiB;AAC1C,EAAAA,KAAI,QAAQ,cAAc;AAC1B,EAAAA,KAAI;AAAA,IACF,OAAO;AAAA,MACL,uBAAuB;AAAA,IACzB,CAAC;AAAA,EACH;AAEA,EAAAA,KAAI,IAAI,KAAK,WAAW,CAAC;AAGzB,EAAAA,KAAI,IAAI,YAAY,CAAC;AAErB,EAAAA,KAAI,IAAI,QAAQ,KAAK,CAAC;AAEtB,EAAAA,KAAI,IAAI,aAAa,CAAC;AAGtB,EAAAA,KAAI,IAAI,QAAQ,WAAW,EAAE,UAAU,KAAK,CAAC,CAAC;AAE9C,EAAAA,KAAI,IAAI,mBAAmB,gBAAgB;AAC3C,EAAAA,KAAI,IAAI,eAAe,mBAAmB;AAE1C,EAAAA,KAAI,IAAI,QAAQ,OAAO,cAAc,CAAC;AAGtC,EAAAA,KAAI,IAAI,QAAQ,CAAC,KAAK,QAAQ;AAC5B,UAAM,gBAAgB,KAAK,KAAK,gBAAgB,IAAI,GAAG;AAEvD,QAAI,WAAW,aAAa,KAAK,UAAU,aAAa,EAAE,OAAO,GAAG;AAElE,YAAM,WACJ,KAAK,QAAQ,aAAa,KAAK;AACjC,UAAI,UAAU,gBAAgB,QAAQ;AACtC,UAAI,SAAS,aAAa;AAAA,IAC5B,OAAO;AAEL,UAAI,SAAS,QAAQ,gBAAgB,YAAY,CAAC;AAAA,IACpD;AAAA,EACF,CAAC;AAED,EAAAA,KAAI,OAAO,MAAM,MAAM;AACrB,YAAQ,IAAI,+CAA+C,IAAI,EAAE;AAAA,EACnE,CAAC;AACH;AAGA,YAAY,GAAG;","names":["app"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { existsSync, lstatSync, readFileSync } from 'node:fs';\nimport path, { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { getConfiguration, getEnvFilePath } from '@intlayer/config';\nimport { configurationRouter } from '@routes/config.routes';\nimport { dictionaryRouter } from '@routes/dictionary.routes';\nimport { intlayer } from 'express-intlayer';\nimport compression from 'compression';\nimport cookieParser from 'cookie-parser';\nimport cors, { type CorsOptions } from 'cors';\nimport express, { type Express } from 'express';\nimport helmet from 'helmet';\nimport mime from 'mime';\nimport { checkPortAvailability } from '@utils/checkPortAvailability';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nconst envFileOptions = {\n env: process.env.NODE_ENV,\n envFile: process.env.ENV_FILE,\n};\n\n// Load package.json\nconst packageJson = JSON.parse(\n readFileSync(resolve(__dirname, '../../package.json'), 'utf8')\n);\n\nconst app: Express = express();\n\n// Load internationalization request handler\napp.use(intlayer());\n\nconst FALLBACK_PORT = 8000;\nconst config = getConfiguration(envFileOptions);\nconst port = config.editor.port ?? FALLBACK_PORT;\n\nconst clientDistPath = resolve(__dirname, '../../client/dist');\n\nconst corsOptions: CorsOptions = {\n origin: '*',\n credentials: true,\n};\n\nconst startServer = async (app: Express) => {\n const isPortAvailable = await checkPortAvailability(port);\n\n if (!isPortAvailable) {\n console.error(`\\x1b[1;31mError: Port ${port} is already in use.\\x1b[0m`);\n process.exit(255);\n }\n\n app.disable('x-powered-by'); // Disabled to prevent attackers from knowing that the app is running Express\n app.use(\n helmet({\n contentSecurityPolicy: false,\n })\n );\n\n app.use(cors(corsOptions));\n\n // Compress all HTTP responses\n app.use(compression());\n\n app.use(express.json());\n\n app.use(cookieParser());\n\n // Parse incoming requests with urlencoded payloads\n app.use(express.urlencoded({ extended: true }));\n\n app.use('/api/dictionary', dictionaryRouter);\n app.use('/api/config', configurationRouter);\n\n app.use(express.static(clientDistPath));\n\n // For single-page applications, redirect all unmatched routes to index.html\n app.get(/(.*)/, (req, res) => {\n const requestedPath = path.join(clientDistPath, req.url); // Full path of the requested file\n\n if (existsSync(requestedPath) && lstatSync(requestedPath).isFile()) {\n // If the requested file exists, determine its MIME type and serve it\n const mimeType =\n mime.getType(requestedPath) ?? 'application/octet-stream';\n res.setHeader('Content-Type', mimeType);\n res.sendFile(requestedPath);\n } else {\n // Otherwise, serve the index.html for React Router fallback\n res.sendFile(resolve(clientDistPath, 'index.html'));\n }\n });\n\n app.listen(port, () => {\n const dotEnvFilePath = getEnvFilePath(\n envFileOptions.env,\n envFileOptions.envFile\n );\n\n console.log(`\n \\x1b[1;90mINTLAYER v${packageJson.version}\\x1b[0m\n\n Editor running at: \\x1b[90mhttp://localhost:${port}\\x1b[0m\n - Watching application at: \\x1b[90m${config.editor.applicationURL}\\x1b[0m\n - Environment: ${dotEnvFilePath}\n `);\n });\n};\n\n// Start it up!\nstartServer(app);\n"],"mappings":"AAAA,SAAS,YAAY,WAAW,oBAAoB;AACpD,OAAO,QAAQ,SAAS,eAAe;AACvC,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB,sBAAsB;AACjD,SAAS,2BAA2B;AACpC,SAAS,wBAAwB;AACjC,SAAS,gBAAgB;AACzB,OAAO,iBAAiB;AACxB,OAAO,kBAAkB;AACzB,OAAO,UAAgC;AACvC,OAAO,aAA+B;AACtC,OAAO,YAAY;AACnB,OAAO,UAAU;AACjB,SAAS,6BAA6B;AAEtC,MAAM,YAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AAExD,MAAM,iBAAiB;AAAA,EACrB,KAAK,QAAQ,IAAI;AAAA,EACjB,SAAS,QAAQ,IAAI;AACvB;AAGA,MAAM,cAAc,KAAK;AAAA,EACvB,aAAa,QAAQ,WAAW,oBAAoB,GAAG,MAAM;AAC/D;AAEA,MAAM,MAAe,QAAQ;AAG7B,IAAI,IAAI,SAAS,CAAC;AAElB,MAAM,gBAAgB;AACtB,MAAM,SAAS,iBAAiB,cAAc;AAC9C,MAAM,OAAO,OAAO,OAAO,QAAQ;AAEnC,MAAM,iBAAiB,QAAQ,WAAW,mBAAmB;AAE7D,MAAM,cAA2B;AAAA,EAC/B,QAAQ;AAAA,EACR,aAAa;AACf;AAEA,MAAM,cAAc,OAAOA,SAAiB;AAC1C,QAAM,kBAAkB,MAAM,sBAAsB,IAAI;AAExD,MAAI,CAAC,iBAAiB;AACpB,YAAQ,MAAM,yBAAyB,IAAI,4BAA4B;AACvE,YAAQ,KAAK,GAAG;AAAA,EAClB;AAEA,EAAAA,KAAI,QAAQ,cAAc;AAC1B,EAAAA,KAAI;AAAA,IACF,OAAO;AAAA,MACL,uBAAuB;AAAA,IACzB,CAAC;AAAA,EACH;AAEA,EAAAA,KAAI,IAAI,KAAK,WAAW,CAAC;AAGzB,EAAAA,KAAI,IAAI,YAAY,CAAC;AAErB,EAAAA,KAAI,IAAI,QAAQ,KAAK,CAAC;AAEtB,EAAAA,KAAI,IAAI,aAAa,CAAC;AAGtB,EAAAA,KAAI,IAAI,QAAQ,WAAW,EAAE,UAAU,KAAK,CAAC,CAAC;AAE9C,EAAAA,KAAI,IAAI,mBAAmB,gBAAgB;AAC3C,EAAAA,KAAI,IAAI,eAAe,mBAAmB;AAE1C,EAAAA,KAAI,IAAI,QAAQ,OAAO,cAAc,CAAC;AAGtC,EAAAA,KAAI,IAAI,QAAQ,CAAC,KAAK,QAAQ;AAC5B,UAAM,gBAAgB,KAAK,KAAK,gBAAgB,IAAI,GAAG;AAEvD,QAAI,WAAW,aAAa,KAAK,UAAU,aAAa,EAAE,OAAO,GAAG;AAElE,YAAM,WACJ,KAAK,QAAQ,aAAa,KAAK;AACjC,UAAI,UAAU,gBAAgB,QAAQ;AACtC,UAAI,SAAS,aAAa;AAAA,IAC5B,OAAO;AAEL,UAAI,SAAS,QAAQ,gBAAgB,YAAY,CAAC;AAAA,IACpD;AAAA,EACF,CAAC;AAED,EAAAA,KAAI,OAAO,MAAM,MAAM;AACrB,UAAM,iBAAiB;AAAA,MACrB,eAAe;AAAA,MACf,eAAe;AAAA,IACjB;AAEA,YAAQ,IAAI;AAAA,0BACU,YAAY,OAAO;AAAA;AAAA,2DAEc,IAAI;AAAA,0CACrB,OAAO,OAAO,cAAc;AAAA,kCACpC,cAAc;AAAA,KAC3C;AAAA,EACH,CAAC;AACH;AAGA,YAAY,GAAG;","names":["app"]}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var checkPortAvailability_exports = {};
30
+ __export(checkPortAvailability_exports, {
31
+ checkPortAvailability: () => checkPortAvailability
32
+ });
33
+ module.exports = __toCommonJS(checkPortAvailability_exports);
34
+ var import_node_net = __toESM(require("node:net"), 1);
35
+ const checkPortAvailability = (port) => {
36
+ return new Promise((resolve) => {
37
+ const server = import_node_net.default.createServer();
38
+ server.once("error", (err) => {
39
+ if (err.code === "EADDRINUSE") {
40
+ resolve(false);
41
+ } else {
42
+ resolve(true);
43
+ }
44
+ });
45
+ server.once("listening", () => {
46
+ server.close();
47
+ resolve(true);
48
+ });
49
+ server.listen(port);
50
+ });
51
+ };
52
+ // Annotate the CommonJS export names for ESM import in node:
53
+ 0 && (module.exports = {
54
+ checkPortAvailability
55
+ });
56
+ //# sourceMappingURL=checkPortAvailability.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/checkPortAvailability.ts"],"sourcesContent":["import net from 'node:net';\n\nexport const checkPortAvailability = (port: number): Promise<boolean> => {\n return new Promise((resolve) => {\n const server = net.createServer();\n\n server.once('error', (err: any) => {\n if (err.code === 'EADDRINUSE') {\n resolve(false); // Port is in use\n } else {\n resolve(true);\n }\n });\n\n server.once('listening', () => {\n server.close();\n resolve(true); // Port is available\n });\n\n server.listen(port);\n });\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAgB;AAET,MAAM,wBAAwB,CAAC,SAAmC;AACvE,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,SAAS,gBAAAA,QAAI,aAAa;AAEhC,WAAO,KAAK,SAAS,CAAC,QAAa;AACjC,UAAI,IAAI,SAAS,cAAc;AAC7B,gBAAQ,KAAK;AAAA,MACf,OAAO;AACL,gBAAQ,IAAI;AAAA,MACd;AAAA,IACF,CAAC;AAED,WAAO,KAAK,aAAa,MAAM;AAC7B,aAAO,MAAM;AACb,cAAQ,IAAI;AAAA,IACd,CAAC;AAED,WAAO,OAAO,IAAI;AAAA,EACpB,CAAC;AACH;","names":["net"]}
@@ -0,0 +1,22 @@
1
+ import net from "node:net";
2
+ const checkPortAvailability = (port) => {
3
+ return new Promise((resolve) => {
4
+ const server = net.createServer();
5
+ server.once("error", (err) => {
6
+ if (err.code === "EADDRINUSE") {
7
+ resolve(false);
8
+ } else {
9
+ resolve(true);
10
+ }
11
+ });
12
+ server.once("listening", () => {
13
+ server.close();
14
+ resolve(true);
15
+ });
16
+ server.listen(port);
17
+ });
18
+ };
19
+ export {
20
+ checkPortAvailability
21
+ };
22
+ //# sourceMappingURL=checkPortAvailability.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/checkPortAvailability.ts"],"sourcesContent":["import net from 'node:net';\n\nexport const checkPortAvailability = (port: number): Promise<boolean> => {\n return new Promise((resolve) => {\n const server = net.createServer();\n\n server.once('error', (err: any) => {\n if (err.code === 'EADDRINUSE') {\n resolve(false); // Port is in use\n } else {\n resolve(true);\n }\n });\n\n server.once('listening', () => {\n server.close();\n resolve(true); // Port is available\n });\n\n server.listen(port);\n });\n};\n"],"mappings":"AAAA,OAAO,SAAS;AAET,MAAM,wBAAwB,CAAC,SAAmC;AACvE,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,SAAS,IAAI,aAAa;AAEhC,WAAO,KAAK,SAAS,CAAC,QAAa;AACjC,UAAI,IAAI,SAAS,cAAc;AAC7B,gBAAQ,KAAK;AAAA,MACf,OAAO;AACL,gBAAQ,IAAI;AAAA,MACd;AAAA,IACF,CAAC;AAED,WAAO,KAAK,aAAa,MAAM;AAC7B,aAAO,MAAM;AACb,cAAQ,IAAI;AAAA,IACd,CAAC;AAED,WAAO,OAAO,IAAI;AAAA,EACpB,CAAC;AACH;","names":[]}