serverless-plugin-warmup 5.3.1 → 7.0.0

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/.eslintignore CHANGED
@@ -1 +1,2 @@
1
- coverage
1
+ coverage
2
+ test_integration
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2020 Juanjo Diaz
3
+ Copyright (c) 2021 Juanjo Diaz
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -2,14 +2,15 @@
2
2
  [![Serverless][serverless-badge]](serverless-badge-url)
3
3
  [![npm version][npm-version-badge]][npm-version-badge-url]
4
4
  [![npm monthly downloads][npm-downloads-badge]][npm-version-badge-url]
5
- [![Build Status][travis-badge]][travis-badge-url]
5
+ [![Node.js CI](https://github.com/juanjoDiaz/serverless-plugin-warmup/actions/workflows/on-push.yaml/badge.svg)](https://github.com/juanjoDiaz/serverless-plugin-warmup/actions/workflows/on-push.yaml)
6
6
  [![Coverage Status][coveralls-badge]][coveralls-badge-url]
7
7
  [![license](https://img.shields.io/npm/l/serverless-plugin-warmup.svg)](https://raw.githubusercontent.com/juanjoDiaz/serverless-plugin-warmup/master/LICENSE)
8
8
 
9
9
  Keep your lambdas warm during winter.
10
10
 
11
11
  **Requirements:**
12
- * Serverless *v1.12.x* or higher (Recommended *v1.33.x* or higher because of [this](https://github.com/juanjoDiaz/serverless-plugin-warmup/pull/69)).
12
+ * Node *v14.x* or higher
13
+ * Serverless *v3.x* or higher
13
14
  * AWS provider
14
15
 
15
16
  ## How it works
@@ -43,6 +44,7 @@ custom:
43
44
  events:
44
45
  - schedule: cron(0/5 8-17 ? * MON-FRI *)
45
46
  concurrency: 10
47
+ logRetentionInDays: 10
46
48
  outOfOfficeHoursWarmer:
47
49
  enabled: true
48
50
  events:
@@ -64,10 +66,11 @@ The options are the same for all the warmers:
64
66
  * **vpc** The VPC and subnets in which to deploy. Can be any [Serverless VPC configuration](https://serverless.com/framework/docs/providers/aws/guide/functions#vpc-configuration) or be set to `false` in order to deploy the warmup function outside of a VPC (defaults to the vpc in the provider)
65
67
  * **memorySize** The memory to be assigned to the warmer lambda (defaults to `128`)
66
68
  * **events** The event that triggers the warmer lambda. Can be any [Serverless event](https://serverless.com/framework/docs/providers/aws/events/) (defaults to `- schedule: rate(5 minutes)`)
67
- * **package** The package configuration. Can be any [Serverless package configuration](https://serverless.com/framework/docs/providers/aws/guide/packaging#package-configuration) (defaults to `{ individually: true, exclude: ['**'], include: ['.warmup/${warmerName}/**'] }`)
69
+ * **package** The package configuration. Can be any [Serverless package configuration](https://serverless.com/framework/docs/providers/aws/guide/packaging#package-configuration) (defaults to `{ individually: true, patterns: ['!**', '.warmup/${warmerName}/**'] }`)
68
70
  * **timeout** How many seconds until the warmer lambda times out. (defaults to `10`)
69
71
  * **environment** Can be used to set environment variables in the warmer lambda. You can also unset variables configured at the provider by setting them to undefined. However, you should almost never have to change the default. (defaults to unset all package level environment variables. )
70
72
  * **tracing** Specify whether to enable/disable tracing at the function level. When tracing is enabled, warmer functions will use NPM to install the X-Ray client and use it to trace requests (It takes any of the values supported by serverless as `boolean`, `Active`or `PassThrough` and defaults to the provider-level setting)
73
+ * **logRetentionInDays** Set the retention time in days for the log group associated to this warmer lamba
71
74
  * **prewarm** If set to true, it warms up your lambdas right after deploying (defaults to `false`)
72
75
 
73
76
  There are also some options which can be set under `custom.warmup.<yourWarmer>` to be applied to all your lambdas or under `yourLambda.warmup.<yourWarmer>` to overridde the global configuration for that particular lambda. Keep in mind that in order to configure a warmer at the function level, it needed to be previously configured at the `custom` section or the pluging will error.
@@ -97,13 +100,13 @@ custom:
97
100
  - schedule: 'cron(0/5 8-17 ? * MON-FRI *)' # Run WarmUp every 5 minutes Mon-Fri between 8:00am and 5:55pm (UTC)
98
101
  package:
99
102
  individually: true
100
- exclude: # exclude additional binaries that are included at the serverless package level
101
- - ../**
102
- - ../../**
103
- include:
103
+ patterns:
104
+ - '!../**'
105
+ - '!../../**'
104
106
  - ./**
105
107
  timeout: 20
106
108
  tracing: true
109
+ logRetentionInDays: 10
107
110
  prewarm: true # Run WarmUp immediately after a deploymentlambda
108
111
  clientContext:
109
112
  source: my-custom-source
@@ -450,6 +453,39 @@ The `warmers` flag takes a comma-separated list of warmer names. If it's nor pro
450
453
 
451
454
  ## Migrations
452
455
 
456
+ ### v5.X to v6.X
457
+
458
+ #### Removed include/exclude in favour of patterns
459
+
460
+ From Serverless 2.32.0 the `patterns` option is the recommended approach to include/exclude files from packaging. In version 3.X, the `include` and `exclude` are removed.
461
+
462
+ This plugin applies the same philosophy.
463
+
464
+ What used to be:
465
+ ```yaml
466
+ custom:
467
+ warmup:
468
+ default:
469
+ enabled: 'prod'
470
+ package:
471
+ individually: true
472
+ exclude: '../**',
473
+ include: 'myFolder'
474
+ ```
475
+
476
+ is the same as
477
+ ```yaml
478
+ custom:
479
+ warmup:
480
+ default:
481
+ enabled: 'prod'
482
+ package:
483
+ individually: true
484
+ patterns:
485
+ - '!../**',
486
+ - 'myFolder'
487
+ ```
488
+
453
489
  ### v4.X to v5.X
454
490
 
455
491
  #### Support multiple warmer
@@ -568,8 +604,6 @@ This software is released under the MIT license. See [the license file](LICENSE)
568
604
  [npm-version-badge]: https://badge.fury.io/js/serverless-plugin-warmup.svg
569
605
  [npm-version-badge-url]: https://www.npmjs.com/package/serverless-plugin-warmup
570
606
  [npm-downloads-badge]: https://img.shields.io/npm/dm/serverless-plugin-warmup.svg
571
- [travis-badge]: https://travis-ci.org/juanjoDiaz/serverless-plugin-warmup.svg
572
- [travis-badge-url]: https://travis-ci.org/juanjoDiaz/serverless-plugin-warmup
573
607
  [coveralls-badge]: https://coveralls.io/repos/juanjoDiaz/serverless-plugin-warmup/badge.svg?branch=master
574
608
  [coveralls-badge-url]: https://coveralls.io/r/juanjoDiaz/serverless-plugin-warmup?branch=master
575
609
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "serverless-plugin-warmup",
3
- "version": "5.3.1",
3
+ "version": "7.0.0",
4
4
  "description": "Keep your lambdas warm during winter.",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -31,10 +31,10 @@
31
31
  "homepage": "https://github.com/juanjoDiaz/serverless-plugin-warmup",
32
32
  "dependencies": {},
33
33
  "devDependencies": {
34
- "eslint": "^7.28.0",
35
- "eslint-config-airbnb-base": "^14.2.1",
36
- "eslint-plugin-import": "^2.23.4",
37
- "husky": "^6.0.0",
38
- "jest": "^27.0.4"
34
+ "eslint": "^8.5.0",
35
+ "eslint-config-airbnb-base": "^15.0.0",
36
+ "eslint-plugin-import": "^2.24.2",
37
+ "husky": "^7.0.2",
38
+ "jest": "^27.2.0"
39
39
  }
40
40
  }
package/src/config.js CHANGED
@@ -25,18 +25,15 @@ function getWarmerConfig(config, defaultOpts) {
25
25
  individually: (config.package.individually !== undefined)
26
26
  ? config.package.individually
27
27
  : defaultOpts.package.individually,
28
- exclude: Array.isArray(config.package.exclude)
29
- ? config.package.exclude
30
- : defaultOpts.package.exclude,
31
- include: Array.isArray(config.package.include)
32
- ? (config.package.include.includes(path.join(folderName, '**'))
33
- ? config.package.include
34
- : [...config.package.include, path.join(folderName, '**')])
35
- : [...defaultOpts.package.include, path.join(folderName, '**')],
28
+ patterns: ['!**', ...Array.isArray(config.package.patterns)
29
+ ? (config.package.patterns.includes(path.join(folderName, '**'))
30
+ ? config.package.patterns
31
+ : [...config.package.patterns, path.join(folderName, '**')])
32
+ : [...defaultOpts.package.patterns, path.join(folderName, '**')]],
36
33
  }
37
34
  : {
38
35
  ...defaultOpts.package,
39
- include: [...defaultOpts.package.include, path.join(folderName, '**')],
36
+ patterns: ['!**', ...defaultOpts.package.patterns, path.join(folderName, '**')],
40
37
  },
41
38
  memorySize: (config.memorySize !== undefined) ? config.memorySize : defaultOpts.memorySize,
42
39
  timeout: (config.timeout !== undefined) ? config.timeout : defaultOpts.timeout,
@@ -44,6 +41,9 @@ function getWarmerConfig(config, defaultOpts) {
44
41
  ? config.environment
45
42
  : defaultOpts.environment,
46
43
  tracing: (config.tracing !== undefined) ? config.tracing : defaultOpts.tracing,
44
+ logRetentionInDays: (config.logRetentionInDays !== undefined)
45
+ ? config.logRetentionInDays
46
+ : defaultOpts.logRetentionInDays,
47
47
  prewarm: (config.prewarm !== undefined) ? config.prewarm : defaultOpts.prewarm,
48
48
  };
49
49
  /* eslint-enable no-nested-ternary */
@@ -82,7 +82,7 @@ function getFunctionConfig(config, defaultOpts) {
82
82
  *
83
83
  * @return {Array} - List of functions to be warmed up and their specific configs
84
84
  * */
85
- function getFunctionsByWarmer(service, stage, configsByWarmer) {
85
+ function getFunctionsByWarmer(service, stage, configsByWarmer, serverlessClasses) {
86
86
  const functions = service.getAllFunctions()
87
87
  .map((name) => service.getFunction(name))
88
88
  .map((config) => {
@@ -100,7 +100,7 @@ function getFunctionsByWarmer(service, stage, configsByWarmer) {
100
100
  const unknownWarmers = Object.keys(config.warmup)
101
101
  .filter((warmerName) => configsByWarmer[warmerName] === undefined);
102
102
  if (unknownWarmers.length > 0) {
103
- throw new Error(`WarmUp: Invalid function-level warmup configuration (${unknownWarmers.join(', ')}) in function ${config.name}. Every warmer should be declared in the custom section.`);
103
+ throw new serverlessClasses.Error(`WarmUp: Invalid function-level warmup configuration (${unknownWarmers.join(', ')}) in function ${config.name}. Every warmer should be declared in the custom section.`);
104
104
  }
105
105
 
106
106
  return {
@@ -137,7 +137,7 @@ function getFunctionsByWarmer(service, stage, configsByWarmer) {
137
137
  *
138
138
  * @return {Object} - Configuration options to be used by the plugin
139
139
  * */
140
- function getConfigsByWarmer(service, stage) {
140
+ function getConfigsByWarmer({ service, classes }, stage) {
141
141
  const getWarmerDefaultOpts = (warmerName) => ({
142
142
  folderName: path.join('.warmup', warmerName),
143
143
  cleanFolder: true,
@@ -146,13 +146,7 @@ function getConfigsByWarmer(service, stage) {
146
146
  events: [{ schedule: 'rate(5 minutes)' }],
147
147
  package: {
148
148
  individually: true,
149
- // Negating the includes to work around https://github.com/serverless/serverless/issues/8093
150
- include: service.package && service.package.include
151
- ? service.package.include
152
- .filter((pattern) => !pattern.startsWith('!'))
153
- .map((pattern) => `!${pattern}`)
154
- : [],
155
- exclude: ['**'],
149
+ patterns: [],
156
150
  },
157
151
  timeout: 10,
158
152
  environment: Object.keys(service.provider.environment || [])
@@ -176,7 +170,7 @@ function getConfigsByWarmer(service, stage) {
176
170
  },
177
171
  }), {});
178
172
 
179
- const functionsByWarmer = getFunctionsByWarmer(service, stage, configsByWarmer);
173
+ const functionsByWarmer = getFunctionsByWarmer(service, stage, configsByWarmer, classes);
180
174
 
181
175
  return Object.entries(configsByWarmer).reduce((warmers, [warmerName, warmerConfig]) => ({
182
176
  ...warmers,
package/src/index.js CHANGED
@@ -28,12 +28,13 @@ class WarmUp {
28
28
  * @constructor
29
29
  *
30
30
  * @param {!Object} serverless - Serverless object
31
- * @param {!Object} options - Serverless options
31
+ * @param {!Object} cliOptions - Serverless cliOptions
32
32
  * */
33
- constructor(serverless, options) {
33
+ constructor(serverless, cliOptions, { log }) {
34
34
  /** Serverless variables */
35
35
  this.serverless = serverless;
36
- this.options = options;
36
+ this.cliOptions = cliOptions;
37
+ this.log = log;
37
38
 
38
39
  this.provider = this.serverless.getProvider('aws');
39
40
 
@@ -46,7 +47,7 @@ class WarmUp {
46
47
  cleanupTempDir: { lifecycleEvents: ['cleanup'] },
47
48
  prewarm: {
48
49
  lifecycleEvents: ['start', 'end'],
49
- options: {
50
+ cliOptions: {
50
51
  warmers: {
51
52
  shortcut: 'w',
52
53
  usage: 'Comma-separated list of warmer names to prewarm.',
@@ -85,7 +86,7 @@ class WarmUp {
85
86
  configPlugin() {
86
87
  this.stage = this.stage || this.provider.getStage();
87
88
  this.configsByWarmer = this.configsByWarmer
88
- || getConfigsByWarmer(this.serverless.service, this.stage);
89
+ || getConfigsByWarmer(this.serverless, this.stage);
89
90
  }
90
91
 
91
92
  /**
@@ -116,13 +117,13 @@ class WarmUp {
116
117
 
117
118
  await Promise.all(foldersToClean.map(async (folderToClean) => {
118
119
  try {
119
- await fs.rmdir(
120
+ await fs.rm(
120
121
  path.join(this.serviceDir, folderToClean),
121
122
  { recursive: true },
122
123
  );
123
124
  } catch (err) {
124
125
  if (err.code !== 'ENOENT') {
125
- this.serverless.cli.log(`WarmUp: Couldn't clean up temporary folder ${folderToClean}.`);
126
+ this.log.error(`WarmUp: Couldn't clean up temporary folder ${folderToClean}.`);
126
127
  }
127
128
  }
128
129
  }));
@@ -133,11 +134,11 @@ class WarmUp {
133
134
  foldersToClean.some((folder) => folder.startsWith('.warmup'))
134
135
  && (await fs.readdir(defaultDir)).length === 0
135
136
  ) {
136
- await fs.rmdir(defaultDir, { recursive: true });
137
+ await fs.rm(defaultDir, { recursive: true });
137
138
  }
138
139
  } catch (err) {
139
140
  if (err.code !== 'ENOENT') {
140
- this.serverless.cli.log('WarmUp: Couldn\'t clean up temporary folder .warmup.');
141
+ this.log.error('WarmUp: Couldn\'t clean up temporary folder .warmup.');
141
142
  }
142
143
  }
143
144
  }
@@ -151,8 +152,8 @@ class WarmUp {
151
152
  * @return {Promise}
152
153
  * */
153
154
  async prewarmFunctions() {
154
- const warmerNames = (this.options.warmers)
155
- ? this.options.warmers.split(',')
155
+ const warmerNames = (this.cliOptions.warmers)
156
+ ? this.cliOptions.warmers.split(',')
156
157
  : Object.entries(this.configsByWarmer)
157
158
  .filter(([, warmerConfig]) => warmerConfig.prewarm)
158
159
  .map(([warmerName]) => warmerName);
@@ -160,7 +161,7 @@ class WarmUp {
160
161
  await Promise.all(warmerNames.map(async (warmerName) => {
161
162
  const warmerConfig = this.configsByWarmer[warmerName];
162
163
  if (!warmerConfig) {
163
- throw new Error(`Warmer names ${warmerName} doesn't exist.`);
164
+ throw new this.serverless.classes.Error(`Warmer names ${warmerName} doesn't exist.`);
164
165
  }
165
166
  addWarmUpFunctionToService(this.serverless.service, warmerName, warmerConfig);
166
167
  await this.invokeWarmer(warmerName, warmerConfig);
@@ -173,12 +174,19 @@ class WarmUp {
173
174
  * */
174
175
  async configureWarmer(warmerName, warmerConfig) {
175
176
  if (warmerConfig.functions.length === 0) {
176
- this.serverless.cli.log(`WarmUp: Skipping warmer "${warmerName}" creation. No functions to warm up.`);
177
+ this.log.warning(`WarmUp: Skipping warmer "${warmerName}" creation. No functions to warm up.`);
177
178
  return;
178
179
  }
179
180
 
180
- this.serverless.cli.log(`WarmUp: Creating warmer "${warmerName}" to warm up ${warmerConfig.functions.length} function${warmerConfig.functions.length === 1 ? '' : 's'}:`);
181
- warmerConfig.functions.forEach((func) => this.serverless.cli.log(` * ${func.name}`));
181
+ // Avoid double processing due to the workaround for webpack/bundle plugins
182
+ // resetting the plugin and ignoring changes
183
+ if (this.serverless.service.functions[`warmUpPlugin${capitalize(warmerName)}`]) {
184
+ return;
185
+ }
186
+
187
+ this.log.notice(`WarmUp: Creating warmer "${warmerName}" to warm up ${warmerConfig.functions.length} function${warmerConfig.functions.length === 1 ? '' : 's'}`);
188
+ this.log.info(':');
189
+ warmerConfig.functions.forEach((func) => this.log.info(` * ${func.name}`));
182
190
 
183
191
  const handlerFolder = path.join(this.serviceDir, warmerConfig.folderName);
184
192
 
@@ -203,11 +211,11 @@ class WarmUp {
203
211
 
204
212
  async invokeWarmer(warmerName, warmerConfig) {
205
213
  if (warmerConfig.functions.length === 0) {
206
- this.serverless.cli.log(`WarmUp: Skipping prewarming using warmer "${warmerName}". No functions to warm up.`);
214
+ this.log.warning(`WarmUp: Skipping prewarming using warmer "${warmerName}". No functions to warm up.`);
207
215
  return;
208
216
  }
209
217
 
210
- this.serverless.cli.log(`WarmUp: Prewarming up you functions using warmer "${warmerName}".`);
218
+ this.log.notice(`WarmUp: Prewarming up your functions using warmer "${warmerName}".`);
211
219
 
212
220
  try {
213
221
  const { SERVERLESS_ALIAS } = this.serverless.service.getFunction(`warmUpPlugin${capitalize(warmerName)}`).environment || {};
@@ -220,9 +228,9 @@ class WarmUp {
220
228
  };
221
229
 
222
230
  await this.provider.request('Lambda', 'invoke', params);
223
- this.serverless.cli.log(`WarmUp: Warmer "${warmerName}" successfully prewarmed your functions.`);
231
+ this.log.notice(`WarmUp: Warmer "${warmerName}" successfully prewarmed your functions.`);
224
232
  } catch (err) {
225
- this.serverless.cli.log(`WarmUp: Error while prewarming your functions using warmer "${warmerName}".`, err);
233
+ this.log.error(`WarmUp: Error while prewarming your functions using warmer "${warmerName}".`, err);
226
234
  }
227
235
  }
228
236
  }
package/src/schema.js CHANGED
@@ -5,7 +5,7 @@ function extendServerlessSchema(serverless) {
5
5
  // Most of these are taken from
6
6
  // https://github.com/serverless/serverless/blob/master/lib/configSchema.js
7
7
  // https://github.com/serverless/serverless/blob/master/lib/plugins/aws/provider.js
8
- // https://github.com/serverless/serverless/blob/master/lib/plugins/aws/package/compile/events/schedule/index.js
8
+ // https://github.com/serverless/serverless/blob/master/lib/plugins/aws/package/compile/events/schedule.js
9
9
 
10
10
  const rateSyntax = '^rate\\((?:1 (?:minute|hour|day)|(?:1\\d+|[2-9]\\d*) (?:minute|hour|day)s)\\)$';
11
11
  const cronSyntax = '^cron\\(\\S+ \\S+ \\S+ \\S+ \\S+ \\S+\\)$';
@@ -27,67 +27,78 @@ function extendServerlessSchema(serverless) {
27
27
  type: 'array',
28
28
  items: {
29
29
  type: 'object',
30
- anyOf: [
31
- { type: 'string', pattern: scheduleSyntax },
32
- {
33
- type: 'object',
34
- properties: {
35
- rate: { type: 'string', pattern: scheduleSyntax },
36
- enabled: { type: 'boolean' },
37
- alias: { type: 'string' },
38
- name: {
39
- type: 'string', minLength: 1, maxLength: 64, pattern: '[\\.\\-_A-Za-z0-9]+',
30
+ properties: {
31
+ schedule: {
32
+ anyOf: [
33
+ { type: 'string', pattern: scheduleSyntax },
34
+ {
35
+ type: 'object',
36
+ properties: {
37
+ rate: {
38
+ type: 'array',
39
+ minItems: 1,
40
+ items: {
41
+ type: 'string',
42
+ pattern: scheduleSyntax,
43
+ },
44
+ },
45
+ enabled: { type: 'boolean' },
46
+ name: {
47
+ type: 'string', minLength: 1, maxLength: 64, pattern: '[\\.\\-_A-Za-z0-9]+',
48
+ },
49
+ description: { type: 'string', maxLength: 512 },
50
+ input: {
51
+ anyOf: [
52
+ { type: 'string', maxLength: 8192 },
53
+ {
54
+ type: 'object',
55
+ oneOf: [
56
+ {
57
+ properties: {
58
+ body: { type: 'string', maxLength: 8192 },
59
+ },
60
+ required: ['body'],
61
+ additionalProperties: false,
62
+ },
63
+ {
64
+ not: {
65
+ required: ['body'],
66
+ },
67
+ },
68
+ ],
69
+ },
70
+ ],
71
+ },
72
+ inputPath: { type: 'string', maxLength: 256 },
73
+ inputTransformer: {
74
+ type: 'object',
75
+ properties: {
76
+ inputTemplate: {
77
+ type: 'string',
78
+ minLength: 1,
79
+ maxLength: 8192,
80
+ },
81
+ inputPathsMap: { type: 'object' },
82
+ },
83
+ required: ['inputTemplate'],
84
+ additionalProperties: false,
85
+ },
86
+ },
87
+ required: ['rate'],
88
+ additionalProperties: false,
40
89
  },
41
- description: { type: 'string', maxLength: 512 },
42
- // input: {
43
- // anyOf: [
44
- // { type: 'string', maxLength: 8192 },
45
- // {
46
- // type: 'object',
47
- // oneOf: [
48
- // {
49
- // properties: {
50
- // body: { type: 'string', maxLength: 8192 },
51
- // },
52
- // required: ['body'],
53
- // additionalProperties: false,
54
- // },
55
- // {
56
- // not: {
57
- // required: ['body'],
58
- // },
59
- // },
60
- // ],
61
- // },
62
- // ],
63
- // },
64
- // inputPath: { type: 'string', maxLength: 256 },
65
- // inputTransformer: {
66
- // type: 'object',
67
- // properties: {
68
- // inputTemplate: {
69
- // type: 'string',
70
- // minLength: 1,
71
- // maxLength: 8192,
72
- // },
73
- // inputPathsMap: { type: 'object' },
74
- // },
75
- // required: ['inputTemplate'],
76
- // additionalProperties: false,
77
- // },
78
- },
79
- required: ['rate'],
80
- additionalProperties: false,
90
+ ],
81
91
  },
82
- ],
92
+ },
93
+ required: ['schedule'],
94
+ additionalProperties: false,
83
95
  },
84
96
  },
85
97
  package: {
86
98
  type: 'object',
87
99
  properties: {
88
100
  artifact: { type: 'string' },
89
- exclude: { type: 'array', items: { type: 'string' } },
90
- include: { type: 'array', items: { type: 'string' } },
101
+ patterns: { type: 'array', items: { type: 'string' } },
91
102
  individually: { type: 'boolean' },
92
103
  },
93
104
  additionalProperties: false,
@@ -96,6 +107,10 @@ function extendServerlessSchema(serverless) {
96
107
  timeout: { $ref: '#/definitions/awsLambdaTimeout' },
97
108
  environment: { $ref: '#/definitions/awsLambdaEnvironment' },
98
109
  tracing: { $ref: '#/definitions/awsLambdaTracing' },
110
+ logRetentionInDays: {
111
+ type: 'number',
112
+ enum: [1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653],
113
+ },
99
114
  prewarm: { type: 'boolean' },
100
115
  };
101
116
 
@@ -124,10 +139,13 @@ function extendServerlessSchema(serverless) {
124
139
  serverless.configSchemaHandler.defineCustomProperties({
125
140
  properties: {
126
141
  warmup: {
127
- '.*': {
128
- type: 'object',
129
- properties: { ...globalConfigSchemaProperties, ...functionConfigSchemaProperties },
130
- additionalProperties: false,
142
+ type: 'object',
143
+ patternProperties: {
144
+ '.*': {
145
+ type: 'object',
146
+ properties: { ...globalConfigSchemaProperties, ...functionConfigSchemaProperties },
147
+ additionalProperties: false,
148
+ },
131
149
  },
132
150
  },
133
151
  },
@@ -139,10 +157,13 @@ function extendServerlessSchema(serverless) {
139
157
  type: 'object',
140
158
  properties: {
141
159
  warmup: {
142
- '.*': {
143
- type: 'object',
144
- properties: { functionConfigSchemaProperties },
145
- additionalProperties: false,
160
+ type: 'object',
161
+ patternProperties: {
162
+ '.*': {
163
+ type: 'object',
164
+ properties: functionConfigSchemaProperties,
165
+ additionalProperties: false,
166
+ },
146
167
  },
147
168
  },
148
169
  },
package/src/warmer.js CHANGED
@@ -225,9 +225,13 @@ function addWarmUpFunctionToService(service, warmerName, warmerConfig) {
225
225
  ? { environment: warmerConfig.environment }
226
226
  : {}),
227
227
  ...(warmerConfig.tracing !== undefined ? { tracing: warmerConfig.tracing } : {}),
228
+ ...(warmerConfig.logRetentionInDays !== undefined
229
+ ? { logRetentionInDays: warmerConfig.logRetentionInDays }
230
+ : {}),
228
231
  ...(warmerConfig.role ? { role: warmerConfig.role } : {}),
229
232
  ...(warmerConfig.tags ? { tags: warmerConfig.tags } : {}),
230
233
  ...(warmerConfig.vpc ? { vpc: warmerConfig.vpc } : {}),
234
+ layers: [],
231
235
  };
232
236
  }
233
237