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 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.Delegate = exports.tryCreateDelegate = exports.FUNCTIONS_RUNTIME = exports.FUNCTIONS_CODEGEN = exports.FUNCTIONS_SDK = exports.ADMIN_SDK = void 0;
  4. const util_1 = require("util");
  5. const node_fetch_1 = require("node-fetch");
  6. const fs = require("fs");
  7. const path = require("path");
  8. const spawn = require("cross-spawn");
  9. const error_1 = require("../../../../error");
  10. const logger_1 = require("../../../../logger");
  11. const gomod = require("./gomod");
  12. const VERSION_TO_RUNTIME = {
  13. "1.13": "go113",
  14. };
  15. exports.ADMIN_SDK = "firebase.google.com/go/v4";
  16. exports.FUNCTIONS_SDK = "github.com/FirebaseExtended/firebase-functions-go";
  17. exports.FUNCTIONS_CODEGEN = exports.FUNCTIONS_SDK + "/support/codegen";
  18. exports.FUNCTIONS_RUNTIME = exports.FUNCTIONS_SDK + "/support/runtime";
  19. async function tryCreateDelegate(context) {
  20. const goModPath = path.join(context.sourceDir, "go.mod");
  21. let module;
  22. try {
  23. const modBuffer = await (0, util_1.promisify)(fs.readFile)(goModPath);
  24. module = gomod.parseModule(modBuffer.toString("utf8"));
  25. }
  26. catch (err) {
  27. logger_1.logger.debug("Customer code is not Golang code (or they aren't using gomod)");
  28. return;
  29. }
  30. let runtime = context.runtime;
  31. if (!runtime) {
  32. if (!module.version) {
  33. throw new error_1.FirebaseError("Could not detect Golang version from go.mod");
  34. }
  35. if (!VERSION_TO_RUNTIME[module.version]) {
  36. throw new error_1.FirebaseError(`go.mod specifies Golang version ${module.version} which is unsupported by Google Cloud Functions. Valid values are ${Object.keys(VERSION_TO_RUNTIME).join(", ")}`);
  37. }
  38. runtime = VERSION_TO_RUNTIME[module.version];
  39. }
  40. return new Delegate(context.projectId, context.sourceDir, runtime, module);
  41. }
  42. exports.tryCreateDelegate = tryCreateDelegate;
  43. class Delegate {
  44. constructor(projectId, sourceDir, runtime, module) {
  45. this.projectId = projectId;
  46. this.sourceDir = sourceDir;
  47. this.runtime = runtime;
  48. this.module = module;
  49. this.name = "golang";
  50. }
  51. validate() {
  52. return Promise.resolve();
  53. }
  54. async build() {
  55. try {
  56. await (0, util_1.promisify)(fs.mkdir)(path.join(this.sourceDir, "autogen"));
  57. }
  58. catch (err) {
  59. if ((err === null || err === void 0 ? void 0 : err.code) !== "EEXIST") {
  60. throw new error_1.FirebaseError("Failed to create codegen directory", { children: [err] });
  61. }
  62. }
  63. const genBinary = spawn.sync("go", ["run", exports.FUNCTIONS_CODEGEN, this.module.module], {
  64. cwd: this.sourceDir,
  65. env: Object.assign(Object.assign({}, process.env), { HOME: process.env.HOME, PATH: process.env.PATH, GOPATH: process.env.GOPATH }),
  66. stdio: ["ignore", "pipe", "pipe"],
  67. });
  68. if (genBinary.status !== 0) {
  69. throw new error_1.FirebaseError("Failed to run codegen", {
  70. children: [new Error(genBinary.stderr.toString())],
  71. });
  72. }
  73. await (0, util_1.promisify)(fs.writeFile)(path.join(this.sourceDir, "autogen", "main.go"), genBinary.stdout);
  74. }
  75. watch() {
  76. return Promise.resolve(() => Promise.resolve());
  77. }
  78. serve(port, adminPort, envs) {
  79. var _a;
  80. const childProcess = spawn("go", ["run", "./autogen"], {
  81. env: Object.assign(Object.assign(Object.assign({}, process.env), envs), { PORT: port.toString(), ADMIN_PORT: adminPort.toString(), HOME: process.env.HOME, PATH: process.env.PATH, GOPATH: process.env.GOPATH }),
  82. cwd: this.sourceDir,
  83. stdio: ["ignore", "pipe", "inherit"],
  84. });
  85. (_a = childProcess.stdout) === null || _a === void 0 ? void 0 : _a.on("data", (chunk) => {
  86. logger_1.logger.debug(chunk.toString());
  87. });
  88. return Promise.resolve(async () => {
  89. const p = new Promise((resolve, reject) => {
  90. childProcess.once("exit", resolve);
  91. childProcess.once("error", reject);
  92. });
  93. await (0, node_fetch_1.default)(`http://localhost:${adminPort}/__/quitquitquit`);
  94. setTimeout(() => {
  95. if (!childProcess.killed) {
  96. childProcess.kill("SIGKILL");
  97. }
  98. }, 10000);
  99. return p;
  100. });
  101. }
  102. async discoverBuild() {
  103. return Promise.resolve({ requiredAPIs: [], endpoints: {}, params: [] });
  104. }
  105. }
  106. exports.Delegate = Delegate;