@architect/inventory 2.2.1-RC.0 → 3.0.0-RC.10
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 +54 -1
- package/package.json +12 -10
- package/readme.md +5 -4
- package/src/config/_upsert.js +1 -1
- package/src/config/arc.js +3 -3
- package/src/config/pragmas/app.js +1 -1
- package/src/config/pragmas/events.js +3 -2
- package/src/config/pragmas/http.js +5 -4
- package/src/config/pragmas/index.js +16 -5
- package/src/config/pragmas/meta/custom-lambdas.js +10 -0
- package/src/config/pragmas/{src-dirs.js → meta/src-dirs.js} +13 -10
- package/src/config/pragmas/plugins.js +109 -4
- package/src/config/pragmas/populate-lambda/_custom-lambdas.js +10 -0
- package/src/config/pragmas/populate-lambda/_events.js +17 -11
- package/src/config/pragmas/populate-lambda/_http.js +18 -10
- package/src/config/pragmas/populate-lambda/_scheduled.js +18 -10
- package/src/config/pragmas/populate-lambda/_tables-streams.js +20 -23
- package/src/config/pragmas/populate-lambda/_ws.js +26 -0
- package/src/config/pragmas/populate-lambda/get-handler.js +86 -13
- package/src/config/pragmas/populate-lambda/get-lambda.js +23 -0
- package/src/config/pragmas/populate-lambda/get-runtime.js +8 -7
- package/src/config/pragmas/populate-lambda/index.js +134 -84
- package/src/config/pragmas/queues.js +3 -2
- package/src/config/pragmas/scheduled.js +3 -2
- package/src/config/pragmas/shared.js +41 -44
- package/src/config/pragmas/sort/http.js +3 -2
- package/src/config/pragmas/static.js +5 -4
- package/src/config/pragmas/tables-indexes.js +3 -10
- package/src/config/pragmas/tables-streams.js +7 -5
- package/src/config/pragmas/tables.js +1 -1
- package/src/config/pragmas/validate/_events.js +1 -1
- package/src/config/pragmas/validate/_http.js +4 -4
- package/src/config/pragmas/validate/_lib.js +3 -10
- package/src/config/pragmas/validate/_scheduled.js +2 -2
- package/src/config/pragmas/validate/_shared.js +1 -1
- package/src/config/pragmas/validate/_tables-streams.js +6 -8
- package/src/config/pragmas/validate/_tables.js +2 -2
- package/src/config/pragmas/validate/index.js +2 -2
- package/src/config/pragmas/views.js +39 -37
- package/src/config/pragmas/ws.js +6 -4
- package/src/config/project/index.js +36 -20
- package/src/config/project/plugins/env.js +71 -0
- package/src/config/project/plugins/index.js +7 -0
- package/src/config/project/plugins/runtimes.js +67 -0
- package/src/config/project/prefs/dotenv.js +81 -0
- package/src/config/project/{prefs.js → prefs/index.js} +41 -22
- package/src/config/project/validate/index.js +15 -8
- package/src/defaults/index.js +20 -13
- package/src/env/index.js +76 -61
- package/src/get.js +1 -2
- package/src/index.js +17 -15
- package/src/lib/asap-src.js +3 -3
- package/src/lib/error-fmt.js +2 -10
- package/src/lib/get-lambda-dirs.js +37 -0
- package/src/lib/index.js +42 -0
- package/src/lib/is.js +3 -1
- package/src/lib/merge-env-vars.js +32 -0
- package/src/lib/pragmas.js +19 -3
- package/src/read/index.js +1 -3
- package/src/read/reader.js +2 -2
- package/src/validate/config.js +12 -6
- package/src/validate/index.js +17 -18
- package/src/validate/layers.js +2 -2
- package/src/validate/paths.js +17 -0
- package/src/validate/tables-children.js +5 -5
- package/src/config/pragmas/indexes.js +0 -19
- package/src/config/pragmas/macros.js +0 -5
- package/src/config/pragmas/populate-lambda/_plugins.js +0 -25
- package/src/config/pragmas/populate-lambda/_websockets.js +0 -19
- package/src/config/project/plugins.js +0 -31
- package/src/lib/http-methods.js +0 -2
|
@@ -1,30 +1,37 @@
|
|
|
1
|
-
let
|
|
2
|
-
let
|
|
3
|
-
let
|
|
1
|
+
let { join } = require('path')
|
|
2
|
+
let { existsSync, readFileSync } = require('fs')
|
|
3
|
+
let read = require('../../../read')
|
|
4
|
+
let validate = require('../validate')
|
|
5
|
+
let { is, validationPatterns: valid } = require('../../../lib')
|
|
6
|
+
let { parse } = require('./dotenv')
|
|
4
7
|
let { homedir } = require('os')
|
|
5
8
|
|
|
6
9
|
module.exports = function getPrefs ({ scope, inventory, errors }) {
|
|
7
10
|
let cwd = scope === 'global'
|
|
8
11
|
? homedir()
|
|
9
|
-
: inventory._project.
|
|
12
|
+
: inventory._project.cwd
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
let envFilepath = join(cwd, '.env')
|
|
15
|
+
let hasEnvFile = scope === 'local' && existsSync(envFilepath)
|
|
12
16
|
let prefs = read({ type: 'preferences', cwd, errors })
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
|
|
18
|
+
if (!prefs.filepath && !hasEnvFile) return null
|
|
19
|
+
|
|
20
|
+
let preferences = {}
|
|
21
|
+
|
|
22
|
+
// Populate Architect preferences
|
|
23
|
+
if (prefs.filepath && prefs.arc) {
|
|
15
24
|
// Ok, this gets a bit hairy
|
|
16
25
|
// Arc outputs an object of nested arrays
|
|
17
26
|
// Basically, construct a pared-down intermediate prefs obj for consumers
|
|
18
27
|
Object.entries(prefs.arc).forEach(([ key, val ]) => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
/* istanbul ignore else */ // Parser should get this, but jic
|
|
28
|
+
/* istanbul ignore else: Parser should get this, but jic */
|
|
22
29
|
if (!preferences[key]) preferences[key] = {}
|
|
23
|
-
/* istanbul ignore else
|
|
30
|
+
/* istanbul ignore else: Parser should only produce arrays, but jic */
|
|
24
31
|
if (is.array(val)) {
|
|
25
32
|
val.forEach(v => {
|
|
26
33
|
if (is.array(v)) {
|
|
27
|
-
/* istanbul ignore if
|
|
34
|
+
/* istanbul ignore if: Single vals should be strings, but jic */
|
|
28
35
|
if (v.length === 1) preferences[key] = v[0]
|
|
29
36
|
if (v.length === 2) preferences[key][v[0]] = v[1]
|
|
30
37
|
if (v.length > 2) preferences[key][v[0]] = [ ...v.slice(1) ]
|
|
@@ -39,35 +46,47 @@ module.exports = function getPrefs ({ scope, inventory, errors }) {
|
|
|
39
46
|
// Turn env vars with spaces into strings
|
|
40
47
|
if (key === 'env') {
|
|
41
48
|
[ 'testing', 'staging', 'production' ].forEach(e => {
|
|
42
|
-
/* istanbul ignore else
|
|
49
|
+
/* istanbul ignore else: Yet another jic */
|
|
43
50
|
if (preferences.env[e]) {
|
|
44
51
|
Object.entries(preferences.env[e]).forEach(([ key, val ]) => {
|
|
52
|
+
if (!valid.envVar.test(key)) {
|
|
53
|
+
errors.push(`Env var '${key}' is invalid, must be [a-zA-Z0-9_]`)
|
|
54
|
+
}
|
|
45
55
|
if (is.array(val)) preferences.env[e][key] = val.join(' ')
|
|
46
56
|
})
|
|
47
57
|
}
|
|
58
|
+
else preferences.env[e] = null
|
|
48
59
|
})
|
|
49
60
|
}
|
|
50
61
|
// Turn Sandbox scripts into commands
|
|
51
62
|
if (key === 'sandbox-startup') {
|
|
52
63
|
preferences[key] = val.map(v => {
|
|
53
64
|
if (is.string(v)) return v
|
|
54
|
-
/* istanbul ignore else
|
|
65
|
+
/* istanbul ignore else: Yet another jic */
|
|
55
66
|
if (is.array(v)) return v.join(' ')
|
|
56
67
|
})
|
|
57
68
|
}
|
|
58
69
|
})
|
|
59
70
|
|
|
60
71
|
validate(preferences, errors)
|
|
72
|
+
}
|
|
61
73
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
74
|
+
// Populate .env (testing environment only, disables other env vars)
|
|
75
|
+
if (hasEnvFile) {
|
|
76
|
+
let dotenv = parse(readFileSync(envFilepath))
|
|
77
|
+
preferences.env = {
|
|
78
|
+
testing: Object.keys(dotenv).length ? dotenv : null,
|
|
79
|
+
staging: null,
|
|
80
|
+
production: null,
|
|
69
81
|
}
|
|
70
82
|
}
|
|
71
83
|
|
|
72
|
-
return
|
|
84
|
+
return {
|
|
85
|
+
preferences: {
|
|
86
|
+
...preferences,
|
|
87
|
+
_arc: prefs.arc,
|
|
88
|
+
_raw: prefs.raw,
|
|
89
|
+
},
|
|
90
|
+
preferencesFile: prefs.filepath
|
|
91
|
+
}
|
|
73
92
|
}
|
|
@@ -1,13 +1,20 @@
|
|
|
1
|
-
let is = require('./../../../lib
|
|
1
|
+
let { is } = require('./../../../lib')
|
|
2
2
|
|
|
3
3
|
module.exports = function validatePreferences (preferences, errors) {
|
|
4
4
|
// Env checks
|
|
5
|
-
let { env } = preferences
|
|
6
|
-
if (!env) return
|
|
7
|
-
if (env && !is.object(env)) errors.push(`Invalid preferences setting: @env ${env}`)
|
|
8
|
-
|
|
5
|
+
let { env, sandbox } = preferences
|
|
9
6
|
let envs = [ 'testing', 'staging', 'production' ]
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
|
|
8
|
+
if (env && !is.object(env)) {
|
|
9
|
+
errors.push(`Invalid preferences setting: @env ${env}`)
|
|
10
|
+
}
|
|
11
|
+
else if (env) {
|
|
12
|
+
envs.forEach(e => {
|
|
13
|
+
if (env[e] && !is.object(env[e])) errors.push(`Invalid preferences setting: @env ${e}`)
|
|
14
|
+
})
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (sandbox?.env && !envs.includes(sandbox.env)) {
|
|
18
|
+
errors.push(`Invalid preferences setting: @sandbox env ${sandbox.env}`)
|
|
19
|
+
}
|
|
13
20
|
}
|
package/src/defaults/index.js
CHANGED
|
@@ -1,38 +1,45 @@
|
|
|
1
|
+
let { join } = require('path')
|
|
1
2
|
let fnConfig = require('./function-config')
|
|
2
|
-
let pragmas = require('../lib
|
|
3
|
+
let { pragmas } = require('../lib')
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Returns a default stub inventory object
|
|
6
7
|
* - Every possible officially supported value should be present
|
|
7
8
|
*/
|
|
8
9
|
module.exports = function inventoryDefaults (params = {}) {
|
|
9
|
-
let { cwd, region } = params
|
|
10
|
+
let { cwd = process.cwd(), deployStage = null, region } = params
|
|
10
11
|
// Allow region env var override
|
|
11
|
-
region = process.env.AWS_REGION ||
|
|
12
|
+
region = region || process.env.AWS_REGION || 'us-west-2'
|
|
12
13
|
let defaultFunctionConfig = fnConfig()
|
|
13
14
|
return {
|
|
14
15
|
// Meta
|
|
15
16
|
_arc: {
|
|
16
17
|
version: 'Unknown', // @architect/architect semver (if installed)
|
|
17
18
|
defaultFunctionConfig, // Architect's default function config
|
|
18
|
-
pragmas, // Registry of all
|
|
19
|
+
pragmas, // Registry of all, Lambda, reserved, retired pragmas
|
|
20
|
+
deployStage, // Deploy stage of the running project (if specified)
|
|
19
21
|
},
|
|
20
22
|
_project: {
|
|
21
23
|
type: 'aws',
|
|
22
|
-
|
|
24
|
+
cwd, // Project root dir
|
|
25
|
+
src: join(cwd, 'src'), // Default source tree dir
|
|
26
|
+
build: null, // Optional build artifact dir
|
|
23
27
|
manifest: null, // Root project manifest filename
|
|
24
|
-
|
|
25
|
-
preferences: null, // Realized preferences obj, resolved from global > local
|
|
28
|
+
preferences: null, // Realized preferences obj, resolved from local > global
|
|
26
29
|
localPreferences: null, // Local preferences obj
|
|
27
30
|
localPreferencesFile: null, // Local preferences file path
|
|
28
31
|
globalPreferences: null, // Global preferences obj
|
|
29
32
|
globalPreferencesFile: null, // Global preferences file path
|
|
30
33
|
defaultFunctionConfig, // Project-level function config
|
|
31
34
|
rootHandler: null, // null | configured | arcStaticAssetProxy | proxy
|
|
32
|
-
|
|
35
|
+
env: { // Env vars pulled from:
|
|
36
|
+
local: null, // - Local/global prefs or .env
|
|
37
|
+
plugins: null, // - Plugins
|
|
38
|
+
aws: null, // - SSM
|
|
39
|
+
},
|
|
40
|
+
customRuntimes: null, // Runtime plugins
|
|
33
41
|
arc: [], // Raw arc obj
|
|
34
42
|
raw: '', // Raw arc string
|
|
35
|
-
env: null, // Env vars pulled from SSM (if enabled)
|
|
36
43
|
},
|
|
37
44
|
// App + vendor config
|
|
38
45
|
app: '',
|
|
@@ -52,9 +59,7 @@ module.exports = function inventoryDefaults (params = {}) {
|
|
|
52
59
|
cdn: null,
|
|
53
60
|
events: null,
|
|
54
61
|
http: null,
|
|
55
|
-
|
|
56
|
-
macros: null,
|
|
57
|
-
plugins: null, // These are the Lambdas created by plugins, not the plugin modules, which are in _project.plugins
|
|
62
|
+
plugins: null,
|
|
58
63
|
proxy: null,
|
|
59
64
|
queues: null,
|
|
60
65
|
scheduled: null,
|
|
@@ -65,7 +70,9 @@ module.exports = function inventoryDefaults (params = {}) {
|
|
|
65
70
|
'tables-streams': null,
|
|
66
71
|
views: null,
|
|
67
72
|
ws: null,
|
|
68
|
-
//
|
|
73
|
+
// Unclassified / non-pragma custom Lambdas created by plugins
|
|
74
|
+
customLambdas: null,
|
|
75
|
+
// Collection of all Lambda source paths
|
|
69
76
|
lambdaSrcDirs: null,
|
|
70
77
|
// Lambda lookup by source directory
|
|
71
78
|
lambdasBySrcDir: null,
|
package/src/env/index.js
CHANGED
|
@@ -1,76 +1,91 @@
|
|
|
1
|
+
let { mergeEnvVars } = require('../lib')
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Read env vars out of SSM
|
|
3
5
|
*/
|
|
4
6
|
module.exports = function env (params, inventory, callback) {
|
|
5
|
-
if (params.env) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
// eslint-disable-next-line
|
|
9
|
-
var aws = require('aws-sdk')
|
|
10
|
-
}
|
|
11
|
-
catch (err) {
|
|
12
|
-
let msg = `'aws-sdk' not found, please install locally or globally (see also readme#aws-sdk-caveat)`
|
|
13
|
-
return callback(Error(msg))
|
|
14
|
-
}
|
|
15
|
-
let name = inventory.app
|
|
16
|
-
let { region } = inventory.aws
|
|
17
|
-
let ssm = new aws.SSM({ region })
|
|
18
|
-
let result = []
|
|
19
|
-
|
|
20
|
-
function getSomeEnvVars (name, NextToken, callback) {
|
|
21
|
-
// Base query to ssm
|
|
22
|
-
let query = {
|
|
23
|
-
Path: `/${name}`,
|
|
24
|
-
Recursive: true,
|
|
25
|
-
MaxResults: 10,
|
|
26
|
-
WithDecryption: true
|
|
27
|
-
}
|
|
7
|
+
if (!params.env) {
|
|
8
|
+
return callback()
|
|
9
|
+
}
|
|
28
10
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
11
|
+
/* istanbul ignore next */
|
|
12
|
+
try {
|
|
13
|
+
// eslint-disable-next-line
|
|
14
|
+
var aws = require('aws-sdk')
|
|
15
|
+
}
|
|
16
|
+
catch (err) {
|
|
17
|
+
let msg = `'aws-sdk' not found, please install locally or globally (see also readme#aws-sdk-caveat)`
|
|
18
|
+
return callback(Error(msg))
|
|
19
|
+
}
|
|
20
|
+
let name = inventory.app
|
|
21
|
+
let { region } = inventory.aws
|
|
22
|
+
let ssm = new aws.SSM({ region })
|
|
23
|
+
let result = []
|
|
32
24
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return {
|
|
41
|
-
app: name, // jic
|
|
42
|
-
env: bits[2],
|
|
43
|
-
name: bits[3],
|
|
44
|
-
value: param.Value,
|
|
45
|
-
}
|
|
46
|
-
}))
|
|
47
|
-
// Check for more data and, if so, recurse
|
|
48
|
-
/* istanbul ignore if */ // Sadly no way to easily mock this for testing
|
|
49
|
-
if (data.NextToken) {
|
|
50
|
-
getSomeEnvVars(name, data.NextToken, callback)
|
|
51
|
-
}
|
|
52
|
-
else callback(null, result)
|
|
53
|
-
}
|
|
54
|
-
})
|
|
25
|
+
function getSomeEnvVars (name, NextToken, callback) {
|
|
26
|
+
// Base query to ssm
|
|
27
|
+
let query = {
|
|
28
|
+
Path: `/${name}`,
|
|
29
|
+
Recursive: true,
|
|
30
|
+
MaxResults: 10,
|
|
31
|
+
WithDecryption: true
|
|
55
32
|
}
|
|
56
33
|
|
|
57
|
-
|
|
34
|
+
// Check if we're paginating
|
|
35
|
+
/* istanbul ignore if */
|
|
36
|
+
if (NextToken) query.NextToken = NextToken
|
|
37
|
+
|
|
38
|
+
// Perform the query
|
|
39
|
+
ssm.getParametersByPath(query, function _query (err, data) {
|
|
58
40
|
if (err) callback(err)
|
|
59
41
|
else {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
let
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
|
|
42
|
+
// Tidy up the response
|
|
43
|
+
result = result.concat(data.Parameters.map(function (param) {
|
|
44
|
+
let bits = param.Name.split('/')
|
|
45
|
+
return {
|
|
46
|
+
app: name, // jic
|
|
47
|
+
env: bits[2],
|
|
48
|
+
name: bits[3],
|
|
49
|
+
value: param.Value,
|
|
50
|
+
}
|
|
51
|
+
}))
|
|
52
|
+
// Check for more data and, if so, recurse
|
|
53
|
+
/* istanbul ignore if: Sadly no way to easily mock this for testing */
|
|
54
|
+
if (data.NextToken) {
|
|
55
|
+
getSomeEnvVars(name, data.NextToken, callback)
|
|
70
56
|
}
|
|
71
|
-
callback()
|
|
57
|
+
else callback(null, result)
|
|
72
58
|
}
|
|
73
59
|
})
|
|
74
60
|
}
|
|
75
|
-
|
|
61
|
+
|
|
62
|
+
getSomeEnvVars(name, false, function done (err, result) {
|
|
63
|
+
if (err) callback(err)
|
|
64
|
+
else {
|
|
65
|
+
let testing = null
|
|
66
|
+
let staging = null
|
|
67
|
+
let production = null
|
|
68
|
+
if (result.length) {
|
|
69
|
+
// TODO refactor into a reducer?
|
|
70
|
+
result.forEach(({ env, name: k, value: v }) => {
|
|
71
|
+
if (env === 'testing') testing = Object.assign({}, testing, { [k]: v })
|
|
72
|
+
if (env === 'staging') staging = Object.assign({}, staging, { [k]: v })
|
|
73
|
+
if (env === 'production') production = Object.assign({}, production, { [k]: v })
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
let errors = []
|
|
78
|
+
inventory._project.env.aws = mergeEnvVars({
|
|
79
|
+
env: 'Application',
|
|
80
|
+
source: inventory._project.env.plugins,
|
|
81
|
+
target: { testing, staging, production },
|
|
82
|
+
errors,
|
|
83
|
+
})
|
|
84
|
+
if (errors.length) {
|
|
85
|
+
callback(Error(errors[0]))
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
callback()
|
|
89
|
+
}
|
|
90
|
+
})
|
|
76
91
|
}
|
package/src/get.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
let is = require('./lib
|
|
1
|
+
let { is } = require('./lib')
|
|
2
2
|
|
|
3
3
|
module.exports = function _get (inventory) {
|
|
4
4
|
function getter (prag, name) {
|
|
@@ -38,5 +38,4 @@ module.exports = function _get (inventory) {
|
|
|
38
38
|
// These refer to other pragmas, and thus may allow multiple same/same-named entities
|
|
39
39
|
let multipleResults = [
|
|
40
40
|
'tables-indexes',
|
|
41
|
-
'indexes',
|
|
42
41
|
]
|
package/src/index.js
CHANGED
|
@@ -5,7 +5,7 @@ let config = require('./config')
|
|
|
5
5
|
let getEnv = require('./env')
|
|
6
6
|
let validate = require('./validate')
|
|
7
7
|
let get = require('./get')
|
|
8
|
-
let errorFmt = require('./lib
|
|
8
|
+
let { errorFmt } = require('./lib')
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Architect Inventory
|
|
@@ -50,10 +50,7 @@ module.exports = function architectInventory (params = {}, callback) {
|
|
|
50
50
|
|
|
51
51
|
// Exit early if supplied Arc is fundamentally broken
|
|
52
52
|
if (errors.length) {
|
|
53
|
-
callback(errorFmt({
|
|
54
|
-
type: 'manifest',
|
|
55
|
-
errors,
|
|
56
|
-
}))
|
|
53
|
+
callback(errorFmt({ type: 'manifest', errors }))
|
|
57
54
|
return promise
|
|
58
55
|
}
|
|
59
56
|
|
|
@@ -61,27 +58,32 @@ module.exports = function architectInventory (params = {}, callback) {
|
|
|
61
58
|
let inventory = inventoryDefaults(params)
|
|
62
59
|
|
|
63
60
|
// Set up project params for config
|
|
64
|
-
let project = {
|
|
61
|
+
let project = { arc, cwd, errors, filepath, inventory, raw }
|
|
65
62
|
|
|
66
63
|
// Populate inventory.arc
|
|
67
64
|
inventory._arc = config._arc(project)
|
|
68
65
|
|
|
66
|
+
// @plugins come first, as they register hooks all around the project
|
|
67
|
+
inventory.plugins = config.pragmas.plugins(project)
|
|
68
|
+
|
|
69
69
|
// Establish default function config from project + Arc defaults
|
|
70
|
-
inventory._project = config._project(project
|
|
70
|
+
inventory._project = config._project(project)
|
|
71
|
+
|
|
72
|
+
// End here if plugins failed
|
|
73
|
+
if (errors.length) {
|
|
74
|
+
callback(errorFmt({ type: 'plugin', errors }))
|
|
75
|
+
return promise
|
|
76
|
+
}
|
|
71
77
|
|
|
72
|
-
// Userland: fill out the pragmas
|
|
78
|
+
// Userland: fill out the pragmas, starting with @plugins
|
|
73
79
|
inventory = {
|
|
74
80
|
...inventory,
|
|
75
|
-
...config.pragmas(project
|
|
81
|
+
...config.pragmas(project)
|
|
76
82
|
}
|
|
77
83
|
|
|
78
|
-
// End here if first-pass
|
|
84
|
+
// End here if first-pass validation failed
|
|
79
85
|
if (errors.length) {
|
|
80
|
-
callback(errorFmt({
|
|
81
|
-
type: 'validation',
|
|
82
|
-
errors,
|
|
83
|
-
inventory,
|
|
84
|
-
}))
|
|
86
|
+
callback(errorFmt({ type: 'validation', errors }))
|
|
85
87
|
return promise
|
|
86
88
|
}
|
|
87
89
|
|
package/src/lib/asap-src.js
CHANGED
package/src/lib/error-fmt.js
CHANGED
|
@@ -1,26 +1,18 @@
|
|
|
1
|
-
let { basename } = require('path')
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* Common error formatter
|
|
5
3
|
*
|
|
6
4
|
* @param params {object}
|
|
7
5
|
* @param params.type {string} - Inventory error type: `manifest`, `validation`, or `configuration`
|
|
8
6
|
* @param params.errors {array} - Array of one or more errors to output
|
|
9
|
-
* @param params.meta {string} - Appends optional info to primary error message
|
|
10
7
|
* @param params.inventory {object} - Inventory object
|
|
11
8
|
*
|
|
12
9
|
* @returns Formatted Error + appended ARC_ERRORS property
|
|
13
10
|
*/
|
|
14
11
|
module.exports = function format (params) {
|
|
15
|
-
let { type, errors
|
|
16
|
-
if (!meta && type === 'validation') {
|
|
17
|
-
meta = inventory._project.manifest
|
|
18
|
-
? ` in ${basename(inventory._project.manifest)}`
|
|
19
|
-
: ''
|
|
20
|
-
}
|
|
12
|
+
let { type, errors } = params
|
|
21
13
|
let output = errors.map(err => `- ${err}`).join('\n')
|
|
22
14
|
let errType = type[0].toUpperCase() + type.substr(1)
|
|
23
|
-
let err = Error(`${errType} error${errors.length > 1 ? 's' : ''}
|
|
15
|
+
let err = Error(`${errType} error${errors.length > 1 ? 's' : ''}:\n${output}`)
|
|
24
16
|
err.ARC_ERRORS = { type, errors }
|
|
25
17
|
return err
|
|
26
18
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
let { isAbsolute, join } = require('path')
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Get the src (and build) dirs for a Lambda
|
|
5
|
+
* - Arc Lambdas: pass a name + pragma || relative file path
|
|
6
|
+
* - Plugin Lambdas: pass a relative file path || absolute file path
|
|
7
|
+
*/
|
|
8
|
+
function getLambdaDirs (params, options) {
|
|
9
|
+
let { cwd, item, projSrc, projBuild, type: pragma } = params
|
|
10
|
+
let { name, plugin, customSrc } = options
|
|
11
|
+
let lambdaDirs = {}
|
|
12
|
+
|
|
13
|
+
if (plugin) {
|
|
14
|
+
let src = normalizeSrc(cwd, item.src)
|
|
15
|
+
lambdaDirs.src = src
|
|
16
|
+
if (projBuild) {
|
|
17
|
+
lambdaDirs.build = src.replace(src, projBuild)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
let root = customSrc ? cwd : projSrc
|
|
22
|
+
let path = customSrc || join(pragma, name)
|
|
23
|
+
lambdaDirs.src = join(root, path)
|
|
24
|
+
if (projBuild) {
|
|
25
|
+
lambdaDirs.build = join(projBuild, path)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return lambdaDirs
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function normalizeSrc (cwd, dir) {
|
|
32
|
+
if (isAbsolute(dir)) return dir
|
|
33
|
+
return join(cwd, dir)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
getLambdaDirs.normalizeSrc = normalizeSrc
|
|
37
|
+
module.exports = getLambdaDirs
|
package/src/lib/index.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
let asapSrc = require('./asap-src')
|
|
2
|
+
let errorFmt = require('./error-fmt')
|
|
3
|
+
let getLambdaDirs = require('./get-lambda-dirs')
|
|
4
|
+
let is = require('./is')
|
|
5
|
+
let mergeEnvVars = require('./merge-env-vars')
|
|
6
|
+
let pragmas = require('./pragmas')
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Why take up a whole fs block when smol libs can just live here?
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// For setting `lambda.build`, compiled + transpiled are effectively the same
|
|
13
|
+
let compiledRuntimes = [ 'compiled', 'transpiled' ]
|
|
14
|
+
|
|
15
|
+
// `any` must come last for Sandbox route sorting purposes
|
|
16
|
+
let httpMethods = [ 'get', 'post', 'put', 'patch', 'delete', 'options', 'head', 'any' ]
|
|
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
|
+
// IEEE 1003.1-2001 does not allow lowercase, so consider this a compromise for the Windows folks in the house
|
|
24
|
+
envVar: /^[a-zA-Z0-9_]+$/,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Error tidier: remove the error name, just print the message + stack data
|
|
28
|
+
let tidyError = err => err.message + `\n` + err.stack.split('\n').slice(1).join('\n')
|
|
29
|
+
|
|
30
|
+
module.exports = {
|
|
31
|
+
asapSrc,
|
|
32
|
+
compiledRuntimes,
|
|
33
|
+
errorFmt,
|
|
34
|
+
getLambdaDirs,
|
|
35
|
+
httpMethods,
|
|
36
|
+
is,
|
|
37
|
+
mergeEnvVars,
|
|
38
|
+
normalizeSrc: getLambdaDirs.normalizeSrc,
|
|
39
|
+
pragmas,
|
|
40
|
+
tidyError,
|
|
41
|
+
validationPatterns,
|
|
42
|
+
}
|
package/src/lib/is.js
CHANGED
|
@@ -4,10 +4,12 @@ module.exports = {
|
|
|
4
4
|
// Types
|
|
5
5
|
array: item => Array.isArray(item),
|
|
6
6
|
bool: item => typeof item === 'boolean',
|
|
7
|
+
defined: item => typeof item !== 'undefined',
|
|
8
|
+
fn: item => typeof item === 'function',
|
|
9
|
+
nullish: item => typeof item === 'undefined' || item === null,
|
|
7
10
|
number: item => Number.isInteger(item),
|
|
8
11
|
object: item => typeof item === 'object' && !Array.isArray(item),
|
|
9
12
|
string: item => typeof item === 'string',
|
|
10
|
-
defined: item => typeof item !== 'undefined' && item !== null,
|
|
11
13
|
// Filesystem
|
|
12
14
|
exists: path => existsSync(path),
|
|
13
15
|
folder: path => existsSync(path) && lstatSync(path).isDirectory(),
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
let envs = [ 'testing', 'staging', 'production' ]
|
|
2
|
+
|
|
3
|
+
module.exports = function mergeEnvVars (params) {
|
|
4
|
+
let { name, source, target, errors } = params
|
|
5
|
+
if (source === null) return target
|
|
6
|
+
if (target === null) return source
|
|
7
|
+
let probs = []
|
|
8
|
+
|
|
9
|
+
// Deep copy to reset any potential refs
|
|
10
|
+
let merged = JSON.parse(JSON.stringify(target))
|
|
11
|
+
envs.forEach(env => {
|
|
12
|
+
if (!source[env]) return
|
|
13
|
+
Object.keys(source[env]).forEach(k => {
|
|
14
|
+
if (merged[env]?.[k]) {
|
|
15
|
+
probs.push(`'${env}' variable '${k}'`)
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
if (!merged[env]) merged[env] = {}
|
|
19
|
+
merged[env][k] = source[env][k]
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
if (probs.length) {
|
|
25
|
+
let s = probs.length > 1 ? 's' : ''
|
|
26
|
+
let msg = `${name} env var${s} conflicts with plugin:\n` +
|
|
27
|
+
`- ${probs.join('\n- ')}`
|
|
28
|
+
errors.push(msg)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return merged
|
|
32
|
+
}
|
package/src/lib/pragmas.js
CHANGED
|
@@ -6,8 +6,6 @@ module.exports = {
|
|
|
6
6
|
'cdn',
|
|
7
7
|
'events',
|
|
8
8
|
'http',
|
|
9
|
-
'indexes', // -> transitioning to @tables-indexes
|
|
10
|
-
'macros',
|
|
11
9
|
'plugins',
|
|
12
10
|
'proxy',
|
|
13
11
|
'queues',
|
|
@@ -24,10 +22,28 @@ module.exports = {
|
|
|
24
22
|
lambdas: [
|
|
25
23
|
'events',
|
|
26
24
|
'http',
|
|
27
|
-
'plugins',
|
|
28
25
|
'queues',
|
|
29
26
|
'scheduled',
|
|
30
27
|
'tables-streams',
|
|
31
28
|
'ws',
|
|
32
29
|
],
|
|
30
|
+
// Reserved pragma names that map to internal Inventory properties
|
|
31
|
+
reserved: [
|
|
32
|
+
'customLambdas',
|
|
33
|
+
],
|
|
34
|
+
// Retired pragmas no longer in active use
|
|
35
|
+
retired: [
|
|
36
|
+
'indexes',
|
|
37
|
+
'macros',
|
|
38
|
+
'slack',
|
|
39
|
+
'streams', // Never fully launched
|
|
40
|
+
// Static types
|
|
41
|
+
'css',
|
|
42
|
+
'html',
|
|
43
|
+
'js',
|
|
44
|
+
'json',
|
|
45
|
+
'jsonapi',
|
|
46
|
+
'text',
|
|
47
|
+
'xml',
|
|
48
|
+
]
|
|
33
49
|
}
|