Skip to content
2 changes: 1 addition & 1 deletion src/deploy/functions/runtimes/discovery/v1alpha1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@
}

const ROLE_REGEX =
/^(roles\/[a-zA-Z0-9_\.\-]+|projects\/[a-zA-Z0-9\-]+\/roles\/[a-zA-Z0-9_\.\-]+|organizations\/[0-9]+\/roles\/[a-zA-Z0-9_\.\-]+)$/;

Check warning on line 197 in src/deploy/functions/runtimes/discovery/v1alpha1.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unnecessary escape character: \-

Check warning on line 197 in src/deploy/functions/runtimes/discovery/v1alpha1.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unnecessary escape character: \.

Check warning on line 197 in src/deploy/functions/runtimes/discovery/v1alpha1.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unnecessary escape character: \-

Check warning on line 197 in src/deploy/functions/runtimes/discovery/v1alpha1.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unnecessary escape character: \.

Check warning on line 197 in src/deploy/functions/runtimes/discovery/v1alpha1.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unnecessary escape character: \-

Check warning on line 197 in src/deploy/functions/runtimes/discovery/v1alpha1.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unnecessary escape character: \-

Check warning on line 197 in src/deploy/functions/runtimes/discovery/v1alpha1.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unnecessary escape character: \.

function parseRequiredRoles(manifest: WireManifest): string[] {
const roles: string[] = manifest.requiredRoles || [];
Expand Down Expand Up @@ -230,7 +230,7 @@
assertKeyTypes(prefix, ep, {
region: "List",
platform: (platform) => build.AllFunctionsPlatforms.includes(platform),
entryPoint: "string",
entryPoint: (ep) => typeof ep === "string" && ep.length > 0,
omit: "Field<boolean>?",
availableMemoryMb: (mem) => mem === null || isCEL(mem) || backend.isValidMemoryOption(mem),
maxInstances: "Field<number>?",
Expand Down Expand Up @@ -396,8 +396,8 @@
retry: ep.eventTrigger.retry,
};
// Allow serviceAccountEmail but prefer serviceAccount
if ("serviceAccountEmail" in (ep.eventTrigger as any)) {

Check warning on line 399 in src/deploy/functions/runtimes/discovery/v1alpha1.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unexpected any. Specify a different type
eventTrigger.serviceAccount = (ep.eventTrigger as any).serviceAccountEmail;

Check warning on line 400 in src/deploy/functions/runtimes/discovery/v1alpha1.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe member access .serviceAccountEmail on an `any` value

Check warning on line 400 in src/deploy/functions/runtimes/discovery/v1alpha1.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe assignment of an `any` value
}
copyIfPresent(
eventTrigger,
Expand Down
43 changes: 43 additions & 0 deletions src/functionsShellCommandAction.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { expect } from "chai";

import { initializeFunctionsShellContext } from "./functionsShellCommandAction";
import { EmulatedTriggerDefinition } from "./emulator/functionsEmulatorShared";
import { FunctionsEmulatorShell } from "./emulator/functionsEmulatorShell";

describe("initializeFunctionsShellContext", () => {
it("uses trigger.entryPoint for shell bindings", () => {
const hyphenatedTrigger: EmulatedTriggerDefinition = {
id: "us-central1-dummystore-bot",
region: "us-central1",
platform: "gcfv1",
name: "dummystore-bot",
entryPoint: "dummystore-bot",
httpsTrigger: {},
};
const groupedTrigger: EmulatedTriggerDefinition = {
id: "us-central1-grouped-fn",
region: "us-central1",
platform: "gcfv1",
name: "grouped-fn",
entryPoint: "grouped.fn",
httpsTrigger: {},
};

const emulator = {
triggers: [hyphenatedTrigger, groupedTrigger],
emulatedFunctions: [hyphenatedTrigger.id, groupedTrigger.id],
urls: {
[hyphenatedTrigger.id]: "http://127.0.0.1/hyphenated",
[groupedTrigger.id]: "http://127.0.0.1/grouped",
},
} as FunctionsEmulatorShell;

const context: Record<string, unknown> = {};
initializeFunctionsShellContext(context, emulator);

expect(context).to.have.property("dummystore-bot").that.is.a("function");
expect(context).to.not.have.nested.property("dummystore.bot");
expect(context).to.have.nested.property("grouped.fn").that.is.a("function");
expect(context).to.have.property("help").that.is.a("string");
});
});
32 changes: 17 additions & 15 deletions src/functionsShellCommandAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,21 @@ import { needProjectId } from "./projectUtils";

const serveFunctions = new FunctionsServer();

export const initializeFunctionsShellContext = (
context: Record<string, unknown>,
emulator: shell.FunctionsEmulatorShell,
) => {
for (const trigger of emulator.triggers) {
if (emulator.emulatedFunctions.includes(trigger.id)) {
const localFunction = new LocalFunction(trigger, emulator.urls, emulator);
_.set(context, trigger.entryPoint, localFunction.makeFn());
}
}
context.help =
"Instructions for the Functions Shell can be found at: " +
"https://firebase.google.com/docs/functions/local-emulator";
};

export const actionFunction = async (options: Options) => {
if (typeof options.port === "string") {
options.port = parseInt(options.port, 10);
Expand Down Expand Up @@ -95,19 +110,6 @@ export const actionFunction = async (options: Options) => {
process.exit();
}

const initializeContext = (context: any) => {
for (const trigger of emulator.triggers) {
if (emulator.emulatedFunctions.includes(trigger.id)) {
const localFunction = new LocalFunction(trigger, emulator.urls, emulator);
const triggerNameDotNotation = trigger.name.replace(/-/g, ".");
_.set(context, triggerNameDotNotation, localFunction.makeFn());
}
}
context.help =
"Instructions for the Functions Shell can be found at: " +
"https://firebase.google.com/docs/functions/local-emulator";
};

for (const e of runningEmulators) {
const info = remoteEmulators[e];
utils.logLabeledBullet(
Expand Down Expand Up @@ -138,8 +140,8 @@ export const actionFunction = async (options: Options) => {
writer: writer,
useColors: true,
});
initializeContext(replServer.context);
replServer.on("reset", initializeContext);
initializeFunctionsShellContext(replServer.context, emulator);
replServer.on("reset", (context) => initializeFunctionsShellContext(context, emulator));

return new Promise((resolve) => {
replServer.on("exit", () => {
Expand Down
50 changes: 50 additions & 0 deletions src/gcp/cloudfunctionsv2.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,31 @@ describe("cloudfunctionsv2", () => {
await cloudfunctionsv2.createFunction(testFunction);
expect(scope.isDone()).to.be.true;
});

it("should preserve a hyphenated entry point in FUNCTION_TARGET", async () => {
const testFunction = {
...CLOUD_FUNCTION_V2,
buildConfig: {
...CLOUD_FUNCTION_V2.buildConfig,
entryPoint: "dummystore-bot",
environmentVariables: {},
},
};

const scope = nock(functionsV2Origin())
.post("/v2/projects/project/locations/region/functions", (body) => {
expect(body.serviceConfig.environmentVariables).to.have.property(
"FUNCTION_TARGET",
"dummystore-bot",
);
return true;
})
.query({ functionId: "id" })
.reply(200, { name: "operations/123", done: true });

await cloudfunctionsv2.createFunction(testFunction);
expect(scope.isDone()).to.be.true;
});
});

describe("updateFunction", () => {
Expand All @@ -966,5 +991,30 @@ describe("cloudfunctionsv2", () => {
await cloudfunctionsv2.updateFunction(CLOUD_FUNCTION_V2);
expect(scope.isDone()).to.be.true;
});

it("should preserve a hyphenated entry point in FUNCTION_TARGET", async () => {
const testFunction = {
...CLOUD_FUNCTION_V2,
buildConfig: {
...CLOUD_FUNCTION_V2.buildConfig,
entryPoint: "dummystore-bot",
environmentVariables: {},
},
};

const scope = nock(functionsV2Origin())
.patch("/v2/projects/project/locations/region/functions/id", (body) => {
expect(body.serviceConfig.environmentVariables).to.have.property(
"FUNCTION_TARGET",
"dummystore-bot",
);
return true;
})
.query(true)
.reply(200, { name: "operations/123", done: true });

await cloudfunctionsv2.updateFunction(testFunction);
expect(scope.isDone()).to.be.true;
});
});
});
4 changes: 2 additions & 2 deletions src/gcp/cloudfunctionsv2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ export async function createFunction(cloudFunction: InputCloudFunction): Promise

cloudFunction.serviceConfig.environmentVariables = {
...cloudFunction.serviceConfig.environmentVariables,
FUNCTION_TARGET: cloudFunction.buildConfig.entryPoint.replaceAll("-", "."),
FUNCTION_TARGET: cloudFunction.buildConfig.entryPoint,
// Enable logging execution id by default for better debugging
LOG_EXECUTION_ID: "true",
};
Expand Down Expand Up @@ -394,7 +394,7 @@ export async function updateFunction(cloudFunction: InputCloudFunction): Promise
};
cloudFunction.serviceConfig.environmentVariables = {
...cloudFunction.serviceConfig.environmentVariables,
FUNCTION_TARGET: cloudFunction.buildConfig.entryPoint.replaceAll("-", "."),
FUNCTION_TARGET: cloudFunction.buildConfig.entryPoint,
// Enable logging execution id by default for better debugging
LOG_EXECUTION_ID: "true",
};
Expand Down
Loading