@architect/inventory 6.1.0-RC.0 → 6.1.0-RC.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@architect/inventory",
3
- "version": "6.1.0-RC.0",
3
+ "version": "6.1.0-RC.1",
4
4
  "description": "Architect project resource enumeration utility",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -8,7 +8,7 @@
8
8
  "test": "npm run lint && npm run test:integration && npm run test:coverage",
9
9
  "test:integration": "node --test --test-reporter=spec test/integration/*-test.js",
10
10
  "test:coverage": "node --test --test-reporter=spec --experimental-test-coverage --test-coverage-lines=100 --test-coverage-exclude='test/**/*' 'test/unit/**/*-test.js'",
11
- "test:unit": "node --test --test-reporter=spec --test-coverage-exclude='test/**/*' 'test/unit/**/*-test.js'",
11
+ "test:unit": "node --test --test-reporter=spec 'test/unit/**/*-test.js'",
12
12
  "rc": "npm version prerelease --preid RC",
13
13
  "vendor": "scripts/vendor"
14
14
  },
@@ -33,12 +33,14 @@ module.exports = function populateScheduled (params) {
33
33
  let { item, errors, plugin } = params
34
34
  let rate = null
35
35
  let cron = null
36
+ let timezone = null
36
37
  if (plugin) {
37
38
  let { name, src } = item
38
39
  if (name && src && (item.rate || item.cron)) {
39
40
  if (item.rate) rate = get.rate(item.rate)
40
41
  if (item.cron) cron = get.cron(item.cron)
41
- return { ...item, rate, cron, ...getLambdaDirs(params, { plugin }) }
42
+ if (item.timezone) timezone = item.timezone
43
+ return { ...item, rate, cron, timezone, ...getLambdaDirs(params, { plugin }) }
42
44
  }
43
45
  errors.push(`Invalid plugin-generated @scheduled item: name: ${name}, rate: ${item.rate}, cron: ${item.cron}, src: ${src}`)
44
46
  return
@@ -57,12 +59,12 @@ module.exports = function populateScheduled (params) {
57
59
  if (isCron) cron = get.cron(clean(isCron))
58
60
 
59
61
  let dirs = getLambdaDirs(params, { name })
60
- return { name, rate, cron, ...dirs }
62
+ return { name, rate, cron, timezone, ...dirs }
61
63
  }
62
64
  else if (is.object(item)) {
63
65
  let name = Object.keys(item)[0]
64
66
 
65
- // Handle rate + cron props
67
+ // Handle rate + cron + timezone props
66
68
  if (item[name].rate) {
67
69
  let itemRate = item[name].rate
68
70
  let exp = is.array(itemRate) ? itemRate.join(' ') : itemRate
@@ -73,9 +75,12 @@ module.exports = function populateScheduled (params) {
73
75
  let exp = is.array(itemCron) ? itemCron.join(' ') : itemCron
74
76
  cron = get.cron(exp)
75
77
  }
78
+ if (item[name].timezone) {
79
+ timezone = item[name].timezone
80
+ }
76
81
 
77
82
  let dirs = getLambdaDirs(params, { name, customSrc: item[name].src })
78
- return { name, rate, cron, ...dirs }
83
+ return { name, rate, cron, timezone, ...dirs }
79
84
  }
80
85
  errors.push(`Invalid @scheduled item: ${item}`)
81
86
  }
@@ -174,7 +174,7 @@ function populate (type, pragma, inventory, errors, plugin) {
174
174
  let normalize = path => path.replace(/[\\\/]/g, sep)
175
175
 
176
176
  // Lambda setter plugins can technically return anything, so this ensures everything is tidy
177
- let lambdaProps = [ 'cron', 'batchSize', 'batchWindow', 'fifo', 'method', 'path', 'plugin', 'rate', 'route', 'table', 'type' ]
177
+ let lambdaProps = [ 'cron', 'batchSize', 'batchWindow', 'fifo', 'method', 'path', 'plugin', 'rate', 'route', 'table', 'timezone', 'type' ]
178
178
  let configProps = [ ...Object.keys(defaultFunctionConfig()), 'fifo', 'views' ]
179
179
  let getKnownProps = (knownProps, raw = {}) => {
180
180
  let props = knownProps.flatMap(prop => is.defined(raw[prop]) ? [ [ prop, raw[prop] ] ] : [])
@@ -43,13 +43,13 @@ module.exports = function validateEventsAndQueues (pragma, pragmaName, errors) {
43
43
  if (event.pragma === 'queues') {
44
44
  let { fifo, batchSize, batchWindow } = event
45
45
  if (!is.nullish(fifo) && !is.bool(fifo)) {
46
- errors.push(`Invalid ${pragmaName} item (fifo must be a boolean): ${name}`)
46
+ errors.push(`Invalid ${pragmaName} item (fifo must be a boolean): ${name}`)
47
47
  }
48
48
  if (!is.nullish(batchSize) && !is.number(batchSize)) {
49
- errors.push(`Invalid ${pragmaName} item (batchSize must be a number): ${name}`)
49
+ errors.push(`Invalid ${pragmaName} item (batchSize must be a number): ${name}`)
50
50
  }
51
51
  if (!is.nullish(batchWindow) && !is.number(batchWindow)) {
52
- errors.push(`Invalid ${pragmaName} item (batchWindow must be a number): ${name}`)
52
+ errors.push(`Invalid ${pragmaName} item (batchWindow must be a number): ${name}`)
53
53
  }
54
54
  }
55
55
  })
@@ -14,7 +14,7 @@ module.exports = function validateScheduled (scheduled, errors) {
14
14
  unique(scheduled, '@scheduled', errors)
15
15
 
16
16
  scheduled.forEach(schedule => {
17
- let { name, rate, cron } = schedule
17
+ let { name, rate, cron, timezone } = schedule
18
18
  regex(name, 'veryLooseName', '@scheduled', errors)
19
19
 
20
20
  // Assume 14 chars are taken up by resource naming in arc/package
@@ -22,6 +22,7 @@ module.exports = function validateScheduled (scheduled, errors) {
22
22
 
23
23
  if (cron) validateCron(schedule, errors)
24
24
  if (rate) validateRate(schedule, errors)
25
+ if (timezone) validateTimezone(schedule, errors)
25
26
 
26
27
  if (!cron && !rate) errors.push(`Invalid @scheduled item (no cron or rate expression found): ${name}`)
27
28
  if (cron && rate) errors.push(`Invalid @scheduled item (use either cron or rate, not both): ${name}`)
@@ -53,6 +54,22 @@ function validateCron (schedule, errors) {
53
54
  if (!year.toString().match(minHrYr)) expErr('year', year)
54
55
  }
55
56
 
57
+ function validateTimezone (schedule, errors) {
58
+ let { name, timezone } = schedule
59
+ if (!is.string(timezone) || !timezone.length) {
60
+ errors.push(`Invalid @scheduled item (timezone must be a non-empty string): ${name}`)
61
+ }
62
+ else {
63
+ // AWS EventBridge accepts IANA timezone identifiers (e.g., America/New_York, Europe/London)
64
+ try {
65
+ Intl.DateTimeFormat(undefined, { timeZone: timezone })
66
+ }
67
+ catch {
68
+ errors.push(`Invalid @scheduled item (timezone must be a valid IANA timzone identifier): ${name}`)
69
+ }
70
+ }
71
+ }
72
+
56
73
  let singular = [ 'minute', 'hour', 'day' ]
57
74
  let plural = [ 'minutes', 'hours', 'days' ]
58
75
  function validateRate (schedule, errors) {