@opengis/cms 0.0.32 → 0.0.34
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/index.js +6933 -6487
- package/dist/index.umd.cjs +51 -50
- package/package.json +7 -5
- package/server/plugins/vite.js +18 -30
- package/server/routes/cms/controllers/deleteContent.js +6 -7
- package/server/routes/cms/controllers/deleteMedia.js +76 -76
- package/server/routes/cms/controllers/downloadMedia.js +49 -49
- package/server/routes/cms/controllers/getPermissions.js +15 -15
- package/server/routes/cms/controllers/insertContent.js +7 -7
- package/server/routes/cms/controllers/listMedia.js +94 -94
- package/server/routes/cms/controllers/metadataMedia.js +39 -39
- package/server/routes/cms/controllers/setPermissions.js +49 -49
- package/server/routes/cms/controllers/updateContent.js +16 -14
- package/server/routes/cms/controllers/uploadMedia.js +79 -79
- package/server/routes/cms/utils/getSingle.js +2 -0
- package/server/templates/select/core.user_mentioned.sql +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengis/cms",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.34",
|
|
4
4
|
"description": "cms",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Softpro",
|
|
@@ -12,10 +12,13 @@
|
|
|
12
12
|
"plugin.js"
|
|
13
13
|
],
|
|
14
14
|
"scripts": {
|
|
15
|
+
"patch": "npm version patch && git push && npm publish",
|
|
15
16
|
"test": "node --test test/**/*.test.js",
|
|
16
17
|
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
|
|
17
|
-
"
|
|
18
|
-
"
|
|
18
|
+
"dev": "NODE_ENV=dev bun --env-file=.env.softpro server ",
|
|
19
|
+
"admin": "vite admin",
|
|
20
|
+
"build": "vite build && vite build admin",
|
|
21
|
+
"build:lib": "vite build",
|
|
19
22
|
"proxy": "vite dev admin",
|
|
20
23
|
"build-npm": "vite build",
|
|
21
24
|
"start": "bun --env-file=.env.ip server",
|
|
@@ -24,7 +27,6 @@
|
|
|
24
27
|
"prod": "NODE_ENV=production bun --env-file=.env.ip server ",
|
|
25
28
|
"prod-ip": "PORT=3019 node server --config=ip",
|
|
26
29
|
"prod-ip-test": "PORT=3025 node server --config=ip",
|
|
27
|
-
"dev": "node server --config=softpro",
|
|
28
30
|
"debug": "bun --watch server --config=softpro",
|
|
29
31
|
"ip-test": "node server --config=ip-test",
|
|
30
32
|
"ip": "node --env-file=.env.ip server",
|
|
@@ -65,4 +67,4 @@
|
|
|
65
67
|
"vitest": "3.2.4",
|
|
66
68
|
"vue-tsc": "^2.2.10"
|
|
67
69
|
}
|
|
68
|
-
}
|
|
70
|
+
}
|
package/server/plugins/vite.js
CHANGED
|
@@ -1,58 +1,46 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
|
-
import path
|
|
3
|
-
import {
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { createServer } from 'vite';
|
|
4
4
|
|
|
5
5
|
import { config } from '@opengis/fastify-table/utils.js';
|
|
6
6
|
|
|
7
|
-
const
|
|
8
|
-
const root = `${dir}/../..`;
|
|
9
|
-
const adminRoot = path.join(root, 'admin');
|
|
10
|
-
|
|
11
|
-
const isProduction = process.env.NODE_ENV === 'production' || config.production;
|
|
7
|
+
const isProduction = process.env.NODE_ENV !== 'dev';
|
|
12
8
|
console.log({ isProduction })
|
|
13
9
|
async function plugin(fastify) {
|
|
14
10
|
// vite server
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
server: {
|
|
22
|
-
middlewareMode: true,
|
|
23
|
-
},
|
|
24
|
-
});
|
|
11
|
+
const viteServer = !isProduction ? await createServer({
|
|
12
|
+
root: 'admin',
|
|
13
|
+
server: {
|
|
14
|
+
middlewareMode: true,
|
|
15
|
+
},
|
|
16
|
+
}) : null;
|
|
25
17
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
// hot relaod template
|
|
18
|
+
if (!isProduction) {
|
|
19
|
+
const dir1 = process.cwd();
|
|
20
|
+
viteServer.watcher.add(dir1);
|
|
30
21
|
viteServer.watcher.on('all', (d, t) => {
|
|
31
22
|
if (!t.includes('module')) return;
|
|
32
23
|
console.log(d, t);
|
|
33
24
|
viteServer.ws.send({ type: 'full-reload' });
|
|
34
25
|
});
|
|
35
26
|
|
|
36
|
-
// this is middleware for vite's dev
|
|
27
|
+
// this is middleware for vite's dev server
|
|
37
28
|
fastify.addHook('onRequest', async (req, reply) => {
|
|
38
29
|
const { user } = req.session?.passport || {};
|
|
39
|
-
|
|
40
|
-
return reply.redirect('/login');
|
|
41
|
-
}
|
|
30
|
+
// console.log(req.url);
|
|
42
31
|
|
|
43
32
|
const next = () => new Promise((resolve) => {
|
|
44
33
|
viteServer.middlewares(req.raw, reply.raw, () => resolve());
|
|
45
34
|
});
|
|
35
|
+
|
|
46
36
|
await next();
|
|
47
37
|
});
|
|
48
|
-
fastify.get('*', async () => { });
|
|
49
|
-
return;
|
|
50
38
|
}
|
|
51
39
|
|
|
52
40
|
// From Build
|
|
53
41
|
fastify.get('*', async (req, reply) => {
|
|
54
42
|
const { user } = req.session?.passport || {};
|
|
55
|
-
const indexPath = path.join(
|
|
43
|
+
const indexPath = path.join('admin/dist', 'index.html');
|
|
56
44
|
if (!user && config.pg && !req.url.startsWith('/src/') && !config.auth?.disable) {
|
|
57
45
|
return reply.redirect('/login');
|
|
58
46
|
}
|
|
@@ -65,8 +53,8 @@ async function plugin(fastify) {
|
|
|
65
53
|
|
|
66
54
|
const fileSize = {};
|
|
67
55
|
async function staticFile(req, reply) {
|
|
68
|
-
const assetsDir = '/dist';
|
|
69
|
-
const filePath = path.join(
|
|
56
|
+
const assetsDir = 'admin/dist';
|
|
57
|
+
const filePath = path.join( assetsDir, req.url);
|
|
70
58
|
const ext = path.extname(filePath);
|
|
71
59
|
|
|
72
60
|
if (!fs.existsSync(filePath)) return { status: 404, message: 'not found' };
|
|
@@ -18,24 +18,23 @@ export default async function deleteContent(req, reply) {
|
|
|
18
18
|
return reply.status(400).send('not enough params: id');
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
|
|
22
21
|
if (id === 'pages') {
|
|
23
22
|
return reply.status(403).send('access restricted: pages contents cannot be deleted');
|
|
24
23
|
}
|
|
25
24
|
|
|
25
|
+
const { ctid, dbtable } = await pg.query('select content_type_id as ctid, table_name as dbtable from site.content_types where $1 in (content_type_id, name)', [params.type])
|
|
26
|
+
.then(el => el.rows?.[0] || {});
|
|
27
|
+
|
|
26
28
|
const arr = config.pg ? await pg.query(`select array_agg(relname)::text[] from pg_class a
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
left join pg_namespace b on a.relnamespace=b.oid
|
|
30
|
+
where a.relam=2 and b.nspname='data'`).then(el => el.rows?.[0]?.array_agg || []) : [];
|
|
29
31
|
|
|
30
|
-
if (!arr.length) {
|
|
32
|
+
if (!arr.length && type !== 'pages') {
|
|
31
33
|
return reply.status(400).send('empty schema: data');
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
const table = arr.find(el => el === params.type);
|
|
35
37
|
|
|
36
|
-
const { ctid, dbtable } = await pg.query('select content_type_id as ctid, table_name as dbtable from site.content_types where $1 in (content_type_id, name)', [params.type])
|
|
37
|
-
.then(el => el.rows?.[0] || {});
|
|
38
|
-
|
|
39
38
|
// singletone with extra at site.content_data
|
|
40
39
|
if (!table && !dbtable && ctid) {
|
|
41
40
|
const { cid, status } = ctid === 'pages' && id
|
|
@@ -1,77 +1,77 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import { existsSync } from 'node:fs';
|
|
3
|
-
import { rm, stat, readdir } from 'node:fs/promises';
|
|
4
|
-
|
|
5
|
-
import { config, dataDelete, getFolder, pgClients } from "@opengis/fastify-table/utils.js";
|
|
6
|
-
|
|
7
|
-
// path.resolve() converts POSIX paths from getFolder to valid Windows paths (Bun/Node fs require this on Windows)
|
|
8
|
-
const rootDir = path.resolve(getFolder(config, 'local'));
|
|
9
|
-
const dir = '/files';
|
|
10
|
-
|
|
11
|
-
export default async function deleteMedia({
|
|
12
|
-
pg = pgClients.client, params = {}, query = {}, user = {}, method = 'DELETE',
|
|
13
|
-
}, reply) {
|
|
14
|
-
if (!config.debug && method !== 'DELETE') {
|
|
15
|
-
return reply.status(403).send('access restricted');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
if (!params.id && query.subdir) {
|
|
19
|
-
const dirpath = path.join(rootDir, dir, query.subdir || '');
|
|
20
|
-
const exists = existsSync(dirpath);
|
|
21
|
-
const stats = await stat(dirpath);
|
|
22
|
-
|
|
23
|
-
if (!stats.isDirectory()) {
|
|
24
|
-
return reply.status(400).send('not a directory');
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (!exists) {
|
|
28
|
-
return reply.status(404).send('subdir not found: ' + query.subdir);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const content = await readdir(dirpath, { recursive: true });
|
|
32
|
-
|
|
33
|
-
if (query.subdir.startsWith('uploads') && !query.subdir.split('/')[1]) {
|
|
34
|
-
return reply.status(403).send('access restricted: uploads directory');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// only admins are allowed to delete non-empty directories
|
|
38
|
-
if (content?.length && !user?.user_type?.includes?.('admin')) {
|
|
39
|
-
return reply.status(400).send('directory is not empty');
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
await rm(dirpath, { recursive: true });
|
|
43
|
-
return reply.status(200).send('subdirectory successfully deleted');
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (!params?.id) {
|
|
47
|
-
return reply.status(400).send('not enough params: id');
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (!pg.pk?.['site.media']) {
|
|
51
|
-
return reply.status(404).send('table not found');
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const { url: relpath, id } = await pg.query(
|
|
55
|
-
'select media_id as id, url from site.media where media_id = $1 and url is not null',
|
|
56
|
-
[params.id],
|
|
57
|
-
).then(el => el.rows?.[0] || {});
|
|
58
|
-
|
|
59
|
-
if (!id) {
|
|
60
|
-
return reply.status(404).send('media not found: ' + params.id);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const res = await dataDelete({
|
|
64
|
-
pg,
|
|
65
|
-
id,
|
|
66
|
-
table: 'site.media',
|
|
67
|
-
uid: user?.uid || 0,
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
const filepath = path.join(rootDir, relpath);
|
|
71
|
-
|
|
72
|
-
if (existsSync(filepath)) {
|
|
73
|
-
await rm(filepath, { recursive: true });
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return { id, ...res || {} };
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { rm, stat, readdir } from 'node:fs/promises';
|
|
4
|
+
|
|
5
|
+
import { config, dataDelete, getFolder, pgClients } from "@opengis/fastify-table/utils.js";
|
|
6
|
+
|
|
7
|
+
// path.resolve() converts POSIX paths from getFolder to valid Windows paths (Bun/Node fs require this on Windows)
|
|
8
|
+
const rootDir = path.resolve(getFolder(config, 'local'));
|
|
9
|
+
const dir = '/files';
|
|
10
|
+
|
|
11
|
+
export default async function deleteMedia({
|
|
12
|
+
pg = pgClients.client, params = {}, query = {}, user = {}, method = 'DELETE',
|
|
13
|
+
}, reply) {
|
|
14
|
+
if (!config.debug && method !== 'DELETE') {
|
|
15
|
+
return reply.status(403).send('access restricted');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (!params.id && query.subdir) {
|
|
19
|
+
const dirpath = path.join(rootDir, dir, query.subdir || '');
|
|
20
|
+
const exists = existsSync(dirpath);
|
|
21
|
+
const stats = await stat(dirpath);
|
|
22
|
+
|
|
23
|
+
if (!stats.isDirectory()) {
|
|
24
|
+
return reply.status(400).send('not a directory');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (!exists) {
|
|
28
|
+
return reply.status(404).send('subdir not found: ' + query.subdir);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const content = await readdir(dirpath, { recursive: true });
|
|
32
|
+
|
|
33
|
+
if (query.subdir.startsWith('uploads') && !query.subdir.split('/')[1]) {
|
|
34
|
+
return reply.status(403).send('access restricted: uploads directory');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// only admins are allowed to delete non-empty directories
|
|
38
|
+
if (content?.length && !user?.user_type?.includes?.('admin')) {
|
|
39
|
+
return reply.status(400).send('directory is not empty');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
await rm(dirpath, { recursive: true });
|
|
43
|
+
return reply.status(200).send('subdirectory successfully deleted');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!params?.id) {
|
|
47
|
+
return reply.status(400).send('not enough params: id');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!pg.pk?.['site.media']) {
|
|
51
|
+
return reply.status(404).send('table not found');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const { url: relpath, id } = await pg.query(
|
|
55
|
+
'select media_id as id, url from site.media where media_id = $1 and url is not null',
|
|
56
|
+
[params.id],
|
|
57
|
+
).then(el => el.rows?.[0] || {});
|
|
58
|
+
|
|
59
|
+
if (!id) {
|
|
60
|
+
return reply.status(404).send('media not found: ' + params.id);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const res = await dataDelete({
|
|
64
|
+
pg,
|
|
65
|
+
id,
|
|
66
|
+
table: 'site.media',
|
|
67
|
+
uid: user?.uid || 0,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const filepath = path.join(rootDir, relpath);
|
|
71
|
+
|
|
72
|
+
if (existsSync(filepath)) {
|
|
73
|
+
await rm(filepath, { recursive: true });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return { id, ...res || {} };
|
|
77
77
|
}
|
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import { existsSync } from 'node:fs';
|
|
3
|
-
import { readFile } from 'node:fs/promises';
|
|
4
|
-
|
|
5
|
-
import { config, getFolder, pgClients } from "@opengis/fastify-table/utils.js";
|
|
6
|
-
|
|
7
|
-
// path.resolve() converts POSIX paths from getFolder to valid Windows paths (Bun/Node fs require this on Windows)
|
|
8
|
-
const rootDir = path.resolve(getFolder(config, 'local'));
|
|
9
|
-
|
|
10
|
-
export default async function downloadMedia({
|
|
11
|
-
pg = pgClients.client, params = {},
|
|
12
|
-
}, reply) {
|
|
13
|
-
if (!params?.id) {
|
|
14
|
-
return reply.status(400).send('not enough params: id');
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
if (!pg.pk?.['site.media']) {
|
|
18
|
-
return reply.status(404).send('table not found');
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const { filename, mime, id, url: relpath } = await pg.query(
|
|
22
|
-
'select media_id as id, filename, mime, url from site.media where media_id = $1 and url is not null',
|
|
23
|
-
[params.id],
|
|
24
|
-
).then(el => el.rows?.[0] || {});
|
|
25
|
-
|
|
26
|
-
if (!id) {
|
|
27
|
-
return reply.status(404).send('media not found: ' + params.id);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const filepath = path.join(rootDir, relpath);
|
|
31
|
-
|
|
32
|
-
if (!existsSync(filepath)) {
|
|
33
|
-
return reply.status(404).send('file not found');
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const buffer = await readFile(filepath, { buffer: true });
|
|
37
|
-
|
|
38
|
-
// skip xml load for preview
|
|
39
|
-
if (params.type === 'preview' && path.extname(filename) !== '.xml') {
|
|
40
|
-
return reply.headers({ 'Content-Type': mime }).send(buffer);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return reply
|
|
44
|
-
.headers({
|
|
45
|
-
'Content-Type': mime,
|
|
46
|
-
'Content-Disposition': `attachment; filename=${filename || path.basename(filepath)}`,
|
|
47
|
-
})
|
|
48
|
-
.send(buffer);
|
|
49
|
-
}
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
|
|
5
|
+
import { config, getFolder, pgClients } from "@opengis/fastify-table/utils.js";
|
|
6
|
+
|
|
7
|
+
// path.resolve() converts POSIX paths from getFolder to valid Windows paths (Bun/Node fs require this on Windows)
|
|
8
|
+
const rootDir = path.resolve(getFolder(config, 'local'));
|
|
9
|
+
|
|
10
|
+
export default async function downloadMedia({
|
|
11
|
+
pg = pgClients.client, params = {},
|
|
12
|
+
}, reply) {
|
|
13
|
+
if (!params?.id) {
|
|
14
|
+
return reply.status(400).send('not enough params: id');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (!pg.pk?.['site.media']) {
|
|
18
|
+
return reply.status(404).send('table not found');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const { filename, mime, id, url: relpath } = await pg.query(
|
|
22
|
+
'select media_id as id, filename, mime, url from site.media where media_id = $1 and url is not null',
|
|
23
|
+
[params.id],
|
|
24
|
+
).then(el => el.rows?.[0] || {});
|
|
25
|
+
|
|
26
|
+
if (!id) {
|
|
27
|
+
return reply.status(404).send('media not found: ' + params.id);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const filepath = path.join(rootDir, relpath);
|
|
31
|
+
|
|
32
|
+
if (!existsSync(filepath)) {
|
|
33
|
+
return reply.status(404).send('file not found');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const buffer = await readFile(filepath, { buffer: true });
|
|
37
|
+
|
|
38
|
+
// skip xml load for preview
|
|
39
|
+
if (params.type === 'preview' && path.extname(filename) !== '.xml') {
|
|
40
|
+
return reply.headers({ 'Content-Type': mime }).send(buffer);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return reply
|
|
44
|
+
.headers({
|
|
45
|
+
'Content-Type': mime,
|
|
46
|
+
'Content-Disposition': `attachment; filename=${filename || path.basename(filepath)}`,
|
|
47
|
+
})
|
|
48
|
+
.send(buffer);
|
|
49
|
+
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { pgClients } from '@opengis/fastify-table/utils.js';
|
|
2
|
-
|
|
3
|
-
export default async function getPermissions(req, reply) {
|
|
4
|
-
const { pg = pgClients.client, params = {}, user = {} } = req;
|
|
5
|
-
|
|
6
|
-
if (!user?.uid) {
|
|
7
|
-
return reply.status(401).send('unauthorized');
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const { rows = [] } = await pg.query(
|
|
11
|
-
`select * from site.permissions where ${params.id ? 'user_id=$1' : 'true'}`,
|
|
12
|
-
[params.id].filter(Boolean),
|
|
13
|
-
);
|
|
14
|
-
|
|
15
|
-
return { permissions: rows };
|
|
1
|
+
import { pgClients } from '@opengis/fastify-table/utils.js';
|
|
2
|
+
|
|
3
|
+
export default async function getPermissions(req, reply) {
|
|
4
|
+
const { pg = pgClients.client, params = {}, user = {} } = req;
|
|
5
|
+
|
|
6
|
+
if (!user?.uid) {
|
|
7
|
+
return reply.status(401).send('unauthorized');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const { rows = [] } = await pg.query(
|
|
11
|
+
`select * from site.permissions where ${params.id ? 'user_id=$1' : 'true'}`,
|
|
12
|
+
[params.id].filter(Boolean),
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
return { permissions: rows };
|
|
16
16
|
}
|
|
@@ -42,12 +42,6 @@ export default async function insertContent(req, reply) {
|
|
|
42
42
|
left join pg_namespace b on a.relnamespace=b.oid
|
|
43
43
|
where a.relam=2 and b.nspname='data'`).then(el => el.rows?.[0]?.array_agg || []) : [];
|
|
44
44
|
|
|
45
|
-
if (!arr.length) {
|
|
46
|
-
return reply.status(400).send('empty schema: data');
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const table = arr.find(el => el === params.type);
|
|
50
|
-
|
|
51
45
|
const { content_id: contentId, type: contentType } = await pg.query(
|
|
52
46
|
'select content_id, (select type from site.content_types where content_type_id=t.content_type_id) from site.contents t where slug=$1',
|
|
53
47
|
[['single', 'pages'].includes(type) ? id : type],
|
|
@@ -58,6 +52,12 @@ export default async function insertContent(req, reply) {
|
|
|
58
52
|
[contentId],
|
|
59
53
|
).then(el => el.rows?.[0]?.content_type_id) : null;
|
|
60
54
|
|
|
55
|
+
if (!arr.length && (ctypeId || type) !== 'pages') {
|
|
56
|
+
return reply.status(400).send('empty schema: data');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const table = arr.find(el => el === params.type);
|
|
60
|
+
|
|
61
61
|
const { ctid, dbtable, columns: contentColumns } = await pg.query(
|
|
62
62
|
'select content_type_id as ctid, table_name as dbtable, columns from site.content_types where $1 in (content_type_id, name)',
|
|
63
63
|
[type === 'single' && id ? id : (ctypeId || type)],
|
|
@@ -70,7 +70,7 @@ export default async function insertContent(req, reply) {
|
|
|
70
70
|
: contentColumns;
|
|
71
71
|
|
|
72
72
|
// site.content_data, includes singletone
|
|
73
|
-
if (((!table && !dbtable) || type === 'pages')) {
|
|
73
|
+
if (((!table && !dbtable) || (ctypeId || type) === 'pages')) {
|
|
74
74
|
const cid = await pg.query(
|
|
75
75
|
'select content_id from site.contents where content_type_id=$1 limit 1',
|
|
76
76
|
[ctid || 'pages'],
|