@ditojs/server 2.0.5 → 2.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 +11 -13
- package/src/app/Application.js +226 -179
- package/src/app/Validator.js +53 -43
- package/src/cli/console.js +6 -4
- package/src/cli/db/createMigration.js +59 -30
- package/src/cli/db/migrate.js +6 -4
- package/src/cli/db/reset.js +8 -5
- package/src/cli/db/rollback.js +6 -4
- package/src/cli/db/seed.js +2 -1
- package/src/cli/index.js +1 -1
- package/src/controllers/AdminController.js +98 -84
- package/src/controllers/CollectionController.js +37 -30
- package/src/controllers/Controller.js +83 -43
- package/src/controllers/ControllerAction.js +27 -15
- package/src/controllers/ModelController.js +4 -1
- package/src/controllers/RelationController.js +19 -21
- package/src/controllers/UsersController.js +3 -4
- package/src/decorators/parameters.js +3 -1
- package/src/decorators/scope.js +1 -1
- package/src/errors/ControllerError.js +2 -1
- package/src/errors/DatabaseError.js +20 -11
- package/src/graph/DitoGraphProcessor.js +48 -40
- package/src/graph/expression.js +6 -8
- package/src/graph/graph.js +20 -11
- package/src/lib/EventEmitter.js +12 -12
- package/src/middleware/handleConnectMiddleware.js +16 -10
- package/src/middleware/handleError.js +6 -5
- package/src/middleware/handleSession.js +33 -29
- package/src/middleware/handleUser.js +2 -2
- package/src/middleware/index.js +1 -0
- package/src/middleware/logRequests.js +3 -3
- package/src/middleware/setupRequestStorage.js +14 -0
- package/src/mixins/AssetMixin.js +62 -58
- package/src/mixins/SessionMixin.js +13 -10
- package/src/mixins/TimeStampedMixin.js +33 -29
- package/src/mixins/UserMixin.js +130 -116
- package/src/models/Model.js +245 -194
- package/src/models/definitions/filters.js +14 -13
- package/src/query/QueryBuilder.js +252 -195
- package/src/query/QueryFilters.js +3 -3
- package/src/query/QueryParameters.js +2 -2
- package/src/query/Registry.js +8 -10
- package/src/schema/keywords/_validate.js +10 -8
- package/src/schema/properties.test.js +247 -206
- package/src/schema/relations.js +42 -20
- package/src/schema/relations.test.js +36 -19
- package/src/services/Service.js +8 -14
- package/src/storage/S3Storage.js +5 -3
- package/src/storage/Storage.js +16 -14
- package/src/utils/function.js +7 -4
- package/src/utils/function.test.js +30 -6
- package/src/utils/object.test.js +5 -1
- package/types/index.d.ts +244 -257
package/src/app/Validator.js
CHANGED
|
@@ -59,13 +59,17 @@ export class Validator extends objection.Validator {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
addSchemas(this.keywords, (keyword, schema) =>
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
addSchemas(this.keywords, (keyword, schema) =>
|
|
63
|
+
ajv.addKeyword({
|
|
64
|
+
keyword,
|
|
65
|
+
...schema
|
|
66
|
+
})
|
|
67
|
+
)
|
|
68
|
+
addSchemas(this.formats, (format, schema) =>
|
|
69
|
+
ajv.addFormat(format, {
|
|
70
|
+
...schema
|
|
71
|
+
})
|
|
72
|
+
)
|
|
69
73
|
|
|
70
74
|
// Also add all model schemas that were already compiled so far.
|
|
71
75
|
for (const schema of this.schemas) {
|
|
@@ -85,10 +89,13 @@ export class Validator extends objection.Validator {
|
|
|
85
89
|
return opts
|
|
86
90
|
}, {})
|
|
87
91
|
const cacheKey = formatJson(opts, false)
|
|
88
|
-
const { ajv } =
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
+
const { ajv } = (
|
|
93
|
+
this.ajvCache[cacheKey] ||
|
|
94
|
+
(this.ajvCache[cacheKey] = {
|
|
95
|
+
ajv: this.createAjv(opts),
|
|
96
|
+
options
|
|
97
|
+
})
|
|
98
|
+
)
|
|
92
99
|
return ajv
|
|
93
100
|
}
|
|
94
101
|
|
|
@@ -98,40 +105,41 @@ export class Validator extends objection.Validator {
|
|
|
98
105
|
// Assume `options.throw = true` as the default.
|
|
99
106
|
const dontThrow = options.throw === false
|
|
100
107
|
return options.async
|
|
101
|
-
// For async:
|
|
102
|
-
|
|
108
|
+
? // For async:
|
|
109
|
+
dontThrow
|
|
103
110
|
? async function validate(data) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
111
|
+
// Emulate `options.throw == false` behavior for async validation:
|
|
112
|
+
// Return `true` or `false`, and store errors on `validate.errors`
|
|
113
|
+
// if validation failed.
|
|
114
|
+
let result
|
|
115
|
+
try {
|
|
116
|
+
// Use `call()` to pass `this` as context to Ajv, see passContext:
|
|
117
|
+
result = await validator.call(this, data)
|
|
118
|
+
} catch (error) {
|
|
119
|
+
if (error.errors) {
|
|
120
|
+
validate.errors = error.errors
|
|
121
|
+
result = false
|
|
122
|
+
} else {
|
|
123
|
+
throw error
|
|
124
|
+
}
|
|
117
125
|
}
|
|
126
|
+
return result
|
|
118
127
|
}
|
|
119
|
-
return result
|
|
120
|
-
}
|
|
121
128
|
: validator // The default for async is to throw.
|
|
122
|
-
// For sync:
|
|
123
|
-
|
|
129
|
+
: // For sync:
|
|
130
|
+
dontThrow
|
|
124
131
|
? validator // The default for sync is to not throw.
|
|
125
|
-
: function(data) {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
+
: function (data) {
|
|
133
|
+
// Emulate `options.throw == true` behavior for sync validation:
|
|
134
|
+
// Return `true` if successful, throw `Ajv.ValidationError`
|
|
135
|
+
// otherwise. Use `call()` to pass `this` as context to Ajv,
|
|
136
|
+
// see `passContext`:
|
|
137
|
+
const result = validator.call(this, data)
|
|
138
|
+
if (!result) {
|
|
139
|
+
throw new Ajv.ValidationError(validator.errors)
|
|
140
|
+
}
|
|
141
|
+
return result
|
|
132
142
|
}
|
|
133
|
-
return result
|
|
134
|
-
}
|
|
135
143
|
}
|
|
136
144
|
|
|
137
145
|
getKeyword(keyword) {
|
|
@@ -204,9 +212,10 @@ export class Validator extends objection.Validator {
|
|
|
204
212
|
// https://github.com/epoberezkin/ajv/issues/671
|
|
205
213
|
const key = dataPath.replace(/\['([^']*)'\]/g, '/$1').slice(1)
|
|
206
214
|
const { message, keyword, params } = error
|
|
207
|
-
const definition =
|
|
208
|
-
|
|
209
|
-
|
|
215
|
+
const definition =
|
|
216
|
+
keyword === 'format'
|
|
217
|
+
? this.getFormat(params.format)
|
|
218
|
+
: this.getKeyword(keyword)
|
|
210
219
|
const identifier = `${key}_${keyword}`
|
|
211
220
|
if (
|
|
212
221
|
// Ajv produces duplicate validation errors sometimes, filter them out.
|
|
@@ -247,7 +256,8 @@ export class Validator extends objection.Validator {
|
|
|
247
256
|
if (errors.length === 2) {
|
|
248
257
|
const [error1, error2] = errors
|
|
249
258
|
if (
|
|
250
|
-
error1.keyword === 'type' &&
|
|
259
|
+
error1.keyword === 'type' &&
|
|
260
|
+
error1.params.type === 'null' &&
|
|
251
261
|
error2.keyword === 'oneOf'
|
|
252
262
|
) {
|
|
253
263
|
delete errorHash[dataPath]
|
package/src/cli/console.js
CHANGED
|
@@ -52,7 +52,9 @@ export default async function startConsole(app, config) {
|
|
|
52
52
|
try {
|
|
53
53
|
await fs.stat(historyFile)
|
|
54
54
|
const lines = await fs.readFile(historyFile)
|
|
55
|
-
lines
|
|
55
|
+
lines
|
|
56
|
+
.toString()
|
|
57
|
+
.split('\n')
|
|
56
58
|
.reverse()
|
|
57
59
|
.slice(0, config.historySize)
|
|
58
60
|
.filter(line => line.trim())
|
|
@@ -104,8 +106,8 @@ function displayUsage(app, config, details) {
|
|
|
104
106
|
${
|
|
105
107
|
modelHandleNames.length > 0
|
|
106
108
|
? ` - Dito models: ${
|
|
107
|
-
|
|
108
|
-
|
|
109
|
+
modelHandleNames.map(m => pico.cyan(m)).join(', ')
|
|
110
|
+
}`
|
|
109
111
|
: ''
|
|
110
112
|
}
|
|
111
113
|
`)
|
|
@@ -123,7 +125,7 @@ function displayUsage(app, config, details) {
|
|
|
123
125
|
|
|
124
126
|
// Wraps the default eval with a handler that resolves promises
|
|
125
127
|
function wrapEval({ eval: defaultEval }) {
|
|
126
|
-
return async function(code, context, file, cb) {
|
|
128
|
+
return async function (code, context, file, cb) {
|
|
127
129
|
return defaultEval.call(this, code, context, file, async (err, result) => {
|
|
128
130
|
if (err || !(result && isFunction(result.then))) {
|
|
129
131
|
return cb(err, result)
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import path from 'path'
|
|
2
2
|
import fs from 'fs/promises'
|
|
3
3
|
import pico from 'picocolors'
|
|
4
|
+
import { getRelationClass, isThroughRelationClass } from '@ditojs/server'
|
|
4
5
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
isObject,
|
|
7
|
+
isArray,
|
|
8
|
+
isString,
|
|
9
|
+
deindent,
|
|
10
|
+
capitalize
|
|
10
11
|
} from '@ditojs/utils'
|
|
11
12
|
import { exists } from '../../utils/fs.js'
|
|
12
13
|
|
|
@@ -47,11 +48,12 @@ export async function createMigration(app, name, ...modelNames) {
|
|
|
47
48
|
dropTables.unshift(deindent`
|
|
48
49
|
.dropTableIfExists('${tableName}')`)
|
|
49
50
|
}
|
|
50
|
-
const getCode = tables =>
|
|
51
|
-
|
|
51
|
+
const getCode = tables =>
|
|
52
|
+
tables.length > 0
|
|
53
|
+
? deindent`
|
|
52
54
|
await knex.schema
|
|
53
55
|
${tables.join('\n')}`
|
|
54
|
-
|
|
56
|
+
: ''
|
|
55
57
|
const filename = `${getTimestamp()}_${name}.js`
|
|
56
58
|
const file = path.join(migrationDir, filename)
|
|
57
59
|
if (await exists(file)) {
|
|
@@ -59,15 +61,20 @@ export async function createMigration(app, name, ...modelNames) {
|
|
|
59
61
|
console.info(pico.red(`Migration '${filename}' already exists.`))
|
|
60
62
|
return false
|
|
61
63
|
} else {
|
|
62
|
-
await fs.writeFile(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
await fs.writeFile(
|
|
65
|
+
file,
|
|
66
|
+
deindent`
|
|
67
|
+
/** @param {import('knex').Knex} knex */
|
|
68
|
+
export async function up(knex) {
|
|
69
|
+
${getCode(createTables)}
|
|
70
|
+
}
|
|
66
71
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
/** @param {import('knex').Knex} knex */
|
|
73
|
+
export async function down(knex) {
|
|
74
|
+
${getCode(dropTables)}
|
|
75
|
+
}
|
|
76
|
+
`
|
|
77
|
+
)
|
|
71
78
|
console.info(pico.cyan(`Migration '${filename}' successfully created.`))
|
|
72
79
|
return true
|
|
73
80
|
}
|
|
@@ -82,8 +89,17 @@ async function collectModelTables(modelClass, app, tables) {
|
|
|
82
89
|
for (const [name, property] of Object.entries(properties)) {
|
|
83
90
|
const column = app.normalizeIdentifier(name)
|
|
84
91
|
let {
|
|
85
|
-
description,
|
|
86
|
-
|
|
92
|
+
description,
|
|
93
|
+
type,
|
|
94
|
+
specificType,
|
|
95
|
+
unsigned,
|
|
96
|
+
computed,
|
|
97
|
+
nullable,
|
|
98
|
+
required,
|
|
99
|
+
primary,
|
|
100
|
+
foreign,
|
|
101
|
+
unique,
|
|
102
|
+
index,
|
|
87
103
|
default: _default
|
|
88
104
|
} = property
|
|
89
105
|
const knexType = typeToKnex[type] || type
|
|
@@ -95,8 +111,10 @@ async function collectModelTables(modelClass, app, tables) {
|
|
|
95
111
|
// To declare composite foreign keys as unique, you can give each
|
|
96
112
|
// property the same string value in the `unique` keywords, e.g.:
|
|
97
113
|
// `unique: 'customerId_name'
|
|
98
|
-
const composites =
|
|
114
|
+
const composites = (
|
|
115
|
+
uniqueComposites[unique] ||
|
|
99
116
|
(uniqueComposites[unique] = [])
|
|
117
|
+
)
|
|
100
118
|
composites.push(column)
|
|
101
119
|
unique = false
|
|
102
120
|
}
|
|
@@ -115,9 +133,10 @@ async function collectModelTables(modelClass, app, tables) {
|
|
|
115
133
|
if (_default !== undefined) {
|
|
116
134
|
let value = defaultValues[_default]
|
|
117
135
|
if (!value) {
|
|
118
|
-
value =
|
|
119
|
-
|
|
120
|
-
|
|
136
|
+
value =
|
|
137
|
+
isArray(_default) || isObject(_default)
|
|
138
|
+
? JSON.stringify(_default)
|
|
139
|
+
: _default
|
|
121
140
|
if (isString(value)) {
|
|
122
141
|
value = `'${value}'`
|
|
123
142
|
}
|
|
@@ -148,14 +167,20 @@ async function collectModelTables(modelClass, app, tables) {
|
|
|
148
167
|
}
|
|
149
168
|
}
|
|
150
169
|
}
|
|
151
|
-
statements.push(
|
|
152
|
-
|
|
170
|
+
statements.push(
|
|
171
|
+
statement
|
|
172
|
+
.filter(str => !!str)
|
|
173
|
+
.join('.')
|
|
174
|
+
.replace(/\.\n\./g, '\n .')
|
|
175
|
+
)
|
|
153
176
|
}
|
|
154
177
|
}
|
|
155
178
|
for (const composites of Object.values(uniqueComposites)) {
|
|
156
|
-
statements.push(
|
|
157
|
-
|
|
158
|
-
|
|
179
|
+
statements.push(
|
|
180
|
+
`table.unique([${
|
|
181
|
+
composites.map(column => `'${column}'`).join(', ')
|
|
182
|
+
}])`
|
|
183
|
+
)
|
|
159
184
|
}
|
|
160
185
|
}
|
|
161
186
|
|
|
@@ -173,9 +198,11 @@ async function collectThroughTables(modelClass, app, tables) {
|
|
|
173
198
|
// See convertRelations()
|
|
174
199
|
const tableName = app.normalizeIdentifier(`${fromClass}${toClass}`)
|
|
175
200
|
const fromId = app.normalizeIdentifier(
|
|
176
|
-
`${fromClass}${capitalize(fromProperty)}`
|
|
201
|
+
`${fromClass}${capitalize(fromProperty)}`
|
|
202
|
+
)
|
|
177
203
|
const toId = app.normalizeIdentifier(
|
|
178
|
-
`${toClass}${capitalize(toProperty)}`
|
|
204
|
+
`${toClass}${capitalize(toProperty)}`
|
|
205
|
+
)
|
|
179
206
|
tables.push({ tableName, statements })
|
|
180
207
|
statements.push(`table.increments('id').primary()`)
|
|
181
208
|
statements.push(deindent`
|
|
@@ -201,10 +228,12 @@ function padDate(segment) {
|
|
|
201
228
|
// like "moment.js".
|
|
202
229
|
function getTimestamp() {
|
|
203
230
|
const d = new Date()
|
|
204
|
-
return
|
|
231
|
+
return (
|
|
232
|
+
d.getFullYear().toString() +
|
|
205
233
|
padDate(d.getMonth() + 1) +
|
|
206
234
|
padDate(d.getDate()) +
|
|
207
235
|
padDate(d.getHours()) +
|
|
208
236
|
padDate(d.getMinutes()) +
|
|
209
237
|
padDate(d.getSeconds())
|
|
238
|
+
)
|
|
210
239
|
}
|
package/src/cli/db/migrate.js
CHANGED
|
@@ -2,9 +2,11 @@ import pico from 'picocolors'
|
|
|
2
2
|
|
|
3
3
|
export async function migrate(knex) {
|
|
4
4
|
const [batch, log] = await knex.migrate.latest()
|
|
5
|
-
console.info(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
pico.
|
|
5
|
+
console.info(
|
|
6
|
+
log.length === 0
|
|
7
|
+
? pico.cyan('Already up to date')
|
|
8
|
+
: pico.green(`Batch ${batch} run: ${log.length} migrations\n`) +
|
|
9
|
+
pico.cyan(log.join('\n'))
|
|
10
|
+
)
|
|
9
11
|
return true
|
|
10
12
|
}
|
package/src/cli/db/reset.js
CHANGED
|
@@ -10,11 +10,14 @@ export async function reset(knex) {
|
|
|
10
10
|
batches.push(batch)
|
|
11
11
|
migrations.push(...log)
|
|
12
12
|
}
|
|
13
|
-
console.info(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
console.info(
|
|
14
|
+
migrations.length === 0
|
|
15
|
+
? pico.cyan('Already at the base migration')
|
|
16
|
+
: pico.green(
|
|
17
|
+
`${batches.length > 1 ? 'Batches' : 'Batch'} ${batches} ` +
|
|
18
|
+
`rolled back: ${migrations.length} migrations\n`
|
|
19
|
+
) + pico.cyan(migrations.join('\n'))
|
|
20
|
+
)
|
|
18
21
|
await migrate(knex)
|
|
19
22
|
return true
|
|
20
23
|
}
|
package/src/cli/db/rollback.js
CHANGED
|
@@ -2,9 +2,11 @@ import pico from 'picocolors'
|
|
|
2
2
|
|
|
3
3
|
export async function rollback(knex) {
|
|
4
4
|
const [batch, log] = await knex.migrate.rollback()
|
|
5
|
-
console.info(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
pico.
|
|
5
|
+
console.info(
|
|
6
|
+
log.length === 0
|
|
7
|
+
? pico.cyan('Already at the base migration')
|
|
8
|
+
: pico.green(`Batch ${batch} rolled back: ${log.length} migrations\n`) +
|
|
9
|
+
pico.cyan(log.join('\n'))
|
|
10
|
+
)
|
|
9
11
|
return true
|
|
10
12
|
}
|
package/src/cli/db/seed.js
CHANGED
|
@@ -25,9 +25,10 @@ export async function seed(app) {
|
|
|
25
25
|
const seed = object.default || object
|
|
26
26
|
// Try to determine the related model from the seed name, and use it also
|
|
27
27
|
// to determine seed sequence based on its index in `app.models`.
|
|
28
|
-
const modelClass =
|
|
28
|
+
const modelClass = (
|
|
29
29
|
app.models[name] ||
|
|
30
30
|
app.models[camelize(pluralize.singular(name), true)]
|
|
31
|
+
)
|
|
31
32
|
const index = modelClass ? modelIndices[modelClass.name] : Infinity
|
|
32
33
|
seeds.push({
|
|
33
34
|
base,
|
package/src/cli/index.js
CHANGED
|
@@ -26,7 +26,7 @@ function setSilent(silent) {
|
|
|
26
26
|
async function execute() {
|
|
27
27
|
try {
|
|
28
28
|
// Dynamically load app or config from the path provided package.json script
|
|
29
|
-
const [
|
|
29
|
+
const [, , command, importPath, ...args] = process.argv
|
|
30
30
|
const execute = command && getCommand(commands, command.split(':'))
|
|
31
31
|
if (!isFunction(execute)) {
|
|
32
32
|
throw new Error(`Unknown command: ${command}`)
|
|
@@ -3,9 +3,7 @@ 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 {
|
|
7
|
-
viteCommonjs as createCommonJsPlugin
|
|
8
|
-
} from '@originjs/vite-plugin-commonjs'
|
|
6
|
+
import { viteCommonjs as createCommonJsPlugin } from '@originjs/vite-plugin-commonjs'
|
|
9
7
|
import { testModuleIdentifier, getPostCssConfig } from '@ditojs/build'
|
|
10
8
|
import { merge } from '@ditojs/utils'
|
|
11
9
|
import { Controller } from './Controller.js'
|
|
@@ -28,8 +26,9 @@ export class AdminController extends Controller {
|
|
|
28
26
|
// If no mode is specified, use `production` since that's just the hosting
|
|
29
27
|
// of the pre-built admin files. `development` serves the admin directly
|
|
30
28
|
// sources with HRM, and thus should be explicitly activated.
|
|
31
|
-
this.mode =
|
|
32
|
-
this.
|
|
29
|
+
this.mode = (
|
|
30
|
+
this.config.mode ||
|
|
31
|
+
(this.app.config.env === 'development' ? 'development' : 'production')
|
|
33
32
|
)
|
|
34
33
|
this.closed = false
|
|
35
34
|
}
|
|
@@ -38,11 +37,16 @@ export class AdminController extends Controller {
|
|
|
38
37
|
const { config } = this
|
|
39
38
|
let str = config[name]
|
|
40
39
|
if (config.build?.path || config.dist?.path) {
|
|
41
|
-
deprecate(
|
|
40
|
+
deprecate(
|
|
41
|
+
`config.admin.build.path and config.admin.dist.path are deprecated. Use config.admin.root and config.admin.dist instead.`
|
|
42
|
+
)
|
|
42
43
|
|
|
43
|
-
str =
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
str =
|
|
45
|
+
name === 'root'
|
|
46
|
+
? config.build?.path
|
|
47
|
+
: name === 'dist'
|
|
48
|
+
? config.dist?.path
|
|
49
|
+
: null
|
|
46
50
|
}
|
|
47
51
|
if (!str) {
|
|
48
52
|
throw new ControllerError(
|
|
@@ -156,9 +160,11 @@ export class AdminController extends Controller {
|
|
|
156
160
|
}
|
|
157
161
|
})
|
|
158
162
|
|
|
159
|
-
this.koa.use(
|
|
160
|
-
|
|
161
|
-
|
|
163
|
+
this.koa.use(
|
|
164
|
+
handleConnectMiddleware(server.middlewares, {
|
|
165
|
+
expandMountPath: true
|
|
166
|
+
})
|
|
167
|
+
)
|
|
162
168
|
}
|
|
163
169
|
|
|
164
170
|
getViteConfig(config = {}) {
|
|
@@ -169,85 +175,93 @@ export class AdminController extends Controller {
|
|
|
169
175
|
const base = `${this.url}/`
|
|
170
176
|
const views = path.join(root, 'views')
|
|
171
177
|
|
|
172
|
-
return defineConfig(
|
|
173
|
-
|
|
174
|
-
base,
|
|
175
|
-
mode: this.mode,
|
|
176
|
-
envFile: false,
|
|
177
|
-
configFile: false,
|
|
178
|
-
plugins: [
|
|
179
|
-
createVuePlugin(),
|
|
180
|
-
createCommonJsPlugin(),
|
|
178
|
+
return defineConfig(
|
|
179
|
+
merge(
|
|
181
180
|
{
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
rollupOptions: {
|
|
202
|
-
output: {
|
|
203
|
-
manualChunks(id) {
|
|
204
|
-
if (id.startsWith(views)) {
|
|
205
|
-
return 'views'
|
|
206
|
-
} else if (id.startsWith(cwd)) {
|
|
207
|
-
return 'common'
|
|
208
|
-
} else {
|
|
209
|
-
const module = (
|
|
210
|
-
id.match(/node_modules\/((?:@[^/]*\/)?[^/$]*)/)?.[1] || ''
|
|
181
|
+
root,
|
|
182
|
+
base,
|
|
183
|
+
mode: this.mode,
|
|
184
|
+
envFile: false,
|
|
185
|
+
configFile: false,
|
|
186
|
+
plugins: [
|
|
187
|
+
createVuePlugin(),
|
|
188
|
+
createCommonJsPlugin(),
|
|
189
|
+
{
|
|
190
|
+
// Private plugin to inject script tag above main module that
|
|
191
|
+
// loads the `dito` object through its own end-point, see:
|
|
192
|
+
// `sendDitoObject()`
|
|
193
|
+
name: 'inject-dito-object',
|
|
194
|
+
transformIndexHtml: {
|
|
195
|
+
enforce: 'post',
|
|
196
|
+
transform(html) {
|
|
197
|
+
return html.replace(
|
|
198
|
+
/(\s*)(<script type="module"[^>]*?><\/script>)/,
|
|
199
|
+
`$1<script src="${base}dito.js"></script>$1$2`
|
|
211
200
|
)
|
|
212
|
-
return testModuleIdentifier(module, coreDependencies)
|
|
213
|
-
? 'core'
|
|
214
|
-
: 'vendor'
|
|
215
201
|
}
|
|
216
202
|
}
|
|
217
203
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
204
|
+
],
|
|
205
|
+
build: {
|
|
206
|
+
...(!development && {
|
|
207
|
+
outDir: this.getPath('dist'),
|
|
208
|
+
assetsDir: '.',
|
|
209
|
+
emptyOutDir: true,
|
|
210
|
+
chunkSizeWarningLimit: 1000,
|
|
211
|
+
rollupOptions: {
|
|
212
|
+
output: {
|
|
213
|
+
manualChunks(id) {
|
|
214
|
+
if (id.startsWith(views)) {
|
|
215
|
+
return 'views'
|
|
216
|
+
} else if (id.startsWith(cwd)) {
|
|
217
|
+
return 'common'
|
|
218
|
+
} else {
|
|
219
|
+
const module = id.match(
|
|
220
|
+
/node_modules\/((?:@[^/]*\/)?[^/$]*)/
|
|
221
|
+
)?.[1] || ''
|
|
222
|
+
return testModuleIdentifier(module, coreDependencies)
|
|
223
|
+
? 'core'
|
|
224
|
+
: 'vendor'
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
})
|
|
230
|
+
},
|
|
231
|
+
css: {
|
|
232
|
+
postcss: getPostCssConfig()
|
|
233
|
+
},
|
|
234
|
+
optimizeDeps: {
|
|
235
|
+
exclude: development ? ditoPackages : [],
|
|
236
|
+
include: [
|
|
237
|
+
...(
|
|
238
|
+
development
|
|
239
|
+
? // https://discuss.prosemirror.net/t/rangeerror-adding-different-instances-of-a-keyed-plugin-plugin/4242/13
|
|
240
|
+
[
|
|
241
|
+
'prosemirror-state',
|
|
242
|
+
'prosemirror-transform',
|
|
243
|
+
'prosemirror-model',
|
|
244
|
+
'prosemirror-view'
|
|
245
|
+
]
|
|
246
|
+
: ditoPackages
|
|
247
|
+
),
|
|
248
|
+
...nonEsmDependencies
|
|
249
|
+
]
|
|
250
|
+
},
|
|
251
|
+
resolve: {
|
|
252
|
+
extensions: ['.js', '.json', '.vue'],
|
|
253
|
+
preserveSymlinks: true,
|
|
254
|
+
alias: [
|
|
255
|
+
{
|
|
256
|
+
find: '@',
|
|
257
|
+
replacement: root
|
|
258
|
+
}
|
|
234
259
|
]
|
|
235
|
-
: ditoPackages
|
|
236
|
-
),
|
|
237
|
-
...nonEsmDependencies
|
|
238
|
-
]
|
|
239
|
-
},
|
|
240
|
-
resolve: {
|
|
241
|
-
extensions: ['.js', '.json', '.vue'],
|
|
242
|
-
preserveSymlinks: true,
|
|
243
|
-
alias: [
|
|
244
|
-
{
|
|
245
|
-
find: '@',
|
|
246
|
-
replacement: root
|
|
247
260
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
261
|
+
},
|
|
262
|
+
config
|
|
263
|
+
)
|
|
264
|
+
)
|
|
251
265
|
}
|
|
252
266
|
}
|
|
253
267
|
|