codeforlife 2.6.13 → 2.6.15

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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [2.6.15](https://github.com/ocadotechnology/codeforlife-package-javascript/compare/v2.6.14...v2.6.15) (2025-04-24)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Upgrade to Node 22 ([#84](https://github.com/ocadotechnology/codeforlife-package-javascript/issues/84)) ([78de472](https://github.com/ocadotechnology/codeforlife-package-javascript/commit/78de472ae5632df0410536f6593f9cde9beded82))
7
+
8
+ ## [2.6.14](https://github.com/ocadotechnology/codeforlife-package-javascript/compare/v2.6.13...v2.6.14) (2025-03-25)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * schemas for user and teacher derivatives ([b068235](https://github.com/ocadotechnology/codeforlife-package-javascript/commit/b0682358a07d2452d526d3bdad9c991302a2203d))
14
+
1
15
  ## [2.6.13](https://github.com/ocadotechnology/codeforlife-package-javascript/compare/v2.6.12...v2.6.13) (2025-03-25)
2
16
 
3
17
 
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "codeforlife",
3
3
  "description": "Common frontend code",
4
4
  "private": false,
5
- "version": "2.6.13",
5
+ "version": "2.6.15",
6
6
  "type": "module",
7
7
  "scripts": {
8
8
  "cli": "VITE_CONFIG=./vite.config.ts ../scripts/frontend/cli $@"
@@ -45,7 +45,7 @@
45
45
  "@testing-library/user-event": "^14.5.2",
46
46
  "@types/express": "^5.0.0",
47
47
  "@types/js-cookie": "^3.0.3",
48
- "@types/node": "^20.14.2",
48
+ "@types/node": "^22.14.1",
49
49
  "@types/qs": "^6.9.7",
50
50
  "@types/react": "^18.2.47",
51
51
  "@types/react-dom": "^18.2.18",
package/src/api/models.ts CHANGED
@@ -91,6 +91,7 @@ export type NonAdminSchoolTeacher<Fields = Teacher> = SchoolTeacher<Fields> & {
91
91
 
92
92
  export type NonSchoolTeacher<Fields = Teacher> = Fields & {
93
93
  school?: undefined
94
+ is_admin: false
94
95
  }
95
96
 
96
97
  // -----------------------------------------------------------------------------
@@ -3,12 +3,23 @@ import * as yup from "yup"
3
3
  import { UK_COUNTIES, COUNTRY_ISO_CODES } from "../utils/general"
4
4
  import type {
5
5
  User,
6
+ TeacherUser,
7
+ SchoolTeacherUser,
8
+ AdminSchoolTeacherUser,
9
+ NonAdminSchoolTeacherUser,
10
+ NonSchoolTeacherUser,
6
11
  Teacher,
7
12
  Student,
8
13
  Class,
9
14
  School,
10
15
  AuthFactor,
11
16
  OtpBypassToken,
17
+ StudentUser,
18
+ IndependentUser,
19
+ SchoolTeacher,
20
+ AdminSchoolTeacher,
21
+ NonAdminSchoolTeacher,
22
+ NonSchoolTeacher,
12
23
  } from "./models"
13
24
  import {
14
25
  unicodeAlphanumericString,
@@ -29,6 +40,10 @@ const id = {
29
40
  otpBypassToken: numericId(),
30
41
  }
31
42
 
43
+ // -----------------------------------------------------------------------------
44
+ // User Schemas
45
+ // -----------------------------------------------------------------------------
46
+
32
47
  const _userTeacher: Omit<Schemas<Teacher>, "user"> = {
33
48
  id: id.teacher.required(),
34
49
  school: id.school,
@@ -65,11 +80,122 @@ export const user: Schemas<User> = {
65
80
  student: yup.object(_userStudent).optional(),
66
81
  }
67
82
 
83
+ export const teacherUser: Schemas<TeacherUser> = {
84
+ ...user,
85
+ password: user.password
86
+ .min(10, "must be at least 10 characters long")
87
+ .matches(/[A-Z]/, "must contain at least one uppercase letter")
88
+ .matches(/[a-z]/, "must contain at least one lowercase letter")
89
+ .matches(/[0-9]/, "must contain at least one digit")
90
+ .matches(
91
+ /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/,
92
+ "must contain at least one special character",
93
+ ),
94
+ email: user.email.required(),
95
+ last_name: user.last_name.required(),
96
+ teacher: user.teacher.required(),
97
+ student: yup.string().oneOf([undefined]),
98
+ }
99
+
100
+ const _userSchoolTeacher: Omit<Schemas<SchoolTeacher>, "user"> = {
101
+ ..._userTeacher,
102
+ school: _userTeacher.school.required(),
103
+ }
104
+
105
+ export const schoolTeacherUser: Schemas<SchoolTeacherUser> = {
106
+ ...teacherUser,
107
+ teacher: yup.object(_userSchoolTeacher),
108
+ }
109
+
110
+ const _userAdminSchoolTeacher: Omit<Schemas<AdminSchoolTeacher>, "user"> = {
111
+ ..._userSchoolTeacher,
112
+ is_admin: _userSchoolTeacher.is_admin.isTrue(),
113
+ }
114
+
115
+ export const adminSchoolTeacherUser: Schemas<AdminSchoolTeacherUser> = {
116
+ ...schoolTeacherUser,
117
+ teacher: yup.object(_userAdminSchoolTeacher),
118
+ }
119
+
120
+ const _userNonAdminSchoolTeacher: Omit<
121
+ Schemas<NonAdminSchoolTeacher>,
122
+ "user"
123
+ > = {
124
+ ..._userSchoolTeacher,
125
+ is_admin: _userSchoolTeacher.is_admin.isFalse(),
126
+ }
127
+
128
+ export const nonAdminSchoolTeacherUser: Schemas<NonAdminSchoolTeacherUser> = {
129
+ ...schoolTeacherUser,
130
+ teacher: yup.object(_userNonAdminSchoolTeacher),
131
+ }
132
+
133
+ const _userNonSchoolTeacher: Omit<Schemas<NonSchoolTeacher>, "user"> = {
134
+ ..._userTeacher,
135
+ school: yup.string().oneOf([undefined]),
136
+ is_admin: _userTeacher.is_admin.isFalse(),
137
+ }
138
+
139
+ export const nonSchoolTeacherUser: Schemas<NonSchoolTeacherUser> = {
140
+ ...teacherUser,
141
+ teacher: yup.object(_userNonSchoolTeacher),
142
+ }
143
+
144
+ export const studentUser: Schemas<StudentUser> = {
145
+ ...user,
146
+ password: user.password.min(6, "must be at least 6 characters long"),
147
+ email: user.email.oneOf([undefined]),
148
+ last_name: user.last_name.oneOf([undefined]),
149
+ teacher: yup.string().oneOf([undefined]),
150
+ student: user.student.required(),
151
+ }
152
+
153
+ export const indyUser: Schemas<IndependentUser> = {
154
+ ...user,
155
+ password: user.password
156
+ .min(8, "must be at least 8 characters long")
157
+ .matches(/[A-Z]/, "must contain at least one uppercase letter")
158
+ .matches(/[a-z]/, "must contain at least one lowercase letter")
159
+ .matches(/[0-9]/, "must contain at least one digit"),
160
+ email: user.email.required(),
161
+ last_name: user.last_name.required(),
162
+ teacher: yup.string().oneOf([undefined]),
163
+ student: yup.string().oneOf([undefined]),
164
+ }
165
+
166
+ // -----------------------------------------------------------------------------
167
+ // Teacher Schemas
168
+ // -----------------------------------------------------------------------------
169
+
68
170
  export const teacher: Schemas<Teacher> = {
69
171
  ..._userTeacher,
70
172
  user: id.user.required(),
71
173
  }
72
174
 
175
+ export const schoolTeacher: Schemas<SchoolTeacher> = {
176
+ ..._userSchoolTeacher,
177
+ user: id.user.required(),
178
+ }
179
+
180
+ export const adminSchoolTeacher: Schemas<AdminSchoolTeacher> = {
181
+ ..._userAdminSchoolTeacher,
182
+ user: id.user.required(),
183
+ }
184
+
185
+ export const nonAdminSchoolTeacher: Schemas<NonAdminSchoolTeacher> = {
186
+ ..._userNonAdminSchoolTeacher,
187
+ user: id.user.required(),
188
+ }
189
+
190
+ export const nonSchoolTeacher: Schemas<NonSchoolTeacher> = {
191
+ ..._userNonSchoolTeacher,
192
+ user: id.user.required(),
193
+ }
194
+
195
+ // -----------------------------------------------------------------------------
196
+ // Other Schemas
197
+ // -----------------------------------------------------------------------------
198
+
73
199
  export const student: Schemas<Student> = {
74
200
  ..._userStudent,
75
201
  user: id.user.required(),