@architect/inventory 3.2.0-RC.0 → 3.2.1
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/changelog.md +20 -0
- package/package.json +1 -1
- package/src/config/pragmas/plugins.js +19 -15
- package/src/config/pragmas/populate-lambda/index.js +21 -6
- package/src/config/pragmas/populate-other/index.js +13 -13
- package/src/config/pragmas/shared.js +26 -14
- package/src/config/pragmas/static.js +8 -6
- package/src/config/pragmas/validate/_lib.js +13 -4
- package/src/config/pragmas/validate/_shared.js +5 -6
- package/src/config/pragmas/validate/_static.js +40 -0
- package/src/config/pragmas/validate/index.js +1 -0
- package/src/config/pragmas/views.js +27 -15
package/changelog.md
CHANGED
|
@@ -2,17 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
+
## [3.2.1] 2022-08-10
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- By default, when a `set.shared|views` plugin sets a `src` path, if it is not present on the filesystem, Inventory falls back to default paths (e.g. `src/shared|views`)
|
|
10
|
+
- `set.shared|views` plugins now accept a `required` flag to enforce a validation error should a `src` path conflict with the project manifest (or not be found on the filesystem)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- Fixed an obscure internal reference passing bug in `set.proxy|shared|static|views` plugins
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
5
19
|
## [3.2.0] 2022-07-24
|
|
6
20
|
|
|
7
21
|
### Added
|
|
8
22
|
|
|
9
23
|
- Added support for new setter plugin APIs, specifically: `@proxy`, `@shared`, `@static`, `@tables`, `@tables-indexes`, `@views`
|
|
24
|
+
- Added new `@static` setting: `compression`
|
|
10
25
|
|
|
11
26
|
|
|
12
27
|
### Changed
|
|
13
28
|
|
|
29
|
+
- Lambdas defined in the userland Architect project manifest now override conflicting Lambdas returned by plugins (instead of throwing validation errors); fixes #1352
|
|
30
|
+
- Plugin developers can now use a `required` flag to enforce a validation error should their plugin conflict with userland Lambdas
|
|
14
31
|
- `@tables` and `@tables-indexes` can now accept lower case key types (e.g. `*string` instead of `*String`)
|
|
15
32
|
- `@tables` and `@tables-indexes` can also accept `*` and `**` as a shortcut for string-type primary and sort keys
|
|
33
|
+
- Changed plugin function property tags from `plugin|type` to `_plugin|_type` to indicate internal property namespacing
|
|
34
|
+
- Added `@static` pragma validation
|
|
35
|
+
- Fixed obscure case where `@static` `ignore` setting might only use the first list item
|
|
16
36
|
|
|
17
37
|
|
|
18
38
|
### Fixed
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@ let { is, normalizeSrc, pragmas, tidyError, validationPatterns } = require('../.
|
|
|
4
4
|
let { lambdas } = pragmas
|
|
5
5
|
let nonLambdaSetters = [ 'customLambdas', 'env', 'proxy', 'runtimes', 'shared', 'static', 'views', 'tables', 'tables-indexes' ]
|
|
6
6
|
let setters = [ ...lambdas, ...nonLambdaSetters ]
|
|
7
|
-
let pluginMethods = [ 'deploy', 'sandbox' ]
|
|
7
|
+
let pluginMethods = [ 'deploy', 'sandbox' ]
|
|
8
8
|
let reservedNames = [ '_methods' ]
|
|
9
9
|
|
|
10
10
|
module.exports = function getPluginModules ({ arc, inventory, errors }) {
|
|
@@ -67,8 +67,8 @@ module.exports = function getPluginModules ({ arc, inventory, errors }) {
|
|
|
67
67
|
return
|
|
68
68
|
}
|
|
69
69
|
if (!methods.set[setter]) methods.set[setter] = []
|
|
70
|
-
fn.
|
|
71
|
-
fn.
|
|
70
|
+
fn._plugin = name
|
|
71
|
+
fn._type = type
|
|
72
72
|
methods.set[setter].push(fn)
|
|
73
73
|
}
|
|
74
74
|
})
|
|
@@ -83,8 +83,8 @@ module.exports = function getPluginModules ({ arc, inventory, errors }) {
|
|
|
83
83
|
}
|
|
84
84
|
if (!methods[method]) methods[method] = {}
|
|
85
85
|
if (!methods[method][hook]) methods[method][hook] = []
|
|
86
|
-
fn.
|
|
87
|
-
fn.
|
|
86
|
+
fn._plugin = name
|
|
87
|
+
fn._type = type
|
|
88
88
|
methods[method][hook].push(fn)
|
|
89
89
|
})
|
|
90
90
|
}
|
|
@@ -101,14 +101,18 @@ module.exports = function getPluginModules ({ arc, inventory, errors }) {
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
function getPath (cwd, srcDir, name) {
|
|
104
|
-
let
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
else if (existsSync(
|
|
112
|
-
|
|
113
|
-
|
|
104
|
+
let path1 = join(cwd, 'src', srcDir, `${name}.js`)
|
|
105
|
+
let path2 = join(cwd, 'src', srcDir, name)
|
|
106
|
+
let path3 = join(cwd, 'node_modules', name)
|
|
107
|
+
let path4 = join(cwd, 'node_modules', `@${name}`)
|
|
108
|
+
/**/ if (existsSync(path1)) return path1
|
|
109
|
+
else if (existsSync(path2)) return path2
|
|
110
|
+
else if (existsSync(path3)) return path3
|
|
111
|
+
else if (existsSync(path4)) return path4
|
|
112
|
+
try {
|
|
113
|
+
return require.resolve(name)
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return
|
|
117
|
+
}
|
|
114
118
|
}
|
|
@@ -25,26 +25,26 @@ function populateLambda (type, params) {
|
|
|
25
25
|
var result = fn({ arc: invCopy._project.arc, inventory: { inv: invCopy } })
|
|
26
26
|
}
|
|
27
27
|
catch (err) {
|
|
28
|
-
err.message = `Setter plugin exception: plugin: ${fn.
|
|
28
|
+
err.message = `Setter plugin exception: plugin: ${fn._plugin}, method: set.${type}`
|
|
29
29
|
+ `\n` + err.message
|
|
30
30
|
throw err
|
|
31
31
|
}
|
|
32
32
|
if (!result ||
|
|
33
33
|
(!is.object(result) && !is.array(result)) ||
|
|
34
34
|
(is.array(result) && result.some(r => !is.object(r)))) {
|
|
35
|
-
errors.push(`Setter plugins must return a valid response: plugin: ${fn.
|
|
35
|
+
errors.push(`Setter plugins must return a valid response: plugin: ${fn._plugin}, method: set.${type}`)
|
|
36
36
|
return []
|
|
37
37
|
}
|
|
38
38
|
if (is.array(result)) {
|
|
39
39
|
result.forEach((item, i) => {
|
|
40
|
-
item.
|
|
41
|
-
item.
|
|
40
|
+
item._plugin = fn._plugin
|
|
41
|
+
item._type = fn._type
|
|
42
42
|
result[i] = item
|
|
43
43
|
})
|
|
44
44
|
}
|
|
45
45
|
else {
|
|
46
|
-
result.
|
|
47
|
-
result.
|
|
46
|
+
result._plugin = fn._plugin
|
|
47
|
+
result._type = fn._type
|
|
48
48
|
}
|
|
49
49
|
return result
|
|
50
50
|
})
|
|
@@ -53,6 +53,15 @@ function populateLambda (type, params) {
|
|
|
53
53
|
|
|
54
54
|
let pragmaLambda = populate(type, pragma || arc[type], inventory, errors) || []
|
|
55
55
|
let aggregate = [ ...pluginLambda, ...pragmaLambda ]
|
|
56
|
+
|
|
57
|
+
// Filter plugins, if appropriate: not required, but do conflict with a manifest entry
|
|
58
|
+
aggregate = aggregate.filter(lambda => {
|
|
59
|
+
if (lambda._plugin && !lambda.required &&
|
|
60
|
+
aggregate.some(({ name, _plugin }) => !_plugin && name === lambda.name)) {
|
|
61
|
+
return false
|
|
62
|
+
}
|
|
63
|
+
return true
|
|
64
|
+
})
|
|
56
65
|
return aggregate.length ? aggregate : null
|
|
57
66
|
}
|
|
58
67
|
|
|
@@ -136,6 +145,12 @@ function populate (type, pragma, inventory, errors, plugin) {
|
|
|
136
145
|
// Final tidying of any undefined properties
|
|
137
146
|
Object.keys(lambda).forEach(k => !is.defined(lambda[k]) && delete lambda[k])
|
|
138
147
|
|
|
148
|
+
// Pass through the plugin tag and required status
|
|
149
|
+
if (item._plugin) {
|
|
150
|
+
lambda._plugin = item._plugin
|
|
151
|
+
if (item.required === true) lambda.required = true
|
|
152
|
+
}
|
|
153
|
+
|
|
139
154
|
lambdas.push(lambda)
|
|
140
155
|
}
|
|
141
156
|
|
|
@@ -14,28 +14,28 @@ function resources (params) {
|
|
|
14
14
|
var result = fn({ arc: invCopy._project.arc, inventory: { inv: invCopy } })
|
|
15
15
|
}
|
|
16
16
|
catch (err) {
|
|
17
|
-
err.message = `Setter plugin exception: plugin: ${fn.
|
|
17
|
+
err.message = `Setter plugin exception: plugin: ${fn._plugin}, method: set.${type}`
|
|
18
18
|
+ `\n` + err.message
|
|
19
19
|
throw err
|
|
20
20
|
}
|
|
21
21
|
if (!result ||
|
|
22
22
|
(!is.object(result) && !is.array(result)) ||
|
|
23
23
|
(is.array(result) && result.some(r => !is.object(r)))) {
|
|
24
|
-
errors.push(`Setter plugins must return a valid response: plugin: ${fn.
|
|
24
|
+
errors.push(`Setter plugins must return a valid response: plugin: ${fn._plugin}, method: set.${type}`)
|
|
25
25
|
return []
|
|
26
26
|
}
|
|
27
27
|
if (is.array(result)) {
|
|
28
28
|
result.forEach((item, i) => {
|
|
29
29
|
item = populateTemplate(template, item)
|
|
30
|
-
item.
|
|
31
|
-
item.
|
|
30
|
+
item._plugin = fn._plugin
|
|
31
|
+
item._type = fn._type
|
|
32
32
|
result[i] = item
|
|
33
33
|
})
|
|
34
34
|
}
|
|
35
35
|
else {
|
|
36
36
|
result = populateTemplate(template, result)
|
|
37
|
-
result.
|
|
38
|
-
result.
|
|
37
|
+
result._plugin = fn._plugin
|
|
38
|
+
result._type = fn._type
|
|
39
39
|
}
|
|
40
40
|
return result
|
|
41
41
|
})
|
|
@@ -75,27 +75,27 @@ function validate (item, valid, type) {
|
|
|
75
75
|
*/
|
|
76
76
|
function settings (params) {
|
|
77
77
|
let { errors, settings, plugins, inventory, type, valid } = params
|
|
78
|
+
let newSettings = is.defined(settings) ? JSON.parse(JSON.stringify(settings)) : settings
|
|
78
79
|
if (plugins) {
|
|
79
80
|
let invCopy = deepFrozenCopy(inventory)
|
|
80
|
-
let pluginSettings = settings
|
|
81
81
|
let foundError = false
|
|
82
82
|
plugins.forEach(fn => {
|
|
83
83
|
try {
|
|
84
84
|
var result = fn({ arc: invCopy._project.arc, inventory: { inv: invCopy } })
|
|
85
85
|
}
|
|
86
86
|
catch (err) {
|
|
87
|
-
err.message = `Setter plugin exception: plugin: ${fn.
|
|
87
|
+
err.message = `Setter plugin exception: plugin: ${fn._plugin}, method: set.${type}`
|
|
88
88
|
+ `\n` + err.message
|
|
89
89
|
throw err
|
|
90
90
|
}
|
|
91
91
|
if (!result || !is.object(result)) {
|
|
92
|
-
errors.push(`Setter plugins must return a valid response: plugin: ${fn.
|
|
92
|
+
errors.push(`Setter plugins must return a valid response: plugin: ${fn._plugin}, method: set.${type}`)
|
|
93
93
|
foundError = true
|
|
94
94
|
}
|
|
95
95
|
else {
|
|
96
96
|
Object.entries(result).forEach(([ setting, value ]) => {
|
|
97
97
|
if (is.defined(settings[setting]) && is.defined(value)) {
|
|
98
|
-
|
|
98
|
+
newSettings[setting] = value
|
|
99
99
|
}
|
|
100
100
|
})
|
|
101
101
|
}
|
|
@@ -103,15 +103,15 @@ function settings (params) {
|
|
|
103
103
|
if (foundError) return null
|
|
104
104
|
|
|
105
105
|
// Validation pass
|
|
106
|
-
let validationErrors = validate(
|
|
106
|
+
let validationErrors = validate(newSettings, valid, type)
|
|
107
107
|
if (validationErrors.length) {
|
|
108
108
|
errors = errors.push(...validationErrors)
|
|
109
109
|
return null
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
return
|
|
112
|
+
return newSettings
|
|
113
113
|
}
|
|
114
|
-
return
|
|
114
|
+
return newSettings
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
module.exports = { resources, settings }
|
|
@@ -14,10 +14,10 @@ module.exports = function configureShared ({ arc, pragmas, inventory, errors })
|
|
|
14
14
|
shared: []
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
let
|
|
17
|
+
let foundPluginSrc, foundArcSrc, required = false
|
|
18
18
|
let pluginSrc = populate.settings({
|
|
19
19
|
errors,
|
|
20
|
-
settings: shared,
|
|
20
|
+
settings: { ...shared, required: null },
|
|
21
21
|
plugins: inventory.plugins?._methods?.set?.shared,
|
|
22
22
|
inventory,
|
|
23
23
|
type: 'shared',
|
|
@@ -27,33 +27,45 @@ module.exports = function configureShared ({ arc, pragmas, inventory, errors })
|
|
|
27
27
|
// Lambda paths have not yet been reified in Inventory
|
|
28
28
|
if (is.string(pluginSrc?.src)) {
|
|
29
29
|
shared.src = pluginSrc.src
|
|
30
|
-
|
|
30
|
+
required = pluginSrc.required
|
|
31
|
+
foundPluginSrc = true
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
// First pass to get + check shared folder (if any)
|
|
34
35
|
if (arc?.shared?.length) {
|
|
35
36
|
for (let share of arc.shared) {
|
|
36
|
-
if (is.array(share)) {
|
|
37
|
-
|
|
38
|
-
if (key === 'src' && is.string(share[1])) {
|
|
37
|
+
if (is.array(share) && share[0]?.toLowerCase() === 'src') {
|
|
38
|
+
if (is.string(share[1])) {
|
|
39
39
|
shared.src = share[1]
|
|
40
|
-
|
|
40
|
+
foundArcSrc = true
|
|
41
|
+
if (required) errors.push(`@shared src setting conflicts with plugin`)
|
|
41
42
|
continue
|
|
42
43
|
}
|
|
43
|
-
|
|
44
|
-
errors.push(`@shared invalid setting: ${key}`)
|
|
45
|
-
}
|
|
44
|
+
else errors.push(`@shared invalid setting: src`)
|
|
46
45
|
}
|
|
47
46
|
}
|
|
48
47
|
}
|
|
49
48
|
|
|
50
|
-
if
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
// Source path selection + validation: manifest always wins; validate plugins differently if required; if not, fall back to `src/shared` (or null)
|
|
50
|
+
if (foundArcSrc) {
|
|
51
|
+
validate.shared(shared.src, cwd, errors, true)
|
|
52
|
+
}
|
|
53
|
+
else if (foundPluginSrc) {
|
|
54
|
+
if (!required) {
|
|
55
|
+
if (!is.exists(shared.src)) shared.src = src
|
|
56
|
+
if (!is.exists(shared.src)) return null
|
|
57
|
+
}
|
|
58
|
+
validate.shared(shared.src, cwd, errors, required)
|
|
59
|
+
}
|
|
60
|
+
else if (is.exists(src)) {
|
|
61
|
+
shared.src = src
|
|
62
|
+
validate.shared(shared.src, cwd, errors, false)
|
|
63
|
+
}
|
|
53
64
|
// Exit if configured shared folder doesn't exist
|
|
54
|
-
|
|
65
|
+
else return null
|
|
55
66
|
|
|
56
67
|
// Proceeding from here resets all shared config, so make sure it's only if specific shared are specified
|
|
68
|
+
let foundSrcSetting = foundArcSrc || foundPluginSrc
|
|
57
69
|
let some = arc.shared?.length && !(arc?.shared?.length === 1 && foundSrcSetting)
|
|
58
70
|
if (some) {
|
|
59
71
|
// Reset shared settings
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
let populate = require('./populate-other')
|
|
2
2
|
let { asapSrc, is } = require('../../lib')
|
|
3
|
+
let validate = require('./validate')
|
|
3
4
|
|
|
4
5
|
module.exports = function configureStatic ({ arc, inventory, errors }) {
|
|
5
6
|
let staticSetters = inventory.plugins?._methods?.set?.static
|
|
@@ -10,6 +11,7 @@ module.exports = function configureStatic ({ arc, inventory, errors }) {
|
|
|
10
11
|
|
|
11
12
|
let staticPragma = arc.static || []
|
|
12
13
|
let _static = {
|
|
14
|
+
compression: false, // Arc applied default
|
|
13
15
|
fingerprint: null,
|
|
14
16
|
folder: 'public', // Arc applied default
|
|
15
17
|
ignore: null,
|
|
@@ -35,16 +37,14 @@ module.exports = function configureStatic ({ arc, inventory, errors }) {
|
|
|
35
37
|
})
|
|
36
38
|
|
|
37
39
|
let settings = Object.entries(_static).map(([ setting ]) => setting)
|
|
40
|
+
let validSetting = key => settings.includes(key)
|
|
38
41
|
for (let setting of staticPragma) {
|
|
39
|
-
|
|
42
|
+
// The ignore setting can come in a couple shapes, so we have to handle those
|
|
40
43
|
if (setting.ignore) {
|
|
41
44
|
_static.ignore = setting.ignore
|
|
42
45
|
}
|
|
43
|
-
else if (is.array(setting) &&
|
|
44
|
-
|
|
45
|
-
validSetting(setting[0])) {
|
|
46
|
-
let isIgnore = setting[0] === 'ignore'
|
|
47
|
-
_static[setting[0]] = isIgnore ? [ setting[1] ] : setting[1]
|
|
46
|
+
else if (is.array(setting) && validSetting(setting[0])) {
|
|
47
|
+
_static[setting[0]] = setting[0] === 'ignore' ? [ ...setting.slice(1) ] : setting[1]
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
@@ -54,5 +54,7 @@ module.exports = function configureStatic ({ arc, inventory, errors }) {
|
|
|
54
54
|
inventory._project.asapSrc = asapSrc()
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
validate.static(_static, errors)
|
|
58
|
+
|
|
57
59
|
return _static
|
|
58
60
|
}
|
|
@@ -22,10 +22,19 @@ function size (value, min, max, pragmaName, errors) {
|
|
|
22
22
|
|
|
23
23
|
function unique (lambdas, pragmaName, errors) {
|
|
24
24
|
if (!is.array(lambdas)) throw ReferenceError(`Invalid Lambda array: ${lambdas}`)
|
|
25
|
-
let names = []
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (names.includes(name) && !
|
|
25
|
+
let names = [] // List of names we've looked at
|
|
26
|
+
let namesErrored = [] // List of any offending names
|
|
27
|
+
if (lambdas.length) lambdas.forEach(({ name, pragma }) => {
|
|
28
|
+
if (names.includes(name) && !namesErrored.includes(name)) {
|
|
29
|
+
let err = `Duplicate ${pragmaName} item: ${name}`
|
|
30
|
+
|
|
31
|
+
// If we find a plugin Lambda, that means the filter let it through because it's required by the plugin, so we must now error
|
|
32
|
+
let foundPlugin = lambdas.find(l => l._plugin && l.name === name)
|
|
33
|
+
if (foundPlugin) err = `Plugin requires conflicting ${pragmaName} item: ${name}, plugin: ${foundPlugin._plugin}, method: set.${pragma}`
|
|
34
|
+
|
|
35
|
+
namesErrored.push(name)
|
|
36
|
+
errors.push(err)
|
|
37
|
+
}
|
|
29
38
|
names.push(name)
|
|
30
39
|
})
|
|
31
40
|
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
let { join, resolve, sep } = require('path')
|
|
2
2
|
let { is } = require('../../../lib')
|
|
3
3
|
|
|
4
|
-
module.exports = function validateShared (src, cwd, errors) {
|
|
5
|
-
let path = src
|
|
4
|
+
module.exports = function validateShared (src, cwd, errors, required) {
|
|
5
|
+
let path = src?.startsWith(cwd) ? src : resolve(join(cwd, src))
|
|
6
6
|
|
|
7
|
-
if (
|
|
8
|
-
else if (!is.
|
|
7
|
+
if (is.exists(path) && !is.folder(path)) errors.push(`Must be a directory: ${src}`)
|
|
8
|
+
else if (!is.exists(path) && required) errors.push(`Directory not found: ${src}`)
|
|
9
9
|
|
|
10
|
-
let valid = path && path.
|
|
11
|
-
(cwd.split(sep) < path.split(sep))
|
|
10
|
+
let valid = path?.startsWith(cwd) && (cwd.split(sep) < path.split(sep))
|
|
12
11
|
if (!valid) errors.push(`Directory must be a subfolder of this project: ${src}`)
|
|
13
12
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
let { is } = require('../../../lib')
|
|
2
|
+
|
|
3
|
+
module.exports = function validateStatic (_static, errors) {
|
|
4
|
+
// `folder` validation happens elsewhere
|
|
5
|
+
let {
|
|
6
|
+
compression,
|
|
7
|
+
fingerprint,
|
|
8
|
+
ignore,
|
|
9
|
+
prefix,
|
|
10
|
+
prune,
|
|
11
|
+
spa,
|
|
12
|
+
staging,
|
|
13
|
+
production,
|
|
14
|
+
} = _static
|
|
15
|
+
|
|
16
|
+
if (compression && ![ true, 'br', 'gzip' ].includes(compression)) {
|
|
17
|
+
errors.push(`Compression must be 'br' or 'gzip'`)
|
|
18
|
+
}
|
|
19
|
+
if (fingerprint && ![ true, 'external' ].includes(fingerprint)) {
|
|
20
|
+
errors.push(`Fingerprint must be true or 'external'`)
|
|
21
|
+
}
|
|
22
|
+
if (ignore && (!is.array(ignore) || !ignore.every(i => is.string(i)))) {
|
|
23
|
+
errors.push(`Ignore must be a list of one or more strings`)
|
|
24
|
+
}
|
|
25
|
+
if (prefix && !is.string(prefix)) {
|
|
26
|
+
errors.push(`Prefix must be a string`)
|
|
27
|
+
}
|
|
28
|
+
if (!is.nullish(prune) && !is.bool(prune)) {
|
|
29
|
+
errors.push(`Prune must be a boolean`)
|
|
30
|
+
}
|
|
31
|
+
if (!is.nullish(spa) && !is.bool(spa)) {
|
|
32
|
+
errors.push(`spa must be a string`)
|
|
33
|
+
}
|
|
34
|
+
if (!is.nullish(staging) && !is.string(staging)) {
|
|
35
|
+
errors.push(`Staging must be a string`)
|
|
36
|
+
}
|
|
37
|
+
if (!is.nullish(production) && !is.string(production)) {
|
|
38
|
+
errors.push(`Production must be a string`)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -8,6 +8,7 @@ module.exports = {
|
|
|
8
8
|
queues: require('./_events'), // Same ruleset as @events
|
|
9
9
|
scheduled: require('./_scheduled'),
|
|
10
10
|
shared: require('./_shared'), // Also includes @views
|
|
11
|
+
static: require('./_static'),
|
|
11
12
|
tables: require('./_tables'),
|
|
12
13
|
tablesIndexes: require('./_tables'), // Same ruleset as @tables (more or less)
|
|
13
14
|
tablesStreams: require('./_tables-streams'),
|
|
@@ -18,10 +18,10 @@ module.exports = function configureViews ({ arc, pragmas, inventory, errors }) {
|
|
|
18
18
|
views: []
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
let
|
|
21
|
+
let foundPluginSrc, foundArcSrc, required = false
|
|
22
22
|
let pluginSrc = populate.settings({
|
|
23
23
|
errors,
|
|
24
|
-
settings: views,
|
|
24
|
+
settings: { ...views, required: null },
|
|
25
25
|
plugins: inventory.plugins?._methods?.set?.views,
|
|
26
26
|
inventory,
|
|
27
27
|
type: 'views',
|
|
@@ -31,33 +31,45 @@ module.exports = function configureViews ({ arc, pragmas, inventory, errors }) {
|
|
|
31
31
|
// Lambda paths have not yet been reified in Inventory
|
|
32
32
|
if (is.string(pluginSrc?.src)) {
|
|
33
33
|
views.src = pluginSrc.src
|
|
34
|
-
|
|
34
|
+
required = pluginSrc.required
|
|
35
|
+
foundPluginSrc = true
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
// First pass to get + check views folder (if any)
|
|
38
39
|
if (arc?.views?.length) {
|
|
39
40
|
for (let view of arc.views) {
|
|
40
|
-
if (is.array(view)) {
|
|
41
|
-
|
|
42
|
-
if (key === 'src' && is.string(view[1])) {
|
|
41
|
+
if (is.array(view) && view[0]?.toLowerCase() === 'src') {
|
|
42
|
+
if (is.string(view[1])) {
|
|
43
43
|
views.src = view[1]
|
|
44
|
-
|
|
44
|
+
foundArcSrc = true
|
|
45
|
+
if (required) errors.push(`@views src setting conflicts with plugin`)
|
|
45
46
|
continue
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
-
errors.push(`@shared invalid setting: ${key}`)
|
|
49
|
-
}
|
|
48
|
+
else errors.push(`@views invalid setting: src`)
|
|
50
49
|
}
|
|
51
50
|
}
|
|
52
51
|
}
|
|
53
52
|
|
|
54
|
-
if
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (
|
|
53
|
+
// Source path selection + validation: manifest always wins; validate plugins differently if required; if not, fall back to `src/shared` (or null)
|
|
54
|
+
if (foundArcSrc) {
|
|
55
|
+
validate.shared(views.src, cwd, errors, true)
|
|
56
|
+
}
|
|
57
|
+
else if (foundPluginSrc) {
|
|
58
|
+
if (!required) {
|
|
59
|
+
if (!is.exists(views.src)) views.src = src
|
|
60
|
+
if (!is.exists(views.src)) return null
|
|
61
|
+
}
|
|
62
|
+
validate.shared(views.src, cwd, errors, required)
|
|
63
|
+
}
|
|
64
|
+
else if (is.exists(src)) {
|
|
65
|
+
views.src = src
|
|
66
|
+
validate.shared(views.src, cwd, errors, false)
|
|
67
|
+
}
|
|
68
|
+
// Exit if configured shared folder doesn't exist
|
|
69
|
+
else return null
|
|
59
70
|
|
|
60
71
|
// Proceeding from here resets all views config, so make sure it's only if specific views are specified
|
|
72
|
+
let foundSrcSetting = foundArcSrc || foundPluginSrc
|
|
61
73
|
let some = arc.views?.length && !(arc?.views?.length === 1 && foundSrcSetting)
|
|
62
74
|
if (some) {
|
|
63
75
|
// Reset views settings
|