serverless-offline 10.2.1 → 10.3.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/README.md CHANGED
@@ -141,6 +141,8 @@ Used to disable cookie-validation on hapi.js-server.
141
141
 
142
142
  #### disableScheduledEvents
143
143
 
144
+ _This option is deprecated and will be removed in the next major version. If you want to disable the event, please define it in the 'events.schedule.enabled' section of the serverless config._
145
+
144
146
  Disables all scheduled events. Overrides configurations in serverless.yml.
145
147
 
146
148
  #### dockerHost
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "dedicatedTo": "Blue, a great migrating bird.",
3
3
  "name": "serverless-offline",
4
- "version": "10.2.1",
4
+ "version": "10.3.1",
5
5
  "description": "Emulate AWS λ and API Gateway locally when developing your Serverless project",
6
6
  "license": "MIT",
7
7
  "exports": {
@@ -83,10 +83,10 @@
83
83
  },
84
84
  "dependencies": {
85
85
  "@hapi/boom": "^10.0.0",
86
- "@hapi/h2o2": "^9.1.0",
86
+ "@hapi/h2o2": "^10.0.0",
87
87
  "@hapi/hapi": "^20.2.2",
88
88
  "@serverless/utils": "^6.7.0",
89
- "aws-sdk": "^2.1222.0",
89
+ "aws-sdk": "^2.1224.0",
90
90
  "boxen": "^7.0.0",
91
91
  "chalk": "^5.0.1",
92
92
  "execa": "^6.1.0",
@@ -97,7 +97,7 @@
97
97
  "jsonpath-plus": "^7.2.0",
98
98
  "jsonschema": "^1.4.1",
99
99
  "jszip": "^3.10.1",
100
- "luxon": "^3.0.3",
100
+ "luxon": "^3.0.4",
101
101
  "node-fetch": "^3.2.10",
102
102
  "node-schedule": "^2.1.0",
103
103
  "object.hasown": "^1.1.1",
@@ -109,7 +109,7 @@
109
109
  "devDependencies": {
110
110
  "@istanbuljs/esm-loader-hook": "^0.2.0",
111
111
  "archiver": "^5.3.1",
112
- "eslint": "^8.23.1",
112
+ "eslint": "^8.24.0",
113
113
  "eslint-config-airbnb-base": "^15.0.0",
114
114
  "eslint-config-prettier": "^8.5.0",
115
115
  "eslint-plugin-import": "^2.25.4",
@@ -7,7 +7,6 @@ import {
7
7
  SERVER_SHUTDOWN_TIMEOUT,
8
8
  } from './config/index.js'
9
9
  import { gray, orange } from './config/colors.js'
10
- import { createApiKey } from './utils/index.js'
11
10
 
12
11
  export default class ServerlessOffline {
13
12
  #cliOptions = null
@@ -62,6 +61,16 @@ export default class ServerlessOffline {
62
61
  async start() {
63
62
  this.#mergeOptions()
64
63
 
64
+ if (this.#options.disableScheduledEvents) {
65
+ log.notice()
66
+ log.warning(
67
+ orange(`'--disableScheduledEvents' is deprecated and will be removed in the next major version.
68
+ Please disable the event in the 'events.schedule.enabled' section of the serverless config.
69
+ If you are experiencing any issues please let us know: https://github.com/dherault/serverless-offline/issues`),
70
+ )
71
+ log.notice()
72
+ }
73
+
65
74
  const { httpEvents, lambdas, scheduleEvents, webSocketEvents } =
66
75
  this.#getEvents()
67
76
 
@@ -266,8 +275,6 @@ export default class ServerlessOffline {
266
275
 
267
276
  const functionKeys = service.getAllFunctions()
268
277
 
269
- let hasPrivateHttpEvent = false
270
-
271
278
  functionKeys.forEach((functionKey) => {
272
279
  const functionDefinition = service.getFunction(functionKey)
273
280
 
@@ -337,10 +344,6 @@ export default class ServerlessOffline {
337
344
  }
338
345
  }
339
346
 
340
- if (http?.private) {
341
- hasPrivateHttpEvent = true
342
- }
343
-
344
347
  httpEvents.push(httpEvent)
345
348
  }
346
349
 
@@ -360,31 +363,6 @@ export default class ServerlessOffline {
360
363
  })
361
364
  })
362
365
 
363
- // for simple API Key authentication model
364
- if (hasPrivateHttpEvent) {
365
- if (this.#options.apiKey) {
366
- log.notice()
367
- log.warning(
368
- orange(`'--apiKey' is deprecated and will be removed in the next major version.
369
- Please define the apiKey value in the 'provider.apiGateway.apiKeys' section of the serverless config.
370
- If you are experiencing any issues please let us know: https://github.com/dherault/serverless-offline/issues`),
371
- )
372
- log.notice()
373
- } else {
374
- this.#options.apiKey = createApiKey()
375
- }
376
-
377
- log.notice(`Key with token: ${this.#options.apiKey}`)
378
-
379
- if (this.#options.noAuth) {
380
- log.notice(
381
- `Authorizers are turned off. You do not need to use 'x-api-key' header.`,
382
- )
383
- } else {
384
- log.notice(`Remember to use 'x-api-key' on the request headers.`)
385
- }
386
- }
387
-
388
366
  return {
389
367
  httpEvents,
390
368
  lambdas,
@@ -22,46 +22,46 @@ export default {
22
22
  corsExposedHeaders: {
23
23
  type: 'string',
24
24
  usage:
25
- 'Used to build the Access-Control-Exposed-Headers response header for CORS support',
25
+ 'Used to build the Access-Control-Exposed-Headers response header for CORS support.',
26
26
  },
27
27
  disableCookieValidation: {
28
28
  type: 'boolean',
29
- usage: 'Used to disable cookie-validation on hapi.js-server',
29
+ usage: 'Used to disable cookie-validation on hapi.js-server.',
30
30
  },
31
31
  disableScheduledEvents: {
32
32
  type: 'boolean',
33
33
  usage:
34
- 'Disables all scheduled events. Overrides configurations in serverless.yml. Default: false',
34
+ '[This option is deprecated] Disables all scheduled events. Overrides configurations in serverless.yml. Default: false.',
35
35
  },
36
36
  dockerHost: {
37
37
  type: 'string',
38
- usage: 'The host name of Docker. Default: localhost',
38
+ usage: 'The host name of Docker. Default: localhost.',
39
39
  },
40
40
  dockerHostServicePath: {
41
41
  type: 'string',
42
42
  usage:
43
- 'Defines service path which is used by SLS running inside Docker container',
43
+ 'Defines service path which is used by SLS running inside Docker container.',
44
44
  },
45
45
  dockerNetwork: {
46
46
  type: 'string',
47
- usage: 'The network that the Docker container will connect to',
47
+ usage: 'The network that the Docker container will connect to.',
48
48
  },
49
49
  dockerReadOnly: {
50
50
  type: 'boolean',
51
- usage: 'Marks if the docker code layer should be read only. Default: true',
51
+ usage: 'Marks if the docker code layer should be read only. Default: true.',
52
52
  },
53
53
  enforceSecureCookies: {
54
54
  type: 'boolean',
55
- usage: 'Enforce secure cookies',
55
+ usage: 'Enforce secure cookies.',
56
56
  },
57
57
  host: {
58
58
  shortcut: 'o',
59
59
  type: 'string',
60
- usage: 'The host name to listen on. Default: localhost',
60
+ usage: 'The host name to listen on. Default: localhost.',
61
61
  },
62
62
  httpPort: {
63
63
  type: 'string',
64
- usage: 'HTTP port to listen on. Default: 3000',
64
+ usage: 'HTTP port to listen on. Default: 3000.',
65
65
  },
66
66
  httpsProtocol: {
67
67
  shortcut: 'H',
@@ -76,20 +76,20 @@ export default {
76
76
  },
77
77
  lambdaPort: {
78
78
  type: 'string',
79
- usage: 'Lambda http port to listen on. Default: 3002',
79
+ usage: 'Lambda http port to listen on. Default: 3002.',
80
80
  },
81
81
  layersDir: {
82
82
  type: 'string',
83
83
  usage:
84
- 'The directory layers should be stored in. Default: {codeDir}/.serverless-offline/layers',
84
+ 'The directory layers should be stored in. Default: {codeDir}/.serverless-offline/layers.',
85
85
  },
86
86
  localEnvironment: {
87
87
  type: 'boolean',
88
- usage: 'Copy local environment variables. Default: false',
88
+ usage: 'Copy local environment variables. Default: false.',
89
89
  },
90
90
  noAuth: {
91
91
  type: 'boolean',
92
- usage: 'Turns off all authorizers',
92
+ usage: 'Turns off all authorizers.',
93
93
  },
94
94
  noPrependStageInUrl: {
95
95
  type: 'boolean',
@@ -125,24 +125,24 @@ export default {
125
125
  },
126
126
  useDocker: {
127
127
  type: 'boolean',
128
- usage: 'Uses docker for node/python/ruby/provided',
128
+ usage: 'Uses docker for node/python/ruby/provided.',
129
129
  },
130
130
  useInProcess: {
131
131
  type: 'boolean',
132
- usage: "Run handlers in the same process as 'serverless-offline'",
132
+ usage: "Run handlers in the same process as 'serverless-offline'.",
133
133
  },
134
134
  webSocketHardTimeout: {
135
135
  type: 'string',
136
136
  usage:
137
- 'Set WebSocket hard timeout in seconds to reproduce AWS limits (https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html#apigateway-execution-service-websocket-limits-table). Default: 7200 (2 hours)',
137
+ 'Set WebSocket hard timeout in seconds to reproduce AWS limits (https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html#apigateway-execution-service-websocket-limits-table). Default: 7200 (2 hours).',
138
138
  },
139
139
  webSocketIdleTimeout: {
140
140
  type: 'string',
141
141
  usage:
142
- 'Set WebSocket idle timeout in seconds to reproduce AWS limits (https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html#apigateway-execution-service-websocket-limits-table). Default: 600 (10 minutes)',
142
+ 'Set WebSocket idle timeout in seconds to reproduce AWS limits (https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html#apigateway-execution-service-websocket-limits-table). Default: 600 (10 minutes).',
143
143
  },
144
144
  websocketPort: {
145
145
  type: 'string',
146
- usage: 'Websocket port to listen on. Default: 3001',
146
+ usage: 'Websocket port to listen on. Default: 3001.',
147
147
  },
148
148
  }
@@ -1,11 +1,19 @@
1
+ import { log } from '@serverless/utils/log.js'
1
2
  import HttpEventDefinition from './HttpEventDefinition.js'
2
3
  import HttpServer from './HttpServer.js'
4
+ import { orange } from '../../config/colors.js'
5
+ import { createApiKey } from '../../utils/index.js'
3
6
 
4
7
  export default class Http {
8
+ #hasPrivateHttpEvent = false
9
+
5
10
  #httpServer = null
6
11
 
12
+ #options = null
13
+
7
14
  constructor(serverless, options, lambda) {
8
15
  this.#httpServer = new HttpServer(serverless, options, lambda)
16
+ this.#options = options
9
17
  }
10
18
 
11
19
  start() {
@@ -30,8 +38,36 @@ export default class Http {
30
38
  create(events) {
31
39
  events.forEach(({ functionKey, handler, http }) => {
32
40
  this.#createEvent(functionKey, http, handler)
41
+
42
+ if (http.private) {
43
+ this.#hasPrivateHttpEvent = true
44
+ }
33
45
  })
34
46
 
47
+ if (this.#hasPrivateHttpEvent) {
48
+ if (this.#options.apiKey) {
49
+ log.notice()
50
+ log.warning(
51
+ orange(`'--apiKey' is deprecated and will be removed in the next major version.
52
+ Please define the apiKey value in the 'provider.apiGateway.apiKeys' section of the serverless config.
53
+ If you are experiencing any issues please let us know: https://github.com/dherault/serverless-offline/issues`),
54
+ )
55
+ log.notice()
56
+ } else {
57
+ this.#options.apiKey = createApiKey()
58
+ }
59
+
60
+ log.notice(`Key with token: ${this.#options.apiKey}`)
61
+
62
+ if (this.#options.noAuth) {
63
+ log.notice(
64
+ `Authorizers are turned off. You do not need to use 'x-api-key' header.`,
65
+ )
66
+ } else {
67
+ log.notice(`Remember to use 'x-api-key' on the request headers.`)
68
+ }
69
+ }
70
+
35
71
  this.#httpServer.writeRoutesTerminal()
36
72
  }
37
73
 
@@ -898,8 +898,6 @@ export default class HttpServer {
898
898
  }
899
899
 
900
900
  createRoutes(functionKey, httpEvent, handler) {
901
- const [handlerPath] = splitHandlerPathAndName(handler)
902
-
903
901
  let method
904
902
  let path
905
903
  let hapiPath
@@ -926,6 +924,8 @@ export default class HttpServer {
926
924
  hapiPath = generateHapiPath(path, this.#options, this.#serverless)
927
925
  }
928
926
 
927
+ const [handlerPath] = splitHandlerPathAndName(handler)
928
+
929
929
  const endpoint = new Endpoint(
930
930
  join(this.#serverless.config.servicePath, handlerPath),
931
931
  httpEvent,
@@ -129,12 +129,14 @@ export default class LambdaProxyIntegrationEventV2 {
129
129
  const requestTime = formatToClfTime(received)
130
130
  const requestTimeEpoch = received
131
131
 
132
- const cookies = entries(this.#request.state).flatMap(([key, value]) => {
133
- if (isArray(value)) {
134
- return value.map((v) => `${key}=${v}`)
135
- }
136
- return `${key}=${value}`
137
- })
132
+ const cookies = this.#request.state
133
+ ? entries(this.#request.state).flatMap(([key, value]) => {
134
+ if (isArray(value)) {
135
+ return value.map((v) => `${key}=${v}`)
136
+ }
137
+ return `${key}=${value}`
138
+ })
139
+ : undefined
138
140
 
139
141
  return {
140
142
  body,