@architect/inventory 3.0.0-RC.6 → 3.0.0-RC.7
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 +5 -0
- package/package.json +2 -2
- package/src/config/pragmas/plugins.js +5 -1
- package/src/config/pragmas/populate-lambda/index.js +37 -7
- package/src/config/pragmas/static.js +4 -2
- package/src/config/pragmas/validate/_lib.js +3 -10
- package/src/config/pragmas/views.js +2 -2
- package/src/config/project/index.js +1 -1
- package/src/config/project/plugins/env.js +46 -9
- package/src/config/project/plugins/runtimes.js +42 -32
- package/src/defaults/index.js +3 -3
- package/src/lib/index.js +8 -0
- package/src/validate/index.js +16 -9
- package/src/validate/paths.js +17 -0
package/changelog.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@architect/inventory",
|
|
3
|
-
"version": "3.0.0-RC.
|
|
3
|
+
"version": "3.0.0-RC.7",
|
|
4
4
|
"description": "Architect project resource enumeration utility",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"eslintConfig": {
|
|
43
43
|
"extends": "@architect/eslint-config"
|
|
44
44
|
},
|
|
45
|
-
"
|
|
45
|
+
"nyc": {
|
|
46
46
|
"check-coverage": true,
|
|
47
47
|
"branches": 100,
|
|
48
48
|
"lines": 100,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
let { join } = require('path')
|
|
2
2
|
let { existsSync } = require('fs')
|
|
3
|
-
let { is, normalizeSrc, pragmas } = require('../../lib')
|
|
3
|
+
let { is, normalizeSrc, pragmas, validationPatterns } = require('../../lib')
|
|
4
4
|
let { lambdas } = pragmas
|
|
5
5
|
let nonLambdaSetters = [ 'customLambdas', 'env', 'runtimes' ]
|
|
6
6
|
let setters = [ ...lambdas, ...nonLambdaSetters ]
|
|
@@ -37,6 +37,10 @@ module.exports = function getPluginModules ({ arc, inventory, errors }) {
|
|
|
37
37
|
errors.push('Plugin name _methods is reserved, please rename your plugin')
|
|
38
38
|
continue
|
|
39
39
|
}
|
|
40
|
+
if (!validationPatterns.veryLooseName.test(name)) {
|
|
41
|
+
errors.push('Plugin names can only contain [a-zA-Z0-9/\\-._]')
|
|
42
|
+
continue
|
|
43
|
+
}
|
|
40
44
|
if (pluginPath) {
|
|
41
45
|
try {
|
|
42
46
|
if (type === 'plugin') {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
let { sep } = require('path')
|
|
1
2
|
let read = require('../../../read')
|
|
2
3
|
let getLambda = require('./get-lambda')
|
|
3
4
|
let getRuntime = require('./get-runtime')
|
|
@@ -9,22 +10,44 @@ let { compiledRuntimes, is } = require('../../../lib')
|
|
|
9
10
|
/**
|
|
10
11
|
* Build out the Lambda tree from the Arc manifest or a passed pragma, and plugins
|
|
11
12
|
*/
|
|
12
|
-
function populateLambda (type,
|
|
13
|
+
function populateLambda (type, params) {
|
|
14
|
+
// Passing a pragma array via params allows special overrides
|
|
15
|
+
// See: @tables populating inv['tables-streams']
|
|
16
|
+
let { arc, inventory, errors, pragma } = params
|
|
17
|
+
|
|
13
18
|
let plugins = inventory.plugins?._methods?.set?.[type]
|
|
14
19
|
let pluginLambda = []
|
|
15
20
|
if (plugins) {
|
|
16
21
|
let pluginResults = plugins.flatMap(fn => {
|
|
17
|
-
|
|
18
|
-
|
|
22
|
+
try {
|
|
23
|
+
var result = fn({ arc, inventory: { inv: inventory } })
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
err.message = `Setter plugin exception: plugin: ${fn.plugin}, method: set.${type}`
|
|
27
|
+
+ `\n` + err.message
|
|
28
|
+
throw err
|
|
29
|
+
}
|
|
30
|
+
if (!result ||
|
|
31
|
+
(!is.object(result) && !is.array(result)) ||
|
|
32
|
+
(is.array(result) && result.some(r => !is.object(r)))) {
|
|
19
33
|
errors.push(`Setter plugins must return a valid response: plugin: ${fn.plugin}, method: set.${type}`)
|
|
20
34
|
return []
|
|
21
35
|
}
|
|
22
|
-
result
|
|
23
|
-
|
|
36
|
+
if (is.array(result)) {
|
|
37
|
+
result.forEach(item => {
|
|
38
|
+
item.plugin = fn.plugin
|
|
39
|
+
item.type = fn.type
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
result.plugin = fn.plugin
|
|
44
|
+
result.type = fn.type
|
|
45
|
+
}
|
|
24
46
|
return result
|
|
25
47
|
})
|
|
26
48
|
pluginLambda = populate(type, pluginResults, inventory, errors, true) || []
|
|
27
49
|
}
|
|
50
|
+
|
|
28
51
|
let pragmaLambda = populate(type, pragma || arc[type], inventory, errors) || []
|
|
29
52
|
let aggregate = [ ...pluginLambda, ...pragmaLambda ]
|
|
30
53
|
return aggregate.length ? aggregate : null
|
|
@@ -46,6 +69,11 @@ function populate (type, pragma, inventory, errors, plugin) {
|
|
|
46
69
|
if (!result) continue
|
|
47
70
|
|
|
48
71
|
let { name, src, build } = result
|
|
72
|
+
|
|
73
|
+
// Normalize paths, especially since plugin authors may not use path.join
|
|
74
|
+
src = normalize(src)
|
|
75
|
+
if (build) build = normalize(build)
|
|
76
|
+
|
|
49
77
|
// Set up fresh config, then overlay plugin config
|
|
50
78
|
let config = defaultProjectConfig()
|
|
51
79
|
config = { ...config, ...getKnownProps(configProps, result.config) }
|
|
@@ -82,7 +110,7 @@ function populate (type, pragma, inventory, errors, plugin) {
|
|
|
82
110
|
|
|
83
111
|
// Tidy up any irrelevant properties
|
|
84
112
|
if (!compiledRuntimes.includes(config.runtimeConfig?.type)) {
|
|
85
|
-
//
|
|
113
|
+
// Super important! If we don't clean up the build prop, many explosions will explode
|
|
86
114
|
build = undefined
|
|
87
115
|
}
|
|
88
116
|
if (type !== 'http') {
|
|
@@ -111,8 +139,10 @@ function populate (type, pragma, inventory, errors, plugin) {
|
|
|
111
139
|
return lambdas
|
|
112
140
|
}
|
|
113
141
|
|
|
142
|
+
let normalize = path => path.replace(/[\\\/]/g, sep)
|
|
143
|
+
|
|
114
144
|
// Lambda setter plugins can technically return anything, so this ensures everything is tidy
|
|
115
|
-
let lambdaProps = [ 'cron', 'method', 'path', 'plugin', 'rate', 'route', 'table' ]
|
|
145
|
+
let lambdaProps = [ 'cron', 'method', 'path', 'plugin', 'rate', 'route', 'table', 'type' ]
|
|
116
146
|
let configProps = [ ...Object.keys(defaultFunctionConfig()), 'fifo', 'views' ]
|
|
117
147
|
let getKnownProps = (knownProps, raw = {}) => {
|
|
118
148
|
let props = knownProps.flatMap(prop => is.defined(raw[prop]) ? [ [ prop, raw[prop] ] ] : [])
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
let { asapSrc, is } = require('../../lib')
|
|
2
2
|
|
|
3
3
|
module.exports = function configureStatic ({ arc, inventory }) {
|
|
4
|
+
let httpSetters = inventory.plugins?._methods?.set?.http
|
|
5
|
+
|
|
4
6
|
// @static is inferred by @http
|
|
5
|
-
if (!arc.static && !arc.http) return null
|
|
7
|
+
if (!arc.static && !arc.http && !httpSetters) return null
|
|
6
8
|
|
|
7
9
|
let staticPragma = arc.static || []
|
|
8
10
|
let _static = {
|
|
@@ -37,7 +39,7 @@ module.exports = function configureStatic ({ arc, inventory }) {
|
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
// Handy shortcut to ASAP for bare @static
|
|
40
|
-
if (!arc.http) {
|
|
42
|
+
if (!arc.http && !httpSetters) {
|
|
41
43
|
inventory._project.rootHandler = 'arcStaticAssetProxy'
|
|
42
44
|
inventory._project.asapSrc = asapSrc()
|
|
43
45
|
}
|
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
let { is } = require('../../../lib')
|
|
2
|
-
|
|
3
|
-
let patterns = {
|
|
4
|
-
looseName: new RegExp(/^[a-z][a-zA-Z0-9-_]+$/),
|
|
5
|
-
strictName: new RegExp(/^[a-z][a-z0-9-]+$/),
|
|
6
|
-
// DynamoDB, SNS, SQS
|
|
7
|
-
veryLooseName: new RegExp(/^[a-zA-Z0-9/\-._]*$/),
|
|
8
|
-
}
|
|
1
|
+
let { is, validationPatterns } = require('../../../lib')
|
|
9
2
|
|
|
10
3
|
function regex (value, pattern, pragmaName, errors) {
|
|
11
|
-
if (!
|
|
12
|
-
if (!
|
|
4
|
+
if (!validationPatterns[pattern]) throw ReferenceError(`Invalid validation pattern specified: ${pattern}`)
|
|
5
|
+
if (!validationPatterns[pattern].test(value)) errors.push(`Invalid ${pragmaName} item: '${value}' must match ${validationPatterns[pattern]}`)
|
|
13
6
|
}
|
|
14
7
|
|
|
15
8
|
function size (value, min, max, pragmaName, errors) {
|
|
@@ -48,8 +48,8 @@ module.exports = function configureViews ({ arc, pragmas, inventory, errors }) {
|
|
|
48
48
|
|
|
49
49
|
// Set new views settings
|
|
50
50
|
for (let view of arc.views) {
|
|
51
|
-
let method = view[0]
|
|
52
|
-
let path = view[1]
|
|
51
|
+
let method = view?.[0]?.toLowerCase()
|
|
52
|
+
let path = view?.[1]
|
|
53
53
|
if (method === 'src') continue
|
|
54
54
|
let name = `${method} ${path}`
|
|
55
55
|
let route = pragmas.http.find(n => n.name === name)
|
|
@@ -68,7 +68,7 @@ module.exports = function getProjectConfig (params) {
|
|
|
68
68
|
})
|
|
69
69
|
|
|
70
70
|
let { build, runtimes } = plugins.runtimes(params, _project)
|
|
71
|
-
if (build)
|
|
71
|
+
if (build) _project.build = join(_project.cwd, build)
|
|
72
72
|
if (runtimes) _project.customRuntimes = runtimes
|
|
73
73
|
}
|
|
74
74
|
|
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
let { is } = require('../../../lib')
|
|
2
|
+
let envs = [ 'testing', 'staging', 'production' ]
|
|
3
|
+
let str = value => {
|
|
4
|
+
if (is.object(value) || is.array(value)) return JSON.stringify(value)
|
|
5
|
+
return String(value)
|
|
6
|
+
}
|
|
2
7
|
|
|
3
8
|
module.exports = function setEnvPlugins (params, project) {
|
|
4
9
|
let { errors, inventory } = params
|
|
5
10
|
let envPlugins = inventory.plugins?._methods?.set?.env
|
|
6
11
|
if (envPlugins?.length) {
|
|
7
|
-
let env = {
|
|
12
|
+
let env = {
|
|
13
|
+
testing: null,
|
|
14
|
+
staging: null,
|
|
15
|
+
production: null,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// IEEE 1003.1-2001 does not allow lowercase, so consider this a compromise for the Windows folks in the house
|
|
19
|
+
let validName = /^[a-zA-Z0-9_]+$/
|
|
8
20
|
|
|
9
21
|
// inventory._project is not yet built, so provide as much as we can to plugins for now
|
|
10
22
|
let inv = { ...inventory, _project: project }
|
|
@@ -15,19 +27,44 @@ module.exports = function setEnvPlugins (params, project) {
|
|
|
15
27
|
if (!is.object(result) || !Object.keys(result).length) {
|
|
16
28
|
return errors.push(`Env plugin returned invalid data, must return an Object with one or more keys + values: ${errType}`)
|
|
17
29
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
30
|
+
// Populate env vars based on environment
|
|
31
|
+
// If any keys are environment names, disregard all keys except environment names
|
|
32
|
+
if (Object.keys(result).some(k => envs.includes(k))) {
|
|
33
|
+
envs.forEach(e => {
|
|
34
|
+
if (result[e]) Object.entries(result[e]).forEach(([ k, v ]) => {
|
|
35
|
+
let errored = false, val = str(v)
|
|
36
|
+
if (!env[e]) env[e] = { [k]: val }
|
|
37
|
+
else if (env[e][k] && !errored) {
|
|
38
|
+
errored = true
|
|
39
|
+
errors.push(`Env var '${k}' already registered: ${errType}`)
|
|
40
|
+
}
|
|
41
|
+
else env[e][k] = val
|
|
42
|
+
})
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
// Populate all environments based on env var
|
|
46
|
+
else {
|
|
47
|
+
Object.entries(result).forEach(([ k, v ]) => {
|
|
48
|
+
if (!validName.test(k)) {
|
|
49
|
+
return errors.push(`Env var '${k}' is invalid, must be [a-zA-Z0-9_]`)
|
|
50
|
+
}
|
|
51
|
+
let errored = false, val = str(v)
|
|
52
|
+
envs.forEach(e => {
|
|
53
|
+
if (!env[e]) env[e] = { [k]: val }
|
|
54
|
+
else if (env[e][k] && !errored) {
|
|
55
|
+
errored = true
|
|
56
|
+
errors.push(`Env var '${k}' already registered: ${errType}`)
|
|
57
|
+
}
|
|
58
|
+
else env[e][k] = val
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
}
|
|
25
62
|
}
|
|
26
63
|
catch (err) {
|
|
27
64
|
errors.push(`Runtime plugin '${fn.plugin}' failed: ${err.message}`)
|
|
28
65
|
}
|
|
29
66
|
})
|
|
30
|
-
return
|
|
67
|
+
return env
|
|
31
68
|
}
|
|
32
69
|
return inventory._project.env.plugins
|
|
33
70
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
let { is } = require('../../../lib')
|
|
1
|
+
let { is, validationPatterns } = require('../../../lib')
|
|
2
2
|
let { aliases, runtimeList } = require('lambda-runtimes')
|
|
3
|
+
let { looserName } = validationPatterns
|
|
3
4
|
let allRuntimes = runtimeList.concat([ 'deno', ...Object.keys(aliases) ])
|
|
5
|
+
let validTypes = [ 'transpiled', 'compiled', 'interpreted' ]
|
|
6
|
+
let builtTypes = validTypes.filter(t => t !== 'interpreted')
|
|
4
7
|
|
|
5
8
|
module.exports = function setRuntimePlugins (params, project) {
|
|
6
9
|
let { errors, inventory } = params
|
|
@@ -15,40 +18,47 @@ module.exports = function setRuntimePlugins (params, project) {
|
|
|
15
18
|
runtimePlugins.forEach(fn => {
|
|
16
19
|
let errType = `plugin: ${fn.plugin}, method: set.runtimes`
|
|
17
20
|
try {
|
|
18
|
-
|
|
19
|
-
result = is.array(result) ? result : [ result ]
|
|
20
|
-
result.forEach(runtime => {
|
|
21
|
-
// TODO add more validation
|
|
22
|
-
let { name } = runtime
|
|
23
|
-
if (!name) {
|
|
24
|
-
let msg = `Runtime plugin must provide a name: ${errType}`
|
|
25
|
-
return errors.push(msg)
|
|
26
|
-
}
|
|
27
|
-
if (allRuntimes.includes(name)) {
|
|
28
|
-
let msg = `Runtime name '${name}' is reserved: ${errType}`
|
|
29
|
-
return errors.push(msg)
|
|
30
|
-
}
|
|
31
|
-
if (runtimes[name]) {
|
|
32
|
-
let msg = `Runtime '${name}' already registered: ${errType}`
|
|
33
|
-
return errors.push(msg)
|
|
34
|
-
}
|
|
35
|
-
if (runtime.build) {
|
|
36
|
-
if (build && build !== runtime.build) {
|
|
37
|
-
errors.push(`Runtime '${name}' cannot set a build directory, as it is already configured to: ${build}`)
|
|
38
|
-
}
|
|
39
|
-
else if (is.bool(runtime.build) ||
|
|
40
|
-
!is.string(runtime.build)) {
|
|
41
|
-
build = 'build'
|
|
42
|
-
}
|
|
43
|
-
else build = runtime.build
|
|
44
|
-
}
|
|
45
|
-
runtimes.runtimes.push(name)
|
|
46
|
-
runtimes[name] = runtime
|
|
47
|
-
})
|
|
21
|
+
var result = fn({ inventory: { inv } })
|
|
48
22
|
}
|
|
49
23
|
catch (err) {
|
|
50
|
-
|
|
24
|
+
err.message = `Runtime plugin exception: ${errType}`
|
|
25
|
+
+ `\n` + err.message
|
|
26
|
+
throw err
|
|
51
27
|
}
|
|
28
|
+
// Accept one or more results, then loop through them
|
|
29
|
+
result = is.array(result) ? result : [ result ]
|
|
30
|
+
result.forEach(runtime => {
|
|
31
|
+
let { name, type, baseRuntime } = runtime
|
|
32
|
+
if (!name || !looserName.test(name)) {
|
|
33
|
+
let msg = `Runtime plugin must provide a valid name: ${errType}`
|
|
34
|
+
return errors.push(msg)
|
|
35
|
+
}
|
|
36
|
+
if (!type || !validTypes.includes(type)) {
|
|
37
|
+
let msg = `Runtime plugin must provide a valid type: ${errType}`
|
|
38
|
+
return errors.push(msg)
|
|
39
|
+
}
|
|
40
|
+
if (allRuntimes.includes(name)) {
|
|
41
|
+
let msg = `Runtime name '${name}' is reserved: ${errType}`
|
|
42
|
+
return errors.push(msg)
|
|
43
|
+
}
|
|
44
|
+
if (runtimes[name]) {
|
|
45
|
+
let msg = `Runtime name '${name}' already registered: ${errType}`
|
|
46
|
+
return errors.push(msg)
|
|
47
|
+
}
|
|
48
|
+
if (builtTypes.includes(type)) {
|
|
49
|
+
if (build && runtime.build && build !== runtime.build) {
|
|
50
|
+
return errors.push(`Runtime '${name}' cannot set a build directory, as it is already configured to: ${build}`)
|
|
51
|
+
}
|
|
52
|
+
// Adhere to Postel's Law
|
|
53
|
+
build = 'build'
|
|
54
|
+
if (is.string(runtime.build)) build = runtime.build
|
|
55
|
+
}
|
|
56
|
+
if (type === 'transpiled' && !allRuntimes.includes(baseRuntime)) {
|
|
57
|
+
return errors.push(`Runtime '${name}' must include a valid baseRuntime property corresponding to a valid Lambda runtime (e.g. 'nodejs14.x')`)
|
|
58
|
+
}
|
|
59
|
+
runtimes.runtimes.push(name)
|
|
60
|
+
runtimes[name] = runtime
|
|
61
|
+
})
|
|
52
62
|
})
|
|
53
63
|
return { build, runtimes }
|
|
54
64
|
}
|
package/src/defaults/index.js
CHANGED
|
@@ -33,9 +33,9 @@ module.exports = function inventoryDefaults (params = {}) {
|
|
|
33
33
|
defaultFunctionConfig, // Project-level function config
|
|
34
34
|
rootHandler: null, // null | configured | arcStaticAssetProxy | proxy
|
|
35
35
|
env: { // Env vars pulled from:
|
|
36
|
-
local: null, // Local/global prefs or .env
|
|
37
|
-
plugins: null, // Plugins
|
|
38
|
-
aws: null, // SSM
|
|
36
|
+
local: null, // - Local/global prefs or .env
|
|
37
|
+
plugins: null, // - Plugins
|
|
38
|
+
aws: null, // - SSM
|
|
39
39
|
},
|
|
40
40
|
customRuntimes: null, // Runtime plugins
|
|
41
41
|
arc: [], // Raw arc obj
|
package/src/lib/index.js
CHANGED
|
@@ -15,6 +15,13 @@ let compiledRuntimes = [ 'compiled', 'transpiled' ]
|
|
|
15
15
|
// `any` must come last for Sandbox route sorting purposes
|
|
16
16
|
let httpMethods = [ 'get', 'post', 'put', 'patch', 'delete', 'options', 'head', 'any' ]
|
|
17
17
|
|
|
18
|
+
let validationPatterns = {
|
|
19
|
+
strictName: /^[a-z][a-z0-9-]+$/,
|
|
20
|
+
looseName: /^[a-z][a-zA-Z0-9-_]+$/,
|
|
21
|
+
looserName: /^[a-z][a-zA-Z0-9-._]+$/,
|
|
22
|
+
veryLooseName: /^[a-zA-Z0-9/\-._]*$/,
|
|
23
|
+
}
|
|
24
|
+
|
|
18
25
|
module.exports = {
|
|
19
26
|
asapSrc,
|
|
20
27
|
compiledRuntimes,
|
|
@@ -25,4 +32,5 @@ module.exports = {
|
|
|
25
32
|
mergeEnvVars,
|
|
26
33
|
normalizeSrc: getLambdaDirs.normalizeSrc,
|
|
27
34
|
pragmas,
|
|
35
|
+
validationPatterns,
|
|
28
36
|
}
|
package/src/validate/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
let config = require('./config')
|
|
2
2
|
let layers = require('./layers')
|
|
3
3
|
let tablesChildren = require('./tables-children')
|
|
4
|
-
let
|
|
4
|
+
let paths = require('./paths')
|
|
5
|
+
let { errorFmt } = require('../lib')
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Final inventory validation
|
|
@@ -11,26 +12,32 @@ module.exports = function finalValidation (params, inventory) {
|
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Deal with vendor configuration errors
|
|
15
|
+
* - Analyze function configuration
|
|
16
|
+
* - Ensure layer configuration will work, AWS blows up with awful errors on this
|
|
17
|
+
* - TODO add deeper policy validation
|
|
14
18
|
*/
|
|
15
|
-
// Analyze function configuration
|
|
16
19
|
config(params, inventory, errors)
|
|
17
|
-
|
|
18
|
-
// Ensure layer configuration will work, AWS blows up with awful errors on this
|
|
19
20
|
layers(params, inventory, errors)
|
|
20
|
-
|
|
21
|
-
// TODO add deeper policy validation here
|
|
22
|
-
|
|
23
21
|
if (errors.length) {
|
|
24
22
|
return errorFmt({ type: 'configuration', errors })
|
|
25
23
|
}
|
|
26
24
|
|
|
27
25
|
/**
|
|
28
26
|
* Deal with project validation errors
|
|
27
|
+
* - Ensure @tables children (@tables-streams, @tables-indexes) have parent tables present
|
|
29
28
|
*/
|
|
30
|
-
// Ensure @tables children (@tables-streams, @tables-indexes) have parent tables present
|
|
31
29
|
tablesChildren(inventory, errors)
|
|
32
|
-
|
|
33
30
|
if (errors.length) {
|
|
34
31
|
return errorFmt({ type: 'validation', errors })
|
|
35
32
|
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* File path validation
|
|
36
|
+
* - Ensure all file paths are ascii
|
|
37
|
+
*/
|
|
38
|
+
paths(inventory, errors)
|
|
39
|
+
if (errors.length) {
|
|
40
|
+
return errorFmt({ type: 'file path', errors })
|
|
41
|
+
}
|
|
42
|
+
|
|
36
43
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module.exports = function checkFilePaths (inventory, errors) {
|
|
2
|
+
let ascii = /^[ -~]+$/
|
|
3
|
+
let err = str => errors.push(`${str} path must contain only ascii characters`)
|
|
4
|
+
|
|
5
|
+
let { _project: proj } = inventory
|
|
6
|
+
if (!ascii.test(proj.cwd)) return err('Project file')
|
|
7
|
+
if (!ascii.test(proj.src)) return err('Project source')
|
|
8
|
+
if (proj.build && !ascii.test(proj.build)) return err('Build')
|
|
9
|
+
|
|
10
|
+
let lambdas = inventory.lambdasBySrcDir
|
|
11
|
+
if (lambdas){
|
|
12
|
+
Object.values(lambdas).forEach(lambda => {
|
|
13
|
+
let { name, pragma, src } = lambda
|
|
14
|
+
if (!ascii.test(src)) err(`@${pragma} ${name} source`)
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
}
|