@architect/inventory 2.2.1 → 3.0.0-RC.3

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.
Files changed (69) hide show
  1. package/changelog.md +41 -0
  2. package/package.json +8 -6
  3. package/readme.md +5 -4
  4. package/src/config/_upsert.js +1 -1
  5. package/src/config/arc.js +3 -3
  6. package/src/config/pragmas/app.js +1 -1
  7. package/src/config/pragmas/events.js +3 -2
  8. package/src/config/pragmas/http.js +5 -4
  9. package/src/config/pragmas/index.js +16 -5
  10. package/src/config/pragmas/meta/custom-lambdas.js +10 -0
  11. package/src/config/pragmas/{src-dirs.js → meta/src-dirs.js} +13 -10
  12. package/src/config/pragmas/plugins.js +104 -4
  13. package/src/config/pragmas/populate-lambda/_custom-lambdas.js +10 -0
  14. package/src/config/pragmas/populate-lambda/_events.js +17 -11
  15. package/src/config/pragmas/populate-lambda/_http.js +18 -10
  16. package/src/config/pragmas/populate-lambda/_scheduled.js +18 -10
  17. package/src/config/pragmas/populate-lambda/_tables-streams.js +20 -23
  18. package/src/config/pragmas/populate-lambda/_ws.js +26 -0
  19. package/src/config/pragmas/populate-lambda/get-handler.js +86 -13
  20. package/src/config/pragmas/populate-lambda/get-lambda.js +23 -0
  21. package/src/config/pragmas/populate-lambda/get-runtime.js +8 -7
  22. package/src/config/pragmas/populate-lambda/index.js +104 -86
  23. package/src/config/pragmas/queues.js +3 -2
  24. package/src/config/pragmas/scheduled.js +3 -2
  25. package/src/config/pragmas/shared.js +41 -44
  26. package/src/config/pragmas/sort/http.js +2 -2
  27. package/src/config/pragmas/static.js +1 -2
  28. package/src/config/pragmas/tables-indexes.js +3 -10
  29. package/src/config/pragmas/tables-streams.js +7 -5
  30. package/src/config/pragmas/tables.js +1 -1
  31. package/src/config/pragmas/validate/_events.js +1 -1
  32. package/src/config/pragmas/validate/_http.js +3 -3
  33. package/src/config/pragmas/validate/_lib.js +1 -1
  34. package/src/config/pragmas/validate/_scheduled.js +2 -2
  35. package/src/config/pragmas/validate/_shared.js +1 -1
  36. package/src/config/pragmas/validate/_tables-streams.js +6 -8
  37. package/src/config/pragmas/validate/_tables.js +2 -2
  38. package/src/config/pragmas/validate/index.js +2 -2
  39. package/src/config/pragmas/views.js +39 -37
  40. package/src/config/pragmas/ws.js +6 -4
  41. package/src/config/project/index.js +34 -18
  42. package/src/config/project/plugins/env.js +33 -0
  43. package/src/config/project/plugins/index.js +7 -0
  44. package/src/config/project/plugins/runtimes.js +56 -0
  45. package/src/config/project/prefs/dotenv.js +73 -0
  46. package/src/config/project/{prefs.js → prefs/index.js} +32 -14
  47. package/src/config/project/validate/index.js +1 -1
  48. package/src/defaults/index.js +20 -13
  49. package/src/env/index.js +76 -61
  50. package/src/get.js +1 -2
  51. package/src/index.js +17 -15
  52. package/src/lib/asap-src.js +3 -3
  53. package/src/lib/error-fmt.js +2 -10
  54. package/src/lib/get-lambda-dirs.js +37 -0
  55. package/src/lib/index.js +28 -0
  56. package/src/lib/is.js +3 -1
  57. package/src/lib/merge-env-vars.js +32 -0
  58. package/src/lib/pragmas.js +19 -3
  59. package/src/read/reader.js +1 -1
  60. package/src/validate/config.js +12 -6
  61. package/src/validate/index.js +3 -11
  62. package/src/validate/layers.js +2 -2
  63. package/src/validate/tables-children.js +5 -5
  64. package/src/config/pragmas/indexes.js +0 -19
  65. package/src/config/pragmas/macros.js +0 -5
  66. package/src/config/pragmas/populate-lambda/_plugins.js +0 -25
  67. package/src/config/pragmas/populate-lambda/_websockets.js +0 -19
  68. package/src/config/project/plugins.js +0 -31
  69. package/src/lib/http-methods.js +0 -2
package/changelog.md CHANGED
@@ -2,6 +2,47 @@
2
2
 
3
3
  ---
4
4
 
5
+ ## [3.0.0] 2022-01-04
6
+
7
+ ### Added
8
+
9
+ - Architect 10 plugin API support! Specifically:
10
+ - `plugins.set.runtimes` - custom runtime support (still in beta)
11
+ - `plugins.set.env` - add environment variables to all Lambdas
12
+ - `plugins.set.events|http|scheduled|tables-streams|ws` - generate or drop in Lambdas in Architect pragmas
13
+ - `plugins.set.customLambdas` - generate or drop in unique Lambdas with custom event sources
14
+ - More below...
15
+ - Added `inv|get.plugins` tree + methods
16
+ - What used to be `plugins` in the plugins beta is now `customLambdas` (see next item)
17
+ - Added `inv|get.customLambdas`
18
+ - Formerly `inv|get.plugins`
19
+ - Added `inv._project.customRuntimes`
20
+ - Added low-level support for `build` destinations to runtime plugins that register type `transpiled` or `compiled`
21
+ - Added `handlerModuleSystem` property for `nodejs14.x` Lambdas, with a value of `cjs` or `esm` based on Lambda + Node.js conventions
22
+ - Added `handlerFile` detection for `nodejs14.x` + `deno` Lambdas
23
+ - This will detect the correct handler file on the filesystem, and fall back to a default handler file if none are found (e.g. `index.js` in `nodejs14.x`)
24
+ - Added `inv._arc.deployStage` property, enabling Inventory to be aware of an intended deploy stage; (this property may change, consider it in beta!)
25
+ - Added built-in support for reading `.env` files when enumerating local env var preferences
26
+
27
+
28
+ ### Changed
29
+
30
+ - Breaking change: changed `_project.src`, added `_project.cwd`, making both the pair significantly more literal and descriptive
31
+ - `_project.src` is now the default source tree folder (eg `$cwd/src`)
32
+ - `_project.cwd` refers to the current working directory of the project
33
+ - Breaking change: `_project.env` is now by default an object populated by three properties: `local`, `plugins`, and `aws`, reflecting the env vars found for each environment
34
+ - Breaking change: AWS region prioritizes a region passed via param over `AWS_REGION` env var; this should realistically have little or no effect in practice
35
+ - Breaking change: legacy `@tables-streams` folders (`src/tables/...` and `src/streams/...`) are now deprecated
36
+ - Existing functions can be simply moved to `src/tables-streams/{name}` (or use a custom `src` property)
37
+ - Breaking change: renamed `lambda.handlerFunction` to `lambda.handlerMethod`
38
+ - Breaking change: prioritize `mod.ts|js` handlers in Deno Lambdas
39
+ - Performance improvements to building `inv.shared` + `inv.views`
40
+ - Improved memory footprint of Inventory object by preserving references in `lambdaSrcDirs`, `lambdasBySrcDir`
41
+ - Added `pragma` property to all Lambdas to aid in reference preservation
42
+ - Tidy up order of enumerated properties in each Lambda
43
+
44
+ ---
45
+
5
46
  ## [2.2.1] 2021-11-22
6
47
 
7
48
  ### Fixed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@architect/inventory",
3
- "version": "2.2.1",
3
+ "version": "3.0.0-RC.3",
4
4
  "description": "Architect project resource enumeration utility",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -9,7 +9,8 @@
9
9
  "test:integration": "cross-env tape 'test/integration/**/*-test.js' | tap-spec",
10
10
  "coverage": "nyc --reporter=lcov --reporter=text npm run test:unit",
11
11
  "lint": "eslint . --fix",
12
- "rc": "npm version prerelease --preid RC"
12
+ "rc": "npm version prerelease --preid RC",
13
+ "vendor": "scripts/vendor"
13
14
  },
14
15
  "engines": {
15
16
  "node": ">=14"
@@ -23,14 +24,15 @@
23
24
  "@architect/asap": "~4.1.0",
24
25
  "@architect/parser": "~5.0.2",
25
26
  "@architect/utils": "~3.0.4",
26
- "lambda-runtimes": "~1.1.0"
27
+ "lambda-runtimes": "~1.1.1"
27
28
  },
28
29
  "devDependencies": {
29
30
  "@architect/eslint-config": "~2.0.1",
30
31
  "aws-sdk": "2.880.0",
31
- "aws-sdk-mock": "~5.4.0",
32
+ "aws-sdk-mock": "~5.5.0",
32
33
  "cross-env": "~7.0.3",
33
- "eslint": "~8.2.0",
34
+ "dotenv": "~12.0.3",
35
+ "eslint": "~8.5.0",
34
36
  "mock-fs": "~5.1.2",
35
37
  "mock-require": "~3.0.3",
36
38
  "nyc": "~15.1.0",
@@ -40,7 +42,7 @@
40
42
  "eslintConfig": {
41
43
  "extends": "@architect/eslint-config"
42
44
  },
43
- "nyc": {
45
+ "_nyc": {
44
46
  "check-coverage": true,
45
47
  "branches": 100,
46
48
  "lines": 100,
package/readme.md CHANGED
@@ -43,7 +43,7 @@ The inventory object contains the entirety of a project's data, including Archit
43
43
 
44
44
  Top-level inventory parameters that start with an underscore (e.g. `_arc`, `_project`) denote project metadata or internal diagnostic data; all other parameters represent userland project resources.
45
45
 
46
- In a project inventory, `null` values are used as placeholders for known values or options that were not user-defined. The existence of a non-`null` value can be inferred as a user having specifically defined a setting. For example: `arc.http === null` can be construed as the user having **not** defined an `@http` pragma. This rule has some exceptions:
46
+ In a project inventory, `null` values are used as placeholders for known values or options that were not user-defined. The existence of a non-`null` value can be inferred as a user having specifically defined a setting. For example: `arc.http: null` can be construed as the user having **not** defined an `@http` pragma. This rule has some exceptions:
47
47
 
48
48
  - A handful of settings that must be backfilled if not supplied
49
49
  - Example: `inv.aws.region`, which is required by the `aws-sdk` to function, and will be backfilled if not defined
@@ -51,9 +51,10 @@ In a project inventory, `null` values are used as placeholders for known values
51
51
  - Example: while `@static` can be defined on its own without any other pragmas, the existence of `@http` infers `@static`
52
52
  - Thus, the act of adding `@http` will necessarily make `inv.static` non-`null`
53
53
  - Settings that generate related resources
54
- - Example: DynamoDB streams can be defined in `@tables` with `stream true`; Inventory would interpret a table with `stream true` as a new `inv.streams` resource and thus make `inv.streams` non-`null`
55
-
56
- > Note: The `inv` format is primarily designed and intended for internal use within Architect libraries; as such, Inventory may theoretically introduce breaking changes in its behavior, shape, or naming conventions.
54
+ - Example: DynamoDB streams can be defined in `@tables` with `stream true`; Inventory would interpret a table with `stream true` as a new `inv['tables-streams']` resource and thus make `inv['tables-streams']` non-`null`
55
+ - Lambda `handlerFile` file path property is present even if the file is not
56
+ - This differs from Lambda `configFile` file path properties, which will be `null` if no file is present
57
+ - This exception is namely because some workflows may need the computed default handler path (example: when running `arc create`)
57
58
 
58
59
 
59
60
  #### `get`
@@ -1,4 +1,4 @@
1
- let is = require('../lib/is')
1
+ let { is } = require('../lib')
2
2
 
3
3
  /**
4
4
  * Overlay / append properties onto an existing config object
package/src/config/arc.js CHANGED
@@ -6,14 +6,14 @@ let { join } = require('path')
6
6
  */
7
7
  module.exports = function getArcConfig (params) {
8
8
  let { cwd, inventory } = params
9
- let arc = { ...inventory._arc }
9
+ let _arc = { ...inventory._arc }
10
10
 
11
11
  // Version
12
12
  let installed = join(cwd, 'node_modules', '@architect', 'architect', 'package.json')
13
13
  if (existsSync(installed)) {
14
14
  let { version } = JSON.parse(readFileSync(installed))
15
- arc.version = version
15
+ _arc.version = version
16
16
  }
17
17
 
18
- return arc
18
+ return _arc
19
19
  }
@@ -1,5 +1,5 @@
1
1
  let { validate } = require('./validate')
2
- let is = require('../../lib/is')
2
+ let { is } = require('../../lib')
3
3
 
4
4
  module.exports = function configureApp ({ arc, errors }) {
5
5
  if (!is.array(arc.app) ||
@@ -2,9 +2,10 @@ let populate = require('./populate-lambda')
2
2
  let validate = require('./validate')
3
3
 
4
4
  module.exports = function configureEvents ({ arc, inventory, errors }) {
5
- if (!arc.events || !arc.events.length) return null
5
+ let eventsPlugins = inventory.plugins?._methods?.set?.events
6
+ if (!arc?.events?.length && !eventsPlugins?.length) return null
6
7
 
7
- let events = populate.events(arc.events, inventory, errors)
8
+ let events = populate.events({ arc, inventory, errors })
8
9
 
9
10
  validate.events(events, '@events', errors)
10
11
 
@@ -1,15 +1,16 @@
1
1
  let { join } = require('path')
2
2
  let populate = require('./populate-lambda')
3
- let asapSrc = require('../../lib/asap-src')
3
+ let { asapSrc } = require('../../lib')
4
4
  let validate = require('./validate')
5
5
  let sort = require('./sort/http')
6
6
 
7
7
  module.exports = function configureHTTP ({ arc, inventory, errors }) {
8
- if (!arc.http) return null
8
+ let httpPlugins = inventory.plugins?._methods?.set?.http
9
+ if (!arc.http && !httpPlugins?.length) return null
9
10
 
10
11
  // Populate normally returns null on an empty Lambda pragma
11
12
  // However, @http is special because it gets the Architect Static Asset Proxy (ASAP), so fall back to an empty array
12
- let http = populate.http(arc.http, inventory, errors) || []
13
+ let http = populate.http({ arc, inventory, errors }) || []
13
14
 
14
15
  // Attempt to determine specifically what is handling requests to the root
15
16
  // This should probably just be replaced by proper route ordering
@@ -53,7 +54,7 @@ module.exports = function configureHTTP ({ arc, inventory, errors }) {
53
54
  config: { ...inventory._arc.defaultFunctionConfig },
54
55
  src,
55
56
  handlerFile: join(src, 'index.js'),
56
- handlerFunction: 'handler',
57
+ handlerMethod: 'handler',
57
58
  configFile: null,
58
59
  arcStaticAssetProxy: true,
59
60
  method: 'get',
@@ -1,23 +1,27 @@
1
- let { all: allPragmas } = require('../../lib/pragmas')
1
+ let { pragmas } = require('../../lib')
2
+ let { all: allPragmas } = pragmas
2
3
 
3
4
  // Get all pragmas except special cases
4
- let isSpecial = p => [ 'shared', 'views' ].includes(p)
5
+ let isSpecial = p => [ 'plugins', 'shared', 'views' ].includes(p)
5
6
  let visitors = allPragmas.map(p => {
6
7
  // eslint-disable-next-line
7
8
  if (!isSpecial(p)) return require(`./${p}`)
8
9
  }).filter(Boolean)
9
10
 
10
- // Special order-dependent visitors that run in a second pass
11
- let srcDirs = require('./src-dirs')
11
+ // Special order-dependent visitors
12
+ let customLambdas = require('./meta/custom-lambdas')
13
+ let srcDirs = require('./meta/src-dirs')
12
14
  let shared = require('./shared')
13
15
  let views = require('./views')
14
16
 
15
- module.exports = function configureArcPragmas ({ arc, inventory }, errors) {
17
+ function configureArcPragmas ({ arc, inventory, errors }) {
16
18
  if (inventory._project.type !== 'aws') {
17
19
  throw ReferenceError('Inventory can only configure pragmas for AWS projects')
18
20
  }
19
21
 
20
22
  let pragmas = {}
23
+
24
+ // All the main pragma visitors
21
25
  visitors.forEach(visitor => {
22
26
  // Expects pragma visitors to have function name of: `configure${pragma}`
23
27
  let name = visitor.name.replace('configure', '').toLowerCase()
@@ -27,6 +31,9 @@ module.exports = function configureArcPragmas ({ arc, inventory }, errors) {
27
31
  pragmas[name] = visitor({ arc, inventory, errors })
28
32
  })
29
33
 
34
+ // Custom Lambdas from @plugins
35
+ pragmas.customLambdas = customLambdas({ arc, inventory, errors })
36
+
30
37
  // Lambda source directory list
31
38
  let dirs = srcDirs({ pragmas, errors })
32
39
  pragmas.lambdaSrcDirs = dirs.lambdaSrcDirs
@@ -40,3 +47,7 @@ module.exports = function configureArcPragmas ({ arc, inventory }, errors) {
40
47
 
41
48
  return pragmas
42
49
  }
50
+
51
+ // Plugins get run early so visitors can rely on the plugin method tree
52
+ configureArcPragmas.plugins = require('./plugins')
53
+ module.exports = configureArcPragmas
@@ -0,0 +1,10 @@
1
+ let populate = require('../populate-lambda')
2
+
3
+ module.exports = function configureCustomLambdas ({ arc, inventory, errors }) {
4
+ let customLambdaPlugins = inventory.plugins?._methods?.set?.customLambdas
5
+ if (!customLambdaPlugins?.length) return null
6
+
7
+ let customLambdas = populate.customLambdas({ arc, inventory, errors })
8
+
9
+ return customLambdas
10
+ }
@@ -1,23 +1,27 @@
1
- let { lambdas } = require('../../lib/pragmas')
2
- let is = require('../../lib/is')
1
+ let { is, pragmas } = require('../../../lib')
2
+ let { lambdas } = pragmas
3
3
 
4
4
  module.exports = function collectSourceDirs ({ pragmas, errors }) {
5
5
  let lambdaSrcDirs = []
6
6
  let unsortedBySrcDir = {}
7
7
  Object.entries(pragmas).forEach(([ pragma, values ]) => {
8
- let mayHaveSrcDirs = lambdas.includes(pragma)
8
+ let mayHaveSrcDirs = lambdas.includes(pragma) || pragma === 'customLambdas'
9
9
  if (mayHaveSrcDirs && is.array(values)) {
10
10
  pragmas[pragma].forEach(item => {
11
11
  if (item.arcStaticAssetProxy === true) return // Special exception for ASAP
12
12
  else if (is.string(item.src)) {
13
13
  lambdaSrcDirs.push(item.src)
14
14
  // Multiple Lambdae may map to a single dir
15
- if (unsortedBySrcDir[item.src]) {
16
- unsortedBySrcDir[item.src] = is.array(unsortedBySrcDir[item.src])
17
- ? [ ...unsortedBySrcDir[item.src], { ...item, pragma } ]
18
- : [ unsortedBySrcDir[item.src], { ...item, pragma } ]
15
+ // >2 Lambdas found with same src dir
16
+ if (is.array(unsortedBySrcDir[item.src])) {
17
+ unsortedBySrcDir[item.src].push(item)
19
18
  }
20
- else unsortedBySrcDir[item.src] = { ...item, pragma }
19
+ // 2 Lambdas found with same src dir
20
+ else if (is.object(unsortedBySrcDir[item.src])) {
21
+ unsortedBySrcDir[item.src] = [ unsortedBySrcDir[item.src], item ]
22
+ }
23
+ // 1 Lambda found
24
+ else unsortedBySrcDir[item.src] = item
21
25
  }
22
26
  else errors.push(`Lambda is missing source directory: ${JSON.stringify(item, null, 2)}`)
23
27
  })
@@ -29,8 +33,7 @@ module.exports = function collectSourceDirs ({ pragmas, errors }) {
29
33
 
30
34
  // Sort the object for human readability
31
35
  let lambdasBySrcDir = null
32
- unsortedBySrcDir = Object.keys(unsortedBySrcDir).length ? unsortedBySrcDir : null
33
- if (unsortedBySrcDir) {
36
+ if (Object.keys(unsortedBySrcDir).length) {
34
37
  lambdasBySrcDir = {}
35
38
  lambdaSrcDirs.forEach(d => lambdasBySrcDir[d] = unsortedBySrcDir[d])
36
39
  }
@@ -1,9 +1,109 @@
1
- let populate = require('./populate-lambda')
1
+ let { join } = require('path')
2
+ let { existsSync } = require('fs')
3
+ let { is, normalizeSrc, pragmas } = require('../../lib')
4
+ let { lambdas } = pragmas
5
+ let nonLambdaSetters = [ 'customLambdas', 'env', 'runtimes' ]
6
+ let setters = [ ...lambdas, ...nonLambdaSetters ]
7
+ let pluginMethods = [ 'deploy', 'sandbox' ] // TODO add more!
2
8
 
3
- module.exports = function configurePlugins ({ arc, inventory, errors }) {
4
- if (!arc.plugins || !arc.plugins.length) return null
9
+ module.exports = function getPluginModules ({ arc, inventory, errors }) {
10
+ if (!arc?.plugins?.length && !arc?.macros?.length) return null
11
+ let plugins = {}
12
+ let methods = {}
13
+ let { cwd } = inventory._project
5
14
 
6
- let plugins = populate.plugins(arc.plugins, inventory, errors)
15
+ let pluginItems = []
16
+ let tagPlugins = (arr, type) => pluginItems.push(...arr.map(p => ({ plugin: p, type })))
17
+ if (arc?.plugins?.length) tagPlugins(arc.plugins, 'plugin')
18
+ if (arc?.macros?.length) tagPlugins(arc.macros, 'macro')
7
19
 
20
+ for (let pluginItem of pluginItems) {
21
+ let { plugin, type } = pluginItem
22
+ let name
23
+ let pluginPath
24
+
25
+ if (is.string(plugin)) {
26
+ name = plugin
27
+ pluginPath = getPath(cwd, type + 's', name)
28
+ }
29
+ else if (is.object(plugin)) {
30
+ name = Object.keys(plugin)[0]
31
+ pluginPath = plugin[name].src
32
+ ? normalizeSrc(cwd, plugin[name].src)
33
+ : join(cwd, 'src', type + 's', name)
34
+ }
35
+
36
+ if (name === '_methods') {
37
+ errors.push('Plugin name _methods is reserved, please rename your plugin')
38
+ continue
39
+ }
40
+ if (pluginPath) {
41
+ try {
42
+ if (type === 'plugin') {
43
+ // eslint-disable-next-line
44
+ plugins[name] = require(pluginPath)
45
+ }
46
+ // Remap @macros to deploy.start
47
+ if (type === 'macro') {
48
+ // eslint-disable-next-line
49
+ plugins[name] = { deploy: { start: require(pluginPath) } }
50
+ }
51
+ // Walk each plugin and build the method tree
52
+ Object.entries(plugins[name]).forEach(([ method, item ]) => {
53
+ // Primitive setters
54
+ if (method === 'set') {
55
+ if (!methods.set) methods.set = {}
56
+ setters.forEach(setter => {
57
+ if (item[setter]) {
58
+ let fn = item[setter]
59
+ if (!is.fn(fn) || fn.constructor.name === 'AsyncFunction') {
60
+ let msg = `Invalid plugin, setters must be synchronous functions: plugin: ${name}, method: set.${setter}`
61
+ errors.push(msg)
62
+ return
63
+ }
64
+ if (!methods.set[setter]) methods.set[setter] = []
65
+ fn.plugin = name
66
+ fn.type = type
67
+ methods.set[setter].push(fn)
68
+ }
69
+ })
70
+ }
71
+ // Command hooks
72
+ else if (pluginMethods.includes(method)) {
73
+ Object.entries(item).forEach(([ hook, fn ]) => {
74
+ if (!is.fn(fn)) {
75
+ let msg = `Invalid plugin, must be a function: plugin: ${name}, method: ${method}.${hook}`
76
+ errors.push(msg)
77
+ return
78
+ }
79
+ if (!methods[method]) methods[method] = {}
80
+ if (!methods[method][hook]) methods[method][hook] = []
81
+ fn.plugin = name
82
+ fn.type = type
83
+ methods[method][hook].push(fn)
84
+ })
85
+ }
86
+ })
87
+ }
88
+ catch (err) {
89
+ errors.push(`Unable to load plugin '${name}': ${err.message.split('\n')[0]}`)
90
+ }
91
+ }
92
+ else errors.push(`Cannot find plugin '${name || plugin}'! Are you sure you have installed or created it correctly?`)
93
+ }
94
+ plugins._methods = methods
8
95
  return plugins
9
96
  }
97
+
98
+ function getPath (cwd, srcDir, name) {
99
+ let paths = [
100
+ join(cwd, 'src', srcDir, `${name}.js`),
101
+ join(cwd, 'src', srcDir, name),
102
+ join(cwd, 'node_modules', name),
103
+ join(cwd, 'node_modules', `@${name}`),
104
+ ]
105
+ if (existsSync(paths[0])) return paths[0]
106
+ else if (existsSync(paths[1])) return paths[1]
107
+ else if (existsSync(paths[2])) return paths[2]
108
+ else if (existsSync(paths[3])) return paths[3]
109
+ }
@@ -0,0 +1,10 @@
1
+ let { getLambdaDirs } = require('../../../lib')
2
+
3
+ module.exports = function populateCustomLambdas (params) {
4
+ let { item, errors } = params
5
+ let { name, src } = item
6
+ if (name && src) {
7
+ return { ...item, ...getLambdaDirs(params, { plugin: true }) }
8
+ }
9
+ errors.push(`Invalid plugin-generated custom Lambda: name: ${name}, src: ${src}`)
10
+ }
@@ -1,18 +1,24 @@
1
- let { join } = require('path')
2
- let is = require('../../../lib/is')
1
+ let { is, getLambdaDirs } = require('../../../lib')
3
2
 
4
- module.exports = function populateEvents ({ item, dir, cwd, errors }) {
5
- if (is.string(item)) {
3
+ module.exports = function populateEvents (params) {
4
+ let { type, item, errors, plugin } = params
5
+ if (plugin) {
6
+ let { name, src } = item
7
+ if (name && src) {
8
+ return { ...item, ...getLambdaDirs(params, { plugin }) }
9
+ }
10
+ errors.push(`Invalid plugin-generated @${type} item: name: ${name}, src: ${src}`)
11
+ return
12
+ }
13
+ else if (is.string(item)) {
6
14
  let name = item
7
- let src = join(cwd, dir, name)
8
- return { name, src }
15
+ let dirs = getLambdaDirs(params, { name })
16
+ return { name, ...dirs }
9
17
  }
10
18
  else if (is.object(item)) {
11
19
  let name = Object.keys(item)[0]
12
- let src = item[name].src
13
- ? join(cwd, item[name].src)
14
- : join(cwd, dir, name)
15
- return { name, src }
20
+ let dirs = getLambdaDirs(params, { name, customSrc: item[name].src })
21
+ return { name, ...dirs }
16
22
  }
17
- errors.push(`Invalid @events or @queues item: ${item}`)
23
+ errors.push(`Invalid @${type} item: ${item}`)
18
24
  }
@@ -1,15 +1,25 @@
1
- let { join } = require('path')
2
1
  let { getLambdaName } = require('@architect/utils')
3
- let is = require('../../../lib/is')
2
+ let { is, getLambdaDirs } = require('../../../lib')
4
3
 
5
- module.exports = function populateHTTP ({ item, dir, cwd, errors }) {
6
- if (is.array(item) && item.length === 2) {
4
+ module.exports = function populateHTTP (params) {
5
+ let { item, errors, plugin } = params
6
+ if (plugin) {
7
+ let { method, path, src } = item
8
+ if (method && path && src) {
9
+ let name = `${method} ${path}`
10
+ let route = { name, ...item, ...getLambdaDirs(params, { plugin }) }
11
+ return route
12
+ }
13
+ errors.push(`Invalid plugin-generated @http route: method: ${method}, path: ${path}, src: ${src}`)
14
+ return
15
+ }
16
+ else if (is.array(item) && item.length === 2) {
7
17
  let method = item[0].toLowerCase()
8
18
  let path = item[1]
9
19
  let name = `${method} ${path}`
10
20
  let lambdaName = `${method}${getLambdaName(path)}`
11
- let src = join(cwd, dir, lambdaName)
12
- let route = { name, method, path, src }
21
+ let dirs = getLambdaDirs(params, { name: lambdaName })
22
+ let route = { name, method, path, ...dirs }
13
23
  return route
14
24
  }
15
25
  else if (is.object(item)) {
@@ -17,10 +27,8 @@ module.exports = function populateHTTP ({ item, dir, cwd, errors }) {
17
27
  let method = item[path].method.toLowerCase()
18
28
  let name = `${method} ${path}`
19
29
  let lambdaName = `${method}${getLambdaName(path)}`
20
- let src = item[path].src
21
- ? join(cwd, item[path].src)
22
- : join(cwd, dir, lambdaName)
23
- let route = { name, method, path, src }
30
+ let dirs = getLambdaDirs(params, { name: lambdaName, customSrc: item[path].src })
31
+ let route = { name, method, path, ...dirs }
24
32
  return route
25
33
  }
26
34
  errors.push(`Invalid @http route: ${item}`)
@@ -1,5 +1,4 @@
1
- let { join } = require('path')
2
- let is = require('../../../lib/is')
1
+ let { is, getLambdaDirs } = require('../../../lib')
3
2
 
4
3
  let coerceNumbers = str => !isNaN(Number(str)) ? Number(str) : str
5
4
 
@@ -30,10 +29,21 @@ let get = {
30
29
  }
31
30
  }
32
31
 
33
- module.exports = function populateScheduled ({ item, dir, cwd, errors }) {
32
+ module.exports = function populateScheduled (params) {
33
+ let { item, errors, plugin } = params
34
34
  let rate = null
35
35
  let cron = null
36
- if (is.array(item)) {
36
+ if (plugin) {
37
+ let { name, src } = item
38
+ if (name && src && (item.rate || item.cron)) {
39
+ if (item.rate) rate = get.rate(item.rate)
40
+ if (item.cron) cron = get.cron(item.cron)
41
+ return { ...item, rate, cron, ...getLambdaDirs(params, { plugin }) }
42
+ }
43
+ errors.push(`Invalid plugin-generated @scheduled item: name: ${name}, rate: ${item.rate}, cron: ${item.cron}, src: ${src}`)
44
+ return
45
+ }
46
+ else if (is.array(item)) {
37
47
  let name = item[0]
38
48
 
39
49
  // Hacky but it works
@@ -46,8 +56,8 @@ module.exports = function populateScheduled ({ item, dir, cwd, errors }) {
46
56
  if (isRate) rate = get.rate(clean(isRate))
47
57
  if (isCron) cron = get.cron(clean(isCron))
48
58
 
49
- let src = join(cwd, dir, name)
50
- return { name, src, rate, cron }
59
+ let dirs = getLambdaDirs(params, { name })
60
+ return { name, rate, cron, ...dirs }
51
61
  }
52
62
  else if (is.object(item)) {
53
63
  let name = Object.keys(item)[0]
@@ -64,10 +74,8 @@ module.exports = function populateScheduled ({ item, dir, cwd, errors }) {
64
74
  cron = get.cron(exp)
65
75
  }
66
76
 
67
- let src = item[name].src
68
- ? join(cwd, item[name].src)
69
- : join(cwd, dir, name)
70
- return { name, src, rate, cron }
77
+ let dirs = getLambdaDirs(params, { name, customSrc: item[name].src })
78
+ return { name, rate, cron, ...dirs }
71
79
  }
72
80
  errors.push(`Invalid @scheduled item: ${item}`)
73
81
  }
@@ -1,38 +1,35 @@
1
- let { join } = require('path')
2
- let { existsSync } = require('fs')
3
- let is = require('../../../lib/is')
1
+ let { is, getLambdaDirs } = require('../../../lib')
2
+ let ts = 'tables-streams'
4
3
 
5
- module.exports = function populateTablesStreams ({ type, item, dir, cwd, errors }) {
4
+ module.exports = function populateTablesStreams (params) {
5
+ let { type, item, errors, plugin } = params
6
6
  if (type === 'tables' && is.object(item)) {
7
7
  let name = Object.keys(item)[0]
8
- // Check for the legacy dir from before `@tables tablename stream true` generated a @tables-streams item
9
- let legacySrc = join(cwd, dir, name)
10
- let streamSrc = join(cwd, 'src', 'streams', name)
11
- let tablesStreamsSrc = join(cwd, 'src', 'tables-streams', name)
12
-
13
- let src
14
- if (existsSync(legacySrc)) src = legacySrc
15
- else if (existsSync(streamSrc)) src = streamSrc // TODO [remove] in 10.0
16
- else src = tablesStreamsSrc
17
-
18
8
  let table = name
19
- return { name, src, table }
9
+ let dirs = getLambdaDirs({ ...params, type: ts }, { name })
10
+ return { name, table, ...dirs }
11
+ }
12
+ else if (type === ts && plugin) {
13
+ let { name, src, table } = item
14
+ if (name && src && table) {
15
+ return { ...item, ...getLambdaDirs(params, { plugin }) }
16
+ }
17
+ errors.push(`Invalid plugin-generated @${type} item: name: ${name}, table: ${table}, src: ${src}`)
18
+ return
20
19
  }
21
- else if (type === 'tables-streams' && is.string(item)) {
20
+ else if (type === ts && is.string(item)) {
22
21
  let name = item
23
- let src = join(cwd, dir, name)
24
22
  let table = name
25
- return { name, src, table }
23
+ let dirs = getLambdaDirs(params, { name })
24
+ return { name, table, ...dirs }
26
25
  }
27
- else if (type === 'tables-streams' && is.object(item)) {
26
+ else if (type === ts && is.object(item)) {
28
27
  let name = Object.keys(item)[0]
29
- let src = item[name].src
30
- ? join(cwd, item[name].src)
31
- : join(cwd, dir, name)
32
28
  let table = item[name].table
33
29
  ? item[name].table
34
30
  : name
35
- return { name, src, table }
31
+ let dirs = getLambdaDirs(params, { name, customSrc: item[name].src })
32
+ return { name, table, ...dirs }
36
33
  }
37
34
  errors.push(`Invalid @${type} item: ${item}`)
38
35
  }
@@ -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
+ }