@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
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
let { is, getLambdaDirs } = require('../../../lib')
|
|
2
|
+
|
|
3
|
+
module.exports = function populateWebSockets (params) {
|
|
4
|
+
let { item, errors, plugin } = params
|
|
5
|
+
if (plugin) {
|
|
6
|
+
let { name, src } = item
|
|
7
|
+
if (name && src) {
|
|
8
|
+
return { ...item, route: name, ...getLambdaDirs(params, { plugin }) }
|
|
9
|
+
}
|
|
10
|
+
errors.push(`Invalid plugin-generated @ws item: name: ${name}, src: ${src}`)
|
|
11
|
+
return
|
|
12
|
+
}
|
|
13
|
+
else if (is.string(item)) {
|
|
14
|
+
let name = item
|
|
15
|
+
let route = name // Same as name, just what AWS calls it
|
|
16
|
+
let dirs = getLambdaDirs(params, { name })
|
|
17
|
+
return { name, route, ...dirs }
|
|
18
|
+
}
|
|
19
|
+
else if (is.object(item)) {
|
|
20
|
+
let name = Object.keys(item)[0]
|
|
21
|
+
let route = name
|
|
22
|
+
let dirs = getLambdaDirs(params, { name, customSrc: item[name].src })
|
|
23
|
+
return { name, route, ...dirs }
|
|
24
|
+
}
|
|
25
|
+
errors.push(`Invalid @ws item: ${item}`)
|
|
26
|
+
}
|
|
@@ -1,14 +1,87 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
let
|
|
6
|
-
|
|
7
|
-
if (
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
let
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
let { join } = require('path')
|
|
2
|
+
let { existsSync, readFileSync } = require('fs')
|
|
3
|
+
|
|
4
|
+
module.exports = function getHandler ({ config, src, build, errors }) {
|
|
5
|
+
let { handler, runtime, runtimeConfig } = config
|
|
6
|
+
let parts = handler.split('.') // Default is 'index.handler'
|
|
7
|
+
if (parts.length !== 2) {
|
|
8
|
+
errors.push(`Invalid handler: ${handler}. Expected {file}.{method}, example: index.handler`)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let { file, ext, handlerModuleSystem } = getExt({ runtime, src, errors })
|
|
12
|
+
file = file || parts[0] // Falls back to 'index'
|
|
13
|
+
ext = ext ? '.' + ext : ''
|
|
14
|
+
let handlerFile = join(src, `${file}${ext}`)
|
|
15
|
+
let handlerMethod = parts[1]
|
|
16
|
+
let customRuntimeType = runtimeConfig?.type
|
|
17
|
+
|
|
18
|
+
// Compiled to an interpreted runtime (eg TypeScript)
|
|
19
|
+
if (customRuntimeType === 'transpiled') {
|
|
20
|
+
handlerFile = join(build, runtimeConfig?.handlerFile || 'index.js')
|
|
21
|
+
}
|
|
22
|
+
// Compiled to a binary
|
|
23
|
+
else if (customRuntimeType === 'compiled') {
|
|
24
|
+
handlerFile = join(build, runtimeConfig.handlerFile || 'handler')
|
|
25
|
+
}
|
|
26
|
+
// Interpreted
|
|
27
|
+
else if (customRuntimeType === 'interpreted') {
|
|
28
|
+
handlerFile = join(src, runtimeConfig.handlerFile || 'index')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let handlerConfig = { handlerFile, handlerMethod, handlerModuleSystem }
|
|
32
|
+
return handlerConfig
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let nodeHandlers = [ 'index.js', 'index.mjs', 'index.cjs' ]
|
|
36
|
+
let denoHandlers = [ 'mod.ts', 'mod.js' ]
|
|
37
|
+
// TODO: these are all prob going away
|
|
38
|
+
.concat([ 'mod.tsx', 'index.ts', 'index.js', 'index.tsx' ])
|
|
39
|
+
|
|
40
|
+
function getExt ({ runtime, src, errors }) {
|
|
41
|
+
try {
|
|
42
|
+
if (runtime.startsWith('node')) {
|
|
43
|
+
if (runtime === 'nodejs12.x') {
|
|
44
|
+
return { ext: 'js', handlerModuleSystem: 'cjs' }
|
|
45
|
+
}
|
|
46
|
+
// This presumes Node.js 14.x+ Lambda releases use the same CJS/ESM pattern
|
|
47
|
+
else {
|
|
48
|
+
let { file, ext = 'js' } = findHandler(nodeHandlers, src)
|
|
49
|
+
let handlerModuleSystem = ext === 'mjs' ? 'esm' : 'cjs'
|
|
50
|
+
let pkgFile = join(src, 'package.json')
|
|
51
|
+
if (existsSync(pkgFile)) {
|
|
52
|
+
let pkg = JSON.parse(readFileSync(pkgFile))
|
|
53
|
+
handlerModuleSystem = getModSystem(pkg)
|
|
54
|
+
}
|
|
55
|
+
return { file, ext, handlerModuleSystem }
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (runtime.startsWith('python')) return { ext: 'py' }
|
|
59
|
+
if (runtime.startsWith('ruby')) return { ext: 'rb' }
|
|
60
|
+
if (runtime.startsWith('deno')) {
|
|
61
|
+
let { file = 'mod', ext = 'ts' } = findHandler(denoHandlers, src)
|
|
62
|
+
return { file, ext }
|
|
63
|
+
}
|
|
64
|
+
return { ext: '' }
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
errors.push(`Error getting Lambda handler in ${src}: ${err.message}`)
|
|
68
|
+
return {}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function findHandler (arr, src){
|
|
73
|
+
for (let handler of arr) {
|
|
74
|
+
if (existsSync(join(src, handler))) {
|
|
75
|
+
let bits = handler.split('.')
|
|
76
|
+
return { file: bits[0], ext: bits[1] }
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return {}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function getModSystem (pkg) {
|
|
83
|
+
if (pkg?.type === 'module') return 'esm'
|
|
84
|
+
else if (pkg?.type === 'commonjs') return 'cjs'
|
|
85
|
+
else if (pkg?.type) throw Error(`Invalid 'type' field: ${pkg.type}`)
|
|
86
|
+
return 'cjs'
|
|
14
87
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Pragma-specific Lambda constructors
|
|
2
|
+
let getHTTP = require('./_http')
|
|
3
|
+
let getEvents = require('./_events')
|
|
4
|
+
let getCustomLambdas = require('./_custom-lambdas')
|
|
5
|
+
let getScheduled = require('./_scheduled')
|
|
6
|
+
let getWS = require('./_ws')
|
|
7
|
+
let getTablesStreams = require('./_tables-streams')
|
|
8
|
+
|
|
9
|
+
let cl = 'customLambdas'
|
|
10
|
+
let ts = 'tables-streams'
|
|
11
|
+
|
|
12
|
+
module.exports = function getLambda (params) {
|
|
13
|
+
let { type } = params
|
|
14
|
+
if (type === 'http') return getHTTP(params)
|
|
15
|
+
if (type === 'events') return getEvents(params)
|
|
16
|
+
if (type === cl) return getCustomLambdas(params)
|
|
17
|
+
if (type === 'queues') return getEvents(params) // Effectively the same as events
|
|
18
|
+
if (type === 'scheduled') return getScheduled(params)
|
|
19
|
+
if (type === ts) return getTablesStreams(params)
|
|
20
|
+
if (type === 'tables') return getTablesStreams(params) // Shortcut for creating streams
|
|
21
|
+
/* istanbul ignore else: clearer to be explicit here */
|
|
22
|
+
if (type === 'ws') return getWS(params)
|
|
23
|
+
}
|
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
let is = require('../../../lib
|
|
2
|
-
let { aliases, runtimes
|
|
1
|
+
let { is } = require('../../../lib')
|
|
2
|
+
let { aliases, runtimes } = require('lambda-runtimes')
|
|
3
3
|
|
|
4
4
|
// Runtime interpolater
|
|
5
|
-
module.exports = function getRuntime (config) {
|
|
5
|
+
module.exports = function getRuntime ({ config, inventory }) {
|
|
6
6
|
let { runtime } = config
|
|
7
7
|
|
|
8
|
-
if (runtimeList.includes(runtime) || runtime === 'deno') {
|
|
9
|
-
return config
|
|
10
|
-
}
|
|
11
|
-
|
|
12
8
|
if (typeof runtime === 'string') {
|
|
13
9
|
runtime = runtime.toLowerCase()
|
|
10
|
+
let customRuntime = inventory._project?.customRuntimes?.[runtime]
|
|
14
11
|
|
|
15
12
|
// Runtime is not actually an AWS value, but a shorthand/aliased name
|
|
16
13
|
if (aliases[runtime]) {
|
|
@@ -18,6 +15,10 @@ module.exports = function getRuntime (config) {
|
|
|
18
15
|
config.runtime = runtimes[aliased][0]
|
|
19
16
|
config.runtimeAlias = runtime
|
|
20
17
|
}
|
|
18
|
+
// Runtime is custom via plugin
|
|
19
|
+
else if (customRuntime) {
|
|
20
|
+
config.runtimeConfig = customRuntime
|
|
21
|
+
}
|
|
21
22
|
}
|
|
22
23
|
else if (is.defined(runtime)) {
|
|
23
24
|
// Someone did something funky like specify a number or bool, so coerce and let it fail validation
|
|
@@ -1,113 +1,163 @@
|
|
|
1
|
+
let { sep } = require('path')
|
|
2
|
+
let { deepFrozenCopy } = require('@architect/utils')
|
|
1
3
|
let read = require('../../../read')
|
|
4
|
+
let getLambda = require('./get-lambda')
|
|
2
5
|
let getRuntime = require('./get-runtime')
|
|
3
6
|
let getHandler = require('./get-handler')
|
|
4
7
|
let upsert = require('../../_upsert')
|
|
5
|
-
let
|
|
6
|
-
|
|
7
|
-
// Pragma-specific Lambda constructors
|
|
8
|
-
let getHTTP = require('./_http')
|
|
9
|
-
let getEvents = require('./_events')
|
|
10
|
-
let getPlugins = require('./_plugins')
|
|
11
|
-
let getScheduled = require('./_scheduled')
|
|
12
|
-
let getWS = require('./_websockets')
|
|
13
|
-
let getTablesStreams = require('./_tables-streams')
|
|
8
|
+
let defaultFunctionConfig = require('../../../defaults/function-config')
|
|
9
|
+
let { compiledRuntimes, is } = require('../../../lib')
|
|
14
10
|
|
|
15
11
|
/**
|
|
16
|
-
* Build out the Lambda tree
|
|
12
|
+
* Build out the Lambda tree from the Arc manifest or a passed pragma, and plugins
|
|
17
13
|
*/
|
|
18
|
-
function populateLambda (type,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
let
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// Some lambda populators (e.g. plugins) may return empty results
|
|
31
|
-
if (!results) continue
|
|
32
|
-
// Some lambda populators (e.g. plugins) may return multiple results
|
|
33
|
-
if (!is.array(results)) results = [ results ]
|
|
34
|
-
|
|
35
|
-
results.forEach(result => {
|
|
36
|
-
let { name, src } = result
|
|
37
|
-
// Set up fresh config
|
|
38
|
-
let config = createDefaultConfig()
|
|
39
|
-
|
|
40
|
-
// Knock out any pragma-specific early
|
|
41
|
-
if (type === 'queues') {
|
|
42
|
-
config.fifo = config.fifo === undefined ? true : config.fifo
|
|
14
|
+
function populateLambda (type, params) {
|
|
15
|
+
// Passing a pragma array via params allows special overrides
|
|
16
|
+
// See: @tables populating inv['tables-streams']
|
|
17
|
+
let { arc, inventory, errors, pragma } = params
|
|
18
|
+
|
|
19
|
+
let plugins = inventory.plugins?._methods?.set?.[type]
|
|
20
|
+
let pluginLambda = []
|
|
21
|
+
if (plugins) {
|
|
22
|
+
let invCopy = deepFrozenCopy(inventory)
|
|
23
|
+
let pluginResults = plugins.flatMap(fn => {
|
|
24
|
+
try {
|
|
25
|
+
var result = fn({ arc: invCopy._project.arc, inventory: { inv: invCopy } })
|
|
43
26
|
}
|
|
44
|
-
|
|
45
|
-
|
|
27
|
+
catch (err) {
|
|
28
|
+
err.message = `Setter plugin exception: plugin: ${fn.plugin}, method: set.${type}`
|
|
29
|
+
+ `\n` + err.message
|
|
30
|
+
throw err
|
|
46
31
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
32
|
+
if (!result ||
|
|
33
|
+
(!is.object(result) && !is.array(result)) ||
|
|
34
|
+
(is.array(result) && result.some(r => !is.object(r)))) {
|
|
35
|
+
errors.push(`Setter plugins must return a valid response: plugin: ${fn.plugin}, method: set.${type}`)
|
|
36
|
+
return []
|
|
37
|
+
}
|
|
38
|
+
if (is.array(result)) {
|
|
39
|
+
result.forEach(item => {
|
|
40
|
+
item.plugin = fn.plugin
|
|
41
|
+
item.type = fn.type
|
|
42
|
+
})
|
|
57
43
|
}
|
|
58
|
-
|
|
59
|
-
|
|
44
|
+
else {
|
|
45
|
+
result.plugin = fn.plugin
|
|
46
|
+
result.type = fn.type
|
|
60
47
|
}
|
|
48
|
+
return result
|
|
49
|
+
})
|
|
50
|
+
pluginLambda = populate(type, pluginResults, inventory, errors, true) || []
|
|
51
|
+
}
|
|
61
52
|
|
|
62
|
-
|
|
63
|
-
|
|
53
|
+
let pragmaLambda = populate(type, pragma || arc[type], inventory, errors) || []
|
|
54
|
+
let aggregate = [ ...pluginLambda, ...pragmaLambda ]
|
|
55
|
+
return aggregate.length ? aggregate : null
|
|
56
|
+
}
|
|
64
57
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
delete config.apigateway
|
|
68
|
-
}
|
|
58
|
+
function populate (type, pragma, inventory, errors, plugin) {
|
|
59
|
+
if (!pragma || !pragma.length) return
|
|
69
60
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
let lambda = {
|
|
74
|
-
name,
|
|
75
|
-
config,
|
|
76
|
-
src,
|
|
77
|
-
handlerFile,
|
|
78
|
-
handlerFunction,
|
|
79
|
-
configFile,
|
|
80
|
-
...result, // Any other pragma-specific stuff
|
|
81
|
-
}
|
|
61
|
+
let defaultProjectConfig = () => JSON.parse(JSON.stringify(inventory._project.defaultFunctionConfig))
|
|
62
|
+
let { cwd, src: projSrc, build: projBuild } = inventory._project
|
|
82
63
|
|
|
83
|
-
|
|
84
|
-
|
|
64
|
+
// Fill er up
|
|
65
|
+
let lambdas = []
|
|
66
|
+
|
|
67
|
+
for (let item of pragma) {
|
|
68
|
+
// Get name, source dir, and any pragma-specific properties
|
|
69
|
+
let result = getLambda({ type, item, cwd, projSrc, projBuild, inventory, errors, plugin })
|
|
70
|
+
// Some Lambda populators (e.g. plugins) may return empty result
|
|
71
|
+
if (!result) continue
|
|
72
|
+
|
|
73
|
+
let { name, src, build } = result
|
|
74
|
+
|
|
75
|
+
// Normalize paths, especially since plugin authors may not use path.join
|
|
76
|
+
src = normalize(src)
|
|
77
|
+
if (build) build = normalize(build)
|
|
78
|
+
|
|
79
|
+
// Set up fresh config, then overlay plugin config
|
|
80
|
+
let config = defaultProjectConfig()
|
|
81
|
+
config = { ...config, ...getKnownProps(configProps, result.config) }
|
|
82
|
+
|
|
83
|
+
// Knock out any pragma-specific early
|
|
84
|
+
if (type === 'queues') {
|
|
85
|
+
config.fifo = config.fifo === undefined ? true : config.fifo
|
|
86
|
+
}
|
|
87
|
+
if (type === 'http') {
|
|
88
|
+
if (name.startsWith('get ') || name.startsWith('any ')) config.views = true
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Now let's check in on the function config
|
|
92
|
+
let { arc: arcConfig, filepath } = read({ type: 'functionConfig', cwd: src, errors })
|
|
93
|
+
|
|
94
|
+
// Set function config file path (if one is present)
|
|
95
|
+
let configFile = filepath ? filepath : null
|
|
96
|
+
|
|
97
|
+
// Layer any function config over Arc / project defaults
|
|
98
|
+
if (arcConfig && arcConfig.aws) {
|
|
99
|
+
config = upsert(config, arcConfig.aws)
|
|
100
|
+
}
|
|
101
|
+
if (arcConfig && arcConfig.arc) {
|
|
102
|
+
config = upsert(config, arcConfig.arc)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Interpolate runtimes
|
|
106
|
+
config = getRuntime({ config, inventory })
|
|
107
|
+
|
|
108
|
+
// Disable code sharing on [trans|com]piled functions
|
|
109
|
+
if (compiledRuntimes.includes(config.runtimeConfig?.type)) {
|
|
110
|
+
config.shared = config.views = false
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Tidy up any irrelevant properties
|
|
114
|
+
if (!compiledRuntimes.includes(config.runtimeConfig?.type)) {
|
|
115
|
+
// Super important! If we don't clean up the build prop, many explosions will explode
|
|
116
|
+
build = undefined
|
|
117
|
+
}
|
|
118
|
+
if (type !== 'http') {
|
|
119
|
+
delete config.apigateway
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Now we know the final source dir + runtime + handler: assemble handler props
|
|
123
|
+
let handlerProps = getHandler({ config, src, build, errors })
|
|
124
|
+
|
|
125
|
+
let lambda = {
|
|
126
|
+
name,
|
|
127
|
+
...getKnownProps(lambdaProps, result), // Pragma-specific stuff
|
|
128
|
+
config,
|
|
129
|
+
src,
|
|
130
|
+
build,
|
|
131
|
+
...handlerProps,
|
|
132
|
+
configFile,
|
|
133
|
+
pragma: type !== 'customLambdas' ? type : null,
|
|
134
|
+
}
|
|
135
|
+
// Final tidying of any undefined properties
|
|
136
|
+
Object.keys(lambda).forEach(k => !is.defined(lambda[k]) && delete lambda[k])
|
|
137
|
+
|
|
138
|
+
lambdas.push(lambda)
|
|
85
139
|
}
|
|
86
140
|
|
|
87
141
|
return lambdas
|
|
88
142
|
}
|
|
89
143
|
|
|
90
|
-
let
|
|
144
|
+
let normalize = path => path.replace(/[\\\/]/g, sep)
|
|
91
145
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if (type === 'plugins') return getPlugins(params)
|
|
99
|
-
if (type === 'queues') return getEvents(params) // Effectively the same as events
|
|
100
|
-
if (type === 'scheduled') return getScheduled(params)
|
|
101
|
-
if (type === ts) return getTablesStreams(params)
|
|
102
|
-
if (type === 'tables') return getTablesStreams(params) // Shortcut for creating streams
|
|
103
|
-
/* istanbul ignore else */ /* Clearer to be explicit here */
|
|
104
|
-
if (type === 'ws') return getWS(params)
|
|
146
|
+
// Lambda setter plugins can technically return anything, so this ensures everything is tidy
|
|
147
|
+
let lambdaProps = [ 'cron', 'method', 'path', 'plugin', 'rate', 'route', 'table', 'type' ]
|
|
148
|
+
let configProps = [ ...Object.keys(defaultFunctionConfig()), 'fifo', 'views' ]
|
|
149
|
+
let getKnownProps = (knownProps, raw = {}) => {
|
|
150
|
+
let props = knownProps.flatMap(prop => is.defined(raw[prop]) ? [ [ prop, raw[prop] ] ] : [])
|
|
151
|
+
return Object.fromEntries(props)
|
|
105
152
|
}
|
|
106
153
|
|
|
154
|
+
let cl = 'customLambdas'
|
|
155
|
+
let ts = 'tables-streams'
|
|
156
|
+
|
|
107
157
|
module.exports = {
|
|
108
158
|
events: populateLambda.bind({}, 'events'),
|
|
109
159
|
http: populateLambda.bind({}, 'http'),
|
|
110
|
-
|
|
160
|
+
[cl]: populateLambda.bind({}, cl),
|
|
111
161
|
queues: populateLambda.bind({}, 'queues'),
|
|
112
162
|
scheduled: populateLambda.bind({}, 'scheduled'),
|
|
113
163
|
tables: populateLambda.bind({}, 'tables'),
|
|
@@ -2,9 +2,10 @@ let populate = require('./populate-lambda')
|
|
|
2
2
|
let validate = require('./validate')
|
|
3
3
|
|
|
4
4
|
module.exports = function configureQueues ({ arc, inventory, errors }) {
|
|
5
|
-
|
|
5
|
+
let queuesPlugins = inventory.plugins?._methods?.set?.queues
|
|
6
|
+
if (!arc?.queues?.length && !queuesPlugins?.length) return null
|
|
6
7
|
|
|
7
|
-
let queues = populate.queues(arc
|
|
8
|
+
let queues = populate.queues({ arc, inventory, errors })
|
|
8
9
|
|
|
9
10
|
validate.queues(queues, '@queues', errors)
|
|
10
11
|
|
|
@@ -2,9 +2,10 @@ let populate = require('./populate-lambda')
|
|
|
2
2
|
let validate = require('./validate')
|
|
3
3
|
|
|
4
4
|
module.exports = function configureScheduled ({ arc, inventory, errors }) {
|
|
5
|
-
|
|
5
|
+
let scheduledPlugins = inventory.plugins?._methods?.set?.scheduled
|
|
6
|
+
if (!arc?.scheduled?.length && !scheduledPlugins?.length) return null
|
|
6
7
|
|
|
7
|
-
let scheduled = populate.scheduled(arc
|
|
8
|
+
let scheduled = populate.scheduled({ arc, inventory, errors })
|
|
8
9
|
|
|
9
10
|
validate.scheduled(scheduled, errors)
|
|
10
11
|
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
let { join } = require('path')
|
|
2
2
|
let validate = require('./validate')
|
|
3
|
-
let is = require('../../lib
|
|
4
|
-
let
|
|
3
|
+
let { is, pragmas } = require('../../lib')
|
|
4
|
+
let lambdas = pragmas.lambdas.concat('customLambdas')
|
|
5
5
|
|
|
6
6
|
module.exports = function configureShared ({ arc, pragmas, inventory, errors }) {
|
|
7
7
|
if (!pragmas.lambdaSrcDirs) return null
|
|
8
8
|
|
|
9
|
-
let cwd = inventory._project
|
|
10
|
-
let src = join(
|
|
9
|
+
let { cwd, src: projSrc } = inventory._project
|
|
10
|
+
let src = join(projSrc, 'shared')
|
|
11
11
|
let shared = {
|
|
12
12
|
src,
|
|
13
13
|
shared: [] // Revert to null later if none are defined
|
|
14
14
|
}
|
|
15
|
-
if (arc.shared && arc.shared.length) {
|
|
16
|
-
let foundSrc = false
|
|
17
15
|
|
|
18
|
-
|
|
16
|
+
// First pass to get + check shared folder (if any)
|
|
17
|
+
let foundSrc = false
|
|
18
|
+
if (arc?.shared?.length) {
|
|
19
19
|
for (let share of arc.shared) {
|
|
20
20
|
if (is.array(share)) {
|
|
21
|
-
let key = share[0]
|
|
21
|
+
let key = share[0]?.toLowerCase()
|
|
22
22
|
if (key === 'src' && is.string(share[1])) {
|
|
23
23
|
shared.src = share[1]
|
|
24
24
|
foundSrc = true
|
|
@@ -30,49 +30,49 @@ module.exports = function configureShared ({ arc, pragmas, inventory, errors })
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
+
}
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
// Exit if configured shared folder doesn't exist
|
|
36
|
+
if (!is.exists(shared.src)) return null
|
|
37
|
+
|
|
38
|
+
// Proceeding from here resets all shared config, so make sure it's only if specific shared are specified
|
|
39
|
+
let some = arc.shared?.length && !(arc?.shared?.length === 1 && foundSrc)
|
|
40
|
+
if (some) {
|
|
41
|
+
// Reset shared settings
|
|
42
|
+
for (let pragma of lambdas) {
|
|
43
|
+
if (!pragmas[pragma]) continue
|
|
44
|
+
for (let { config } of pragmas[pragma]) {
|
|
45
|
+
config.shared = false
|
|
43
46
|
}
|
|
47
|
+
}
|
|
44
48
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
// Set new shared settings
|
|
50
|
+
for (let pragma of arc.shared) {
|
|
51
|
+
if (is.array(pragma)) continue // Bail on src setting
|
|
52
|
+
if (!is.object(pragma)) {
|
|
53
|
+
return errors.push(`@shared invalid setting: ${pragma}`)
|
|
54
|
+
}
|
|
51
55
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
let p = Object.keys(pragma)[0]
|
|
57
|
+
if (!lambdas.includes(p)) {
|
|
58
|
+
return errors.push(`${p} is not a valid @shared pragma`)
|
|
59
|
+
}
|
|
56
60
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
// Ignore shared into ASAP
|
|
67
|
-
if (!fn.arcStaticAssetProxy) fn.config.shared = true
|
|
61
|
+
let entries = is.object(pragma[p])
|
|
62
|
+
? Object.entries(pragma[p])
|
|
63
|
+
: pragma[p]
|
|
64
|
+
for (let lambda of entries) {
|
|
65
|
+
let name = p === 'http' ? lambda.join(' ') : lambda
|
|
66
|
+
let fn = pragmas[p].find(n => n.name === name)
|
|
67
|
+
if (!fn) {
|
|
68
|
+
return errors.push(`@shared ${name} not found in @${p} Lambdas`)
|
|
68
69
|
}
|
|
70
|
+
// Ignore shared into ASAP
|
|
71
|
+
if (!fn.arcStaticAssetProxy) fn.config.shared = true
|
|
69
72
|
}
|
|
70
73
|
}
|
|
71
74
|
}
|
|
72
75
|
|
|
73
|
-
// Exit if default views folder doesn't exist
|
|
74
|
-
if (!is.exists(shared.src)) return null
|
|
75
|
-
|
|
76
76
|
// lambda.config.shared was added by function config defaults, or added above
|
|
77
77
|
for (let pragma of lambdas) {
|
|
78
78
|
if (!pragmas[pragma]) continue
|
|
@@ -83,8 +83,5 @@ module.exports = function configureShared ({ arc, pragmas, inventory, errors })
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
// De-dupe (in case multiple functions live at the same src path)
|
|
87
|
-
shared.shared = [ ...new Set(shared.shared) ]
|
|
88
|
-
|
|
89
86
|
return shared
|
|
90
87
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
let
|
|
1
|
+
let { httpMethods } = require('../../../lib')
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* HTTP route sorter; this is a multifurcating tree, so we'll do a few passes
|
|
@@ -32,7 +32,7 @@ module.exports = function sortHTTP (http) {
|
|
|
32
32
|
|
|
33
33
|
// Multi-pass route sort
|
|
34
34
|
let sorted = []
|
|
35
|
-
|
|
35
|
+
httpMethods.forEach(method => {
|
|
36
36
|
if (!tree[method]) return
|
|
37
37
|
/* istanbul ignore next: random test shuffles may not trigger all paths */
|
|
38
38
|
tree[method]
|
|
@@ -55,6 +55,7 @@ module.exports = function sortHTTP (http) {
|
|
|
55
55
|
if (a.path < b.path) return -1
|
|
56
56
|
if (a.path > b.path) return 1
|
|
57
57
|
})
|
|
58
|
+
// Trailing capture sort
|
|
58
59
|
.sort((a, b) => {
|
|
59
60
|
if (!a.depth && b.depth === 1 && b.trailingCapture) return -1
|
|
60
61
|
if (a.depth - b.depth < 0) return
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
let asapSrc = require('../../lib
|
|
2
|
-
let is = require('../../lib/is')
|
|
1
|
+
let { asapSrc, is } = require('../../lib')
|
|
3
2
|
|
|
4
3
|
module.exports = function configureStatic ({ arc, inventory }) {
|
|
4
|
+
let httpSetters = inventory.plugins?._methods?.set?.http
|
|
5
|
+
|
|
5
6
|
// @static is inferred by @http
|
|
6
|
-
if (!arc.static && !arc.http) return null
|
|
7
|
+
if (!arc.static && !arc.http && !httpSetters) return null
|
|
7
8
|
|
|
8
9
|
let staticPragma = arc.static || []
|
|
9
10
|
let _static = {
|
|
@@ -38,7 +39,7 @@ module.exports = function configureStatic ({ arc, inventory }) {
|
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
// Handy shortcut to ASAP for bare @static
|
|
41
|
-
if (!arc.http) {
|
|
42
|
+
if (!arc.http && !httpSetters) {
|
|
42
43
|
inventory._project.rootHandler = 'arcStaticAssetProxy'
|
|
43
44
|
inventory._project.asapSrc = asapSrc()
|
|
44
45
|
}
|
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
let is = require('../../lib
|
|
1
|
+
let { is } = require('../../lib')
|
|
2
2
|
let validate = require('./validate')
|
|
3
3
|
|
|
4
|
-
function configureTablesIndexes ({ arc, errors }) {
|
|
4
|
+
module.exports = function configureTablesIndexes ({ arc, errors }) {
|
|
5
5
|
if (!arc['tables-indexes'] || !arc['tables-indexes'].length) return null
|
|
6
6
|
if (arc['tables-indexes'] && !arc.tables) {
|
|
7
7
|
errors.push(`Specifying @tables-indexes requires specifying corresponding @tables`)
|
|
8
8
|
return null
|
|
9
9
|
}
|
|
10
|
-
if (arc['tables-indexes']?.length && arc.indexes?.length) {
|
|
11
|
-
errors.push(`Either @tables-indexes or @indexes can be specified, but not both`)
|
|
12
|
-
return null
|
|
13
|
-
}
|
|
14
10
|
|
|
15
11
|
let indexes = getIndexes(arc, 'tables-indexes', errors)
|
|
16
|
-
validate.
|
|
12
|
+
validate.tablesIndexes(indexes, '@tables-indexes', errors)
|
|
17
13
|
|
|
18
14
|
return indexes
|
|
19
15
|
}
|
|
@@ -54,6 +50,3 @@ let getIndexes = (arc, pragma, errors) => {
|
|
|
54
50
|
error(index)
|
|
55
51
|
}).filter(Boolean) // Invalid indexes may create undefined entries in the map
|
|
56
52
|
}
|
|
57
|
-
|
|
58
|
-
configureTablesIndexes.getIndexes = getIndexes
|
|
59
|
-
module.exports = configureTablesIndexes
|