@opengis/cms 0.0.42 → 0.0.44

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.
Files changed (95) hide show
  1. package/README.md +98 -98
  2. package/dist/{en-CzEziHMG.js → en-OTy187va.js} +1 -0
  3. package/dist/index.html +29 -29
  4. package/dist/index.js +6266 -15660
  5. package/dist/index.umd.cjs +75 -77
  6. package/dist/{uk-TyVZmyOZ.js → uk-Dy2psXBp.js} +1 -0
  7. package/input-types.json +10 -0
  8. package/module/cms/cls/content.status.json +17 -17
  9. package/module/cms/cls/user_type.json +9 -9
  10. package/module/cms/form/admin.users.form.json +77 -77
  11. package/module/cms/select/cms.page_type.sql +1 -1
  12. package/module/cms/select/news_tag_id.sql +11 -11
  13. package/module/cms/table/admin.users.table.json +53 -53
  14. package/module/cms/table/collection.default.table.json +96 -96
  15. package/module/cms/table/single.default.table.json +116 -114
  16. package/package.json +65 -71
  17. package/plugin.js +43 -76
  18. package/server/app.js +35 -35
  19. package/server/config.js +4 -4
  20. package/server/functions/getDraftKey.js +22 -22
  21. package/server/index.js +22 -22
  22. package/server/migrations/fixes.sql +124 -124
  23. package/server/migrations/site.sql +595 -595
  24. package/server/plugins/adminHook.js +78 -78
  25. package/server/plugins/hook.js +59 -59
  26. package/server/plugins/vite.js +75 -75
  27. package/server/routes/category/controllers/cms.category.delete.js +21 -21
  28. package/server/routes/category/controllers/cms.category.get.js +17 -17
  29. package/server/routes/category/controllers/cms.category.list.js +16 -16
  30. package/server/routes/category/controllers/cms.category.post.js +21 -21
  31. package/server/routes/category/controllers/cms.category.put.js +23 -23
  32. package/server/routes/category/index.mjs +22 -22
  33. package/server/routes/cms/controllers/cmsStat.js +55 -55
  34. package/server/routes/cms/controllers/cmsSuggest.js +57 -57
  35. package/server/routes/cms/controllers/deleteContent.js +113 -113
  36. package/server/routes/cms/controllers/getContent.js +110 -110
  37. package/server/routes/cms/controllers/getContentBySlug.js +93 -95
  38. package/server/routes/cms/controllers/getPermissions.js +15 -15
  39. package/server/routes/cms/controllers/insertContent.js +217 -218
  40. package/server/routes/cms/controllers/properties.get.js +53 -53
  41. package/server/routes/cms/controllers/properties.post.js +99 -99
  42. package/server/routes/cms/controllers/searchContent.js +205 -205
  43. package/server/routes/cms/controllers/setPermissions.js +49 -49
  44. package/server/routes/cms/controllers/translate.js +89 -89
  45. package/server/routes/cms/controllers/updateContent.js +238 -240
  46. package/server/routes/cms/index.mjs +112 -114
  47. package/server/routes/cms/utils/additionalData.js +35 -35
  48. package/server/routes/cms/utils/getCollection.js +82 -82
  49. package/server/routes/cms/utils/getSingle.js +187 -189
  50. package/server/routes/cms/utils/inputTypes.js +6 -0
  51. package/server/routes/cms/utils/insertContentLocalization.js +86 -86
  52. package/server/routes/cms/utils/requestTranslation.js +85 -85
  53. package/server/routes/cms/utils/updateLocalization.js +47 -47
  54. package/server/routes/cmsSpace/controllers/deleteSpace.js +25 -25
  55. package/server/routes/cmsSpace/controllers/getSpaces.js +27 -27
  56. package/server/routes/cmsSpace/controllers/insertSpace.js +21 -21
  57. package/server/routes/cmsSpace/controllers/updateSpace.js +23 -23
  58. package/server/routes/cmsSpace/index.mjs +20 -20
  59. package/server/routes/contentType/controllers/addContentType.js +162 -162
  60. package/server/routes/contentType/controllers/contentTypeList.js +54 -54
  61. package/server/routes/contentType/controllers/delContentType.js +75 -75
  62. package/server/routes/contentType/controllers/editContentType.js +61 -61
  63. package/server/routes/contentType/controllers/getContentType.js +37 -37
  64. package/server/routes/contentType/index.mjs +35 -35
  65. package/server/routes/contentType/utils/updateContents.js +28 -28
  66. package/server/routes/contentType/utils/updateCustomContentTable.js +53 -55
  67. package/server/routes/feedback/controllers/email.list.js +24 -24
  68. package/server/routes/feedback/controllers/feedback.js +48 -48
  69. package/server/routes/feedback/controllers/feedback.list.js +37 -37
  70. package/server/routes/feedback/controllers/news.subscriptions.js +44 -44
  71. package/server/routes/feedback/index.mjs +71 -71
  72. package/server/routes/logs/controllers/export.user.logs.js +77 -77
  73. package/server/routes/logs/controllers/user.logs.js +44 -44
  74. package/server/routes/logs/index.mjs +9 -9
  75. package/server/routes/menu/controllers/addMenu.js +37 -37
  76. package/server/routes/menu/controllers/delMenu.js +31 -31
  77. package/server/routes/menu/controllers/editMenu.js +41 -41
  78. package/server/routes/menu/controllers/getMenu.js +42 -42
  79. package/server/routes/menu/index.mjs +13 -13
  80. package/server/routes/migration/controllers/collectionToCustom.js +137 -137
  81. package/server/routes/migration/index.mjs +8 -8
  82. package/server/routes/root.mjs +8 -8
  83. package/server/routes/tags/controllers/add.tags.js +24 -24
  84. package/server/routes/tags/controllers/del.tags.js +19 -19
  85. package/server/routes/tags/controllers/edit.tags.js +25 -25
  86. package/server/routes/tags/controllers/get.tags.js +15 -15
  87. package/server/routes/tags/index.mjs +14 -14
  88. package/server/templates/cls/cms.category_type.json +9 -9
  89. package/server/templates/cls/cms.content_review_status.json +9 -9
  90. package/server/templates/cls/cms.content_status.json +9 -9
  91. package/server/templates/cls/cms.content_type.json +9 -9
  92. package/server/templates/cls/cms.lang.json +9 -9
  93. package/server/templates/page/login.html +126 -126
  94. package/server/templates/select/core.user_mentioned.sql +1 -1
  95. package/dist/index-W-qQIppj-DRzFSjU1.js +0 -2452
@@ -1,114 +1,116 @@
1
- {
2
- "table": "site.contents",
3
- "columns": [
4
- {
5
- "label": "Slug",
6
- "name": "slug",
7
- "parent": "title",
8
- "required": true,
9
- "type": "slug"
10
- },
11
- {
12
- "label": "Title",
13
- "name": "title",
14
- "required": true,
15
- "type": "text",
16
- "localization": true
17
- },
18
- {
19
- "label": "Status",
20
- "name": "status",
21
- "type": "select",
22
- "data": "content.status",
23
- "options": [
24
- {
25
- "id": "draft",
26
- "text": "Draft"
27
- },
28
- {
29
- "id": "published",
30
- "text": "Published"
31
- },
32
- {
33
- "id": "archived",
34
- "text": "Archived"
35
- },
36
- {
37
- "id": "delayPublished",
38
- "text": "Delay Published"
39
- }
40
- ],
41
- "required": true
42
- },
43
- {
44
- "label": "Publish at",
45
- "name": "published_at",
46
- "required": true,
47
- "type": "datetime"
48
- },
49
- {
50
- "label": "Контент",
51
- "name": "single_body",
52
- "type": "richtext",
53
- "localization": true
54
- },
55
- {
56
- "name": "single_sections",
57
- "label": "Секції",
58
- "type": "reference",
59
- "localization": true
60
- },
61
- {
62
- "label": "Зображення",
63
- "name": "main_image",
64
- "type": "mediaselect"
65
- }
66
- ],
67
- "filters": [
68
- {
69
- "extra": false,
70
- "id": "status",
71
- "name": "status",
72
- "title": "Статус",
73
- "type": "Check",
74
- "data": "content.status",
75
- "ua": "Статус"
76
- },
77
- {
78
- "extra": false,
79
- "label": "Publish at",
80
- "name": "published_at",
81
- "type": "Date"
82
- },
83
- {
84
- "extra": false,
85
- "label": "Контент",
86
- "name": "single_body",
87
- "type": "Text"
88
- },
89
- {
90
- "extra": false,
91
- "name": "tag_list",
92
- "type": "Tags",
93
- "sql": "id in (select b.data_id from site.tags a left join site.tag_data b on a.tag_id=b.tag_id where a.tag_id=any($1))",
94
- "label": "Теги"
95
- },
96
- {
97
- "extra": false,
98
- "columns": "slug,title",
99
- "id": "search",
100
- "name": "search",
101
- "placeholder": "Пошук по тексту",
102
- "title": "Пошук по тексту",
103
- "type": "Text"
104
- },
105
- {
106
- "extra": false,
107
- "id": "created_at",
108
- "name": "created_at",
109
- "title": "Дата створення",
110
- "type": "Date",
111
- "ua": "Дата створення"
112
- }
113
- ]
114
- }
1
+ {
2
+ "table": "site.contents",
3
+ "columns": [
4
+ {
5
+ "label": "Заголовок",
6
+ "name": "title",
7
+ "required": true,
8
+ "type": "text",
9
+ "localization": true
10
+ },
11
+ {
12
+ "label": "Посилання",
13
+ "name": "slug",
14
+ "parent": "title",
15
+ "required": true,
16
+ "type": "slug"
17
+ },
18
+ {
19
+ "label": "Статус",
20
+ "name": "status",
21
+ "type": "select",
22
+ "data": "content.status",
23
+ "options": [
24
+ {
25
+ "id": "draft",
26
+ "text": "Чернетка"
27
+ },
28
+ {
29
+ "id": "published",
30
+ "text": "Опубліковано"
31
+ },
32
+ {
33
+ "id": "archived",
34
+ "text": "Архівовано"
35
+ },
36
+ {
37
+ "id": "delayPublished",
38
+ "text": "Відкладена публікація"
39
+ }
40
+ ],
41
+ "required": true
42
+ },
43
+ {
44
+ "label": "Дата публікації",
45
+ "name": "published_at",
46
+ "required": true,
47
+ "type": "datetime"
48
+ },
49
+ {
50
+ "label": "Контент",
51
+ "name": "single_body",
52
+ "type": "richtext",
53
+ "localization": true
54
+ },
55
+ {
56
+ "name": "single_sections",
57
+ "label": "Секції",
58
+ "type": "reference",
59
+ "localization": true
60
+ },
61
+ {
62
+ "label": "Зображення",
63
+ "name": "main_image",
64
+ "type": "mediaselect"
65
+ }
66
+ ],
67
+ "filters": [
68
+ {
69
+ "extra": false,
70
+ "id": "status",
71
+ "name": "status",
72
+ "title": "Статус",
73
+ "type": "Check",
74
+ "data": "content.status",
75
+ "ua": "Статус"
76
+ },
77
+ {
78
+ "extra": false,
79
+ "label": "Publish at",
80
+ "name": "published_at",
81
+ "type": "Date"
82
+ },
83
+ {
84
+ "extra": false,
85
+ "placeholder": "Пошук по тексту",
86
+ "label": "Пошук по тексту",
87
+ "columns": "slug,title",
88
+ "name": "search",
89
+ "type": "Text"
90
+ },
91
+ {
92
+ "extra": false,
93
+ "name": "tag_list",
94
+ "type": "Tags",
95
+ "sql": "id in (select b.data_id from site.tags a left join site.tag_data b on a.tag_id=b.tag_id where a.tag_id=any($1))",
96
+ "label": "Теги"
97
+ },
98
+ {
99
+ "extra": false,
100
+ "columns": "slug,title",
101
+ "id": "search",
102
+ "name": "search",
103
+ "placeholder": "Пошук по тексту",
104
+ "title": "Пошук по тексту",
105
+ "type": "Text"
106
+ },
107
+ {
108
+ "extra": false,
109
+ "id": "created_at",
110
+ "name": "created_at",
111
+ "title": "Дата створення",
112
+ "type": "Date",
113
+ "ua": "Дата створення"
114
+ }
115
+ ]
116
+ }
package/package.json CHANGED
@@ -1,71 +1,65 @@
1
- {
2
- "name": "@opengis/cms",
3
- "version": "0.0.42",
4
- "description": "cms",
5
- "type": "module",
6
- "author": "Softpro",
7
- "main": "./dist/index.js",
8
- "license": "EULA",
9
- "files": [
10
- "module",
11
- "dist",
12
- "server",
13
- "plugin.js"
14
- ],
15
- "scripts": {
16
- "patch": "npm version patch && git push && npm publish",
17
- "test": "node --test test/**/*.test.js",
18
- "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
19
- "dev": "NODE_ENV=dev bun --env-file=.env.softpro server ",
20
- "admin": "vite admin",
21
- "build": "vite build && vite build admin",
22
- "build:lib": "vite build",
23
- "proxy": "vite dev admin",
24
- "build-npm": "vite build",
25
- "start": "bun --env-file=.env.ip server",
26
- "prod-ip1": "node server --config=ip ",
27
- "prod-softpro1": "node server --config=softpro",
28
- "prod": "NODE_ENV=production bun --env-file=.env.ip server ",
29
- "prod-ip": "PORT=3019 node server --config=ip",
30
- "prod-ip-test": "PORT=3025 node server --config=ip",
31
- "debug": "bun --watch server --config=softpro",
32
- "ip-test": "node server --config=ip-test",
33
- "ip": "node --env-file=.env.ip server",
34
- "demo": "node --env-file=.env.demo --env-file=.env server",
35
- "i18n:sync": "node i18n-sync.cjs",
36
- "prepublishOnly": "bun build:lib",
37
- "softpro": "bun --env-file=.env.softpro server",
38
- "softpro1": "bun --env-file=.env.prod-softpro.local server"
39
- },
40
- "dependencies": {},
41
- "resolutions": {
42
- "rollup": "4.30.0"
43
- },
44
- "devDependencies": {
45
- "@fastify/compress": "^8.1.0",
46
- "@opengis/core": "^0.0.30",
47
- "@opengis/fastify-table": "^2.0.128",
48
- "@opengis/filter": "^0.1.10",
49
- "@opengis/form": "^0.0.70",
50
- "@opengis/richtext": "0.0.38",
51
- "@vueuse/head": "2.0.0",
52
- "js-yaml": "^4.1.0",
53
- "lucide-vue-next": "0.344.0",
54
- "vite": "5.1.4",
55
- "vue": "^3.5.17",
56
- "vue-i18n": "11.1.5",
57
- "vue-router": "4.4.3",
58
- "vuedraggable": "4.1.0",
59
- "@tailwindcss/typography": "0.5.10",
60
- "@tsconfig/node22": "^22.0.2",
61
- "@vitejs/plugin-vue": "5.0.4",
62
- "autoprefixer": "10.4.18",
63
- "eslint": "8.49.0",
64
- "postcss": "8.4.35",
65
- "sass": "^1.92.1",
66
- "tailwindcss": "3.4.1",
67
- "typescript": "~5.8.0",
68
- "vitest": "3.2.4",
69
- "vue-tsc": "^2.2.10"
70
- }
71
- }
1
+ {
2
+ "name": "@opengis/cms",
3
+ "version": "0.0.44",
4
+ "description": "cms",
5
+ "type": "module",
6
+ "author": "Softpro",
7
+ "main": "./dist/index.js",
8
+ "license": "EULA",
9
+ "files": [
10
+ "module",
11
+ "dist",
12
+ "server",
13
+ "plugin.js",
14
+ "input-types.json"
15
+ ],
16
+ "scripts": {
17
+ "patch": "npm version patch && git push && npm publish",
18
+ "test": "node --test test/**/*.test.js",
19
+ "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
20
+ "dev": "NODE_ENV=dev bun --env-file=.env.softpro server ",
21
+ "admin": "vite admin",
22
+ "build": "vite build && vite build admin",
23
+ "build:lib": "vite build",
24
+ "proxy": "vite dev admin",
25
+ "start": "bun --env-file=.env.ip server",
26
+ "prod": "NODE_ENV=production bun --env-file=.env.ip server ",
27
+ "ip": "bun --env-file=.env.ip server",
28
+ "demo": "node --env-file=.env.demo --env-file=.env server",
29
+ "i18n:sync": "node i18n-sync.cjs",
30
+ "prepublishOnly": "bun build:lib",
31
+ "softpro": "bun --env-file=.env.softpro server",
32
+ "softpro1": "NODE_ENV=production bun --env-file=.env.prod-softpro.local server"
33
+ },
34
+ "dependencies": {},
35
+ "resolutions": {
36
+ "rollup": "4.30.0"
37
+ },
38
+ "devDependencies": {
39
+ "@fastify/compress": "^8.1.0",
40
+ "@opengis/core": "^0.0.30",
41
+ "@opengis/fastify-table": "^2.0.128",
42
+ "@opengis/filter": "^0.1.31",
43
+ "@opengis/form": "^0.0.70",
44
+ "@opengis/richtext": "0.0.38",
45
+ "@vueuse/head": "2.0.0",
46
+ "js-yaml": "^4.1.0",
47
+ "lucide-vue-next": "0.344.0",
48
+ "vite": "5.1.4",
49
+ "vue": "^3.5.17",
50
+ "vue-i18n": "11.1.5",
51
+ "vue-router": "4.4.3",
52
+ "vuedraggable": "4.1.0",
53
+ "@tailwindcss/typography": "0.5.10",
54
+ "@tsconfig/node22": "^22.0.2",
55
+ "@vitejs/plugin-vue": "5.0.4",
56
+ "autoprefixer": "10.4.18",
57
+ "eslint": "8.49.0",
58
+ "postcss": "8.4.35",
59
+ "sass": "^1.92.1",
60
+ "tailwindcss": "3.4.1",
61
+ "typescript": "~5.8.0",
62
+ "vitest": "3.2.4",
63
+ "vue-tsc": "^2.2.10"
64
+ }
65
+ }
package/plugin.js CHANGED
@@ -1,76 +1,43 @@
1
- import path from 'node:path';
2
- import { fileURLToPath } from 'url';
3
- import { existsSync, readFileSync } from 'node:fs';
4
-
5
- import { config, execMigrations, getPGAsync } from '@opengis/fastify-table/utils.js';
6
- import { table } from 'node:console';
7
-
8
- const dirname = path.dirname(fileURLToPath(import.meta.url));
9
-
10
- // node server --config=softpro
11
- console.log(process.argv);
12
- if (process.argv.find(el => el.includes('--config'))) {
13
- const filename = process.argv.find(el => el.includes('--config')).split('=').pop();
14
- const cmsConfig = existsSync(`config/${filename}.json`)
15
- ? JSON.parse(readFileSync(`config/${filename}.json`, 'utf8'))
16
- : {};
17
-
18
- console.log('cms init', cmsConfig.pg?.database);
19
- Object.keys(cmsConfig).forEach(key => {
20
- config[key] = cmsConfig[key];
21
- });
22
- config.spacename = 'default' || cmsConfig.name || filename;
23
- } else {
24
- config.spacename = 'default' || config.spacename || process.env.NODE_ENV; // --env.file=.env.ip
25
- }
26
-
27
- const { prefix = '/api' } = config;
28
-
29
- export default async function (app) {
30
- app.register(import('./server/routes/menu/index.mjs'), { prefix });
31
- app.register(import('./server/routes/migration/index.mjs'), { prefix });
32
- app.register(import('./server/routes/cms/index.mjs'), { prefix });
33
- app.register(import('./server/routes/cmsSpace/index.mjs'), { prefix });
34
- app.register(import('./server/routes/contentType/index.mjs'), { prefix });
35
- app.register(import('./server/routes/category/index.mjs'), { prefix });
36
- app.register(import('./server/routes/tags/index.mjs'), { prefix });
37
- app.register(import('./server/routes/logs/index.mjs'), { prefix });
38
- app.register(import('./server/routes/feedback/index.mjs'), { prefix });
39
- const pg = await getPGAsync(config.pg);
40
- execMigrations(path.join(dirname, 'server/migrations'), pg).catch(err => console.log(err));
41
- if (pg?.pk?.['site.content_types']) {
42
- const customTables = await pg.query('select array_agg(table_name) from site.content_types where table_name is not null').catch(err => console.log(err)).then(el => el?.rows?.[0]?.array_agg || []);
43
-
44
- await Promise.all(customTables.filter(table => pg.pk?.[`data.${table}`])?.map(async (table) => {
45
- await pg.query(`alter table data.${table} add column if not exists meta json`).catch(err => console.log(err));
46
- await pg.query(`alter table data.${table} add column if not exists main_image text`).catch(err => console.log(err));
47
- await pg.query(`update site.content_types
48
- SET columns = columns::jsonb || jsonb_build_object('name', 'main_image', 'type', 'image', 'label', 'Зображення')
49
- WHERE not EXISTS (
50
- SELECT 1
51
- FROM jsonb_array_elements(columns::jsonb) AS obj(elem)
52
- JOIN LATERAL jsonb_each_text(elem) AS kv(key, value) ON true
53
- WHERE key = 'name' and value='main_image'
54
- )`);
55
- await pg.query(`alter table data.${table} add column if not exists published_at timestamp without time zone not null default now()`).catch(err => console.log(err));
56
- await pg.query(`alter table data.${table} add column if not exists is_pin boolean DEFAULT false`).catch(err => console.log(err));
57
- await pg.query(`alter table data.${table} drop column if exists publish_at`).catch(err => console.log(err));
58
- }));
59
-
60
-
61
-
62
- /*customTables.filter(table => pg.pk?.[`data.${table}`])?.forEach(table => pg.query(`alter table data.${table} add column if not exists meta json`).catch(err => console.log(err)));
63
- customTables.filter(table => pg.pk?.[`data.${table}`])?.forEach(table => pg.query(`alter table data.${table} add column if not exists published_at timestamp without time zone not null default now()`).catch(err => console.log(err)));
64
- customTables.filter(table => pg.pk?.[`data.${table}`])?.forEach(table => pg.query(`alter table data.${table} add column if not exists is_pin boolean DEFAULT false`).catch(err => console.log(err)));*/
65
-
66
-
67
- }
68
- /* if (pg?.pk?.['site.content_types'] && pg?.pk?.['site.contents']) {
69
- await pg.query('insert into site.contents(content_type_id, space_id, locale) select content_type_id, $1, $2 from site.content_types where content_type_id not in (select content_type_id from site.contents)', [config.spacename || 'default', config.locale || 'ua']).catch(err => {
70
- console.log(err.toString());
71
- });
72
- }
73
- if (pg?.pk?.['site.spaces']) {
74
- pg.query('insert into site.spaces(space_id, name) values($1, $1) on conflict(space_id) do nothing', [config.spacename || 'default']).catch(err => console.error('spaces insert error', err.toString())); // for content site.spaces
75
- } */
76
- }
1
+ import path from 'node:path';
2
+ import { fileURLToPath } from 'url';
3
+
4
+ import { config, execMigrations, getPGAsync, addTemplateDir } from '@opengis/fastify-table/utils.js';
5
+ // for cms as plugin only
6
+ addTemplateDir(path.join(process.cwd(), 'node_modules/@opengis/cms/module/cms'));
7
+
8
+ const dirname = path.dirname(fileURLToPath(import.meta.url));
9
+
10
+ const { prefix = '/api' } = config;
11
+
12
+ export default async function (app) {
13
+ app.register(import('./server/routes/menu/index.mjs'), { prefix });
14
+ app.register(import('./server/routes/migration/index.mjs'), { prefix });
15
+ app.register(import('./server/routes/cms/index.mjs'), { prefix });
16
+ app.register(import('./server/routes/cmsSpace/index.mjs'), { prefix });
17
+ app.register(import('./server/routes/contentType/index.mjs'), { prefix });
18
+ app.register(import('./server/routes/category/index.mjs'), { prefix });
19
+ app.register(import('./server/routes/tags/index.mjs'), { prefix });
20
+ app.register(import('./server/routes/logs/index.mjs'), { prefix });
21
+ app.register(import('./server/routes/feedback/index.mjs'), { prefix });
22
+ const pg = await getPGAsync(config.pg);
23
+ execMigrations(path.join(dirname, 'server/migrations'), pg).catch(err => console.log(err));
24
+ if (pg?.pk?.['site.content_types']) {
25
+ const customTables = await pg.query('select array_agg(table_name) from site.content_types where table_name is not null').catch(err => console.log(err)).then(el => el?.rows?.[0]?.array_agg || []);
26
+
27
+ await Promise.all(customTables.filter(table => pg.pk?.[`data.${table}`])?.map(async (table) => {
28
+ await pg.query(`alter table data.${table} add column if not exists meta json`).catch(err => console.log(err));
29
+ await pg.query(`alter table data.${table} add column if not exists main_image text`).catch(err => console.log(err));
30
+ await pg.query(`update site.content_types
31
+ SET columns = columns::jsonb || jsonb_build_object('name', 'main_image', 'type', 'image', 'label', 'Зображення')
32
+ WHERE not EXISTS (
33
+ SELECT 1
34
+ FROM jsonb_array_elements(columns::jsonb) AS obj(elem)
35
+ JOIN LATERAL jsonb_each_text(elem) AS kv(key, value) ON true
36
+ WHERE key = 'name' and value='main_image'
37
+ )`);
38
+ await pg.query(`alter table data.${table} add column if not exists published_at timestamp without time zone not null default now()`).catch(err => console.log(err));
39
+ await pg.query(`alter table data.${table} add column if not exists is_pin boolean DEFAULT false`).catch(err => console.log(err));
40
+ await pg.query(`alter table data.${table} drop column if exists publish_at`).catch(err => console.log(err));
41
+ }));
42
+ }
43
+ }
package/server/app.js CHANGED
@@ -1,35 +1,35 @@
1
- import { config, addHook } from '@opengis/fastify-table/utils.js';
2
-
3
- config.rateLimit = false;
4
- config.prefix = config.prefix || '/api';
5
- config.mode = config.mode || 'cms';
6
- // config.auth.oneUser = true;
7
- config.auth = config.auth || {};
8
- config.auth['2fa'] = config.auth['2fa'] || {};
9
- config.auth['2fa'].prefix = config.auth['2fa'].prefix || 'cms';
10
- config.auth['2fa'].sufix = config.auth['2fa'].sufix || 'login';
11
-
12
- // when frontend is implemented/used
13
- // config.auth.loginPage = true; // disable core loginPage api, use vue component instead
14
- // config.auth.link = config.auth.link || { '2fa': { login: '/2fa' } };
15
-
16
- export default async function (app) {
17
- // core
18
- app.register(import('@fastify/compress'), { encodings: ['br', 'gzip'], });
19
- app.register(import('./plugins/adminHook.js'));
20
- app.register(import('./plugins/hook.js'));
21
-
22
- app.register(import('@opengis/fastify-table'), config);
23
-
24
- app.register(import('./plugins/vite.js'));
25
- // API
26
- app.register(import('./routes/root.mjs'));
27
- app.register(import('../plugin.js'));
28
-
29
- addHook('errorMessage', (params) => {
30
- if (params?.constraint && params.constraint === 'content_data_content_id_fkey') {
31
- return 'Перед видаленням даного типу контенту, необхідно видалити всі дані, що до нього відносяться.';
32
- }
33
- return params?.message || 'Помилка API';
34
- });
35
- }
1
+ import { config, addHook } from '@opengis/fastify-table/utils.js';
2
+
3
+ config.rateLimit = false;
4
+ config.prefix = config.prefix || '/api';
5
+ config.mode = config.mode || 'cms';
6
+ // config.auth.oneUser = true;
7
+ config.auth = config.auth || {};
8
+ config.auth['2fa'] = config.auth['2fa'] || {};
9
+ config.auth['2fa'].prefix = config.auth['2fa'].prefix || 'cms';
10
+ config.auth['2fa'].sufix = config.auth['2fa'].sufix || 'login';
11
+
12
+ // when frontend is implemented/used
13
+ // config.auth.loginPage = true; // disable core loginPage api, use vue component instead
14
+ // config.auth.link = config.auth.link || { '2fa': { login: '/2fa' } };
15
+
16
+ export default function (app) {
17
+ // core
18
+ app.register(import('@fastify/compress'), { encodings: ['br', 'gzip'], });
19
+ app.register(import('./plugins/adminHook.js'));
20
+ app.register(import('./plugins/hook.js'));
21
+
22
+ app.register(import('@opengis/fastify-table'), config);
23
+
24
+ app.register(import('./plugins/vite.js'));
25
+ // API
26
+ app.register(import('./routes/root.mjs'));
27
+ app.register(import('../plugin.js'));
28
+
29
+ addHook('errorMessage', (params) => {
30
+ if (params?.constraint && params.constraint === 'content_data_content_id_fkey') {
31
+ return 'Перед видаленням даного типу контенту, необхідно видалити всі дані, що до нього відносяться.';
32
+ }
33
+ return params?.message || 'Помилка API';
34
+ });
35
+ }
package/server/config.js CHANGED
@@ -1,5 +1,5 @@
1
- import { readFile } from 'fs/promises';
2
- import fs from 'fs';
3
- const config = fs.existsSync('config.json') ? JSON.parse(await readFile('config.json')) : {};
4
-
1
+ import { readFile } from 'fs/promises';
2
+ import fs from 'fs';
3
+ const config = fs.existsSync('config.json') ? JSON.parse(await readFile('config.json')) : {};
4
+
5
5
  export default config;
@@ -1,22 +1,22 @@
1
- import { randomUUID } from "node:crypto";
2
-
3
- import { config, getRedis } from "@opengis/fastify-table/utils.js";
4
-
5
- const rclient = getRedis();
6
- const redisKey = [config.pg?.database, "draftKey"].filter(Boolean).join(":");
7
-
8
- // allow users to view content in draft status if passed as query param
9
- export default async function getDraftKey(nocache = false) {
10
- const cacheKey = await rclient.get(redisKey);
11
- const ttl = await rclient.ttl(redisKey) || 0;
12
-
13
- if (cacheKey && !nocache) {
14
- return { draftKey: cacheKey, ttl: (ttl / 60).toFixed(0) + " minutes" };
15
- }
16
-
17
- const draftKey = randomUUID().replace(/-/g, "").substring(0, 10);
18
-
19
- // refresh every hour
20
- await rclient.set(redisKey, draftKey, "EX", 60 * 60);
21
- return { draftKey };
22
- }
1
+ import { randomUUID } from "node:crypto";
2
+
3
+ import { config, getRedis } from "@opengis/fastify-table/utils.js";
4
+
5
+ const rclient = getRedis();
6
+ const redisKey = [config.pg?.database, "draftKey"].filter(Boolean).join(":");
7
+
8
+ // allow users to view content in draft status if passed as query param
9
+ export default async function getDraftKey(nocache = false) {
10
+ const cacheKey = await rclient.get(redisKey);
11
+ const ttl = await rclient.ttl(redisKey) || 0;
12
+
13
+ if (cacheKey && !nocache) {
14
+ return { draftKey: cacheKey, ttl: (ttl / 60).toFixed(0) + " minutes" };
15
+ }
16
+
17
+ const draftKey = randomUUID().replace(/-/g, "").substring(0, 10);
18
+
19
+ // refresh every hour
20
+ await rclient.set(redisKey, draftKey, "EX", 60 * 60);
21
+ return { draftKey };
22
+ }