@opengis/cms 0.0.44 → 0.0.45
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 +98 -98
- package/dist/{en-OTy187va.js → en-sWmaB9uu.js} +3 -1
- package/dist/index.html +29 -29
- package/dist/index.js +4208 -4125
- package/dist/index.umd.cjs +70 -65
- package/dist/{uk-Dy2psXBp.js → uk-rH4IPxG5.js} +4 -2
- package/input-types.json +9 -9
- 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 +3 -3
- package/plugin.js +43 -43
- package/server/app.js +35 -35
- package/server/config.js +4 -4
- package/server/functions/getDraftKey.js +22 -22
- package/server/index.js +22 -22
- package/server/migrations/fixes.sql +124 -124
- package/server/migrations/site.sql +595 -595
- 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 -49
- package/server/routes/cms/controllers/getContent.js +110 -110
- package/server/routes/cms/controllers/getContentBySlug.js +93 -93
- package/server/routes/cms/controllers/getPermissions.js +15 -15
- package/server/routes/cms/controllers/insertContent.js +217 -217
- package/server/routes/cms/controllers/listMedia.js +108 -94
- package/server/routes/cms/controllers/metadataMedia.js +39 -39
- package/server/routes/cms/controllers/properties.get.js +53 -53
- package/server/routes/cms/controllers/properties.post.js +99 -99
- package/server/routes/cms/controllers/searchContent.js +205 -205
- package/server/routes/cms/controllers/setPermissions.js +49 -49
- package/server/routes/cms/controllers/translate.js +89 -89
- package/server/routes/cms/controllers/updateContent.js +238 -238
- package/server/routes/cms/controllers/uploadMedia.js +79 -79
- package/server/routes/cms/index.mjs +112 -112
- package/server/routes/cms/utils/additionalData.js +35 -35
- package/server/routes/cms/utils/getCollection.js +82 -82
- package/server/routes/cms/utils/getSingle.js +187 -187
- package/server/routes/cms/utils/inputTypes.js +5 -5
- package/server/routes/cms/utils/insertContentLocalization.js +86 -86
- package/server/routes/cms/utils/requestTranslation.js +85 -85
- package/server/routes/cms/utils/updateLocalization.js +47 -47
- package/server/routes/cmsSpace/controllers/deleteSpace.js +25 -25
- package/server/routes/cmsSpace/controllers/getSpaces.js +27 -27
- package/server/routes/cmsSpace/controllers/insertSpace.js +21 -21
- package/server/routes/cmsSpace/controllers/updateSpace.js +23 -23
- package/server/routes/cmsSpace/index.mjs +20 -20
- package/server/routes/contentType/controllers/addContentType.js +162 -162
- package/server/routes/contentType/controllers/contentTypeList.js +54 -54
- package/server/routes/contentType/controllers/delContentType.js +75 -75
- package/server/routes/contentType/controllers/editContentType.js +61 -61
- package/server/routes/contentType/controllers/getContentType.js +37 -37
- package/server/routes/contentType/index.mjs +35 -35
- package/server/routes/contentType/utils/updateContents.js +28 -28
- 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 +42 -42
- 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/server/templates/select/core.user_mentioned.sql +1 -1
|
@@ -1,78 +1,78 @@
|
|
|
1
|
-
import fp from 'fastify-plugin';
|
|
2
|
-
import { createReadStream } from 'node:fs';
|
|
3
|
-
|
|
4
|
-
function plugin(fastify) {
|
|
5
|
-
// preSerialization
|
|
6
|
-
fastify.addHook('preSerialization', async (req, reply, payload) => {
|
|
7
|
-
/*if (req.url.includes('/suggest/') && !req.query.json) {
|
|
8
|
-
return payload?.data;
|
|
9
|
-
}*/
|
|
10
|
-
/* if (payload.redirect) {
|
|
11
|
-
return reply.redirect(payload.redirect);
|
|
12
|
-
}*/
|
|
13
|
-
if (reply.sent) {
|
|
14
|
-
return null;
|
|
15
|
-
}
|
|
16
|
-
if (!payload) {
|
|
17
|
-
return payload;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (['200', '400', '500', '403', '404'].includes(payload.status)) {
|
|
21
|
-
reply.status(payload.status);
|
|
22
|
-
}
|
|
23
|
-
/* if (payload.headers) {
|
|
24
|
-
reply.headers(payload.headers);
|
|
25
|
-
} */
|
|
26
|
-
if (payload.buffer) {
|
|
27
|
-
return payload.buffer;
|
|
28
|
-
}
|
|
29
|
-
if (payload.file) {
|
|
30
|
-
// const buffer = await readFile(payload.file);
|
|
31
|
-
// return reply.send(buffer);
|
|
32
|
-
const stream = createReadStream(payload.file);
|
|
33
|
-
return stream;
|
|
34
|
-
// return reply.send(stream);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (payload.message) {
|
|
38
|
-
return payload.message;
|
|
39
|
-
}
|
|
40
|
-
return payload;
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
// preValidation
|
|
44
|
-
fastify.addHook('preValidation', async (req) => {
|
|
45
|
-
const parseRawBody = ['POST', 'PUT'].includes(req.method) && req.body && typeof req.body === 'string'
|
|
46
|
-
&& req.body.trim(/\r\n/g).startsWith('{')
|
|
47
|
-
&& req.body.trim(/\r\n/g).endsWith('}');
|
|
48
|
-
if (parseRawBody) {
|
|
49
|
-
try {
|
|
50
|
-
req.body = JSON.parse(req.body || '{}');
|
|
51
|
-
}
|
|
52
|
-
catch (err) {
|
|
53
|
-
// throw new Error('invalid body');
|
|
54
|
-
// return { error: 'invalid body', status: 400 };
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
// allow upload file
|
|
60
|
-
const kIsMultipart = Symbol.for('[FastifyMultipart.isMultipart]');
|
|
61
|
-
fastify.addContentTypeParser('multipart', (request, _, done) => {
|
|
62
|
-
request[kIsMultipart] = true;
|
|
63
|
-
done(null);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
// parse Body
|
|
67
|
-
function contentParser(req, body, done) {
|
|
68
|
-
const parseBody = decodeURIComponent(body.toString()).split('&').reduce((acc, el) => {
|
|
69
|
-
const [key, val] = el.split('=');
|
|
70
|
-
return { ...acc, [key]: val };
|
|
71
|
-
}, {});
|
|
72
|
-
done(null, parseBody);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
fastify.addContentTypeParser('application/x-www-form-urlencoded', { parseAs: 'buffer' }, contentParser);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export default fp(plugin);
|
|
1
|
+
import fp from 'fastify-plugin';
|
|
2
|
+
import { createReadStream } from 'node:fs';
|
|
3
|
+
|
|
4
|
+
function plugin(fastify) {
|
|
5
|
+
// preSerialization
|
|
6
|
+
fastify.addHook('preSerialization', async (req, reply, payload) => {
|
|
7
|
+
/*if (req.url.includes('/suggest/') && !req.query.json) {
|
|
8
|
+
return payload?.data;
|
|
9
|
+
}*/
|
|
10
|
+
/* if (payload.redirect) {
|
|
11
|
+
return reply.redirect(payload.redirect);
|
|
12
|
+
}*/
|
|
13
|
+
if (reply.sent) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
if (!payload) {
|
|
17
|
+
return payload;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (['200', '400', '500', '403', '404'].includes(payload.status)) {
|
|
21
|
+
reply.status(payload.status);
|
|
22
|
+
}
|
|
23
|
+
/* if (payload.headers) {
|
|
24
|
+
reply.headers(payload.headers);
|
|
25
|
+
} */
|
|
26
|
+
if (payload.buffer) {
|
|
27
|
+
return payload.buffer;
|
|
28
|
+
}
|
|
29
|
+
if (payload.file) {
|
|
30
|
+
// const buffer = await readFile(payload.file);
|
|
31
|
+
// return reply.send(buffer);
|
|
32
|
+
const stream = createReadStream(payload.file);
|
|
33
|
+
return stream;
|
|
34
|
+
// return reply.send(stream);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (payload.message) {
|
|
38
|
+
return payload.message;
|
|
39
|
+
}
|
|
40
|
+
return payload;
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// preValidation
|
|
44
|
+
fastify.addHook('preValidation', async (req) => {
|
|
45
|
+
const parseRawBody = ['POST', 'PUT'].includes(req.method) && req.body && typeof req.body === 'string'
|
|
46
|
+
&& req.body.trim(/\r\n/g).startsWith('{')
|
|
47
|
+
&& req.body.trim(/\r\n/g).endsWith('}');
|
|
48
|
+
if (parseRawBody) {
|
|
49
|
+
try {
|
|
50
|
+
req.body = JSON.parse(req.body || '{}');
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
// throw new Error('invalid body');
|
|
54
|
+
// return { error: 'invalid body', status: 400 };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// allow upload file
|
|
60
|
+
const kIsMultipart = Symbol.for('[FastifyMultipart.isMultipart]');
|
|
61
|
+
fastify.addContentTypeParser('multipart', (request, _, done) => {
|
|
62
|
+
request[kIsMultipart] = true;
|
|
63
|
+
done(null);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// parse Body
|
|
67
|
+
function contentParser(req, body, done) {
|
|
68
|
+
const parseBody = decodeURIComponent(body.toString()).split('&').reduce((acc, el) => {
|
|
69
|
+
const [key, val] = el.split('=');
|
|
70
|
+
return { ...acc, [key]: val };
|
|
71
|
+
}, {});
|
|
72
|
+
done(null, parseBody);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
fastify.addContentTypeParser('application/x-www-form-urlencoded', { parseAs: 'buffer' }, contentParser);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export default fp(plugin);
|
package/server/plugins/hook.js
CHANGED
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
import fp from 'fastify-plugin';
|
|
2
|
-
import { randomUUID, createHash } from 'node:crypto';
|
|
3
|
-
|
|
4
|
-
import { addHook, addCron, config, pgClients } from '@opengis/fastify-table/utils.js';
|
|
5
|
-
|
|
6
|
-
import getDraftKey from '../functions/getDraftKey.js';
|
|
7
|
-
|
|
8
|
-
const pg = pgClients.client;
|
|
9
|
-
|
|
10
|
-
const q = `select
|
|
11
|
-
content_id as id, a.status, type, published_at, table_name as table
|
|
12
|
-
from site.contents a
|
|
13
|
-
left join site.content_types b
|
|
14
|
-
on a.content_type_id=b.content_type_id
|
|
15
|
-
where
|
|
16
|
-
b.visible
|
|
17
|
-
and case
|
|
18
|
-
when type = 'single'
|
|
19
|
-
then
|
|
20
|
-
a.status='delayPublished'
|
|
21
|
-
and CURRENT_DATE >= published_at::date
|
|
22
|
-
else true
|
|
23
|
-
end`;
|
|
24
|
-
|
|
25
|
-
async function updateDelayPublished() {
|
|
26
|
-
const rows = await pg.query(q).then(el => el.rows || []);
|
|
27
|
-
|
|
28
|
-
const result = await Promise.all(rows.map(async ({ id, status, type, table }) => {
|
|
29
|
-
if (status === 'delayPublished' && type === 'single') {
|
|
30
|
-
const { rowCount } = await pg.query(`update site.contents set status='published' where content_id=$1`, [id]);
|
|
31
|
-
return { id, type, rowCount };
|
|
32
|
-
} else if (table && type === 'collection') {
|
|
33
|
-
const { rowCount } = await pg.query(`update data."${table}" set status='published' where status='delayPublished' and now() >= published_at`);
|
|
34
|
-
return { id, type, rowCount };
|
|
35
|
-
} else {
|
|
36
|
-
return { id, type, skip: true };
|
|
37
|
-
}
|
|
38
|
-
}));
|
|
39
|
-
const r = { updated: result.reduce((acc, curr) => acc + +(curr.rowCount || 0), 0), skipped: result.filter(el => el.skip).length };
|
|
40
|
-
if (config.trace) console.log(r);
|
|
41
|
-
return r;
|
|
42
|
-
}
|
|
43
|
-
function plugin(app) {
|
|
44
|
-
addHook('afterUser', async ({ payload = {} }) => {
|
|
45
|
-
if (payload?.user) {
|
|
46
|
-
// get from cache, refresh hourly
|
|
47
|
-
const { draftKey, ttl } = await getDraftKey();
|
|
48
|
-
Object.assign(payload.user, { draftKey, draftKeyTTL: ttl });
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
// force refresh at restart
|
|
52
|
-
app.addHook('onListen', async () => {
|
|
53
|
-
await getDraftKey(true);
|
|
54
|
-
});
|
|
55
|
-
addCron(updateDelayPublished, 60 * 60);
|
|
56
|
-
updateDelayPublished();
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export default fp(plugin);
|
|
1
|
+
import fp from 'fastify-plugin';
|
|
2
|
+
import { randomUUID, createHash } from 'node:crypto';
|
|
3
|
+
|
|
4
|
+
import { addHook, addCron, config, pgClients } from '@opengis/fastify-table/utils.js';
|
|
5
|
+
|
|
6
|
+
import getDraftKey from '../functions/getDraftKey.js';
|
|
7
|
+
|
|
8
|
+
const pg = pgClients.client;
|
|
9
|
+
|
|
10
|
+
const q = `select
|
|
11
|
+
content_id as id, a.status, type, published_at, table_name as table
|
|
12
|
+
from site.contents a
|
|
13
|
+
left join site.content_types b
|
|
14
|
+
on a.content_type_id=b.content_type_id
|
|
15
|
+
where
|
|
16
|
+
b.visible
|
|
17
|
+
and case
|
|
18
|
+
when type = 'single'
|
|
19
|
+
then
|
|
20
|
+
a.status='delayPublished'
|
|
21
|
+
and CURRENT_DATE >= published_at::date
|
|
22
|
+
else true
|
|
23
|
+
end`;
|
|
24
|
+
|
|
25
|
+
async function updateDelayPublished() {
|
|
26
|
+
const rows = await pg.query(q).then(el => el.rows || []);
|
|
27
|
+
|
|
28
|
+
const result = await Promise.all(rows.map(async ({ id, status, type, table }) => {
|
|
29
|
+
if (status === 'delayPublished' && type === 'single') {
|
|
30
|
+
const { rowCount } = await pg.query(`update site.contents set status='published' where content_id=$1`, [id]);
|
|
31
|
+
return { id, type, rowCount };
|
|
32
|
+
} else if (table && type === 'collection') {
|
|
33
|
+
const { rowCount } = await pg.query(`update data."${table}" set status='published' where status='delayPublished' and now() >= published_at`);
|
|
34
|
+
return { id, type, rowCount };
|
|
35
|
+
} else {
|
|
36
|
+
return { id, type, skip: true };
|
|
37
|
+
}
|
|
38
|
+
}));
|
|
39
|
+
const r = { updated: result.reduce((acc, curr) => acc + +(curr.rowCount || 0), 0), skipped: result.filter(el => el.skip).length };
|
|
40
|
+
if (config.trace) console.log(r);
|
|
41
|
+
return r;
|
|
42
|
+
}
|
|
43
|
+
function plugin(app) {
|
|
44
|
+
addHook('afterUser', async ({ payload = {} }) => {
|
|
45
|
+
if (payload?.user) {
|
|
46
|
+
// get from cache, refresh hourly
|
|
47
|
+
const { draftKey, ttl } = await getDraftKey();
|
|
48
|
+
Object.assign(payload.user, { draftKey, draftKeyTTL: ttl });
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
// force refresh at restart
|
|
52
|
+
app.addHook('onListen', async () => {
|
|
53
|
+
await getDraftKey(true);
|
|
54
|
+
});
|
|
55
|
+
addCron(updateDelayPublished, 60 * 60);
|
|
56
|
+
updateDelayPublished();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export default fp(plugin);
|
package/server/plugins/vite.js
CHANGED
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { createServer } from 'vite';
|
|
4
|
-
|
|
5
|
-
import { config } from '@opengis/fastify-table/utils.js';
|
|
6
|
-
|
|
7
|
-
const isProduction = process.env.NODE_ENV !== 'dev';
|
|
8
|
-
console.log({ isProduction })
|
|
9
|
-
async function plugin(fastify) {
|
|
10
|
-
// vite server
|
|
11
|
-
const viteServer = !isProduction ? await createServer({
|
|
12
|
-
root: 'admin',
|
|
13
|
-
server: {
|
|
14
|
-
middlewareMode: true,
|
|
15
|
-
},
|
|
16
|
-
}) : null;
|
|
17
|
-
|
|
18
|
-
if (!isProduction) {
|
|
19
|
-
const dir1 = process.cwd();
|
|
20
|
-
viteServer.watcher.add(dir1);
|
|
21
|
-
viteServer.watcher.on('all', (d, t) => {
|
|
22
|
-
if (!t.includes('module')) return;
|
|
23
|
-
console.log(d, t);
|
|
24
|
-
viteServer.ws.send({ type: 'full-reload' });
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
// this is middleware for vite's dev server
|
|
28
|
-
fastify.addHook('onRequest', async (req, reply) => {
|
|
29
|
-
const { user } = req.session?.passport || {};
|
|
30
|
-
// console.log(req.url);
|
|
31
|
-
|
|
32
|
-
const next = () => new Promise((resolve) => {
|
|
33
|
-
viteServer.middlewares(req.raw, reply.raw, () => resolve());
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
await next();
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// From Build
|
|
41
|
-
fastify.get('*', async (req, reply) => {
|
|
42
|
-
const { user } = req.session?.passport || {};
|
|
43
|
-
const indexPath = path.join('admin/dist', 'index.html');
|
|
44
|
-
if (!user && config.pg && !req.url.startsWith('/src/') && !config.auth?.disable) {
|
|
45
|
-
return reply.redirect('/login');
|
|
46
|
-
}
|
|
47
|
-
if (!fs.existsSync(indexPath)) {
|
|
48
|
-
return reply.status(404).send('index.html not found');
|
|
49
|
-
}
|
|
50
|
-
const stream = fs.createReadStream(indexPath);
|
|
51
|
-
return reply.type('text/html').send(stream);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
const fileSize = {};
|
|
55
|
-
async function staticFile(req, reply) {
|
|
56
|
-
const assetsDir = 'admin/dist';
|
|
57
|
-
const filePath = path.join( assetsDir, req.url);
|
|
58
|
-
const ext = path.extname(filePath);
|
|
59
|
-
|
|
60
|
-
if (!fs.existsSync(filePath)) return { status: 404, message: 'not found' };
|
|
61
|
-
fileSize[filePath] = fileSize[filePath] || fs.statSync(filePath).size;
|
|
62
|
-
const mime = {
|
|
63
|
-
'.js': 'text/javascript', '.css': 'text/css', '.woff2': 'application/font-woff', '.png': 'image/png', '.svg': 'image/svg+xml', '.jpg': 'image/jpg',
|
|
64
|
-
}[ext];
|
|
65
|
-
reply.headers({ 'Cache-control': 'max-age=3600, public', 'Content-length': fileSize[filePath], 'Content-Encoding': 'identity' });
|
|
66
|
-
|
|
67
|
-
const stream = fs.createReadStream(filePath);
|
|
68
|
-
return mime ? reply.type(mime).send(stream) : stream;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
fastify.get('/assets/*', staticFile);
|
|
72
|
-
fastify.get('/public/*', staticFile);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export default plugin;
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { createServer } from 'vite';
|
|
4
|
+
|
|
5
|
+
import { config } from '@opengis/fastify-table/utils.js';
|
|
6
|
+
|
|
7
|
+
const isProduction = process.env.NODE_ENV !== 'dev';
|
|
8
|
+
console.log({ isProduction })
|
|
9
|
+
async function plugin(fastify) {
|
|
10
|
+
// vite server
|
|
11
|
+
const viteServer = !isProduction ? await createServer({
|
|
12
|
+
root: 'admin',
|
|
13
|
+
server: {
|
|
14
|
+
middlewareMode: true,
|
|
15
|
+
},
|
|
16
|
+
}) : null;
|
|
17
|
+
|
|
18
|
+
if (!isProduction) {
|
|
19
|
+
const dir1 = process.cwd();
|
|
20
|
+
viteServer.watcher.add(dir1);
|
|
21
|
+
viteServer.watcher.on('all', (d, t) => {
|
|
22
|
+
if (!t.includes('module')) return;
|
|
23
|
+
console.log(d, t);
|
|
24
|
+
viteServer.ws.send({ type: 'full-reload' });
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// this is middleware for vite's dev server
|
|
28
|
+
fastify.addHook('onRequest', async (req, reply) => {
|
|
29
|
+
const { user } = req.session?.passport || {};
|
|
30
|
+
// console.log(req.url);
|
|
31
|
+
|
|
32
|
+
const next = () => new Promise((resolve) => {
|
|
33
|
+
viteServer.middlewares(req.raw, reply.raw, () => resolve());
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
await next();
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// From Build
|
|
41
|
+
fastify.get('*', async (req, reply) => {
|
|
42
|
+
const { user } = req.session?.passport || {};
|
|
43
|
+
const indexPath = path.join('admin/dist', 'index.html');
|
|
44
|
+
if (!user && config.pg && !req.url.startsWith('/src/') && !config.auth?.disable) {
|
|
45
|
+
return reply.redirect('/login');
|
|
46
|
+
}
|
|
47
|
+
if (!fs.existsSync(indexPath)) {
|
|
48
|
+
return reply.status(404).send('index.html not found');
|
|
49
|
+
}
|
|
50
|
+
const stream = fs.createReadStream(indexPath);
|
|
51
|
+
return reply.type('text/html').send(stream);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const fileSize = {};
|
|
55
|
+
async function staticFile(req, reply) {
|
|
56
|
+
const assetsDir = 'admin/dist';
|
|
57
|
+
const filePath = path.join( assetsDir, req.url);
|
|
58
|
+
const ext = path.extname(filePath);
|
|
59
|
+
|
|
60
|
+
if (!fs.existsSync(filePath)) return { status: 404, message: 'not found' };
|
|
61
|
+
fileSize[filePath] = fileSize[filePath] || fs.statSync(filePath).size;
|
|
62
|
+
const mime = {
|
|
63
|
+
'.js': 'text/javascript', '.css': 'text/css', '.woff2': 'application/font-woff', '.png': 'image/png', '.svg': 'image/svg+xml', '.jpg': 'image/jpg',
|
|
64
|
+
}[ext];
|
|
65
|
+
reply.headers({ 'Cache-control': 'max-age=3600, public', 'Content-length': fileSize[filePath], 'Content-Encoding': 'identity' });
|
|
66
|
+
|
|
67
|
+
const stream = fs.createReadStream(filePath);
|
|
68
|
+
return mime ? reply.type(mime).send(stream) : stream;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
fastify.get('/assets/*', staticFile);
|
|
72
|
+
fastify.get('/public/*', staticFile);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export default plugin;
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { dataDelete, getMeta } from '@opengis/fastify-table/utils.js';
|
|
2
|
-
|
|
3
|
-
export default async function categoryDelete({ user = {}, params = {} }) {
|
|
4
|
-
|
|
5
|
-
if (!params.id) {
|
|
6
|
-
return { message: 'id is required', status: 400 };
|
|
7
|
-
}
|
|
8
|
-
const { pk } = await getMeta({ table: 'site.categories' });
|
|
9
|
-
|
|
10
|
-
if (!pk) {
|
|
11
|
-
return { message: 'table not found', status: 404 };
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const res = await dataDelete({
|
|
15
|
-
table: 'site.categories',
|
|
16
|
-
id: params.id,
|
|
17
|
-
uid: user?.uid
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
return { id: res.category_id, rows: [res] };
|
|
21
|
-
}
|
|
1
|
+
import { dataDelete, getMeta } from '@opengis/fastify-table/utils.js';
|
|
2
|
+
|
|
3
|
+
export default async function categoryDelete({ user = {}, params = {} }) {
|
|
4
|
+
|
|
5
|
+
if (!params.id) {
|
|
6
|
+
return { message: 'id is required', status: 400 };
|
|
7
|
+
}
|
|
8
|
+
const { pk } = await getMeta({ table: 'site.categories' });
|
|
9
|
+
|
|
10
|
+
if (!pk) {
|
|
11
|
+
return { message: 'table not found', status: 404 };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const res = await dataDelete({
|
|
15
|
+
table: 'site.categories',
|
|
16
|
+
id: params.id,
|
|
17
|
+
uid: user?.uid
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
return { id: res.category_id, rows: [res] };
|
|
21
|
+
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { pgClients, getMeta, getTemplate } from '@opengis/fastify-table/utils.js';
|
|
2
|
-
|
|
3
|
-
export default async function categoryGet({ pg = pgClients.client, params = {} }) {
|
|
4
|
-
|
|
5
|
-
const { pk } = await getMeta({ table: 'site.categories' });
|
|
6
|
-
|
|
7
|
-
if (!pk) {
|
|
8
|
-
return { message: 'table not found', status: 404 };
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const { rows, rowCount: total } = await pg.query(
|
|
12
|
-
`select a.category_id as id, a.* FROM site.categories a
|
|
13
|
-
where a.category_id=$1`,
|
|
14
|
-
[params.id]
|
|
15
|
-
);
|
|
16
|
-
return { message: { total, rows }, status: 200 };
|
|
17
|
-
}
|
|
1
|
+
import { pgClients, getMeta, getTemplate } from '@opengis/fastify-table/utils.js';
|
|
2
|
+
|
|
3
|
+
export default async function categoryGet({ pg = pgClients.client, params = {} }) {
|
|
4
|
+
|
|
5
|
+
const { pk } = await getMeta({ table: 'site.categories' });
|
|
6
|
+
|
|
7
|
+
if (!pk) {
|
|
8
|
+
return { message: 'table not found', status: 404 };
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const { rows, rowCount: total } = await pg.query(
|
|
12
|
+
`select a.category_id as id, a.* FROM site.categories a
|
|
13
|
+
where a.category_id=$1`,
|
|
14
|
+
[params.id]
|
|
15
|
+
);
|
|
16
|
+
return { message: { total, rows }, status: 200 };
|
|
17
|
+
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { pgClients, getTemplate, getMeta } from '@opengis/fastify-table/utils.js';
|
|
2
|
-
|
|
3
|
-
export default async function categoryList({ pg = pgClients.client, query = {} }) {
|
|
4
|
-
|
|
5
|
-
const { pk } = await getMeta({ table: 'site.categories' });
|
|
6
|
-
|
|
7
|
-
if (!pk) {
|
|
8
|
-
return { message: 'table not found', status: 404 };
|
|
9
|
-
}
|
|
10
|
-
const sql = `select a.category_id as id, a.* FROM site.categories a
|
|
11
|
-
where ${query.category_id ? 'category_id=$1' : '1=1'}`
|
|
12
|
-
|
|
13
|
-
const { rows, rowCount: total } = await pg.query(sql, [query.category_id].filter((el) => el));
|
|
14
|
-
|
|
15
|
-
return { message: { total, rows }, status: 200 };
|
|
16
|
-
}
|
|
1
|
+
import { pgClients, getTemplate, getMeta } from '@opengis/fastify-table/utils.js';
|
|
2
|
+
|
|
3
|
+
export default async function categoryList({ pg = pgClients.client, query = {} }) {
|
|
4
|
+
|
|
5
|
+
const { pk } = await getMeta({ table: 'site.categories' });
|
|
6
|
+
|
|
7
|
+
if (!pk) {
|
|
8
|
+
return { message: 'table not found', status: 404 };
|
|
9
|
+
}
|
|
10
|
+
const sql = `select a.category_id as id, a.* FROM site.categories a
|
|
11
|
+
where ${query.category_id ? 'category_id=$1' : '1=1'}`
|
|
12
|
+
|
|
13
|
+
const { rows, rowCount: total } = await pg.query(sql, [query.category_id].filter((el) => el));
|
|
14
|
+
|
|
15
|
+
return { message: { total, rows }, status: 200 };
|
|
16
|
+
}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { dataInsert, getMeta } from "@opengis/fastify-table/utils.js";
|
|
2
|
-
|
|
3
|
-
export default async function categoryPost(req) {
|
|
4
|
-
const { user = {}, body = {} } = req;
|
|
5
|
-
|
|
6
|
-
const { pk } = await getMeta({ table: "site.categories" });
|
|
7
|
-
|
|
8
|
-
if (!pk) {
|
|
9
|
-
return { message: "table not found", status: 404 };
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const resData = await dataInsert({
|
|
13
|
-
table: "site.categories",
|
|
14
|
-
data: body,
|
|
15
|
-
uid: user?.uid,
|
|
16
|
-
});
|
|
17
|
-
// console.log(resData);
|
|
18
|
-
const res = resData?.rows[0];
|
|
19
|
-
|
|
20
|
-
return { id: res.category_id, rows: [res] };
|
|
21
|
-
}
|
|
1
|
+
import { dataInsert, getMeta } from "@opengis/fastify-table/utils.js";
|
|
2
|
+
|
|
3
|
+
export default async function categoryPost(req) {
|
|
4
|
+
const { user = {}, body = {} } = req;
|
|
5
|
+
|
|
6
|
+
const { pk } = await getMeta({ table: "site.categories" });
|
|
7
|
+
|
|
8
|
+
if (!pk) {
|
|
9
|
+
return { message: "table not found", status: 404 };
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const resData = await dataInsert({
|
|
13
|
+
table: "site.categories",
|
|
14
|
+
data: body,
|
|
15
|
+
uid: user?.uid,
|
|
16
|
+
});
|
|
17
|
+
// console.log(resData);
|
|
18
|
+
const res = resData?.rows[0];
|
|
19
|
+
|
|
20
|
+
return { id: res.category_id, rows: [res] };
|
|
21
|
+
}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { dataUpdate, getMeta } from '@opengis/fastify-table/utils.js';
|
|
2
|
-
|
|
3
|
-
export default async function categoryPut({ body = {}, params = {} }) {
|
|
4
|
-
|
|
5
|
-
if (!params.id) {
|
|
6
|
-
return { message: 'id is required', status: 400 };
|
|
7
|
-
}
|
|
8
|
-
const { pk } = await getMeta({ table: 'site.categories' });
|
|
9
|
-
|
|
10
|
-
if (!pk) {
|
|
11
|
-
return { message: 'table not found', status: 404 };
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const resData = await dataUpdate({
|
|
15
|
-
table: 'site.categories',
|
|
16
|
-
data: body,
|
|
17
|
-
id: params.id,
|
|
18
|
-
});
|
|
19
|
-
// console.log(resData)
|
|
20
|
-
const res = resData;
|
|
21
|
-
|
|
22
|
-
return { id: res.category_id, rows: [res] };
|
|
23
|
-
}
|
|
1
|
+
import { dataUpdate, getMeta } from '@opengis/fastify-table/utils.js';
|
|
2
|
+
|
|
3
|
+
export default async function categoryPut({ body = {}, params = {} }) {
|
|
4
|
+
|
|
5
|
+
if (!params.id) {
|
|
6
|
+
return { message: 'id is required', status: 400 };
|
|
7
|
+
}
|
|
8
|
+
const { pk } = await getMeta({ table: 'site.categories' });
|
|
9
|
+
|
|
10
|
+
if (!pk) {
|
|
11
|
+
return { message: 'table not found', status: 404 };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const resData = await dataUpdate({
|
|
15
|
+
table: 'site.categories',
|
|
16
|
+
data: body,
|
|
17
|
+
id: params.id,
|
|
18
|
+
});
|
|
19
|
+
// console.log(resData)
|
|
20
|
+
const res = resData;
|
|
21
|
+
|
|
22
|
+
return { id: res.category_id, rows: [res] };
|
|
23
|
+
}
|