@opengis/cms 0.0.61 → 0.0.62
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +131 -131
- package/dist/{EditCollectionPage-3Q57ptN3.js → EditCollectionPage-C4uNmBJf.js} +1 -1
- package/dist/{contentForm-CLStrfSg.js → contentForm-CcFbUeal.js} +144 -146
- package/dist/index.js +1 -1
- package/dist/{vs-builder-preview-BH4VAM3a.js → vs-builder-preview-DL3RYMp7.js} +11 -12
- package/dist/vs-form-custom-datatable-D880w8gx.js +493 -0
- package/input-types.json +9 -9
- package/locales/en.json +815 -815
- package/locales/uk.json +813 -813
- package/module/cms/cls/content.status.json +17 -17
- package/module/cms/cls/user_type.json +9 -9
- package/module/cms/form/admin.users.form.json +77 -77
- package/module/cms/select/cms.page_type.sql +1 -1
- package/module/cms/select/news_tag_id.sql +11 -11
- package/module/cms/table/admin.users.table.json +53 -53
- package/module/cms/table/collection.default.table.json +96 -96
- package/module/cms/table/single.default.table.json +116 -116
- package/package.json +69 -69
- package/plugin.js +43 -43
- package/server/app.js +35 -35
- package/server/config.js +4 -4
- package/server/functions/getContent.js +45 -45
- package/server/functions/getDraftKey.js +22 -22
- package/server/functions/getSearchData.js +31 -31
- package/server/functions/getTags.js +30 -30
- package/server/functions/getUser.js +27 -27
- package/server/functions/utils/mock.reply.js +55 -55
- package/server/index.js +22 -22
- package/server/migrations/fixes.sql +132 -132
- package/server/migrations/site.sql +596 -596
- package/server/plugins/adminHook.js +78 -78
- package/server/plugins/hook.js +59 -59
- package/server/plugins/vite.js +75 -75
- package/server/routes/category/controllers/cms.category.delete.js +21 -21
- package/server/routes/category/controllers/cms.category.get.js +17 -17
- package/server/routes/category/controllers/cms.category.list.js +16 -16
- package/server/routes/category/controllers/cms.category.post.js +21 -21
- package/server/routes/category/controllers/cms.category.put.js +23 -23
- package/server/routes/category/index.mjs +22 -22
- package/server/routes/cms/controllers/cmsStat.js +55 -55
- package/server/routes/cms/controllers/cmsSuggest.js +57 -57
- package/server/routes/cms/controllers/deleteContent.js +113 -113
- package/server/routes/cms/controllers/deleteMedia.js +76 -76
- package/server/routes/cms/controllers/downloadMedia.js +84 -84
- package/server/routes/cms/controllers/getContent.js +113 -113
- package/server/routes/cms/controllers/getContentBySlug.js +93 -93
- package/server/routes/cms/controllers/insertContent.js +226 -226
- package/server/routes/cms/controllers/listMedia.js +155 -155
- package/server/routes/cms/controllers/metadataMedia.js +39 -39
- package/server/routes/cms/controllers/properties.get.js +18 -18
- package/server/routes/cms/controllers/properties.post.js +99 -99
- package/server/routes/cms/controllers/searchContent.js +214 -214
- package/server/routes/cms/controllers/translate.js +89 -89
- package/server/routes/cms/controllers/updateContent.js +231 -231
- package/server/routes/cms/controllers/uploadMedia.js +79 -79
- package/server/routes/cms/functions/getSettings.js +48 -48
- package/server/routes/cms/index.mjs +112 -112
- package/server/routes/cms/utils/additionalData.js +35 -35
- package/server/routes/cms/utils/getCollection.js +89 -89
- package/server/routes/cms/utils/getSingle.js +188 -188
- package/server/routes/cms/utils/inputTypes.js +5 -5
- package/server/routes/cms/utils/insertContentLocalization.js +104 -104
- package/server/routes/cms/utils/requestTranslation.js +135 -135
- package/server/routes/cms/utils/updateLocalization.js +42 -42
- package/server/routes/cmsSpace/controllers/deleteSpace.js +26 -26
- package/server/routes/cmsSpace/controllers/getSpaces.js +28 -28
- package/server/routes/cmsSpace/controllers/insertSpace.js +22 -22
- package/server/routes/cmsSpace/controllers/updateSpace.js +24 -24
- package/server/routes/cmsSpace/index.mjs +20 -20
- package/server/routes/contentType/controllers/addContentType.js +160 -160
- package/server/routes/contentType/controllers/contentTypeList.js +47 -47
- package/server/routes/contentType/controllers/delContentType.js +75 -75
- package/server/routes/contentType/controllers/editContentType.js +70 -70
- package/server/routes/contentType/controllers/getContentType.js +57 -57
- package/server/routes/contentType/index.mjs +35 -35
- package/server/routes/contentType/utils/updateContents.js +44 -44
- package/server/routes/contentType/utils/updateCustomContentTable.js +53 -53
- package/server/routes/feedback/controllers/email.list.js +24 -24
- package/server/routes/feedback/controllers/feedback.js +48 -48
- package/server/routes/feedback/controllers/feedback.list.js +37 -37
- package/server/routes/feedback/controllers/news.subscriptions.js +44 -44
- package/server/routes/feedback/index.mjs +71 -71
- package/server/routes/logs/controllers/export.user.logs.js +77 -77
- package/server/routes/logs/controllers/user.logs.js +44 -44
- package/server/routes/logs/index.mjs +9 -9
- package/server/routes/menu/controllers/addMenu.js +37 -37
- package/server/routes/menu/controllers/delMenu.js +31 -31
- package/server/routes/menu/controllers/editMenu.js +41 -41
- package/server/routes/menu/controllers/getMenu.js +24 -24
- package/server/routes/menu/functions/getMenu.js +50 -50
- package/server/routes/menu/index.mjs +13 -13
- package/server/routes/migration/controllers/collectionToCustom.js +137 -137
- package/server/routes/migration/index.mjs +8 -8
- package/server/routes/root.mjs +8 -8
- package/server/routes/tags/controllers/add.tags.js +24 -24
- package/server/routes/tags/controllers/del.tags.js +19 -19
- package/server/routes/tags/controllers/edit.tags.js +25 -25
- package/server/routes/tags/controllers/get.tags.js +15 -15
- package/server/routes/tags/index.mjs +14 -14
- package/server/templates/cls/cms.category_type.json +9 -9
- package/server/templates/cls/cms.content_review_status.json +9 -9
- package/server/templates/cls/cms.content_status.json +9 -9
- package/server/templates/cls/cms.content_type.json +9 -9
- package/server/templates/cls/cms.lang.json +9 -9
- package/server/templates/page/login.html +126 -126
- package/utils.d.ts +52 -52
- package/utils.js +8 -8
- package/dist/getField-CpwVE28P.js +0 -179
- package/dist/vs-form-custom-datatable-BDZo48w3.js +0 -317
|
@@ -1,135 +1,135 @@
|
|
|
1
|
-
import { config } from "@opengis/fastify-table/utils.js";
|
|
2
|
-
|
|
3
|
-
const { host = 'https://translate.softpro.ua', key = '' } = config.integrations?.translation || {};
|
|
4
|
-
|
|
5
|
-
const divider = ' <divider> ';
|
|
6
|
-
|
|
7
|
-
// Wrap dot notation keys in quotes
|
|
8
|
-
export const arrayToPhrases = (arr, prefix = 'item', mainIdx = null) => {
|
|
9
|
-
if (!arr || !arr.length) return [];
|
|
10
|
-
|
|
11
|
-
return arr.flatMap((obj, idx) => {
|
|
12
|
-
const currentMainIdx = mainIdx ?? idx;
|
|
13
|
-
|
|
14
|
-
return Object.entries(obj).flatMap(([key, value]) => {
|
|
15
|
-
if (Array.isArray(value)) {
|
|
16
|
-
return arrayToPhrases(value, `${prefix}.${key}`, currentMainIdx);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return [{
|
|
20
|
-
prefix,
|
|
21
|
-
value,
|
|
22
|
-
key,
|
|
23
|
-
mainIdx: currentMainIdx,
|
|
24
|
-
idx,
|
|
25
|
-
}];
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
export default async function requestTranslation(entries, from = 'uk', to) {
|
|
31
|
-
// Flatten all phrases
|
|
32
|
-
const phrasesWithMeta = entries.flatMap(([key, value]) =>
|
|
33
|
-
Array.isArray(value) ? arrayToPhrases(value, key) : [{ key, value, prefix: key }]
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
// Translate each phrase independently
|
|
37
|
-
const translatedPhrases = await Promise.all(
|
|
38
|
-
phrasesWithMeta.map(async ({ key, idx, prefix, value, mainIdx }) => {
|
|
39
|
-
if (!value || typeof value === 'number' || value?.startsWith?.('/files/')) {
|
|
40
|
-
return { key, idx, mainIdx, prefix, value, skip: true }; // fallback to original
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
const parts =
|
|
45
|
-
typeof value === 'string' && value.startsWith('<') && value.endsWith('>')
|
|
46
|
-
? [...value.matchAll(/(<[^>]+>)|([^<]+)/gs)].map(([, tag, str]) =>
|
|
47
|
-
tag
|
|
48
|
-
? { tag }
|
|
49
|
-
: { str, tIndex: null, skip: !str.trim() || /^[—–\-.: ]+$/.test(str.trim()) ? true : false, preSpace: str.startsWith(' ') ? ' ' : '', postSpace: str.endsWith(' ') ? ' ' : '' }
|
|
50
|
-
)
|
|
51
|
-
: [{ str: value, tIndex: 0, skip: false }];
|
|
52
|
-
|
|
53
|
-
// assign translation index only to fragments that should be translated
|
|
54
|
-
const q = [];
|
|
55
|
-
parts.forEach((p) => {
|
|
56
|
-
if (!p.tag && !p.skip) {
|
|
57
|
-
p.tIndex = q.length;
|
|
58
|
-
q.push(p.str);
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
const resp = await fetch(`${host}/translate`, {
|
|
63
|
-
method: "POST",
|
|
64
|
-
headers: { "Content-Type": "application/json" },
|
|
65
|
-
body: JSON.stringify({
|
|
66
|
-
q,
|
|
67
|
-
source: from || "auto",
|
|
68
|
-
target: to,
|
|
69
|
-
format: "text",
|
|
70
|
-
api_key: key
|
|
71
|
-
}),
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
if (resp.status !== 200 || resp.headers.get('content-type') !== 'application/json') {
|
|
75
|
-
const err = await resp.text();
|
|
76
|
-
console.warn('translation request error', resp.status, err);
|
|
77
|
-
return { key, idx, prefix, value, error: err }; // fallback to original
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const body = await resp.json();
|
|
81
|
-
const translated = body.translatedText || [];
|
|
82
|
-
|
|
83
|
-
const resultValue = parts
|
|
84
|
-
.map((p) => {
|
|
85
|
-
if (p.tag) return p.tag;
|
|
86
|
-
if (p.skip) return p.str; // keep original punctuation/whitespace
|
|
87
|
-
const txt = translated[p.tIndex] ?? p.str ?? '';
|
|
88
|
-
return `${p.preSpace || ''}${txt}${p.postSpace || ''}`; // restore spaces
|
|
89
|
-
})
|
|
90
|
-
.join('');
|
|
91
|
-
|
|
92
|
-
return { key, idx, mainIdx, prefix, value: resultValue || value };
|
|
93
|
-
} catch (err) {
|
|
94
|
-
console.warn('translation request failed', err.toString());
|
|
95
|
-
return { key, idx, mainIdx, prefix, value, error: err.toString() }; // fallback
|
|
96
|
-
}
|
|
97
|
-
})
|
|
98
|
-
);
|
|
99
|
-
|
|
100
|
-
const result = translatedPhrases.reduce((acc, curr) => {
|
|
101
|
-
const { key, idx, prefix: prefix1, value, mainIdx } = curr;
|
|
102
|
-
const [prefix, subkey] = prefix1.split('.');
|
|
103
|
-
|
|
104
|
-
if (!acc[`${prefix}:${to}`]) {
|
|
105
|
-
acc[`${prefix}:${to}`] = Array.isArray(entries.find(e => e[0] === prefix)[1]) ? [] : null;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (subkey && Array.isArray(entries.find(e => e[0] === prefix)[1])) {
|
|
109
|
-
if (!acc[`${prefix}:${to}`][mainIdx]) {
|
|
110
|
-
acc[`${prefix}:${to}`][mainIdx] = {};
|
|
111
|
-
}
|
|
112
|
-
if (!acc[`${prefix}:${to}`][mainIdx][subkey]) {
|
|
113
|
-
acc[`${prefix}:${to}`][mainIdx][subkey] = [];
|
|
114
|
-
}
|
|
115
|
-
if (!acc[`${prefix}:${to}`][mainIdx][subkey]?.[idx]) {
|
|
116
|
-
acc[`${prefix}:${to}`][mainIdx][subkey][idx] = {};
|
|
117
|
-
}
|
|
118
|
-
acc[`${prefix}:${to}`][mainIdx][subkey][idx][key] = value;
|
|
119
|
-
// console.log(prefix, to, idx, subkey, mainIdx, key);
|
|
120
|
-
} else if (Array.isArray(entries.find(e => e[0] === prefix)[1])) {
|
|
121
|
-
if (!acc[`${prefix}:${to}`][idx]) {
|
|
122
|
-
acc[`${prefix}:${to}`][idx] = {};
|
|
123
|
-
}
|
|
124
|
-
acc[`${prefix}:${to}`][idx][key] = value;
|
|
125
|
-
} else {
|
|
126
|
-
acc[`${prefix}:${to}`] = value;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return acc;
|
|
130
|
-
}, {});
|
|
131
|
-
|
|
132
|
-
const errors = translatedPhrases.filter(({ error }) => !!error).length;
|
|
133
|
-
|
|
134
|
-
return { result, errors };
|
|
135
|
-
}
|
|
1
|
+
import { config } from "@opengis/fastify-table/utils.js";
|
|
2
|
+
|
|
3
|
+
const { host = 'https://translate.softpro.ua', key = '' } = config.integrations?.translation || {};
|
|
4
|
+
|
|
5
|
+
const divider = ' <divider> ';
|
|
6
|
+
|
|
7
|
+
// Wrap dot notation keys in quotes
|
|
8
|
+
export const arrayToPhrases = (arr, prefix = 'item', mainIdx = null) => {
|
|
9
|
+
if (!arr || !arr.length) return [];
|
|
10
|
+
|
|
11
|
+
return arr.flatMap((obj, idx) => {
|
|
12
|
+
const currentMainIdx = mainIdx ?? idx;
|
|
13
|
+
|
|
14
|
+
return Object.entries(obj).flatMap(([key, value]) => {
|
|
15
|
+
if (Array.isArray(value)) {
|
|
16
|
+
return arrayToPhrases(value, `${prefix}.${key}`, currentMainIdx);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return [{
|
|
20
|
+
prefix,
|
|
21
|
+
value,
|
|
22
|
+
key,
|
|
23
|
+
mainIdx: currentMainIdx,
|
|
24
|
+
idx,
|
|
25
|
+
}];
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default async function requestTranslation(entries, from = 'uk', to) {
|
|
31
|
+
// Flatten all phrases
|
|
32
|
+
const phrasesWithMeta = entries.flatMap(([key, value]) =>
|
|
33
|
+
Array.isArray(value) ? arrayToPhrases(value, key) : [{ key, value, prefix: key }]
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
// Translate each phrase independently
|
|
37
|
+
const translatedPhrases = await Promise.all(
|
|
38
|
+
phrasesWithMeta.map(async ({ key, idx, prefix, value, mainIdx }) => {
|
|
39
|
+
if (!value || typeof value === 'number' || value?.startsWith?.('/files/')) {
|
|
40
|
+
return { key, idx, mainIdx, prefix, value, skip: true }; // fallback to original
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const parts =
|
|
45
|
+
typeof value === 'string' && value.startsWith('<') && value.endsWith('>')
|
|
46
|
+
? [...value.matchAll(/(<[^>]+>)|([^<]+)/gs)].map(([, tag, str]) =>
|
|
47
|
+
tag
|
|
48
|
+
? { tag }
|
|
49
|
+
: { str, tIndex: null, skip: !str.trim() || /^[—–\-.: ]+$/.test(str.trim()) ? true : false, preSpace: str.startsWith(' ') ? ' ' : '', postSpace: str.endsWith(' ') ? ' ' : '' }
|
|
50
|
+
)
|
|
51
|
+
: [{ str: value, tIndex: 0, skip: false }];
|
|
52
|
+
|
|
53
|
+
// assign translation index only to fragments that should be translated
|
|
54
|
+
const q = [];
|
|
55
|
+
parts.forEach((p) => {
|
|
56
|
+
if (!p.tag && !p.skip) {
|
|
57
|
+
p.tIndex = q.length;
|
|
58
|
+
q.push(p.str);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const resp = await fetch(`${host}/translate`, {
|
|
63
|
+
method: "POST",
|
|
64
|
+
headers: { "Content-Type": "application/json" },
|
|
65
|
+
body: JSON.stringify({
|
|
66
|
+
q,
|
|
67
|
+
source: from || "auto",
|
|
68
|
+
target: to,
|
|
69
|
+
format: "text",
|
|
70
|
+
api_key: key
|
|
71
|
+
}),
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
if (resp.status !== 200 || resp.headers.get('content-type') !== 'application/json') {
|
|
75
|
+
const err = await resp.text();
|
|
76
|
+
console.warn('translation request error', resp.status, err);
|
|
77
|
+
return { key, idx, prefix, value, error: err }; // fallback to original
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const body = await resp.json();
|
|
81
|
+
const translated = body.translatedText || [];
|
|
82
|
+
|
|
83
|
+
const resultValue = parts
|
|
84
|
+
.map((p) => {
|
|
85
|
+
if (p.tag) return p.tag;
|
|
86
|
+
if (p.skip) return p.str; // keep original punctuation/whitespace
|
|
87
|
+
const txt = translated[p.tIndex] ?? p.str ?? '';
|
|
88
|
+
return `${p.preSpace || ''}${txt}${p.postSpace || ''}`; // restore spaces
|
|
89
|
+
})
|
|
90
|
+
.join('');
|
|
91
|
+
|
|
92
|
+
return { key, idx, mainIdx, prefix, value: resultValue || value };
|
|
93
|
+
} catch (err) {
|
|
94
|
+
console.warn('translation request failed', err.toString());
|
|
95
|
+
return { key, idx, mainIdx, prefix, value, error: err.toString() }; // fallback
|
|
96
|
+
}
|
|
97
|
+
})
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
const result = translatedPhrases.reduce((acc, curr) => {
|
|
101
|
+
const { key, idx, prefix: prefix1, value, mainIdx } = curr;
|
|
102
|
+
const [prefix, subkey] = prefix1.split('.');
|
|
103
|
+
|
|
104
|
+
if (!acc[`${prefix}:${to}`]) {
|
|
105
|
+
acc[`${prefix}:${to}`] = Array.isArray(entries.find(e => e[0] === prefix)[1]) ? [] : null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (subkey && Array.isArray(entries.find(e => e[0] === prefix)[1])) {
|
|
109
|
+
if (!acc[`${prefix}:${to}`][mainIdx]) {
|
|
110
|
+
acc[`${prefix}:${to}`][mainIdx] = {};
|
|
111
|
+
}
|
|
112
|
+
if (!acc[`${prefix}:${to}`][mainIdx][subkey]) {
|
|
113
|
+
acc[`${prefix}:${to}`][mainIdx][subkey] = [];
|
|
114
|
+
}
|
|
115
|
+
if (!acc[`${prefix}:${to}`][mainIdx][subkey]?.[idx]) {
|
|
116
|
+
acc[`${prefix}:${to}`][mainIdx][subkey][idx] = {};
|
|
117
|
+
}
|
|
118
|
+
acc[`${prefix}:${to}`][mainIdx][subkey][idx][key] = value;
|
|
119
|
+
// console.log(prefix, to, idx, subkey, mainIdx, key);
|
|
120
|
+
} else if (Array.isArray(entries.find(e => e[0] === prefix)[1])) {
|
|
121
|
+
if (!acc[`${prefix}:${to}`][idx]) {
|
|
122
|
+
acc[`${prefix}:${to}`][idx] = {};
|
|
123
|
+
}
|
|
124
|
+
acc[`${prefix}:${to}`][idx][key] = value;
|
|
125
|
+
} else {
|
|
126
|
+
acc[`${prefix}:${to}`] = value;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return acc;
|
|
130
|
+
}, {});
|
|
131
|
+
|
|
132
|
+
const errors = translatedPhrases.filter(({ error }) => !!error).length;
|
|
133
|
+
|
|
134
|
+
return { result, errors };
|
|
135
|
+
}
|
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
import { dataInsert, getTemplate } from "@opengis/fastify-table/utils.js";
|
|
2
|
-
|
|
3
|
-
export default async function updateLocalization(pg, id, body, contentTypeId, uid) {
|
|
4
|
-
if (!pg || !id || !body || !contentTypeId) { return null };
|
|
5
|
-
|
|
6
|
-
const contentColumns = await pg.query('select content_type_id as ctid, name as ctname, table_name as dbtable, columns from site.content_types where content_type_id in (select content_type_id from site.contents where content_id=$1) or content_type_id=$2 order by content_type_id = \'pages\'', [id, contentTypeId]).then(el => el.rows?.[0]?.columns || []);
|
|
7
|
-
|
|
8
|
-
// const contentColumns = await pg.query('select columns from site.content_types where content_type_id=$1', [contentTypeId])
|
|
9
|
-
// .then(el => el.rows?.[0]?.columns || []);
|
|
10
|
-
|
|
11
|
-
const loadTable = contentTypeId === 'pages'
|
|
12
|
-
? await getTemplate('table', 'single.default.table')
|
|
13
|
-
: await getTemplate('table', 'collection.default.table');
|
|
14
|
-
|
|
15
|
-
const columns = (loadTable?.columns || []).concat((contentColumns || []).filter(col => loadTable?.columns.findIndex(el => el.name === col.name) === -1));
|
|
16
|
-
|
|
17
|
-
await pg.query('delete from site.localization where object_id=$1', [id]);
|
|
18
|
-
|
|
19
|
-
const schemaKeys = columns.filter(el => el?.name && el.localization).map(el => el.name);
|
|
20
|
-
|
|
21
|
-
const bodyKeys = Object.keys(body || {}).filter(key => body[key] && key.includes(':') && key.split(':').pop() && schemaKeys.includes(key.split(':').shift()));
|
|
22
|
-
const obj = bodyKeys.reduce((acc, curr) => ({ ...acc, [curr]: body[curr] }), {});
|
|
23
|
-
|
|
24
|
-
if (bodyKeys.length === 0) { return null; }
|
|
25
|
-
|
|
26
|
-
const arr = Object.keys(obj).reduce((acc, curr) => {
|
|
27
|
-
acc.push({
|
|
28
|
-
field_key: curr,
|
|
29
|
-
field_value: body[curr],
|
|
30
|
-
object_id: id,
|
|
31
|
-
});
|
|
32
|
-
return acc;
|
|
33
|
-
}, []);
|
|
34
|
-
|
|
35
|
-
await Promise.all(arr.map(async row => dataInsert({
|
|
36
|
-
pg,
|
|
37
|
-
table: 'site.localization',
|
|
38
|
-
data: row,
|
|
39
|
-
uid,
|
|
40
|
-
})));
|
|
41
|
-
|
|
42
|
-
return obj;
|
|
1
|
+
import { dataInsert, getTemplate } from "@opengis/fastify-table/utils.js";
|
|
2
|
+
|
|
3
|
+
export default async function updateLocalization(pg, id, body, contentTypeId, uid) {
|
|
4
|
+
if (!pg || !id || !body || !contentTypeId) { return null };
|
|
5
|
+
|
|
6
|
+
const contentColumns = await pg.query('select content_type_id as ctid, name as ctname, table_name as dbtable, columns from site.content_types where content_type_id in (select content_type_id from site.contents where content_id=$1) or content_type_id=$2 order by content_type_id = \'pages\'', [id, contentTypeId]).then(el => el.rows?.[0]?.columns || []);
|
|
7
|
+
|
|
8
|
+
// const contentColumns = await pg.query('select columns from site.content_types where content_type_id=$1', [contentTypeId])
|
|
9
|
+
// .then(el => el.rows?.[0]?.columns || []);
|
|
10
|
+
|
|
11
|
+
const loadTable = contentTypeId === 'pages'
|
|
12
|
+
? await getTemplate('table', 'single.default.table')
|
|
13
|
+
: await getTemplate('table', 'collection.default.table');
|
|
14
|
+
|
|
15
|
+
const columns = (loadTable?.columns || []).concat((contentColumns || []).filter(col => loadTable?.columns.findIndex(el => el.name === col.name) === -1));
|
|
16
|
+
|
|
17
|
+
await pg.query('delete from site.localization where object_id=$1', [id]);
|
|
18
|
+
|
|
19
|
+
const schemaKeys = columns.filter(el => el?.name && el.localization).map(el => el.name);
|
|
20
|
+
|
|
21
|
+
const bodyKeys = Object.keys(body || {}).filter(key => body[key] && key.includes(':') && key.split(':').pop() && schemaKeys.includes(key.split(':').shift()));
|
|
22
|
+
const obj = bodyKeys.reduce((acc, curr) => ({ ...acc, [curr]: body[curr] }), {});
|
|
23
|
+
|
|
24
|
+
if (bodyKeys.length === 0) { return null; }
|
|
25
|
+
|
|
26
|
+
const arr = Object.keys(obj).reduce((acc, curr) => {
|
|
27
|
+
acc.push({
|
|
28
|
+
field_key: curr,
|
|
29
|
+
field_value: body[curr],
|
|
30
|
+
object_id: id,
|
|
31
|
+
});
|
|
32
|
+
return acc;
|
|
33
|
+
}, []);
|
|
34
|
+
|
|
35
|
+
await Promise.all(arr.map(async row => dataInsert({
|
|
36
|
+
pg,
|
|
37
|
+
table: 'site.localization',
|
|
38
|
+
data: row,
|
|
39
|
+
uid,
|
|
40
|
+
})));
|
|
41
|
+
|
|
42
|
+
return obj;
|
|
43
43
|
}
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import { dataDelete, pgClients } from '@opengis/fastify-table/utils.js';
|
|
2
|
-
|
|
3
|
-
export default async function deleteSpace({ pg = pgClients.client, user, params, headers = {} }, reply) {
|
|
4
|
-
return null;
|
|
5
|
-
if (!params?.id) { return reply.status(400).send('not enough params: id'); }
|
|
6
|
-
if (!pg?.pk) { return reply.status(400).send('empty pg'); }
|
|
7
|
-
if (!pg?.pk?.['site.spaces']) { return reply.status(400).send('table not found: site.spaces'); }
|
|
8
|
-
|
|
9
|
-
if (params?.id && params.id === 'default') {
|
|
10
|
-
return reply.status(400).send('default space cannot be deleted');
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const exists = await pg.query('select space_id from site.spaces where space_id=$1', [params.id]).then(el => el.rows?.[0]?.space_id);
|
|
14
|
-
if (!exists) { return reply.status(404).send('space not found: ' + params.id); }
|
|
15
|
-
|
|
16
|
-
const { referer } = headers;
|
|
17
|
-
|
|
18
|
-
const res = await dataDelete({
|
|
19
|
-
pg,
|
|
20
|
-
table: 'site.spaces',
|
|
21
|
-
id: params?.id,
|
|
22
|
-
uid: user?.uid,
|
|
23
|
-
referer,
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
return { id: params.id, ...res || {} };
|
|
1
|
+
import { dataDelete, pgClients } from '@opengis/fastify-table/utils.js';
|
|
2
|
+
|
|
3
|
+
export default async function deleteSpace({ pg = pgClients.client, user, params, headers = {} }, reply) {
|
|
4
|
+
return null;
|
|
5
|
+
if (!params?.id) { return reply.status(400).send('not enough params: id'); }
|
|
6
|
+
if (!pg?.pk) { return reply.status(400).send('empty pg'); }
|
|
7
|
+
if (!pg?.pk?.['site.spaces']) { return reply.status(400).send('table not found: site.spaces'); }
|
|
8
|
+
|
|
9
|
+
if (params?.id && params.id === 'default') {
|
|
10
|
+
return reply.status(400).send('default space cannot be deleted');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const exists = await pg.query('select space_id from site.spaces where space_id=$1', [params.id]).then(el => el.rows?.[0]?.space_id);
|
|
14
|
+
if (!exists) { return reply.status(404).send('space not found: ' + params.id); }
|
|
15
|
+
|
|
16
|
+
const { referer } = headers;
|
|
17
|
+
|
|
18
|
+
const res = await dataDelete({
|
|
19
|
+
pg,
|
|
20
|
+
table: 'site.spaces',
|
|
21
|
+
id: params?.id,
|
|
22
|
+
uid: user?.uid,
|
|
23
|
+
referer,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
return { id: params.id, ...res || {} };
|
|
27
27
|
}
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import { pgClients } from '@opengis/fastify-table/utils.js';
|
|
2
|
-
|
|
3
|
-
const maxLimit = 100;
|
|
4
|
-
const defaultLimit = 20;
|
|
5
|
-
|
|
6
|
-
export default async function getSpaces({ pg = pgClients.client, user, params = {}, query = {} }, reply) {
|
|
7
|
-
return null;
|
|
8
|
-
if (!pg?.pk) { return reply.status(400).send('empty pg'); }
|
|
9
|
-
if (!pg?.pk?.['site.spaces']) { return reply.status(400).send('table not found: site.spaces'); }
|
|
10
|
-
|
|
11
|
-
const limit = Math.min(maxLimit, +(query.limit || defaultLimit));
|
|
12
|
-
const offset = query.page && query.page > 0 && !params.id ? (query.page - 1) * limit : 0;
|
|
13
|
-
|
|
14
|
-
const q = `select * from site.spaces where ${params.id ? 'space_id=$1' : '1=1'} limit ${limit} offset ${offset}`;
|
|
15
|
-
if (query.sql && user?.uid) return q;
|
|
16
|
-
|
|
17
|
-
const { rows = [] } = await pg.query(q, [params.id].filter(Boolean));
|
|
18
|
-
|
|
19
|
-
const total = await pg.queryCache('select count(*) from site.spaces', { table: 'site.spaces' }).then(el => el.rows?.[0]?.count || 0);
|
|
20
|
-
|
|
21
|
-
rows.forEach(row => Object.assign(row, { id: row.space_id }));
|
|
22
|
-
|
|
23
|
-
if (params.id) {
|
|
24
|
-
if (!rows.length) { return reply.status(404).send('space not found: ' + params.id); }
|
|
25
|
-
return reply.status(200).send(rows[0]);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return { total, filtered: rows.length, rows };
|
|
1
|
+
import { pgClients } from '@opengis/fastify-table/utils.js';
|
|
2
|
+
|
|
3
|
+
const maxLimit = 100;
|
|
4
|
+
const defaultLimit = 20;
|
|
5
|
+
|
|
6
|
+
export default async function getSpaces({ pg = pgClients.client, user, params = {}, query = {} }, reply) {
|
|
7
|
+
return null;
|
|
8
|
+
if (!pg?.pk) { return reply.status(400).send('empty pg'); }
|
|
9
|
+
if (!pg?.pk?.['site.spaces']) { return reply.status(400).send('table not found: site.spaces'); }
|
|
10
|
+
|
|
11
|
+
const limit = Math.min(maxLimit, +(query.limit || defaultLimit));
|
|
12
|
+
const offset = query.page && query.page > 0 && !params.id ? (query.page - 1) * limit : 0;
|
|
13
|
+
|
|
14
|
+
const q = `select * from site.spaces where ${params.id ? 'space_id=$1' : '1=1'} limit ${limit} offset ${offset}`;
|
|
15
|
+
if (query.sql && user?.uid) return q;
|
|
16
|
+
|
|
17
|
+
const { rows = [] } = await pg.query(q, [params.id].filter(Boolean));
|
|
18
|
+
|
|
19
|
+
const total = await pg.queryCache('select count(*) from site.spaces', { table: 'site.spaces' }).then(el => el.rows?.[0]?.count || 0);
|
|
20
|
+
|
|
21
|
+
rows.forEach(row => Object.assign(row, { id: row.space_id }));
|
|
22
|
+
|
|
23
|
+
if (params.id) {
|
|
24
|
+
if (!rows.length) { return reply.status(404).send('space not found: ' + params.id); }
|
|
25
|
+
return reply.status(200).send(rows[0]);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return { total, filtered: rows.length, rows };
|
|
29
29
|
}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { dataInsert, pgClients } from '@opengis/fastify-table/utils.js';
|
|
2
|
-
|
|
3
|
-
export default async function insertSpace({ pg = pgClients.client, user, params, headers = {}, body = {} }, reply) {
|
|
4
|
-
return null;
|
|
5
|
-
if (!pg?.pk) { return reply.status(400).send('empty pg'); }
|
|
6
|
-
if (!pg?.pk?.['site.spaces']) { return reply.status(400).send('table not found: site.spaces'); }
|
|
7
|
-
|
|
8
|
-
const exists = params?.id ? await pg.query('select space_id from site.spaces where space_id=$1', [params.id]).then(el => el.rows?.[0]?.space_id) : false;
|
|
9
|
-
if (exists) { return reply.status(400).send('space aleady exists: ' + params?.id); }
|
|
10
|
-
|
|
11
|
-
const { referer } = headers;
|
|
12
|
-
|
|
13
|
-
const res = await dataInsert({
|
|
14
|
-
pg,
|
|
15
|
-
table: 'site.spaces',
|
|
16
|
-
data: body,
|
|
17
|
-
id: params?.id,
|
|
18
|
-
uid: user?.uid,
|
|
19
|
-
referer,
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
return { id: res?.rows?.[0]?.space_id, rows: res?.rows || [] };
|
|
1
|
+
import { dataInsert, pgClients } from '@opengis/fastify-table/utils.js';
|
|
2
|
+
|
|
3
|
+
export default async function insertSpace({ pg = pgClients.client, user, params, headers = {}, body = {} }, reply) {
|
|
4
|
+
return null;
|
|
5
|
+
if (!pg?.pk) { return reply.status(400).send('empty pg'); }
|
|
6
|
+
if (!pg?.pk?.['site.spaces']) { return reply.status(400).send('table not found: site.spaces'); }
|
|
7
|
+
|
|
8
|
+
const exists = params?.id ? await pg.query('select space_id from site.spaces where space_id=$1', [params.id]).then(el => el.rows?.[0]?.space_id) : false;
|
|
9
|
+
if (exists) { return reply.status(400).send('space aleady exists: ' + params?.id); }
|
|
10
|
+
|
|
11
|
+
const { referer } = headers;
|
|
12
|
+
|
|
13
|
+
const res = await dataInsert({
|
|
14
|
+
pg,
|
|
15
|
+
table: 'site.spaces',
|
|
16
|
+
data: body,
|
|
17
|
+
id: params?.id,
|
|
18
|
+
uid: user?.uid,
|
|
19
|
+
referer,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
return { id: res?.rows?.[0]?.space_id, rows: res?.rows || [] };
|
|
23
23
|
}
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import { dataUpdate, pgClients } from '@opengis/fastify-table/utils.js';
|
|
2
|
-
|
|
3
|
-
export default async function updateSpace({ pg = pgClients.client, user, params, headers = {}, body = {} }, reply) {
|
|
4
|
-
return null;
|
|
5
|
-
// if (!params?.id) { return reply.status(400).send('not enough params: id'); }
|
|
6
|
-
if (!pg?.pk) { return reply.status(400).send('empty pg'); }
|
|
7
|
-
if (!pg?.pk?.['site.spaces']) { return reply.status(400).send('table not found: site.spaces'); }
|
|
8
|
-
|
|
9
|
-
const id = 'default';
|
|
10
|
-
const exists = await pg.query('select space_id from site.spaces where space_id=$1', [id]).then(el => el.rows?.[0]?.space_id);
|
|
11
|
-
if (!exists) { return reply.status(404).send('space not found: ' + id); }
|
|
12
|
-
|
|
13
|
-
const { referer } = headers;
|
|
14
|
-
|
|
15
|
-
const res = await dataUpdate({
|
|
16
|
-
pg,
|
|
17
|
-
table: 'site.spaces',
|
|
18
|
-
data: body,
|
|
19
|
-
id,
|
|
20
|
-
uid: user?.uid,
|
|
21
|
-
referer,
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
return { id, ...res || {} };
|
|
1
|
+
import { dataUpdate, pgClients } from '@opengis/fastify-table/utils.js';
|
|
2
|
+
|
|
3
|
+
export default async function updateSpace({ pg = pgClients.client, user, params, headers = {}, body = {} }, reply) {
|
|
4
|
+
return null;
|
|
5
|
+
// if (!params?.id) { return reply.status(400).send('not enough params: id'); }
|
|
6
|
+
if (!pg?.pk) { return reply.status(400).send('empty pg'); }
|
|
7
|
+
if (!pg?.pk?.['site.spaces']) { return reply.status(400).send('table not found: site.spaces'); }
|
|
8
|
+
|
|
9
|
+
const id = 'default';
|
|
10
|
+
const exists = await pg.query('select space_id from site.spaces where space_id=$1', [id]).then(el => el.rows?.[0]?.space_id);
|
|
11
|
+
if (!exists) { return reply.status(404).send('space not found: ' + id); }
|
|
12
|
+
|
|
13
|
+
const { referer } = headers;
|
|
14
|
+
|
|
15
|
+
const res = await dataUpdate({
|
|
16
|
+
pg,
|
|
17
|
+
table: 'site.spaces',
|
|
18
|
+
data: body,
|
|
19
|
+
id,
|
|
20
|
+
uid: user?.uid,
|
|
21
|
+
referer,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
return { id, ...res || {} };
|
|
25
25
|
}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
// space
|
|
2
|
-
import getSpaces from './controllers/getSpaces.js';
|
|
3
|
-
import insertSpace from './controllers/insertSpace.js';
|
|
4
|
-
import updateSpace from './controllers/updateSpace.js';
|
|
5
|
-
import deleteSpace from './controllers/deleteSpace.js';
|
|
6
|
-
|
|
7
|
-
const params = {
|
|
8
|
-
config: {
|
|
9
|
-
policy: [
|
|
10
|
-
'public'
|
|
11
|
-
]
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export default async function route(app) {
|
|
16
|
-
app.get('/cms-space/:id?', params, getSpaces);
|
|
17
|
-
app.post('/cms-space/:id?', params, insertSpace);
|
|
18
|
-
app.put('/cms-space/:id?', params, updateSpace);
|
|
19
|
-
app.delete('/cms-space/:id', params, deleteSpace);
|
|
20
|
-
}
|
|
1
|
+
// space
|
|
2
|
+
import getSpaces from './controllers/getSpaces.js';
|
|
3
|
+
import insertSpace from './controllers/insertSpace.js';
|
|
4
|
+
import updateSpace from './controllers/updateSpace.js';
|
|
5
|
+
import deleteSpace from './controllers/deleteSpace.js';
|
|
6
|
+
|
|
7
|
+
const params = {
|
|
8
|
+
config: {
|
|
9
|
+
policy: [
|
|
10
|
+
'public'
|
|
11
|
+
]
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default async function route(app) {
|
|
16
|
+
app.get('/cms-space/:id?', params, getSpaces);
|
|
17
|
+
app.post('/cms-space/:id?', params, insertSpace);
|
|
18
|
+
app.put('/cms-space/:id?', params, updateSpace);
|
|
19
|
+
app.delete('/cms-space/:id', params, deleteSpace);
|
|
20
|
+
}
|