@ditojs/server 2.100.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +14 -15
- package/src/controllers/AdminController.js +2 -14
- package/src/models/Model.js +43 -7
- package/types/index.d.ts +187 -93
- package/src/models/Model.test.js +0 -180
- package/src/schema/relations.test.js +0 -177
- package/src/schema/schema.test.js +0 -720
- package/src/storage/Storage.test.js +0 -58
- package/src/utils/function.test.js +0 -77
- package/src/utils/object.test.js +0 -86
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ditojs/server",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Dito.js Server – Dito.js is a declarative and modern web framework, based on Objection.js, Koa.js and Vue.js",
|
|
6
6
|
"repository": "https://github.com/ditojs/dito/tree/main/packages/server",
|
|
@@ -10,11 +10,10 @@
|
|
|
10
10
|
"types": "./types/index.d.ts",
|
|
11
11
|
"files": [
|
|
12
12
|
"src/",
|
|
13
|
-
"types/"
|
|
13
|
+
"types/",
|
|
14
|
+
"!src/**/*.test.js",
|
|
15
|
+
"!src/**/__snapshots__/"
|
|
14
16
|
],
|
|
15
|
-
"scripts": {
|
|
16
|
-
"types": "tsc --noEmit --esModuleInterop ./types/index.d.ts"
|
|
17
|
-
},
|
|
18
17
|
"bin": {
|
|
19
18
|
"dito": "./src/cli/index.js"
|
|
20
19
|
},
|
|
@@ -25,14 +24,13 @@
|
|
|
25
24
|
"node >= 18"
|
|
26
25
|
],
|
|
27
26
|
"dependencies": {
|
|
28
|
-
"@ditojs/admin": "^
|
|
29
|
-
"@ditojs/build": "^
|
|
30
|
-
"@ditojs/router": "^
|
|
31
|
-
"@ditojs/utils": "^
|
|
27
|
+
"@ditojs/admin": "^3.1.0",
|
|
28
|
+
"@ditojs/build": "^3.1.0",
|
|
29
|
+
"@ditojs/router": "^3.1.0",
|
|
30
|
+
"@ditojs/utils": "^3.1.0",
|
|
32
31
|
"@koa/cors": "^5.0.0",
|
|
33
32
|
"@koa/etag": "^5.0.2",
|
|
34
33
|
"@koa/multer": "^4.0.0",
|
|
35
|
-
"@originjs/vite-plugin-commonjs": "^1.0.3",
|
|
36
34
|
"ajv": "^8.20.0",
|
|
37
35
|
"ajv-formats": "^3.0.1",
|
|
38
36
|
"bcryptjs": "^3.0.3",
|
|
@@ -62,7 +60,7 @@
|
|
|
62
60
|
"passthrough-counter": "^1.0.0",
|
|
63
61
|
"picocolors": "^1.1.1",
|
|
64
62
|
"picomatch": "^4.0.7",
|
|
65
|
-
"pino": "^10.
|
|
63
|
+
"pino": "^10.4.0",
|
|
66
64
|
"pino-pretty": "^13.1.3",
|
|
67
65
|
"pluralize": "^8.0.0",
|
|
68
66
|
"repl": "^0.1.3",
|
|
@@ -76,19 +74,20 @@
|
|
|
76
74
|
"objection": "^3.0.1"
|
|
77
75
|
},
|
|
78
76
|
"devDependencies": {
|
|
79
|
-
"@aws-sdk/client-s3": "^3.
|
|
80
|
-
"@aws-sdk/lib-storage": "^3.
|
|
77
|
+
"@aws-sdk/client-s3": "^3.1146.0",
|
|
78
|
+
"@aws-sdk/lib-storage": "^3.1146.0",
|
|
81
79
|
"@types/koa-bodyparser": "^4.3.13",
|
|
82
80
|
"@types/koa-compress": "^4.0.7",
|
|
81
|
+
"@types/koa-mount": "^4.0.5",
|
|
83
82
|
"@types/koa-response-time": "^2.1.5",
|
|
84
|
-
"@types/koa-session": "^6.4.5",
|
|
85
83
|
"@types/koa-static": "^4.0.4",
|
|
86
84
|
"@types/koa__cors": "^5.0.1",
|
|
87
85
|
"@types/koa__multer": "^2.0.8",
|
|
86
|
+
"@types/multer-s3": "^3.0.3",
|
|
88
87
|
"@types/node": "^26.6.4",
|
|
89
88
|
"knex": "^3.3.0",
|
|
90
89
|
"objection": "^3.1.5",
|
|
91
90
|
"typescript": "^6.0.3"
|
|
92
91
|
},
|
|
93
|
-
"gitHead": "
|
|
92
|
+
"gitHead": "97314265c5cbac6a248d7350f43fea8ea92b995f"
|
|
94
93
|
}
|
|
@@ -3,7 +3,6 @@ import Koa from 'koa'
|
|
|
3
3
|
import serve from 'koa-static'
|
|
4
4
|
import { defineConfig, createServer } from 'vite'
|
|
5
5
|
import createVuePlugin from '@vitejs/plugin-vue'
|
|
6
|
-
import { viteCommonjs as createCommonJsPlugin } from '@originjs/vite-plugin-commonjs'
|
|
7
6
|
import { testModuleIdentifier, getPostCssConfig } from '@ditojs/build'
|
|
8
7
|
import { assignDeeply } from '@ditojs/utils'
|
|
9
8
|
import { Controller } from './Controller.js'
|
|
@@ -178,7 +177,6 @@ export class AdminController extends Controller {
|
|
|
178
177
|
configFile: false,
|
|
179
178
|
plugins: [
|
|
180
179
|
createVuePlugin(),
|
|
181
|
-
createCommonJsPlugin(),
|
|
182
180
|
{
|
|
183
181
|
// Private plugin to inject script tag above main module that
|
|
184
182
|
// loads the `dito` object through its own end-point, see:
|
|
@@ -250,8 +248,7 @@ export class AdminController extends Controller {
|
|
|
250
248
|
'prosemirror-view'
|
|
251
249
|
]
|
|
252
250
|
: ditoPackages
|
|
253
|
-
)
|
|
254
|
-
...nonEsmDependencies
|
|
251
|
+
)
|
|
255
252
|
]
|
|
256
253
|
},
|
|
257
254
|
resolve: {
|
|
@@ -279,12 +276,6 @@ const ditoPackages = [
|
|
|
279
276
|
'@ditojs/utils'
|
|
280
277
|
]
|
|
281
278
|
|
|
282
|
-
const nonEsmDependencies = [
|
|
283
|
-
// All non-es modules need to be explicitly included here, and some of
|
|
284
|
-
// them only work due to the use of `createCommonJsPlugin()`.
|
|
285
|
-
'@lk77/vue3-color'
|
|
286
|
-
]
|
|
287
|
-
|
|
288
279
|
const coreDependencies = [
|
|
289
280
|
...ditoPackages,
|
|
290
281
|
|
|
@@ -296,12 +287,11 @@ const coreDependencies = [
|
|
|
296
287
|
'vue',
|
|
297
288
|
'@vue/*',
|
|
298
289
|
'@vueuse/*',
|
|
299
|
-
'
|
|
290
|
+
'vue-color',
|
|
300
291
|
'@kyvg/vue3-notification',
|
|
301
292
|
'vue-multiselect',
|
|
302
293
|
'vue-router',
|
|
303
294
|
'vue-upload-component',
|
|
304
|
-
'tinycolor2',
|
|
305
295
|
'focus-trap',
|
|
306
296
|
'tabbable',
|
|
307
297
|
'sortablejs',
|
|
@@ -314,8 +304,6 @@ const coreDependencies = [
|
|
|
314
304
|
'nanoid',
|
|
315
305
|
'punycode',
|
|
316
306
|
'rope-sequence',
|
|
317
|
-
'filesize',
|
|
318
|
-
'filesize-parser',
|
|
319
307
|
'tslib', // ?
|
|
320
308
|
'orderedmap',
|
|
321
309
|
'w3c-keyname'
|
package/src/models/Model.js
CHANGED
|
@@ -16,7 +16,9 @@ import {
|
|
|
16
16
|
setValueAtDataPath,
|
|
17
17
|
mapConcurrently,
|
|
18
18
|
assignDeeply,
|
|
19
|
-
deprecate
|
|
19
|
+
deprecate,
|
|
20
|
+
formatPlainDate,
|
|
21
|
+
parsePlainDate
|
|
20
22
|
} from '@ditojs/utils'
|
|
21
23
|
import { QueryBuilder } from '../query/index.js'
|
|
22
24
|
import { EventEmitter, KnexHelper } from '../lib/index.js'
|
|
@@ -443,10 +445,21 @@ export class Model extends objection.Model {
|
|
|
443
445
|
static get dateAttributes() {
|
|
444
446
|
return this._getCached(
|
|
445
447
|
'jsonSchema:dateAttributes',
|
|
448
|
+
() =>
|
|
449
|
+
this.getAttributes(
|
|
450
|
+
({ type, computed }) => !computed && type === 'date'
|
|
451
|
+
),
|
|
452
|
+
[]
|
|
453
|
+
)
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
static get datetimeAttributes() {
|
|
457
|
+
return this._getCached(
|
|
458
|
+
'jsonSchema:datetimeAttributes',
|
|
446
459
|
() =>
|
|
447
460
|
this.getAttributes(
|
|
448
461
|
({ type, computed }) => (
|
|
449
|
-
!computed && ['
|
|
462
|
+
!computed && ['datetime', 'timestamp'].includes(type)
|
|
450
463
|
)
|
|
451
464
|
),
|
|
452
465
|
[]
|
|
@@ -590,12 +603,20 @@ export class Model extends objection.Model {
|
|
|
590
603
|
// @override
|
|
591
604
|
$formatDatabaseJson(json) {
|
|
592
605
|
const { constructor } = this
|
|
593
|
-
for (const key of constructor.
|
|
606
|
+
for (const key of constructor.datetimeAttributes) {
|
|
594
607
|
const date = json[key]
|
|
595
608
|
if (date?.toISOString) {
|
|
596
609
|
json[key] = date.toISOString()
|
|
597
610
|
}
|
|
598
611
|
}
|
|
612
|
+
for (const key of constructor.dateAttributes) {
|
|
613
|
+
const date = json[key]
|
|
614
|
+
if (date?.toISOString) {
|
|
615
|
+
// Store dates as their plain date, as the database ignores the
|
|
616
|
+
// time zone when casting a timestamp to a date.
|
|
617
|
+
json[key] = formatPlainDate(date)
|
|
618
|
+
}
|
|
619
|
+
}
|
|
599
620
|
if (constructor.isSQLite()) {
|
|
600
621
|
// SQLite does not support boolean natively and needs conversion...
|
|
601
622
|
for (const key of constructor.booleanAttributes) {
|
|
@@ -636,10 +657,17 @@ export class Model extends objection.Model {
|
|
|
636
657
|
// @override
|
|
637
658
|
$parseJson(json, { trusted = false } = {}) {
|
|
638
659
|
const { constructor } = this
|
|
639
|
-
for (const key of
|
|
660
|
+
for (const key of [
|
|
661
|
+
...constructor.dateAttributes,
|
|
662
|
+
...constructor.datetimeAttributes
|
|
663
|
+
]) {
|
|
640
664
|
const date = json[key]
|
|
641
665
|
if (date !== undefined) {
|
|
642
|
-
|
|
666
|
+
// Parse plain dates like `2026-05-14` as local midnight, which is
|
|
667
|
+
// also how Postgres reads them for timestamps.
|
|
668
|
+
json[key] = isString(date)
|
|
669
|
+
? parsePlainDate(date) ?? new Date(date)
|
|
670
|
+
: date
|
|
643
671
|
}
|
|
644
672
|
}
|
|
645
673
|
// Convert plain asset files objects to AssetFile instances with references
|
|
@@ -652,13 +680,21 @@ export class Model extends objection.Model {
|
|
|
652
680
|
|
|
653
681
|
// @override
|
|
654
682
|
$formatJson(json) {
|
|
683
|
+
const { constructor } = this
|
|
655
684
|
// Remove hidden attributes.
|
|
656
|
-
for (const key of
|
|
685
|
+
for (const key of constructor.hiddenAttributes) {
|
|
657
686
|
delete json[key]
|
|
658
687
|
}
|
|
688
|
+
// Return dates as their plain date, see `$formatDatabaseJson()`.
|
|
689
|
+
for (const key of constructor.dateAttributes) {
|
|
690
|
+
const date = json[key]
|
|
691
|
+
if (date?.toISOString) {
|
|
692
|
+
json[key] = formatPlainDate(date)
|
|
693
|
+
}
|
|
694
|
+
}
|
|
659
695
|
// Sign asset files so clients can send them back with valid signatures.
|
|
660
696
|
// Clone file objects to avoid mutating the model's internals.
|
|
661
|
-
|
|
697
|
+
constructor._signAssetFiles(json)
|
|
662
698
|
return json
|
|
663
699
|
}
|
|
664
700
|
|