firebase-functions 7.0.2 → 7.0.3

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.
@@ -1,14 +1,20 @@
1
1
  import { __export } from "../../_virtual/rolldown_runtime.mjs";
2
2
  import { initV2Endpoint } from "../../runtime/manifest.mjs";
3
+ import { convertIfPresent, convertInvoker } from "../../common/encoding.mjs";
3
4
  import { withInit } from "../../common/onInit.mjs";
5
+ import { withErrorHandler } from "../../common/providers/https.mjs";
4
6
  import { normalizePath } from "../../common/utilities/path.mjs";
5
7
  import { wrapTraceContext } from "../trace.mjs";
6
8
  import { getGlobalOptions, optionsToEndpoint } from "../options.mjs";
7
9
  import { PathPattern } from "../../common/utilities/path-pattern.mjs";
10
+ import express from "express";
11
+ import fs from "fs";
8
12
 
9
13
  //#region src/v2/providers/dataconnect.ts
10
14
  var dataconnect_exports = /* @__PURE__ */ __export({
15
+ initGraphqlServer: () => initGraphqlServer,
11
16
  mutationExecutedEventType: () => mutationExecutedEventType,
17
+ onGraphRequest: () => onGraphRequest,
12
18
  onMutationExecuted: () => onMutationExecuted
13
19
  });
14
20
  /** @internal */
@@ -125,6 +131,81 @@ function onOperation(eventType, mutationOrOpts, handler) {
125
131
  func.__endpoint = makeEndpoint(eventType, opts, servicePattern, connectorPattern, operationPattern);
126
132
  return func;
127
133
  }
134
+ /** @hidden */
135
+ async function initGraphqlServer(opts) {
136
+ if (!opts.schema && !opts.schemaFilePath || opts.schema && opts.schemaFilePath) {
137
+ throw new Error("Exactly one of 'schema' or 'schemaFilePath' must be provided.");
138
+ }
139
+ if (opts.schemaFilePath) {
140
+ opts.schema = fs.readFileSync(opts.schemaFilePath, "utf-8");
141
+ }
142
+ if (!opts.resolvers.query && !opts.resolvers.mutation) {
143
+ throw new Error("At least one query or mutation resolver must be provided.");
144
+ }
145
+ const apolloResolvers = {};
146
+ if (opts.resolvers.query) {
147
+ apolloResolvers.Query = opts.resolvers.query;
148
+ }
149
+ if (opts.resolvers.mutation) {
150
+ apolloResolvers.Mutation = opts.resolvers.mutation;
151
+ }
152
+ try {
153
+ const { ApolloServer } = await import("@apollo/server");
154
+ const { expressMiddleware } = await import("@as-integrations/express4");
155
+ const serverPromise$1 = (async () => {
156
+ const app = express();
157
+ const server = new ApolloServer({
158
+ typeDefs: opts.schema,
159
+ resolvers: apolloResolvers
160
+ });
161
+ await server.start();
162
+ app.use(`/${opts.path ?? "graphql"}`, express.json(), expressMiddleware(server));
163
+ return app;
164
+ })();
165
+ return serverPromise$1;
166
+ } catch (e) {
167
+ if (e instanceof Error) {
168
+ throw new Error("Error initializing GraphQL server: " + e.message);
169
+ } else {
170
+ throw e;
171
+ }
172
+ }
173
+ }
174
+ let serverPromise = null;
175
+ /**
176
+ * @hidden
177
+ * Handles HTTPS GraphQL requests.
178
+ * @param {GraphqlServerOptions} opts - Options for configuring the GraphQL server.
179
+ * @returns {HttpsFunction} A function you can export and deploy.
180
+ */
181
+ function onGraphRequest(opts) {
182
+ const handler = wrapTraceContext(withInit(withErrorHandler(async (req, res) => {
183
+ serverPromise = serverPromise ?? initGraphqlServer(opts);
184
+ const app = await serverPromise;
185
+ app(req, res);
186
+ })));
187
+ const globalOpts = getGlobalOptions();
188
+ const baseOpts = optionsToEndpoint(globalOpts);
189
+ const specificOpts = optionsToEndpoint(opts);
190
+ const endpoint = {
191
+ ...initV2Endpoint(globalOpts, opts),
192
+ platform: "gcfv2",
193
+ ...baseOpts,
194
+ ...specificOpts,
195
+ labels: {
196
+ ...baseOpts?.labels,
197
+ ...specificOpts?.labels
198
+ },
199
+ dataConnectGraphqlTrigger: {}
200
+ };
201
+ convertIfPresent(endpoint.dataConnectGraphqlTrigger, globalOpts, "invoker", "invoker", convertInvoker);
202
+ convertIfPresent(endpoint.dataConnectGraphqlTrigger, opts, "invoker", "invoker", convertInvoker);
203
+ if (opts.schemaFilePath) {
204
+ endpoint.dataConnectGraphqlTrigger.schemaFilePath = opts.schemaFilePath;
205
+ }
206
+ handler.__endpoint = endpoint;
207
+ return handler;
208
+ }
128
209
 
129
210
  //#endregion
130
- export { dataconnect_exports, mutationExecutedEventType, onMutationExecuted };
211
+ export { dataconnect_exports, initGraphqlServer, mutationExecutedEventType, onGraphRequest, onMutationExecuted };
@@ -45,6 +45,10 @@ export interface ManifestEndpoint {
45
45
  callableTrigger?: {
46
46
  genkitAction?: string;
47
47
  };
48
+ dataConnectGraphqlTrigger?: {
49
+ invoker?: string[];
50
+ schemaFilePath?: string;
51
+ };
48
52
  eventTrigger?: {
49
53
  eventFilters: Record<string, string | Expression<string>>;
50
54
  eventFilterPathPatterns?: Record<string, string | Expression<string>>;
@@ -1,3 +1,6 @@
1
+ import express from "express";
2
+ import type { GraphQLResolveInfo } from "graphql";
3
+ import { HttpsFunction, HttpsOptions } from "./https";
1
4
  import { CloudEvent, CloudFunction } from "../core";
2
5
  import { ParamsOf, VarName } from "../../common/params";
3
6
  import { EventHandlerOptions, SupportedRegion } from "../options";
@@ -93,3 +96,60 @@ export declare function onMutationExecuted<Mutation extends string, Variables =
93
96
  * @param handler - Event handler which is run every time a mutation is executed.
94
97
  */
95
98
  export declare function onMutationExecuted<Options extends OperationOptions, Variables = unknown, ResponseData = unknown>(opts: Options, handler: (event: DataConnectEvent<MutationEventData<Variables, ResponseData>, DataConnectParams<Options>>) => unknown | Promise<unknown>): CloudFunction<DataConnectEvent<MutationEventData<Variables, ResponseData>, DataConnectParams<Options>>>;
99
+ /** @hidden */
100
+ export declare function initGraphqlServer(opts: GraphqlServerOptions): Promise<express.Express>;
101
+ /**
102
+ * @hidden
103
+ * Handles HTTPS GraphQL requests.
104
+ * @param {GraphqlServerOptions} opts - Options for configuring the GraphQL server.
105
+ * @returns {HttpsFunction} A function you can export and deploy.
106
+ */
107
+ export declare function onGraphRequest(opts: GraphqlServerOptions): HttpsFunction;
108
+ /**
109
+ * @hidden
110
+ * Options for configuring the GraphQL server.
111
+ */
112
+ export interface GraphqlServerOptions extends Omit<HttpsOptions, "cors"> {
113
+ /**
114
+ * A valid SDL string that represents the GraphQL server's schema.
115
+ * Either `schema` or `schemaFilePath` is required.
116
+ */
117
+ schema?: string;
118
+ /**
119
+ * A relative file path from the Firebase project directory to a valid GraphQL schema.
120
+ * Either `schema` or `schemaFilePath` is required.
121
+ */
122
+ schemaFilePath?: string;
123
+ /**
124
+ * The path where the GraphQL server will be served on the Cloud Run function.
125
+ * e.g. https://...run.app/{path}
126
+ * If no path is provided, "graphql" is used as the default.
127
+ */
128
+ path?: string;
129
+ /** A map of functions that populate data for individual GraphQL schema fields. */
130
+ resolvers: GraphqlResolvers;
131
+ }
132
+ /**
133
+ * @hidden
134
+ * Per-request context state shared by all resolvers in a particular query.
135
+ */
136
+ export interface FirebaseContext {
137
+ auth?: {
138
+ /** The UID of the Firebase user that made the request, if present. */
139
+ uid?: string;
140
+ /** The token attached to the `X-Firebase-Auth-Token` in the request, if present. */
141
+ token?: string;
142
+ };
143
+ }
144
+ /**
145
+ * @hidden
146
+ * Resolver functions that populate data for individual GraphQL schema fields.
147
+ */
148
+ export interface GraphqlResolvers {
149
+ query?: {
150
+ [resolver: string]: (parent: unknown, args: Record<string, unknown>, context: FirebaseContext, info: GraphQLResolveInfo) => unknown;
151
+ };
152
+ mutation?: {
153
+ [key: string]: (parent: unknown, args: Record<string, unknown>, context: FirebaseContext, info: GraphQLResolveInfo) => unknown;
154
+ };
155
+ }
@@ -1,14 +1,22 @@
1
1
  const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.js');
2
2
  const require_runtime_manifest = require('../../runtime/manifest.js');
3
+ const require_common_encoding = require('../../common/encoding.js');
3
4
  const require_common_onInit = require('../../common/onInit.js');
5
+ const require_common_providers_https = require('../../common/providers/https.js');
4
6
  const require_common_utilities_path = require('../../common/utilities/path.js');
5
7
  const require_v2_trace = require('../trace.js');
6
8
  const require_v2_options = require('../options.js');
7
9
  const require_common_utilities_path_pattern = require('../../common/utilities/path-pattern.js');
10
+ let express = require("express");
11
+ express = require_rolldown_runtime.__toESM(express);
12
+ let fs = require("fs");
13
+ fs = require_rolldown_runtime.__toESM(fs);
8
14
 
9
15
  //#region src/v2/providers/dataconnect.ts
10
16
  var dataconnect_exports = /* @__PURE__ */ require_rolldown_runtime.__export({
17
+ initGraphqlServer: () => initGraphqlServer,
11
18
  mutationExecutedEventType: () => mutationExecutedEventType,
19
+ onGraphRequest: () => onGraphRequest,
12
20
  onMutationExecuted: () => onMutationExecuted
13
21
  });
14
22
  /** @internal */
@@ -125,6 +133,81 @@ function onOperation(eventType, mutationOrOpts, handler) {
125
133
  func.__endpoint = makeEndpoint(eventType, opts, servicePattern, connectorPattern, operationPattern);
126
134
  return func;
127
135
  }
136
+ /** @hidden */
137
+ async function initGraphqlServer(opts) {
138
+ if (!opts.schema && !opts.schemaFilePath || opts.schema && opts.schemaFilePath) {
139
+ throw new Error("Exactly one of 'schema' or 'schemaFilePath' must be provided.");
140
+ }
141
+ if (opts.schemaFilePath) {
142
+ opts.schema = fs.default.readFileSync(opts.schemaFilePath, "utf-8");
143
+ }
144
+ if (!opts.resolvers.query && !opts.resolvers.mutation) {
145
+ throw new Error("At least one query or mutation resolver must be provided.");
146
+ }
147
+ const apolloResolvers = {};
148
+ if (opts.resolvers.query) {
149
+ apolloResolvers.Query = opts.resolvers.query;
150
+ }
151
+ if (opts.resolvers.mutation) {
152
+ apolloResolvers.Mutation = opts.resolvers.mutation;
153
+ }
154
+ try {
155
+ const { ApolloServer } = await import("@apollo/server");
156
+ const { expressMiddleware } = await import("@as-integrations/express4");
157
+ const serverPromise$1 = (async () => {
158
+ const app = (0, express.default)();
159
+ const server = new ApolloServer({
160
+ typeDefs: opts.schema,
161
+ resolvers: apolloResolvers
162
+ });
163
+ await server.start();
164
+ app.use(`/${opts.path ?? "graphql"}`, express.default.json(), expressMiddleware(server));
165
+ return app;
166
+ })();
167
+ return serverPromise$1;
168
+ } catch (e) {
169
+ if (e instanceof Error) {
170
+ throw new Error("Error initializing GraphQL server: " + e.message);
171
+ } else {
172
+ throw e;
173
+ }
174
+ }
175
+ }
176
+ let serverPromise = null;
177
+ /**
178
+ * @hidden
179
+ * Handles HTTPS GraphQL requests.
180
+ * @param {GraphqlServerOptions} opts - Options for configuring the GraphQL server.
181
+ * @returns {HttpsFunction} A function you can export and deploy.
182
+ */
183
+ function onGraphRequest(opts) {
184
+ const handler = require_v2_trace.wrapTraceContext(require_common_onInit.withInit(require_common_providers_https.withErrorHandler(async (req, res) => {
185
+ serverPromise = serverPromise ?? initGraphqlServer(opts);
186
+ const app = await serverPromise;
187
+ app(req, res);
188
+ })));
189
+ const globalOpts = require_v2_options.getGlobalOptions();
190
+ const baseOpts = require_v2_options.optionsToEndpoint(globalOpts);
191
+ const specificOpts = require_v2_options.optionsToEndpoint(opts);
192
+ const endpoint = {
193
+ ...require_runtime_manifest.initV2Endpoint(globalOpts, opts),
194
+ platform: "gcfv2",
195
+ ...baseOpts,
196
+ ...specificOpts,
197
+ labels: {
198
+ ...baseOpts?.labels,
199
+ ...specificOpts?.labels
200
+ },
201
+ dataConnectGraphqlTrigger: {}
202
+ };
203
+ require_common_encoding.convertIfPresent(endpoint.dataConnectGraphqlTrigger, globalOpts, "invoker", "invoker", require_common_encoding.convertInvoker);
204
+ require_common_encoding.convertIfPresent(endpoint.dataConnectGraphqlTrigger, opts, "invoker", "invoker", require_common_encoding.convertInvoker);
205
+ if (opts.schemaFilePath) {
206
+ endpoint.dataConnectGraphqlTrigger.schemaFilePath = opts.schemaFilePath;
207
+ }
208
+ handler.__endpoint = endpoint;
209
+ return handler;
210
+ }
128
211
 
129
212
  //#endregion
130
213
  Object.defineProperty(exports, 'dataconnect_exports', {
@@ -133,5 +216,7 @@ Object.defineProperty(exports, 'dataconnect_exports', {
133
216
  return dataconnect_exports;
134
217
  }
135
218
  });
219
+ exports.initGraphqlServer = initGraphqlServer;
136
220
  exports.mutationExecutedEventType = mutationExecutedEventType;
221
+ exports.onGraphRequest = onGraphRequest;
137
222
  exports.onMutationExecuted = onMutationExecuted;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firebase-functions",
3
- "version": "7.0.2",
3
+ "version": "7.0.3",
4
4
  "description": "Firebase SDK for Cloud Functions",
5
5
  "keywords": [
6
6
  "firebase",
@@ -508,6 +508,8 @@
508
508
  "protobufjs": "^7.2.2"
509
509
  },
510
510
  "devDependencies": {
511
+ "@apollo/server": "^5.2.0",
512
+ "@as-integrations/express4": "^1.1.2",
511
513
  "@eslint/eslintrc": "^3.3.1",
512
514
  "@firebase/api-documenter": "^0.2.0",
513
515
  "@microsoft/api-documenter": "^7.13.45",
@@ -534,6 +536,7 @@
534
536
  "eslint-plugin-prettier": "^4.2.1",
535
537
  "firebase-admin": "^13.0.0",
536
538
  "genkit": "^1.0.0-rc.4",
539
+ "graphql": "^16.12.0",
537
540
  "jsdom": "^16.2.1",
538
541
  "jsonwebtoken": "^9.0.0",
539
542
  "jwk-to-pem": "^2.0.5",
@@ -554,8 +557,18 @@
554
557
  "yargs": "^15.3.1"
555
558
  },
556
559
  "peerDependencies": {
560
+ "@apollo/server": "^5.2.0",
561
+ "@as-integrations/express4": "^1.1.2",
557
562
  "firebase-admin": "^11.10.0 || ^12.0.0 || ^13.0.0"
558
563
  },
564
+ "peerDependenciesMeta": {
565
+ "@apollo/server": {
566
+ "optional": true
567
+ },
568
+ "@as-integrations/express4": {
569
+ "optional": true
570
+ }
571
+ },
559
572
  "engines": {
560
573
  "node": ">=18.0.0"
561
574
  }