@isardsat/editorial-server 6.4.3 → 6.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/storage.d.ts +3 -1
- package/dist/lib/storage.js +6 -6
- package/dist/lib/utils/fs.js +10 -4
- package/dist/routes/actions.js +2 -2
- package/dist/routes/data.js +25 -4
- package/package.json +3 -3
package/dist/lib/storage.d.ts
CHANGED
|
@@ -12,7 +12,9 @@ export declare function createStorage(dataDirectory: string): {
|
|
|
12
12
|
}, import("zod").ZodTypeAny, "passthrough">>;
|
|
13
13
|
singleton?: boolean | undefined;
|
|
14
14
|
}>>;
|
|
15
|
-
getContent: (
|
|
15
|
+
getContent: ({ production, }: {
|
|
16
|
+
production?: boolean;
|
|
17
|
+
}) => Promise<EditorialData>;
|
|
16
18
|
getLocalisationMessages: (langCode: string) => Promise<any>;
|
|
17
19
|
saveLocalisationMessages: (messages: any) => Promise<boolean>;
|
|
18
20
|
createItem: (item: EditorialDataObjectWithType) => Promise<import("zod").objectOutputType<{
|
package/dist/lib/storage.js
CHANGED
|
@@ -16,14 +16,14 @@ export function createStorage(dataDirectory) {
|
|
|
16
16
|
/**
|
|
17
17
|
* TODO: This should ideally cache the result of reading the file until an update occurs.
|
|
18
18
|
*/
|
|
19
|
-
async function getContent() {
|
|
20
|
-
return await readFile(dataPath, "utf-8").then((value) => JSON.parse(value));
|
|
19
|
+
async function getContent({ production, }) {
|
|
20
|
+
return await readFile(production ? dataProdPath : dataPath, "utf-8").then((value) => JSON.parse(value));
|
|
21
21
|
}
|
|
22
22
|
async function getLocalisationMessages(langCode) {
|
|
23
23
|
return await readFile(join(dataDirectory, "locales", "messages", `${langCode}.json`), "utf-8").then((value) => JSON.parse(value));
|
|
24
24
|
}
|
|
25
25
|
async function saveContent({ production }) {
|
|
26
|
-
const content = await getContent();
|
|
26
|
+
const content = await getContent({ production: false });
|
|
27
27
|
await writeFileSafe(production ? dataProdPath : dataPath, JSON.stringify(EditorialDataSchema.parse(content), null, 2));
|
|
28
28
|
return true;
|
|
29
29
|
}
|
|
@@ -32,7 +32,7 @@ export function createStorage(dataDirectory) {
|
|
|
32
32
|
return true;
|
|
33
33
|
}
|
|
34
34
|
async function createItem(item) {
|
|
35
|
-
const content = await getContent();
|
|
35
|
+
const content = await getContent({ production: false });
|
|
36
36
|
content[item.type] = content[item.type] ?? {};
|
|
37
37
|
content[item.type][item.id] = EditorialDataItemSchema.parse(item);
|
|
38
38
|
// TODO: Use superjson to safely encode different types.
|
|
@@ -40,7 +40,7 @@ export function createStorage(dataDirectory) {
|
|
|
40
40
|
return item;
|
|
41
41
|
}
|
|
42
42
|
async function updateItem(item) {
|
|
43
|
-
const content = await getContent();
|
|
43
|
+
const content = await getContent({ production: false });
|
|
44
44
|
const oldItem = content[item.type][item.id];
|
|
45
45
|
const newItem = EditorialDataItemSchema.parse({
|
|
46
46
|
...oldItem,
|
|
@@ -53,7 +53,7 @@ export function createStorage(dataDirectory) {
|
|
|
53
53
|
return newItem;
|
|
54
54
|
}
|
|
55
55
|
async function deleteItem(item) {
|
|
56
|
-
const content = await getContent();
|
|
56
|
+
const content = await getContent({ production: false });
|
|
57
57
|
delete content[item.type][item.id];
|
|
58
58
|
// TODO: Use superjson to safely encode different types.
|
|
59
59
|
await writeFileSafe(dataPath, JSON.stringify(content, null, 2));
|
package/dist/lib/utils/fs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { copyFile, rename, writeFile } from
|
|
2
|
-
import { tmpdir } from
|
|
3
|
-
import { basename, dirname, join } from
|
|
1
|
+
import { access, constants, copyFile, rename, writeFile } from "fs/promises";
|
|
2
|
+
import { tmpdir } from "os";
|
|
3
|
+
import { basename, dirname, join } from "path";
|
|
4
4
|
/**
|
|
5
5
|
* This function writes a file in as atomic a way as possible. It first creates
|
|
6
6
|
* a backup of the file to be written to, writes new content to a temporary
|
|
@@ -10,7 +10,13 @@ export async function writeFileSafe(file, contents) {
|
|
|
10
10
|
const fileName = basename(file);
|
|
11
11
|
const destination = join(dirname(file), `${fileName}.${Date.now()}.tmp`);
|
|
12
12
|
try {
|
|
13
|
-
|
|
13
|
+
try {
|
|
14
|
+
await access(file, constants.F_OK);
|
|
15
|
+
await copyFile(file, join(tmpdir(), fileName));
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
// File doesn't exist, skip backup
|
|
19
|
+
}
|
|
14
20
|
await writeFile(destination, contents);
|
|
15
21
|
await rename(destination, file);
|
|
16
22
|
}
|
package/dist/routes/actions.js
CHANGED
|
@@ -29,8 +29,8 @@ export function createActionRoutes(storage, hooks) {
|
|
|
29
29
|
}),
|
|
30
30
|
// TODO: Don't async, let the promises run in the background.
|
|
31
31
|
async (c) => {
|
|
32
|
-
await storage.saveContent({ production:
|
|
33
|
-
const content = await storage.getContent();
|
|
32
|
+
await storage.saveContent({ production: true });
|
|
33
|
+
const content = await storage.getContent({ production: true });
|
|
34
34
|
const schema = await storage.getSchema();
|
|
35
35
|
try {
|
|
36
36
|
const scriptResult = await hooks.onLocalize(content, schema);
|
package/dist/routes/data.js
CHANGED
|
@@ -23,6 +23,18 @@ export function createDataRoutes(config, storage) {
|
|
|
23
23
|
app.openapi(createRoute({
|
|
24
24
|
method: "get",
|
|
25
25
|
path: "/data",
|
|
26
|
+
request: {
|
|
27
|
+
query: z.object({
|
|
28
|
+
lang: z
|
|
29
|
+
.string()
|
|
30
|
+
.optional()
|
|
31
|
+
.openapi({
|
|
32
|
+
param: { name: "lang", in: "query" },
|
|
33
|
+
example: "es_ES",
|
|
34
|
+
}),
|
|
35
|
+
preview: z.string().optional(),
|
|
36
|
+
}),
|
|
37
|
+
},
|
|
26
38
|
responses: {
|
|
27
39
|
200: {
|
|
28
40
|
content: {
|
|
@@ -34,7 +46,8 @@ export function createDataRoutes(config, storage) {
|
|
|
34
46
|
},
|
|
35
47
|
},
|
|
36
48
|
}), async (c) => {
|
|
37
|
-
const
|
|
49
|
+
const { preview } = c.req.valid("query");
|
|
50
|
+
const content = await storage.getContent({ production: !preview });
|
|
38
51
|
return c.json(content);
|
|
39
52
|
});
|
|
40
53
|
app.openapi(createRoute({
|
|
@@ -75,7 +88,7 @@ export function createDataRoutes(config, storage) {
|
|
|
75
88
|
const { itemType } = c.req.valid("param");
|
|
76
89
|
const { lang, preview } = c.req.valid("query");
|
|
77
90
|
const origin = preview ? new URL(c.req.url).origin : publicFilesUrl;
|
|
78
|
-
const content = await storage.getContent();
|
|
91
|
+
const content = await storage.getContent({ production: !preview });
|
|
79
92
|
const schema = await storage.getSchema();
|
|
80
93
|
const collection = content[itemType];
|
|
81
94
|
if (!collection) {
|
|
@@ -95,6 +108,8 @@ export function createDataRoutes(config, storage) {
|
|
|
95
108
|
for (const [key, value] of Object.entries(itemValue)) {
|
|
96
109
|
if (!schema[itemType].fields[key]?.isUploadedFile)
|
|
97
110
|
continue;
|
|
111
|
+
if (value.startsWith("http"))
|
|
112
|
+
continue;
|
|
98
113
|
collection[itemKey][key] = `${origin}/${value}`;
|
|
99
114
|
}
|
|
100
115
|
}
|
|
@@ -110,6 +125,9 @@ export function createDataRoutes(config, storage) {
|
|
|
110
125
|
example: "newsItem",
|
|
111
126
|
}),
|
|
112
127
|
}),
|
|
128
|
+
query: z.object({
|
|
129
|
+
preview: z.string().optional(),
|
|
130
|
+
}),
|
|
113
131
|
},
|
|
114
132
|
responses: {
|
|
115
133
|
200: {
|
|
@@ -123,7 +141,8 @@ export function createDataRoutes(config, storage) {
|
|
|
123
141
|
},
|
|
124
142
|
}), async (c) => {
|
|
125
143
|
const { itemType } = c.req.valid("param");
|
|
126
|
-
const
|
|
144
|
+
const { preview } = c.req.valid("query");
|
|
145
|
+
const content = await storage.getContent({ production: !preview });
|
|
127
146
|
return c.json(Object.keys(content[itemType]));
|
|
128
147
|
});
|
|
129
148
|
app.openapi(createRoute({
|
|
@@ -168,7 +187,7 @@ export function createDataRoutes(config, storage) {
|
|
|
168
187
|
const { itemType, id } = c.req.valid("param");
|
|
169
188
|
const { lang, preview } = c.req.valid("query");
|
|
170
189
|
const origin = preview ? new URL(c.req.url).origin : publicFilesUrl;
|
|
171
|
-
const content = await storage.getContent();
|
|
190
|
+
const content = await storage.getContent({ production: !preview });
|
|
172
191
|
const schema = await storage.getSchema();
|
|
173
192
|
const collection = content[itemType];
|
|
174
193
|
if (!collection) {
|
|
@@ -191,6 +210,8 @@ export function createDataRoutes(config, storage) {
|
|
|
191
210
|
for (const [key, value] of Object.entries(item)) {
|
|
192
211
|
if (!schema[itemType].fields[key]?.isUploadedFile)
|
|
193
212
|
continue;
|
|
213
|
+
if (value.startsWith("http"))
|
|
214
|
+
continue;
|
|
194
215
|
item[key] = `${origin}/${value}`;
|
|
195
216
|
}
|
|
196
217
|
return c.json(item);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@isardsat/editorial-server",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"hono": "^4.6.20",
|
|
15
15
|
"yaml": "^2.7.0",
|
|
16
16
|
"zod": "^3.24.1",
|
|
17
|
-
"@isardsat/editorial-admin": "^6.
|
|
18
|
-
"@isardsat/editorial-common": "^6.
|
|
17
|
+
"@isardsat/editorial-admin": "^6.5.0",
|
|
18
|
+
"@isardsat/editorial-common": "^6.5.0"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@tsconfig/node22": "^22.0.0",
|