@opengis/cms 0.0.13 → 0.0.14
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/package.json +2 -2
- package/server/migrations/site.sql +13 -1
- package/server/routes/site/controllers/deleteContent.js +45 -0
- package/server/routes/site/controllers/getContent.js +43 -0
- package/server/routes/site/controllers/insertContent.js +48 -0
- package/server/routes/site/controllers/updateContent.js +52 -0
- package/server/routes/site/index.mjs +11 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengis/cms",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
4
4
|
"description": "cms",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Softpro",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@opengis/fastify-auth": "1.0.85",
|
|
27
27
|
"@opengis/fastify-file": "1.0.76",
|
|
28
|
-
"@opengis/fastify-table": "1.3.
|
|
28
|
+
"@opengis/fastify-table": "1.3.45",
|
|
29
29
|
"@opengis/v3-core": "^0.3.165",
|
|
30
30
|
"@opengis/v3-filter": "^0.0.74",
|
|
31
31
|
"@vitejs/plugin-vue": "^5.0.4",
|
|
@@ -2,7 +2,15 @@ create schema if not exists admin;
|
|
|
2
2
|
create table if not exists admin.users (uid text primary key default next_id());
|
|
3
3
|
|
|
4
4
|
create schema if not exists site;
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
-- drop table if exists site.categories cascade;
|
|
7
|
+
create table if not exists site.categories (
|
|
8
|
+
category_id text primary key default next_id(),
|
|
9
|
+
created_at TIMESTAMP DEFAULT NOW(),
|
|
10
|
+
updated_at TIMESTAMP DEFAULT NOW(),
|
|
11
|
+
created_by text REFERENCES admin.users(uid),
|
|
12
|
+
updated_by text REFERENCES admin.users(uid)
|
|
13
|
+
);
|
|
6
14
|
|
|
7
15
|
-- drop table if exists site.articles cascade;
|
|
8
16
|
CREATE TABLE if not exists site.articles (
|
|
@@ -97,6 +105,10 @@ CREATE TABLE if not exists site.article_media (
|
|
|
97
105
|
related_type VARCHAR(50) NOT NULL,
|
|
98
106
|
field VARCHAR(50) NOT NULL,
|
|
99
107
|
order_index INTEGER DEFAULT 0,
|
|
108
|
+
created_at TIMESTAMP DEFAULT NOW(),
|
|
109
|
+
updated_at TIMESTAMP DEFAULT NOW(),
|
|
110
|
+
created_by text REFERENCES admin.users(uid),
|
|
111
|
+
updated_by text REFERENCES admin.users(uid),
|
|
100
112
|
PRIMARY KEY (article_id, media_id, field)
|
|
101
113
|
);
|
|
102
114
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { pgClients, dataDelete } from '@opengis/fastify-table/utils.js';
|
|
2
|
+
|
|
3
|
+
export default async function deleteContent(req, reply) {
|
|
4
|
+
const {
|
|
5
|
+
pg = pgClients.client,
|
|
6
|
+
params = {},
|
|
7
|
+
user = {},
|
|
8
|
+
headers = {},
|
|
9
|
+
} = req;
|
|
10
|
+
|
|
11
|
+
const { type, id } = params;
|
|
12
|
+
|
|
13
|
+
if (!type) {
|
|
14
|
+
return reply.status(400).send('not enough params: type');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (!id) {
|
|
18
|
+
return reply.status(400).send('not enough params: id');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const arr = await pg.query(`select array_agg(relname)::text[] from pg_class a
|
|
22
|
+
left join pg_namespace b on a.relnamespace=b.oid
|
|
23
|
+
where a.relam=2 and b.nspname='site'`).then(el => el.rows?.[0]?.array_agg || []);
|
|
24
|
+
|
|
25
|
+
if (!arr.length) {
|
|
26
|
+
return reply.status(400).send('empty schema: site');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const table = arr.find(el => el === params.type);
|
|
30
|
+
|
|
31
|
+
if (!table) {
|
|
32
|
+
return reply.status(400).send('invalid params: type');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const result = await dataDelete({
|
|
36
|
+
pg,
|
|
37
|
+
id,
|
|
38
|
+
table: 'site.' + table,
|
|
39
|
+
referer: headers?.referer,
|
|
40
|
+
uid: user?.uid || 0,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const pk = pg.pk?.['site.' + table];
|
|
44
|
+
return reply.status(200).send({ id: result?.[pk], ...result || {} });
|
|
45
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { pgClients, getData } from '@opengis/fastify-table/utils.js';
|
|
2
|
+
|
|
3
|
+
const maxLimit = 100;
|
|
4
|
+
|
|
5
|
+
export default async function getContent(req, reply) {
|
|
6
|
+
const { pg = pgClients.client, params = {}, query = {}, user = {} } = req;
|
|
7
|
+
const { type, id } = params;
|
|
8
|
+
const { filter, state, limit = 16, page, search, order, sql } = query;
|
|
9
|
+
|
|
10
|
+
if (!type) {
|
|
11
|
+
return reply.status(400).send('not enough params: type');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const arr = await pg.query(`select array_agg(relname)::text[] from pg_class a
|
|
15
|
+
left join pg_namespace b on a.relnamespace=b.oid
|
|
16
|
+
where a.relam=2 and b.nspname='site'`).then(el => el.rows?.[0]?.array_agg || []);
|
|
17
|
+
|
|
18
|
+
if (!arr.length) {
|
|
19
|
+
return reply.status(400).send('empty schema: site');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const table = arr.find(el => el === params.type);
|
|
23
|
+
|
|
24
|
+
if (!table) {
|
|
25
|
+
return reply.status(400).send('invalid params: type');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const res = await getData({
|
|
29
|
+
pg,
|
|
30
|
+
id,
|
|
31
|
+
table: 'site.' + table,
|
|
32
|
+
filter,
|
|
33
|
+
state,
|
|
34
|
+
limit: Math.min(limit, maxLimit),
|
|
35
|
+
page,
|
|
36
|
+
search,
|
|
37
|
+
order,
|
|
38
|
+
sql,
|
|
39
|
+
user,
|
|
40
|
+
}, reply, 1);
|
|
41
|
+
|
|
42
|
+
return res;
|
|
43
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { pgClients, dataInsert } from '@opengis/fastify-table/utils.js';
|
|
2
|
+
|
|
3
|
+
export default async function insertContent(req, reply) {
|
|
4
|
+
const {
|
|
5
|
+
pg = pgClients.client,
|
|
6
|
+
params = {},
|
|
7
|
+
user = {},
|
|
8
|
+
body = {},
|
|
9
|
+
headers = {},
|
|
10
|
+
} = req;
|
|
11
|
+
|
|
12
|
+
const { type, id = body?.id } = params;
|
|
13
|
+
|
|
14
|
+
if (!type) {
|
|
15
|
+
return reply.status(400).send('not enough params: type');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const arr = await pg.query(`select array_agg(relname)::text[] from pg_class a
|
|
19
|
+
left join pg_namespace b on a.relnamespace=b.oid
|
|
20
|
+
where a.relam=2 and b.nspname='site'`).then(el => el.rows?.[0]?.array_agg || []);
|
|
21
|
+
|
|
22
|
+
if (!arr.length) {
|
|
23
|
+
return reply.status(400).send('empty schema: site');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const table = arr.find(el => el === params.type);
|
|
27
|
+
|
|
28
|
+
if (!table) {
|
|
29
|
+
return reply.status(400).send('invalid params: type');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const { rows = [] } = await dataInsert({
|
|
33
|
+
pg,
|
|
34
|
+
id,
|
|
35
|
+
table: 'site.' + table,
|
|
36
|
+
data: body,
|
|
37
|
+
referer: headers?.referer,
|
|
38
|
+
uid: user?.uid || 0,
|
|
39
|
+
}).catch(err => {
|
|
40
|
+
if (err.message?.includes?.('unique constraint')) {
|
|
41
|
+
return reply.status(400).send('Порушенні унікальності: ' + err.message?.match?.(/([^"]+)/g)?.[1]);
|
|
42
|
+
}
|
|
43
|
+
return reply.status(500).send(err.toString());
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const pk = pg.pk?.['site.' + table];
|
|
47
|
+
return reply.status(200).send({ id: rows[0]?.[pk], rows });
|
|
48
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { pgClients, dataUpdate } from '@opengis/fastify-table/utils.js';
|
|
2
|
+
|
|
3
|
+
export default async function updateContent(req, reply) {
|
|
4
|
+
const {
|
|
5
|
+
pg = pgClients.client,
|
|
6
|
+
params = {},
|
|
7
|
+
user = {},
|
|
8
|
+
body = {},
|
|
9
|
+
headers = {},
|
|
10
|
+
} = req;
|
|
11
|
+
|
|
12
|
+
const { type, id } = params;
|
|
13
|
+
|
|
14
|
+
if (!type) {
|
|
15
|
+
return reply.status(400).send('not enough params: type');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (!id) {
|
|
19
|
+
return reply.status(400).send('not enough params: id');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const arr = await pg.query(`select array_agg(relname)::text[] from pg_class a
|
|
23
|
+
left join pg_namespace b on a.relnamespace=b.oid
|
|
24
|
+
where a.relam=2 and b.nspname='site'`).then(el => el.rows?.[0]?.array_agg || []);
|
|
25
|
+
|
|
26
|
+
if (!arr.length) {
|
|
27
|
+
return reply.status(400).send('empty schema: site');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const table = arr.find(el => el === params.type);
|
|
31
|
+
|
|
32
|
+
if (!table) {
|
|
33
|
+
return reply.status(400).send('invalid params: type');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const result = await dataUpdate({
|
|
37
|
+
pg,
|
|
38
|
+
id,
|
|
39
|
+
table: 'site.' + table,
|
|
40
|
+
data: body,
|
|
41
|
+
referer: headers?.referer,
|
|
42
|
+
uid: user?.uid || 0,
|
|
43
|
+
}).catch(err => {
|
|
44
|
+
if (err.message?.includes?.('unique constraint')) {
|
|
45
|
+
return reply.status(400).send('Порушенні унікальності: ' + err.message?.match?.(/([^"]+)/g)?.[1]);
|
|
46
|
+
}
|
|
47
|
+
return reply.status(500).send(err.toString());
|
|
48
|
+
});;
|
|
49
|
+
|
|
50
|
+
const pk = pg.pk?.['site.' + table];
|
|
51
|
+
return reply.status(200).send({ id: result?.[pk], ...result || {} });
|
|
52
|
+
}
|
|
@@ -9,6 +9,12 @@ import uploadMedia from './controllers/uploadMedia.js';
|
|
|
9
9
|
import del from './controllers/deleteMedia.js';
|
|
10
10
|
import download from './controllers/downloadMedia.js';
|
|
11
11
|
|
|
12
|
+
// content
|
|
13
|
+
import getContent from './controllers/getContent.js';
|
|
14
|
+
import insertContent from './controllers/insertContent.js';
|
|
15
|
+
import updateContent from './controllers/updateContent.js';
|
|
16
|
+
import deleteContent from './controllers/deleteContent.js';
|
|
17
|
+
|
|
12
18
|
const schemaObj = {
|
|
13
19
|
type: 'object',
|
|
14
20
|
properties: {
|
|
@@ -31,4 +37,9 @@ export default async function route(app) {
|
|
|
31
37
|
app.get('/site-media/:id', params, metadata);
|
|
32
38
|
app.delete('/site-media/:id', params, del);
|
|
33
39
|
app.get('/site-media/:id/delete', params, del); // debug
|
|
40
|
+
|
|
41
|
+
app.get('/site/:type/:id?', params, getContent);
|
|
42
|
+
app.post('/site/:type/:id?', params, insertContent);
|
|
43
|
+
app.put('/site/:type/:id', params, updateContent);
|
|
44
|
+
app.delete('/site/:type/:id', params, deleteContent);
|
|
34
45
|
}
|