No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.js 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.Delegate = exports.tryCreateDelegate = void 0;
  4. const util_1 = require("util");
  5. const fs = require("fs");
  6. const path = require("path");
  7. const portfinder = require("portfinder");
  8. const semver = require("semver");
  9. const spawn = require("cross-spawn");
  10. const node_fetch_1 = require("node-fetch");
  11. const error_1 = require("../../../../error");
  12. const parseRuntimeAndValidateSDK_1 = require("./parseRuntimeAndValidateSDK");
  13. const logger_1 = require("../../../../logger");
  14. const utils_1 = require("../../../../utils");
  15. const discovery = require("../discovery");
  16. const validate = require("./validate");
  17. const versioning = require("./versioning");
  18. const parseTriggers = require("./parseTriggers");
  19. const MIN_FUNCTIONS_SDK_VERSION = "3.20.0";
  20. async function tryCreateDelegate(context) {
  21. const packageJsonPath = path.join(context.sourceDir, "package.json");
  22. if (!(await (0, util_1.promisify)(fs.exists)(packageJsonPath))) {
  23. logger_1.logger.debug("Customer code is not Node");
  24. return undefined;
  25. }
  26. const runtime = (0, parseRuntimeAndValidateSDK_1.getRuntimeChoice)(context.sourceDir, context.runtime);
  27. if (!runtime.startsWith("nodejs")) {
  28. logger_1.logger.debug("Customer has a package.json but did not get a nodejs runtime. This should not happen");
  29. throw new error_1.FirebaseError(`Unexpected runtime ${runtime}`);
  30. }
  31. return new Delegate(context.projectId, context.projectDir, context.sourceDir, runtime);
  32. }
  33. exports.tryCreateDelegate = tryCreateDelegate;
  34. class Delegate {
  35. constructor(projectId, projectDir, sourceDir, runtime) {
  36. this.projectId = projectId;
  37. this.projectDir = projectDir;
  38. this.sourceDir = sourceDir;
  39. this.runtime = runtime;
  40. this.name = "nodejs";
  41. this._sdkVersion = undefined;
  42. }
  43. get sdkVersion() {
  44. if (this._sdkVersion === undefined) {
  45. this._sdkVersion = versioning.getFunctionsSDKVersion(this.sourceDir) || "";
  46. }
  47. return this._sdkVersion;
  48. }
  49. validate() {
  50. versioning.checkFunctionsSDKVersion(this.sdkVersion);
  51. const relativeDir = path.relative(this.projectDir, this.sourceDir);
  52. validate.packageJsonIsValid(relativeDir, this.sourceDir, this.projectDir);
  53. return Promise.resolve();
  54. }
  55. async build() {
  56. }
  57. watch() {
  58. return Promise.resolve(() => Promise.resolve());
  59. }
  60. serve(port, config, envs) {
  61. var _a;
  62. const env = Object.assign(Object.assign({}, envs), { PORT: port.toString(), FUNCTIONS_CONTROL_API: "true", HOME: process.env.HOME, PATH: process.env.PATH, NODE_ENV: process.env.NODE_ENV });
  63. if (Object.keys(config || {}).length) {
  64. env.CLOUD_RUNTIME_CONFIG = JSON.stringify(config);
  65. }
  66. const sdkPath = require.resolve("firebase-functions", { paths: [this.sourceDir] });
  67. const binPath = sdkPath.substring(0, sdkPath.lastIndexOf("node_modules") + 12);
  68. const childProcess = spawn(path.join(binPath, ".bin", "firebase-functions"), [this.sourceDir], {
  69. env,
  70. cwd: this.sourceDir,
  71. stdio: ["ignore", "pipe", "inherit"],
  72. });
  73. (_a = childProcess.stdout) === null || _a === void 0 ? void 0 : _a.on("data", (chunk) => {
  74. logger_1.logger.debug(chunk.toString());
  75. });
  76. return Promise.resolve(async () => {
  77. const p = new Promise((resolve, reject) => {
  78. childProcess.once("exit", resolve);
  79. childProcess.once("error", reject);
  80. });
  81. await (0, node_fetch_1.default)(`http://localhost:${port}/__/quitquitquit`);
  82. setTimeout(() => {
  83. if (!childProcess.killed) {
  84. childProcess.kill("SIGKILL");
  85. }
  86. }, 10000);
  87. return p;
  88. });
  89. }
  90. async discoverBuild(config, env) {
  91. if (!semver.valid(this.sdkVersion)) {
  92. logger_1.logger.debug(`Could not parse firebase-functions version '${this.sdkVersion}' into semver. Falling back to parseTriggers.`);
  93. return parseTriggers.discoverBuild(this.projectId, this.sourceDir, this.runtime, config, env);
  94. }
  95. if (semver.lt(this.sdkVersion, MIN_FUNCTIONS_SDK_VERSION)) {
  96. (0, utils_1.logLabeledWarning)("functions", `You are using an old version of firebase-functions SDK (${this.sdkVersion}). ` +
  97. `Please update firebase-functions SDK to >=${MIN_FUNCTIONS_SDK_VERSION}`);
  98. return parseTriggers.discoverBuild(this.projectId, this.sourceDir, this.runtime, config, env);
  99. }
  100. let discovered = await discovery.detectFromYaml(this.sourceDir, this.projectId, this.runtime);
  101. if (!discovered) {
  102. const getPort = (0, util_1.promisify)(portfinder.getPort);
  103. const port = await getPort();
  104. const kill = await this.serve(port, config, env);
  105. try {
  106. discovered = await discovery.detectFromPort(port, this.projectId, this.runtime);
  107. }
  108. finally {
  109. await kill();
  110. }
  111. }
  112. return discovered;
  113. }
  114. }
  115. exports.Delegate = Delegate;