@opengis/cms 0.0.54 → 0.0.56
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 +57 -24
- package/dist/{ArticlesPage-Cuit_90w.js → ArticlesPage-BcR1hbds.js} +3 -3
- package/dist/{BuilderPage-B79YHrmr.js → BuilderPage-CK_osM89.js} +51 -51
- package/dist/{CollectionsBreadcrumb.vue_vue_type_script_setup_true_lang-B6irHMzL.js → CollectionsBreadcrumb.vue_vue_type_script_setup_true_lang-CnOe9ORD.js} +19 -19
- package/dist/{EditCollectionPage-CAVLcvLg.js → EditCollectionPage-Cw3GQYRe.js} +2 -2
- package/dist/{MenuAddPage-CmU4kAUM.js → MenuAddPage-Bf48Z-ah.js} +1 -1
- package/dist/{MenuItemPage-UV8JlJvT.js → MenuItemPage-CXn5HC8j.js} +113 -112
- package/dist/{MenuPage-c4TPJgIN.js → MenuPage-tJZtK46W.js} +1 -1
- package/dist/MonacoEditor.vue_vue_type_script_setup_true_lang-B1DrxmQX.js +84 -0
- package/dist/{UniversalTable.vue_vue_type_script_setup_true_lang-DR4PQwqR.js → UniversalTable.vue_vue_type_script_setup_true_lang-CJGTsd1V.js} +80 -80
- package/dist/{UniversalTablePagination.vue_vue_type_script_setup_true_lang-C8P9DCeX.js → UniversalTablePagination.vue_vue_type_script_setup_true_lang-GYZd_gkA.js} +46 -46
- package/dist/{contentForm-BQdeYVFh.js → contentForm-B6gHgGkz.js} +1 -1
- package/dist/index.js +5 -5
- package/dist/style.css +1 -1
- package/package.json +68 -68
- package/server/functions/getContent.js +3 -3
- package/server/functions/getSearchData.js +1 -1
- package/server/migrations/site.sql +2 -2
- package/server/routes/cms/controllers/getContent.js +6 -4
- package/server/routes/cms/controllers/getPermissions.js +15 -15
- package/server/routes/cms/controllers/setPermissions.js +49 -49
- package/server/routes/cms/controllers/updateContent.js +27 -1
- package/server/routes/cms/functions/getSettings.js +1 -1
- package/server/routes/cms/utils/getSingle.js +6 -10
- package/server/routes/contentType/controllers/editContentType.js +29 -9
- package/server/routes/contentType/controllers/getContentType.js +13 -0
- package/server/routes/contentType/utils/updateContents.js +16 -0
- package/server/routes/menu/controllers/getMenu.js +2 -2
- package/server/routes/menu/functions/getMenu.js +3 -3
- package/server/templates/select/core.user_mentioned.sql +1 -1
- package/dist/MonacoEditor.vue_vue_type_script_setup_true_lang-C8cip9Ci.js +0 -84
package/package.json
CHANGED
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@opengis/cms",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "cms",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"author": "Softpro",
|
|
7
|
-
"main": "./dist/index.js",
|
|
8
|
-
"license": "EULA",
|
|
9
|
-
"files": [
|
|
10
|
-
"module",
|
|
11
|
-
"locales",
|
|
12
|
-
"dist",
|
|
13
|
-
"server",
|
|
14
|
-
"plugin.js",
|
|
15
|
-
"utils.js",
|
|
16
|
-
"utils.d.ts",
|
|
17
|
-
"input-types.json"
|
|
18
|
-
],
|
|
19
|
-
"scripts": {
|
|
20
|
-
"patch": "npm version patch && git push && npm publish",
|
|
21
|
-
"test": "node --test test/**/*.test.js",
|
|
22
|
-
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
|
|
23
|
-
"dev": "NODE_ENV=dev bun --env-file=.env.ip server ",
|
|
24
|
-
"admin": "vite admin",
|
|
25
|
-
"build": "vite build && vite build admin",
|
|
26
|
-
"build:lib": "vite build",
|
|
27
|
-
"proxy": "vite dev admin",
|
|
28
|
-
"start": "bun --env-file=.env.ip server",
|
|
29
|
-
"prod": "NODE_ENV=production bun --env-file=.env.ip server ",
|
|
30
|
-
"ip": "bun --env-file=.env.ip server",
|
|
31
|
-
"demo": "node --env-file=.env.demo --env-file=.env server",
|
|
32
|
-
"i18n:sync": "node i18n-sync.cjs",
|
|
33
|
-
"prepublishOnly": "bun build:lib",
|
|
34
|
-
"softpro": "bun --env-file=.env.softpro server",
|
|
35
|
-
"softpro1": "NODE_ENV=production bun --env-file=.env.prod-softpro.local server"
|
|
36
|
-
},
|
|
37
|
-
"dependencies": {},
|
|
38
|
-
"resolutions": {
|
|
39
|
-
"rollup": "4.30.0"
|
|
40
|
-
},
|
|
41
|
-
"devDependencies": {
|
|
42
|
-
"@fastify/compress": "^8.1.0",
|
|
43
|
-
"@opengis/core": "^0.0.30",
|
|
44
|
-
"@opengis/fastify-table": "^2.0.143",
|
|
45
|
-
"@opengis/filter": "^0.1.31",
|
|
46
|
-
"@opengis/form": "^0.0.109",
|
|
47
|
-
"@opengis/richtext": "0.0.45",
|
|
48
|
-
"@vueuse/head": "2.0.0",
|
|
49
|
-
"js-yaml": "^4.1.0",
|
|
50
|
-
"lucide-vue-next": "0.344.0",
|
|
51
|
-
"vite": "5.1.4",
|
|
52
|
-
"vue": "^3.5.17",
|
|
53
|
-
"vue-i18n": "11.1.5",
|
|
54
|
-
"vue-router": "4.4.3",
|
|
55
|
-
"vuedraggable": "4.1.0",
|
|
56
|
-
"@tailwindcss/typography": "0.5.10",
|
|
57
|
-
"@tsconfig/node22": "^22.0.2",
|
|
58
|
-
"@vitejs/plugin-vue": "5.0.4",
|
|
59
|
-
"autoprefixer": "10.4.18",
|
|
60
|
-
"eslint": "8.49.0",
|
|
61
|
-
"postcss": "8.4.35",
|
|
62
|
-
"sass": "^1.92.1",
|
|
63
|
-
"tailwindcss": "3.4.1",
|
|
64
|
-
"typescript": "~5.8.0",
|
|
65
|
-
"vitest": "3.2.4",
|
|
66
|
-
"vue-tsc": "^2.2.10"
|
|
67
|
-
}
|
|
68
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@opengis/cms",
|
|
3
|
+
"version": "0.0.56",
|
|
4
|
+
"description": "cms",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"author": "Softpro",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"license": "EULA",
|
|
9
|
+
"files": [
|
|
10
|
+
"module",
|
|
11
|
+
"locales",
|
|
12
|
+
"dist",
|
|
13
|
+
"server",
|
|
14
|
+
"plugin.js",
|
|
15
|
+
"utils.js",
|
|
16
|
+
"utils.d.ts",
|
|
17
|
+
"input-types.json"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"patch": "npm version patch && git push && npm publish",
|
|
21
|
+
"test": "node --test test/**/*.test.js",
|
|
22
|
+
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
|
|
23
|
+
"dev": "NODE_ENV=dev bun --env-file=.env.ip server ",
|
|
24
|
+
"admin": "vite admin",
|
|
25
|
+
"build": "vite build && vite build admin",
|
|
26
|
+
"build:lib": "vite build",
|
|
27
|
+
"proxy": "vite dev admin",
|
|
28
|
+
"start": "bun --env-file=.env.ip server",
|
|
29
|
+
"prod": "NODE_ENV=production bun --env-file=.env.ip server ",
|
|
30
|
+
"ip": "bun --env-file=.env.ip server",
|
|
31
|
+
"demo": "node --env-file=.env.demo --env-file=.env server",
|
|
32
|
+
"i18n:sync": "node i18n-sync.cjs",
|
|
33
|
+
"prepublishOnly": "bun build:lib",
|
|
34
|
+
"softpro": "bun --env-file=.env.softpro server",
|
|
35
|
+
"softpro1": "NODE_ENV=production bun --env-file=.env.prod-softpro.local server"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {},
|
|
38
|
+
"resolutions": {
|
|
39
|
+
"rollup": "4.30.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@fastify/compress": "^8.1.0",
|
|
43
|
+
"@opengis/core": "^0.0.30",
|
|
44
|
+
"@opengis/fastify-table": "^2.0.143",
|
|
45
|
+
"@opengis/filter": "^0.1.31",
|
|
46
|
+
"@opengis/form": "^0.0.109",
|
|
47
|
+
"@opengis/richtext": "0.0.45",
|
|
48
|
+
"@vueuse/head": "2.0.0",
|
|
49
|
+
"js-yaml": "^4.1.0",
|
|
50
|
+
"lucide-vue-next": "0.344.0",
|
|
51
|
+
"vite": "5.1.4",
|
|
52
|
+
"vue": "^3.5.17",
|
|
53
|
+
"vue-i18n": "11.1.5",
|
|
54
|
+
"vue-router": "4.4.3",
|
|
55
|
+
"vuedraggable": "4.1.0",
|
|
56
|
+
"@tailwindcss/typography": "0.5.10",
|
|
57
|
+
"@tsconfig/node22": "^22.0.2",
|
|
58
|
+
"@vitejs/plugin-vue": "5.0.4",
|
|
59
|
+
"autoprefixer": "10.4.18",
|
|
60
|
+
"eslint": "8.49.0",
|
|
61
|
+
"postcss": "8.4.35",
|
|
62
|
+
"sass": "^1.92.1",
|
|
63
|
+
"tailwindcss": "3.4.1",
|
|
64
|
+
"typescript": "~5.8.0",
|
|
65
|
+
"vitest": "3.2.4",
|
|
66
|
+
"vue-tsc": "^2.2.10"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -22,9 +22,9 @@ export default async function getContentBySlug({ slug, filter, tags, state, loca
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
// check if any crud operations performed, if not - return cached response
|
|
25
|
-
const crudInc = await rclient.get(`pg:${table}:crud`) || 0;
|
|
25
|
+
const crudInc = await rclient.get(`pg:${config.pg?.database}:${table}:crud`) || 0;
|
|
26
26
|
|
|
27
|
-
const cacheKey = createHash('md5').update([config.pg?.database, 'cms:content', slug, crudInc, filter, tags, state, locale, contextQuery, collection, fields, limit, page, fields && typeof fields !== 'string' ? JSON.stringify(fields) : fields].join(':')).digest('hex');
|
|
27
|
+
const cacheKey = createHash('md5').update([config.pg?.database, 'cms:content', slug, crudInc, filter, tags, state, locale, contextQuery, collection, fields, limit, page, order, desc, fields && typeof fields !== 'string' ? JSON.stringify(fields) : fields].join(':')).digest('hex');
|
|
28
28
|
const cacheData = ttl === 0 ? null : JSON.parse(await rclient.get(cacheKey));
|
|
29
29
|
|
|
30
30
|
// return from cache
|
|
@@ -33,7 +33,7 @@ export default async function getContentBySlug({ slug, filter, tags, state, loca
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
const req = { pg: pgClients.client, params: { type: collection, id: slug }, query: { filter, tags, state, contextQuery, locale, fields, limit, page, order, desc } };
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
const mockReply = createMockReply();
|
|
38
38
|
const result = await getContent(req, mockReply, true);
|
|
39
39
|
|
|
@@ -10,7 +10,7 @@ const rclient = getRedis();
|
|
|
10
10
|
|
|
11
11
|
export default async function getSearchData({ page = 1, limit = 12, ttl = 3600, search, locale, tags, filter, contentType, asc } = {}) {
|
|
12
12
|
// check if any crud operations performed, if not - return cached response
|
|
13
|
-
const crudInc = await rclient.get(`pg:site.contents:crud`) || 0;
|
|
13
|
+
const crudInc = await rclient.get(`pg:${config.pg?.database}:site.contents:crud`) || 0;
|
|
14
14
|
|
|
15
15
|
const cacheKey = createHash('md5').update([config.pg?.database, 'cms:search', crudInc, page, limit, search, locale, tags, filter, contentType, asc].join(':')).digest('hex');
|
|
16
16
|
const cacheData = ttl === 0 ? null : JSON.parse(await rclient.get(cacheKey));
|
|
@@ -370,8 +370,8 @@ CREATE TABLE if not exists site.contents (
|
|
|
370
370
|
FOREIGN KEY (updated_by) REFERENCES admin.users(uid)
|
|
371
371
|
);
|
|
372
372
|
|
|
373
|
-
alter table site.contents add column if not exists
|
|
374
|
-
alter table site.contents add column if not exists
|
|
373
|
+
alter table site.contents add column if not exists space_id text;
|
|
374
|
+
alter table site.contents add column if not exists content_type_id text;
|
|
375
375
|
ALTER TABLE site.contents add COLUMN if not exists created_at TIMESTAMP DEFAULT NOW();
|
|
376
376
|
ALTER TABLE site.contents add COLUMN if not exists updated_at TIMESTAMP DEFAULT NOW();
|
|
377
377
|
ALTER TABLE site.contents add COLUMN if not exists created_by text REFERENCES admin.users(uid);
|
|
@@ -35,7 +35,9 @@ addHook('preFilter', async ({ pg = pgClients.client, table }) => {
|
|
|
35
35
|
|
|
36
36
|
const defaultFields = ['title', 'slug', 'status', 'created_at', 'updated_at', 'main_image', 'published_at'];
|
|
37
37
|
|
|
38
|
-
export default async function getContent(req, reply,
|
|
38
|
+
export default async function getContent(req, reply, opt) {
|
|
39
|
+
const called = !!opt;
|
|
40
|
+
const { showDrafts: showDrafts1 } = opt || {};
|
|
39
41
|
const { pg = pgClients.client, params = {}, query = {}, headers = {} } = req;
|
|
40
42
|
const user = req.user || {};
|
|
41
43
|
const { type, id } = params;
|
|
@@ -46,7 +48,7 @@ export default async function getContent(req, reply, called = false) {
|
|
|
46
48
|
|
|
47
49
|
const { draftKey } = await getDraftKey();
|
|
48
50
|
const showDrafts = query.draftKey && query.draftKey === draftKey;
|
|
49
|
-
const statusQuery = !!req.user?.uid || showDrafts ||
|
|
51
|
+
const statusQuery = !!req.user?.uid || showDrafts || showDrafts1 ? '1=1' : `status='published'`;
|
|
50
52
|
|
|
51
53
|
// headers.authorization = 'Bearer tokenExample'
|
|
52
54
|
const isValidToken = await pg.query(
|
|
@@ -63,7 +65,7 @@ export default async function getContent(req, reply, called = false) {
|
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
const { contentId, contentTypeId, meta } = params.type === 'pages'
|
|
66
|
-
?
|
|
68
|
+
? { contentId: params.id || 'pages', contentTypeId: params.id || 'pages', meta: null }
|
|
67
69
|
: await pg.query(`select content_id as "contentId", content_type_id as "contentTypeId", meta from site.contents where $1 in (slug, content_id, content_type_id)`, [params.type]).then(el => el.rows?.[0] || {});
|
|
68
70
|
|
|
69
71
|
if (!contentId) {
|
|
@@ -86,7 +88,7 @@ export default async function getContent(req, reply, called = false) {
|
|
|
86
88
|
|
|
87
89
|
defaultColumns.forEach(col => Object.assign(col, { default: true }));
|
|
88
90
|
|
|
89
|
-
const columns = columns1.filter(col => !defaultColumns.map(el => el.name).includes(col.name));
|
|
91
|
+
const columns = (columns1 || []).filter(col => !defaultColumns.map(el => el.name).includes(col.name));
|
|
90
92
|
|
|
91
93
|
const result = contentType === 'collection' && table
|
|
92
94
|
? await getCollection({
|
|
@@ -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
|
}
|
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
import { logger, pgClients, dataInsert } from '@opengis/fastify-table/utils.js';
|
|
2
|
-
|
|
3
|
-
export default async function setPermissions(req, reply) {
|
|
4
|
-
const { pg = pgClients.client, params = {}, user = {}, body = {} } = req;
|
|
5
|
-
|
|
6
|
-
if (!user?.uid) {
|
|
7
|
-
return reply.status(401).send('unauthorized');
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
if (!params.id) {
|
|
11
|
-
return reply.status(400).send('not enough params: id');
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const client = await pg.connect()
|
|
15
|
-
const result = {};
|
|
16
|
-
try {
|
|
17
|
-
await client.query('BEGIN');
|
|
18
|
-
|
|
19
|
-
const { rowCount = 0 } = await client.query(
|
|
20
|
-
`delete from site.permissions where user_id=$1`,
|
|
21
|
-
[params.id].filter(Boolean),
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
Object.assign(result, { deleted: rowCount });
|
|
25
|
-
|
|
26
|
-
if (Array.isArray(body.permissions) && body.permissions?.length) {
|
|
27
|
-
body.permissions.forEach((el) => {
|
|
28
|
-
Object.assign(el, { user_id: el.user_id || params.id });
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
await Promise.all(body.permissions.map(async (el) => dataInsert({
|
|
32
|
-
pg: client,
|
|
33
|
-
table: 'site.permissions',
|
|
34
|
-
data: el,
|
|
35
|
-
uid: user.uid,
|
|
36
|
-
})));
|
|
37
|
-
|
|
38
|
-
Object.assign(result, { inserted: body.permissions.length });
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
await client.query('COMMIT');
|
|
42
|
-
return reply.status(200).send(result);
|
|
43
|
-
} catch (err) {
|
|
44
|
-
await client.query('ROLLBACK');
|
|
45
|
-
logger.file('cms/permissions', { error: err.toString(), stack: err.stack });
|
|
46
|
-
return reply.status(500).send('set permissions error');
|
|
47
|
-
} finally {
|
|
48
|
-
client.release();
|
|
49
|
-
}
|
|
1
|
+
import { logger, pgClients, dataInsert } from '@opengis/fastify-table/utils.js';
|
|
2
|
+
|
|
3
|
+
export default async function setPermissions(req, reply) {
|
|
4
|
+
const { pg = pgClients.client, params = {}, user = {}, body = {} } = req;
|
|
5
|
+
|
|
6
|
+
if (!user?.uid) {
|
|
7
|
+
return reply.status(401).send('unauthorized');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (!params.id) {
|
|
11
|
+
return reply.status(400).send('not enough params: id');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const client = await pg.connect()
|
|
15
|
+
const result = {};
|
|
16
|
+
try {
|
|
17
|
+
await client.query('BEGIN');
|
|
18
|
+
|
|
19
|
+
const { rowCount = 0 } = await client.query(
|
|
20
|
+
`delete from site.permissions where user_id=$1`,
|
|
21
|
+
[params.id].filter(Boolean),
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
Object.assign(result, { deleted: rowCount });
|
|
25
|
+
|
|
26
|
+
if (Array.isArray(body.permissions) && body.permissions?.length) {
|
|
27
|
+
body.permissions.forEach((el) => {
|
|
28
|
+
Object.assign(el, { user_id: el.user_id || params.id });
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
await Promise.all(body.permissions.map(async (el) => dataInsert({
|
|
32
|
+
pg: client,
|
|
33
|
+
table: 'site.permissions',
|
|
34
|
+
data: el,
|
|
35
|
+
uid: user.uid,
|
|
36
|
+
})));
|
|
37
|
+
|
|
38
|
+
Object.assign(result, { inserted: body.permissions.length });
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
await client.query('COMMIT');
|
|
42
|
+
return reply.status(200).send(result);
|
|
43
|
+
} catch (err) {
|
|
44
|
+
await client.query('ROLLBACK');
|
|
45
|
+
logger.file('cms/permissions', { error: err.toString(), stack: err.stack });
|
|
46
|
+
return reply.status(500).send('set permissions error');
|
|
47
|
+
} finally {
|
|
48
|
+
client.release();
|
|
49
|
+
}
|
|
50
50
|
}
|
|
@@ -120,17 +120,43 @@ export default async function updateContent(req, reply) {
|
|
|
120
120
|
return reply.status(400).send('access restricted: empty/invalid block ' + emptyBlock);
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
const single = await pg.query(
|
|
124
|
+
`select 1 FROM site.contents
|
|
125
|
+
where content_id=$1`, [params.id]
|
|
126
|
+
).then(el => el.rowCount || 0);
|
|
127
|
+
|
|
128
|
+
const customCtExists = await pg.query(
|
|
129
|
+
`select 1 FROM site.content_types
|
|
130
|
+
where content_type_id=$1`, [params.id]
|
|
131
|
+
).then(el => el.rowCount || 0);
|
|
132
|
+
|
|
123
133
|
const client = await pg.connect();
|
|
124
134
|
|
|
125
135
|
try {
|
|
126
136
|
await client.query('begin');
|
|
127
|
-
|
|
137
|
+
|
|
138
|
+
const res = {};
|
|
139
|
+
|
|
140
|
+
if (single && !customCtExists) {
|
|
141
|
+
const res1 = await dataInsert({
|
|
142
|
+
pg: client,
|
|
143
|
+
table: 'site.content_types',
|
|
144
|
+
id: params.id,
|
|
145
|
+
data: body,
|
|
146
|
+
uid: user?.uid,
|
|
147
|
+
});
|
|
148
|
+
Object.assign(res, res1);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const res1 = await dataUpdate({
|
|
128
152
|
pg: client,
|
|
129
153
|
table: 'site.contents',
|
|
130
154
|
id,
|
|
131
155
|
data: { ...body, content_type_id: ctid1 },
|
|
132
156
|
uid: user?.uid,
|
|
133
157
|
});
|
|
158
|
+
Object.assign(res, res1);
|
|
159
|
+
|
|
134
160
|
// if (contentId) {
|
|
135
161
|
// await client.query(`delete from site.content_data where content_id=$1`, [contentId]);
|
|
136
162
|
// }
|
|
@@ -12,7 +12,7 @@ export default async function getSettings({ entity = 'app', keys = ['cms'], uid
|
|
|
12
12
|
return { error: "properties table not found", code: 404 };
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
const crudInc = await rclient.get(`pg:admin.properties:crud`) || 0;
|
|
15
|
+
const crudInc = await rclient.get(`pg:${config.pg?.database}:admin.properties:crud`) || 0;
|
|
16
16
|
const cacheKey = [config.pg?.database, "cms:settings", crudInc, entity, keys, uid].filter(Boolean).join(":");
|
|
17
17
|
const cache = ttl === 0 ? null : await rclient.get(cacheKey);
|
|
18
18
|
|
|
@@ -11,16 +11,9 @@ export default async function getSingle({
|
|
|
11
11
|
const id = id1 || (contentId1 === 'pages' ? undefined : contentId1) || '';
|
|
12
12
|
const contentId = id1 ? contentId1 : "pages";
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
// "type": "select",
|
|
18
|
-
// "data": "cms.page_type"
|
|
19
|
-
// });
|
|
20
|
-
|
|
21
|
-
const customColumns = await pg.query(`
|
|
22
|
-
SELECT columns FROM site.content_types WHERE content_type_id in (select content_type_id from site.contents where content_id=$1) limit 1
|
|
23
|
-
`, [id1 || contentId]).then(el => el.rows?.[0]?.columns || []);
|
|
14
|
+
const customColumns = await pg.query(
|
|
15
|
+
`select columns FROM site.content_types where content_type_id=$1`, [id || contentId]
|
|
16
|
+
).then(el => el.rows?.[0]?.columns || []);
|
|
24
17
|
|
|
25
18
|
const contentQuery = contentId === 'pages' || !id
|
|
26
19
|
? `(type = 'single' or content_type_id = 'pages')`
|
|
@@ -174,6 +167,9 @@ export default async function getSingle({
|
|
|
174
167
|
});
|
|
175
168
|
});
|
|
176
169
|
|
|
170
|
+
// temporary solution, before front makes changes to call by id, not type
|
|
171
|
+
rows1.forEach(row => Object.assign(row, { content_type_id: row.content_id }));
|
|
172
|
+
|
|
177
173
|
return {
|
|
178
174
|
locales,
|
|
179
175
|
type: 'single',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { dataInsert, dataUpdate, pgClients } from '@opengis/fastify-table/utils.js';
|
|
2
2
|
|
|
3
3
|
import updateCustomContentTable from '../utils/updateCustomContentTable.js';
|
|
4
4
|
import updateContents from '../utils/updateContents.js';
|
|
@@ -13,12 +13,22 @@ export default async function builderPut(req, reply) {
|
|
|
13
13
|
return reply.status(404).send('table not found');
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
const single = await pg.query(
|
|
17
|
+
`select content_id as id FROM site.contents
|
|
18
|
+
where $1 in (content_id, slug)`, [params.id]
|
|
19
|
+
).then(el => el.rows?.[0]);
|
|
20
|
+
|
|
21
|
+
const customCtExists = await pg.query(
|
|
22
|
+
`select 1 FROM site.content_types
|
|
23
|
+
where content_type_id=$1`, [params.id]
|
|
24
|
+
).then(el => el.rowCount || 0);
|
|
25
|
+
|
|
16
26
|
const { cid, table } = await pg.query(
|
|
17
27
|
`select content_type_id as cid, table_name as table, type from site.content_types where $1 in (content_type_id, name)`,
|
|
18
28
|
[params.id],
|
|
19
29
|
).then(el => el.rows?.[0] || {});
|
|
20
30
|
|
|
21
|
-
if (!cid) {
|
|
31
|
+
if (!cid && !single) {
|
|
22
32
|
return reply.status(404).send('content type not found');
|
|
23
33
|
}
|
|
24
34
|
|
|
@@ -39,13 +49,23 @@ export default async function builderPut(req, reply) {
|
|
|
39
49
|
await updateCustomContentTable({ pg: client, id: cid, columns });
|
|
40
50
|
}
|
|
41
51
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
if (single && !customCtExists) {
|
|
53
|
+
await dataInsert({
|
|
54
|
+
pg,
|
|
55
|
+
table: 'site.content_types',
|
|
56
|
+
id: params.id,
|
|
57
|
+
data: body,
|
|
58
|
+
uid: user?.uid,
|
|
59
|
+
});
|
|
60
|
+
} else {
|
|
61
|
+
await dataUpdate({
|
|
62
|
+
pg: client,
|
|
63
|
+
table: 'site.content_types',
|
|
64
|
+
id: cid,
|
|
65
|
+
data: body,
|
|
66
|
+
uid: user?.uid,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
49
69
|
|
|
50
70
|
const row = await updateContents(client, cid, { ...body, slug: body.slug || body.name }, user?.uid);
|
|
51
71
|
|
|
@@ -9,11 +9,24 @@ export default async function builderGet({ pg = pgClients.client, params = {} },
|
|
|
9
9
|
return reply.status(404).send('table not found');
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
const single = await pg.query(
|
|
13
|
+
`select content_id as id, * FROM site.contents
|
|
14
|
+
where $1 in (content_id, slug)`, [params.id]
|
|
15
|
+
).then(el => el.rows?.[0]);
|
|
16
|
+
|
|
12
17
|
const row = await pg.query(
|
|
13
18
|
`select content_type_id as id, * FROM site.content_types
|
|
14
19
|
where $1 in (content_type_id, name)`, [params.id]
|
|
15
20
|
).then(el => el.rows?.[0]);
|
|
16
21
|
|
|
22
|
+
if (single && !row) {
|
|
23
|
+
const loadTable = await getTemplate('table', 'single.default.table');
|
|
24
|
+
const { columns: defaultColumns } = loadTable || {};
|
|
25
|
+
(defaultColumns || []).forEach(col => Object.assign(col, { default: true }));
|
|
26
|
+
const columns = (defaultColumns || []).filter(col => !col.hidden);
|
|
27
|
+
return reply.status(200).send({ default: true, id: single.id, name: single.slug, type: 'single', ...single, columns });
|
|
28
|
+
}
|
|
29
|
+
|
|
17
30
|
if (!row) {
|
|
18
31
|
return reply.status(404).send('content type not found');
|
|
19
32
|
}
|
|
@@ -19,6 +19,22 @@ export default async function updateContents(pg, id, data, uid) {
|
|
|
19
19
|
return result;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
const single = await pg.query(
|
|
23
|
+
`select content_id from site.contents where content_id=$1`,
|
|
24
|
+
[id],
|
|
25
|
+
).then(el => el.rowCount || 0);
|
|
26
|
+
|
|
27
|
+
if (single) {
|
|
28
|
+
const result = await dataUpdate({
|
|
29
|
+
pg,
|
|
30
|
+
table: 'site.contents',
|
|
31
|
+
id,
|
|
32
|
+
data,
|
|
33
|
+
uid,
|
|
34
|
+
});
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
|
|
22
38
|
const result = await dataInsert({
|
|
23
39
|
pg,
|
|
24
40
|
table: 'site.contents',
|
|
@@ -10,7 +10,7 @@ export default async function getMenuAPI(req, reply) {
|
|
|
10
10
|
page: query.page,
|
|
11
11
|
limit: Math.min(query.limit || limit, limit),
|
|
12
12
|
sql: query.sql,
|
|
13
|
-
ttl:
|
|
13
|
+
ttl: 0
|
|
14
14
|
});
|
|
15
15
|
|
|
16
16
|
if (result.error) {
|
|
@@ -21,5 +21,5 @@ export default async function getMenuAPI(req, reply) {
|
|
|
21
21
|
return reply.status(200).send(result);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
return reply.status(200).send({ rows: result.rows });
|
|
24
|
+
return reply.status(200).send({ cache: result.cache, rows: result.rows });
|
|
25
25
|
}
|
|
@@ -14,8 +14,8 @@ export default async function getMenu(name, { locale, ttl = 3600, page, limit =
|
|
|
14
14
|
return { error: 'table not found', code: 404 };
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
const crudInc = await rclient.get(`pg:site.menus:crud`) || 0;
|
|
18
|
-
const cacheKey = createHash('md5').update([config.pg?.database, 'cms:menu', crudInc, name, locale].filter(Boolean).join(':')).digest('hex');
|
|
17
|
+
const crudInc = await rclient.get(`pg:${config.pg?.database}:site.menus:crud`) || 0;
|
|
18
|
+
const cacheKey = createHash('md5').update([config.pg?.database, 'cms:menu', crudInc, name, locale, page, limit].filter(Boolean).join(':')).digest('hex');
|
|
19
19
|
|
|
20
20
|
const cache = ttl === 0 ? null : await rclient.get(cacheKey);
|
|
21
21
|
|
|
@@ -46,5 +46,5 @@ export default async function getMenu(name, { locale, ttl = 3600, page, limit =
|
|
|
46
46
|
// save to cache, default = 1 hour
|
|
47
47
|
if (ttl) await rclient.set(cacheKey, JSON.stringify(payload), 'EX', ttl);
|
|
48
48
|
|
|
49
|
-
return payload;
|
|
49
|
+
return { cache: false, ...payload };
|
|
50
50
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
select uid, coalesce(sur_name,'')||coalesce(' '||user_name,'') as text, email from admin.users
|
|
1
|
+
select uid, coalesce(sur_name,'')||coalesce(' '||user_name,'') as text, email from admin.users
|
|
2
2
|
where enabled order by coalesce(sur_name,'')||coalesce(' '||user_name,'')
|