placementt-core 1.400.1144 → 1.400.1145

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,3 +13,12 @@ export declare function resolveActivities(activities: {
13
13
  }, overrides?: InstituteData["activityOverrides"]): {
14
14
  [id: string]: ExternalActivity;
15
15
  };
16
+ /** Ids of the careers hubs an institute has an approved link with. */
17
+ export declare function approvedCareersHubIds(institute?: Pick<InstituteData, "careersHubLinks">): string[];
18
+ /**
19
+ * The activityOverrides that apply when `institute` views activities. A hub uses its own.
20
+ * A school linked to careers hubs inherits each approved hub's overrides, so its staff,
21
+ * employers and alumni see the hub's wording and not the global one; anything the school
22
+ * sets itself wins. Pass the hubs named by approvedCareersHubIds(institute).
23
+ */
24
+ export declare function combineActivityOverrides(institute?: Pick<InstituteData, "activityOverrides">, hubs?: (Pick<InstituteData, "activityOverrides"> | undefined)[]): InstituteData["activityOverrides"];
package/lib/activities.js CHANGED
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resolveActivities = resolveActivities;
4
+ exports.approvedCareersHubIds = approvedCareersHubIds;
5
+ exports.combineActivityOverrides = combineActivityOverrides;
4
6
  /**
5
7
  * Applies a hub's activityOverrides to a set of public activities. Every read path
6
8
  * (frontend and backend) must pass fetched externalActivities through this before
@@ -26,4 +28,23 @@ function resolveActivities(activities, overrides) {
26
28
  }];
27
29
  }));
28
30
  }
31
+ /** Ids of the careers hubs an institute has an approved link with. */
32
+ function approvedCareersHubIds(institute) {
33
+ return Object.entries(institute?.careersHubLinks || {})
34
+ .filter(([, link]) => link.status === "approved")
35
+ .map(([hubId]) => hubId);
36
+ }
37
+ /**
38
+ * The activityOverrides that apply when `institute` views activities. A hub uses its own.
39
+ * A school linked to careers hubs inherits each approved hub's overrides, so its staff,
40
+ * employers and alumni see the hub's wording and not the global one; anything the school
41
+ * sets itself wins. Pass the hubs named by approvedCareersHubIds(institute).
42
+ */
43
+ function combineActivityOverrides(institute, hubs = []) {
44
+ const combined = {};
45
+ [...hubs.map((hub) => hub?.activityOverrides), institute?.activityOverrides].forEach((overrides) => Object.entries(overrides || {}).forEach(([id, override]) => {
46
+ combined[id] = { ...combined[id], ...override };
47
+ }));
48
+ return Object.keys(combined).length ? combined : undefined;
49
+ }
29
50
  //# sourceMappingURL=activities.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"activities.js","sourceRoot":"","sources":["../src/activities.ts"],"names":[],"mappings":";;AAWA,8CAgBC;AAzBD;;;;;;;;GAQG;AACH,SAAgB,iBAAiB,CAC7B,UAA4C,EAC5C,SAA8C;IAE9C,IAAI,CAAC,SAAS;QAAE,OAAO,UAAU,CAAC;IAClC,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE;QACxE,MAAM,QAAQ,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,CAAC,QAAQ;YAAE,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QACrC,OAAO,CAAC,EAAE,EAAE;gBACR,GAAG,QAAQ;gBACX,GAAG,CAAC,QAAQ,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChE,GAAG,CAAC,QAAQ,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAC,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClF,GAAG,CAAC,QAAQ,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,IAAI,KAAK;aACvC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC,CAAC;AACR,CAAC"}
1
+ {"version":3,"file":"activities.js","sourceRoot":"","sources":["../src/activities.ts"],"names":[],"mappings":";;AAWA,8CAgBC;AAGD,sDAIC;AAQD,4DAUC;AAlDD;;;;;;;;GAQG;AACH,SAAgB,iBAAiB,CAC7B,UAA4C,EAC5C,SAA8C;IAE9C,IAAI,CAAC,SAAS;QAAE,OAAO,UAAU,CAAC;IAClC,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE;QACxE,MAAM,QAAQ,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,CAAC,QAAQ;YAAE,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QACrC,OAAO,CAAC,EAAE,EAAE;gBACR,GAAG,QAAQ;gBACX,GAAG,CAAC,QAAQ,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChE,GAAG,CAAC,QAAQ,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAC,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClF,GAAG,CAAC,QAAQ,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,IAAI,KAAK;aACvC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC,CAAC;AACR,CAAC;AAED,sEAAsE;AACtE,SAAgB,qBAAqB,CAAC,SAAkD;IACpF,OAAO,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,eAAe,IAAI,EAAE,CAAC;SAClD,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC;SAChD,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC;AAED;;;;;GAKG;AACH,SAAgB,wBAAwB,CACpC,SAAoD,EACpD,OAA+D,EAAE;IAEjE,MAAM,QAAQ,GAAoD,EAAE,CAAC;IACrE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,iBAAiB,CAAC,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CAC/F,MAAM,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE;QACvD,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,EAAE,GAAG,QAAQ,EAAC,CAAC;IAClD,CAAC,CAAC,CAAC,CAAC;IACR,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/D,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const activities_1 = require("./activities");
4
+ const link = (status) => ({ exists: true, invited: "2026-09-01", status });
5
+ describe("approvedCareersHubIds", () => {
6
+ it("returns only hubs the school has an approved link with", () => {
7
+ expect((0, activities_1.approvedCareersHubIds)({ careersHubLinks: {
8
+ solent: link("approved"),
9
+ surrey: link("invited"),
10
+ sutherland: link("declined"),
11
+ } })).toEqual(["solent"]);
12
+ });
13
+ it("returns nothing for an institute with no links", () => {
14
+ expect((0, activities_1.approvedCareersHubIds)({})).toEqual([]);
15
+ expect((0, activities_1.approvedCareersHubIds)(undefined)).toEqual([]);
16
+ });
17
+ });
18
+ describe("combineActivityOverrides", () => {
19
+ it("gives a hub its own overrides", () => {
20
+ expect((0, activities_1.combineActivityOverrides)({ activityOverrides: { a: { title: "Networking Activity" } } }))
21
+ .toEqual({ a: { title: "Networking Activity" } });
22
+ });
23
+ it("gives a linked school its hub's overrides", () => {
24
+ expect((0, activities_1.combineActivityOverrides)({}, [{ activityOverrides: { a: { title: "Employer Workshop", disabled: false }, b: { disabled: true } } }]))
25
+ .toEqual({ a: { title: "Employer Workshop", disabled: false }, b: { disabled: true } });
26
+ });
27
+ it("lets the school's own override win, field by field", () => {
28
+ expect((0, activities_1.combineActivityOverrides)({ activityOverrides: { a: { description: "School wording" } } }, [{ activityOverrides: { a: { title: "Hub title", description: "Hub wording" } } }])).toEqual({ a: { title: "Hub title", description: "School wording" } });
29
+ });
30
+ it("returns undefined when nothing is overridden", () => {
31
+ expect((0, activities_1.combineActivityOverrides)({}, [undefined, {}])).toBeUndefined();
32
+ });
33
+ it("feeds resolveActivities so a school sees the hub's rename and disable", () => {
34
+ const activities = {
35
+ a: { title: "CV/Personal Statements", description: "", color: "#000", activityType: "other" },
36
+ b: { title: "Short Placement", description: "", color: "#000", activityType: "workExperience" },
37
+ };
38
+ const resolved = (0, activities_1.resolveActivities)(activities, (0, activities_1.combineActivityOverrides)({}, [{ activityOverrides: {
39
+ a: { title: "Employer Workshop" },
40
+ b: { disabled: true },
41
+ } }]));
42
+ expect(resolved.a.title).toBe("Employer Workshop");
43
+ expect(resolved.b.disabled).toBe(true);
44
+ });
45
+ });
46
+ //# sourceMappingURL=activities.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activities.test.js","sourceRoot":"","sources":["../src/activities.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "private": false,
3
3
  "name": "placementt-core",
4
4
  "author": "Placementt",
5
- "version": "1.400.1144",
5
+ "version": "1.400.1145",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/index.d.ts",
8
8
  "scripts": {
@@ -0,0 +1,55 @@
1
+ import {approvedCareersHubIds, combineActivityOverrides, resolveActivities} from "./activities";
2
+ import {ExternalActivity, InstituteData} from "./typeDefinitions";
3
+
4
+ const link = (status: "invited"|"approved"|"declined") => ({exists: true, invited: "2026-09-01", status});
5
+
6
+ describe("approvedCareersHubIds", () => {
7
+ it("returns only hubs the school has an approved link with", () => {
8
+ expect(approvedCareersHubIds({careersHubLinks: {
9
+ solent: link("approved"),
10
+ surrey: link("invited"),
11
+ sutherland: link("declined"),
12
+ }} as Pick<InstituteData, "careersHubLinks">)).toEqual(["solent"]);
13
+ });
14
+
15
+ it("returns nothing for an institute with no links", () => {
16
+ expect(approvedCareersHubIds({})).toEqual([]);
17
+ expect(approvedCareersHubIds(undefined)).toEqual([]);
18
+ });
19
+ });
20
+
21
+ describe("combineActivityOverrides", () => {
22
+ it("gives a hub its own overrides", () => {
23
+ expect(combineActivityOverrides({activityOverrides: {a: {title: "Networking Activity"}}}))
24
+ .toEqual({a: {title: "Networking Activity"}});
25
+ });
26
+
27
+ it("gives a linked school its hub's overrides", () => {
28
+ expect(combineActivityOverrides({}, [{activityOverrides: {a: {title: "Employer Workshop", disabled: false}, b: {disabled: true}}}]))
29
+ .toEqual({a: {title: "Employer Workshop", disabled: false}, b: {disabled: true}});
30
+ });
31
+
32
+ it("lets the school's own override win, field by field", () => {
33
+ expect(combineActivityOverrides(
34
+ {activityOverrides: {a: {description: "School wording"}}},
35
+ [{activityOverrides: {a: {title: "Hub title", description: "Hub wording"}}}],
36
+ )).toEqual({a: {title: "Hub title", description: "School wording"}});
37
+ });
38
+
39
+ it("returns undefined when nothing is overridden", () => {
40
+ expect(combineActivityOverrides({}, [undefined, {}])).toBeUndefined();
41
+ });
42
+
43
+ it("feeds resolveActivities so a school sees the hub's rename and disable", () => {
44
+ const activities: {[id: string]: ExternalActivity} = {
45
+ a: {title: "CV/Personal Statements", description: "", color: "#000", activityType: "other"},
46
+ b: {title: "Short Placement", description: "", color: "#000", activityType: "workExperience"},
47
+ };
48
+ const resolved = resolveActivities(activities, combineActivityOverrides({}, [{activityOverrides: {
49
+ a: {title: "Employer Workshop"},
50
+ b: {disabled: true},
51
+ }}]));
52
+ expect(resolved.a.title).toBe("Employer Workshop");
53
+ expect(resolved.b.disabled).toBe(true);
54
+ });
55
+ });
package/src/activities.ts CHANGED
@@ -26,3 +26,28 @@ export function resolveActivities(
26
26
  }];
27
27
  }));
28
28
  }
29
+
30
+ /** Ids of the careers hubs an institute has an approved link with. */
31
+ export function approvedCareersHubIds(institute?: Pick<InstituteData, "careersHubLinks">): string[] {
32
+ return Object.entries(institute?.careersHubLinks || {})
33
+ .filter(([, link]) => link.status === "approved")
34
+ .map(([hubId]) => hubId);
35
+ }
36
+
37
+ /**
38
+ * The activityOverrides that apply when `institute` views activities. A hub uses its own.
39
+ * A school linked to careers hubs inherits each approved hub's overrides, so its staff,
40
+ * employers and alumni see the hub's wording and not the global one; anything the school
41
+ * sets itself wins. Pass the hubs named by approvedCareersHubIds(institute).
42
+ */
43
+ export function combineActivityOverrides(
44
+ institute?: Pick<InstituteData, "activityOverrides">,
45
+ hubs: (Pick<InstituteData, "activityOverrides">|undefined)[] = [],
46
+ ): InstituteData["activityOverrides"] {
47
+ const combined: NonNullable<InstituteData["activityOverrides"]> = {};
48
+ [...hubs.map((hub) => hub?.activityOverrides), institute?.activityOverrides].forEach((overrides) =>
49
+ Object.entries(overrides || {}).forEach(([id, override]) => {
50
+ combined[id] = {...combined[id], ...override};
51
+ }));
52
+ return Object.keys(combined).length ? combined : undefined;
53
+ }