@darco2903/auth-api 2.0.4-beta.0

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.
@@ -0,0 +1,107 @@
1
+ import { initContract, ZodErrorSchema } from "@ts-rest/core";
2
+ import z from "zod";
3
+ import { apiError, apiSuccess } from "../types.js";
4
+ import { authHeaderSchema, emailSchema, passwordSchema, usernameSchema, userPublicIdSchema, userPublicSchema, userSchema, } from "../types/index.js";
5
+ const c = initContract();
6
+ export default c.router({
7
+ fromId: {
8
+ method: "GET",
9
+ path: "/user/id/:userId",
10
+ description: "Get user by ID",
11
+ pathParams: z.object({
12
+ userId: userPublicIdSchema,
13
+ }),
14
+ responses: {
15
+ 200: apiSuccess(userPublicSchema),
16
+ 400: ZodErrorSchema,
17
+ 404: apiError(z.literal("NOT_FOUND"), z.literal("User not found")),
18
+ 500: apiError(z.literal("INTERNAL_SERVER_ERROR"), z.string()),
19
+ },
20
+ },
21
+ fromIds: {
22
+ method: "GET",
23
+ path: "/user/ids",
24
+ description: "Get users by IDs",
25
+ query: z.object({
26
+ userIds: z.array(userPublicIdSchema),
27
+ }),
28
+ responses: {
29
+ 200: apiSuccess(z.array(userPublicSchema)),
30
+ 400: ZodErrorSchema,
31
+ 500: apiError(z.literal("INTERNAL_SERVER_ERROR"), z.string()),
32
+ },
33
+ },
34
+ me: {
35
+ method: "GET",
36
+ path: "/user/me",
37
+ description: "Get current user",
38
+ headers: authHeaderSchema,
39
+ responses: {
40
+ 200: apiSuccess(userSchema),
41
+ 401: apiError(z.literal("UNAUTHORIZED"), z.literal("Unauthorized")),
42
+ 404: apiError(z.literal("NOT_FOUND"), z.literal("User not found")),
43
+ 500: apiError(z.literal("INTERNAL_SERVER_ERROR"), z.string()),
44
+ },
45
+ },
46
+ updateEmail: {
47
+ method: "PATCH",
48
+ path: "/user/email",
49
+ description: "Update email for current user",
50
+ headers: authHeaderSchema,
51
+ body: z.object({
52
+ email: emailSchema,
53
+ }),
54
+ responses: {
55
+ 200: apiSuccess(c.noBody()),
56
+ 400: ZodErrorSchema,
57
+ 401: apiError(z.literal("UNAUTHORIZED"), z.string()),
58
+ 500: apiError(z.literal("INTERNAL_SERVER_ERROR"), z.string()),
59
+ },
60
+ },
61
+ updatePassword: {
62
+ method: "PATCH",
63
+ path: "/user/password",
64
+ description: "Update password for current user",
65
+ headers: authHeaderSchema,
66
+ body: z.object({
67
+ password: passwordSchema,
68
+ disconnectAll: z.boolean().default(true),
69
+ }),
70
+ responses: {
71
+ 200: apiSuccess(c.noBody()),
72
+ 400: ZodErrorSchema,
73
+ 401: apiError(z.literal("UNAUTHORIZED"), z.string()),
74
+ 500: apiError(z.literal("INTERNAL_SERVER_ERROR"), z.string()),
75
+ },
76
+ },
77
+ updateUsername: {
78
+ method: "PATCH",
79
+ path: "/user/username",
80
+ description: "Update username for current user",
81
+ headers: authHeaderSchema,
82
+ body: z.object({
83
+ username: usernameSchema,
84
+ }),
85
+ responses: {
86
+ 200: apiSuccess(c.noBody()),
87
+ 400: ZodErrorSchema,
88
+ 401: apiError(z.literal("UNAUTHORIZED"), z.string()),
89
+ 500: apiError(z.literal("INTERNAL_SERVER_ERROR"), z.string()),
90
+ },
91
+ },
92
+ updateBorder: {
93
+ method: "POST",
94
+ path: "/user/picture/profile/border",
95
+ description: "Set border for user profile picture",
96
+ headers: authHeaderSchema,
97
+ body: z.object({
98
+ roundBorder: z.boolean(),
99
+ }),
100
+ responses: {
101
+ 200: apiSuccess(c.noBody()),
102
+ 400: ZodErrorSchema,
103
+ 401: apiError(z.literal("UNAUTHORIZED"), z.literal("Unauthorized")),
104
+ 500: apiError(z.literal("INTERNAL_SERVER_ERROR"), z.string()),
105
+ },
106
+ },
107
+ });
@@ -0,0 +1,2 @@
1
+ export * from "./client.js";
2
+ export * from "./server.js";
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./client.js";
2
+ export * from "./server.js";
@@ -0,0 +1,11 @@
1
+ export declare enum UserRole {
2
+ Banned = -1,
3
+ Guest = 0,
4
+ Newbie = 10,
5
+ User = 50,
6
+ Moderator = 100,
7
+ Admin = 150,
8
+ SuperAdmin = 200,
9
+ Developer = 250,
10
+ Owner = 255
11
+ }
package/dist/roles.js ADDED
@@ -0,0 +1,12 @@
1
+ export var UserRole;
2
+ (function (UserRole) {
3
+ UserRole[UserRole["Banned"] = -1] = "Banned";
4
+ UserRole[UserRole["Guest"] = 0] = "Guest";
5
+ UserRole[UserRole["Newbie"] = 10] = "Newbie";
6
+ UserRole[UserRole["User"] = 50] = "User";
7
+ UserRole[UserRole["Moderator"] = 100] = "Moderator";
8
+ UserRole[UserRole["Admin"] = 150] = "Admin";
9
+ UserRole[UserRole["SuperAdmin"] = 200] = "SuperAdmin";
10
+ UserRole[UserRole["Developer"] = 250] = "Developer";
11
+ UserRole[UserRole["Owner"] = 255] = "Owner";
12
+ })(UserRole || (UserRole = {}));
@@ -0,0 +1,11 @@
1
+ export * from "./common.js";
2
+ import { ResultAsync } from "neverthrow";
3
+ import type { Time } from "@darco2903/secondthought";
4
+ import type { CdnAssetTokenData } from "@darco2903/cdn-api/server";
5
+ import { type JWTVerifyError, type AccessTokenData, type AccessTokenDataDecoded, type JWTSignError } from "./types/index.js";
6
+ export declare function JWTVerify(token: string, pubKey: string): ResultAsync<AccessTokenDataDecoded, JWTVerifyError>;
7
+ /**
8
+ * Sign a JWT token with the given payload and private key, with the specified expiration time.
9
+ * @param expiresIn Expiration time in seconds or a Time object.
10
+ */
11
+ export declare function JWTSign(payload: AccessTokenData | CdnAssetTokenData, privKey: string, expiresIn: number | Time): ResultAsync<string, JWTSignError>;
package/dist/server.js ADDED
@@ -0,0 +1,58 @@
1
+ export * from "./common.js";
2
+ import jwt from "jsonwebtoken";
3
+ import { ResultAsync } from "neverthrow";
4
+ import { accessTokenDataDecodedSchema, } from "./types/index.js";
5
+ import { JWT_ALGORITHM } from "./consts.js";
6
+ export function JWTVerify(token, pubKey) {
7
+ return ResultAsync.fromPromise(new Promise((resolve, reject) => {
8
+ jwt.verify(token, pubKey, { algorithms: [JWT_ALGORITHM] }, (e, decoded) => {
9
+ if (e) {
10
+ reject({
11
+ name: e.name,
12
+ message: e.message,
13
+ });
14
+ }
15
+ else if (decoded === undefined) {
16
+ reject({
17
+ name: "InvalidToken",
18
+ message: "Token is undefined",
19
+ });
20
+ }
21
+ else {
22
+ const res = accessTokenDataDecodedSchema.safeParse(decoded);
23
+ if (res.success) {
24
+ resolve(res.data);
25
+ }
26
+ else {
27
+ reject({
28
+ name: "InvalidTokenData",
29
+ message: "Invalid token data",
30
+ });
31
+ }
32
+ }
33
+ });
34
+ }), (e) => e);
35
+ }
36
+ /**
37
+ * Sign a JWT token with the given payload and private key, with the specified expiration time.
38
+ * @param expiresIn Expiration time in seconds or a Time object.
39
+ */
40
+ export function JWTSign(payload, privKey, expiresIn) {
41
+ const expiresInSec = typeof expiresIn === "number" ? expiresIn : expiresIn.toSecond().time;
42
+ return ResultAsync.fromPromise(new Promise((resolve, reject) => {
43
+ jwt.sign(payload, privKey, {
44
+ algorithm: JWT_ALGORITHM,
45
+ expiresIn: expiresInSec,
46
+ }, (e, token) => {
47
+ if (e || token === undefined) {
48
+ reject({
49
+ name: "JsonWebTokenError",
50
+ message: e?.message ?? "Failed to sign token",
51
+ });
52
+ }
53
+ else {
54
+ resolve(token);
55
+ }
56
+ });
57
+ }), (e) => e);
58
+ }
@@ -0,0 +1,5 @@
1
+ import z from "zod";
2
+ export declare const authServiceSchema: z.ZodLiteral<"auth">;
3
+ export type AuthService = z.infer<typeof authServiceSchema>;
4
+ export declare const authAssetTypeSchema: z.ZodEnum<["avatar"]>;
5
+ export type AuthAssetTypes = z.infer<typeof authAssetTypeSchema>;
@@ -0,0 +1,3 @@
1
+ import z from "zod";
2
+ export const authServiceSchema = z.literal("auth");
3
+ export const authAssetTypeSchema = z.enum(["avatar"]);
@@ -0,0 +1,26 @@
1
+ import z from "zod";
2
+ export declare const accessSchema: z.ZodObject<{
3
+ accessToken: z.ZodString;
4
+ expiresIn: z.ZodNumber;
5
+ }, "strip", z.ZodTypeAny, {
6
+ accessToken: string;
7
+ expiresIn: number;
8
+ }, {
9
+ accessToken: string;
10
+ expiresIn: number;
11
+ }>;
12
+ export declare const accessRefreshSchema: z.ZodObject<{
13
+ accessToken: z.ZodString;
14
+ expiresIn: z.ZodNumber;
15
+ } & {
16
+ refreshToken: z.ZodString;
17
+ }, "strip", z.ZodTypeAny, {
18
+ accessToken: string;
19
+ expiresIn: number;
20
+ refreshToken: string;
21
+ }, {
22
+ accessToken: string;
23
+ expiresIn: number;
24
+ refreshToken: string;
25
+ }>;
26
+ export declare const totpCodeSchema: z.ZodString;
@@ -0,0 +1,9 @@
1
+ import z from "zod";
2
+ export const accessSchema = z.object({
3
+ accessToken: z.string(),
4
+ expiresIn: z.number().int().min(0),
5
+ });
6
+ export const accessRefreshSchema = accessSchema.extend({
7
+ refreshToken: z.string(),
8
+ });
9
+ export const totpCodeSchema = z.string().min(6).max(6);
@@ -0,0 +1,8 @@
1
+ import z from "zod";
2
+ export declare const tokenSchema: z.ZodString;
3
+ export declare const emailSchema: z.ZodString;
4
+ export declare const emailCredentialSchema: z.ZodString;
5
+ export declare const passwordSchema: z.ZodString;
6
+ export declare const passwordCredentialSchema: z.ZodEffects<z.ZodString, string, string>;
7
+ export declare const usernameSchema: z.ZodString;
8
+ export declare const turnstileSchema: z.ZodString;
@@ -0,0 +1,44 @@
1
+ import z from "zod";
2
+ import { PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, NAME_MAX_LENGTH, NAME_MIN_LENGTH, EMAIL_MAX_LENGTH, } from "../consts.js";
3
+ export const tokenSchema = z.string().nonempty("Token is required");
4
+ const emailSchemaBase = z.string().max(EMAIL_MAX_LENGTH, "Email is too long");
5
+ export const emailSchema = emailSchemaBase.email();
6
+ export const emailCredentialSchema = emailSchemaBase.email({
7
+ message: "Invalid Credentials",
8
+ });
9
+ // const REGEX_LOWER = /[a-z]/; // contains at least one lowercase letter
10
+ // const REGEX_UPPER = /[A-Z]/; // contains at least one uppercase letter
11
+ // const REGEX_NUMBER = /[0-9]/; // contains at least one number
12
+ // const REGEX_SPECIAL = /[" !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"]/; // contains at least one special character
13
+ export const passwordSchema = z
14
+ .string()
15
+ // .regex(REGEX_LOWER, "Password must contain at least one lowercase letter")
16
+ // .regex(REGEX_UPPER, "Password must contain at least one uppercase letter")
17
+ // .regex(REGEX_NUMBER, "Password must contain at least one number")
18
+ // .regex(
19
+ // REGEX_SPECIAL,
20
+ // "Password must contain at least one special character"
21
+ // )
22
+ .min(PASSWORD_MIN_LENGTH, "Password is too short")
23
+ .max(PASSWORD_MAX_LENGTH, "Password is too long");
24
+ export const passwordCredentialSchema = z.string().superRefine((val, ctx) => {
25
+ // const hasLower = REGEX_LOWER.test(val);
26
+ // const hasUpper = REGEX_UPPER.test(val);
27
+ // const hasNumber = REGEX_NUMBER.test(val);
28
+ // const hasSpecial = REGEX_SPECIAL.test(val);
29
+ const validLength = val.length >= PASSWORD_MIN_LENGTH && val.length <= PASSWORD_MAX_LENGTH;
30
+ // if (!(hasLower && hasUpper && hasNumber && hasSpecial && validLength)) {
31
+ if (!validLength) {
32
+ ctx.addIssue({
33
+ code: z.ZodIssueCode.custom,
34
+ message: "Invalid Credentials",
35
+ });
36
+ }
37
+ });
38
+ export const usernameSchema = z
39
+ .string()
40
+ .min(NAME_MIN_LENGTH, "Username is too short")
41
+ .max(NAME_MAX_LENGTH, "Username is too long");
42
+ export const turnstileSchema = z
43
+ .string()
44
+ .nonempty({ message: "Turnstile token is required" });
@@ -0,0 +1,5 @@
1
+ export * from "./assets.js";
2
+ export * from "./auth.js";
3
+ export * from "./creds.js";
4
+ export * from "./jwt.js";
5
+ export * from "./user.js";
@@ -0,0 +1,5 @@
1
+ export * from "./assets.js";
2
+ export * from "./auth.js";
3
+ export * from "./creds.js";
4
+ export * from "./jwt.js";
5
+ export * from "./user.js";
@@ -0,0 +1,73 @@
1
+ import z from "zod";
2
+ export type JWTVerifyError = {
3
+ name: "TokenExpiredError" | "JsonWebTokenError" | "NotBeforeError" | "InvalidToken" | "InvalidTokenData";
4
+ message: string;
5
+ };
6
+ export type JWTSignError = {
7
+ name: "InvalidTokenData" | "JsonWebTokenError";
8
+ message: string;
9
+ };
10
+ export declare const jwtSchema: z.ZodString;
11
+ export declare const authHeaderSchema: z.ZodObject<{
12
+ authorization: z.ZodOptional<z.ZodString>;
13
+ }, "strip", z.ZodTypeAny, {
14
+ authorization?: string | undefined;
15
+ }, {
16
+ authorization?: string | undefined;
17
+ }>;
18
+ export declare const accessTokenDataSchema: z.ZodObject<{
19
+ public_id: z.ZodString;
20
+ role: z.ZodNumber;
21
+ password_reset: z.ZodOptional<z.ZodString>;
22
+ totp_required: z.ZodBoolean;
23
+ totp_verified: z.ZodBoolean;
24
+ }, "strip", z.ZodTypeAny, {
25
+ role: number;
26
+ public_id: string;
27
+ totp_required: boolean;
28
+ totp_verified: boolean;
29
+ password_reset?: string | undefined;
30
+ }, {
31
+ role: number;
32
+ public_id: string;
33
+ totp_required: boolean;
34
+ totp_verified: boolean;
35
+ password_reset?: string | undefined;
36
+ }>;
37
+ export type AccessTokenData = z.infer<typeof accessTokenDataSchema>;
38
+ export declare const accessTokenDataDecodedSchema: z.ZodIntersection<z.ZodObject<{
39
+ iat: z.ZodNumber;
40
+ exp: z.ZodNumber;
41
+ }, "strip", z.ZodTypeAny, {
42
+ exp: number;
43
+ iat: number;
44
+ }, {
45
+ exp: number;
46
+ iat: number;
47
+ }>, z.ZodObject<{
48
+ public_id: z.ZodString;
49
+ role: z.ZodNumber;
50
+ password_reset: z.ZodOptional<z.ZodString>;
51
+ totp_required: z.ZodBoolean;
52
+ totp_verified: z.ZodBoolean;
53
+ }, "strip", z.ZodTypeAny, {
54
+ role: number;
55
+ public_id: string;
56
+ totp_required: boolean;
57
+ totp_verified: boolean;
58
+ password_reset?: string | undefined;
59
+ }, {
60
+ role: number;
61
+ public_id: string;
62
+ totp_required: boolean;
63
+ totp_verified: boolean;
64
+ password_reset?: string | undefined;
65
+ }>>;
66
+ export type AccessTokenDataDecoded = z.infer<typeof accessTokenDataDecodedSchema>;
67
+ export declare const cdnFeedbackHeaderSchema: z.ZodObject<{
68
+ authorization: z.ZodString;
69
+ }, "strip", z.ZodTypeAny, {
70
+ authorization: string;
71
+ }, {
72
+ authorization: string;
73
+ }>;
@@ -0,0 +1,23 @@
1
+ import z from "zod";
2
+ import { userPublicIdSchema } from "./user.js";
3
+ const JWTData = z.object({
4
+ iat: z.number(),
5
+ exp: z.number(),
6
+ });
7
+ export const jwtSchema = z.string().startsWith("Bearer ");
8
+ ///////////////////////////////////
9
+ export const authHeaderSchema = z.object({
10
+ authorization: jwtSchema.optional(),
11
+ });
12
+ export const accessTokenDataSchema = z.object({
13
+ public_id: userPublicIdSchema,
14
+ role: z.number().int().min(-1).max(255),
15
+ password_reset: z.string().optional(),
16
+ totp_required: z.boolean(),
17
+ totp_verified: z.boolean(),
18
+ });
19
+ export const accessTokenDataDecodedSchema = z.intersection(JWTData, accessTokenDataSchema);
20
+ ///////////////////////////////////
21
+ export const cdnFeedbackHeaderSchema = z.object({
22
+ authorization: jwtSchema,
23
+ });
@@ -0,0 +1,90 @@
1
+ import z from "zod";
2
+ export declare const userPublicIdSchema: z.ZodString;
3
+ declare const userAssetsSchema: z.ZodObject<{
4
+ avatar: z.ZodNullable<z.ZodString>;
5
+ }, "strip", z.ZodTypeAny, {
6
+ avatar: string | null;
7
+ }, {
8
+ avatar: string | null;
9
+ }>;
10
+ export type UserAssets = z.infer<typeof userAssetsSchema>;
11
+ export declare const userPublicSchema: z.ZodObject<{
12
+ public_id: z.ZodString;
13
+ name: z.ZodString;
14
+ assets: z.ZodObject<{
15
+ avatar: z.ZodNullable<z.ZodString>;
16
+ }, "strip", z.ZodTypeAny, {
17
+ avatar: string | null;
18
+ }, {
19
+ avatar: string | null;
20
+ }>;
21
+ round_border: z.ZodBoolean;
22
+ }, "strip", z.ZodTypeAny, {
23
+ name: string;
24
+ public_id: string;
25
+ assets: {
26
+ avatar: string | null;
27
+ };
28
+ round_border: boolean;
29
+ }, {
30
+ name: string;
31
+ public_id: string;
32
+ assets: {
33
+ avatar: string | null;
34
+ };
35
+ round_border: boolean;
36
+ }>;
37
+ export type UserPublic = z.infer<typeof userPublicSchema>;
38
+ export declare const userSchema: z.ZodObject<{
39
+ public_id: z.ZodString;
40
+ name: z.ZodString;
41
+ assets: z.ZodObject<{
42
+ avatar: z.ZodNullable<z.ZodString>;
43
+ }, "strip", z.ZodTypeAny, {
44
+ avatar: string | null;
45
+ }, {
46
+ avatar: string | null;
47
+ }>;
48
+ round_border: z.ZodBoolean;
49
+ } & {
50
+ email: z.ZodString;
51
+ role: z.ZodNumber;
52
+ verified: z.ZodBoolean;
53
+ last_login: z.ZodNullable<z.ZodDate>;
54
+ created_at: z.ZodDate;
55
+ updated_at: z.ZodDate;
56
+ email_verif: z.ZodNullable<z.ZodDate>;
57
+ password_reset: z.ZodNullable<z.ZodDate>;
58
+ }, "strip", z.ZodTypeAny, {
59
+ name: string;
60
+ role: number;
61
+ email: string;
62
+ public_id: string;
63
+ assets: {
64
+ avatar: string | null;
65
+ };
66
+ round_border: boolean;
67
+ verified: boolean;
68
+ last_login: Date | null;
69
+ created_at: Date;
70
+ updated_at: Date;
71
+ email_verif: Date | null;
72
+ password_reset: Date | null;
73
+ }, {
74
+ name: string;
75
+ role: number;
76
+ email: string;
77
+ public_id: string;
78
+ assets: {
79
+ avatar: string | null;
80
+ };
81
+ round_border: boolean;
82
+ verified: boolean;
83
+ last_login: Date | null;
84
+ created_at: Date;
85
+ updated_at: Date;
86
+ email_verif: Date | null;
87
+ password_reset: Date | null;
88
+ }>;
89
+ export type User = z.infer<typeof userSchema>;
90
+ export {};
@@ -0,0 +1,26 @@
1
+ import z from "zod";
2
+ import { USER_PUBLIC_ID_LENGTH } from "../consts.js";
3
+ export const userPublicIdSchema = z
4
+ .string()
5
+ .length(USER_PUBLIC_ID_LENGTH)
6
+ .regex(/^[a-zA-Z0-9]+$/);
7
+ const asset = z.string().url().nullable();
8
+ const userAssetsSchema = z.object({
9
+ avatar: asset,
10
+ });
11
+ export const userPublicSchema = z.object({
12
+ public_id: z.string(),
13
+ name: z.string(),
14
+ assets: userAssetsSchema,
15
+ round_border: z.boolean(),
16
+ });
17
+ export const userSchema = userPublicSchema.extend({
18
+ email: z.string().email(),
19
+ role: z.number().int().min(-1, "Invalid level").max(255, "Invalid level"),
20
+ verified: z.boolean(),
21
+ last_login: z.date().nullable(),
22
+ created_at: z.date(),
23
+ updated_at: z.date(),
24
+ email_verif: z.date().nullable(),
25
+ password_reset: z.date().nullable(),
26
+ });
@@ -0,0 +1,32 @@
1
+ import { z, type ZodType } from "zod";
2
+ import type { ContractNoBodyType } from "@ts-rest/core";
3
+ export declare const apiSuccess: <T extends ZodType | ContractNoBodyType>(schema: T) => T;
4
+ export declare const apiError: <T, U>(code: ZodType<T>, error: ZodType<U>) => z.ZodObject<{
5
+ code: z.ZodType<T, z.ZodTypeDef, T>;
6
+ error: z.ZodType<U, z.ZodTypeDef, U>;
7
+ name: z.ZodLiteral<"APIError">;
8
+ }, "strip", z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<{
9
+ code: z.ZodType<T, z.ZodTypeDef, T>;
10
+ error: z.ZodType<U, z.ZodTypeDef, U>;
11
+ name: z.ZodLiteral<"APIError">;
12
+ }>, any> extends infer T_1 ? { [k in keyof T_1]: T_1[k]; } : never, z.baseObjectInputType<{
13
+ code: z.ZodType<T, z.ZodTypeDef, T>;
14
+ error: z.ZodType<U, z.ZodTypeDef, U>;
15
+ name: z.ZodLiteral<"APIError">;
16
+ }> extends infer T_2 ? { [k_1 in keyof T_2]: T_2[k_1]; } : never>;
17
+ export declare const apiErrorData: <T, U, V>(code: ZodType<T>, error: ZodType<U>, data: ZodType<V>) => z.ZodObject<{
18
+ code: z.ZodType<T, z.ZodTypeDef, T>;
19
+ error: z.ZodType<U, z.ZodTypeDef, U>;
20
+ name: z.ZodLiteral<"APIError">;
21
+ data: z.ZodType<V, z.ZodTypeDef, V>;
22
+ }, "strip", z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<{
23
+ code: z.ZodType<T, z.ZodTypeDef, T>;
24
+ error: z.ZodType<U, z.ZodTypeDef, U>;
25
+ name: z.ZodLiteral<"APIError">;
26
+ data: z.ZodType<V, z.ZodTypeDef, V>;
27
+ }>, any> extends infer T_1 ? { [k in keyof T_1]: T_1[k]; } : never, z.baseObjectInputType<{
28
+ code: z.ZodType<T, z.ZodTypeDef, T>;
29
+ error: z.ZodType<U, z.ZodTypeDef, U>;
30
+ name: z.ZodLiteral<"APIError">;
31
+ data: z.ZodType<V, z.ZodTypeDef, V>;
32
+ }> extends infer T_2 ? { [k_1 in keyof T_2]: T_2[k_1]; } : never>;
package/dist/types.js ADDED
@@ -0,0 +1,13 @@
1
+ import { z } from "zod";
2
+ export const apiSuccess = (schema) => schema;
3
+ export const apiError = (code, error) => z.object({
4
+ code,
5
+ error,
6
+ name: z.literal("APIError"),
7
+ });
8
+ export const apiErrorData = (code, error, data) => z.object({
9
+ code,
10
+ error,
11
+ name: z.literal("APIError"),
12
+ data,
13
+ });
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@darco2903/auth-api",
3
+ "version": "2.0.4-beta.0",
4
+ "description": "",
5
+ "main": "./dist/index.js",
6
+ "type": "module",
7
+ "keywords": [],
8
+ "author": "",
9
+ "license": "ISC",
10
+ "repository": {
11
+ "url": "https://github.com/Darco2903/web-common.git"
12
+ },
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
16
+ "exports": {
17
+ ".": "./dist/index.js",
18
+ "./client": "./dist/client.js",
19
+ "./server": "./dist/server.js"
20
+ },
21
+ "dependencies": {
22
+ "@darco2903/cdn-api": "^1.0.6",
23
+ "@ts-rest/core": "^3.52.1",
24
+ "@ts-rest/open-api": "^3.52.1",
25
+ "jsonwebtoken": "^9.0.3",
26
+ "neverthrow": "^8.2.0",
27
+ "zod": "^3.25.76"
28
+ },
29
+ "peerDependencies": {
30
+ "@darco2903/secondthought": "^1.1.0"
31
+ },
32
+ "devDependencies": {
33
+ "@types/jsonwebtoken": "^9.0.10",
34
+ "@types/node": "^25.4.0",
35
+ "prettier": "^3.8.1",
36
+ "rimraf": "^6.1.3",
37
+ "tsx": "^4.21.0",
38
+ "typescript": "^5.9.3",
39
+ "vitest": "^4.0.18"
40
+ },
41
+ "scripts": {
42
+ "build": "tsc",
43
+ "test": "vitest",
44
+ "clean": "rimraf -g dist openapi.json darco2903-auth-api-*.tgz",
45
+ "generate:openapi": "tsx tools/generate-openapi.ts"
46
+ }
47
+ }
@@ -0,0 +1,25 @@
1
+ import fs from "fs";
2
+ import { generateOpenApi } from "@ts-rest/open-api";
3
+ import { contract } from "../src/";
4
+
5
+ import { version } from "../package.json";
6
+
7
+ console.log("Generating OpenAPI documentation...");
8
+ console.log(`API version: ${version}`);
9
+
10
+ const openApiDocument = generateOpenApi(contract, {
11
+ info: {
12
+ title: "Auth API",
13
+ version,
14
+ },
15
+ servers: [
16
+ {
17
+ url: "https://auth.darco2903.fr",
18
+ },
19
+ {
20
+ url: "https://dev-auth.darco2903.fr",
21
+ },
22
+ ],
23
+ });
24
+
25
+ fs.writeFileSync("openapi.json", JSON.stringify(openApiDocument, null, 2));