@teardown/schemas 0.1.21 → 0.1.23
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/package.json +49 -52
- package/src/common/primitives.ts +21 -0
- package/src/common/responses.ts +25 -0
- package/{dist/common/type-checks.d.ts → src/common/type-checks.ts} +23 -4
- package/{dist/index.js → src/index.ts} +1 -0
- package/src/modules/analytics/schemas.ts +178 -0
- package/src/modules/builds/schemas.ts +171 -0
- package/src/modules/devices/schemas.ts +196 -0
- package/src/modules/environment/schemas.ts +81 -0
- package/src/modules/events/index.ts +2 -0
- package/src/modules/events/schemas.ts +129 -0
- package/src/modules/identify/schemas.ts +257 -0
- package/src/modules/me/schemas.ts +87 -0
- package/src/modules/orgs/schemas.ts +260 -0
- package/src/modules/personas/schemas.ts +123 -0
- package/src/modules/projects/schemas.ts +179 -0
- package/src/modules/sessions/schemas.ts +158 -0
- package/src/modules/versions/schemas.ts +192 -0
- package/dist/common/index.js +0 -3
- package/dist/common/primitives.d.ts +0 -11
- package/dist/common/primitives.js +0 -8
- package/dist/common/responses.d.ts +0 -27
- package/dist/common/responses.js +0 -13
- package/dist/common/type-checks.js +0 -1
- package/dist/index.d.ts +0 -13
- package/dist/modules/analytics/schemas.d.ts +0 -239
- package/dist/modules/analytics/schemas.js +0 -136
- package/dist/modules/builds/schemas.d.ts +0 -248
- package/dist/modules/builds/schemas.js +0 -137
- package/dist/modules/devices/schemas.d.ts +0 -207
- package/dist/modules/devices/schemas.js +0 -165
- package/dist/modules/environment/schemas.d.ts +0 -56
- package/dist/modules/environment/schemas.js +0 -57
- package/dist/modules/events/schemas.d.ts +0 -138
- package/dist/modules/events/schemas.js +0 -116
- package/dist/modules/identify/index.js +0 -1
- package/dist/modules/identify/schemas.d.ts +0 -377
- package/dist/modules/identify/schemas.js +0 -221
- package/dist/modules/index.js +0 -12
- package/dist/modules/me/index.d.ts +0 -1
- package/dist/modules/me/index.js +0 -1
- package/dist/modules/me/schemas.d.ts +0 -75
- package/dist/modules/me/schemas.js +0 -76
- package/dist/modules/orgs/index.d.ts +0 -1
- package/dist/modules/orgs/index.js +0 -1
- package/dist/modules/orgs/schemas.d.ts +0 -308
- package/dist/modules/orgs/schemas.js +0 -214
- package/dist/modules/personas/index.d.ts +0 -1
- package/dist/modules/personas/index.js +0 -1
- package/dist/modules/personas/schemas.d.ts +0 -170
- package/dist/modules/personas/schemas.js +0 -100
- package/dist/modules/projects/index.d.ts +0 -1
- package/dist/modules/projects/index.js +0 -1
- package/dist/modules/projects/schemas.d.ts +0 -222
- package/dist/modules/projects/schemas.js +0 -145
- package/dist/modules/sessions/index.d.ts +0 -1
- package/dist/modules/sessions/index.js +0 -1
- package/dist/modules/sessions/schemas.d.ts +0 -258
- package/dist/modules/sessions/schemas.js +0 -128
- package/dist/modules/versions/index.d.ts +0 -1
- package/dist/modules/versions/index.js +0 -1
- package/dist/modules/versions/schemas.d.ts +0 -248
- package/dist/modules/versions/schemas.js +0 -155
- /package/{dist/common/index.d.ts → src/common/index.ts} +0 -0
- /package/{dist/modules/analytics/index.d.ts → src/modules/analytics/index.ts} +0 -0
- /package/{dist/modules/analytics/index.js → src/modules/builds/index.ts} +0 -0
- /package/{dist/modules/builds/index.d.ts → src/modules/devices/index.ts} +0 -0
- /package/{dist/modules/builds/index.js → src/modules/environment/index.ts} +0 -0
- /package/{dist/modules/devices/index.d.ts → src/modules/identify/index.ts} +0 -0
- /package/{dist/modules/index.d.ts → src/modules/index.ts} +0 -0
- /package/{dist/modules/devices/index.js → src/modules/me/index.ts} +0 -0
- /package/{dist/modules/environment/index.d.ts → src/modules/orgs/index.ts} +0 -0
- /package/{dist/modules/environment/index.js → src/modules/personas/index.ts} +0 -0
- /package/{dist/modules/events/index.d.ts → src/modules/projects/index.ts} +0 -0
- /package/{dist/modules/events/index.js → src/modules/sessions/index.ts} +0 -0
- /package/{dist/modules/identify/index.d.ts → src/modules/versions/index.ts} +0 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { type Static, Type } from "@sinclair/typebox";
|
|
2
|
+
import { OrgRoleWithOrgSchema } from "../orgs/schemas";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* User schema
|
|
6
|
+
* Represents Supabase Auth user structure
|
|
7
|
+
*/
|
|
8
|
+
export const UserSchema = Type.Object({
|
|
9
|
+
id: Type.String({ format: "uuid" }),
|
|
10
|
+
email: Type.Optional(Type.String({ format: "email" })),
|
|
11
|
+
app_metadata: Type.Record(Type.String(), Type.Unknown()),
|
|
12
|
+
user_metadata: Type.Record(Type.String(), Type.Unknown()),
|
|
13
|
+
created_at: Type.String(),
|
|
14
|
+
|
|
15
|
+
// id: string
|
|
16
|
+
// app_metadata: UserAppMetadata
|
|
17
|
+
// user_metadata: UserMetadata
|
|
18
|
+
// aud: string
|
|
19
|
+
// confirmation_sent_at?: string
|
|
20
|
+
// recovery_sent_at?: string
|
|
21
|
+
// email_change_sent_at?: string
|
|
22
|
+
// new_email?: string
|
|
23
|
+
// new_phone?: string
|
|
24
|
+
// invited_at?: string
|
|
25
|
+
// action_link?: string
|
|
26
|
+
// email?: string
|
|
27
|
+
// phone?: string
|
|
28
|
+
// created_at: string
|
|
29
|
+
// confirmed_at?: string
|
|
30
|
+
// email_confirmed_at?: string
|
|
31
|
+
// phone_confirmed_at?: string
|
|
32
|
+
// last_sign_in_at?: string
|
|
33
|
+
// role?: string
|
|
34
|
+
// updated_at?: string
|
|
35
|
+
// identities?: UserIdentity[]
|
|
36
|
+
// is_anonymous?: boolean
|
|
37
|
+
// is_sso_user?: boolean
|
|
38
|
+
// factors?: (Factor<FactorType, 'verified'> | Factor<FactorType, 'unverified'>)[]
|
|
39
|
+
// deleted_at?: string
|
|
40
|
+
});
|
|
41
|
+
export type User = Static<typeof UserSchema>;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Me response schema
|
|
45
|
+
*/
|
|
46
|
+
export const MeResponseSchema = Type.Object({
|
|
47
|
+
user: UserSchema,
|
|
48
|
+
});
|
|
49
|
+
export type MeResponse = Static<typeof MeResponseSchema>;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Me orgs response schema
|
|
53
|
+
* Reuses OrgRoleWithOrgSchema from orgs module
|
|
54
|
+
*/
|
|
55
|
+
export const MeOrgsResponseSchema = Type.Object({
|
|
56
|
+
orgs: Type.Array(OrgRoleWithOrgSchema),
|
|
57
|
+
});
|
|
58
|
+
export type MeOrgsResponse = Static<typeof MeOrgsResponseSchema>;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Me error response schema
|
|
62
|
+
* Discriminated union by error code
|
|
63
|
+
*/
|
|
64
|
+
export const MeErrorSchema = Type.Union([
|
|
65
|
+
Type.Object({
|
|
66
|
+
code: Type.Literal("UNAUTHORIZED"),
|
|
67
|
+
message: Type.String(),
|
|
68
|
+
}),
|
|
69
|
+
Type.Object({
|
|
70
|
+
code: Type.Literal("USER_NOT_FOUND"),
|
|
71
|
+
message: Type.String(),
|
|
72
|
+
}),
|
|
73
|
+
Type.Object({
|
|
74
|
+
code: Type.Literal("FETCH_FAILED"),
|
|
75
|
+
message: Type.String(),
|
|
76
|
+
}),
|
|
77
|
+
]);
|
|
78
|
+
export type MeError = Static<typeof MeErrorSchema>;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Me error response wrapper
|
|
82
|
+
*/
|
|
83
|
+
export const MeErrorResponseSchema = Type.Object({
|
|
84
|
+
success: Type.Literal(false),
|
|
85
|
+
error: MeErrorSchema,
|
|
86
|
+
});
|
|
87
|
+
export type MeErrorResponse = Static<typeof MeErrorResponseSchema>;
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { type Static, Type } from "@sinclair/typebox";
|
|
2
|
+
import { OrgRoleTypeEnum, OrgTypeEnum } from "@teardown/types";
|
|
3
|
+
import {
|
|
4
|
+
type AssertSchemaCompatibleWithInsert,
|
|
5
|
+
type AssertSchemaCompatibleWithRow,
|
|
6
|
+
type AssertSchemaCompatibleWithUpdate,
|
|
7
|
+
type AssertTrue,
|
|
8
|
+
SlugSchema,
|
|
9
|
+
} from "../../common";
|
|
10
|
+
|
|
11
|
+
export const OrgHeadersSchema = Type.Object({
|
|
12
|
+
"td-org-id": Type.String(),
|
|
13
|
+
});
|
|
14
|
+
export type OrgHeaders = Static<typeof OrgHeadersSchema>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Helper to check if role is admin or owner
|
|
18
|
+
*/
|
|
19
|
+
export function isAdminRole(role: string): boolean {
|
|
20
|
+
return role === OrgRoleTypeEnum.OWNER || role === OrgRoleTypeEnum.ADMIN;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Helper to check if role is owner
|
|
25
|
+
*/
|
|
26
|
+
export function isOwnerRole(role: string): boolean {
|
|
27
|
+
return role === OrgRoleTypeEnum.OWNER;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Parse and validate an OrgRoleTypeEnum value
|
|
32
|
+
* Uses a switch statement to ensure type safety and runtime validation
|
|
33
|
+
* @param value - The value to parse
|
|
34
|
+
* @returns The validated OrgRoleTypeEnum value
|
|
35
|
+
* @throws Error if the value is not a valid OrgRoleTypeEnum
|
|
36
|
+
*/
|
|
37
|
+
export function parseOrgRoleTypeEnum(value: unknown): OrgRoleTypeEnum {
|
|
38
|
+
switch (value) {
|
|
39
|
+
case OrgRoleTypeEnum.OWNER:
|
|
40
|
+
return OrgRoleTypeEnum.OWNER;
|
|
41
|
+
case OrgRoleTypeEnum.ADMIN:
|
|
42
|
+
return OrgRoleTypeEnum.ADMIN;
|
|
43
|
+
case OrgRoleTypeEnum.ENGINEER:
|
|
44
|
+
return OrgRoleTypeEnum.ENGINEER;
|
|
45
|
+
default:
|
|
46
|
+
throw new Error(
|
|
47
|
+
`Invalid OrgRoleTypeEnum value: ${value}. Expected one of: ${Object.values(OrgRoleTypeEnum).join(", ")}`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Parse and validate an OrgTypeEnum value
|
|
54
|
+
* Uses a switch statement to ensure type safety and runtime validation
|
|
55
|
+
* @param value - The value to parse
|
|
56
|
+
* @returns The validated OrgTypeEnum value
|
|
57
|
+
* @throws Error if the value is not a valid OrgTypeEnum
|
|
58
|
+
*/
|
|
59
|
+
export function parseOrgTypeEnum(value: unknown): OrgTypeEnum {
|
|
60
|
+
switch (value) {
|
|
61
|
+
case OrgTypeEnum.PERSONAL:
|
|
62
|
+
return OrgTypeEnum.PERSONAL;
|
|
63
|
+
case OrgTypeEnum.START_UP:
|
|
64
|
+
return OrgTypeEnum.START_UP;
|
|
65
|
+
case OrgTypeEnum.SCALE_UP:
|
|
66
|
+
return OrgTypeEnum.SCALE_UP;
|
|
67
|
+
case OrgTypeEnum.AGENCY:
|
|
68
|
+
return OrgTypeEnum.AGENCY;
|
|
69
|
+
case OrgTypeEnum.ENTERPRISE:
|
|
70
|
+
return OrgTypeEnum.ENTERPRISE;
|
|
71
|
+
default:
|
|
72
|
+
throw new Error(`Invalid OrgTypeEnum value: ${value}. Expected one of: ${Object.values(OrgTypeEnum).join(", ")}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export const OrgSlugOrIdParamsSchema = Type.Object({
|
|
77
|
+
org_id_or_slug: Type.String(),
|
|
78
|
+
});
|
|
79
|
+
export type OrgSlugOrIdParams = Static<typeof OrgSlugOrIdParamsSchema>;
|
|
80
|
+
|
|
81
|
+
export const OrgIdParamsSchema = Type.Object({
|
|
82
|
+
org_id: Type.String(),
|
|
83
|
+
});
|
|
84
|
+
export type OrgIdParams = Static<typeof OrgIdParamsSchema>;
|
|
85
|
+
|
|
86
|
+
export const OrgSlugParamsSchema = Type.Object({
|
|
87
|
+
// org_slug: SlugSchema,
|
|
88
|
+
});
|
|
89
|
+
export type OrgSlugParams = Static<typeof OrgSlugParamsSchema>;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Base org schema
|
|
93
|
+
* Represents organisation table structure
|
|
94
|
+
*/
|
|
95
|
+
export const OrgSchema = Type.Object({
|
|
96
|
+
id: Type.String({ format: "uuid" }),
|
|
97
|
+
name: Type.String({ minLength: 1 }),
|
|
98
|
+
slug: SlugSchema,
|
|
99
|
+
type: Type.Enum(OrgTypeEnum),
|
|
100
|
+
created_at: Type.String(),
|
|
101
|
+
updated_at: Type.String(),
|
|
102
|
+
});
|
|
103
|
+
export type Org = Static<typeof OrgSchema>;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Org role schema
|
|
107
|
+
* Represents organisation_role table structure
|
|
108
|
+
*/
|
|
109
|
+
export const OrgRoleSchema = Type.Object({
|
|
110
|
+
id: Type.String({ format: "uuid" }),
|
|
111
|
+
org_id: Type.String({ format: "uuid" }),
|
|
112
|
+
user_id: Type.String({ format: "uuid" }),
|
|
113
|
+
role: Type.Enum(OrgRoleTypeEnum),
|
|
114
|
+
created_at: Type.String(),
|
|
115
|
+
updated_at: Type.String(),
|
|
116
|
+
});
|
|
117
|
+
export type OrgRole = Static<typeof OrgRoleSchema>;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Extended org role with org name
|
|
121
|
+
* Used for user's org list
|
|
122
|
+
*/
|
|
123
|
+
export const OrgRoleWithOrgSchema = Type.Composite([
|
|
124
|
+
OrgRoleSchema,
|
|
125
|
+
Type.Object({
|
|
126
|
+
org_id: Type.String({ format: "uuid" }),
|
|
127
|
+
org_name: Type.String(),
|
|
128
|
+
org_slug: SlugSchema,
|
|
129
|
+
}),
|
|
130
|
+
]);
|
|
131
|
+
export type OrgRoleWithOrg = Static<typeof OrgRoleWithOrgSchema>;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Create org request schema
|
|
135
|
+
*/
|
|
136
|
+
export const CreateOrgSchema = Type.Object({
|
|
137
|
+
name: Type.String({ minLength: 1, maxLength: 255 }),
|
|
138
|
+
slug: SlugSchema,
|
|
139
|
+
type: Type.Enum(OrgTypeEnum),
|
|
140
|
+
});
|
|
141
|
+
export type CreateOrg = Static<typeof CreateOrgSchema>;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Update org request schema
|
|
145
|
+
*/
|
|
146
|
+
export const UpdateOrgSchema = Type.Object({
|
|
147
|
+
name: Type.Optional(Type.String({ minLength: 1, maxLength: 255 })),
|
|
148
|
+
});
|
|
149
|
+
export type UpdateOrg = Static<typeof UpdateOrgSchema>;
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Add org role request schema
|
|
153
|
+
*/
|
|
154
|
+
export const AddOrgRoleSchema = Type.Object({
|
|
155
|
+
org_id: Type.String({ format: "uuid" }),
|
|
156
|
+
user_id: Type.String({ format: "uuid" }),
|
|
157
|
+
role: Type.Enum(OrgRoleTypeEnum),
|
|
158
|
+
});
|
|
159
|
+
export type AddOrgRole = Static<typeof AddOrgRoleSchema>;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Single org response schema
|
|
163
|
+
*/
|
|
164
|
+
export const OrgResponseSchema = Type.Object({
|
|
165
|
+
success: Type.Literal(true),
|
|
166
|
+
data: Type.Object({
|
|
167
|
+
org: OrgRoleWithOrgSchema,
|
|
168
|
+
}),
|
|
169
|
+
});
|
|
170
|
+
export type OrgResponse = Static<typeof OrgResponseSchema>;
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Org error response schema
|
|
174
|
+
* Discriminated union by error code
|
|
175
|
+
*/
|
|
176
|
+
export const OrgErrorSchema = Type.Union([
|
|
177
|
+
Type.Object({
|
|
178
|
+
code: Type.Literal("UNKNOWN_ERROR"),
|
|
179
|
+
message: Type.String(),
|
|
180
|
+
}),
|
|
181
|
+
Type.Object({
|
|
182
|
+
code: Type.Literal("VALIDATION_ERROR"),
|
|
183
|
+
message: Type.String(),
|
|
184
|
+
}),
|
|
185
|
+
Type.Object({
|
|
186
|
+
code: Type.Literal("ORG_ID_MISMATCH"),
|
|
187
|
+
message: Type.String(),
|
|
188
|
+
}),
|
|
189
|
+
Type.Object({
|
|
190
|
+
code: Type.Literal("ORG_NOT_FOUND"),
|
|
191
|
+
message: Type.String(),
|
|
192
|
+
}),
|
|
193
|
+
Type.Object({
|
|
194
|
+
code: Type.Literal("ORG_ROLE_NOT_FOUND"),
|
|
195
|
+
message: Type.String(),
|
|
196
|
+
}),
|
|
197
|
+
Type.Object({
|
|
198
|
+
code: Type.Literal("USER_NOT_IN_ORG"),
|
|
199
|
+
message: Type.String(),
|
|
200
|
+
}),
|
|
201
|
+
Type.Object({
|
|
202
|
+
code: Type.Literal("FORBIDDEN"),
|
|
203
|
+
message: Type.String(),
|
|
204
|
+
}),
|
|
205
|
+
Type.Object({
|
|
206
|
+
code: Type.Literal("UNAUTHORIZED"),
|
|
207
|
+
message: Type.String(),
|
|
208
|
+
}),
|
|
209
|
+
Type.Object({
|
|
210
|
+
code: Type.Literal("INVALID_ROLE"),
|
|
211
|
+
message: Type.String(),
|
|
212
|
+
}),
|
|
213
|
+
Type.Object({
|
|
214
|
+
code: Type.Literal("ORG_ID_REQUIRED"),
|
|
215
|
+
message: Type.String(),
|
|
216
|
+
}),
|
|
217
|
+
Type.Object({
|
|
218
|
+
code: Type.Literal("SLUG_ALREADY_EXISTS"),
|
|
219
|
+
message: Type.String(),
|
|
220
|
+
}),
|
|
221
|
+
Type.Object({
|
|
222
|
+
code: Type.Literal("FETCH_FAILED"),
|
|
223
|
+
message: Type.String(),
|
|
224
|
+
}),
|
|
225
|
+
Type.Object({
|
|
226
|
+
code: Type.Literal("CREATE_FAILED"),
|
|
227
|
+
message: Type.String(),
|
|
228
|
+
}),
|
|
229
|
+
Type.Object({
|
|
230
|
+
code: Type.Literal("UPDATE_FAILED"),
|
|
231
|
+
message: Type.String(),
|
|
232
|
+
}),
|
|
233
|
+
Type.Object({
|
|
234
|
+
code: Type.Literal("DELETE_FAILED"),
|
|
235
|
+
message: Type.String(),
|
|
236
|
+
}),
|
|
237
|
+
Type.Object({
|
|
238
|
+
code: Type.Literal("ROLE_CREATION_FAILED"),
|
|
239
|
+
message: Type.String(),
|
|
240
|
+
}),
|
|
241
|
+
]);
|
|
242
|
+
export type OrgError = Static<typeof OrgErrorSchema>;
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Org error response wrapper
|
|
246
|
+
*/
|
|
247
|
+
export const OrgErrorResponseSchema = Type.Object({
|
|
248
|
+
success: Type.Literal(false),
|
|
249
|
+
error: OrgErrorSchema,
|
|
250
|
+
});
|
|
251
|
+
export type OrgErrorResponse = Static<typeof OrgErrorResponseSchema>;
|
|
252
|
+
|
|
253
|
+
export const OrgRequestResponseSchema = Type.Union([OrgResponseSchema, OrgErrorResponseSchema]);
|
|
254
|
+
export type OrgRequestResponse = Static<typeof OrgRequestResponseSchema>;
|
|
255
|
+
|
|
256
|
+
export type _CheckOrgRow = AssertTrue<AssertSchemaCompatibleWithRow<Org, "orgs">>;
|
|
257
|
+
export type _CheckCreateOrg = AssertTrue<AssertSchemaCompatibleWithInsert<CreateOrg, "orgs">>;
|
|
258
|
+
export type _CheckUpdateOrg = AssertTrue<AssertSchemaCompatibleWithUpdate<UpdateOrg, "orgs">>;
|
|
259
|
+
export type _CheckOrgRoleRow = AssertTrue<AssertSchemaCompatibleWithRow<OrgRole, "org_roles">>;
|
|
260
|
+
export type _CheckAddOrgRole = AssertTrue<AssertSchemaCompatibleWithInsert<AddOrgRole, "org_roles">>;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { type Static, Type } from "@sinclair/typebox";
|
|
2
|
+
import type { AssertSchemaCompatibleWithRow, AssertTrue } from "../../common";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Base persona schema
|
|
6
|
+
* Represents personas table structure
|
|
7
|
+
*/
|
|
8
|
+
export const PersonaSchema = Type.Object({
|
|
9
|
+
id: Type.String({ format: "uuid" }),
|
|
10
|
+
environment_id: Type.String({ format: "uuid" }),
|
|
11
|
+
user_id: Type.Union([Type.String(), Type.Null()]),
|
|
12
|
+
name: Type.Union([Type.String(), Type.Null()]),
|
|
13
|
+
email: Type.Union([Type.String({ format: "email" }), Type.Null()]),
|
|
14
|
+
created_at: Type.String(),
|
|
15
|
+
updated_at: Type.String(),
|
|
16
|
+
});
|
|
17
|
+
export type Persona = Static<typeof PersonaSchema>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Persona params schema
|
|
21
|
+
*/
|
|
22
|
+
export const PersonaParamsSchema = Type.Object({
|
|
23
|
+
persona_id: Type.String({ format: "uuid" }),
|
|
24
|
+
});
|
|
25
|
+
export type PersonaParams = Static<typeof PersonaParamsSchema>;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Search personas query schema
|
|
29
|
+
* Supports pagination, search, and sorting
|
|
30
|
+
*/
|
|
31
|
+
export const SearchPersonasQuerySchema = Type.Object({
|
|
32
|
+
project_id: Type.String({ format: "uuid" }),
|
|
33
|
+
page: Type.Number({ minimum: 1, default: 1 }),
|
|
34
|
+
limit: Type.Number({ minimum: 1, maximum: 100, default: 20 }),
|
|
35
|
+
search: Type.Optional(Type.String()),
|
|
36
|
+
sort_by: Type.Union([Type.Literal("created_at"), Type.Literal("updated_at"), Type.Literal("name"), Type.Literal("email")], {
|
|
37
|
+
default: "created_at",
|
|
38
|
+
}),
|
|
39
|
+
sort_order: Type.Union([Type.Literal("asc"), Type.Literal("desc")], { default: "desc" }),
|
|
40
|
+
});
|
|
41
|
+
export type SearchPersonasQuery = Static<typeof SearchPersonasQuerySchema>;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Search personas query schema without project_id (injected from headers)
|
|
45
|
+
*/
|
|
46
|
+
export const SearchPersonasQueryParamsSchema = Type.Omit(SearchPersonasQuerySchema, ["project_id"]);
|
|
47
|
+
export type SearchPersonasQueryParams = Static<typeof SearchPersonasQueryParamsSchema>;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Personas by IDs request schema
|
|
51
|
+
*/
|
|
52
|
+
export const PersonasByIdsSchema = Type.Object({
|
|
53
|
+
persona_ids: Type.Array(Type.String({ format: "uuid" }), { minItems: 1, maxItems: 100 }),
|
|
54
|
+
});
|
|
55
|
+
export type PersonasByIds = Static<typeof PersonasByIdsSchema>;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Paginated personas response schema
|
|
59
|
+
*/
|
|
60
|
+
export const PersonasResponseSchema = Type.Object({
|
|
61
|
+
personas: Type.Array(PersonaSchema),
|
|
62
|
+
pagination: Type.Object({
|
|
63
|
+
page: Type.Integer({ minimum: 1 }),
|
|
64
|
+
limit: Type.Integer({ minimum: 1 }),
|
|
65
|
+
total: Type.Integer({ minimum: 0 }),
|
|
66
|
+
total_pages: Type.Integer({ minimum: 0 }),
|
|
67
|
+
}),
|
|
68
|
+
});
|
|
69
|
+
export type PersonasResponse = Static<typeof PersonasResponseSchema>;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Single persona response schema
|
|
73
|
+
*/
|
|
74
|
+
export const PersonaResponseSchema = Type.Object({
|
|
75
|
+
success: Type.Literal(true),
|
|
76
|
+
data: PersonaSchema,
|
|
77
|
+
});
|
|
78
|
+
export type PersonaResponse = Static<typeof PersonaResponseSchema>;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Persona error response schema
|
|
82
|
+
* Discriminated union by error code
|
|
83
|
+
*/
|
|
84
|
+
export const PersonaErrorSchema = Type.Union([
|
|
85
|
+
Type.Object({
|
|
86
|
+
code: Type.Literal("PERSONA_NOT_FOUND"),
|
|
87
|
+
message: Type.String(),
|
|
88
|
+
}),
|
|
89
|
+
Type.Object({
|
|
90
|
+
code: Type.Literal("PROJECT_NOT_FOUND"),
|
|
91
|
+
message: Type.String(),
|
|
92
|
+
}),
|
|
93
|
+
Type.Object({
|
|
94
|
+
code: Type.Literal("FORBIDDEN"),
|
|
95
|
+
message: Type.String(),
|
|
96
|
+
}),
|
|
97
|
+
Type.Object({
|
|
98
|
+
code: Type.Literal("FETCH_FAILED"),
|
|
99
|
+
message: Type.String(),
|
|
100
|
+
}),
|
|
101
|
+
Type.Object({
|
|
102
|
+
code: Type.Literal("INVALID_PARAMS"),
|
|
103
|
+
message: Type.String(),
|
|
104
|
+
}),
|
|
105
|
+
]);
|
|
106
|
+
export type PersonaError = Static<typeof PersonaErrorSchema>;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Persona error response wrapper
|
|
110
|
+
*/
|
|
111
|
+
export const PersonaErrorResponseSchema = Type.Object({
|
|
112
|
+
success: Type.Literal(false),
|
|
113
|
+
error: PersonaErrorSchema,
|
|
114
|
+
});
|
|
115
|
+
export type PersonaErrorResponse = Static<typeof PersonaErrorResponseSchema>;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Persona request response schema
|
|
119
|
+
*/
|
|
120
|
+
export const PersonaRequestResponseSchema = Type.Union([PersonaResponseSchema, PersonaErrorResponseSchema]);
|
|
121
|
+
export type PersonaRequestResponse = Static<typeof PersonaRequestResponseSchema>;
|
|
122
|
+
|
|
123
|
+
export type _CheckPersonaRow = AssertTrue<AssertSchemaCompatibleWithRow<Persona, "personas">>;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { type Static, Type } from "@sinclair/typebox";
|
|
2
|
+
import { ProjectStatusEnum, ProjectTypeEnum } from "@teardown/types";
|
|
3
|
+
import {
|
|
4
|
+
type AssertSchemaCompatibleWithInsert,
|
|
5
|
+
type AssertSchemaCompatibleWithRow,
|
|
6
|
+
type AssertSchemaCompatibleWithUpdate,
|
|
7
|
+
type AssertTrue,
|
|
8
|
+
SlugSchema,
|
|
9
|
+
} from "../../common";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Parse and validate a ProjectTypeEnum value
|
|
13
|
+
* Uses a switch statement to ensure type safety and runtime validation
|
|
14
|
+
* @param value - The value to parse
|
|
15
|
+
* @returns The validated ProjectTypeEnum value
|
|
16
|
+
* @throws Error if the value is not a valid ProjectTypeEnum
|
|
17
|
+
*/
|
|
18
|
+
export function parseProjectTypeEnum(value: unknown): ProjectTypeEnum {
|
|
19
|
+
switch (value) {
|
|
20
|
+
case ProjectTypeEnum.REACT_NATIVE:
|
|
21
|
+
return ProjectTypeEnum.REACT_NATIVE;
|
|
22
|
+
case ProjectTypeEnum.EXPO:
|
|
23
|
+
return ProjectTypeEnum.EXPO;
|
|
24
|
+
default:
|
|
25
|
+
throw new Error(
|
|
26
|
+
`Invalid ProjectTypeEnum value: ${value}. Expected one of: ${Object.values(ProjectTypeEnum).join(", ")}`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Parse and validate a ProjectStatusEnum value
|
|
33
|
+
* Uses a switch statement to ensure type safety and runtime validation
|
|
34
|
+
* @param value - The value to parse
|
|
35
|
+
* @returns The validated ProjectStatusEnum value
|
|
36
|
+
* @throws Error if the value is not a valid ProjectStatusEnum
|
|
37
|
+
*/
|
|
38
|
+
export function parseProjectStatusEnum(value: unknown): ProjectStatusEnum {
|
|
39
|
+
switch (value) {
|
|
40
|
+
case ProjectStatusEnum.PENDING_SETUP:
|
|
41
|
+
return ProjectStatusEnum.PENDING_SETUP;
|
|
42
|
+
case ProjectStatusEnum.ACTIVE:
|
|
43
|
+
return ProjectStatusEnum.ACTIVE;
|
|
44
|
+
case ProjectStatusEnum.PAUSED:
|
|
45
|
+
return ProjectStatusEnum.PAUSED;
|
|
46
|
+
case ProjectStatusEnum.ARCHIVED:
|
|
47
|
+
return ProjectStatusEnum.ARCHIVED;
|
|
48
|
+
default:
|
|
49
|
+
throw new Error(
|
|
50
|
+
`Invalid ProjectStatusEnum value: ${value}. Expected one of: ${Object.values(ProjectStatusEnum).join(", ")}`
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Base project schema
|
|
57
|
+
* Represents projects table structure
|
|
58
|
+
*/
|
|
59
|
+
export const ProjectSchema = Type.Object({
|
|
60
|
+
id: Type.String({ format: "uuid" }),
|
|
61
|
+
org_id: Type.String({ format: "uuid" }),
|
|
62
|
+
name: Type.String({ minLength: 1 }),
|
|
63
|
+
slug: SlugSchema,
|
|
64
|
+
type: Type.Enum(ProjectTypeEnum),
|
|
65
|
+
status: Type.Enum(ProjectStatusEnum),
|
|
66
|
+
created_at: Type.String(),
|
|
67
|
+
updated_at: Type.String(),
|
|
68
|
+
});
|
|
69
|
+
export type Project = Static<typeof ProjectSchema>;
|
|
70
|
+
|
|
71
|
+
export const ProjectParamsSchema = Type.Object({
|
|
72
|
+
project_id_or_slug: Type.String(),
|
|
73
|
+
});
|
|
74
|
+
export type ProjectParams = Static<typeof ProjectParamsSchema>;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Create project request schema
|
|
78
|
+
*/
|
|
79
|
+
export const CreateProjectSchema = Type.Object({
|
|
80
|
+
name: Type.String({ minLength: 1, maxLength: 255 }),
|
|
81
|
+
slug: SlugSchema,
|
|
82
|
+
type: Type.Enum(ProjectTypeEnum),
|
|
83
|
+
org_id: Type.String(),
|
|
84
|
+
});
|
|
85
|
+
export type CreateProject = Static<typeof CreateProjectSchema>;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Update project request schema
|
|
89
|
+
*/
|
|
90
|
+
export const UpdateProjectSchema = Type.Object({
|
|
91
|
+
name: Type.Optional(Type.String({ minLength: 1, maxLength: 255 })),
|
|
92
|
+
slug: Type.Optional(SlugSchema),
|
|
93
|
+
});
|
|
94
|
+
export type UpdateProject = Static<typeof UpdateProjectSchema>;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Single project response schema
|
|
98
|
+
*/
|
|
99
|
+
export const ProjectResponseSchema = Type.Object({
|
|
100
|
+
success: Type.Literal(true),
|
|
101
|
+
data: ProjectSchema,
|
|
102
|
+
});
|
|
103
|
+
export type ProjectResponse = Static<typeof ProjectResponseSchema>;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Multiple projects response schema
|
|
107
|
+
*/
|
|
108
|
+
export const ProjectsResponseSchema = Type.Object({
|
|
109
|
+
projects: Type.Array(ProjectSchema),
|
|
110
|
+
});
|
|
111
|
+
export type ProjectsResponse = Static<typeof ProjectsResponseSchema>;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Project error response schema
|
|
115
|
+
* Discriminated union by error code
|
|
116
|
+
*/
|
|
117
|
+
export const ProjectErrorSchema = Type.Union([
|
|
118
|
+
Type.Object({
|
|
119
|
+
code: Type.Literal("PROJECT_NOT_FOUND"),
|
|
120
|
+
message: Type.String(),
|
|
121
|
+
}),
|
|
122
|
+
Type.Object({
|
|
123
|
+
code: Type.Literal("PROJECT_NOT_IN_ORG"),
|
|
124
|
+
message: Type.String(),
|
|
125
|
+
}),
|
|
126
|
+
Type.Object({
|
|
127
|
+
code: Type.Literal("INVALID_SLUG"),
|
|
128
|
+
message: Type.String(),
|
|
129
|
+
}),
|
|
130
|
+
Type.Object({
|
|
131
|
+
code: Type.Literal("SLUG_ALREADY_EXISTS"),
|
|
132
|
+
message: Type.String(),
|
|
133
|
+
}),
|
|
134
|
+
Type.Object({
|
|
135
|
+
code: Type.Literal("FORBIDDEN"),
|
|
136
|
+
message: Type.String(),
|
|
137
|
+
}),
|
|
138
|
+
Type.Object({
|
|
139
|
+
code: Type.Literal("CREATE_FAILED"),
|
|
140
|
+
message: Type.String(),
|
|
141
|
+
}),
|
|
142
|
+
Type.Object({
|
|
143
|
+
code: Type.Literal("UPDATE_FAILED"),
|
|
144
|
+
message: Type.String(),
|
|
145
|
+
}),
|
|
146
|
+
Type.Object({
|
|
147
|
+
code: Type.Literal("DELETE_FAILED"),
|
|
148
|
+
message: Type.String(),
|
|
149
|
+
}),
|
|
150
|
+
Type.Object({
|
|
151
|
+
code: Type.Literal("FETCH_FAILED"),
|
|
152
|
+
message: Type.String(),
|
|
153
|
+
}),
|
|
154
|
+
Type.Object({
|
|
155
|
+
code: Type.Literal("ARCHIVE_FAILED"),
|
|
156
|
+
message: Type.String(),
|
|
157
|
+
}),
|
|
158
|
+
Type.Object({
|
|
159
|
+
code: Type.Literal("INVALID_REQUEST"),
|
|
160
|
+
message: Type.String(),
|
|
161
|
+
}),
|
|
162
|
+
]);
|
|
163
|
+
export type ProjectError = Static<typeof ProjectErrorSchema>;
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Project error response wrapper
|
|
167
|
+
*/
|
|
168
|
+
export const ProjectErrorResponseSchema = Type.Object({
|
|
169
|
+
success: Type.Literal(false),
|
|
170
|
+
error: ProjectErrorSchema,
|
|
171
|
+
});
|
|
172
|
+
export type ProjectErrorResponse = Static<typeof ProjectErrorResponseSchema>;
|
|
173
|
+
|
|
174
|
+
export const ProjectRequestResponseSchema = Type.Union([ProjectResponseSchema, ProjectErrorResponseSchema]);
|
|
175
|
+
export type ProjectRequestResponse = Static<typeof ProjectRequestResponseSchema>;
|
|
176
|
+
|
|
177
|
+
export type _CheckProjectRow = AssertTrue<AssertSchemaCompatibleWithRow<Project, "projects">>;
|
|
178
|
+
export type _CheckCreateProject = AssertTrue<AssertSchemaCompatibleWithInsert<CreateProject, "projects">>;
|
|
179
|
+
export type _CheckUpdateProject = AssertTrue<AssertSchemaCompatibleWithUpdate<UpdateProject, "projects">>;
|