Skip to content

Commit 73702ed

Browse files
committed
Clean up manifest parsing
1 parent 0b6f5a9 commit 73702ed

2 files changed

Lines changed: 133 additions & 24 deletions

File tree

src/deploy/functions/runtimes/discovery/v1alpha1.spec.ts

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,4 +1102,136 @@ describe("buildFromV1Alpha", () => {
11021102
expect(parsed).to.deep.equal(expected);
11031103
});
11041104
});
1105+
1106+
describe("lifecycleHooks", () => {
1107+
it("copies valid task lifecycle hooks", () => {
1108+
const yaml: v1alpha1.WireManifest = {
1109+
specVersion: "v1alpha1",
1110+
endpoints: {},
1111+
lifecycleHooks: {
1112+
afterInstall: {
1113+
task: {
1114+
function: "myTaskFunc",
1115+
body: { key: "value" },
1116+
},
1117+
},
1118+
},
1119+
};
1120+
1121+
const parsed = v1alpha1.buildFromV1Alpha1(yaml, PROJECT, REGION, RUNTIME);
1122+
const expected: build.Build = build.empty();
1123+
expected.lifecycleHooks = {
1124+
afterInstall: {
1125+
task: {
1126+
function: "myTaskFunc",
1127+
body: { key: "value" },
1128+
},
1129+
},
1130+
};
1131+
expect(parsed).to.deep.equal(expected);
1132+
});
1133+
1134+
it("copies valid callable lifecycle hooks", () => {
1135+
const yaml: v1alpha1.WireManifest = {
1136+
specVersion: "v1alpha1",
1137+
endpoints: {},
1138+
lifecycleHooks: {
1139+
afterUpdate: {
1140+
callable: {
1141+
function: "myCallableFunc",
1142+
},
1143+
},
1144+
},
1145+
};
1146+
1147+
const parsed = v1alpha1.buildFromV1Alpha1(yaml, PROJECT, REGION, RUNTIME);
1148+
const expected: build.Build = build.empty();
1149+
expected.lifecycleHooks = {
1150+
afterUpdate: {
1151+
callable: {
1152+
function: "myCallableFunc",
1153+
},
1154+
},
1155+
};
1156+
expect(parsed).to.deep.equal(expected);
1157+
});
1158+
1159+
it("copies valid http lifecycle hooks", () => {
1160+
const yaml: v1alpha1.WireManifest = {
1161+
specVersion: "v1alpha1",
1162+
endpoints: {},
1163+
lifecycleHooks: {
1164+
afterInstall: {
1165+
http: {
1166+
url: "https://example.com/hook",
1167+
body: "some-body",
1168+
},
1169+
},
1170+
},
1171+
};
1172+
1173+
const parsed = v1alpha1.buildFromV1Alpha1(yaml, PROJECT, REGION, RUNTIME);
1174+
const expected: build.Build = build.empty();
1175+
expected.lifecycleHooks = {
1176+
afterInstall: {
1177+
http: {
1178+
url: "https://example.com/hook",
1179+
body: "some-body",
1180+
},
1181+
},
1182+
};
1183+
expect(parsed).to.deep.equal(expected);
1184+
});
1185+
1186+
it("throws on invalid event type", () => {
1187+
const yaml = {
1188+
specVersion: "v1alpha1",
1189+
endpoints: {},
1190+
lifecycleHooks: {
1191+
invalidHookName: {
1192+
task: {
1193+
function: "myTaskFunc",
1194+
},
1195+
},
1196+
},
1197+
};
1198+
1199+
expect(() => v1alpha1.buildFromV1Alpha1(yaml, PROJECT, REGION, RUNTIME)).to.throw(
1200+
FirebaseError,
1201+
/Invalid eventType "invalidHookName" for lifecycle hook/,
1202+
);
1203+
});
1204+
1205+
it("throws when target function is missing in task hook", () => {
1206+
const yaml = {
1207+
specVersion: "v1alpha1",
1208+
endpoints: {},
1209+
lifecycleHooks: {
1210+
afterInstall: {
1211+
task: {},
1212+
},
1213+
},
1214+
};
1215+
1216+
expect(() => v1alpha1.buildFromV1Alpha1(yaml, PROJECT, REGION, RUNTIME)).to.throw(
1217+
FirebaseError,
1218+
/Invalid target "" for lifecycle hook "afterInstall"/,
1219+
);
1220+
});
1221+
1222+
it("throws when action is missing", () => {
1223+
const yaml = {
1224+
specVersion: "v1alpha1",
1225+
endpoints: {},
1226+
lifecycleHooks: {
1227+
afterInstall: {},
1228+
},
1229+
};
1230+
1231+
expect(() => v1alpha1.buildFromV1Alpha1(yaml, PROJECT, REGION, RUNTIME)).to.throw(
1232+
FirebaseError,
1233+
/No action \(task, callable, or http\) specified for lifecycle hook "afterInstall"/,
1234+
);
1235+
});
1236+
});
11051237
});

src/deploy/functions/runtimes/discovery/v1alpha1.ts

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -157,54 +157,31 @@ export function buildFromV1Alpha1(
157157
if (!hook || typeof hook !== "object") {
158158
throw new FirebaseError(`Invalid lifecycle hook configuration for "${id}".`);
159159
}
160-
const parsedHook: backend.LifecycleHook = {};
161160

162161
if (hook.task) {
163162
if (typeof hook.task.function !== "string" || !hook.task.function) {
164163
throw new FirebaseError(
165164
`Invalid target "${hook.task.function || ""}" for lifecycle hook "${id}"`,
166165
);
167166
}
168-
parsedHook.task = {
169-
function: hook.task.function,
170-
};
171-
if (hook.task.body !== undefined) {
172-
parsedHook.task.body = hook.task.body as Record<string, unknown>;
173-
}
174167
} else if (hook.callable) {
175168
if (typeof hook.callable.function !== "string" || !hook.callable.function) {
176169
throw new FirebaseError(
177170
`Invalid target "${hook.callable.function || ""}" for lifecycle hook "${id}"`,
178171
);
179172
}
180-
parsedHook.callable = {
181-
function: hook.callable.function,
182-
};
183-
if (hook.callable.body !== undefined) {
184-
parsedHook.callable.body = hook.callable.body as Record<string, unknown>;
185-
}
186173
} else if (hook.http) {
187174
const target = hook.http.url || hook.http.function;
188175
if (typeof target !== "string" || !target) {
189176
throw new FirebaseError(`Invalid target "${target || ""}" for lifecycle hook "${id}"`);
190177
}
191-
parsedHook.http = {};
192-
if (hook.http.function) {
193-
parsedHook.http.function = hook.http.function;
194-
}
195-
if (hook.http.url) {
196-
parsedHook.http.url = hook.http.url;
197-
}
198-
if (hook.http.body !== undefined) {
199-
parsedHook.http.body = hook.http.body;
200-
}
201178
} else {
202179
throw new FirebaseError(
203180
`No action (task, callable, or http) specified for lifecycle hook "${id}"`,
204181
);
205182
}
206183

207-
bd.lifecycleHooks[id] = parsedHook;
184+
bd.lifecycleHooks[id] = hook as backend.LifecycleHook;
208185
}
209186
}
210187
return bd;

0 commit comments

Comments
 (0)