@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
package/package.json
CHANGED
|
@@ -1,101 +1,98 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teardown/schemas",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.23",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
8
|
"type": "module",
|
|
9
9
|
"files": [
|
|
10
|
-
"
|
|
10
|
+
"src/**/*"
|
|
11
11
|
],
|
|
12
|
-
"main": "./
|
|
13
|
-
"module": "./
|
|
14
|
-
"types": "./
|
|
12
|
+
"main": "./src/index.ts",
|
|
13
|
+
"module": "./src/index.ts",
|
|
14
|
+
"types": "./src/index.ts",
|
|
15
15
|
"exports": {
|
|
16
16
|
".": {
|
|
17
|
-
"types": "./
|
|
18
|
-
"import": "./
|
|
19
|
-
"default": "./
|
|
17
|
+
"types": "./src/index.ts",
|
|
18
|
+
"import": "./src/index.ts",
|
|
19
|
+
"default": "./src/index.ts"
|
|
20
20
|
},
|
|
21
21
|
"./common": {
|
|
22
|
-
"types": "./
|
|
23
|
-
"import": "./
|
|
24
|
-
"default": "./
|
|
22
|
+
"types": "./src/common/index.ts",
|
|
23
|
+
"import": "./src/common/index.ts",
|
|
24
|
+
"default": "./src/common/index.ts"
|
|
25
25
|
},
|
|
26
26
|
"./devices": {
|
|
27
|
-
"types": "./
|
|
28
|
-
"import": "./
|
|
29
|
-
"default": "./
|
|
27
|
+
"types": "./src/modules/devices/index.ts",
|
|
28
|
+
"import": "./src/modules/devices/index.ts",
|
|
29
|
+
"default": "./src/modules/devices/index.ts"
|
|
30
30
|
},
|
|
31
31
|
"./environment": {
|
|
32
|
-
"types": "./
|
|
33
|
-
"import": "./
|
|
34
|
-
"default": "./
|
|
32
|
+
"types": "./src/modules/environment/index.ts",
|
|
33
|
+
"import": "./src/modules/environment/index.ts",
|
|
34
|
+
"default": "./src/modules/environment/index.ts"
|
|
35
35
|
},
|
|
36
36
|
"./identify": {
|
|
37
|
-
"types": "./
|
|
38
|
-
"import": "./
|
|
39
|
-
"default": "./
|
|
37
|
+
"types": "./src/modules/identify/index.ts",
|
|
38
|
+
"import": "./src/modules/identify/index.ts",
|
|
39
|
+
"default": "./src/modules/identify/index.ts"
|
|
40
40
|
},
|
|
41
41
|
"./me": {
|
|
42
|
-
"types": "./
|
|
43
|
-
"import": "./
|
|
44
|
-
"default": "./
|
|
42
|
+
"types": "./src/modules/me/index.ts",
|
|
43
|
+
"import": "./src/modules/me/index.ts",
|
|
44
|
+
"default": "./src/modules/me/index.ts"
|
|
45
45
|
},
|
|
46
46
|
"./orgs": {
|
|
47
|
-
"types": "./
|
|
48
|
-
"import": "./
|
|
49
|
-
"default": "./
|
|
47
|
+
"types": "./src/modules/orgs/index.ts",
|
|
48
|
+
"import": "./src/modules/orgs/index.ts",
|
|
49
|
+
"default": "./src/modules/orgs/index.ts"
|
|
50
50
|
},
|
|
51
51
|
"./personas": {
|
|
52
|
-
"types": "./
|
|
53
|
-
"import": "./
|
|
54
|
-
"default": "./
|
|
52
|
+
"types": "./src/modules/personas/index.ts",
|
|
53
|
+
"import": "./src/modules/personas/index.ts",
|
|
54
|
+
"default": "./src/modules/personas/index.ts"
|
|
55
55
|
},
|
|
56
56
|
"./projects": {
|
|
57
|
-
"types": "./
|
|
58
|
-
"import": "./
|
|
59
|
-
"default": "./
|
|
57
|
+
"types": "./src/modules/projects/index.ts",
|
|
58
|
+
"import": "./src/modules/projects/index.ts",
|
|
59
|
+
"default": "./src/modules/projects/index.ts"
|
|
60
60
|
},
|
|
61
61
|
"./sessions": {
|
|
62
|
-
"types": "./
|
|
63
|
-
"import": "./
|
|
64
|
-
"default": "./
|
|
62
|
+
"types": "./src/modules/sessions/index.ts",
|
|
63
|
+
"import": "./src/modules/sessions/index.ts",
|
|
64
|
+
"default": "./src/modules/sessions/index.ts"
|
|
65
65
|
},
|
|
66
66
|
"./versions": {
|
|
67
|
-
"types": "./
|
|
68
|
-
"import": "./
|
|
69
|
-
"default": "./
|
|
67
|
+
"types": "./src/modules/versions/index.ts",
|
|
68
|
+
"import": "./src/modules/versions/index.ts",
|
|
69
|
+
"default": "./src/modules/versions/index.ts"
|
|
70
70
|
},
|
|
71
71
|
"./builds": {
|
|
72
|
-
"types": "./
|
|
73
|
-
"import": "./
|
|
74
|
-
"default": "./
|
|
72
|
+
"types": "./src/modules/builds/index.ts",
|
|
73
|
+
"import": "./src/modules/builds/index.ts",
|
|
74
|
+
"default": "./src/modules/builds/index.ts"
|
|
75
75
|
},
|
|
76
76
|
"./analytics": {
|
|
77
|
-
"types": "./
|
|
78
|
-
"import": "./
|
|
79
|
-
"default": "./
|
|
77
|
+
"types": "./src/modules/analytics/index.ts",
|
|
78
|
+
"import": "./src/modules/analytics/index.ts",
|
|
79
|
+
"default": "./src/modules/analytics/index.ts"
|
|
80
80
|
},
|
|
81
81
|
"./events": {
|
|
82
|
-
"types": "./
|
|
83
|
-
"import": "./
|
|
84
|
-
"default": "./
|
|
82
|
+
"types": "./src/modules/events/index.ts",
|
|
83
|
+
"import": "./src/modules/events/index.ts",
|
|
84
|
+
"default": "./src/modules/events/index.ts"
|
|
85
85
|
}
|
|
86
86
|
},
|
|
87
87
|
"scripts": {
|
|
88
|
-
"dev": "tsc --project ./tsconfig.json --watch",
|
|
89
|
-
"build": "tsc --project ./tsconfig.json",
|
|
90
88
|
"typecheck": "tsc --noEmit --project ./tsconfig.json",
|
|
91
89
|
"lint": "bun x biome lint .",
|
|
92
90
|
"fmt": "bun x biome format --write .",
|
|
93
|
-
"check": "bun x biome check ."
|
|
94
|
-
"prepublishOnly": "bun x turbo run build"
|
|
91
|
+
"check": "bun x biome check ."
|
|
95
92
|
},
|
|
96
93
|
"dependencies": {
|
|
97
94
|
"@sinclair/typebox": "^0.34.41",
|
|
98
|
-
"@teardown/types": "0.1.
|
|
95
|
+
"@teardown/types": "0.1.23"
|
|
99
96
|
},
|
|
100
97
|
"devDependencies": {
|
|
101
98
|
"@biomejs/biome": "2.3.7",
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type Static, Type } from "@sinclair/typebox";
|
|
2
|
+
|
|
3
|
+
export const UUIDSchema = Type.String({ format: "uuid", error: "Invalid UUID" });
|
|
4
|
+
export const SlugSchema = Type.String({ pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$", error: "Invalid slug" });
|
|
5
|
+
|
|
6
|
+
export const URLSchema = Type.String({ format: "uri", error: "Invalid URL" });
|
|
7
|
+
export const TimestampSchema = Type.String({ format: "date-time", error: "Invalid timestamp" });
|
|
8
|
+
|
|
9
|
+
export type UUID = Static<typeof UUIDSchema>;
|
|
10
|
+
export type Slug = Static<typeof SlugSchema>;
|
|
11
|
+
export type URL = Static<typeof URLSchema>;
|
|
12
|
+
export type Timestamp = Static<typeof TimestampSchema>;
|
|
13
|
+
|
|
14
|
+
export const EmailSchema = Type.Transform(
|
|
15
|
+
Type.Optional(
|
|
16
|
+
Type.Union([Type.String({ format: "email", error: "Invalid email address" }), Type.Literal(""), Type.Undefined()])
|
|
17
|
+
)
|
|
18
|
+
)
|
|
19
|
+
.Decode((value) => (value === "" ? undefined : value))
|
|
20
|
+
.Encode((value) => value ?? "");
|
|
21
|
+
export type Email = Static<typeof EmailSchema>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type Static, type TSchema, Type } from "@sinclair/typebox";
|
|
2
|
+
|
|
3
|
+
export const SuccessResponseSchema = <T extends TSchema>(dataSchema: T) =>
|
|
4
|
+
Type.Object({
|
|
5
|
+
success: Type.Literal(true),
|
|
6
|
+
data: dataSchema,
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export const ErrorResponseSchema = Type.Object({
|
|
10
|
+
success: Type.Literal(false),
|
|
11
|
+
error: Type.Object({
|
|
12
|
+
message: Type.String(),
|
|
13
|
+
code: Type.Optional(Type.String()),
|
|
14
|
+
}),
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export type SuccessResponse<T> = {
|
|
18
|
+
success: true;
|
|
19
|
+
data: T;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type ErrorResponse = Static<typeof ErrorResponseSchema>;
|
|
23
|
+
|
|
24
|
+
export const RequestResponseSchema = <Success extends TSchema>(successSchema: Success) =>
|
|
25
|
+
Type.Union([SuccessResponseSchema(successSchema), ErrorResponseSchema]);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Insert, Tables, Update } from "@teardown/types";
|
|
2
|
+
|
|
2
3
|
/**
|
|
3
4
|
* Forces TypeScript to error if T is not `true`.
|
|
4
5
|
* Wrap assertion types with this to ensure compile-time validation.
|
|
@@ -9,6 +10,7 @@ import type { Insert, Tables, Update } from "@teardown/types";
|
|
|
9
10
|
* ```
|
|
10
11
|
*/
|
|
11
12
|
export type AssertTrue<T extends true> = T;
|
|
13
|
+
|
|
12
14
|
/**
|
|
13
15
|
* Type-level assertion that ensures SchemaType is compatible with DbType.
|
|
14
16
|
* This will cause a TypeScript error if SchemaType cannot be assigned to DbType.
|
|
@@ -18,7 +20,12 @@ export type AssertTrue<T extends true> = T;
|
|
|
18
20
|
* type _Check = AssertTrue<AssertCompatible<Project, Tables<"projects">["Row"]>>;
|
|
19
21
|
* ```
|
|
20
22
|
*/
|
|
21
|
-
export type AssertCompatible<SchemaType, DbType> = SchemaType extends DbType
|
|
23
|
+
export type AssertCompatible<SchemaType, DbType> = SchemaType extends DbType
|
|
24
|
+
? DbType extends SchemaType
|
|
25
|
+
? true
|
|
26
|
+
: never
|
|
27
|
+
: never;
|
|
28
|
+
|
|
22
29
|
/**
|
|
23
30
|
* Type-level assertion that ensures SchemaType can be assigned to DbType.
|
|
24
31
|
* This is less strict than AssertCompatible - it only checks one-way assignment.
|
|
@@ -29,6 +36,7 @@ export type AssertCompatible<SchemaType, DbType> = SchemaType extends DbType ? D
|
|
|
29
36
|
* ```
|
|
30
37
|
*/
|
|
31
38
|
export type AssertAssignable<SchemaType, DbType> = SchemaType extends DbType ? true : never;
|
|
39
|
+
|
|
32
40
|
/**
|
|
33
41
|
* Helper to check if a schema type is compatible with a database Row type
|
|
34
42
|
*
|
|
@@ -37,7 +45,11 @@ export type AssertAssignable<SchemaType, DbType> = SchemaType extends DbType ? t
|
|
|
37
45
|
* export type _CheckProjectRow = AssertSchemaCompatibleWithRow<Project, "projects">;
|
|
38
46
|
* ```
|
|
39
47
|
*/
|
|
40
|
-
export type AssertSchemaCompatibleWithRow<SchemaType, TableName extends keyof Tables> = AssertCompatible<
|
|
48
|
+
export type AssertSchemaCompatibleWithRow<SchemaType, TableName extends keyof Tables> = AssertCompatible<
|
|
49
|
+
SchemaType,
|
|
50
|
+
Tables[TableName]["Row"]
|
|
51
|
+
>;
|
|
52
|
+
|
|
41
53
|
/**
|
|
42
54
|
* Helper to check if a create schema type is compatible with a database Insert type
|
|
43
55
|
*
|
|
@@ -46,7 +58,11 @@ export type AssertSchemaCompatibleWithRow<SchemaType, TableName extends keyof Ta
|
|
|
46
58
|
* type _CheckCreateProject = AssertSchemaCompatibleWithInsert<CreateProject, "projects">;
|
|
47
59
|
* ```
|
|
48
60
|
*/
|
|
49
|
-
export type AssertSchemaCompatibleWithInsert<SchemaType, TableName extends keyof Tables> = AssertAssignable<
|
|
61
|
+
export type AssertSchemaCompatibleWithInsert<SchemaType, TableName extends keyof Tables> = AssertAssignable<
|
|
62
|
+
SchemaType,
|
|
63
|
+
Insert<TableName>
|
|
64
|
+
>;
|
|
65
|
+
|
|
50
66
|
/**
|
|
51
67
|
* Helper to check if an update schema type is compatible with a database Update type
|
|
52
68
|
*
|
|
@@ -55,4 +71,7 @@ export type AssertSchemaCompatibleWithInsert<SchemaType, TableName extends keyof
|
|
|
55
71
|
* type _CheckUpdateProject = AssertSchemaCompatibleWithUpdate<UpdateProject, "projects">;
|
|
56
72
|
* ```
|
|
57
73
|
*/
|
|
58
|
-
export type AssertSchemaCompatibleWithUpdate<SchemaType, TableName extends keyof Tables> = AssertAssignable<
|
|
74
|
+
export type AssertSchemaCompatibleWithUpdate<SchemaType, TableName extends keyof Tables> = AssertAssignable<
|
|
75
|
+
SchemaType,
|
|
76
|
+
Update<TableName>
|
|
77
|
+
>;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { type Static, Type } from "@sinclair/typebox";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Version adoption schema
|
|
5
|
+
*/
|
|
6
|
+
export const VersionAdoptionPointSchema = Type.Object({
|
|
7
|
+
date: Type.String(), // YYYY-MM-DD
|
|
8
|
+
versions: Type.Record(Type.String(), Type.Number()), // version -> count
|
|
9
|
+
});
|
|
10
|
+
export type VersionAdoptionPoint = Static<typeof VersionAdoptionPointSchema>;
|
|
11
|
+
|
|
12
|
+
export const VersionAdoptionResponseSchema = Type.Object({
|
|
13
|
+
success: Type.Literal(true),
|
|
14
|
+
data: Type.Array(VersionAdoptionPointSchema),
|
|
15
|
+
});
|
|
16
|
+
export type VersionAdoptionResponse = Static<typeof VersionAdoptionResponseSchema>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Active sessions trend schema
|
|
20
|
+
*/
|
|
21
|
+
export const ActiveSessionsPointSchema = Type.Object({
|
|
22
|
+
date: Type.String(), // YYYY-MM-DD
|
|
23
|
+
count: Type.Integer({ minimum: 0 }),
|
|
24
|
+
});
|
|
25
|
+
export type ActiveSessionsPoint = Static<typeof ActiveSessionsPointSchema>;
|
|
26
|
+
|
|
27
|
+
export const ActiveSessionsTrendResponseSchema = Type.Object({
|
|
28
|
+
success: Type.Literal(true),
|
|
29
|
+
data: Type.Array(ActiveSessionsPointSchema),
|
|
30
|
+
});
|
|
31
|
+
export type ActiveSessionsTrendResponse = Static<typeof ActiveSessionsTrendResponseSchema>;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Active users schema (with platform breakdown)
|
|
35
|
+
*/
|
|
36
|
+
export const ActiveUsersSchema = Type.Object({
|
|
37
|
+
total: Type.Integer({ minimum: 0 }),
|
|
38
|
+
ios: Type.Integer({ minimum: 0 }),
|
|
39
|
+
android: Type.Integer({ minimum: 0 }),
|
|
40
|
+
trend: Type.Number(), // percentage change vs previous period
|
|
41
|
+
});
|
|
42
|
+
export type ActiveUsers = Static<typeof ActiveUsersSchema>;
|
|
43
|
+
|
|
44
|
+
export const ActiveUsersResponseSchema = Type.Object({
|
|
45
|
+
success: Type.Literal(true),
|
|
46
|
+
data: ActiveUsersSchema,
|
|
47
|
+
});
|
|
48
|
+
export type ActiveUsersResponse = Static<typeof ActiveUsersResponseSchema>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Active users query params schema
|
|
52
|
+
*/
|
|
53
|
+
export const ActiveUsersQuerySchema = Type.Object({
|
|
54
|
+
start_date: Type.String({ format: "date-time" }),
|
|
55
|
+
end_date: Type.String({ format: "date-time" }),
|
|
56
|
+
});
|
|
57
|
+
export type ActiveUsersQuery = Static<typeof ActiveUsersQuerySchema>;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Build adoption schema (with platform breakdown)
|
|
61
|
+
*/
|
|
62
|
+
export const BuildStatsSchema = Type.Object({
|
|
63
|
+
total: Type.Integer({ minimum: 0 }),
|
|
64
|
+
ios: Type.Integer({ minimum: 0 }),
|
|
65
|
+
android: Type.Integer({ minimum: 0 }),
|
|
66
|
+
});
|
|
67
|
+
export type BuildStats = Static<typeof BuildStatsSchema>;
|
|
68
|
+
|
|
69
|
+
export const BuildAdoptionPointSchema = Type.Object({
|
|
70
|
+
date: Type.String(), // YYYY-MM-DD
|
|
71
|
+
builds: Type.Record(Type.String(), BuildStatsSchema), // build_number -> stats
|
|
72
|
+
});
|
|
73
|
+
export type BuildAdoptionPoint = Static<typeof BuildAdoptionPointSchema>;
|
|
74
|
+
|
|
75
|
+
export const BuildAdoptionResponseSchema = Type.Object({
|
|
76
|
+
success: Type.Literal(true),
|
|
77
|
+
data: Type.Array(BuildAdoptionPointSchema),
|
|
78
|
+
});
|
|
79
|
+
export type BuildAdoptionResponse = Static<typeof BuildAdoptionResponseSchema>;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Date range query params schema (shared)
|
|
83
|
+
*/
|
|
84
|
+
export const DateRangeQuerySchema = Type.Object({
|
|
85
|
+
start_date: Type.String({ format: "date-time" }),
|
|
86
|
+
end_date: Type.String({ format: "date-time" }),
|
|
87
|
+
});
|
|
88
|
+
export type DateRangeQuery = Static<typeof DateRangeQuerySchema>;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Active versions/builds query params schema (with optional search)
|
|
92
|
+
*/
|
|
93
|
+
export const ActiveVersionsQuerySchema = Type.Object({
|
|
94
|
+
start_date: Type.String({ format: "date-time" }),
|
|
95
|
+
end_date: Type.String({ format: "date-time" }),
|
|
96
|
+
search: Type.Optional(Type.String()),
|
|
97
|
+
});
|
|
98
|
+
export type ActiveVersionsQuery = Static<typeof ActiveVersionsQuerySchema>;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Active versions & builds analytics schema
|
|
102
|
+
* Aggregated session counts by version and build for a date range
|
|
103
|
+
*/
|
|
104
|
+
export const ActiveBuildStatsSchema = Type.Object({
|
|
105
|
+
build_id: Type.String(),
|
|
106
|
+
build_number: Type.Integer({ minimum: 0 }),
|
|
107
|
+
platform: Type.Union([Type.Literal("IOS"), Type.Literal("ANDROID")]),
|
|
108
|
+
session_count: Type.Integer({ minimum: 0 }),
|
|
109
|
+
device_count: Type.Integer({ minimum: 0 }),
|
|
110
|
+
});
|
|
111
|
+
export type ActiveBuildStats = Static<typeof ActiveBuildStatsSchema>;
|
|
112
|
+
|
|
113
|
+
export const ActiveVersionStatsSchema = Type.Object({
|
|
114
|
+
version_id: Type.String(),
|
|
115
|
+
version_name: Type.String(),
|
|
116
|
+
session_count: Type.Integer({ minimum: 0 }),
|
|
117
|
+
device_count: Type.Integer({ minimum: 0 }),
|
|
118
|
+
ios_count: Type.Integer({ minimum: 0 }),
|
|
119
|
+
android_count: Type.Integer({ minimum: 0 }),
|
|
120
|
+
builds: Type.Array(ActiveBuildStatsSchema),
|
|
121
|
+
});
|
|
122
|
+
export type ActiveVersionStats = Static<typeof ActiveVersionStatsSchema>;
|
|
123
|
+
|
|
124
|
+
export const ActiveVersionsBuildsSchema = Type.Object({
|
|
125
|
+
versions: Type.Array(ActiveVersionStatsSchema),
|
|
126
|
+
});
|
|
127
|
+
export type ActiveVersionsBuilds = Static<typeof ActiveVersionsBuildsSchema>;
|
|
128
|
+
|
|
129
|
+
export const ActiveVersionsBuildsResponseSchema = Type.Object({
|
|
130
|
+
success: Type.Literal(true),
|
|
131
|
+
data: ActiveVersionsBuildsSchema,
|
|
132
|
+
});
|
|
133
|
+
export type ActiveVersionsBuildsResponse = Static<typeof ActiveVersionsBuildsResponseSchema>;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Session with user/device data for build sessions endpoint
|
|
137
|
+
*/
|
|
138
|
+
export const SessionDeviceSchema = Type.Object({
|
|
139
|
+
id: Type.String(),
|
|
140
|
+
device_name: Type.Union([Type.String(), Type.Null()]),
|
|
141
|
+
device_brand: Type.Union([Type.String(), Type.Null()]),
|
|
142
|
+
});
|
|
143
|
+
export type SessionDevice = Static<typeof SessionDeviceSchema>;
|
|
144
|
+
|
|
145
|
+
export const SessionUserSchema = Type.Object({
|
|
146
|
+
id: Type.String(),
|
|
147
|
+
user_id: Type.Union([Type.String(), Type.Null()]),
|
|
148
|
+
email: Type.Union([Type.String(), Type.Null()]),
|
|
149
|
+
name: Type.Union([Type.String(), Type.Null()]),
|
|
150
|
+
});
|
|
151
|
+
export type SessionUser = Static<typeof SessionUserSchema>;
|
|
152
|
+
|
|
153
|
+
export const SessionWithUserSchema = Type.Object({
|
|
154
|
+
id: Type.String(),
|
|
155
|
+
started_at: Type.String(),
|
|
156
|
+
os_version: Type.Union([Type.String(), Type.Null()]),
|
|
157
|
+
device: SessionDeviceSchema,
|
|
158
|
+
user: Type.Union([SessionUserSchema, Type.Null()]),
|
|
159
|
+
});
|
|
160
|
+
export type SessionWithUser = Static<typeof SessionWithUserSchema>;
|
|
161
|
+
|
|
162
|
+
export const BuildSessionsQuerySchema = Type.Object({
|
|
163
|
+
start_date: Type.String({ format: "date-time" }),
|
|
164
|
+
end_date: Type.String({ format: "date-time" }),
|
|
165
|
+
cursor: Type.Optional(Type.String()),
|
|
166
|
+
limit: Type.Optional(Type.String({ default: "20" })),
|
|
167
|
+
search: Type.Optional(Type.String()),
|
|
168
|
+
});
|
|
169
|
+
export type BuildSessionsQuery = Static<typeof BuildSessionsQuerySchema>;
|
|
170
|
+
|
|
171
|
+
export const BuildSessionsResponseSchema = Type.Object({
|
|
172
|
+
success: Type.Literal(true),
|
|
173
|
+
data: Type.Object({
|
|
174
|
+
sessions: Type.Array(SessionWithUserSchema),
|
|
175
|
+
next_cursor: Type.Union([Type.String(), Type.Null()]),
|
|
176
|
+
}),
|
|
177
|
+
});
|
|
178
|
+
export type BuildSessionsResponse = Static<typeof BuildSessionsResponseSchema>;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { VersionBuildStatusEnum } from "@teardown/types";
|
|
2
|
+
import { type Static, Type } from "@sinclair/typebox";
|
|
3
|
+
import type { AssertSchemaCompatibleWithRow, AssertTrue } from "../../common";
|
|
4
|
+
import { DevicePlatformSchema } from "../devices/schemas";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Build status enum matching database (reuses VersionBuildStatusEnum)
|
|
8
|
+
*/
|
|
9
|
+
export const BuildStatusSchema = Type.Enum(VersionBuildStatusEnum);
|
|
10
|
+
export type BuildStatus = Static<typeof BuildStatusSchema>;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Base build schema
|
|
14
|
+
* Represents version_builds table structure
|
|
15
|
+
*/
|
|
16
|
+
export const BuildSchema = Type.Object({
|
|
17
|
+
id: Type.String({ format: "uuid" }),
|
|
18
|
+
version_id: Type.String({ format: "uuid" }),
|
|
19
|
+
build_number: Type.Integer({ minimum: 0 }),
|
|
20
|
+
name: Type.Union([Type.String(), Type.Null()]),
|
|
21
|
+
summary: Type.Union([Type.String(), Type.Null()]),
|
|
22
|
+
commit_sha: Type.Union([Type.String(), Type.Null()]),
|
|
23
|
+
platform: DevicePlatformSchema,
|
|
24
|
+
status: BuildStatusSchema,
|
|
25
|
+
fingerprint: Type.Union([Type.String(), Type.Null()]),
|
|
26
|
+
created_at: Type.String(),
|
|
27
|
+
updated_at: Type.String(),
|
|
28
|
+
});
|
|
29
|
+
export type Build = Static<typeof BuildSchema>;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Build params schema
|
|
33
|
+
*/
|
|
34
|
+
export const BuildParamsSchema = Type.Object({
|
|
35
|
+
build_id: Type.String({ format: "uuid" }),
|
|
36
|
+
});
|
|
37
|
+
export type BuildParams = Static<typeof BuildParamsSchema>;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Search builds query schema
|
|
41
|
+
* Supports pagination, search, and sorting
|
|
42
|
+
*/
|
|
43
|
+
export const SearchBuildsQuerySchema = Type.Object({
|
|
44
|
+
project_id: Type.String({ format: "uuid" }),
|
|
45
|
+
page: Type.Number({ minimum: 1, default: 1 }),
|
|
46
|
+
limit: Type.Number({ minimum: 1, maximum: 100, default: 20 }),
|
|
47
|
+
search: Type.Optional(Type.String()),
|
|
48
|
+
sort_by: Type.Union(
|
|
49
|
+
[
|
|
50
|
+
Type.Literal("created_at"),
|
|
51
|
+
Type.Literal("updated_at"),
|
|
52
|
+
Type.Literal("build_number"),
|
|
53
|
+
Type.Literal("platform"),
|
|
54
|
+
Type.Literal("name"),
|
|
55
|
+
],
|
|
56
|
+
{ default: "created_at" }
|
|
57
|
+
),
|
|
58
|
+
sort_order: Type.Union([Type.Literal("asc"), Type.Literal("desc")], { default: "desc" }),
|
|
59
|
+
});
|
|
60
|
+
export type SearchBuildsQuery = Static<typeof SearchBuildsQuerySchema>;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Search builds query schema without project_id (injected from headers)
|
|
64
|
+
*/
|
|
65
|
+
export const SearchBuildsQueryParamsSchema = Type.Omit(SearchBuildsQuerySchema, ["project_id"]);
|
|
66
|
+
export type SearchBuildsQueryParams = Static<typeof SearchBuildsQueryParamsSchema>;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Builds by IDs request schema
|
|
70
|
+
*/
|
|
71
|
+
export const BuildsByIdsSchema = Type.Object({
|
|
72
|
+
build_ids: Type.Array(Type.String({ format: "uuid" }), { minItems: 1, maxItems: 100 }),
|
|
73
|
+
});
|
|
74
|
+
export type BuildsByIds = Static<typeof BuildsByIdsSchema>;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Paginated builds response schema
|
|
78
|
+
*/
|
|
79
|
+
export const BuildsResponseSchema = Type.Object({
|
|
80
|
+
builds: Type.Array(BuildSchema),
|
|
81
|
+
pagination: Type.Object({
|
|
82
|
+
page: Type.Integer({ minimum: 1 }),
|
|
83
|
+
limit: Type.Integer({ minimum: 1 }),
|
|
84
|
+
total: Type.Integer({ minimum: 0 }),
|
|
85
|
+
total_pages: Type.Integer({ minimum: 0 }),
|
|
86
|
+
}),
|
|
87
|
+
});
|
|
88
|
+
export type BuildsResponse = Static<typeof BuildsResponseSchema>;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Single build response schema
|
|
92
|
+
*/
|
|
93
|
+
export const BuildResponseSchema = Type.Object({
|
|
94
|
+
success: Type.Literal(true),
|
|
95
|
+
data: BuildSchema,
|
|
96
|
+
});
|
|
97
|
+
export type BuildResponse = Static<typeof BuildResponseSchema>;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Build error response schema
|
|
101
|
+
* Discriminated union by error code
|
|
102
|
+
*/
|
|
103
|
+
export const BuildErrorSchema = Type.Union([
|
|
104
|
+
Type.Object({
|
|
105
|
+
code: Type.Literal("BUILD_NOT_FOUND"),
|
|
106
|
+
message: Type.String(),
|
|
107
|
+
}),
|
|
108
|
+
Type.Object({
|
|
109
|
+
code: Type.Literal("PROJECT_NOT_FOUND"),
|
|
110
|
+
message: Type.String(),
|
|
111
|
+
}),
|
|
112
|
+
Type.Object({
|
|
113
|
+
code: Type.Literal("FORBIDDEN"),
|
|
114
|
+
message: Type.String(),
|
|
115
|
+
}),
|
|
116
|
+
Type.Object({
|
|
117
|
+
code: Type.Literal("FETCH_FAILED"),
|
|
118
|
+
message: Type.String(),
|
|
119
|
+
}),
|
|
120
|
+
Type.Object({
|
|
121
|
+
code: Type.Literal("INVALID_PARAMS"),
|
|
122
|
+
message: Type.String(),
|
|
123
|
+
}),
|
|
124
|
+
]);
|
|
125
|
+
export type BuildError = Static<typeof BuildErrorSchema>;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Build error response wrapper
|
|
129
|
+
*/
|
|
130
|
+
export const BuildErrorResponseSchema = Type.Object({
|
|
131
|
+
success: Type.Literal(false),
|
|
132
|
+
error: BuildErrorSchema,
|
|
133
|
+
});
|
|
134
|
+
export type BuildErrorResponse = Static<typeof BuildErrorResponseSchema>;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Build request response schema
|
|
138
|
+
*/
|
|
139
|
+
export const BuildRequestResponseSchema = Type.Union([BuildResponseSchema, BuildErrorResponseSchema]);
|
|
140
|
+
export type BuildRequestResponse = Static<typeof BuildRequestResponseSchema>;
|
|
141
|
+
|
|
142
|
+
export type _CheckBuildRow = AssertTrue<AssertSchemaCompatibleWithRow<Build, "version_builds">>;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Update build status request body schema
|
|
146
|
+
*/
|
|
147
|
+
export const UpdateBuildStatusBodySchema = Type.Object({
|
|
148
|
+
status: BuildStatusSchema,
|
|
149
|
+
});
|
|
150
|
+
export type UpdateBuildStatusBody = Static<typeof UpdateBuildStatusBodySchema>;
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Add UPDATE_FAILED error code for update operations
|
|
154
|
+
*/
|
|
155
|
+
export const BuildErrorSchemaWithUpdate = Type.Union([
|
|
156
|
+
BuildErrorSchema,
|
|
157
|
+
Type.Object({
|
|
158
|
+
code: Type.Literal("UPDATE_FAILED"),
|
|
159
|
+
message: Type.String(),
|
|
160
|
+
}),
|
|
161
|
+
]);
|
|
162
|
+
export type BuildErrorWithUpdate = Static<typeof BuildErrorSchemaWithUpdate>;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Build error response wrapper with update error
|
|
166
|
+
*/
|
|
167
|
+
export const BuildErrorResponseWithUpdateSchema = Type.Object({
|
|
168
|
+
success: Type.Literal(false),
|
|
169
|
+
error: BuildErrorSchemaWithUpdate,
|
|
170
|
+
});
|
|
171
|
+
export type BuildErrorResponseWithUpdate = Static<typeof BuildErrorResponseWithUpdateSchema>;
|