diff --git a/src/ServerlessOffline.js b/src/ServerlessOffline.js index 4a9e93f7b..744207d97 100644 --- a/src/ServerlessOffline.js +++ b/src/ServerlessOffline.js @@ -60,21 +60,11 @@ export default class ServerlessOffline { 'offline:start:init': this.start.bind(this), 'offline:start:ready': this.ready.bind(this), 'offline:functionsUpdated:cleanup': this.cleanupFunctions.bind(this), - 'offline:start': this._startWithExplicitEnd.bind(this), + 'offline:start': this.#startWithExplicitEnd.bind(this), 'offline:start:end': this.end.bind(this), } } - _printBlankLine() { - if (env.NODE_ENV !== 'test') { - if (this.log) { - this.log.notice() - } else { - console.log() - } - } - } - // Entry point for the plugin (sls offline) when running 'sls offline start' async start() { // Put here so available everywhere, not just in handlers @@ -83,7 +73,7 @@ export default class ServerlessOffline { // check if update is available updateNotifier({ pkg }).notify() - this._verifyServerlessVersionCompatibility() + this.#verifyServerlessVersionCompatibility() this._mergeOptions() @@ -101,11 +91,11 @@ export default class ServerlessOffline { } if (!this.#options.disableScheduledEvents && scheduleEvents.length > 0) { - eventModules.push(this._createSchedule(scheduleEvents)) + eventModules.push(this.#createSchedule(scheduleEvents)) } if (webSocketEvents.length > 0) { - eventModules.push(this._createWebSocket(webSocketEvents)) + eventModules.push(this.#createWebSocket(webSocketEvents)) } await Promise.all(eventModules) @@ -113,7 +103,7 @@ export default class ServerlessOffline { async ready() { if (env.NODE_ENV !== 'test') { - await this._listenForTermination() + await this.#listenForTermination() } } @@ -168,13 +158,13 @@ export default class ServerlessOffline { * by downstream plugins. When running sls offline that can be expected, but docs say that * 'sls offline start' will provide the init and end hooks for other plugins to consume * */ - async _startWithExplicitEnd() { + async #startWithExplicitEnd() { await this.start() await this.ready() this.end() } - async _listenForTermination() { + async #listenForTermination() { const command = await new Promise((resolve) => { process // SIGINT will be usually sent when user presses ctrl+c @@ -231,7 +221,7 @@ export default class ServerlessOffline { } } - async _createSchedule(events) { + async #createSchedule(events) { const { default: Schedule } = await import('./events/schedule/index.js') this.#schedule = new Schedule( @@ -243,7 +233,7 @@ export default class ServerlessOffline { this.#schedule.create(events) } - async _createWebSocket(events) { + async #createWebSocket(events) { const { default: WebSocket } = await import('./events/websocket/index.js') this.#webSocket = new WebSocket( @@ -464,7 +454,7 @@ export default class ServerlessOffline { } // TODO: missing tests - _verifyServerlessVersionCompatibility() { + #verifyServerlessVersionCompatibility() { const currentVersion = this.#serverless.version const requiredVersionRange = pkg.peerDependencies.serverless diff --git a/src/events/http/Endpoint.js b/src/events/http/Endpoint.js index d1870ae21..cdcc7f0e1 100644 --- a/src/events/http/Endpoint.js +++ b/src/events/http/Endpoint.js @@ -41,12 +41,12 @@ export default class Endpoint { // TODO FIXME // eslint-disable-next-line no-constructor-return - return this._generate() + return this.#generate() } // determine whether we have function level overrides for velocity templates // if not we will use defaults - _setVmTemplates(fullEndpoint) { + #setVmTemplates(fullEndpoint) { // determine requestTemplate // first check if requestTemplate is set through serverless const fep = fullEndpoint @@ -107,7 +107,7 @@ export default class Endpoint { // loosely based on: // https://github.com/serverless/serverless/blob/v1.59.2/lib/plugins/aws/package/compile/events/apiGateway/lib/validate.js#L380 - _getIntegration(http) { + #getIntegration(http) { const { integration, async: isAsync } = http if (integration) { const normalizedIntegration = integration.toUpperCase().replace('-', '_') @@ -128,7 +128,7 @@ export default class Endpoint { } // return fully generated Endpoint - _generate() { + #generate() { const offlineEndpoint = new OfflineEndpoint() const fullEndpoint = { @@ -136,11 +136,11 @@ export default class Endpoint { ...this.#http, } - fullEndpoint.integration = this._getIntegration(this.#http) + fullEndpoint.integration = this.#getIntegration(this.#http) if (fullEndpoint.integration === 'AWS') { // determine request and response templates or use defaults - return this._setVmTemplates(fullEndpoint) + return this.#setVmTemplates(fullEndpoint) } return fullEndpoint diff --git a/src/events/http/HttpServer.js b/src/events/http/HttpServer.js index 3ec100984..257b47067 100644 --- a/src/events/http/HttpServer.js +++ b/src/events/http/HttpServer.js @@ -227,7 +227,7 @@ export default class HttpServer { // end with a linefeed. so we (rather crudely) account for that // with toString() and then trim() if (data.toString().trim() === 'rp') { - this._injectLastRequest() + this.#injectLastRequest() } }) } @@ -257,7 +257,7 @@ export default class HttpServer { // return this.#server.listener // } - _printBlankLine() { + #printBlankLine() { if (env.NODE_ENV !== 'test') { if (this.log) { this.log.notice() @@ -267,7 +267,7 @@ export default class HttpServer { } } - _logPluginIssue() { + #logPluginIssue() { if (this.log) { this.log.notice( 'If you think this is an issue with the plugin please submit it, thanks!\nhttps://github.com/dherault/serverless-offline/issues', @@ -281,7 +281,7 @@ export default class HttpServer { } } - _extractJWTAuthSettings(endpoint) { + #extractJWTAuthSettings(endpoint) { const result = authJWTSettingsExtractor( endpoint, this.#serverless.service.provider, @@ -292,7 +292,7 @@ export default class HttpServer { return result.unsupportedAuth ? null : result } - _configureJWTAuthorization(endpoint, functionKey, method, path) { + #configureJWTAuthorization(endpoint, functionKey, method, path) { if (!endpoint.authorizer) { return null } @@ -306,7 +306,7 @@ export default class HttpServer { return null } - const jwtSettings = this._extractJWTAuthSettings(endpoint) + const jwtSettings = this.#extractJWTAuthSettings(endpoint) if (!jwtSettings) { return null } @@ -339,18 +339,18 @@ export default class HttpServer { return authStrategyName } - _extractAuthFunctionName(endpoint) { + #extractAuthFunctionName(endpoint) { const result = authFunctionNameExtractor(endpoint, null, this) return result.unsupportedAuth ? null : result.authorizerName } - _configureAuthorization(endpoint, functionKey, method, path) { + #configureAuthorization(endpoint, functionKey, method, path) { if (!endpoint.authorizer) { return null } - const authFunctionName = this._extractAuthFunctionName(endpoint) + const authFunctionName = this.#extractAuthFunctionName(endpoint) if (!authFunctionName) { return null @@ -416,7 +416,7 @@ export default class HttpServer { return authStrategyName } - _setAuthorizationStrategy(endpoint, functionKey, method, path) { + #setAuthorizationStrategy(endpoint, functionKey, method, path) { /* * The authentication strategy can be provided outside of this project * by injecting the provider through a custom variable in the serverless.yml. @@ -451,8 +451,8 @@ export default class HttpServer { // If the endpoint has an authorization function, create an authStrategy for the route const authStrategyName = this.#options.noAuth ? null - : this._configureJWTAuthorization(endpoint, functionKey, method, path) || - this._configureAuthorization(endpoint, functionKey, method, path) + : this.#configureJWTAuthorization(endpoint, functionKey, method, path) || + this.#configureAuthorization(endpoint, functionKey, method, path) return authStrategyName } @@ -512,7 +512,7 @@ export default class HttpServer { invokePath: `/2015-03-31/functions/${functionKey}/invocations`, }) - const authStrategyName = this._setAuthorizationStrategy( + const authStrategyName = this.#setAuthorizationStrategy( endpoint, functionKey, method, @@ -622,7 +622,7 @@ export default class HttpServer { request.rawPayload = request.payload // Incomming request message - this._printBlankLine() + this.#printBlankLine() if (this.log) { this.log.notice() @@ -744,7 +744,7 @@ export default class HttpServer { try { payloadSchemaValidator.validate(schema, request.payload) } catch (err) { - return this._reply400(response, err.message, err) + return this.#reply400(response, err.message, err) } } @@ -769,7 +769,7 @@ export default class HttpServer { this.v3Utils, ).create() } catch (err) { - return this._reply502( + return this.#reply502( response, `Error while parsing template "${contentType}" for ${functionKey}`, err, @@ -849,7 +849,7 @@ export default class HttpServer { // it here and reply in the same way that we would have above when // we lazy-load the non-IPC handler function. if (this.#options.useChildProcesses && err.ipcException) { - return this._reply502( + return this.#reply502( response, `Error while loading ${functionKey}`, err, @@ -871,7 +871,7 @@ export default class HttpServer { result = { errorMessage, errorType: err.constructor.name, - stackTrace: this._getArrayStackTrace(err.stack), + stackTrace: this.#getArrayStackTrace(err.stack), } if (this.log) { @@ -964,7 +964,7 @@ export default class HttpServer { headerValue = headerValue.toString() } } else { - this._printBlankLine() + this.#printBlankLine() if (this.log) { this.log.warning() @@ -979,8 +979,8 @@ export default class HttpServer { `Offline plugin only supports "integration.response.body[.JSON_path]" right-hand responseParameter. Found "${value}" instead. Skipping.`, ) } - this._logPluginIssue() - this._printBlankLine() + this.#logPluginIssue() + this.#printBlankLine() } } else { headerValue = value.match(/^'.*'$/) ? value.slice(1, -1) : value // See #34 @@ -1009,7 +1009,7 @@ export default class HttpServer { response.header(headerName, headerValue) } } else { - this._printBlankLine() + this.#printBlankLine() if (this.log) { this.log.warning() @@ -1024,8 +1024,8 @@ export default class HttpServer { `Offline plugin only supports "method.response.header.PARAM_NAME" left-hand responseParameter. Found "${key}" instead. Skipping.`, ) } - this._logPluginIssue() - this._printBlankLine() + this.#logPluginIssue() + this.#printBlankLine() } }) } @@ -1101,7 +1101,7 @@ export default class HttpServer { } if (!chosenResponse.statusCode) { - this._printBlankLine() + this.#printBlankLine() if (this.log) { this.log.warning() @@ -1128,7 +1128,7 @@ export default class HttpServer { } else if (typeof result === 'string') { response.source = stringify(result) } else if (result && result.body && typeof result.body !== 'string') { - return this._reply502( + return this.#reply502( response, 'According to the API Gateway specs, the body content must be stringified. Check your Lambda response and make sure you are invoking JSON.stringify(YOUR_CONTENT) on your body object', {}, @@ -1228,7 +1228,7 @@ export default class HttpServer { response.variety = 'buffer' } else { if (result && result.body && typeof result.body !== 'string') { - return this._reply502( + return this.#reply502( response, 'According to the API Gateway specs, the body content must be stringified. Check your Lambda response and make sure you are invoking JSON.stringify(YOUR_CONTENT) on your body object', {}, @@ -1272,7 +1272,7 @@ export default class HttpServer { }) } - _replyError(statusCode, response, message, error) { + #replyError(statusCode, response, message, error) { serverlessLog(message) if (this.log) { @@ -1289,20 +1289,20 @@ export default class HttpServer { errorType: error.constructor.name, offlineInfo: 'If you believe this is an issue with serverless-offline please submit it, thanks. https://github.com/dherault/serverless-offline/issues', - stackTrace: this._getArrayStackTrace(error.stack), + stackTrace: this.#getArrayStackTrace(error.stack), } return response } // Bad news - _reply502(response, message, error) { + #reply502(response, message, error) { // APIG replies 502 by default on failures; - return this._replyError(502, response, message, error) + return this.#replyError(502, response, message, error) } - _reply400(response, message, error) { - return this._replyError(400, response, message, error) + #reply400(response, message, error) { + return this.#replyError(400, response, message, error) } createResourceRoutes() { @@ -1318,7 +1318,7 @@ export default class HttpServer { return } - this._printBlankLine() + this.#printBlankLine() if (this.log) { this.log.notice() @@ -1486,7 +1486,7 @@ export default class HttpServer { this.#server.route(route) } - _getArrayStackTrace(stack) { + #getArrayStackTrace(stack) { if (!stack) return null const splittedStack = stack.split('\n') @@ -1501,7 +1501,7 @@ export default class HttpServer { .map((line) => line.trim()) } - _injectLastRequest() { + #injectLastRequest() { if (this.#lastRequestOptions) { if (this.log) { this.log.notice('Replaying HTTP last request') diff --git a/src/events/http/lambda-events/LambdaProxyIntegrationEventV2.js b/src/events/http/lambda-events/LambdaProxyIntegrationEventV2.js index 70bdf5630..49ad2baf3 100644 --- a/src/events/http/lambda-events/LambdaProxyIntegrationEventV2.js +++ b/src/events/http/lambda-events/LambdaProxyIntegrationEventV2.js @@ -15,11 +15,11 @@ const { assign, entries, fromEntries } = Object // https://www.serverless.com/framework/docs/providers/aws/events/http-api/ // https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html export default class LambdaProxyIntegrationEventV2 { + #additionalRequestContext = null #routeKey = null #request = null #stage = null #stageVariables = null - #additionalRequestContext = null constructor( request, diff --git a/src/events/schedule/Schedule.js b/src/events/schedule/Schedule.js index 2099d1d9a..454cb4772 100644 --- a/src/events/schedule/Schedule.js +++ b/src/events/schedule/Schedule.js @@ -25,7 +25,7 @@ export default class Schedule { } } - _scheduleEvent(functionKey, scheduleEvent) { + #scheduleEvent(functionKey, scheduleEvent) { const { enabled, input, rate } = scheduleEvent if (!enabled) { @@ -45,7 +45,7 @@ export default class Schedule { } rates.forEach((entry) => { - const cron = this._convertExpressionToCron(entry) + const cron = this.#convertExpressionToCron(entry) if (this.log) { this.log.notice( @@ -94,7 +94,7 @@ export default class Schedule { }) } - _convertCronSyntax(cronString) { + #convertCronSyntax(cronString) { if (cronString.split(' ').length < CRON_LENGTH_WITH_YEAR) { return cronString } @@ -102,7 +102,7 @@ export default class Schedule { return cronString.replace(/\s\S+$/, '') } - _convertRateToCron(rate) { + #convertRateToCron(rate) { const [number, unit] = rate.split(' ') switch (unit) { @@ -132,18 +132,18 @@ export default class Schedule { } } - _convertExpressionToCron(scheduleEvent) { + #convertExpressionToCron(scheduleEvent) { const params = scheduleEvent .replace('rate(', '') .replace('cron(', '') .replace(')', '') if (scheduleEvent.startsWith('cron(')) { - return this._convertCronSyntax(params) + return this.#convertCronSyntax(params) } if (scheduleEvent.startsWith('rate(')) { - return this._convertRateToCron(params) + return this.#convertRateToCron(params) } if (this.log) { @@ -155,17 +155,17 @@ export default class Schedule { return undefined } - _create(functionKey, rawScheduleEventDefinition) { + #create(functionKey, rawScheduleEventDefinition) { const scheduleEvent = new ScheduleEventDefinition( rawScheduleEventDefinition, ) - this._scheduleEvent(functionKey, scheduleEvent) + this.#scheduleEvent(functionKey, scheduleEvent) } create(events) { events.forEach(({ functionKey, schedule }) => { - this._create(functionKey, schedule) + this.#create(functionKey, schedule) }) } } diff --git a/src/events/websocket/WebSocketClients.js b/src/events/websocket/WebSocketClients.js index 7a722ae28..507308856 100644 --- a/src/events/websocket/WebSocketClients.js +++ b/src/events/websocket/WebSocketClients.js @@ -47,14 +47,14 @@ export default class WebSocketClients { } } - _addWebSocketClient(client, connectionId) { + #addWebSocketClient(client, connectionId) { this.#clients.set(client, connectionId) this.#clients.set(connectionId, client) - this._onWebSocketUsed(connectionId) - this._addHardTimeout(client, connectionId) + this.#onWebSocketUsed(connectionId) + this.#addHardTimeout(client, connectionId) } - _removeWebSocketClient(client) { + #removeWebSocketClient(client) { const connectionId = this.#clients.get(client) this.#clients.delete(client) @@ -63,11 +63,11 @@ export default class WebSocketClients { return connectionId } - _getWebSocketClient(connectionId) { + #getWebSocketClient(connectionId) { return this.#clients.get(connectionId) } - _addHardTimeout(client, connectionId) { + #addHardTimeout(client, connectionId) { const timeoutId = setTimeout(() => { if (this.log) { this.log.debug(`timeout:hard:${connectionId}`) @@ -79,14 +79,14 @@ export default class WebSocketClients { this.#hardTimeouts.set(client, timeoutId) } - _clearHardTimeout(client) { + #clearHardTimeout(client) { const timeoutId = this.#hardTimeouts.get(client) clearTimeout(timeoutId) } - _onWebSocketUsed(connectionId) { - const client = this._getWebSocketClient(connectionId) - this._clearIdleTimeout(client) + #onWebSocketUsed(connectionId) { + const client = this.#getWebSocketClient(connectionId) + this.#clearIdleTimeout(client) if (this.log) { this.log.debug(`timeout:idle:${connectionId}:reset`) @@ -105,7 +105,7 @@ export default class WebSocketClients { this.#idleTimeouts.set(client, timeoutId) } - _clearIdleTimeout(client) { + #clearIdleTimeout(client) { const timeoutId = this.#idleTimeouts.get(client) clearTimeout(timeoutId) } @@ -260,7 +260,7 @@ export default class WebSocketClients { } } - async _processEvent(websocketClient, connectionId, routeKey, event) { + async #processEvent(websocketClient, connectionId, routeKey, event) { let route = this.#webSocketRoutes.get(routeKey) if (!route && routeKey !== '$disconnect') { @@ -322,7 +322,7 @@ export default class WebSocketClients { } } - _getRoute(value) { + #getRoute(value) { let json try { @@ -344,7 +344,7 @@ export default class WebSocketClients { } addClient(webSocketClient, connectionId) { - this._addWebSocketClient(webSocketClient, connectionId) + this.#addWebSocketClient(webSocketClient, connectionId) webSocketClient.on('close', () => { if (this.log) { @@ -353,14 +353,14 @@ export default class WebSocketClients { debugLog(`disconnect:${connectionId}`) } - this._removeWebSocketClient(webSocketClient) + this.#removeWebSocketClient(webSocketClient) const disconnectEvent = new WebSocketDisconnectEvent( connectionId, ).create() - this._clearHardTimeout(webSocketClient) - this._clearIdleTimeout(webSocketClient) + this.#clearHardTimeout(webSocketClient) + this.#clearIdleTimeout(webSocketClient) const authorizerData = this.#webSocketAuthorizersCache.get(connectionId) if (authorizerData) { @@ -368,7 +368,7 @@ export default class WebSocketClients { disconnectEvent.requestContext.authorizer = authorizerData.authorizer } - this._processEvent( + this.#processEvent( webSocketClient, connectionId, '$disconnect', @@ -383,7 +383,7 @@ export default class WebSocketClients { debugLog(`message:${message}`) } - const route = this._getRoute(message) + const route = this.#getRoute(message) if (this.log) { this.log.debug(`route:${route} on connection=${connectionId}`) @@ -397,13 +397,13 @@ export default class WebSocketClients { event.requestContext.identity = authorizerData.identity event.requestContext.authorizer = authorizerData.authorizer } - this._onWebSocketUsed(connectionId) + this.#onWebSocketUsed(connectionId) - this._processEvent(webSocketClient, connectionId, route, event) + this.#processEvent(webSocketClient, connectionId, route, event) }) } - _extractAuthFunctionName(endpoint) { + #extractAuthFunctionName(endpoint) { if ( typeof endpoint.authorizer === 'object' && endpoint.authorizer.type && @@ -426,13 +426,13 @@ export default class WebSocketClients { return result.unsupportedAuth ? null : result.authorizerName } - _configureAuthorization(endpoint, functionKey) { + #configureAuthorization(endpoint, functionKey) { if (!endpoint.authorizer) { return } if (endpoint.route === '$connect') { - const authFunctionName = this._extractAuthFunctionName(endpoint) + const authFunctionName = this.#extractAuthFunctionName(endpoint) if (!authFunctionName) { return @@ -487,7 +487,7 @@ export default class WebSocketClients { }) if (!this.#options.noAuth) { - this._configureAuthorization(definition, functionKey) + this.#configureAuthorization(definition, functionKey) } if (this.log) { @@ -498,7 +498,7 @@ export default class WebSocketClients { } close(connectionId) { - const client = this._getWebSocketClient(connectionId) + const client = this.#getWebSocketClient(connectionId) if (client) { client.close() @@ -509,10 +509,10 @@ export default class WebSocketClients { } send(connectionId, payload) { - const client = this._getWebSocketClient(connectionId) + const client = this.#getWebSocketClient(connectionId) if (client) { - this._onWebSocketUsed(connectionId) + this.#onWebSocketUsed(connectionId) client.send(payload) return true } diff --git a/src/lambda/LambdaFunction.js b/src/lambda/LambdaFunction.js index f729c3e25..53d11a66f 100644 --- a/src/lambda/LambdaFunction.js +++ b/src/lambda/LambdaFunction.js @@ -80,9 +80,9 @@ export default class LambdaFunction { this.#runtime = runtime this.#timeout = timeout - this._verifySupportedRuntime() + this.#verifySupportedRuntime() - const env = this._getEnv( + const env = this.#getEnv( resolveJoins(provider.environment), functionDefinition.environment, handler, @@ -134,20 +134,20 @@ export default class LambdaFunction { this.#lambdaContext = new LambdaContext(name, memorySize) } - _startExecutionTimer() { + #startExecutionTimer() { this.#executionTimeStarted = performance.now() // this._executionTimeout = this.#executionTimeStarted + this.#timeout * 1000 } - _stopExecutionTimer() { + #stopExecutionTimer() { this.#executionTimeEnded = performance.now() } - _startIdleTimer() { + #startIdleTimer() { this.#idleTimeStarted = performance.now() } - _verifySupportedRuntime() { + #verifySupportedRuntime() { // print message but keep working (don't error out or exit process) if (!supportedRuntimes.has(this.#runtime)) { // this.printBlankLine(); // TODO @@ -172,7 +172,7 @@ export default class LambdaFunction { // based on: // https://github.com/serverless/serverless/blob/v1.50.0/lib/plugins/aws/invokeLocal/index.js#L108 - _getAwsEnvVars() { + #getAwsEnvVars() { return { AWS_DEFAULT_REGION: this.#region, AWS_LAMBDA_FUNCTION_MEMORY_SIZE: this.#memorySize, @@ -192,9 +192,9 @@ export default class LambdaFunction { } } - _getEnv(providerEnv, functionDefinitionEnv, handler) { + #getEnv(providerEnv, functionDefinitionEnv, handler) { return { - ...this._getAwsEnvVars(), + ...this.#getAwsEnvVars(), ...providerEnv, ...functionDefinitionEnv, _HANDLER: handler, // TODO is this available in AWS? @@ -219,18 +219,18 @@ export default class LambdaFunction { } } - _executionTimeInMillis() { + #executionTimeInMillis() { return this.#executionTimeEnded - this.#executionTimeStarted } // round up to the nearest ms - _billedExecutionTimeInMillis() { + #billedExecutionTimeInMillis() { return ceil(this.#executionTimeEnded - this.#executionTimeStarted) } // extractArtifact, loosely based on: // https://github.com/serverless/serverless/blob/v1.57.0/lib/plugins/aws/invokeLocal/index.js#L312 - async _extractArtifact() { + async #extractArtifact() { if (!this.#artifact) { return null } @@ -239,6 +239,7 @@ export default class LambdaFunction { const data = await readFile(this.#artifact) const zip = await jszip.loadAsync(data) + return Promise.all( keys(zip.files).map(async (filename) => { const fileData = await zip.files[filename].async('nodebuffer') @@ -253,8 +254,8 @@ export default class LambdaFunction { ) } - async _initialize() { - await this._extractArtifact() + async #initialize() { + await this.#extractArtifact() this.#initialized = true } @@ -270,7 +271,7 @@ export default class LambdaFunction { this.status = 'BUSY' if (!this.#initialized) { - await this._initialize() + await this.#initialize() } const requestId = createUniqueId() @@ -280,11 +281,11 @@ export default class LambdaFunction { const context = this.#lambdaContext.create() - this._startExecutionTimer() + this.#startExecutionTimer() const result = await this.#handlerRunner.run(this.#event, context) - this._stopExecutionTimer() + this.#stopExecutionTimer() // TEMP TODO FIXME find better solution if (!this.#handlerRunner.isDockerRunner()) { @@ -292,23 +293,23 @@ export default class LambdaFunction { this.log.notice( `(λ: ${ this.#functionKey - }) RequestId: ${requestId} Duration: ${this._executionTimeInMillis().toFixed( + }) RequestId: ${requestId} Duration: ${this.#executionTimeInMillis().toFixed( 2, - )} ms Billed Duration: ${this._billedExecutionTimeInMillis()} ms`, + )} ms Billed Duration: ${this.#billedExecutionTimeInMillis()} ms`, ) } else { serverlessLog( `(λ: ${ this.#functionKey - }) RequestId: ${requestId} Duration: ${this._executionTimeInMillis().toFixed( + }) RequestId: ${requestId} Duration: ${this.#executionTimeInMillis().toFixed( 2, - )} ms Billed Duration: ${this._billedExecutionTimeInMillis()} ms`, + )} ms Billed Duration: ${this.#billedExecutionTimeInMillis()} ms`, ) } } this.status = 'IDLE' - this._startIdleTimer() + this.#startIdleTimer() return result } diff --git a/src/lambda/LambdaFunctionPool.js b/src/lambda/LambdaFunctionPool.js index 29647642a..33a34f836 100644 --- a/src/lambda/LambdaFunctionPool.js +++ b/src/lambda/LambdaFunctionPool.js @@ -12,10 +12,10 @@ export default class LambdaFunctionPool { this.v3Utils = v3Utils // start cleaner - this._startCleanTimer() + this.#startCleanTimer() } - _startCleanTimer() { + #startCleanTimer() { // NOTE: don't use setInterval, as it would schedule always a new run, // regardless of function processing time and e.g. user action (debugging) this.#timerRef = setTimeout(() => { @@ -38,11 +38,11 @@ export default class LambdaFunctionPool { }) // schedule new timer - this._startCleanTimer() + this.#startCleanTimer() }, (this.#options.functionCleanupIdleTimeSeconds * 1000) / 2) } - _cleanupPool() { + #cleanupPool() { const wait = [] this.#pool.forEach((lambdaFunctions) => { @@ -60,7 +60,7 @@ export default class LambdaFunctionPool { async cleanup() { clearTimeout(this.#timerRef) - return this._cleanupPool() + return this.#cleanupPool() } get(functionKey, functionDefinition) { diff --git a/src/lambda/handler-runner/HandlerRunner.js b/src/lambda/handler-runner/HandlerRunner.js index f9e9dd86d..af1cc086f 100644 --- a/src/lambda/handler-runner/HandlerRunner.js +++ b/src/lambda/handler-runner/HandlerRunner.js @@ -26,7 +26,7 @@ export default class HandlerRunner { } } - async _loadRunner() { + async #loadRunner() { const { useDocker, useChildProcesses, useWorkerThreads, allowCache } = this.#options @@ -165,7 +165,7 @@ export default class HandlerRunner { async run(event, context) { if (this.#runner == null) { - this.#runner = await this._loadRunner() + this.#runner = await this.#loadRunner() } return this.#runner.run(event, context) diff --git a/src/lambda/handler-runner/docker-runner/DockerContainer.js b/src/lambda/handler-runner/docker-runner/DockerContainer.js index 9e38e670c..cfe690aa2 100644 --- a/src/lambda/handler-runner/docker-runner/DockerContainer.js +++ b/src/lambda/handler-runner/docker-runner/DockerContainer.js @@ -44,7 +44,7 @@ export default class DockerContainer { this.#env = env this.#functionKey = functionKey this.#handler = handler - this.#imageNameTag = this._baseImage(runtime) + this.#imageNameTag = this.#baseImage(runtime) this.#image = new DockerImage(this.#imageNameTag, v3Utils) this.#runtime = runtime this.#layers = layers @@ -59,7 +59,7 @@ export default class DockerContainer { } } - _baseImage(runtime) { + #baseImage(runtime) { return `lambci/lambda:${runtime}` } @@ -117,7 +117,7 @@ export default class DockerContainer { layerDir = join(this.#servicePath, '.serverless-offline', 'layers') } - layerDir = join(layerDir, this._getLayersSha256()) + layerDir = join(layerDir, this.#getLayersSha256()) if (await pathExists(layerDir)) { if (this.log) { @@ -151,7 +151,7 @@ export default class DockerContainer { } for (const layerArn of this.#layers) { - layers.push(this._downloadLayer(layerArn, layerDir)) + layers.push(this.#downloadLayer(layerArn, layerDir)) } await Promise.all(layers) @@ -177,7 +177,7 @@ export default class DockerContainer { if (platform() === 'linux') { // Add `host.docker.internal` DNS name to access host from inside the container // https://github.com/docker/for-linux/issues/264 - const gatewayIp = await this._getBridgeGatewayIp() + const gatewayIp = await this.#getBridgeGatewayIp() if (gatewayIp) { dockerArgs.push('--add-host', `host.docker.internal:${gatewayIp}`) } @@ -239,7 +239,7 @@ export default class DockerContainer { this.#containerId = containerId this.#port = containerPort - await pRetry(() => this._ping(), { + await pRetry(() => this.#ping(), { // default, factor: 2, // milliseconds @@ -249,7 +249,7 @@ export default class DockerContainer { }) } - async _downloadLayer(layerArn, layerDir) { + async #downloadLayer(layerArn, layerDir) { const layerName = layerArn.split(':layer:')[1] const layerZipFile = `${layerDir}/${layerName}.zip` const layerProgress = this.log && this.progress.get(`layer-${layerName}`) @@ -313,18 +313,18 @@ export default class DockerContainer { if (this.log) { this.log.verbose( - `Retrieving "${layerName}": Downloading ${this._formatBytes( + `Retrieving "${layerName}": Downloading ${this.#formatBytes( layerSize, )}...`, ) layerProgress.notice( - `Retrieving "${layerName}": Downloading ${this._formatBytes( + `Retrieving "${layerName}": Downloading ${this.#formatBytes( layerSize, )}`, ) } else { logLayers( - `[${layerName}] Downloading ${this._formatBytes(layerSize)}...`, + `[${layerName}] Downloading ${this.#formatBytes(layerSize)}...`, ) } @@ -394,7 +394,7 @@ export default class DockerContainer { } } - async _getBridgeGatewayIp() { + async #getBridgeGatewayIp() { let gateway try { ;({ stdout: gateway } = await execa('docker', [ @@ -415,7 +415,7 @@ export default class DockerContainer { return gateway.split('/')[0] } - async _ping() { + async #ping() { const url = `http://${this.#dockerOptions.host}:${ this.#port }/2018-06-01/ping` @@ -462,7 +462,7 @@ export default class DockerContainer { } } - _formatBytes(bytes, decimals = 2) { + #formatBytes(bytes, decimals = 2) { if (bytes === 0) return '0 Bytes' const k = 1024 @@ -474,7 +474,7 @@ export default class DockerContainer { return `${parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}` } - _getLayersSha256() { + #getLayersSha256() { return crypto .createHash('sha256') .update(stringify(this.#layers)) diff --git a/src/lambda/handler-runner/docker-runner/DockerImage.js b/src/lambda/handler-runner/docker-runner/DockerImage.js index c975b9efd..d7f875c4d 100644 --- a/src/lambda/handler-runner/docker-runner/DockerImage.js +++ b/src/lambda/handler-runner/docker-runner/DockerImage.js @@ -5,8 +5,11 @@ import debugLog from '../../../debugLog.js' export default class DockerImage { #imageNameTag = null + static #memoizedPull = promiseMemoize(DockerImage.#pullImage) + constructor(imageNameTag, v3Utils) { this.#imageNameTag = imageNameTag + if (v3Utils) { this.log = v3Utils.log this.progress = v3Utils.progress @@ -15,7 +18,7 @@ export default class DockerImage { } } - static async _pullImage(imageNameTag) { + static async #pullImage(imageNameTag) { if (this.log) { this.log.debug(`Downloading base Docker image... (${imageNameTag})`) } else { @@ -39,8 +42,6 @@ export default class DockerImage { } async pull() { - return DockerImage._memoizedPull(this.#imageNameTag, this.v3Utils) + return DockerImage.#memoizedPull(this.#imageNameTag, this.v3Utils) } } - -DockerImage._memoizedPull = promiseMemoize(DockerImage._pullImage) diff --git a/src/lambda/handler-runner/go-runner/GoRunner.js b/src/lambda/handler-runner/go-runner/GoRunner.js index 76a947711..16e8ad11c 100644 --- a/src/lambda/handler-runner/go-runner/GoRunner.js +++ b/src/lambda/handler-runner/go-runner/GoRunner.js @@ -10,12 +10,12 @@ const { parse, stringify } = JSON const PAYLOAD_IDENTIFIER = 'offline_payload' export default class GoRunner { + #codeDir = null #env = null #handlerPath = null #tmpPath = null #tmpFile = null #goEnv = null - #codeDir = null constructor(funOptions, env, v3Utils) { const { handlerPath, codeDir } = funOptions @@ -43,7 +43,7 @@ export default class GoRunner { this.#tmpPath = null } - _parsePayload(value) { + #parsePayload(value) { const log = [] let payload @@ -165,6 +165,6 @@ export default class GoRunner { // @ignore } - return this._parsePayload(stdout) + return this.#parsePayload(stdout) } } diff --git a/src/lambda/handler-runner/in-process-runner/InProcessRunner.js b/src/lambda/handler-runner/in-process-runner/InProcessRunner.js index a2c59131e..df912b578 100644 --- a/src/lambda/handler-runner/in-process-runner/InProcessRunner.js +++ b/src/lambda/handler-runner/in-process-runner/InProcessRunner.js @@ -5,7 +5,7 @@ import process from 'process' const { assign, keys } = Object -const clearModule = (fP, opts) => { +function clearModule(fP, opts) { const options = opts ?? {} let filePath = fP if (!require.cache[filePath]) { diff --git a/src/lambda/handler-runner/java-runner/JavaRunner.js b/src/lambda/handler-runner/java-runner/JavaRunner.js index 0260d4904..508c1c397 100644 --- a/src/lambda/handler-runner/java-runner/JavaRunner.js +++ b/src/lambda/handler-runner/java-runner/JavaRunner.js @@ -7,11 +7,11 @@ const { parse, stringify } = JSON const { has } = Reflect export default class JavaRunner { + #allowCache = false #env = null #functionName = null #handler = null #deployPackage = null - #allowCache = false constructor(funOptions, env, allowCache, v3Utils) { const { functionName, handler, servicePackage, functionPackage } = @@ -35,7 +35,7 @@ export default class JavaRunner { // () => void cleanup() {} - _parsePayload(value) { + #parsePayload(value) { for (const item of value.split(EOL)) { let json @@ -123,6 +123,6 @@ export default class JavaRunner { } } - return this._parsePayload(result) + return this.#parsePayload(result) } } diff --git a/src/lambda/handler-runner/python-runner/PythonRunner.js b/src/lambda/handler-runner/python-runner/PythonRunner.js index e425d0a02..7c38b7340 100644 --- a/src/lambda/handler-runner/python-runner/PythonRunner.js +++ b/src/lambda/handler-runner/python-runner/PythonRunner.js @@ -66,7 +66,7 @@ export default class PythonRunner { this.handlerProcess.kill() } - _parsePayload(value) { + #parsePayload(value) { let payload for (const item of value.split(EOL)) { @@ -122,7 +122,7 @@ export default class PythonRunner { const onLine = (line) => { try { - const parsed = this._parsePayload(line.toString()) + const parsed = this.#parsePayload(line.toString()) if (parsed) { this.handlerProcess.stdout.readline.removeListener('line', onLine) this.handlerProcess.stderr.removeListener('data', onErr) diff --git a/src/lambda/handler-runner/ruby-runner/RubyRunner.js b/src/lambda/handler-runner/ruby-runner/RubyRunner.js index 274a6394a..d1c6ba625 100644 --- a/src/lambda/handler-runner/ruby-runner/RubyRunner.js +++ b/src/lambda/handler-runner/ruby-runner/RubyRunner.js @@ -32,7 +32,7 @@ export default class RubyRunner { // () => void cleanup() {} - _parsePayload(value) { + #parsePayload(value) { let payload for (const item of value.split(EOL)) { @@ -112,6 +112,6 @@ export default class RubyRunner { } } - return this._parsePayload(stdout) + return this.#parsePayload(stdout) } } diff --git a/src/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js b/src/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js index f012cd852..1ff4cd619 100644 --- a/src/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js +++ b/src/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js @@ -4,8 +4,8 @@ import { MessageChannel, Worker } from 'worker_threads' // eslint-disable-line i const workerThreadHelperPath = resolve(__dirname, './workerThreadHelper.js') export default class WorkerThreadRunner { - #workerThread = null #allowCache = false + #workerThread = null constructor(funOptions /* options */, env, allowCache) { // this._options = options