Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@google-cloud/functions-framework

Package Overview
Dependencies
Maintainers
1
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@google-cloud/functions-framework - npm Package Compare versions

Comparing version 1.7.1 to 1.8.0

build/src/pubsub_middleware.d.ts

1

build/src/cloudevents.js

@@ -16,2 +16,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.getBinaryCloudEventContext = exports.isBinaryCloudEvent = void 0;
/**

@@ -18,0 +19,0 @@ * Checks whether the incoming request is a CloudEvents event in binary content

@@ -19,2 +19,13 @@ import * as express from 'express';

/**
* A legacy event.
*/
export interface LegacyEvent {
data: object;
context: CloudFunctionsContext;
}
interface Data {
data: object;
}
export declare type LegacyCloudFunctionsContext = CloudFunctionsContext | Data;
/**
* The Cloud Functions context object for the event.

@@ -41,3 +52,3 @@ *

*/
resource?: string;
resource?: string | object;
}

@@ -71,11 +82,19 @@ /**

/**
* Describes the subject of the event in the context of the event producer.
*/
subject?: string;
/**
* A link to the schema that the event data adheres to.
*/
schemaurl?: string;
dataschema?: string;
/**
* Content type of the event data.
*/
contenttype?: string;
[key: string]: any;
datacontenttype?: string;
/**
* The event data.
*/
data?: Record<string, unknown | string | number | boolean> | string | number | boolean | null | unknown;
}
export declare type Context = CloudFunctionsContext | CloudEventsContext;
export {};

9

build/src/index.js

@@ -37,2 +37,4 @@ #!/usr/bin/env node

const invoker_1 = require("./invoker");
const server_1 = require("./server");
const types_1 = require("./types");
// Supported command-line flags

@@ -63,5 +65,5 @@ const FLAG = {

const SIGNATURE_TYPE_STRING = argv[FLAG.SIGNATURE_TYPE] || process.env[ENV.SIGNATURE_TYPE] || 'http';
const SIGNATURE_TYPE = invoker_1.SignatureType[SIGNATURE_TYPE_STRING.toUpperCase()];
const SIGNATURE_TYPE = types_1.SignatureType[SIGNATURE_TYPE_STRING.toUpperCase()];
if (SIGNATURE_TYPE === undefined) {
console.error(`Function signature type must be one of: ${Object.values(invoker_1.SignatureType).join(', ')}.`);
console.error(`Function signature type must be one of: ${Object.values(types_1.SignatureType).join(', ')}.`);
// eslint-disable-next-line no-process-exit

@@ -85,3 +87,3 @@ process.exit(1);

}
const SERVER = invoker_1.getServer(USER_FUNCTION, SIGNATURE_TYPE);
const SERVER = server_1.getServer(USER_FUNCTION, SIGNATURE_TYPE);
const ERROR_HANDLER = new invoker_1.ErrorHandler(SERVER);

@@ -93,2 +95,3 @@ SERVER.listen(PORT, () => {

console.log(`Function: ${TARGET}`);
console.log(`Signature type: ${SIGNATURE_TYPE}`);
console.log(`URL: http://localhost:${PORT}/`);

@@ -95,0 +98,0 @@ }

/// <reference types="node" />
import * as express from 'express';
import * as http from 'http';
import { HandlerFunction } from './functions';
import { HttpFunction, EventFunction, EventFunctionWithCallback, CloudEventFunction, CloudEventFunctionWithCallback } from './functions';
declare global {

@@ -11,8 +12,25 @@ namespace Express {

}
export declare enum SignatureType {
HTTP = "http",
EVENT = "event",
CLOUDEVENT = "cloudevent"
}
export declare const setLatestRes: (res: express.Response) => void;
/**
* Wraps the provided function into an Express handler function with additional
* instrumentation logic.
* @param execute Runs user's function.
* @return An Express handler function.
*/
export declare function makeHttpHandler(execute: HttpFunction): express.RequestHandler;
/**
* Wraps cloudevent function (or cloudevent function with callback) in HTTP
* function signature.
* @param userFunction User's function.
* @return HTTP function which wraps the provided event function.
*/
export declare function wrapCloudEventFunction(userFunction: CloudEventFunction | CloudEventFunctionWithCallback): HttpFunction;
/**
* Wraps event function (or event function with callback) in HTTP function
* signature.
* @param userFunction User's function.
* @return HTTP function which wraps the provided event function.
*/
export declare function wrapEventFunction(userFunction: EventFunction | EventFunctionWithCallback): HttpFunction;
/**
* Enables registration of error handlers.

@@ -30,9 +48,1 @@ * @param server HTTP server which invokes user's function.

}
/**
* Creates and configures an Express application and returns an HTTP server
* which will run it.
* @param userFunction User's function.
* @param functionSignatureType Type of user's function signature.
* @return HTTP server.
*/
export declare function getServer(userFunction: HandlerFunction, functionSignatureType: SignatureType): http.Server;

@@ -16,2 +16,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.ErrorHandler = exports.wrapEventFunction = exports.wrapCloudEventFunction = exports.makeHttpHandler = exports.setLatestRes = void 0;
// Node.js server that runs user's code on HTTP request. HTTP response is sent

@@ -24,19 +25,16 @@ // once user's function has completed.

// functions with HTTP trigger).
const bodyParser = require("body-parser");
// eslint-disable-next-line node/no-deprecated-api
const domain = require("domain");
const express = require("express");
const http = require("http");
const onFinished = require("on-finished");
const types_1 = require("./types");
const logger_1 = require("./logger");
const cloudevents_1 = require("./cloudevents");
var SignatureType;
(function (SignatureType) {
SignatureType["HTTP"] = "http";
SignatureType["EVENT"] = "event";
SignatureType["CLOUDEVENT"] = "cloudevent";
})(SignatureType = exports.SignatureType || (exports.SignatureType = {}));
// Response object for the most recent request.
/**
* Response object for the most recent request.
* Used for sending errors to the user.
*/
let latestRes = null;
const setLatestRes = (res) => {
latestRes = res;
};
exports.setLatestRes = setLatestRes;
/**

@@ -107,2 +105,3 @@ * Sends back a response to the incoming request.

}
exports.makeHttpHandler = makeHttpHandler;
/**

@@ -135,4 +134,4 @@ * Wraps cloudevent function (or cloudevent function with callback) in HTTP

}
// Callback style if user function has more than 2 arguments.
if (userFunction.length > 2) {
// Callback style if user function has more than 1 argument.
if (userFunction.length > 1) {
const fn = userFunction;

@@ -154,2 +153,3 @@ return fn(cloudevent, callback);

}
exports.wrapCloudEventFunction = wrapCloudEventFunction;
/**

@@ -214,41 +214,3 @@ * Wraps event function (or event function with callback) in HTTP function

}
/**
* Registers handler functions for route paths.
* @param app Express application object.
* @param userFunction User's function.
* @param functionSignatureType Type of user's function signature.
*/
function registerFunctionRoutes(app, userFunction, functionSignatureType) {
if (functionSignatureType === SignatureType.HTTP) {
app.use('/favicon.ico|/robots.txt', (req, res) => {
// Neither crawlers nor browsers attempting to pull the icon find the body
// contents particularly useful, so we send nothing in the response body.
res.status(404).send(null);
});
app.use('/*', (req, res, next) => {
onFinished(res, (err, res) => {
res.locals.functionExecutionFinished = true;
});
next();
});
app.all('/*', (req, res, next) => {
const handler = makeHttpHandler(userFunction);
handler(req, res, next);
});
}
else if (functionSignatureType === SignatureType.EVENT) {
app.post('/*', (req, res, next) => {
const wrappedUserFunction = wrapEventFunction(userFunction);
const handler = makeHttpHandler(wrappedUserFunction);
handler(req, res, next);
});
}
else {
app.post('/*', (req, res, next) => {
const wrappedUserFunction = wrapCloudEventFunction(userFunction);
const handler = makeHttpHandler(wrappedUserFunction);
handler(req, res, next);
});
}
}
exports.wrapEventFunction = wrapEventFunction;
// Use an exit code which is unused by Node.js:

@@ -288,6 +250,10 @@ // https://nodejs.org/api/process.html#process_exit_codes

process.on(signal, () => {
console.log(`Received ${signal}`);
this.server.close(() => {
// eslint-disable-next-line no-process-exit
process.exit();
logger_1.sendCrashResponse({
err: new Error(`Received ${signal}`),
res: latestRes,
silent: true,
callback: () => {
// eslint-disable-next-line no-process-exit
process.exit();
},
});

@@ -299,66 +265,2 @@ });

exports.ErrorHandler = ErrorHandler;
/**
* Creates and configures an Express application and returns an HTTP server
* which will run it.
* @param userFunction User's function.
* @param functionSignatureType Type of user's function signature.
* @return HTTP server.
*/
function getServer(userFunction, functionSignatureType) {
// App to use for function executions.
const app = express();
// Express middleware
// Set request-specific values in the very first middleware.
app.use('/*', (req, res, next) => {
latestRes = res;
res.locals.functionExecutionFinished = false;
next();
});
/**
* Retains a reference to the raw body buffer to allow access to the raw body
* for things like request signature validation. This is used as the "verify"
* function in body-parser options.
* @param req Express request object.
* @param res Express response object.
* @param buf Buffer to be saved.
*/
function rawBodySaver(req, res, buf) {
req.rawBody = buf;
}
// Set limit to a value larger than 32MB, which is maximum limit of higher
// level layers anyway.
const requestLimit = '1024mb';
const defaultBodySavingOptions = {
limit: requestLimit,
verify: rawBodySaver,
};
const cloudEventsBodySavingOptions = {
type: 'application/cloudevents+json',
limit: requestLimit,
verify: rawBodySaver,
};
const rawBodySavingOptions = {
limit: requestLimit,
verify: rawBodySaver,
type: '*/*',
};
// Use extended query string parsing for URL-encoded bodies.
const urlEncodedOptions = {
limit: requestLimit,
verify: rawBodySaver,
extended: true,
};
// Apply middleware
app.use(bodyParser.json(cloudEventsBodySavingOptions));
app.use(bodyParser.json(defaultBodySavingOptions));
app.use(bodyParser.text(defaultBodySavingOptions));
app.use(bodyParser.urlencoded(urlEncodedOptions));
// The parser will process ALL content types so MUST come last.
// Subsequent parsers will be skipped when one is matched.
app.use(bodyParser.raw(rawBodySavingOptions));
app.enable('trust proxy'); // To respect X-Forwarded-For header.
registerFunctionRoutes(app, userFunction, functionSignatureType);
return http.createServer(app);
}
exports.getServer = getServer;
//# sourceMappingURL=invoker.js.map

@@ -16,2 +16,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.getUserFunction = void 0;
/**

@@ -18,0 +19,0 @@ * Returns user's function from function file.

@@ -16,2 +16,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.sendCrashResponse = void 0;
const types_1 = require("./types");

@@ -35,3 +36,3 @@ /**

res.set(types_1.FUNCTION_STATUS_HEADER_FIELD, 'crash');
res.send(err.message || err);
res.send((err.message || err) + '');
}

@@ -38,0 +39,0 @@ if (callback) {

export declare const FUNCTION_STATUS_HEADER_FIELD = "X-Google-Status";
export declare enum SignatureType {
HTTP = "http",
EVENT = "event",
CLOUDEVENT = "cloudevent"
}

@@ -16,5 +16,12 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.SignatureType = exports.FUNCTION_STATUS_HEADER_FIELD = void 0;
// HTTP header field that is added to Worker response to signalize problems with
// executing the client function.
exports.FUNCTION_STATUS_HEADER_FIELD = 'X-Google-Status';
var SignatureType;
(function (SignatureType) {
SignatureType["HTTP"] = "http";
SignatureType["EVENT"] = "event";
SignatureType["CLOUDEVENT"] = "cloudevent";
})(SignatureType = exports.SignatureType || (exports.SignatureType = {}));
//# sourceMappingURL=types.js.map

@@ -7,2 +7,53 @@ # Changelog

## v1.8.0
06-04-2021 16:11 PDT
### Features
- Update event and cloudevent interfaces (#276)
- Support local development with Pub/Sub emulator (#272)
- Disable x-powered-by header (#223)
### Bug Fixes
- Allow killing process with CTRL+C (#264)
- Do not pass numeric arguments to res.send (#242)
- Fix cloudevent signature callbacks (#234)
- Log function signature type (#228)
- Export the public interfaces (#218)
### Dependencies
- update lodash to 4.17.21 (#284)
- update hosted-git-info to 2.8.9 (#282)
- update googlecloudplatform/functions-framework-conformance action to v0.3.9 (#271)
- update typescript to v4.2.3 (#269)
- update mocha to v8.3.2 (#268)
- update @types/supertest to v2.0.11 (#267)
- update @types/node to v11.15.50 (#266)
- update supertest to v6 (#251)
- update gts to v3 (#250)
- update actions/setup-node action to v2 (#249)
- update @types/minimist to v1.2.1 (#245)
- update @types/express to v4.17.11 (#244)
- update ini to 1.3.7 (#240)
- update @types/mocha to v8.0.3 (#201)
- update minimist to 1.2.5 (#259)
### Documentation
- Add buildpacks/docker quickstart (#212)
- Mention express as the request/response parameters (#200)
### Internal / Testing Changues
- Updates to functions-framework-conformance action (#224, #236, #279, #280)
- Split up invoker tests into separate integration test files (#281)
- Enable eslint for tests (#275)
- Add useful npm scripts (#274)
- CI configuration updates (#219, #217)
- Refactor: split invoker and router (#213)
- Update renovate.json schedule (#210)
## v1.7.1

@@ -9,0 +60,0 @@

{
"name": "@google-cloud/functions-framework",
"version": "1.7.1",
"version": "1.8.0",
"description": "FaaS (Function as a service) framework for writing portable Node.js functions",

@@ -10,12 +10,11 @@ "engines": {

"main": "build/src/index.js",
"types": "build/src/invoker.d.ts",
"types": "build/src/functions.d.ts",
"dependencies": {
"body-parser": "^1.18.3",
"express": "^4.16.4",
"minimist": "^1.2.0",
"minimist": "^1.2.5",
"on-finished": "^2.3.0"
},
"scripts": {
"test": "mocha build/test",
"test-conformance": "cd test/conformance && ./run-conformance-tests.sh",
"test": "mocha build/test --recursive",
"check": "gts check",

@@ -25,5 +24,5 @@ "clean": "gts clean",

"fix": "gts fix",
"watch": "npm run compile -- --watch",
"prepare": "npm run compile",
"pretest": "npm run compile",
"posttest": "npm run check"
"pretest": "npm run compile"
},

@@ -42,14 +41,16 @@ "files": [

"@types/body-parser": "1.17.0",
"@types/express": "4.17.7",
"@types/minimist": "1.2.0",
"@types/mocha": "8.0.1",
"@types/node": "11.15.20",
"@types/express": "4.17.11",
"@types/minimist": "1.2.1",
"@types/mocha": "8.2.2",
"@types/node": "11.15.50",
"@types/on-finished": "2.3.1",
"@types/supertest": "2.0.10",
"gts": "2.0.2",
"mocha": "8.1.1",
"@types/sinon": "^10.0.0",
"@types/supertest": "2.0.11",
"gts": "3.1.0",
"mocha": "8.3.2",
"power-assert": "1.6.1",
"supertest": "4.0.2",
"typescript": "3.9.7"
"sinon": "^10.0.0",
"supertest": "6.1.3",
"typescript": "4.2.3"
}
}
# Functions Framework for Node.js [![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2FGoogleCloudPlatform%2Ffunctions-framework-nodejs%2Fbadge&style=flat)](https://actions-badge.atrox.dev/GoogleCloudPlatform/functions-framework-nodejs/goto) [![npm version](https://img.shields.io/npm/v/@google-cloud/functions-framework.svg)](https://www.npmjs.com/package/@google-cloud/functions-framework) [![npm downloads](https://img.shields.io/npm/dm/@google-cloud/functions-framework.svg)](https://npmcharts.com/compare/@google-cloud/functions-framework?minimal=true)
An open source FaaS (Function as a service) framework for writing portable
Node.js functions -- brought to you by the Google Cloud Functions team.
An open source FaaS (Function as a Service) framework based on [Express](https://expressjs.com/)
for writing portable Node.js functions -- brought to you by the Google Cloud Functions team.

@@ -17,4 +17,9 @@ The Functions Framework lets you write lightweight functions that run in many

```js
/**
* Send "Hello, World!"
* @param req https://expressjs.com/en/api.html#req
* @param res https://expressjs.com/en/api.html#res
*/
exports.helloWorld = (req, res) => {
res.send('Hello, World');
res.send('Hello, World!');
};

@@ -27,3 +32,3 @@ ```

curl http://my-url
# Output: Hello, World
# Output: Hello, World!
```

@@ -36,3 +41,3 @@

# Features
## Features

@@ -45,3 +50,3 @@ - Spin up a local development server for quick testing

# Installation
## Installation

@@ -54,72 +59,102 @@ Add the Functions Framework to your `package.json` file using `npm`.

# Quickstart: Hello, World on your local machine
## Quickstarts
Create an `index.js` file with the following contents:
### Quickstart: Hello, World on your local machine
```js
exports.helloWorld = (req, res) => {
res.send('Hello, World');
};
```
1. Create an `index.js` file with the following contents:
Run the following command:
```js
exports.helloWorld = (req, res) => {
res.send('Hello, World');
};
```
```sh
npx @google-cloud/functions-framework --target=helloWorld
```
1. Run the following command:
Open http://localhost:8080/ in your browser and see _Hello, World_.
```sh
npx @google-cloud/functions-framework --target=helloWorld
```
# Quickstart: Set up a new project
1. Open http://localhost:8080/ in your browser and see _Hello, World_.
Create an `index.js` file with the following contents:
### Quickstart: Set up a new project
```js
exports.helloWorld = (req, res) => {
res.send('Hello, World');
};
```
1. Create a `package.json` file using `npm init`:
To run a function locally, first create a `package.json` file using `npm init`:
```sh
npm init
```
```sh
npm init
```
1. Create an `index.js` file with the following contents:
Now install the Functions Framework:
```js
exports.helloWorld = (req, res) => {
res.send('Hello, World');
};
```
```sh
npm install @google-cloud/functions-framework
```
1. Now install the Functions Framework:
Add a `start` script to `package.json`, with configuration passed via
```sh
npm install @google-cloud/functions-framework
```
1. Add a `start` script to `package.json`, with configuration passed via
command-line arguments:
```js
"scripts": {
"start": "functions-framework --target=helloWorld"
}
```
```js
"scripts": {
"start": "functions-framework --target=helloWorld"
}
```
Use `npm start` to start the built-in local development server:
1. Use `npm start` to start the built-in local development server:
```sh
npm start
...
Serving function...
Function: helloWorld
URL: http://localhost:8080/
```
```sh
npm start
...
Serving function...
Function: helloWorld
URL: http://localhost:8080/
```
Send requests to this function using `curl` from another terminal window:
1. Send requests to this function using `curl` from another terminal window:
```sh
curl localhost:8080
# Output: Hello, World
```
```sh
curl localhost:8080
# Output: Hello, World
```
# Run your function on serverless platforms
### Quickstart: Build a Deployable Container
## Google Cloud Functions
1. Install [Docker](https://store.docker.com/search?type=edition&offering=community) and the [`pack` tool](https://buildpacks.io/docs/install-pack/).
1. Build a container from your function using the Functions [buildpacks](https://github.com/GoogleCloudPlatform/buildpacks):
```sh
pack build \
--builder gcr.io/buildpacks/builder:v1 \
--env GOOGLE_FUNCTION_SIGNATURE_TYPE=http \
--env GOOGLE_FUNCTION_TARGET=helloWorld \
my-first-function
```
1. Start the built container:
```sh
docker run --rm -p 8080:8080 my-first-function
# Output: Serving function...
```
1. Send requests to this function using `curl` from another terminal window:
```sh
curl localhost:8080
# Output: Hello, World!
```
## Run your function on serverless platforms
### Google Cloud Functions
The

@@ -135,3 +170,3 @@ [Node.js 10 runtime on Google Cloud Functions](https://cloud.google.com/functions/docs/concepts/nodejs-10-runtime)

## Cloud Run/Cloud Run on GKE
### Cloud Run/Cloud Run on GKE

@@ -142,7 +177,7 @@ Once you've written your function, added the Functions Framework and updated your `start` script in `package.json`, all that's left is to create a container image. [Check out the Cloud Run quickstart](https://cloud.google.com/run/docs/quickstarts/build-and-deploy) for Node.js to create a container image and deploy it to Cloud Run. You'll write a `Dockerfile` when you build your container. This `Dockerfile` allows you to specify exactly what goes into your container (including custom binaries, a specific operating system, and more).

## Container environments based on Knative
### Container environments based on Knative
Cloud Run and Cloud Run on GKE both implement the [Knative Serving API](https://www.knative.dev/docs/). The Functions Framework is designed to be compatible with Knative environments. Just build and deploy your container to a Knative environment.
# Configure the Functions Framework
## Configure the Functions Framework

@@ -169,3 +204,3 @@ You can configure the Functions Framework using command-line flags or

# Enable Google Cloud Functions Events
## Enable Google Cloud Functions Events

@@ -192,3 +227,3 @@ The Functions Framework can unmarshall incoming

# Enable CloudEvents
## Enable CloudEvents

@@ -216,9 +251,9 @@ The Functions Framework can unmarshall incoming

# Advanced Docs
## Advanced Docs
More advanced guides and docs can be found in the [`docs/` folder](docs/).
# Contributing
## Contributing
Contributions to this library are welcome and encouraged. See
[CONTRIBUTING](CONTRIBUTING.md) for more information on how to get started.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc