diff --git a/package.json b/package.json index 715b6ce..bf8b1ad 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "✅ Do add `devDependencies` below that are `peerDependencies` in the CFL package." ], "dependencies": { - "codeforlife": "github:ocadotechnology/codeforlife-package-javascript#v2.1.3", + "codeforlife": "github:ocadotechnology/codeforlife-package-javascript#v2.1.4", "crypto-js": "^4.2.0" }, "devDependencies": { diff --git a/src/api/authFactor.ts b/src/api/authFactor.ts index 1aa6d05..ea92923 100644 --- a/src/api/authFactor.ts +++ b/src/api/authFactor.ts @@ -1,8 +1,4 @@ -import { - type AuthFactor, - getReadAuthFactorEndpoints, - urls, -} from "codeforlife/api" +import { type AuthFactor, urls } from "codeforlife/api" import { type CreateArg, type CreateResult, @@ -11,15 +7,28 @@ import { buildUrl, tagData, } from "codeforlife/utils/api" +import getReadAuthFactorEndpoints, { + AUTH_FACTOR_TAG, + type ListAuthFactorsArg, + type ListAuthFactorsResult, +} from "codeforlife/api/endpoints/authFactor" import api from "." +export type { ListAuthFactorsArg, ListAuthFactorsResult } + +export type CreateAuthFactorResult = CreateResult +export type CreateAuthFactorArg = CreateArg + +export type DestroyAuthFactorResult = DestroyResult +export type DestroyAuthFactorArg = DestroyArg + const authFactorApi = api.injectEndpoints({ endpoints: build => ({ ...getReadAuthFactorEndpoints(build), createAuthFactor: build.mutation< - CreateResult, - CreateArg + CreateAuthFactorResult, + CreateAuthFactorArg >({ query: body => ({ url: urls.authFactor.list, @@ -27,12 +36,15 @@ const authFactorApi = api.injectEndpoints({ body, }), }), - destroyAuthFactor: build.mutation>({ + destroyAuthFactor: build.mutation< + DestroyAuthFactorResult, + DestroyAuthFactorArg + >({ query: id => ({ url: buildUrl(urls.authFactor.detail, { url: { id } }), method: "DELETE", }), - invalidatesTags: tagData("AuthFactor"), + invalidatesTags: tagData(AUTH_FACTOR_TAG), }), }), }) diff --git a/src/api/klass.ts b/src/api/klass.ts index 34b95aa..7242435 100644 --- a/src/api/klass.ts +++ b/src/api/klass.ts @@ -1,4 +1,4 @@ -import { type Class, getReadClassEndpoints, urls } from "codeforlife/api" +import { type Class, urls } from "codeforlife/api" import { type CreateArg, type CreateResult, @@ -9,47 +9,64 @@ import { buildUrl, tagData, } from "codeforlife/utils/api" +import getReadClassEndpoints, { + CLASS_TAG, + type ListClassesArg, + type ListClassesResult, + type RetrieveClassArg, + type RetrieveClassResult, +} from "codeforlife/api/endpoints/klass" import api from "." +export type { + RetrieveClassArg, + RetrieveClassResult, + ListClassesArg, + ListClassesResult, +} + +export type CreateClassResult = CreateResult +export type CreateClassArg = CreateArg< + Class, + "name" | "read_classmates_data", + "teacher" | "receive_requests_until" +> + +export type DestroyClassResult = DestroyResult +export type DestroyClassArg = DestroyArg + +export type UpdateClassResult = UpdateResult +export type UpdateClassArg = UpdateArg< + Class, + never, + "name" | "read_classmates_data" | "receive_requests_until" | "teacher" +> + const classApi = api.injectEndpoints({ endpoints: build => ({ ...getReadClassEndpoints(build), - createClass: build.mutation< - CreateResult, - CreateArg< - Class, - "name" | "read_classmates_data", - "teacher" | "receive_requests_until" - > - >({ + createClass: build.mutation({ query: body => ({ url: urls.class.list, method: "POST", body, }), }), - destroyClass: build.mutation>({ + destroyClass: build.mutation({ query: id => ({ url: buildUrl(urls.class.detail, { url: { id } }), method: "DELETE", }), - invalidatesTags: tagData("Class"), + invalidatesTags: tagData(CLASS_TAG), }), - updateClass: build.mutation< - UpdateResult, - UpdateArg< - Class, - never, - "name" | "read_classmates_data" | "receive_requests_until" | "teacher" - > - >({ + updateClass: build.mutation({ query: ([id, body]) => ({ url: buildUrl(urls.class.detail, { url: { id } }), method: "PATCH", body, }), - invalidatesTags: tagData("Class"), + invalidatesTags: tagData(CLASS_TAG), }), }), }) diff --git a/src/api/otpBypassToken.ts b/src/api/otpBypassToken.ts index aace65e..b6a9b28 100644 --- a/src/api/otpBypassToken.ts +++ b/src/api/otpBypassToken.ts @@ -2,9 +2,15 @@ import { urls } from "codeforlife/api" import api from "." +export type GenerateOtpBypassTokensResult = string[] +export type GenerateOtpBypassTokensArg = null + const otpBypassTokenApi = api.injectEndpoints({ endpoints: build => ({ - generateOtpBypassTokens: build.mutation({ + generateOtpBypassTokens: build.mutation< + GenerateOtpBypassTokensResult, + GenerateOtpBypassTokensArg + >({ query: () => ({ url: urls.otpBypassToken.list, method: "POST", diff --git a/src/api/school.ts b/src/api/school.ts index 809df17..a96bc69 100644 --- a/src/api/school.ts +++ b/src/api/school.ts @@ -6,33 +6,44 @@ import { buildUrl, tagData, } from "codeforlife/utils/api" -import { type School, getReadSchoolEndpoints, urls } from "codeforlife/api" +import { type School, urls } from "codeforlife/api" +import getReadSchoolEndpoints, { + type RetrieveSchoolArg, + type RetrieveSchoolResult, + SCHOOL_TAG, +} from "codeforlife/api/endpoints/school" import api from "." +export type { RetrieveSchoolArg, RetrieveSchoolResult } + +export type CreateSchoolResult = CreateResult +export type CreateSchoolArg = CreateArg + +export type UpdateSchoolResult = UpdateResult +export type UpdateSchoolArg = UpdateArg< + School, + never, + "name" | "country" | "uk_county" +> + const schoolApi = api.injectEndpoints({ endpoints: build => ({ ...getReadSchoolEndpoints(build), - createSchool: build.mutation< - CreateResult, - CreateArg - >({ + createSchool: build.mutation({ query: body => ({ url: urls.school.list, method: "POST", body, }), }), - updateSchool: build.mutation< - UpdateResult, - UpdateArg - >({ + updateSchool: build.mutation({ query: ([id, body]) => ({ url: buildUrl(urls.school.detail, { url: { id } }), method: "PATCH", body, }), - invalidatesTags: tagData("School"), + invalidatesTags: tagData(SCHOOL_TAG), }), }), }) diff --git a/src/api/schoolTeacherInvitation.ts b/src/api/schoolTeacherInvitation.ts index 0dc87ce..eeb943f 100644 --- a/src/api/schoolTeacherInvitation.ts +++ b/src/api/schoolTeacherInvitation.ts @@ -29,22 +29,71 @@ export type SchoolTeacherInvitation = Model< } > +export type AcceptSchoolTeacherInvitationResult = null +export type AcceptSchoolTeacherInvitationArg = [ + SchoolTeacherInvitation["id"], + { + user?: Arg & { + add_to_newsletter: boolean + } + }, +] + +export type RejectSchoolTeacherInvitationResult = null +export type RejectSchoolTeacherInvitationArg = SchoolTeacherInvitation["id"] + +export type RefreshSchoolTeacherInvitationResult = UpdateResult< + SchoolTeacherInvitation, + "expires_at" +> +export type RefreshSchoolTeacherInvitationArg = + UpdateArg + +export type CreateSchoolTeacherInvitationResult = CreateResult< + SchoolTeacherInvitation, + "expires_at" +> +export type CreateSchoolTeacherInvitationArg = CreateArg< + SchoolTeacherInvitation, + | "invited_teacher_email" + | "invited_teacher_first_name" + | "invited_teacher_last_name" + | "invited_teacher_is_admin" +> + +export type DestroySchoolTeacherInvitationResult = DestroyResult +export type DestroySchoolTeacherInvitationArg = + DestroyArg + +export type RetrieveSchoolTeacherInvitationResult = RetrieveResult< + SchoolTeacherInvitation, + | "expires_at" + | "invited_teacher_email" + | "invited_teacher_first_name" + | "invited_teacher_last_name" + | "invited_teacher_is_admin" +> +export type RetrieveSchoolTeacherInvitationArg = + RetrieveArg + +export type ListSchoolTeacherInvitationsResult = ListResult< + SchoolTeacherInvitation, + | "expires_at" + | "invited_teacher_email" + | "invited_teacher_first_name" + | "invited_teacher_last_name" + | "invited_teacher_is_admin" +> +export type ListSchoolTeacherInvitationsArg = ListArg + const listUrl = "schools/teacher-invitations/" const detailUrl = listUrl + "/" const schoolTeacherInvitationApi = api.injectEndpoints({ endpoints: build => ({ acceptSchoolTeacherInvitation: build.mutation< - null, - [ - SchoolTeacherInvitation["id"], - { - user?: Arg< - User, - "first_name" | "last_name" | "password" | "email" - > & { add_to_newsletter: boolean } - }, - ] + AcceptSchoolTeacherInvitationResult, + AcceptSchoolTeacherInvitationArg >({ query: ([id, body]) => ({ url: buildUrl(detailUrl + "accept/", { url: { id } }), @@ -54,8 +103,8 @@ const schoolTeacherInvitationApi = api.injectEndpoints({ invalidatesTags: tagData("SchoolTeacherInvitation"), }), rejectSchoolTeacherInvitation: build.mutation< - null, - SchoolTeacherInvitation["id"] + RejectSchoolTeacherInvitationResult, + RejectSchoolTeacherInvitationArg >({ query: id => ({ url: buildUrl(detailUrl + "reject/", { url: { id } }), @@ -64,8 +113,8 @@ const schoolTeacherInvitationApi = api.injectEndpoints({ invalidatesTags: tagData("SchoolTeacherInvitation"), }), refreshSchoolTeacherInvitation: build.mutation< - UpdateResult, - UpdateArg + RefreshSchoolTeacherInvitationResult, + RefreshSchoolTeacherInvitationArg >({ query: id => ({ url: buildUrl(detailUrl, { url: { id } }), @@ -74,14 +123,8 @@ const schoolTeacherInvitationApi = api.injectEndpoints({ invalidatesTags: tagData("SchoolTeacherInvitation"), }), createSchoolTeacherInvitation: build.mutation< - CreateResult, - CreateArg< - SchoolTeacherInvitation, - | "invited_teacher_email" - | "invited_teacher_first_name" - | "invited_teacher_last_name" - | "invited_teacher_is_admin" - > + CreateSchoolTeacherInvitationResult, + CreateSchoolTeacherInvitationArg >({ query: body => ({ url: listUrl, @@ -90,8 +133,8 @@ const schoolTeacherInvitationApi = api.injectEndpoints({ }), }), destroySchoolTeacherInvitation: build.mutation< - DestroyResult, - DestroyArg + DestroySchoolTeacherInvitationResult, + DestroySchoolTeacherInvitationArg >({ query: id => ({ url: buildUrl(detailUrl, { url: { id } }), @@ -100,15 +143,8 @@ const schoolTeacherInvitationApi = api.injectEndpoints({ invalidatesTags: tagData("SchoolTeacherInvitation"), }), retrieveSchoolTeacherInvitation: build.query< - RetrieveResult< - SchoolTeacherInvitation, - | "expires_at" - | "invited_teacher_email" - | "invited_teacher_first_name" - | "invited_teacher_last_name" - | "invited_teacher_is_admin" - >, - RetrieveArg + RetrieveSchoolTeacherInvitationResult, + RetrieveSchoolTeacherInvitationArg >({ query: id => ({ url: buildUrl(detailUrl, { url: { id } }), @@ -117,15 +153,8 @@ const schoolTeacherInvitationApi = api.injectEndpoints({ providesTags: tagData("SchoolTeacherInvitation"), }), listSchoolTeacherInvitations: build.query< - ListResult< - SchoolTeacherInvitation, - | "expires_at" - | "invited_teacher_email" - | "invited_teacher_first_name" - | "invited_teacher_last_name" - | "invited_teacher_is_admin" - >, - ListArg + ListSchoolTeacherInvitationsResult, + ListSchoolTeacherInvitationsArg >({ query: search => ({ url: buildUrl(listUrl, { search }), diff --git a/src/api/sso.ts b/src/api/sso.ts index 6dd5b28..510a398 100644 --- a/src/api/sso.ts +++ b/src/api/sso.ts @@ -13,19 +13,36 @@ import api from "." const baseUrl = "sso/session/" +export type LoginWithEmailResult = SessionMetadata +export type LoginWithEmailArg = Arg + +export type LoginWithOtpResult = null +export type LoginWithOtpArg = { otp: string } + +export type LoginWithOtpBypassTokenResult = SessionMetadata +export type LoginWithOtpBypassTokenArg = Arg + +export type LoginAsStudentResult = SessionMetadata +export type LoginAsStudentArg = Arg & { + class_id: Class["id"] +} + +export type AutoLoginAsStudentResult = SessionMetadata +export type AutoLoginAsStudentArg = { + student_id: Student["id"] + auto_gen_password: string +} + const ssoApi = api.injectEndpoints({ endpoints: build => ({ - loginWithEmail: build.mutation< - SessionMetadata, - Arg - >({ + loginWithEmail: build.mutation({ query: body => ({ url: baseUrl + "login-with-email/", method: "POST", body, }), }), - loginWithOtp: build.mutation({ + loginWithOtp: build.mutation({ query: body => ({ url: baseUrl + "login-with-otp/", method: "POST", @@ -33,8 +50,8 @@ const ssoApi = api.injectEndpoints({ }), }), loginWithOtpBypassToken: build.mutation< - SessionMetadata, - Arg + LoginWithOtpBypassTokenResult, + LoginWithOtpBypassTokenArg >({ query: body => ({ url: baseUrl + "login-with-otp-bypass-token/", @@ -42,10 +59,7 @@ const ssoApi = api.injectEndpoints({ body, }), }), - loginAsStudent: build.mutation< - SessionMetadata, - Arg & { class_id: Class["id"] } - >({ + loginAsStudent: build.mutation({ query: body => ({ url: baseUrl + "login-as-student/", method: "POST", @@ -53,11 +67,8 @@ const ssoApi = api.injectEndpoints({ }), }), autoLoginAsStudent: build.mutation< - SessionMetadata, - { - student_id: Student["id"] - auto_gen_password: string - } + AutoLoginAsStudentResult, + AutoLoginAsStudentArg >({ query: body => ({ url: baseUrl + "auto-login-as-student/", diff --git a/src/api/student.ts b/src/api/student.ts index 84f1fc8..1a7f793 100644 --- a/src/api/student.ts +++ b/src/api/student.ts @@ -12,36 +12,59 @@ import { type Student, type User, urls } from "codeforlife/api" import api from "." +export type CreateStudentsResult = BulkCreateResult +export type CreateStudentsArg = BulkCreateArg< + Student, + "klass", + never, + { + user: Arg + } +> + +export type ReleaseStudentsResult = BulkUpdateResult +export type ReleaseStudentsArg = BulkUpdateArg< + Student, + never, + never, + { + user: Arg + } +> + +export type TransferStudentsResult = BulkUpdateResult +export type TransferStudentsArg = BulkUpdateArg< + Student, + "klass", + never, + { + user: Arg + } +> + +export type ResetStudentsPasswordResult = BulkUpdateResult +export type ResetStudentsPasswordArg = BulkUpdateArg< + Student, + never, + never, + { + user: Arg + } +> + +export type DestroyStudentsResult = BulkDestroyResult +export type DestroyStudentsArg = BulkDestroyArg + const studentApi = api.injectEndpoints({ endpoints: build => ({ - createStudents: build.mutation< - BulkCreateResult, - BulkCreateArg< - Student, - "klass", - never, - { - user: Arg - } - > - >({ + createStudents: build.mutation({ query: body => ({ url: urls.student.list + "bulk/", method: "POST", body, }), }), - releaseStudents: build.mutation< - BulkUpdateResult, - BulkUpdateArg< - Student, - never, - never, - { - user: Arg - } - > - >({ + releaseStudents: build.mutation({ query: body => ({ url: urls.student.list + "release/", method: "PUT", @@ -50,15 +73,8 @@ const studentApi = api.injectEndpoints({ invalidatesTags: tagData("User", "user"), }), transferStudents: build.mutation< - BulkUpdateResult, - BulkUpdateArg< - Student, - "klass", - never, - { - user: Arg - } - > + TransferStudentsResult, + TransferStudentsArg >({ query: body => ({ url: urls.student.list + "transfer/", @@ -68,15 +84,8 @@ const studentApi = api.injectEndpoints({ invalidatesTags: tagData("User", "user"), }), resetStudentsPassword: build.mutation< - BulkUpdateResult, - BulkUpdateArg< - Student, - never, - never, - { - user: Arg - } - > + ResetStudentsPasswordResult, + ResetStudentsPasswordArg >({ query: body => ({ url: urls.student.list + "reset-password/", @@ -84,16 +93,14 @@ const studentApi = api.injectEndpoints({ body, }), }), - destroyStudents: build.mutation>( - { - query: body => ({ - url: urls.student.list + "bulk/", - method: "DELETE", - body, - }), - invalidatesTags: tagData("User", "user"), - }, - ), + destroyStudents: build.mutation({ + query: body => ({ + url: urls.student.list + "bulk/", + method: "DELETE", + body, + }), + invalidatesTags: tagData("User", "user"), + }), }), }) diff --git a/src/api/teacher.ts b/src/api/teacher.ts index 313ea2f..29afcee 100644 --- a/src/api/teacher.ts +++ b/src/api/teacher.ts @@ -12,16 +12,25 @@ import { type Teacher, type User, urls } from "codeforlife/api" import api from "." +export type CreateTeacherResult = CreateResult +export type CreateTeacherArg = { + user: Arg & { + add_to_newsletter: boolean + } +} + +export type RemoveTeacherFromSchoolResult = UpdateResult +export type RemoveTeacherFromSchoolArg = UpdateArg + +export type SetTeacherAdminAccessResult = UpdateResult +export type SetTeacherAdminAccessArg = UpdateArg + +export type DestroyTeacherResult = DestroyResult +export type DestroyTeacherArg = DestroyArg + const teacherApi = api.injectEndpoints({ endpoints: build => ({ - createTeacher: build.mutation< - CreateResult, - { - user: Arg & { - add_to_newsletter: boolean - } - } - >({ + createTeacher: build.mutation({ query: body => ({ url: urls.teacher.list, method: "POST", @@ -29,8 +38,8 @@ const teacherApi = api.injectEndpoints({ }), }), removeTeacherFromSchool: build.mutation< - UpdateResult, - UpdateArg + RemoveTeacherFromSchoolResult, + RemoveTeacherFromSchoolArg >({ query: id => ({ url: buildUrl(urls.teacher.detail, { url: { id } }), @@ -39,8 +48,8 @@ const teacherApi = api.injectEndpoints({ invalidatesTags: tagData("User", "user"), }), setTeacherAdminAccess: build.mutation< - UpdateResult, - UpdateArg + SetTeacherAdminAccessResult, + SetTeacherAdminAccessArg >({ query: ([id, body]) => ({ url: buildUrl(urls.teacher.detail, { url: { id } }), @@ -49,7 +58,7 @@ const teacherApi = api.injectEndpoints({ }), invalidatesTags: tagData("User", "user"), }), - destroyTeacher: build.mutation>({ + destroyTeacher: build.mutation({ query: id => ({ url: buildUrl(urls.teacher.detail, { url: { id } }), method: "DELETE", diff --git a/src/api/user.ts b/src/api/user.ts index 5f35757..10bc7ff 100644 --- a/src/api/user.ts +++ b/src/api/user.ts @@ -9,16 +9,81 @@ import { buildUrl, tagData, } from "codeforlife/utils/api" -import { type User, getReadUserEndpoints, urls } from "codeforlife/api" +import { type User, urls } from "codeforlife/api" +import getReadUserEndpoints, { + type ListUsersArg, + type ListUsersResult, + type RetrieveUserArg, + type RetrieveUserResult, + USER_TAG, +} from "codeforlife/api/endpoints/user" import api from "." +export type { + RetrieveUserArg, + RetrieveUserResult, + ListUsersArg, + ListUsersResult, +} + +export type HandleJoinClassRequestResult = UpdateResult +export type HandleJoinClassRequestArg = UpdateArg< + User, + never, + "first_name", + { accept: boolean } +> + +export type RequestPasswordResetResult = null +export type RequestPasswordResetArg = Arg + +export type ResetPasswordResult = UpdateResult +export type ResetPasswordArg = UpdateArg< + User, + "password", + never, + { token: string } +> + +export type VerifyEmailAddressResult = UpdateResult +export type VerifyEmailAddressArg = UpdateArg< + User, + never, + never, + { token: string } +> + +export type UpdateUserResult = UpdateResult +export type UpdateUserArg = UpdateArg< + User, + never, + | "first_name" + | "last_name" + | "email" + | "requesting_to_join_class" + | "password", + { current_password?: string } +> + +export type DestroyIndependentUserResult = DestroyResult +export type DestroyIndependentUserArg = DestroyArg + +export type CreateIndependentUserResult = CreateResult +export type CreateIndependentUserArg = CreateArg< + User, + "first_name" | "last_name" | "email" | "password" +> & { + date_of_birth: string + add_to_newsletter: boolean +} + const userApi = api.injectEndpoints({ endpoints: build => ({ ...getReadUserEndpoints(build), handleJoinClassRequest: build.mutation< - UpdateResult, - UpdateArg + HandleJoinClassRequestResult, + HandleJoinClassRequestArg >({ query: ([id, body]) => ({ url: buildUrl(urls.user.detail + "handle-join-class-request/", { @@ -27,19 +92,19 @@ const userApi = api.injectEndpoints({ method: "PUT", body, }), - invalidatesTags: tagData("User"), + invalidatesTags: tagData(USER_TAG), }), - requestPasswordReset: build.query>({ + requestPasswordReset: build.query< + RequestPasswordResetResult, + RequestPasswordResetArg + >({ query: body => ({ url: urls.user.list + "request-password-reset/", method: "POST", body, }), }), - resetPassword: build.mutation< - UpdateResult, - UpdateArg - >({ + resetPassword: build.mutation({ query: ([id, body]) => ({ url: buildUrl(urls.user.detail + "reset-password/", { url: { id } }), method: "PUT", @@ -47,8 +112,8 @@ const userApi = api.injectEndpoints({ }), }), verifyEmailAddress: build.mutation< - UpdateResult, - UpdateArg + VerifyEmailAddressResult, + VerifyEmailAddressArg >({ query: ([id, body]) => ({ url: buildUrl(urls.user.detail + "verify-email-address/", { @@ -58,39 +123,27 @@ const userApi = api.injectEndpoints({ body, }), }), - updateUser: build.mutation< - UpdateResult, - UpdateArg< - User, - never, - | "first_name" - | "last_name" - | "email" - | "requesting_to_join_class" - | "password", - { current_password?: string } - > - >({ + updateUser: build.mutation({ query: ([id, body]) => ({ url: buildUrl(urls.user.detail, { url: { id } }), method: "PATCH", body, }), - invalidatesTags: tagData("User"), + invalidatesTags: tagData(USER_TAG), }), - destroyIndependentUser: build.mutation>({ + destroyIndependentUser: build.mutation< + DestroyIndependentUserResult, + DestroyIndependentUserArg + >({ query: id => ({ url: buildUrl(urls.user.detail, { url: { id } }), method: "DELETE", }), - invalidatesTags: tagData("User"), + invalidatesTags: tagData(USER_TAG), }), createIndependentUser: build.mutation< - CreateResult, - CreateArg & { - date_of_birth: string - add_to_newsletter: boolean - } + CreateIndependentUserResult, + CreateIndependentUserArg >({ query: body => ({ url: urls.user.list, diff --git a/yarn.lock b/yarn.lock index 0c68a38..bd87343 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2650,9 +2650,9 @@ clsx@^2.1.0, clsx@^2.1.1: resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== -"codeforlife@github:ocadotechnology/codeforlife-package-javascript#v2.1.3": - version "2.1.3" - resolved "https://codeload.github.com/ocadotechnology/codeforlife-package-javascript/tar.gz/f4b88435300bc17a6f4f7555f537150a20d7e779" +"codeforlife@github:ocadotechnology/codeforlife-package-javascript#v2.1.4": + version "2.1.4" + resolved "https://codeload.github.com/ocadotechnology/codeforlife-package-javascript/tar.gz/c7b9913d5caab1381885b019f9c3470d8269e589" dependencies: "@emotion/react" "^11.10.6" "@emotion/styled" "^11.10.6"