-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathindex.js
108 lines (101 loc) · 3.36 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import {resolve, join} from 'node:path'
import {cwd} from 'node:process'
import {existsSync} from 'node:fs'
export default class ServerlessOfflineLambdaFunctionUrls {
constructor(serverless) {
const configuration = serverless.config.serverless.configurationInput
this.serverless = serverless
this.configuration = configuration
this.hooks = {
'offline:start:init': () => this.init(),
}
}
getLambdas(functions) {
return Object.entries(functions).reduce(
(lambdas, [functionKey, functionDefinition]) => [
...lambdas,
{
functionKey,
functionDefinition: {
...functionDefinition,
handler: this.getTranspiledHandlerFilepath(functionDefinition.handler),
},
},
],
[]
)
}
filterNonUrlEnabledFunctions(configuration) {
return Object.entries(configuration.functions).reduce((functions, [functionKey, functionDefinition]) => {
if (!functionDefinition.url) {
return functions
}
return {...functions, [functionKey]: functionDefinition}
}, {})
}
getEvents(functions) {
const stage = this.getStage()
const verbs = this.configuration?.custom?.['serverless-offline']?.urlLambdaFunctionsHttpVerbs ?? ['GET', 'POST']
return Object.entries(functions).reduce((events, [functionKey, {handler}]) => {
const path = `/${stage}/${encodeURIComponent(functionKey)}`
return events.concat(
verbs.map(verb => ({
functionKey,
handler,
http: {
routeKey: `${verb} ${path}`,
payload: '2.0',
isHttpApi: true,
path,
method: verb,
},
}))
)
}, [])
}
getStage() {
return this.serverless.variables.options?.stage ?? this.configuration.provider?.stage
}
mergeServerlessOfflineOptions(options) {
const stage = this.getStage()
const serverlessOfflineOptions = this.configuration?.custom?.['serverless-offline'] ?? {}
return {
...serverlessOfflineOptions,
stage,
host: serverlessOfflineOptions['host'] ?? '127.0.0.1',
httpPort: serverlessOfflineOptions['urlLambdaFunctionsHttpPort'] ?? 3003,
...options,
}
}
getTranspiledHandlerFilepath(handler) {
const webpackDir = existsSync(this.getFullPath('.webpack'))
if (webpackDir) {
return join('.webpack', 'service', handler)
}
const esbuildDir = existsSync(this.getFullPath('.esbuild'))
if (esbuildDir) {
return join('.esbuild', '.build', handler)
}
return handler
}
getFullPath(...args) {
return resolve(cwd(), ...args)
}
async init() {
const {default: Lambda} = await import(
this.getFullPath('node_modules', 'serverless-offline', 'src', 'lambda', 'Lambda.js')
)
const {default: Http} = await import(
this.getFullPath('node_modules', 'serverless-offline', 'src', 'events', 'http', 'Http.js')
)
const functions = this.filterNonUrlEnabledFunctions(this.configuration)
const lambda = new Lambda(this.serverless, this.mergeServerlessOfflineOptions({noTimeout: true}))
lambda.create(this.getLambdas(functions))
const http = new Http(this.serverless, this.mergeServerlessOfflineOptions(), lambda)
await http.createServer()
http.create(this.getEvents(functions))
http.createResourceRoutes()
http.create404Route()
await http.start()
}
}