@architect/inventory 3.0.0-RC.7 → 3.0.0-RC.8
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 +3 -0
- package/package.json +6 -6
- package/src/config/pragmas/plugins.js +3 -2
- package/src/config/pragmas/populate-lambda/index.js +3 -1
- package/src/config/project/plugins/env.js +8 -7
- package/src/config/project/plugins/runtimes.js +4 -3
- package/src/config/project/prefs/dotenv.js +24 -55
- package/src/config/project/prefs/index.js +5 -4
- package/src/lib/index.js +2 -0
package/changelog.md
CHANGED
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
- Breaking change: renamed `lambda.handlerFunction` to `lambda.handlerMethod`
|
|
38
38
|
- Breaking change: prioritize `mod.ts|js` handlers in Deno Lambdas
|
|
39
39
|
- Breaking change: removed `toml` support
|
|
40
|
+
- Breaking change: removed `get.macros` method; as `@macros` are now automatically mapped to the Architect plugins, you can simply use `get.plugins` instead
|
|
40
41
|
- Performance improvements to building `inv.shared` + `inv.views`
|
|
41
42
|
- Improved memory footprint of Inventory object by preserving references in `lambdaSrcDirs`, `lambdasBySrcDir`
|
|
42
43
|
- Added `pragma` property to all Lambdas to aid in reference preservation
|
|
@@ -48,6 +49,8 @@ Update CI
|
|
|
48
49
|
### Fixed
|
|
49
50
|
|
|
50
51
|
- Added file path validation because `aws-sdk` blows up on !ascii paths; fixes #1292, thanks @GustMartins!
|
|
52
|
+
- Fixed env var validation from preference files
|
|
53
|
+
- Fixed error bubbling when reading a preferences file with issues
|
|
51
54
|
|
|
52
55
|
---
|
|
53
56
|
|
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.8",
|
|
4
4
|
"description": "Architect project resource enumeration utility",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -23,21 +23,21 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@architect/asap": "~5.0.0-RC.0",
|
|
25
25
|
"@architect/parser": "~6.0.0-RC.0",
|
|
26
|
-
"@architect/utils": "~3.0.
|
|
26
|
+
"@architect/utils": "~3.1.0-RC.0",
|
|
27
27
|
"lambda-runtimes": "~1.1.1"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@architect/eslint-config": "~2.0.1",
|
|
31
31
|
"aws-sdk": "2.1001.0",
|
|
32
|
-
"aws-sdk-mock": "~5.6.
|
|
32
|
+
"aws-sdk-mock": "~5.6.2",
|
|
33
33
|
"cross-env": "~7.0.3",
|
|
34
|
-
"dotenv": "~
|
|
35
|
-
"eslint": "~8.
|
|
34
|
+
"dotenv": "~15.0.0",
|
|
35
|
+
"eslint": "~8.8.0",
|
|
36
36
|
"mock-fs": "~5.1.2",
|
|
37
37
|
"mock-require": "~3.0.3",
|
|
38
38
|
"nyc": "~15.1.0",
|
|
39
39
|
"tap-spec": "^5.0.0",
|
|
40
|
-
"tape": "^5.
|
|
40
|
+
"tape": "^5.5.0"
|
|
41
41
|
},
|
|
42
42
|
"eslintConfig": {
|
|
43
43
|
"extends": "@architect/eslint-config"
|
|
@@ -5,6 +5,7 @@ let { lambdas } = pragmas
|
|
|
5
5
|
let nonLambdaSetters = [ 'customLambdas', 'env', 'runtimes' ]
|
|
6
6
|
let setters = [ ...lambdas, ...nonLambdaSetters ]
|
|
7
7
|
let pluginMethods = [ 'deploy', 'sandbox' ] // TODO add more!
|
|
8
|
+
let reservedNames = [ '_methods', 'events', 'queues', 'static', 'tables' ]
|
|
8
9
|
|
|
9
10
|
module.exports = function getPluginModules ({ arc, inventory, errors }) {
|
|
10
11
|
if (!arc?.plugins?.length && !arc?.macros?.length) return null
|
|
@@ -33,8 +34,8 @@ module.exports = function getPluginModules ({ arc, inventory, errors }) {
|
|
|
33
34
|
: join(cwd, 'src', type + 's', name)
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
if (name
|
|
37
|
-
errors.push(
|
|
37
|
+
if (reservedNames.includes(name)) {
|
|
38
|
+
errors.push(`Plugin name ${name} is reserved, please rename your plugin`)
|
|
38
39
|
continue
|
|
39
40
|
}
|
|
40
41
|
if (!validationPatterns.veryLooseName.test(name)) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
let { sep } = require('path')
|
|
2
|
+
let { deepFrozenCopy } = require('@architect/utils')
|
|
2
3
|
let read = require('../../../read')
|
|
3
4
|
let getLambda = require('./get-lambda')
|
|
4
5
|
let getRuntime = require('./get-runtime')
|
|
@@ -18,9 +19,10 @@ function populateLambda (type, params) {
|
|
|
18
19
|
let plugins = inventory.plugins?._methods?.set?.[type]
|
|
19
20
|
let pluginLambda = []
|
|
20
21
|
if (plugins) {
|
|
22
|
+
let invCopy = deepFrozenCopy(inventory)
|
|
21
23
|
let pluginResults = plugins.flatMap(fn => {
|
|
22
24
|
try {
|
|
23
|
-
var result = fn({ arc, inventory: { inv:
|
|
25
|
+
var result = fn({ arc: invCopy._project.arc, inventory: { inv: invCopy } })
|
|
24
26
|
}
|
|
25
27
|
catch (err) {
|
|
26
28
|
err.message = `Setter plugin exception: plugin: ${fn.plugin}, method: set.${type}`
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
let {
|
|
1
|
+
let { deepFrozenCopy } = require('@architect/utils')
|
|
2
|
+
let { is, validationPatterns: valid } = require('../../../lib')
|
|
2
3
|
let envs = [ 'testing', 'staging', 'production' ]
|
|
3
4
|
let str = value => {
|
|
4
5
|
if (is.object(value) || is.array(value)) return JSON.stringify(value)
|
|
@@ -15,15 +16,12 @@ module.exports = function setEnvPlugins (params, project) {
|
|
|
15
16
|
production: null,
|
|
16
17
|
}
|
|
17
18
|
|
|
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_]+$/
|
|
20
|
-
|
|
21
19
|
// inventory._project is not yet built, so provide as much as we can to plugins for now
|
|
22
|
-
let inv = { ...inventory, _project: project }
|
|
20
|
+
let inv = deepFrozenCopy({ ...inventory, _project: project })
|
|
23
21
|
envPlugins.forEach(fn => {
|
|
24
22
|
let errType = `plugin: ${fn.plugin}, method: set.env`
|
|
25
23
|
try {
|
|
26
|
-
let result = fn({ inventory: { inv } })
|
|
24
|
+
let result = fn({ arc: inv._project.arc, inventory: { inv } })
|
|
27
25
|
if (!is.object(result) || !Object.keys(result).length) {
|
|
28
26
|
return errors.push(`Env plugin returned invalid data, must return an Object with one or more keys + values: ${errType}`)
|
|
29
27
|
}
|
|
@@ -32,6 +30,9 @@ module.exports = function setEnvPlugins (params, project) {
|
|
|
32
30
|
if (Object.keys(result).some(k => envs.includes(k))) {
|
|
33
31
|
envs.forEach(e => {
|
|
34
32
|
if (result[e]) Object.entries(result[e]).forEach(([ k, v ]) => {
|
|
33
|
+
if (!valid.envVar.test(k)) {
|
|
34
|
+
return errors.push(`Env var '${k}' is invalid, must be [a-zA-Z0-9_]`)
|
|
35
|
+
}
|
|
35
36
|
let errored = false, val = str(v)
|
|
36
37
|
if (!env[e]) env[e] = { [k]: val }
|
|
37
38
|
else if (env[e][k] && !errored) {
|
|
@@ -45,7 +46,7 @@ module.exports = function setEnvPlugins (params, project) {
|
|
|
45
46
|
// Populate all environments based on env var
|
|
46
47
|
else {
|
|
47
48
|
Object.entries(result).forEach(([ k, v ]) => {
|
|
48
|
-
if (!
|
|
49
|
+
if (!valid.envVar.test(k)) {
|
|
49
50
|
return errors.push(`Env var '${k}' is invalid, must be [a-zA-Z0-9_]`)
|
|
50
51
|
}
|
|
51
52
|
let errored = false, val = str(v)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
let { is, validationPatterns } = require('../../../lib')
|
|
2
1
|
let { aliases, runtimeList } = require('lambda-runtimes')
|
|
2
|
+
let { deepFrozenCopy } = require('@architect/utils')
|
|
3
|
+
let { is, validationPatterns } = require('../../../lib')
|
|
3
4
|
let { looserName } = validationPatterns
|
|
4
5
|
let allRuntimes = runtimeList.concat([ 'deno', ...Object.keys(aliases) ])
|
|
5
6
|
let validTypes = [ 'transpiled', 'compiled', 'interpreted' ]
|
|
@@ -13,12 +14,12 @@ module.exports = function setRuntimePlugins (params, project) {
|
|
|
13
14
|
runtimes: [],
|
|
14
15
|
}
|
|
15
16
|
// inventory._project is not yet built, so provide as much as we can to plugins for now
|
|
16
|
-
let inv = { ...inventory, _project: project }
|
|
17
|
+
let inv = deepFrozenCopy({ ...inventory, _project: project })
|
|
17
18
|
let build
|
|
18
19
|
runtimePlugins.forEach(fn => {
|
|
19
20
|
let errType = `plugin: ${fn.plugin}, method: set.runtimes`
|
|
20
21
|
try {
|
|
21
|
-
var result = fn({ inventory: { inv } })
|
|
22
|
+
var result = fn({ arc: inv._project.arc, inventory: { inv } })
|
|
22
23
|
}
|
|
23
24
|
catch (err) {
|
|
24
25
|
err.message = `Runtime plugin exception: ${errType}`
|
|
@@ -7,60 +7,30 @@
|
|
|
7
7
|
var fs = require("fs");
|
|
8
8
|
var path = require("path");
|
|
9
9
|
var os = require("os");
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
var NEWLINE = "\n";
|
|
14
|
-
var RE_INI_KEY_VAL = /^\s*([\w.-]+)\s*=\s*("[^"]*"|'[^']*'|.*?)(\s+#.*)?$/;
|
|
15
|
-
var RE_NEWLINES = /\\n/g;
|
|
16
|
-
var NEWLINES_MATCH = /\r\n|\n|\r/;
|
|
17
|
-
function parse(src, options) {
|
|
18
|
-
const debug = Boolean(options && options.debug);
|
|
19
|
-
const multiline = Boolean(options && options.multiline);
|
|
10
|
+
var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
|
|
11
|
+
function parse(src) {
|
|
20
12
|
const obj = {};
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (multiline && (isMultilineDoubleQuoted || isMultilineSingleQuoted)) {
|
|
34
|
-
const quoteChar = isMultilineDoubleQuoted ? '"' : "'";
|
|
35
|
-
val = val.substring(1);
|
|
36
|
-
while (idx++ < lines.length - 1) {
|
|
37
|
-
line = lines[idx];
|
|
38
|
-
end = line.length - 1;
|
|
39
|
-
if (line[end] === quoteChar) {
|
|
40
|
-
val += NEWLINE + line.substring(0, end);
|
|
41
|
-
break;
|
|
42
|
-
}
|
|
43
|
-
val += NEWLINE + line;
|
|
44
|
-
}
|
|
45
|
-
} else if (isSingleQuoted || isDoubleQuoted) {
|
|
46
|
-
val = val.substring(1, end);
|
|
47
|
-
if (isDoubleQuoted) {
|
|
48
|
-
val = val.replace(RE_NEWLINES, NEWLINE);
|
|
49
|
-
}
|
|
50
|
-
} else {
|
|
51
|
-
val = val.trim();
|
|
52
|
-
}
|
|
53
|
-
obj[key] = val;
|
|
54
|
-
} else if (debug) {
|
|
55
|
-
const trimmedLine = line.trim();
|
|
56
|
-
if (trimmedLine.length && trimmedLine[0] !== "#") {
|
|
57
|
-
log(`Failed to match key and value when parsing line ${idx + 1}: ${line}`);
|
|
58
|
-
}
|
|
13
|
+
let lines = src.toString();
|
|
14
|
+
lines = lines.replace(/\r\n?/mg, "\n");
|
|
15
|
+
let match;
|
|
16
|
+
while ((match = LINE.exec(lines)) != null) {
|
|
17
|
+
const key = match[1];
|
|
18
|
+
let value = match[2] || "";
|
|
19
|
+
value = value.trim();
|
|
20
|
+
const maybeQuote = value[0];
|
|
21
|
+
value = value.replace(/^(['"])([\s\S]+)\1$/mg, "$2");
|
|
22
|
+
if (maybeQuote === '"') {
|
|
23
|
+
value = value.replace(/\\n/g, "\n");
|
|
24
|
+
value = value.replace(/\\r/g, "\r");
|
|
59
25
|
}
|
|
26
|
+
obj[key] = value;
|
|
60
27
|
}
|
|
61
28
|
return obj;
|
|
62
29
|
}
|
|
63
|
-
function
|
|
30
|
+
function _log(message) {
|
|
31
|
+
console.log(`[dotenv][DEBUG] ${message}`);
|
|
32
|
+
}
|
|
33
|
+
function _resolveHome(envPath) {
|
|
64
34
|
return envPath[0] === "~" ? path.join(os.homedir(), envPath.slice(1)) : envPath;
|
|
65
35
|
}
|
|
66
36
|
function config(options) {
|
|
@@ -68,17 +38,16 @@ function config(options) {
|
|
|
68
38
|
let encoding = "utf8";
|
|
69
39
|
const debug = Boolean(options && options.debug);
|
|
70
40
|
const override = Boolean(options && options.override);
|
|
71
|
-
const multiline = Boolean(options && options.multiline);
|
|
72
41
|
if (options) {
|
|
73
42
|
if (options.path != null) {
|
|
74
|
-
dotenvPath =
|
|
43
|
+
dotenvPath = _resolveHome(options.path);
|
|
75
44
|
}
|
|
76
45
|
if (options.encoding != null) {
|
|
77
46
|
encoding = options.encoding;
|
|
78
47
|
}
|
|
79
48
|
}
|
|
80
49
|
try {
|
|
81
|
-
const parsed = DotenvModule.parse(fs.readFileSync(dotenvPath, { encoding })
|
|
50
|
+
const parsed = DotenvModule.parse(fs.readFileSync(dotenvPath, { encoding }));
|
|
82
51
|
Object.keys(parsed).forEach(function(key) {
|
|
83
52
|
if (!Object.prototype.hasOwnProperty.call(process.env, key)) {
|
|
84
53
|
process.env[key] = parsed[key];
|
|
@@ -88,9 +57,9 @@ function config(options) {
|
|
|
88
57
|
}
|
|
89
58
|
if (debug) {
|
|
90
59
|
if (override === true) {
|
|
91
|
-
|
|
60
|
+
_log(`"${key}" is already defined in \`process.env\` and WAS overwritten`);
|
|
92
61
|
} else {
|
|
93
|
-
|
|
62
|
+
_log(`"${key}" is already defined in \`process.env\` and was NOT overwritten`);
|
|
94
63
|
}
|
|
95
64
|
}
|
|
96
65
|
}
|
|
@@ -98,7 +67,7 @@ function config(options) {
|
|
|
98
67
|
return { parsed };
|
|
99
68
|
} catch (e) {
|
|
100
69
|
if (debug) {
|
|
101
|
-
|
|
70
|
+
_log(`Failed to load ${dotenvPath} ${e.message}`);
|
|
102
71
|
}
|
|
103
72
|
return { error: e };
|
|
104
73
|
}
|
|
@@ -2,7 +2,7 @@ let { join } = require('path')
|
|
|
2
2
|
let { existsSync, readFileSync } = require('fs')
|
|
3
3
|
let read = require('../../../read')
|
|
4
4
|
let validate = require('../validate')
|
|
5
|
-
let { is } = require('../../../lib')
|
|
5
|
+
let { is, validationPatterns: valid } = require('../../../lib')
|
|
6
6
|
let { parse } = require('./dotenv')
|
|
7
7
|
let { homedir } = require('os')
|
|
8
8
|
|
|
@@ -20,13 +20,11 @@ module.exports = function getPrefs ({ scope, inventory, errors }) {
|
|
|
20
20
|
let preferences = {}
|
|
21
21
|
|
|
22
22
|
// Populate Architect preferences
|
|
23
|
-
if (prefs.filepath) {
|
|
23
|
+
if (prefs.filepath && prefs.arc) {
|
|
24
24
|
// Ok, this gets a bit hairy
|
|
25
25
|
// Arc outputs an object of nested arrays
|
|
26
26
|
// Basically, construct a pared-down intermediate prefs obj for consumers
|
|
27
27
|
Object.entries(prefs.arc).forEach(([ key, val ]) => {
|
|
28
|
-
// TODO add additional preferences checks and normalization
|
|
29
|
-
|
|
30
28
|
/* istanbul ignore else: Parser should get this, but jic */
|
|
31
29
|
if (!preferences[key]) preferences[key] = {}
|
|
32
30
|
/* istanbul ignore else: Parser should only produce arrays, but jic */
|
|
@@ -51,6 +49,9 @@ module.exports = function getPrefs ({ scope, inventory, errors }) {
|
|
|
51
49
|
/* istanbul ignore else: Yet another jic */
|
|
52
50
|
if (preferences.env[e]) {
|
|
53
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
|
+
}
|
|
54
55
|
if (is.array(val)) preferences.env[e][key] = val.join(' ')
|
|
55
56
|
})
|
|
56
57
|
}
|
package/src/lib/index.js
CHANGED
|
@@ -20,6 +20,8 @@ let validationPatterns = {
|
|
|
20
20
|
looseName: /^[a-z][a-zA-Z0-9-_]+$/,
|
|
21
21
|
looserName: /^[a-z][a-zA-Z0-9-._]+$/,
|
|
22
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_]+$/,
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
module.exports = {
|