@ditojs/server 2.96.0 → 2.97.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 +6 -6
- package/src/app/Application.js +1 -1
- package/src/models/Model.js +14 -7
- package/src/models/Model.test.js +68 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ditojs/server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.97.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",
|
|
@@ -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.97.0",
|
|
29
|
+
"@ditojs/build": "^2.97.0",
|
|
30
|
+
"@ditojs/router": "^2.97.0",
|
|
31
|
+
"@ditojs/utils": "^2.97.0",
|
|
32
32
|
"@koa/cors": "^5.0.0",
|
|
33
33
|
"@koa/etag": "^5.0.2",
|
|
34
34
|
"@koa/multer": "^4.0.0",
|
|
@@ -90,5 +90,5 @@
|
|
|
90
90
|
"objection": "^3.1.5",
|
|
91
91
|
"typescript": "^6.0.3"
|
|
92
92
|
},
|
|
93
|
-
"gitHead": "
|
|
93
|
+
"gitHead": "a15b3aa1474b88b4dbefd114491605b5715a6526"
|
|
94
94
|
}
|
package/src/app/Application.js
CHANGED
|
@@ -924,7 +924,7 @@ export class Application extends Koa {
|
|
|
924
924
|
changedFiles,
|
|
925
925
|
transaction = null
|
|
926
926
|
) {
|
|
927
|
-
let importedFiles
|
|
927
|
+
let importedFiles
|
|
928
928
|
const AssetModel = this.getModel('Asset')
|
|
929
929
|
if (AssetModel) {
|
|
930
930
|
importedFiles = await this.addForeignAssets(
|
package/src/models/Model.js
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
parseDataPath,
|
|
13
13
|
normalizeDataPath,
|
|
14
14
|
getValueAtDataPath,
|
|
15
|
+
getEntriesAtDataPath,
|
|
15
16
|
setValueAtDataPath,
|
|
16
17
|
mapConcurrently,
|
|
17
18
|
assignDeeply,
|
|
@@ -1018,14 +1019,20 @@ export class Model extends objection.Model {
|
|
|
1018
1019
|
const { assets } = this.definition
|
|
1019
1020
|
if (assets) {
|
|
1020
1021
|
for (const dataPath in assets) {
|
|
1021
|
-
const data = getValueAtDataPath(json, dataPath, noop)
|
|
1022
|
-
if (!data) continue
|
|
1023
1022
|
const storage = this.app.getStorage(assets[dataPath].storage)
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
)
|
|
1023
|
+
// Wildcard data paths (e.g. `**.file`) expand to multiple concrete
|
|
1024
|
+
// paths; iterate them so each match is written back to its own
|
|
1025
|
+
// location instead of the flattened wildcard result.
|
|
1026
|
+
const entries = getEntriesAtDataPath(json, dataPath, noop)
|
|
1027
|
+
for (const [path, data] of Object.entries(entries)) {
|
|
1028
|
+
if (data) {
|
|
1029
|
+
setValueAtDataPath(
|
|
1030
|
+
json,
|
|
1031
|
+
path,
|
|
1032
|
+
mapAssetFiles(data, storage, callback)
|
|
1033
|
+
)
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1029
1036
|
}
|
|
1030
1037
|
}
|
|
1031
1038
|
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Model } from './Model.js'
|
|
2
|
+
|
|
3
|
+
function makeFakeModel(assets) {
|
|
4
|
+
const storage = {
|
|
5
|
+
signAssetFile(file) {
|
|
6
|
+
file.signature = `sig-of-${file.key}`
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
return {
|
|
10
|
+
app: {
|
|
11
|
+
getStorage(name) {
|
|
12
|
+
return name === 'test' ? storage : null
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
definition: { assets }
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function signCallback(file, storage) {
|
|
20
|
+
const signed = { ...file }
|
|
21
|
+
storage.signAssetFile(signed)
|
|
22
|
+
return signed
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
describe('Model._mapAssetFiles: asset signing across data paths', () => {
|
|
26
|
+
it('writes the signature back to a literal data path', () => {
|
|
27
|
+
const model = makeFakeModel({ 'image.file': { storage: 'test' } })
|
|
28
|
+
const json = { image: { file: { key: 'foo.png' } } }
|
|
29
|
+
Model._mapAssetFiles.call(model, json, signCallback)
|
|
30
|
+
expect(json.image.file.signature).toBe('sig-of-foo.png')
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it('writes the signature back to every match of a deep wildcard', () => {
|
|
34
|
+
const model = makeFakeModel({ '**.file': { storage: 'test' } })
|
|
35
|
+
const json = {
|
|
36
|
+
content: {
|
|
37
|
+
file: { key: 'a.png' },
|
|
38
|
+
sections: [
|
|
39
|
+
{ file: { key: 'b.png' } },
|
|
40
|
+
{ file: { key: 'c.png' } }
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
Model._mapAssetFiles.call(model, json, signCallback)
|
|
45
|
+
expect(json.content.file.signature).toBe('sig-of-a.png')
|
|
46
|
+
expect(json.content.sections[0].file.signature).toBe('sig-of-b.png')
|
|
47
|
+
expect(json.content.sections[1].file.signature).toBe('sig-of-c.png')
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
it('writes the signature back into wildcard array values', () => {
|
|
51
|
+
const model = makeFakeModel({ '**.files': { storage: 'test' } })
|
|
52
|
+
const json = {
|
|
53
|
+
content: {
|
|
54
|
+
files: [{ key: 'x.png' }, { key: 'y.png' }]
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
Model._mapAssetFiles.call(model, json, signCallback)
|
|
58
|
+
expect(json.content.files[0].signature).toBe('sig-of-x.png')
|
|
59
|
+
expect(json.content.files[1].signature).toBe('sig-of-y.png')
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
it('is a no-op when the wildcard matches nothing', () => {
|
|
63
|
+
const model = makeFakeModel({ '**.file': { storage: 'test' } })
|
|
64
|
+
const json = { name: 'no-files-here' }
|
|
65
|
+
Model._mapAssetFiles.call(model, json, signCallback)
|
|
66
|
+
expect(json).toEqual({ name: 'no-files-here' })
|
|
67
|
+
})
|
|
68
|
+
})
|