@opengis/cms 0.0.60 → 0.0.61
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 +4 -4
- package/dist/{ArticlesPage-BjYzvTWM.js → ArticlesPage-CFjE_cw_.js} +3 -3
- package/dist/{CollectionsBreadcrumb-HePNJb-d.js → CollectionsBreadcrumb-BCxeRikP.js} +1 -1
- package/dist/CollectionsBreadcrumb.vue_vue_type_script_setup_true_lang-umRzB5mY.js +53 -0
- package/dist/{Dashboard-CXkg_pk8.js → Dashboard-C1eGscNd.js} +132 -132
- package/dist/{EditCollectionPage-BycuD920.js → EditCollectionPage-3Q57ptN3.js} +2 -2
- package/dist/{MenuAddPage-QTnwCoGh.js → MenuAddPage-D-p3gFgm.js} +1 -1
- package/dist/{MenuBody-Bi0ONVZf.js → MenuBody-rN5j4YBu.js} +2 -2
- package/dist/{MenuItemPage-B7Y9KFyb.js → MenuItemPage-BoJw885D.js} +3 -3
- package/dist/{MenuList-BLIpeqSd.js → MenuList-DFEBS0NB.js} +53 -53
- package/dist/{MenuPage-3W6jZ15H.js → MenuPage-BCZB_S8j.js} +1 -1
- package/dist/{MenuWrapper-OrOv6sOb.js → MenuWrapper-AZ_8s-zd.js} +1 -1
- package/dist/{MonacoEditor-ByPT8pnv.js → MonacoEditor-Db-3Jc3E.js} +1 -1
- package/dist/MonacoEditor.vue_vue_type_script_setup_true_lang-B1DrxmQX.js +84 -0
- package/dist/{UniversalTable-GBd_pStq.js → UniversalTable-CzqPG-tY.js} +80 -80
- package/dist/{UniversalTablePagination-Dw2hc0nc.js → UniversalTablePagination-4gL47A7I.js} +46 -46
- package/dist/{contentForm-yMn63kza.js → contentForm-CLStrfSg.js} +3 -6
- package/dist/index.js +5 -5
- package/dist/{vs-builder-monaco-Cw-f19gc.js → vs-builder-monaco-B3Jj0V31.js} +1 -1
- package/package.json +69 -69
- package/server/migrations/fixes.sql +5 -2
- package/server/migrations/site.sql +4 -3
- package/server/routes/cms/controllers/deleteContent.js +7 -7
- package/server/routes/cms/controllers/getContent.js +6 -6
- package/server/routes/cms/controllers/getContentBySlug.js +13 -13
- package/server/routes/cms/controllers/getPermissions.js +15 -15
- package/server/routes/cms/controllers/insertContent.js +28 -19
- package/server/routes/cms/controllers/setPermissions.js +49 -49
- package/server/routes/cms/controllers/updateContent.js +12 -47
- package/server/routes/cms/utils/getCollection.js +1 -1
- package/server/routes/cms/utils/getSingle.js +1 -1
- package/server/routes/cms/utils/requestTranslation.js +28 -6
- package/server/routes/cms/utils/updateLocalization.js +1 -6
- package/server/routes/cmsSpace/controllers/deleteSpace.js +1 -0
- package/server/routes/cmsSpace/controllers/getSpaces.js +1 -0
- package/server/routes/cmsSpace/controllers/insertSpace.js +1 -0
- package/server/routes/cmsSpace/controllers/updateSpace.js +1 -0
- package/server/routes/contentType/controllers/contentTypeList.js +4 -11
- package/server/routes/contentType/controllers/editContentType.js +7 -25
- package/server/routes/contentType/controllers/getContentType.js +5 -13
- package/server/templates/select/core.user_mentioned.sql +1 -1
- package/dist/CollectionsBreadcrumb.vue_vue_type_script_setup_true_lang-BJh-tjam.js +0 -53
- package/dist/MonacoEditor.vue_vue_type_script_setup_true_lang-C8cip9Ci.js +0 -84
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { defineComponent as f, mergeModels as
|
|
2
|
-
import { ChevronLeft as
|
|
3
|
-
const
|
|
1
|
+
import { defineComponent as f, mergeModels as p, useModel as w, computed as h, openBlock as d, createElementBlock as c, createElementVNode as e, toDisplayString as n, createTextVNode as u, createVNode as b, unref as g, Fragment as v, renderList as k, normalizeClass as y } from "vue";
|
|
2
|
+
import { ChevronLeft as $, ChevronRight as M } from "lucide-vue-next";
|
|
3
|
+
const C = { class: "flex items-center justify-between px-6 py-4 border-t border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800" }, _ = { class: "flex justify-between flex-1 sm:hidden" }, j = { class: "relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50" }, P = { class: "relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50" }, N = { class: "hidden sm:flex-1 sm:flex sm:items-center sm:justify-between" }, T = { class: "text-sm text-slate-600 dark:text-slate-400" }, V = { class: "font-medium text-slate-800 dark:text-slate-100" }, z = { class: "font-medium text-slate-800 dark:text-slate-100" }, B = {
|
|
4
4
|
class: "relative z-0 inline-flex space-x-2 rounded-md shadow-sm",
|
|
5
5
|
"aria-label": "Pagination"
|
|
6
6
|
}, E = ["disabled"], L = { class: "sr-only" }, S = { class: "space-x-1" }, D = {
|
|
@@ -8,7 +8,7 @@ const M = { class: "flex items-center justify-between px-6 py-4 border-t border-
|
|
|
8
8
|
class: "px-2 py-2 text-gray-400"
|
|
9
9
|
}, F = ["onClick"], R = ["disabled"], U = { class: "sr-only" }, G = /* @__PURE__ */ f({
|
|
10
10
|
__name: "UniversalTablePagination",
|
|
11
|
-
props: /* @__PURE__ */
|
|
11
|
+
props: /* @__PURE__ */ p({
|
|
12
12
|
total: {},
|
|
13
13
|
count: {},
|
|
14
14
|
limit: {}
|
|
@@ -17,66 +17,66 @@ const M = { class: "flex items-center justify-between px-6 py-4 border-t border-
|
|
|
17
17
|
pageModifiers: {}
|
|
18
18
|
}),
|
|
19
19
|
emits: ["update:page"],
|
|
20
|
-
setup(
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
if (
|
|
24
|
-
for (let
|
|
25
|
-
|
|
26
|
-
return
|
|
20
|
+
setup(a) {
|
|
21
|
+
const t = w(a, "page"), r = h(() => Math.ceil(a.total / a.limit)), x = h(() => {
|
|
22
|
+
const s = [];
|
|
23
|
+
if (r.value <= 4) {
|
|
24
|
+
for (let i = 1; i <= r.value; i++)
|
|
25
|
+
s.push(i);
|
|
26
|
+
return s;
|
|
27
27
|
}
|
|
28
|
-
const o = Math.max(2,
|
|
29
|
-
|
|
30
|
-
for (let
|
|
31
|
-
|
|
32
|
-
return m <
|
|
28
|
+
const o = Math.max(2, t.value - 2), m = Math.min(r.value - 1, t.value + 2);
|
|
29
|
+
s.push(1), o > 2 && s.push("ellipsis");
|
|
30
|
+
for (let i = o; i <= m; i++)
|
|
31
|
+
s.push(i);
|
|
32
|
+
return m < r.value - 1 && s.push("ellipsis"), s.push(r.value), s;
|
|
33
33
|
});
|
|
34
|
-
return (
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
return (l, s) => (d(), c("div", C, [
|
|
35
|
+
e("div", _, [
|
|
36
|
+
e("button", j, n(l.$t("cms.common.pagination.previous")), 1),
|
|
37
|
+
e("button", P, n(l.$t("cms.common.pagination.next")), 1)
|
|
38
38
|
]),
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
u(n(
|
|
43
|
-
|
|
44
|
-
u(" " + n(
|
|
45
|
-
|
|
46
|
-
u(" " + n(
|
|
39
|
+
e("div", N, [
|
|
40
|
+
e("div", null, [
|
|
41
|
+
e("p", T, [
|
|
42
|
+
u(n(l.$t("cms.common.pagination.showing")) + " ", 1),
|
|
43
|
+
e("span", V, n(a.count), 1),
|
|
44
|
+
u(" " + n(l.$t("cms.common.pagination.of")) + " ", 1),
|
|
45
|
+
e("span", z, n(a.total), 1),
|
|
46
|
+
u(" " + n(l.$t("cms.common.pagination.results")), 1)
|
|
47
47
|
])
|
|
48
48
|
]),
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
onClick:
|
|
53
|
-
disabled:
|
|
49
|
+
e("div", null, [
|
|
50
|
+
e("nav", B, [
|
|
51
|
+
e("button", {
|
|
52
|
+
onClick: s[0] || (s[0] = (o) => t.value = t.value > 1 ? t.value - 1 : 1),
|
|
53
|
+
disabled: t.value === 1,
|
|
54
54
|
class: "inline-flex items-center justify-center whitespace-nowrap font-medium transition-colors border shadow-sm rounded-md text-xs h-8 w-8 p-0 bg-white border-slate-300 text-slate-600 disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed hover:text-accent-foreground hover:bg-slate-50 dark:bg-slate-700 dark:border-slate-600 dark:text-slate-300 dark:hover:bg-slate-600"
|
|
55
55
|
}, [
|
|
56
|
-
|
|
57
|
-
b(
|
|
56
|
+
e("span", L, n(l.$t("cms.common.pagination.previous")), 1),
|
|
57
|
+
b(g($), { class: "w-5 h-5" })
|
|
58
58
|
], 8, E),
|
|
59
|
-
|
|
60
|
-
(
|
|
59
|
+
e("div", S, [
|
|
60
|
+
(d(!0), c(v, null, k(x.value, (o, m) => (d(), c(v, {
|
|
61
61
|
key: o + "-" + m
|
|
62
62
|
}, [
|
|
63
|
-
o === "ellipsis" ? (
|
|
63
|
+
o === "ellipsis" ? (d(), c("span", D, "...")) : (d(), c("button", {
|
|
64
64
|
key: 1,
|
|
65
|
-
onClick: (
|
|
65
|
+
onClick: (i) => t.value = o,
|
|
66
66
|
class: y(["inline-flex items-center justify-center whitespace-nowrap font-medium transition-colors h-8 w-8 p-0 text-sm rounded-md", {
|
|
67
|
-
"border shadow-sm hover:text-accent-foreground bg-white dark:bg-slate-700 border-slate-300 dark:border-slate-600 text-slate-600 dark:text-slate-300 hover:border-blue-600 hover:bg-slate-50 dark:hover:bg-slate-600": o !==
|
|
68
|
-
"shadow bg-blue-600 hover:bg-blue-700 text-white border-blue-600": o ===
|
|
67
|
+
"border shadow-sm hover:text-accent-foreground bg-white dark:bg-slate-700 border-slate-300 dark:border-slate-600 text-slate-600 dark:text-slate-300 hover:border-blue-600 hover:bg-slate-50 dark:hover:bg-slate-600": o !== t.value,
|
|
68
|
+
"shadow bg-blue-600 hover:bg-blue-700 text-white border-blue-600": o === t.value
|
|
69
69
|
}])
|
|
70
70
|
}, n(o), 11, F))
|
|
71
71
|
], 64))), 128))
|
|
72
72
|
]),
|
|
73
|
-
|
|
74
|
-
onClick:
|
|
75
|
-
disabled:
|
|
73
|
+
e("button", {
|
|
74
|
+
onClick: s[1] || (s[1] = (o) => t.value = t.value < Math.ceil(a.total / a.limit) ? t.value + 1 : Math.ceil(a.total / a.limit)),
|
|
75
|
+
disabled: t.value === Math.ceil(a.total / a.limit),
|
|
76
76
|
class: "inline-flex items-center justify-center whitespace-nowrap font-medium transition-colors border shadow-sm rounded-md text-xs h-8 w-8 p-0 bg-white border-slate-300 text-slate-600 disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed hover:text-accent-foreground hover:bg-slate-50 dark:bg-slate-700 dark:border-slate-600 dark:text-slate-300 dark:hover:bg-slate-600"
|
|
77
77
|
}, [
|
|
78
|
-
|
|
79
|
-
b(
|
|
78
|
+
e("span", U, n(l.$t("cms.common.pagination.next")), 1),
|
|
79
|
+
b(g(M), { class: "w-5 h-5" })
|
|
80
80
|
], 8, R)
|
|
81
81
|
])
|
|
82
82
|
])
|
|
@@ -66,7 +66,7 @@ const Xe = [
|
|
|
66
66
|
), be = h(
|
|
67
67
|
() => import("./VsPreview-DwETkOpb.js")
|
|
68
68
|
), he = h(
|
|
69
|
-
() => import("./CollectionsBreadcrumb-
|
|
69
|
+
() => import("./CollectionsBreadcrumb-BCxeRikP.js")
|
|
70
70
|
);
|
|
71
71
|
x["vs-input-custom-datatable"] = fe, x["vs-input-reference"] = de, x["vs-input-texteditor"] = me, x["vs-input-mediaselect"] = E, x["vs-input-file"] = E, x["vs-input-image"] = E, x["vs-input-richtext-md"] = pe, x["vs-input-integer"] = ve, x["vs-input-relation-link"] = ye;
|
|
72
72
|
const { t: r, locale: G } = Qe(), V = Ue(), d = Oe(), Q = le("cms.menu", null) || le("menu", p([])), _ = p([]), D = p({}), W = p({}), I = p({}), N = p(""), M = p(!0), R = Be(), U = R == null ? void 0 : R.appContext, we = (U == null ? void 0 : U.config.globalProperties) || {}, X = Ee(we, "$settings"), B = m(() => {
|
|
@@ -130,10 +130,7 @@ const Xe = [
|
|
|
130
130
|
title: "",
|
|
131
131
|
status: "draft"
|
|
132
132
|
}), J = p(null), L = p(""), F = m(
|
|
133
|
-
() =>
|
|
134
|
-
var e;
|
|
135
|
-
return (((e = i.value) == null ? void 0 : e.type) || J.value) === "single";
|
|
136
|
-
}
|
|
133
|
+
() => J.value === "single"
|
|
137
134
|
), Te = m(() => {
|
|
138
135
|
const e = [
|
|
139
136
|
{ id: "content", name: r("cms.builder.content") },
|
|
@@ -163,7 +160,7 @@ const Xe = [
|
|
|
163
160
|
var s, c, l;
|
|
164
161
|
const e = ((s = d.params) == null ? void 0 : s.collection) || ((c = d.params) == null ? void 0 : c.id), t = (l = d.params) == null ? void 0 : l.id, o = Se.value, a = o === ee.value, n = [
|
|
165
162
|
{
|
|
166
|
-
label: F ? r("cms.navigation.singletons") : ee.value,
|
|
163
|
+
label: F.value ? r("cms.navigation.singletons") : ee.value,
|
|
167
164
|
route: `collections/${e}`
|
|
168
165
|
}
|
|
169
166
|
];
|
package/dist/index.js
CHANGED
|
@@ -3,12 +3,12 @@ import { useRoute as $, routeLocationKey as K } from "vue-router";
|
|
|
3
3
|
const O = "menu", B = (s, c, a) => {
|
|
4
4
|
const o = s == null ? void 0 : s.trim(), l = a == null ? void 0 : a.trim();
|
|
5
5
|
return o ? o === O ? c ? c === "create" ? { type: "createMenu", collection: o } : { type: "editMenu", collection: o, id: c } : { type: "menu", collection: o } : l === "edit" && c ? { type: "editCollection", collection: o, id: c } : c === "edit" ? { type: "editCollection", collection: o } : c ? c === "create" ? { type: "createArticle", collection: o } : { type: "editArticle", collection: o, id: c } : { type: "articles", collection: o } : { type: "collections" };
|
|
6
|
-
}, R = u(() => import("./CollectionsPage-DHfPNql6.js")), L = u(() => import("./ArticlesPage-
|
|
7
|
-
() => import("./MenuPage-
|
|
6
|
+
}, R = u(() => import("./CollectionsPage-DHfPNql6.js")), L = u(() => import("./ArticlesPage-CFjE_cw_.js")), C = u(() => import("./contentForm-CLStrfSg.js")), N = u(() => import("./EditCollectionPage-3Q57ptN3.js")), W = u(
|
|
7
|
+
() => import("./MenuPage-BCZB_S8j.js")
|
|
8
8
|
), j = u(
|
|
9
|
-
() => import("./MenuItemPage-
|
|
9
|
+
() => import("./MenuItemPage-BoJw885D.js")
|
|
10
10
|
), F = u(
|
|
11
|
-
() => import("./MenuAddPage-
|
|
11
|
+
() => import("./MenuAddPage-D-p3gFgm.js")
|
|
12
12
|
), S = {
|
|
13
13
|
collections: R,
|
|
14
14
|
articles: L,
|
|
@@ -96,7 +96,7 @@ const O = "menu", B = (s, c, a) => {
|
|
|
96
96
|
});
|
|
97
97
|
return M(K, b), (e, n) => v.value ? (g(), k(x(v.value), { key: w.value })) : (g(), E("div", V, D(e.$t("cms.navigation.collections")), 1));
|
|
98
98
|
}
|
|
99
|
-
}), H = u(() => import("./Dashboard-
|
|
99
|
+
}), H = u(() => import("./Dashboard-C1eGscNd.js")), J = u(() => import("./MenuWrapper-AZ_8s-zd.js")), Q = q;
|
|
100
100
|
export {
|
|
101
101
|
Q as Content,
|
|
102
102
|
H as Dashboard,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ref as l, useModel as m, onMounted as u, openBlock as r, createElementBlock as d, createVNode as i, createCommentVNode as s } from "vue";
|
|
2
|
-
import { _ as c } from "./MonacoEditor.vue_vue_type_script_setup_true_lang-
|
|
2
|
+
import { _ as c } from "./MonacoEditor.vue_vue_type_script_setup_true_lang-B1DrxmQX.js";
|
|
3
3
|
const g = {
|
|
4
4
|
__name: "vs-builder-monaco",
|
|
5
5
|
props: {
|
package/package.json
CHANGED
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@opengis/cms",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "cms",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"author": "Softpro",
|
|
7
|
-
"main": "./dist/index.js",
|
|
8
|
-
"types": "./dist/index.d.ts",
|
|
9
|
-
"license": "EULA",
|
|
10
|
-
"files": [
|
|
11
|
-
"module",
|
|
12
|
-
"locales",
|
|
13
|
-
"dist",
|
|
14
|
-
"server",
|
|
15
|
-
"plugin.js",
|
|
16
|
-
"utils.js",
|
|
17
|
-
"utils.d.ts",
|
|
18
|
-
"input-types.json"
|
|
19
|
-
],
|
|
20
|
-
"scripts": {
|
|
21
|
-
"patch": "npm version patch && git push && npm publish",
|
|
22
|
-
"test": "node --test test/**/*.test.js",
|
|
23
|
-
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
|
|
24
|
-
"dev": "NODE_ENV=dev bun --env-file=.env.ip server ",
|
|
25
|
-
"admin": "vite admin",
|
|
26
|
-
"build": "vite build admin",
|
|
27
|
-
"build:lib": "vue-tsc -p tsconfig.build.json --noEmit && vite build && npm run build:types",
|
|
28
|
-
"build:types": "vue-tsc -p tsconfig.types.json",
|
|
29
|
-
"proxy": "vite dev admin",
|
|
30
|
-
"start": "bun --env-file=.env.ip server",
|
|
31
|
-
"prod": "NODE_ENV=production bun --env-file=.env.ip server ",
|
|
32
|
-
"ip": "bun --env-file=.env.ip server",
|
|
33
|
-
"lemken": "bun --env-file=.env.local-lemken 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": "NODE_ENV=production bun --env-file=.env.prod-softpro.local server"
|
|
39
|
-
},
|
|
40
|
-
"resolutions": {
|
|
41
|
-
"rollup": "4.30.0"
|
|
42
|
-
},
|
|
43
|
-
"devDependencies": {
|
|
44
|
-
"@fastify/compress": "^8.1.0",
|
|
45
|
-
"@opengis/core": "^0.0.30",
|
|
46
|
-
"@opengis/fastify-table": "^2.0.147",
|
|
47
|
-
"@opengis/filter": "^0.1.31",
|
|
48
|
-
"@opengis/form": "^0.0.121",
|
|
49
|
-
"@tailwindcss/typography": "0.5.10",
|
|
50
|
-
"@tsconfig/node22": "^22.0.2",
|
|
51
|
-
"@vitejs/plugin-vue": "5.0.4",
|
|
52
|
-
"@vueuse/head": "2.0.0",
|
|
53
|
-
"autoprefixer": "10.4.18",
|
|
54
|
-
"eslint": "8.49.0",
|
|
55
|
-
"js-yaml": "^4.1.0",
|
|
56
|
-
"lucide-vue-next": "^0.564.0",
|
|
57
|
-
"postcss": "8.4.35",
|
|
58
|
-
"sass": "^1.92.1",
|
|
59
|
-
"tailwindcss": "3.4.1",
|
|
60
|
-
"typescript": "~5.8.0",
|
|
61
|
-
"vite": "5.1.4",
|
|
62
|
-
"vitest": "3.2.4",
|
|
63
|
-
"vue": "^3.5.17",
|
|
64
|
-
"vue-i18n": "11.1.5",
|
|
65
|
-
"vue-router": "4.4.3",
|
|
66
|
-
"vue-tsc": "^2.2.10",
|
|
67
|
-
"vuedraggable": "4.1.0"
|
|
68
|
-
}
|
|
69
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@opengis/cms",
|
|
3
|
+
"version": "0.0.61",
|
|
4
|
+
"description": "cms",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"author": "Softpro",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"license": "EULA",
|
|
10
|
+
"files": [
|
|
11
|
+
"module",
|
|
12
|
+
"locales",
|
|
13
|
+
"dist",
|
|
14
|
+
"server",
|
|
15
|
+
"plugin.js",
|
|
16
|
+
"utils.js",
|
|
17
|
+
"utils.d.ts",
|
|
18
|
+
"input-types.json"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"patch": "npm version patch && git push && npm publish",
|
|
22
|
+
"test": "node --test test/**/*.test.js",
|
|
23
|
+
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
|
|
24
|
+
"dev": "NODE_ENV=dev bun --env-file=.env.ip server ",
|
|
25
|
+
"admin": "vite admin",
|
|
26
|
+
"build": "vite build admin",
|
|
27
|
+
"build:lib": "vue-tsc -p tsconfig.build.json --noEmit && vite build && npm run build:types",
|
|
28
|
+
"build:types": "vue-tsc -p tsconfig.types.json",
|
|
29
|
+
"proxy": "vite dev admin",
|
|
30
|
+
"start": "bun --env-file=.env.ip server",
|
|
31
|
+
"prod": "NODE_ENV=production bun --env-file=.env.ip server ",
|
|
32
|
+
"ip": "bun --env-file=.env.ip server",
|
|
33
|
+
"lemken": "bun --env-file=.env.local-lemken 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": "NODE_ENV=production bun --env-file=.env.prod-softpro.local server"
|
|
39
|
+
},
|
|
40
|
+
"resolutions": {
|
|
41
|
+
"rollup": "4.30.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@fastify/compress": "^8.1.0",
|
|
45
|
+
"@opengis/core": "^0.0.30",
|
|
46
|
+
"@opengis/fastify-table": "^2.0.147",
|
|
47
|
+
"@opengis/filter": "^0.1.31",
|
|
48
|
+
"@opengis/form": "^0.0.121",
|
|
49
|
+
"@tailwindcss/typography": "0.5.10",
|
|
50
|
+
"@tsconfig/node22": "^22.0.2",
|
|
51
|
+
"@vitejs/plugin-vue": "5.0.4",
|
|
52
|
+
"@vueuse/head": "2.0.0",
|
|
53
|
+
"autoprefixer": "10.4.18",
|
|
54
|
+
"eslint": "8.49.0",
|
|
55
|
+
"js-yaml": "^4.1.0",
|
|
56
|
+
"lucide-vue-next": "^0.564.0",
|
|
57
|
+
"postcss": "8.4.35",
|
|
58
|
+
"sass": "^1.92.1",
|
|
59
|
+
"tailwindcss": "3.4.1",
|
|
60
|
+
"typescript": "~5.8.0",
|
|
61
|
+
"vite": "5.1.4",
|
|
62
|
+
"vitest": "3.2.4",
|
|
63
|
+
"vue": "^3.5.17",
|
|
64
|
+
"vue-i18n": "11.1.5",
|
|
65
|
+
"vue-router": "4.4.3",
|
|
66
|
+
"vue-tsc": "^2.2.10",
|
|
67
|
+
"vuedraggable": "4.1.0"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
create schema if not exists site;
|
|
2
2
|
|
|
3
|
-
ALTER TABLE if exists site.spaces add column if not exists locales text[];
|
|
3
|
+
/*ALTER TABLE if exists site.spaces add column if not exists locales text[];
|
|
4
4
|
ALTER TABLE IF exists site.spaces add column if not exists default_locale text;
|
|
5
5
|
ALTER TABLE if exists site.spaces alter column default_locale set default 'ua';
|
|
6
6
|
update site.spaces set default_locale = 'ua' where default_locale is null;
|
|
7
|
-
ALTER TABLE if exists site.spaces alter column default_locale set not null
|
|
7
|
+
ALTER TABLE if exists site.spaces alter column default_locale set not null;*/
|
|
8
|
+
-- uncomment after a while or leave old data as is
|
|
9
|
+
/* --- alter table site.contents drop column if exists space_id;
|
|
10
|
+
drop table if exists site.spaces cascade; */
|
|
8
11
|
|
|
9
12
|
ALTER TABLE if exists site.media ADD COLUMN IF NOT EXISTS subdir TEXT;
|
|
10
13
|
COMMENT ON COLUMN site.media.subdir is 'Піддиректорія';
|
|
@@ -271,7 +271,7 @@ COMMENT ON COLUMN site.tokens.token_type IS 'Type of token, such as CMA or PAT.'
|
|
|
271
271
|
COMMENT ON COLUMN site.tokens.token_status IS 'Current status of the token (e.g., Active).';
|
|
272
272
|
COMMENT ON COLUMN site.tokens.space_id IS 'Identifier for the associated space.';
|
|
273
273
|
|
|
274
|
-
CREATE TABLE if not exists site.spaces (
|
|
274
|
+
/*CREATE TABLE if not exists site.spaces (
|
|
275
275
|
space_id text PRIMARY KEY default next_id(), -- Unique identifier for the space
|
|
276
276
|
name TEXT NOT NULL, -- Human-readable name of the space
|
|
277
277
|
created_at TIMESTAMP NOT NULL default now(), -- When the space was created
|
|
@@ -296,6 +296,7 @@ COMMENT ON COLUMN site.spaces.default_locale IS 'Default language/locale of the
|
|
|
296
296
|
COMMENT ON COLUMN site.spaces.plan IS 'Plan type (e.g., "Free", "Premium")';
|
|
297
297
|
|
|
298
298
|
alter table site.spaces alter column default_locale set default 'uk';
|
|
299
|
+
*/
|
|
299
300
|
|
|
300
301
|
CREATE TABLE if not exists site.organizations (
|
|
301
302
|
organization_id TEXT PRIMARY KEY DEFAULT next_id(), -- Unique identifier for the organization
|
|
@@ -348,7 +349,7 @@ COMMENT ON COLUMN site.comments.thread_id IS 'ID of the top-level thread this co
|
|
|
348
349
|
|
|
349
350
|
CREATE TABLE if not exists site.contents (
|
|
350
351
|
content_id text PRIMARY KEY default next_id(),
|
|
351
|
-
space_id text,
|
|
352
|
+
-- space_id text,
|
|
352
353
|
content_type_id text NOT NULL,
|
|
353
354
|
created_at TIMESTAMP NOT NULL DEFAULT now(),
|
|
354
355
|
updated_at TIMESTAMP NOT NULL DEFAULT now(),
|
|
@@ -363,7 +364,7 @@ CREATE TABLE if not exists site.contents (
|
|
|
363
364
|
updated_by text,
|
|
364
365
|
meta json,
|
|
365
366
|
main_image text,
|
|
366
|
-
FOREIGN KEY (space_id) REFERENCES site.spaces(space_id),
|
|
367
|
+
-- FOREIGN KEY (space_id) REFERENCES site.spaces(space_id),
|
|
367
368
|
FOREIGN KEY (content_type_id) REFERENCES site.content_types(content_type_id),
|
|
368
369
|
FOREIGN KEY (created_by) REFERENCES admin.users(uid),
|
|
369
370
|
FOREIGN KEY (published_by) REFERENCES admin.users(uid),
|
|
@@ -11,15 +11,15 @@ export default async function deleteContent(req, reply) {
|
|
|
11
11
|
const { type, id } = params;
|
|
12
12
|
|
|
13
13
|
if (!type) {
|
|
14
|
-
return reply.status(400).send('not enough params: type');
|
|
14
|
+
return reply.status(400).send({ error: 'not enough params: type', code: 400 });
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
if (!id) {
|
|
18
|
-
return reply.status(400).send('not enough params: id');
|
|
18
|
+
return reply.status(400).send({ error: 'not enough params: id', code: 400 });
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
if (id === 'pages') {
|
|
22
|
-
return reply.status(403).send('access restricted: pages contents cannot be deleted');
|
|
22
|
+
return reply.status(403).send({ error: 'access restricted: pages contents cannot be deleted', code: 403 });
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
const { ctid, dbtable } = await pg.query('select content_type_id as ctid, table_name as dbtable from site.content_types where $1 in (content_type_id, name)', [params.type])
|
|
@@ -30,7 +30,7 @@ export default async function deleteContent(req, reply) {
|
|
|
30
30
|
where a.relam=2 and b.nspname='data'`).then(el => el.rows?.[0]?.array_agg || []) : [];
|
|
31
31
|
|
|
32
32
|
if (!arr.length && type !== 'pages') {
|
|
33
|
-
return reply.status(400).send('empty schema: data');
|
|
33
|
+
return reply.status(400).send({ error: 'empty schema: data', code: 400 });
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
const table = arr.find(el => el === params.type);
|
|
@@ -47,11 +47,11 @@ export default async function deleteContent(req, reply) {
|
|
|
47
47
|
).then(el => el.rows?.[0] || {});
|
|
48
48
|
|
|
49
49
|
if (!cid) {
|
|
50
|
-
return reply.status(404).send('contents not found');
|
|
50
|
+
return reply.status(404).send({ error: 'contents not found', code: 404 });
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
if (cid === 'pages') {
|
|
54
|
-
return reply.status(403).send('access restricted: pages contents cannot be deleted');
|
|
54
|
+
return reply.status(403).send({ error: 'access restricted: pages contents cannot be deleted', code: 403 });
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
if (status === 'archived') {
|
|
@@ -81,7 +81,7 @@ export default async function deleteContent(req, reply) {
|
|
|
81
81
|
|
|
82
82
|
// custom table
|
|
83
83
|
if (!table && !dbtable) {
|
|
84
|
-
return reply.status(400).send('invalid params: type');
|
|
84
|
+
return reply.status(400).send({ error: 'invalid params: type', code: 400 });
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
const status = await pg.query(`select status from data."${(table || dbtable)}" where id =$1`, [id]).then(el => el.rows?.[0]?.status);
|
|
@@ -57,11 +57,11 @@ export default async function getContent(req, reply, opt) {
|
|
|
57
57
|
).then(el => el.rows?.[0]?.isvalid);
|
|
58
58
|
|
|
59
59
|
if (!config.local && !isValidToken && config.mode !== 'cms' && !called) {
|
|
60
|
-
return reply.status(403).send('access restricted: token');
|
|
60
|
+
return reply.status(403).send({ error: 'access restricted: token', code: 403 });
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
if (!type) {
|
|
64
|
-
return reply.status(400).send('not enough params: type');
|
|
64
|
+
return reply.status(400).send({ error: 'not enough params: type', code: 400 });
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
const { contentId, contentTypeId, meta } = params.type === 'pages'
|
|
@@ -69,7 +69,7 @@ export default async function getContent(req, reply, opt) {
|
|
|
69
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] || {});
|
|
70
70
|
|
|
71
71
|
if (!contentId) {
|
|
72
|
-
return reply.status(404).send('content not found');
|
|
72
|
+
return reply.status(404).send({ error: 'content not found', code: 404 });
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
const { table, contentType, preview, columns: columns1 } = await pg.query(
|
|
@@ -78,7 +78,7 @@ export default async function getContent(req, reply, opt) {
|
|
|
78
78
|
).then(el => el.rows?.[0] || {});
|
|
79
79
|
|
|
80
80
|
if (!contentType && params.type !== 'pages') {
|
|
81
|
-
return reply.status(404).send('content type not found');
|
|
81
|
+
return reply.status(404).send({ error: 'content type not found', code: 404 });
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
const loadTable = contentType === 'collection' && table
|
|
@@ -86,7 +86,7 @@ export default async function getContent(req, reply, opt) {
|
|
|
86
86
|
: await getTemplate('table', 'single.default.table');
|
|
87
87
|
const { columns: defaultColumns = [], filters: defaultFilters = [] } = loadTable || {};
|
|
88
88
|
|
|
89
|
-
defaultColumns.forEach(col => Object.assign(col, {
|
|
89
|
+
defaultColumns.forEach(col => Object.assign(col, { defaultColumn: true }));
|
|
90
90
|
|
|
91
91
|
const columns = (columns1 || []).filter(col => !defaultColumns.map(el => el.name).includes(col.name));
|
|
92
92
|
|
|
@@ -105,7 +105,7 @@ export default async function getContent(req, reply, opt) {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
if (result?.message) {
|
|
108
|
-
return reply.status(result.status || 500).send(result.message);
|
|
108
|
+
return reply.status(result.status || 500).send({ error: result.message, code: result.status || 500 });
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
Object.assign(result, { meta });
|
|
@@ -4,11 +4,11 @@ import inputTypes from '../utils/inputTypes.js';
|
|
|
4
4
|
|
|
5
5
|
export default async function getContentBySlug({ pg = pgClients.client, params = {}, headers = {} }, reply) {
|
|
6
6
|
if (!params.slug) {
|
|
7
|
-
return reply.status(400).send('not enough params: slug');
|
|
7
|
+
return reply.status(400).send({ error: 'not enough params: slug', code: 400 });
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
if (!pg?.pk?.['site.content_types']) {
|
|
11
|
-
return reply.status(404).send('table not found');
|
|
11
|
+
return reply.status(404).send({ error: 'table not found', code: 404 });
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
// headers.authorization = 'Bearer tokenExample'
|
|
@@ -18,18 +18,18 @@ export default async function getContentBySlug({ pg = pgClients.client, params =
|
|
|
18
18
|
).then(el => el.rows?.[0]?.isvalid);
|
|
19
19
|
|
|
20
20
|
if (!config.local && !isValidToken && config.mode !== 'cms') {
|
|
21
|
-
return reply.status(403).send('access restricted: token');
|
|
21
|
+
return reply.status(403).send({ error: 'access restricted: token', code: 403 });
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
const
|
|
25
|
-
`select content_id
|
|
24
|
+
const cid = await pg.query(
|
|
25
|
+
`select content_id from site.contents where $1 in (content_id,slug) limit 1`,
|
|
26
26
|
[params.slug],
|
|
27
|
-
).then(el => el.rows?.[0]
|
|
27
|
+
).then(el => el.rows?.[0]?.content_id);
|
|
28
28
|
|
|
29
29
|
if (cid) {
|
|
30
|
-
const
|
|
30
|
+
const data = await pg.query(
|
|
31
31
|
`select field_key, field_type, field_value, field_value_object, content_id from site.content_data where content_id=$1`, [cid]
|
|
32
|
-
);
|
|
32
|
+
).then(el => el.rows || []);
|
|
33
33
|
|
|
34
34
|
const meta = await pg.query(
|
|
35
35
|
'select title, status, revision, locale, slug, content_type_id, (select columns from site.content_types where content_type_id=a.content_type_id limit 1) as columns from site.contents a where content_id=$1 limit 1',
|
|
@@ -63,7 +63,7 @@ export default async function getContentBySlug({ pg = pgClients.client, params =
|
|
|
63
63
|
const { rows: contentTypes = [] } = await pg.query(`select content_type_id as ctid, table_name as table, type from site.content_types where table_name is not null and type='collection' `);
|
|
64
64
|
|
|
65
65
|
if (!contentTypes.length || contentTypes.find(row => row.table && pg.pk[row.table])) {
|
|
66
|
-
return reply.status(404).send('content not found');
|
|
66
|
+
return reply.status(404).send({ error: 'content not found', code: 404 });
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
const tlist = await pg.query(`select array_agg((select nspname from pg_namespace where oid=relnamespace)||'.'||relname) tlist
|
|
@@ -74,20 +74,20 @@ export default async function getContentBySlug({ pg = pgClients.client, params =
|
|
|
74
74
|
const { dataid, ctid } = await pg.query(q).then(el => el.rows?.[0] || {});
|
|
75
75
|
|
|
76
76
|
if (!dataid) {
|
|
77
|
-
return reply.status(404).send('content not found: 2');
|
|
77
|
+
return reply.status(404).send({ error: 'content not found: 2', code: 404 });
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
if (!ctid) {
|
|
81
|
-
return reply.status(404).send('content not found: 3');
|
|
81
|
+
return reply.status(404).send({ error: 'content not found: 3', code: 404 });
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
const meta = await pg.query('select content_type_id, type, table_name as table, title, status, name as slug, columns from site.content_types where content_type_id=$1', [ctid]).then(el => el.rows?.[0] || {});
|
|
85
85
|
|
|
86
86
|
if (!meta?.table) {
|
|
87
|
-
return reply.status(404).send('content not found: 4');
|
|
87
|
+
return reply.status(404).send({ error: 'content not found: 4', code: 404 });
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
const
|
|
90
|
+
const rows = await pg.query(`select * from data.${meta.table} where id=$1`, [dataid]).then(el => el.rows || []);
|
|
91
91
|
|
|
92
92
|
return reply.status(200).send({ ...meta, custom: true, rows });
|
|
93
93
|
}
|
|
@@ -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
|
}
|