Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions scripts/bin-test/sources/esm-quoted-hyphen/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as functions from "firebase-functions/v1";

const func = functions.https.onRequest((req, resp) => {
resp.status(200).send("PASS");
});

export { func as "dummystore-bot" };
4 changes: 4 additions & 0 deletions scripts/bin-test/sources/esm-quoted-hyphen/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "esm-quoted-hyphen",
"type": "module"
}
17 changes: 17 additions & 0 deletions scripts/bin-test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,23 @@ describe("functions.yaml", function () {
extensions: {},
},
},
{
name: "quoted hyphen export",
modulePath: "./scripts/bin-test/sources/esm-quoted-hyphen",
expected: {
endpoints: {
"dummystore-bot": {
...DEFAULT_V1_OPTIONS,
platform: "gcfv1",
entryPoint: "dummystore-bot",
httpsTrigger: {},
},
},
requiredAPIs: [],
specVersion: "v1alpha1",
extensions: {},
},
},
];

for (const tc of testcases) {
Expand Down
28 changes: 28 additions & 0 deletions spec/runtime/loader.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,34 @@ describe("extractStack", () => {
});
});

it("preserves literal hyphens in the entry point for flat export names", () => {
const module = {
"dummystore-bot": httpFn,
grouped: {
fn: httpFn,
},
};

const endpoints: Record<string, ManifestEndpoint> = {};
const requiredAPIs: ManifestRequiredAPI[] = [];
const extensions: Record<string, ManifestExtension> = {};

loader.extractStack(module, endpoints, requiredAPIs, extensions);

expect(endpoints).to.be.deep.equal({
"dummystore-bot": {
...MINIMAL_V1_ENDPOINT,
entryPoint: "dummystore-bot",
...httpEndpoint,
},
"grouped-fn": {
...MINIMAL_V1_ENDPOINT,
entryPoint: "grouped.fn",
...httpEndpoint,
},
});
});

describe("with GCLOUD_PROJECT env var", () => {
const project = "my-project";
let prev;
Expand Down
19 changes: 14 additions & 5 deletions src/runtime/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,18 @@ export function extractStack(
endpoints: Record<string, ManifestEndpoint>,
requiredAPIs: ManifestRequiredAPI[],
extensions: Record<string, ManifestExtension>,
prefix = ""
endpointIdPrefix = "",
entryPointPrefix = ""
) {
for (const [name, valAsUnknown] of Object.entries(module)) {
// We're introspecting untrusted code here. Any is appropraite
const val: any = valAsUnknown;
if (typeof val === "function" && val.__endpoint && typeof val.__endpoint === "object") {
const funcName = prefix + name;
endpoints[funcName] = {
const endpointId = endpointIdPrefix + name;
const entryPoint = entryPointPrefix + name;
endpoints[endpointId] = {
...val.__endpoint,
entryPoint: funcName.replace(/-/g, "."),
entryPoint,
};
if (val.__requiredAPIs && Array.isArray(val.__requiredAPIs)) {
requiredAPIs.push(...val.__requiredAPIs);
Expand All @@ -92,7 +94,14 @@ export function extractStack(
events: val.events || [],
};
} else if (isObject(val)) {
extractStack(val, endpoints, requiredAPIs, extensions, prefix + name + "-");
extractStack(
val,
endpoints,
requiredAPIs,
extensions,
endpointIdPrefix + name + "-",
entryPointPrefix + name + "."
);
}
}
}
Expand Down
Loading