@ditojs/server 2.43.0 → 2.44.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 -14
- package/src/app/Application.js +46 -34
- package/src/utils/duration.js +3 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ditojs/server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.44.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/master/packages/server",
|
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
"node >= 18"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@ditojs/admin": "^2.
|
|
29
|
-
"@ditojs/build": "^2.
|
|
30
|
-
"@ditojs/router": "^2.
|
|
31
|
-
"@ditojs/utils": "^2.
|
|
28
|
+
"@ditojs/admin": "^2.44.0",
|
|
29
|
+
"@ditojs/build": "^2.44.0",
|
|
30
|
+
"@ditojs/router": "^2.44.0",
|
|
31
|
+
"@ditojs/utils": "^2.44.0",
|
|
32
32
|
"@koa/cors": "^5.0.0",
|
|
33
33
|
"@koa/multer": "^3.0.2",
|
|
34
34
|
"@originjs/vite-plugin-commonjs": "^1.0.3",
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
"bytes": "^3.1.2",
|
|
39
39
|
"data-uri-to-buffer": "^6.0.2",
|
|
40
40
|
"eventemitter2": "^6.4.9",
|
|
41
|
-
"file-type": "^20.
|
|
41
|
+
"file-type": "^20.4.0",
|
|
42
42
|
"helmet": "^8.0.0",
|
|
43
|
-
"koa": "^2.
|
|
43
|
+
"koa": "^2.16.0",
|
|
44
44
|
"koa-bodyparser": "^4.4.1",
|
|
45
45
|
"koa-compose": "^4.1.0",
|
|
46
46
|
"koa-compress": "^5.1.1",
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
"mime-types": "^2.1.35",
|
|
57
57
|
"multer": "^1.4.5-lts.1",
|
|
58
58
|
"multer-s3": "https://github.com/ditojs/multer-s3#dito",
|
|
59
|
-
"nanoid": "^5.
|
|
60
|
-
"parse-duration": "^2.
|
|
59
|
+
"nanoid": "^5.1.3",
|
|
60
|
+
"parse-duration": "^2.1.3",
|
|
61
61
|
"passport-local": "^1.0.0",
|
|
62
62
|
"passthrough-counter": "^1.0.0",
|
|
63
63
|
"picocolors": "^1.1.1",
|
|
@@ -66,8 +66,8 @@
|
|
|
66
66
|
"pino-pretty": "^13.0.0",
|
|
67
67
|
"pluralize": "^8.0.0",
|
|
68
68
|
"repl": "^0.1.3",
|
|
69
|
-
"type-fest": "^4.
|
|
70
|
-
"uuid": "^11.0
|
|
69
|
+
"type-fest": "^4.37.0",
|
|
70
|
+
"uuid": "^11.1.0"
|
|
71
71
|
},
|
|
72
72
|
"peerDependencies": {
|
|
73
73
|
"@aws-sdk/client-s3": "^3.0.0",
|
|
@@ -84,11 +84,11 @@
|
|
|
84
84
|
"@types/koa-session": "^6.4.5",
|
|
85
85
|
"@types/koa-static": "^4.0.4",
|
|
86
86
|
"@types/koa__cors": "^5.0.0",
|
|
87
|
-
"@types/node": "^22.
|
|
87
|
+
"@types/node": "^22.13.10",
|
|
88
88
|
"knex": "^3.1.0",
|
|
89
89
|
"objection": "^3.1.5",
|
|
90
|
-
"typescript": "^5.
|
|
90
|
+
"typescript": "^5.8.2"
|
|
91
91
|
},
|
|
92
92
|
"types": "types",
|
|
93
|
-
"gitHead": "
|
|
93
|
+
"gitHead": "64f76ac9f74a8915bc02bfea79f0db125f3f4437"
|
|
94
94
|
}
|
package/src/app/Application.js
CHANGED
|
@@ -886,7 +886,7 @@ export class Application extends Koa {
|
|
|
886
886
|
|
|
887
887
|
// Assets handling
|
|
888
888
|
|
|
889
|
-
async createAssets(storage, files, count = 0,
|
|
889
|
+
async createAssets(storage, files, count = 0, transaction = null) {
|
|
890
890
|
const AssetModel = this.getModel('Asset')
|
|
891
891
|
if (AssetModel) {
|
|
892
892
|
const assets = files.map(file => ({
|
|
@@ -895,7 +895,7 @@ export class Application extends Koa {
|
|
|
895
895
|
storage: storage.name,
|
|
896
896
|
count
|
|
897
897
|
}))
|
|
898
|
-
return AssetModel.query(
|
|
898
|
+
return AssetModel.query(transaction).insert(assets)
|
|
899
899
|
}
|
|
900
900
|
return null
|
|
901
901
|
}
|
|
@@ -905,7 +905,7 @@ export class Application extends Koa {
|
|
|
905
905
|
addedFiles,
|
|
906
906
|
removedFiles,
|
|
907
907
|
changedFiles,
|
|
908
|
-
|
|
908
|
+
transaction = null
|
|
909
909
|
) {
|
|
910
910
|
let importedFiles = []
|
|
911
911
|
const AssetModel = this.getModel('Asset')
|
|
@@ -913,7 +913,7 @@ export class Application extends Koa {
|
|
|
913
913
|
importedFiles = await this.addForeignAssets(
|
|
914
914
|
storage,
|
|
915
915
|
[...addedFiles, ...changedFiles],
|
|
916
|
-
|
|
916
|
+
transaction
|
|
917
917
|
)
|
|
918
918
|
if (
|
|
919
919
|
addedFiles.length > 0 ||
|
|
@@ -921,7 +921,7 @@ export class Application extends Koa {
|
|
|
921
921
|
) {
|
|
922
922
|
const changeCount = async (files, increment) => {
|
|
923
923
|
if (files.length > 0) {
|
|
924
|
-
await AssetModel.query(
|
|
924
|
+
await AssetModel.query(transaction)
|
|
925
925
|
.whereIn(
|
|
926
926
|
'key',
|
|
927
927
|
files.map(file => file.key)
|
|
@@ -938,8 +938,8 @@ export class Application extends Koa {
|
|
|
938
938
|
)
|
|
939
939
|
if (cleanupTimeThreshold > 0) {
|
|
940
940
|
setTimeout(
|
|
941
|
-
// Don't pass `
|
|
942
|
-
// create its own transaction.
|
|
941
|
+
// Don't pass `transaction` here, as we want this delayed execution
|
|
942
|
+
// to create its own transaction.
|
|
943
943
|
() => this.releaseUnusedAssets(),
|
|
944
944
|
cleanupTimeThreshold
|
|
945
945
|
)
|
|
@@ -947,12 +947,12 @@ export class Application extends Koa {
|
|
|
947
947
|
}
|
|
948
948
|
// Also execute releaseUnusedAssets() immediately in the same
|
|
949
949
|
// transaction, to potentially clean up other pending assets.
|
|
950
|
-
await this.releaseUnusedAssets(
|
|
950
|
+
await this.releaseUnusedAssets({ transaction })
|
|
951
951
|
return importedFiles
|
|
952
952
|
}
|
|
953
953
|
}
|
|
954
954
|
|
|
955
|
-
async addForeignAssets(storage, files,
|
|
955
|
+
async addForeignAssets(storage, files, transaction = null) {
|
|
956
956
|
const importedFiles = []
|
|
957
957
|
const AssetModel = this.getModel('Asset')
|
|
958
958
|
if (AssetModel) {
|
|
@@ -961,7 +961,7 @@ export class Application extends Koa {
|
|
|
961
961
|
await mapConcurrently(
|
|
962
962
|
Object.entries(filesByKey),
|
|
963
963
|
async ([key, files]) => {
|
|
964
|
-
const asset = await AssetModel.query(
|
|
964
|
+
const asset = await AssetModel.query(transaction).findOne('key', key)
|
|
965
965
|
if (!asset) {
|
|
966
966
|
const [file] = files // Pick the first file
|
|
967
967
|
if (file.data || file.url) {
|
|
@@ -997,7 +997,7 @@ export class Application extends Koa {
|
|
|
997
997
|
}
|
|
998
998
|
}
|
|
999
999
|
const importedFile = await storage.addFile(file, data)
|
|
1000
|
-
await this.createAssets(storage, [importedFile], 0,
|
|
1000
|
+
await this.createAssets(storage, [importedFile], 0, transaction)
|
|
1001
1001
|
importedFiles.push(importedFile)
|
|
1002
1002
|
// Merge back the changed file properties into the actual file
|
|
1003
1003
|
// objects, so that the data from the static model hook can be
|
|
@@ -1030,36 +1030,47 @@ export class Application extends Koa {
|
|
|
1030
1030
|
return importedFiles
|
|
1031
1031
|
}
|
|
1032
1032
|
|
|
1033
|
-
async handleModifiedAssets(storage, files,
|
|
1033
|
+
async handleModifiedAssets(storage, files, transaction = null) {
|
|
1034
1034
|
const modifiedFiles = []
|
|
1035
1035
|
const AssetModel = this.getModel('Asset')
|
|
1036
1036
|
if (AssetModel) {
|
|
1037
|
-
await mapConcurrently(
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
if (
|
|
1041
|
-
const
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
// directly for the actual running query.
|
|
1045
|
-
Object.assign(file, changedFile)
|
|
1046
|
-
modifiedFiles.push(changedFile)
|
|
1047
|
-
} else {
|
|
1048
|
-
throw new AssetError(
|
|
1049
|
-
`Unable to update modified asset from memory source: '${
|
|
1050
|
-
file.name
|
|
1051
|
-
}' ('${
|
|
1052
|
-
file.key
|
|
1053
|
-
}')`
|
|
1037
|
+
await mapConcurrently(
|
|
1038
|
+
files,
|
|
1039
|
+
async file => {
|
|
1040
|
+
if (file.data) {
|
|
1041
|
+
const asset = await AssetModel.query(transaction).findOne(
|
|
1042
|
+
'key',
|
|
1043
|
+
file.key
|
|
1054
1044
|
)
|
|
1045
|
+
if (asset) {
|
|
1046
|
+
const changedFile = await storage.addFile(file, file.data)
|
|
1047
|
+
// Merge back the changed file properties into the actual files
|
|
1048
|
+
// object, so that the data from the static model hook can be used
|
|
1049
|
+
// directly for the actual running query.
|
|
1050
|
+
Object.assign(file, changedFile)
|
|
1051
|
+
modifiedFiles.push(changedFile)
|
|
1052
|
+
} else {
|
|
1053
|
+
throw new AssetError(
|
|
1054
|
+
`Unable to update modified asset from memory source: '${
|
|
1055
|
+
file.name
|
|
1056
|
+
}' ('${
|
|
1057
|
+
file.key
|
|
1058
|
+
}')`
|
|
1059
|
+
)
|
|
1060
|
+
}
|
|
1055
1061
|
}
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1062
|
+
},
|
|
1063
|
+
{ concurrency: storage.concurrency }
|
|
1064
|
+
)
|
|
1058
1065
|
}
|
|
1059
1066
|
return modifiedFiles
|
|
1060
1067
|
}
|
|
1061
1068
|
|
|
1062
|
-
async releaseUnusedAssets(
|
|
1069
|
+
async releaseUnusedAssets({
|
|
1070
|
+
timeThreshold = null,
|
|
1071
|
+
transaction = null,
|
|
1072
|
+
concurrency = 8
|
|
1073
|
+
} = {}) {
|
|
1063
1074
|
const AssetModel = this.getModel('Asset')
|
|
1064
1075
|
if (AssetModel) {
|
|
1065
1076
|
const { assets } = this.config
|
|
@@ -1069,7 +1080,7 @@ export class Application extends Koa {
|
|
|
1069
1080
|
const danglingTimeThreshold = getDuration(
|
|
1070
1081
|
timeThreshold ?? assets.danglingTimeThreshold
|
|
1071
1082
|
)
|
|
1072
|
-
return AssetModel.transaction(
|
|
1083
|
+
return AssetModel.transaction(transaction, async trx => {
|
|
1073
1084
|
// Calculate the date math in JS instead of SQL, as there is no easy
|
|
1074
1085
|
// cross-SQL way to do `now() - interval X hours`:
|
|
1075
1086
|
const now = new Date()
|
|
@@ -1100,7 +1111,8 @@ export class Application extends Koa {
|
|
|
1100
1111
|
asset.error = error
|
|
1101
1112
|
}
|
|
1102
1113
|
return asset.key
|
|
1103
|
-
}
|
|
1114
|
+
},
|
|
1115
|
+
{ concurrency }
|
|
1104
1116
|
)
|
|
1105
1117
|
await AssetModel.query(trx).delete().whereIn('key', orphanedKeys)
|
|
1106
1118
|
}
|
package/src/utils/duration.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { isNumber } from '@ditojs/utils'
|
|
2
|
-
|
|
2
|
+
// eslint-disable-next-line import/default
|
|
3
|
+
import parseDuration from 'parse-duration'
|
|
3
4
|
|
|
4
5
|
export function getDuration(duration) {
|
|
5
|
-
return isNumber(duration) ? duration :
|
|
6
|
+
return isNumber(duration) ? duration : parseDuration(duration)
|
|
6
7
|
}
|
|
7
8
|
|
|
8
9
|
export function addDuration(date, duration) {
|