Build API v2

This commit is contained in:
NeilClack
2026-08-07 14:06:20 -05:00
parent b2091deae0
commit 64f7070ad7
50 changed files with 25534 additions and 26502 deletions
+42 -37
View File
@@ -1,94 +1,99 @@
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
/* eslint-disable */
// biome-ignore-all lint: generated file
// @ts-nocheck
// @ts-nocheck
/*
* This file should be your main import to use Prisma-related types and utilities in a browser.
* This file should be your main import to use Prisma-related types and utilities in a browser.
* Use it to get access to models, enums, and input types.
*
*
* This file does not contain a `PrismaClient` class, nor several other helpers that are intended as server-side only.
* See `client.ts` for the standard, server-side entry point.
*
* 🟢 You can import this file directly.
*/
import * as Prisma from './internal/prismaNamespaceBrowser.ts';
export { Prisma };
export * as $Enums from './enums.ts';
import * as Prisma from './internal/prismaNamespaceBrowser.ts'
export { Prisma }
export * as $Enums from './enums.ts'
export * from './enums.ts';
/**
* Model User
*
*
*/
export type User = Prisma.UserModel;
export type User = Prisma.UserModel
/**
* Model Profile
*
*
*/
export type Profile = Prisma.ProfileModel;
export type Profile = Prisma.ProfileModel
/**
* Model Address
*
*
*/
export type Address = Prisma.AddressModel;
export type Address = Prisma.AddressModel
/**
* Model Session
*
*
*/
export type Session = Prisma.SessionModel;
export type Session = Prisma.SessionModel
/**
* Model Account
*
*
*/
export type Account = Prisma.AccountModel;
export type Account = Prisma.AccountModel
/**
* Model UserRole
*
*
*/
export type UserRole = Prisma.UserRoleModel;
export type UserRole = Prisma.UserRoleModel
/**
* Model Verification
*
*
*/
export type Verification = Prisma.VerificationModel;
export type Verification = Prisma.VerificationModel
/**
* Model Proclamation
*
*
*/
export type Proclamation = Prisma.ProclamationModel;
export type Proclamation = Prisma.ProclamationModel
/**
* Model UserProclamations
*
*
*/
export type UserProclamations = Prisma.UserProclamationsModel;
export type UserProclamations = Prisma.UserProclamationsModel
/**
* Model SolfeggioFrequency
*
*
*/
export type SolfeggioFrequency = Prisma.SolfeggioFrequencyModel;
export type SolfeggioFrequency = Prisma.SolfeggioFrequencyModel
/**
* Model ProclamationCategory
*
*
*/
export type ProclamationCategory = Prisma.ProclamationCategoryModel;
export type ProclamationCategory = Prisma.ProclamationCategoryModel
/**
* Model ProclamationCategorySubscriptionLevel
*
*
*/
export type ProclamationCategorySubscriptionLevel =
Prisma.ProclamationCategorySubscriptionLevelModel;
export type ProclamationCategorySubscriptionLevel = Prisma.ProclamationCategorySubscriptionLevelModel
/**
* Model LicenseKey
*
*
*/
export type LicenseKey = Prisma.LicenseKeyModel;
export type LicenseKey = Prisma.LicenseKeyModel
/**
* Model ApiKey
*
*
*/
export type ApiKey = Prisma.ApiKeyModel;
export type ApiKey = Prisma.ApiKeyModel
/**
* Model SubscriptionLevel
*
*
*/
export type SubscriptionLevel = Prisma.SubscriptionLevelModel;
export type SubscriptionLevel = Prisma.SubscriptionLevelModel
/**
* Model ColorPalette
*
*/
export type ColorPalette = Prisma.ColorPaletteModel
+52 -51
View File
@@ -1,7 +1,8 @@
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
/* eslint-disable */
// biome-ignore-all lint: generated file
// @ts-nocheck
// @ts-nocheck
/*
* This file should be your main import to use Prisma. Through it you get access to all the models, enums, and input types.
* If you're looking for something you can import in the client-side of your application, please refer to the `browser.ts` file instead.
@@ -9,21 +10,21 @@
* 🟢 You can import this file directly.
*/
import * as process from 'node:process';
import * as path from 'node:path';
import { fileURLToPath } from 'node:url';
globalThis['__dirname'] = path.dirname(fileURLToPath(import.meta.url));
import * as process from 'node:process'
import * as path from 'node:path'
import { fileURLToPath } from 'node:url'
globalThis['__dirname'] = path.dirname(fileURLToPath(import.meta.url))
import * as runtime from '@prisma/client/runtime/client';
import * as $Enums from './enums.ts';
import * as $Class from './internal/class.ts';
import * as Prisma from './internal/prismaNamespace.ts';
import * as runtime from "@prisma/client/runtime/client"
import * as $Enums from "./enums.ts"
import * as $Class from "./internal/class.ts"
import * as Prisma from "./internal/prismaNamespace.ts"
export * as $Enums from './enums.ts';
export * from './enums.ts';
export * as $Enums from './enums.ts'
export * from "./enums.ts"
/**
* ## Prisma Client
*
*
* Type-safe database client for TypeScript
* @example
* ```
@@ -33,90 +34,90 @@ export * from './enums.ts';
* // Fetch zero or more Users
* const users = await prisma.user.findMany()
* ```
*
*
* Read more in our [docs](https://pris.ly/d/client).
*/
export const PrismaClient = $Class.getPrismaClientClass();
export type PrismaClient<
LogOpts extends Prisma.LogLevel = never,
OmitOpts extends Prisma.PrismaClientOptions['omit'] = Prisma.PrismaClientOptions['omit'],
ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs
> = $Class.PrismaClient<LogOpts, OmitOpts, ExtArgs>;
export { Prisma };
export const PrismaClient = $Class.getPrismaClientClass()
export type PrismaClient<LogOpts extends Prisma.LogLevel = never, OmitOpts extends Prisma.PrismaClientOptions["omit"] = Prisma.PrismaClientOptions["omit"], ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = $Class.PrismaClient<LogOpts, OmitOpts, ExtArgs>
export { Prisma }
/**
* Model User
*
*
*/
export type User = Prisma.UserModel;
export type User = Prisma.UserModel
/**
* Model Profile
*
*
*/
export type Profile = Prisma.ProfileModel;
export type Profile = Prisma.ProfileModel
/**
* Model Address
*
*
*/
export type Address = Prisma.AddressModel;
export type Address = Prisma.AddressModel
/**
* Model Session
*
*
*/
export type Session = Prisma.SessionModel;
export type Session = Prisma.SessionModel
/**
* Model Account
*
*
*/
export type Account = Prisma.AccountModel;
export type Account = Prisma.AccountModel
/**
* Model UserRole
*
*
*/
export type UserRole = Prisma.UserRoleModel;
export type UserRole = Prisma.UserRoleModel
/**
* Model Verification
*
*
*/
export type Verification = Prisma.VerificationModel;
export type Verification = Prisma.VerificationModel
/**
* Model Proclamation
*
*
*/
export type Proclamation = Prisma.ProclamationModel;
export type Proclamation = Prisma.ProclamationModel
/**
* Model UserProclamations
*
*
*/
export type UserProclamations = Prisma.UserProclamationsModel;
export type UserProclamations = Prisma.UserProclamationsModel
/**
* Model SolfeggioFrequency
*
*
*/
export type SolfeggioFrequency = Prisma.SolfeggioFrequencyModel;
export type SolfeggioFrequency = Prisma.SolfeggioFrequencyModel
/**
* Model ProclamationCategory
*
*
*/
export type ProclamationCategory = Prisma.ProclamationCategoryModel;
export type ProclamationCategory = Prisma.ProclamationCategoryModel
/**
* Model ProclamationCategorySubscriptionLevel
*
*
*/
export type ProclamationCategorySubscriptionLevel =
Prisma.ProclamationCategorySubscriptionLevelModel;
export type ProclamationCategorySubscriptionLevel = Prisma.ProclamationCategorySubscriptionLevelModel
/**
* Model LicenseKey
*
*
*/
export type LicenseKey = Prisma.LicenseKeyModel;
export type LicenseKey = Prisma.LicenseKeyModel
/**
* Model ApiKey
*
*
*/
export type ApiKey = Prisma.ApiKeyModel;
export type ApiKey = Prisma.ApiKeyModel
/**
* Model SubscriptionLevel
*
*
*/
export type SubscriptionLevel = Prisma.SubscriptionLevelModel;
export type SubscriptionLevel = Prisma.SubscriptionLevelModel
/**
* Model ColorPalette
*
*/
export type ColorPalette = Prisma.ColorPaletteModel
+410 -331
View File
@@ -1,402 +1,481 @@
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
/* eslint-disable */
// biome-ignore-all lint: generated file
// @ts-nocheck
// @ts-nocheck
/*
* This file exports various common sort, input & filter types that are not directly linked to a particular model.
*
* 🟢 You can import this file directly.
*/
import type * as runtime from '@prisma/client/runtime/client';
import * as $Enums from './enums.ts';
import type * as Prisma from './internal/prismaNamespace.ts';
import type * as runtime from "@prisma/client/runtime/client"
import * as $Enums from "./enums.ts"
import type * as Prisma from "./internal/prismaNamespace.ts"
export type StringFilter<$PrismaModel = never> = {
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>;
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>;
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>;
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>;
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>;
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>;
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>;
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>;
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>;
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>;
mode?: Prisma.QueryMode;
not?: Prisma.NestedStringFilter<$PrismaModel> | string;
};
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
mode?: Prisma.QueryMode
not?: Prisma.NestedStringFilter<$PrismaModel> | string
}
export type BoolFilter<$PrismaModel = never> = {
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>;
not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean;
};
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean
}
export type StringNullableFilter<$PrismaModel = never> = {
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null;
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null;
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null;
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>;
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>;
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>;
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>;
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>;
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>;
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>;
mode?: Prisma.QueryMode;
not?: Prisma.NestedStringNullableFilter<$PrismaModel> | string | null;
};
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
mode?: Prisma.QueryMode
not?: Prisma.NestedStringNullableFilter<$PrismaModel> | string | null
}
export type DateTimeFilter<$PrismaModel = never> = {
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>;
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>;
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
not?: Prisma.NestedDateTimeFilter<$PrismaModel> | Date | string;
};
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
not?: Prisma.NestedDateTimeFilter<$PrismaModel> | Date | string
}
export type IntNullableFilter<$PrismaModel = never> = {
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null;
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null;
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null;
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>;
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>;
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>;
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>;
not?: Prisma.NestedIntNullableFilter<$PrismaModel> | number | null;
};
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
not?: Prisma.NestedIntNullableFilter<$PrismaModel> | number | null
}
export type SortOrderInput = {
sort: Prisma.SortOrder;
nulls?: Prisma.NullsOrder;
};
sort: Prisma.SortOrder
nulls?: Prisma.NullsOrder
}
export type StringWithAggregatesFilter<$PrismaModel = never> = {
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>;
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>;
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>;
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>;
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>;
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>;
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>;
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>;
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>;
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>;
mode?: Prisma.QueryMode;
not?: Prisma.NestedStringWithAggregatesFilter<$PrismaModel> | string;
_count?: Prisma.NestedIntFilter<$PrismaModel>;
_min?: Prisma.NestedStringFilter<$PrismaModel>;
_max?: Prisma.NestedStringFilter<$PrismaModel>;
};
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
mode?: Prisma.QueryMode
not?: Prisma.NestedStringWithAggregatesFilter<$PrismaModel> | string
_count?: Prisma.NestedIntFilter<$PrismaModel>
_min?: Prisma.NestedStringFilter<$PrismaModel>
_max?: Prisma.NestedStringFilter<$PrismaModel>
}
export type BoolWithAggregatesFilter<$PrismaModel = never> = {
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>;
not?: Prisma.NestedBoolWithAggregatesFilter<$PrismaModel> | boolean;
_count?: Prisma.NestedIntFilter<$PrismaModel>;
_min?: Prisma.NestedBoolFilter<$PrismaModel>;
_max?: Prisma.NestedBoolFilter<$PrismaModel>;
};
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
not?: Prisma.NestedBoolWithAggregatesFilter<$PrismaModel> | boolean
_count?: Prisma.NestedIntFilter<$PrismaModel>
_min?: Prisma.NestedBoolFilter<$PrismaModel>
_max?: Prisma.NestedBoolFilter<$PrismaModel>
}
export type StringNullableWithAggregatesFilter<$PrismaModel = never> = {
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null;
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null;
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null;
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>;
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>;
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>;
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>;
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>;
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>;
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>;
mode?: Prisma.QueryMode;
not?: Prisma.NestedStringNullableWithAggregatesFilter<$PrismaModel> | string | null;
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>;
_min?: Prisma.NestedStringNullableFilter<$PrismaModel>;
_max?: Prisma.NestedStringNullableFilter<$PrismaModel>;
};
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
mode?: Prisma.QueryMode
not?: Prisma.NestedStringNullableWithAggregatesFilter<$PrismaModel> | string | null
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
_min?: Prisma.NestedStringNullableFilter<$PrismaModel>
_max?: Prisma.NestedStringNullableFilter<$PrismaModel>
}
export type DateTimeWithAggregatesFilter<$PrismaModel = never> = {
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>;
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>;
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
not?: Prisma.NestedDateTimeWithAggregatesFilter<$PrismaModel> | Date | string;
_count?: Prisma.NestedIntFilter<$PrismaModel>;
_min?: Prisma.NestedDateTimeFilter<$PrismaModel>;
_max?: Prisma.NestedDateTimeFilter<$PrismaModel>;
};
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
not?: Prisma.NestedDateTimeWithAggregatesFilter<$PrismaModel> | Date | string
_count?: Prisma.NestedIntFilter<$PrismaModel>
_min?: Prisma.NestedDateTimeFilter<$PrismaModel>
_max?: Prisma.NestedDateTimeFilter<$PrismaModel>
}
export type IntNullableWithAggregatesFilter<$PrismaModel = never> = {
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null;
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null;
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null;
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>;
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>;
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>;
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>;
not?: Prisma.NestedIntNullableWithAggregatesFilter<$PrismaModel> | number | null;
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>;
_avg?: Prisma.NestedFloatNullableFilter<$PrismaModel>;
_sum?: Prisma.NestedIntNullableFilter<$PrismaModel>;
_min?: Prisma.NestedIntNullableFilter<$PrismaModel>;
_max?: Prisma.NestedIntNullableFilter<$PrismaModel>;
};
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
not?: Prisma.NestedIntNullableWithAggregatesFilter<$PrismaModel> | number | null
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
_avg?: Prisma.NestedFloatNullableFilter<$PrismaModel>
_sum?: Prisma.NestedIntNullableFilter<$PrismaModel>
_min?: Prisma.NestedIntNullableFilter<$PrismaModel>
_max?: Prisma.NestedIntNullableFilter<$PrismaModel>
}
export type DateTimeNullableFilter<$PrismaModel = never> = {
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null;
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null;
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null;
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
not?: Prisma.NestedDateTimeNullableFilter<$PrismaModel> | Date | string | null;
};
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
not?: Prisma.NestedDateTimeNullableFilter<$PrismaModel> | Date | string | null
}
export type DateTimeNullableWithAggregatesFilter<$PrismaModel = never> = {
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null;
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null;
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null;
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
not?: Prisma.NestedDateTimeNullableWithAggregatesFilter<$PrismaModel> | Date | string | null;
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>;
_min?: Prisma.NestedDateTimeNullableFilter<$PrismaModel>;
_max?: Prisma.NestedDateTimeNullableFilter<$PrismaModel>;
};
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
not?: Prisma.NestedDateTimeNullableWithAggregatesFilter<$PrismaModel> | Date | string | null
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
_min?: Prisma.NestedDateTimeNullableFilter<$PrismaModel>
_max?: Prisma.NestedDateTimeNullableFilter<$PrismaModel>
}
export type IntFilter<$PrismaModel = never> = {
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>;
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>;
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>;
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>;
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>;
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>;
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>;
not?: Prisma.NestedIntFilter<$PrismaModel> | number;
};
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
not?: Prisma.NestedIntFilter<$PrismaModel> | number
}
export type IntWithAggregatesFilter<$PrismaModel = never> = {
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>;
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>;
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>;
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>;
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>;
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>;
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>;
not?: Prisma.NestedIntWithAggregatesFilter<$PrismaModel> | number;
_count?: Prisma.NestedIntFilter<$PrismaModel>;
_avg?: Prisma.NestedFloatFilter<$PrismaModel>;
_sum?: Prisma.NestedIntFilter<$PrismaModel>;
_min?: Prisma.NestedIntFilter<$PrismaModel>;
_max?: Prisma.NestedIntFilter<$PrismaModel>;
};
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
not?: Prisma.NestedIntWithAggregatesFilter<$PrismaModel> | number
_count?: Prisma.NestedIntFilter<$PrismaModel>
_avg?: Prisma.NestedFloatFilter<$PrismaModel>
_sum?: Prisma.NestedIntFilter<$PrismaModel>
_min?: Prisma.NestedIntFilter<$PrismaModel>
_max?: Prisma.NestedIntFilter<$PrismaModel>
}
export type JsonFilter<$PrismaModel = never> =
| Prisma.PatchUndefined<
Prisma.Either<Required<JsonFilterBase<$PrismaModel>>, Exclude<keyof Required<JsonFilterBase<$PrismaModel>>, 'path'>>,
Required<JsonFilterBase<$PrismaModel>>
>
| Prisma.OptionalFlat<Omit<Required<JsonFilterBase<$PrismaModel>>, 'path'>>
export type JsonFilterBase<$PrismaModel = never> = {
equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
path?: string[]
mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel>
string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
}
export type JsonWithAggregatesFilter<$PrismaModel = never> =
| Prisma.PatchUndefined<
Prisma.Either<Required<JsonWithAggregatesFilterBase<$PrismaModel>>, Exclude<keyof Required<JsonWithAggregatesFilterBase<$PrismaModel>>, 'path'>>,
Required<JsonWithAggregatesFilterBase<$PrismaModel>>
>
| Prisma.OptionalFlat<Omit<Required<JsonWithAggregatesFilterBase<$PrismaModel>>, 'path'>>
export type JsonWithAggregatesFilterBase<$PrismaModel = never> = {
equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
path?: string[]
mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel>
string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
_count?: Prisma.NestedIntFilter<$PrismaModel>
_min?: Prisma.NestedJsonFilter<$PrismaModel>
_max?: Prisma.NestedJsonFilter<$PrismaModel>
}
export type NestedStringFilter<$PrismaModel = never> = {
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>;
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>;
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>;
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>;
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>;
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>;
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>;
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>;
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>;
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>;
not?: Prisma.NestedStringFilter<$PrismaModel> | string;
};
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
not?: Prisma.NestedStringFilter<$PrismaModel> | string
}
export type NestedBoolFilter<$PrismaModel = never> = {
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>;
not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean;
};
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean
}
export type NestedStringNullableFilter<$PrismaModel = never> = {
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null;
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null;
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null;
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>;
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>;
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>;
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>;
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>;
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>;
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>;
not?: Prisma.NestedStringNullableFilter<$PrismaModel> | string | null;
};
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
not?: Prisma.NestedStringNullableFilter<$PrismaModel> | string | null
}
export type NestedDateTimeFilter<$PrismaModel = never> = {
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>;
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>;
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
not?: Prisma.NestedDateTimeFilter<$PrismaModel> | Date | string;
};
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
not?: Prisma.NestedDateTimeFilter<$PrismaModel> | Date | string
}
export type NestedIntNullableFilter<$PrismaModel = never> = {
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null;
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null;
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null;
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>;
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>;
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>;
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>;
not?: Prisma.NestedIntNullableFilter<$PrismaModel> | number | null;
};
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
not?: Prisma.NestedIntNullableFilter<$PrismaModel> | number | null
}
export type NestedStringWithAggregatesFilter<$PrismaModel = never> = {
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>;
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>;
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>;
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>;
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>;
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>;
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>;
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>;
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>;
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>;
not?: Prisma.NestedStringWithAggregatesFilter<$PrismaModel> | string;
_count?: Prisma.NestedIntFilter<$PrismaModel>;
_min?: Prisma.NestedStringFilter<$PrismaModel>;
_max?: Prisma.NestedStringFilter<$PrismaModel>;
};
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
not?: Prisma.NestedStringWithAggregatesFilter<$PrismaModel> | string
_count?: Prisma.NestedIntFilter<$PrismaModel>
_min?: Prisma.NestedStringFilter<$PrismaModel>
_max?: Prisma.NestedStringFilter<$PrismaModel>
}
export type NestedIntFilter<$PrismaModel = never> = {
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>;
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>;
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>;
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>;
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>;
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>;
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>;
not?: Prisma.NestedIntFilter<$PrismaModel> | number;
};
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
not?: Prisma.NestedIntFilter<$PrismaModel> | number
}
export type NestedBoolWithAggregatesFilter<$PrismaModel = never> = {
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>;
not?: Prisma.NestedBoolWithAggregatesFilter<$PrismaModel> | boolean;
_count?: Prisma.NestedIntFilter<$PrismaModel>;
_min?: Prisma.NestedBoolFilter<$PrismaModel>;
_max?: Prisma.NestedBoolFilter<$PrismaModel>;
};
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
not?: Prisma.NestedBoolWithAggregatesFilter<$PrismaModel> | boolean
_count?: Prisma.NestedIntFilter<$PrismaModel>
_min?: Prisma.NestedBoolFilter<$PrismaModel>
_max?: Prisma.NestedBoolFilter<$PrismaModel>
}
export type NestedStringNullableWithAggregatesFilter<$PrismaModel = never> = {
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null;
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null;
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null;
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>;
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>;
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>;
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>;
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>;
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>;
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>;
not?: Prisma.NestedStringNullableWithAggregatesFilter<$PrismaModel> | string | null;
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>;
_min?: Prisma.NestedStringNullableFilter<$PrismaModel>;
_max?: Prisma.NestedStringNullableFilter<$PrismaModel>;
};
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
not?: Prisma.NestedStringNullableWithAggregatesFilter<$PrismaModel> | string | null
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
_min?: Prisma.NestedStringNullableFilter<$PrismaModel>
_max?: Prisma.NestedStringNullableFilter<$PrismaModel>
}
export type NestedDateTimeWithAggregatesFilter<$PrismaModel = never> = {
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>;
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>;
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
not?: Prisma.NestedDateTimeWithAggregatesFilter<$PrismaModel> | Date | string;
_count?: Prisma.NestedIntFilter<$PrismaModel>;
_min?: Prisma.NestedDateTimeFilter<$PrismaModel>;
_max?: Prisma.NestedDateTimeFilter<$PrismaModel>;
};
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
not?: Prisma.NestedDateTimeWithAggregatesFilter<$PrismaModel> | Date | string
_count?: Prisma.NestedIntFilter<$PrismaModel>
_min?: Prisma.NestedDateTimeFilter<$PrismaModel>
_max?: Prisma.NestedDateTimeFilter<$PrismaModel>
}
export type NestedIntNullableWithAggregatesFilter<$PrismaModel = never> = {
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null;
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null;
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null;
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>;
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>;
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>;
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>;
not?: Prisma.NestedIntNullableWithAggregatesFilter<$PrismaModel> | number | null;
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>;
_avg?: Prisma.NestedFloatNullableFilter<$PrismaModel>;
_sum?: Prisma.NestedIntNullableFilter<$PrismaModel>;
_min?: Prisma.NestedIntNullableFilter<$PrismaModel>;
_max?: Prisma.NestedIntNullableFilter<$PrismaModel>;
};
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
not?: Prisma.NestedIntNullableWithAggregatesFilter<$PrismaModel> | number | null
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
_avg?: Prisma.NestedFloatNullableFilter<$PrismaModel>
_sum?: Prisma.NestedIntNullableFilter<$PrismaModel>
_min?: Prisma.NestedIntNullableFilter<$PrismaModel>
_max?: Prisma.NestedIntNullableFilter<$PrismaModel>
}
export type NestedFloatNullableFilter<$PrismaModel = never> = {
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel> | null;
in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> | null;
notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> | null;
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>;
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>;
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>;
gte?: number | Prisma.FloatFieldRefInput<$PrismaModel>;
not?: Prisma.NestedFloatNullableFilter<$PrismaModel> | number | null;
};
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel> | null
in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> | null
notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> | null
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
gte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
not?: Prisma.NestedFloatNullableFilter<$PrismaModel> | number | null
}
export type NestedDateTimeNullableFilter<$PrismaModel = never> = {
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null;
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null;
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null;
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
not?: Prisma.NestedDateTimeNullableFilter<$PrismaModel> | Date | string | null;
};
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
not?: Prisma.NestedDateTimeNullableFilter<$PrismaModel> | Date | string | null
}
export type NestedDateTimeNullableWithAggregatesFilter<$PrismaModel = never> = {
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null;
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null;
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null;
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>;
not?: Prisma.NestedDateTimeNullableWithAggregatesFilter<$PrismaModel> | Date | string | null;
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>;
_min?: Prisma.NestedDateTimeNullableFilter<$PrismaModel>;
_max?: Prisma.NestedDateTimeNullableFilter<$PrismaModel>;
};
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
not?: Prisma.NestedDateTimeNullableWithAggregatesFilter<$PrismaModel> | Date | string | null
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
_min?: Prisma.NestedDateTimeNullableFilter<$PrismaModel>
_max?: Prisma.NestedDateTimeNullableFilter<$PrismaModel>
}
export type NestedIntWithAggregatesFilter<$PrismaModel = never> = {
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>;
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>;
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>;
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>;
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>;
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>;
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>;
not?: Prisma.NestedIntWithAggregatesFilter<$PrismaModel> | number;
_count?: Prisma.NestedIntFilter<$PrismaModel>;
_avg?: Prisma.NestedFloatFilter<$PrismaModel>;
_sum?: Prisma.NestedIntFilter<$PrismaModel>;
_min?: Prisma.NestedIntFilter<$PrismaModel>;
_max?: Prisma.NestedIntFilter<$PrismaModel>;
};
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
not?: Prisma.NestedIntWithAggregatesFilter<$PrismaModel> | number
_count?: Prisma.NestedIntFilter<$PrismaModel>
_avg?: Prisma.NestedFloatFilter<$PrismaModel>
_sum?: Prisma.NestedIntFilter<$PrismaModel>
_min?: Prisma.NestedIntFilter<$PrismaModel>
_max?: Prisma.NestedIntFilter<$PrismaModel>
}
export type NestedFloatFilter<$PrismaModel = never> = {
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel>;
in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel>;
notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel>;
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>;
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>;
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>;
gte?: number | Prisma.FloatFieldRefInput<$PrismaModel>;
not?: Prisma.NestedFloatFilter<$PrismaModel> | number;
};
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel>
in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel>
notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel>
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
gte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
not?: Prisma.NestedFloatFilter<$PrismaModel> | number
}
export type NestedJsonFilter<$PrismaModel = never> =
| Prisma.PatchUndefined<
Prisma.Either<Required<NestedJsonFilterBase<$PrismaModel>>, Exclude<keyof Required<NestedJsonFilterBase<$PrismaModel>>, 'path'>>,
Required<NestedJsonFilterBase<$PrismaModel>>
>
| Prisma.OptionalFlat<Omit<Required<NestedJsonFilterBase<$PrismaModel>>, 'path'>>
export type NestedJsonFilterBase<$PrismaModel = never> = {
equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
path?: string[]
mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel>
string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
}
+9 -6
View File
@@ -1,12 +1,15 @@
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
/* eslint-disable */
// biome-ignore-all lint: generated file
// @ts-nocheck
// @ts-nocheck
/*
* This file exports all enum related types from the schema.
*
* 🟢 You can import this file directly.
*/
* This file exports all enum related types from the schema.
*
* 🟢 You can import this file directly.
*/
// This file is empty because there are no enums in the schema.
export {};
export {}
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
@@ -1,7 +1,8 @@
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
/* eslint-disable */
// biome-ignore-all lint: generated file
// @ts-nocheck
// @ts-nocheck
/*
* WARNING: This is an internal file that is subject to change!
*
@@ -14,266 +15,297 @@
* model files in the `model` directory!
*/
import * as runtime from '@prisma/client/runtime/index-browser';
import * as runtime from "@prisma/client/runtime/index-browser"
export type * from '../models.ts';
export type * from './prismaNamespace.ts';
export type * from '../models.ts'
export type * from './prismaNamespace.ts'
export const Decimal = runtime.Decimal
export const Decimal = runtime.Decimal;
export const NullTypes = {
DbNull: runtime.NullTypes.DbNull as new (secret: never) => typeof runtime.DbNull,
JsonNull: runtime.NullTypes.JsonNull as new (secret: never) => typeof runtime.JsonNull,
AnyNull: runtime.NullTypes.AnyNull as new (secret: never) => typeof runtime.AnyNull
};
DbNull: runtime.NullTypes.DbNull as (new (secret: never) => typeof runtime.DbNull),
JsonNull: runtime.NullTypes.JsonNull as (new (secret: never) => typeof runtime.JsonNull),
AnyNull: runtime.NullTypes.AnyNull as (new (secret: never) => typeof runtime.AnyNull),
}
/**
* Helper for filtering JSON entries that have `null` on the database (empty on the db)
*
* @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
*/
export const DbNull = runtime.DbNull;
export const DbNull = runtime.DbNull
/**
* Helper for filtering JSON entries that have JSON `null` values (not empty on the db)
*
* @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
*/
export const JsonNull = runtime.JsonNull;
export const JsonNull = runtime.JsonNull
/**
* Helper for filtering JSON entries that are `Prisma.DbNull` or `Prisma.JsonNull`
*
* @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
*/
export const AnyNull = runtime.AnyNull;
export const AnyNull = runtime.AnyNull
export const ModelName = {
User: 'User',
Profile: 'Profile',
Address: 'Address',
Session: 'Session',
Account: 'Account',
UserRole: 'UserRole',
Verification: 'Verification',
Proclamation: 'Proclamation',
UserProclamations: 'UserProclamations',
SolfeggioFrequency: 'SolfeggioFrequency',
ProclamationCategory: 'ProclamationCategory',
ProclamationCategorySubscriptionLevel: 'ProclamationCategorySubscriptionLevel',
LicenseKey: 'LicenseKey',
ApiKey: 'ApiKey',
SubscriptionLevel: 'SubscriptionLevel'
} as const;
User: 'User',
Profile: 'Profile',
Address: 'Address',
Session: 'Session',
Account: 'Account',
UserRole: 'UserRole',
Verification: 'Verification',
Proclamation: 'Proclamation',
UserProclamations: 'UserProclamations',
SolfeggioFrequency: 'SolfeggioFrequency',
ProclamationCategory: 'ProclamationCategory',
ProclamationCategorySubscriptionLevel: 'ProclamationCategorySubscriptionLevel',
LicenseKey: 'LicenseKey',
ApiKey: 'ApiKey',
SubscriptionLevel: 'SubscriptionLevel',
ColorPalette: 'ColorPalette'
} as const
export type ModelName = (typeof ModelName)[keyof typeof ModelName];
export type ModelName = (typeof ModelName)[keyof typeof ModelName]
/*
* Enums
*/
export const TransactionIsolationLevel = runtime.makeStrictEnum({
ReadUncommitted: 'ReadUncommitted',
ReadCommitted: 'ReadCommitted',
RepeatableRead: 'RepeatableRead',
Serializable: 'Serializable'
} as const);
ReadUncommitted: 'ReadUncommitted',
ReadCommitted: 'ReadCommitted',
RepeatableRead: 'RepeatableRead',
Serializable: 'Serializable'
} as const)
export type TransactionIsolationLevel = (typeof TransactionIsolationLevel)[keyof typeof TransactionIsolationLevel]
export type TransactionIsolationLevel =
(typeof TransactionIsolationLevel)[keyof typeof TransactionIsolationLevel];
export const UserScalarFieldEnum = {
id: 'id',
name: 'name',
email: 'email',
emailVerified: 'emailVerified',
image: 'image',
createdAt: 'createdAt',
updatedAt: 'updatedAt',
roleId: 'roleId'
} as const;
id: 'id',
name: 'name',
email: 'email',
emailVerified: 'emailVerified',
image: 'image',
createdAt: 'createdAt',
updatedAt: 'updatedAt',
roleId: 'roleId'
} as const
export type UserScalarFieldEnum = (typeof UserScalarFieldEnum)[keyof typeof UserScalarFieldEnum]
export type UserScalarFieldEnum = (typeof UserScalarFieldEnum)[keyof typeof UserScalarFieldEnum];
export const ProfileScalarFieldEnum = {
id: 'id',
userId: 'userId',
firstName: 'firstName',
lastName: 'lastName',
phoneNumber: 'phoneNumber',
ghlContactId: 'ghlContactId'
} as const;
id: 'id',
userId: 'userId',
firstName: 'firstName',
lastName: 'lastName',
phoneNumber: 'phoneNumber',
ghlContactId: 'ghlContactId'
} as const
export type ProfileScalarFieldEnum = (typeof ProfileScalarFieldEnum)[keyof typeof ProfileScalarFieldEnum]
export type ProfileScalarFieldEnum =
(typeof ProfileScalarFieldEnum)[keyof typeof ProfileScalarFieldEnum];
export const AddressScalarFieldEnum = {
id: 'id',
profileId: 'profileId',
street: 'street',
city: 'city',
state: 'state',
postalCode: 'postalCode',
country: 'country',
type: 'type',
isDefaultMailing: 'isDefaultMailing',
isDefaultBilling: 'isDefaultBilling',
isDefaultShipping: 'isDefaultShipping'
} as const;
id: 'id',
profileId: 'profileId',
street: 'street',
city: 'city',
state: 'state',
postalCode: 'postalCode',
country: 'country',
type: 'type',
isDefaultMailing: 'isDefaultMailing',
isDefaultBilling: 'isDefaultBilling',
isDefaultShipping: 'isDefaultShipping'
} as const
export type AddressScalarFieldEnum = (typeof AddressScalarFieldEnum)[keyof typeof AddressScalarFieldEnum]
export type AddressScalarFieldEnum =
(typeof AddressScalarFieldEnum)[keyof typeof AddressScalarFieldEnum];
export const SessionScalarFieldEnum = {
id: 'id',
expiresAt: 'expiresAt',
token: 'token',
createdAt: 'createdAt',
updatedAt: 'updatedAt',
ipAddress: 'ipAddress',
userAgent: 'userAgent',
userId: 'userId'
} as const;
id: 'id',
expiresAt: 'expiresAt',
token: 'token',
createdAt: 'createdAt',
updatedAt: 'updatedAt',
ipAddress: 'ipAddress',
userAgent: 'userAgent',
userId: 'userId'
} as const
export type SessionScalarFieldEnum = (typeof SessionScalarFieldEnum)[keyof typeof SessionScalarFieldEnum]
export type SessionScalarFieldEnum =
(typeof SessionScalarFieldEnum)[keyof typeof SessionScalarFieldEnum];
export const AccountScalarFieldEnum = {
id: 'id',
accountId: 'accountId',
providerId: 'providerId',
userId: 'userId',
accessToken: 'accessToken',
refreshToken: 'refreshToken',
idToken: 'idToken',
accessTokenExpiresAt: 'accessTokenExpiresAt',
refreshTokenExpiresAt: 'refreshTokenExpiresAt',
scope: 'scope',
password: 'password',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
} as const;
id: 'id',
accountId: 'accountId',
providerId: 'providerId',
userId: 'userId',
accessToken: 'accessToken',
refreshToken: 'refreshToken',
idToken: 'idToken',
accessTokenExpiresAt: 'accessTokenExpiresAt',
refreshTokenExpiresAt: 'refreshTokenExpiresAt',
scope: 'scope',
password: 'password',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
} as const
export type AccountScalarFieldEnum = (typeof AccountScalarFieldEnum)[keyof typeof AccountScalarFieldEnum]
export type AccountScalarFieldEnum =
(typeof AccountScalarFieldEnum)[keyof typeof AccountScalarFieldEnum];
export const UserRoleScalarFieldEnum = {
id: 'id',
name: 'name'
} as const;
id: 'id',
name: 'name'
} as const
export type UserRoleScalarFieldEnum = (typeof UserRoleScalarFieldEnum)[keyof typeof UserRoleScalarFieldEnum]
export type UserRoleScalarFieldEnum =
(typeof UserRoleScalarFieldEnum)[keyof typeof UserRoleScalarFieldEnum];
export const VerificationScalarFieldEnum = {
id: 'id',
identifier: 'identifier',
value: 'value',
expiresAt: 'expiresAt',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
} as const;
id: 'id',
identifier: 'identifier',
value: 'value',
expiresAt: 'expiresAt',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
} as const
export type VerificationScalarFieldEnum = (typeof VerificationScalarFieldEnum)[keyof typeof VerificationScalarFieldEnum]
export type VerificationScalarFieldEnum =
(typeof VerificationScalarFieldEnum)[keyof typeof VerificationScalarFieldEnum];
export const ProclamationScalarFieldEnum = {
id: 'id',
name: 'name',
content: 'content',
solfeggioFrequencyId: 'solfeggioFrequencyId',
categoryId: 'categoryId',
subscriptionLevelId: 'subscriptionLevelId'
} as const;
id: 'id',
name: 'name',
content: 'content',
solfeggioFrequencyId: 'solfeggioFrequencyId',
categoryId: 'categoryId',
subscriptionLevelId: 'subscriptionLevelId'
} as const
export type ProclamationScalarFieldEnum = (typeof ProclamationScalarFieldEnum)[keyof typeof ProclamationScalarFieldEnum]
export type ProclamationScalarFieldEnum =
(typeof ProclamationScalarFieldEnum)[keyof typeof ProclamationScalarFieldEnum];
export const UserProclamationsScalarFieldEnum = {
userId: 'userId',
proclamationId: 'proclamationId',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
} as const;
userId: 'userId',
proclamationId: 'proclamationId',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
} as const
export type UserProclamationsScalarFieldEnum = (typeof UserProclamationsScalarFieldEnum)[keyof typeof UserProclamationsScalarFieldEnum]
export type UserProclamationsScalarFieldEnum =
(typeof UserProclamationsScalarFieldEnum)[keyof typeof UserProclamationsScalarFieldEnum];
export const SolfeggioFrequencyScalarFieldEnum = {
id: 'id',
name: 'name',
value: 'value'
} as const;
id: 'id',
name: 'name',
value: 'value'
} as const
export type SolfeggioFrequencyScalarFieldEnum = (typeof SolfeggioFrequencyScalarFieldEnum)[keyof typeof SolfeggioFrequencyScalarFieldEnum]
export type SolfeggioFrequencyScalarFieldEnum =
(typeof SolfeggioFrequencyScalarFieldEnum)[keyof typeof SolfeggioFrequencyScalarFieldEnum];
export const ProclamationCategoryScalarFieldEnum = {
id: 'id',
name: 'name',
sortOrder: 'sortOrder',
parentId: 'parentId'
} as const;
id: 'id',
name: 'name',
sortOrder: 'sortOrder',
parentId: 'parentId'
} as const
export type ProclamationCategoryScalarFieldEnum = (typeof ProclamationCategoryScalarFieldEnum)[keyof typeof ProclamationCategoryScalarFieldEnum]
export type ProclamationCategoryScalarFieldEnum =
(typeof ProclamationCategoryScalarFieldEnum)[keyof typeof ProclamationCategoryScalarFieldEnum];
export const ProclamationCategorySubscriptionLevelScalarFieldEnum = {
categoryId: 'categoryId',
subscriptionLevelId: 'subscriptionLevelId'
} as const;
categoryId: 'categoryId',
subscriptionLevelId: 'subscriptionLevelId'
} as const
export type ProclamationCategorySubscriptionLevelScalarFieldEnum = (typeof ProclamationCategorySubscriptionLevelScalarFieldEnum)[keyof typeof ProclamationCategorySubscriptionLevelScalarFieldEnum]
export type ProclamationCategorySubscriptionLevelScalarFieldEnum =
(typeof ProclamationCategorySubscriptionLevelScalarFieldEnum)[keyof typeof ProclamationCategorySubscriptionLevelScalarFieldEnum];
export const LicenseKeyScalarFieldEnum = {
id: 'id',
key: 'key',
active: 'active',
level: 'level',
userId: 'userId'
} as const;
id: 'id',
key: 'key',
active: 'active',
level: 'level',
userId: 'userId'
} as const
export type LicenseKeyScalarFieldEnum = (typeof LicenseKeyScalarFieldEnum)[keyof typeof LicenseKeyScalarFieldEnum]
export type LicenseKeyScalarFieldEnum =
(typeof LicenseKeyScalarFieldEnum)[keyof typeof LicenseKeyScalarFieldEnum];
export const ApiKeyScalarFieldEnum = {
id: 'id',
keyPrefix: 'keyPrefix',
keyHash: 'keyHash',
createdAt: 'createdAt',
expiresAt: 'expiresAt',
revokedAt: 'revokedAt'
} as const;
id: 'id',
keyPrefix: 'keyPrefix',
keyHash: 'keyHash',
createdAt: 'createdAt',
expiresAt: 'expiresAt',
revokedAt: 'revokedAt'
} as const
export type ApiKeyScalarFieldEnum = (typeof ApiKeyScalarFieldEnum)[keyof typeof ApiKeyScalarFieldEnum]
export type ApiKeyScalarFieldEnum =
(typeof ApiKeyScalarFieldEnum)[keyof typeof ApiKeyScalarFieldEnum];
export const SubscriptionLevelScalarFieldEnum = {
id: 'id',
name: 'name',
description: 'description'
} as const;
id: 'id',
name: 'name',
description: 'description'
} as const
export type SubscriptionLevelScalarFieldEnum = (typeof SubscriptionLevelScalarFieldEnum)[keyof typeof SubscriptionLevelScalarFieldEnum]
export const ColorPaletteScalarFieldEnum = {
solfeggioFrequencyId: 'solfeggioFrequencyId',
colors: 'colors'
} as const
export type ColorPaletteScalarFieldEnum = (typeof ColorPaletteScalarFieldEnum)[keyof typeof ColorPaletteScalarFieldEnum]
export type SubscriptionLevelScalarFieldEnum =
(typeof SubscriptionLevelScalarFieldEnum)[keyof typeof SubscriptionLevelScalarFieldEnum];
export const SortOrder = {
asc: 'asc',
desc: 'desc'
} as const;
asc: 'asc',
desc: 'desc'
} as const
export type SortOrder = (typeof SortOrder)[keyof typeof SortOrder]
export const JsonNullValueInput = {
JsonNull: JsonNull
} as const
export type JsonNullValueInput = (typeof JsonNullValueInput)[keyof typeof JsonNullValueInput]
export type SortOrder = (typeof SortOrder)[keyof typeof SortOrder];
export const QueryMode = {
default: 'default',
insensitive: 'insensitive'
} as const;
default: 'default',
insensitive: 'insensitive'
} as const
export type QueryMode = (typeof QueryMode)[keyof typeof QueryMode]
export type QueryMode = (typeof QueryMode)[keyof typeof QueryMode];
export const NullsOrder = {
first: 'first',
last: 'last'
} as const;
first: 'first',
last: 'last'
} as const
export type NullsOrder = (typeof NullsOrder)[keyof typeof NullsOrder]
export const JsonNullValueFilter = {
DbNull: DbNull,
JsonNull: JsonNull,
AnyNull: AnyNull
} as const
export type JsonNullValueFilter = (typeof JsonNullValueFilter)[keyof typeof JsonNullValueFilter]
export type NullsOrder = (typeof NullsOrder)[keyof typeof NullsOrder];
+19 -17
View File
@@ -1,25 +1,27 @@
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
/* eslint-disable */
// biome-ignore-all lint: generated file
// @ts-nocheck
// @ts-nocheck
/*
* This is a barrel export file for all models and their related types.
*
* 🟢 You can import this file directly.
*/
export type * from './models/User.ts';
export type * from './models/Profile.ts';
export type * from './models/Address.ts';
export type * from './models/Session.ts';
export type * from './models/Account.ts';
export type * from './models/UserRole.ts';
export type * from './models/Verification.ts';
export type * from './models/Proclamation.ts';
export type * from './models/UserProclamations.ts';
export type * from './models/SolfeggioFrequency.ts';
export type * from './models/ProclamationCategory.ts';
export type * from './models/ProclamationCategorySubscriptionLevel.ts';
export type * from './models/LicenseKey.ts';
export type * from './models/ApiKey.ts';
export type * from './models/SubscriptionLevel.ts';
export type * from './commonInputTypes.ts';
export type * from './models/User.ts'
export type * from './models/Profile.ts'
export type * from './models/Address.ts'
export type * from './models/Session.ts'
export type * from './models/Account.ts'
export type * from './models/UserRole.ts'
export type * from './models/Verification.ts'
export type * from './models/Proclamation.ts'
export type * from './models/UserProclamations.ts'
export type * from './models/SolfeggioFrequency.ts'
export type * from './models/ProclamationCategory.ts'
export type * from './models/ProclamationCategorySubscriptionLevel.ts'
export type * from './models/LicenseKey.ts'
export type * from './models/ApiKey.ts'
export type * from './models/SubscriptionLevel.ts'
export type * from './models/ColorPalette.ts'
export type * from './commonInputTypes.ts'
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+64
View File
@@ -0,0 +1,64 @@
import { error } from '@sveltejs/kit';
export const MAX_JSON_BODY_BYTES = 64 * 1024;
export function jsonOk(data: unknown, status = 200): Response {
return new Response(JSON.stringify(data), {
status,
headers: { 'content-type': 'application/json' }
});
}
export function jsonError(
status: number,
message: string,
headers?: Record<string, string>
): Response {
return new Response(JSON.stringify({ message }), {
status,
headers: { 'content-type': 'application/json', ...headers }
});
}
/** Read and parse a JSON request body with a size cap. Throws 413 for
* oversized bodies and 400 for invalid JSON / wrong content type. */
export async function readJsonBody(request: Request): Promise<unknown> {
const contentType = request.headers.get('content-type') ?? '';
if (!contentType.includes('application/json')) {
throw error(400, 'content-type must be application/json');
}
const contentLength = Number(request.headers.get('content-length') ?? 0);
if (contentLength > MAX_JSON_BODY_BYTES) {
throw error(413, 'request body too large');
}
const raw = await request.text();
if (raw.length === 0) {
throw error(400, 'request body is required');
}
if (raw.length > MAX_JSON_BODY_BYTES) {
throw error(413, 'request body too large');
}
try {
return JSON.parse(raw);
} catch {
throw error(400, 'invalid JSON body');
}
}
/** Build a 429 response with Retry-After set in seconds. */
export function rateLimited(retryAfterMs: number): Response {
const retryAfterSeconds = Math.max(1, Math.ceil(retryAfterMs / 1000));
return jsonError(429, 'rate limit exceeded', { 'retry-after': String(retryAfterSeconds) });
}
export function clientIp(request: Request): string {
const fwd = request.headers.get('x-forwarded-for');
if (fwd) {
const first = fwd.split(',')[0]?.trim();
if (first) return first;
}
return request.headers.get('x-real-ip') ?? 'unknown';
}
+40
View File
@@ -0,0 +1,40 @@
import { describe, it, expect, beforeEach } from 'vitest';
import { rateLimit, _clearRateLimits } from './v2-rate-limit';
describe('rateLimit', () => {
beforeEach(() => {
_clearRateLimits();
});
it('allows requests up to the limit', () => {
for (let i = 0; i < 3; i++) {
const r = rateLimit({ key: 'k', limit: 3, windowMs: 60_000, now: 1000 });
expect(r.ok).toBe(true);
}
});
it('rejects once the limit is exceeded and reports Retry-After', () => {
for (let i = 0; i < 3; i++) {
rateLimit({ key: 'k', limit: 3, windowMs: 60_000, now: 1000 });
}
const r = rateLimit({ key: 'k', limit: 3, windowMs: 60_000, now: 1000 });
expect(r.ok).toBe(false);
expect(r.retryAfterMs).toBeGreaterThan(0);
});
it('treats keys independently', () => {
rateLimit({ key: 'a', limit: 1, windowMs: 60_000, now: 1000 });
expect(rateLimit({ key: 'a', limit: 1, windowMs: 60_000, now: 1000 }).ok).toBe(false);
expect(rateLimit({ key: 'b', limit: 1, windowMs: 60_000, now: 1000 }).ok).toBe(true);
});
it('lets the window expire before allowing again', () => {
for (let i = 0; i < 2; i++) {
rateLimit({ key: 'k', limit: 2, windowMs: 10_000, now: 1000 });
}
expect(rateLimit({ key: 'k', limit: 2, windowMs: 10_000, now: 1000 }).ok).toBe(false);
expect(rateLimit({ key: 'k', limit: 2, windowMs: 10_000, now: 1000 + 10_000 + 1 }).ok).toBe(
true
);
});
});
+36
View File
@@ -0,0 +1,36 @@
// Simple in-memory sliding-window rate limiter, keyed per process. Suitable
// for per-IP / per-email limits on v2 routes; for multi-instance deployments
// this should move to shared storage (e.g. the database or Redis).
type Bucket = { timestamps: number[] };
const buckets = new Map<string, Bucket>();
export function rateLimit(opts: { key: string; limit: number; windowMs: number; now?: number }): {
ok: boolean;
retryAfterMs: number;
} {
const now = opts.now ?? Date.now();
let bucket = buckets.get(opts.key);
if (!bucket) {
bucket = { timestamps: [] };
buckets.set(opts.key, bucket);
}
bucket.timestamps = bucket.timestamps.filter((t) => now - t < opts.windowMs);
if (bucket.timestamps.length >= opts.limit) {
const oldest = bucket.timestamps[0];
const retryAfterMs = Math.max(0, oldest + opts.windowMs - now);
return { ok: false, retryAfterMs };
}
bucket.timestamps.push(now);
return { ok: true, retryAfterMs: 0 };
}
/** Test hook: clears all rate-limit buckets. */
export function _clearRateLimits(): void {
buckets.clear();
}
+188
View File
@@ -0,0 +1,188 @@
import { describe, it, expect } from 'vitest';
import {
CANONICAL_FREQUENCIES,
CANONICAL_PALETTES,
canonicalIdForFrequency,
serializeCategory,
serializeColorPalette,
serializeLicense,
serializeProclamation,
serializeSubscriptionLevel
} from './v2-serializers';
describe('canonicalIdForFrequency', () => {
it('maps Hz values to canonical ids via the kiosk frequencyIdForHz map', () => {
expect(canonicalIdForFrequency({ value: 174 })).toBe(1);
expect(canonicalIdForFrequency({ value: 285 })).toBe(1);
expect(canonicalIdForFrequency({ value: 396 })).toBe(2);
expect(canonicalIdForFrequency({ value: 417 })).toBe(3);
expect(canonicalIdForFrequency({ value: 432 })).toBe(4);
expect(canonicalIdForFrequency({ value: 528 })).toBe(5);
expect(canonicalIdForFrequency({ value: 639 })).toBe(6);
expect(canonicalIdForFrequency({ value: 741 })).toBe(7);
expect(canonicalIdForFrequency({ value: 852 })).toBe(8);
expect(canonicalIdForFrequency({ value: 963 })).toBe(9);
});
it('returns null for frequencies with no canonical id (e.g. 936 Hz)', () => {
expect(canonicalIdForFrequency({ value: 936 })).toBeNull();
});
});
describe('CANONICAL_FREQUENCIES', () => {
it('emits exactly the 9 canonical frequencies with non-zero ids', () => {
expect(CANONICAL_FREQUENCIES).toHaveLength(9);
for (const freq of CANONICAL_FREQUENCIES) {
expect(freq.id).toBeGreaterThan(0);
expect(typeof freq.name).toBe('string');
expect(canonicalIdForFrequency({ value: freq.value })).toBe(freq.id);
}
});
it('ships a 7-color palette for every canonical id', () => {
for (const freq of CANONICAL_FREQUENCIES) {
const colors = CANONICAL_PALETTES[freq.id];
expect(colors).toBeDefined();
expect(colors).toHaveLength(7);
for (const c of colors) {
expect(c).toMatch(/^#([0-9A-Fa-f]{6})$/);
}
}
});
});
describe('serializeProclamation', () => {
const root396 = { id: 7, name: 'Root', value: 396 };
const crown936 = { id: 1, name: 'Crown', value: 936 };
const solarPlexus528 = { id: 5, name: 'Solar Plexus', value: 528 };
const base = {
id: 'b40fdcb9-703c-420e-af32-a081964c6f08',
name: 'Peace & Relaxation',
content: '<p>The text content, HTML formatted</p>',
categoryId: 5,
subscriptionLevelId: 1
};
it('derives solfeggioFrequencyId from the Hz value, not the DB id', () => {
// DB row id 7 is 396 Hz -> canonical id 2.
const record = serializeProclamation({
...base,
solfeggioFrequency: root396
});
expect(record).toEqual({
...base,
solfeggioFrequencyId: 2
});
});
it('returns null and drops proclamations whose frequency has no canonical id (936 Hz)', () => {
const record = serializeProclamation({
...base,
solfeggioFrequency: crown936
});
expect(record).toBeNull();
});
it('passes through a null subscriptionLevelId (kiosk treats as level 1)', () => {
const record = serializeProclamation({
...base,
subscriptionLevelId: null,
solfeggioFrequency: solarPlexus528
});
expect(record?.subscriptionLevelId).toBeNull();
});
it('embeds a 7-color palette when provided', () => {
const palette = ['#32CD32', '#3CB371', '#90EE90', '#98FB98', '#ADFFA9', '#C8FFD2', '#F0FFF0'];
const record = serializeProclamation(
{
...base,
solfeggioFrequency: solarPlexus528
},
palette
);
expect(record?.colorPalette).toEqual(palette);
});
it('omits colorPalette when not provided', () => {
const record = serializeProclamation({
...base,
solfeggioFrequency: solarPlexus528
});
expect(record?.colorPalette).toBeUndefined();
expect(Object.keys(record ?? {})).not.toContain('colorPalette');
});
});
describe('serializeCategory', () => {
it('keeps parentId null for root categories', () => {
expect(serializeCategory({ id: 4, name: 'Spiritual', sortOrder: 0, parentId: null })).toEqual({
id: 4,
name: 'Spiritual',
sortOrder: 0,
parentId: null
});
});
it('keeps parentId int for children', () => {
expect(serializeCategory({ id: 5, name: 'General', sortOrder: 0, parentId: 4 })).toEqual({
id: 5,
name: 'General',
sortOrder: 0,
parentId: 4
});
});
});
describe('serializeLicense', () => {
it('returns subscription_level as an object when the level row exists', () => {
const result = serializeLicense({
key: 'XXXX-XXXX-XXXX-XXXX',
emailAddress: 'user@example.com',
levelName: 'Advanced',
level: { id: 2, name: 'Advanced', description: 'General + Specific' }
});
expect(result).toEqual({
key: 'XXXX-XXXX-XXXX-XXXX',
email_address: 'user@example.com',
subscription_level: { id: 2, name: 'Advanced', description: 'General + Specific' }
});
});
it('falls back to a structurally consistent object when no level row matches', () => {
const result = serializeLicense({
key: 'XXXX-XXXX-XXXX-XXXX',
emailAddress: 'user@example.com',
levelName: 'SomeCustomLevel',
level: null
});
expect(result).toEqual({
key: 'XXXX-XXXX-XXXX-XXXX',
email_address: 'user@example.com',
subscription_level: { id: null, name: 'SomeCustomLevel', description: null }
});
});
});
describe('serializeSubscriptionLevel', () => {
it('maps rows to {id, name, description}', () => {
expect(
serializeSubscriptionLevel({ id: 1, name: 'Basic', description: 'General only' })
).toEqual({
id: 1,
name: 'Basic',
description: 'General only'
});
});
});
describe('serializeColorPalette', () => {
it('maps rows to {solfeggioFrequencyId, colors}', () => {
const colors = ['#8B6914', '#B8860B', '#DAA520', '#E8B64C', '#FFD700', '#FFE9A8', '#FFF4CC'];
expect(serializeColorPalette({ solfeggioFrequencyId: 1, colors })).toEqual({
solfeggioFrequencyId: 1,
colors
});
});
});
+161
View File
@@ -0,0 +1,161 @@
// Canonical solfeggio id <- Hz, mirroring the kiosk's `frequencyIdForHz()`
// map (radiantwave-rebuild src/audio/audio_downloader.cpp). v2 must emit these
// canonical ids (1-9), never the portal DB autoincrement ids, because
// proclamations and color palettes on the kiosk are keyed by them.
export const CANONICAL_ID_FOR_HZ: Record<number, number> = {
174: 1,
285: 1,
396: 2,
417: 3,
432: 4,
528: 5,
639: 6,
741: 7,
852: 8,
963: 9
};
// The 9 canonical frequencies exactly as the kiosk expects from
// GET /frequencies (id 1-9, non-zero, `value` recognized by frequencyIdForHz).
export const CANONICAL_FREQUENCIES: { id: number; name: string; value: number }[] = [
{ id: 1, name: 'Grounding / Relief', value: 174 },
{ id: 2, name: 'Root', value: 396 },
{ id: 3, name: 'Sacral', value: 417 },
{ id: 4, name: 'Clarity / Wellbeing', value: 432 },
{ id: 5, name: 'Solar Plexus', value: 528 },
{ id: 6, name: 'Heart', value: 639 },
{ id: 7, name: 'Throat', value: 741 },
{ id: 8, name: '3rd Eye', value: 852 },
{ id: 9, name: 'Crown', value: 963 }
];
// Seed palettes per canonical id, matching the kiosk's
// DatabaseManager::seedColorPalettes(). Used to backfill /color-palettes
// when the DB has not been seeded for an id yet.
export const CANONICAL_PALETTES: Record<number, string[]> = {
1: ['#8B6914', '#B8860B', '#DAA520', '#E8B64C', '#FFD700', '#FFE9A8', '#FFF4CC'],
2: ['#8B0000', '#B22222', '#DC143C', '#FF6347', '#FF8C69', '#FFA500', '#FFDAB9'],
3: ['#FF4500', '#FF7F50', '#FF8C00', '#FFA500', '#FFC87F', '#FFDFBA', '#FFEBCD'],
4: ['#8B2252', '#CD3278', '#DB7093', '#FF69B4', '#FFB6C1', '#FFC0CB', '#FFE4E1'],
5: ['#32CD32', '#3CB371', '#90EE90', '#98FB98', '#ADFFA9', '#C8FFD2', '#F0FFF0'],
6: ['#00FF7F', '#00CED1', '#40E0D0', '#5F9EA0', '#7FFFD4', '#AFEEEE', '#E0FFFF'],
7: ['#00BFFF', '#1E90FF', '#4169E1', '#6495ED', '#87CEEB', '#ADD8E6', '#F0F8FF'],
8: ['#4B0082', '#9370DB', '#8A2BE2', '#7B68EE', '#DA70D6', '#D8BFD8', '#E6E6FA'],
9: ['#9400D3', '#BA55D3', '#C71585', '#DDA0DD', '#EE82EE', '#FFF0F5', '#FAF0FA']
};
/** Map a SolfeggioFrequency row to its canonical id, or null if it has no
* canonical id (e.g. 936 Hz). */
export function canonicalIdForFrequency(freq: { value: number }): number | null {
return CANONICAL_ID_FOR_HZ[freq.value] ?? null;
}
export type V2Proclamation = {
id: string;
name: string;
content: string;
categoryId: number;
solfeggioFrequencyId: number;
subscriptionLevelId: number | null;
colorPalette?: string[];
};
export type ProclamationWithFrequency = {
id: string;
name: string;
content: string;
categoryId: number;
subscriptionLevelId: number | null;
solfeggioFrequency: { value: number };
};
/** Serialize a DB proclamation row to the v2 wire format. Returns null when
* the proclamation's frequency has no canonical id (dropped from v2). */
export function serializeProclamation(
p: ProclamationWithFrequency,
palette?: string[]
): V2Proclamation | null {
const solfeggioFrequencyId = CANONICAL_ID_FOR_HZ[p.solfeggioFrequency.value];
if (!solfeggioFrequencyId) return null;
const record: V2Proclamation = {
id: p.id,
name: p.name,
content: p.content,
categoryId: p.categoryId,
solfeggioFrequencyId,
subscriptionLevelId: p.subscriptionLevelId
};
if (palette && palette.length > 0) {
record.colorPalette = palette;
}
return record;
}
export type V2Category = {
id: number;
name: string;
sortOrder: number;
parentId: number | null;
};
export function serializeCategory(c: {
id: number;
name: string;
sortOrder: number;
parentId: number | null;
}): V2Category {
return { id: c.id, name: c.name, sortOrder: c.sortOrder, parentId: c.parentId };
}
export type V2SubscriptionLevel = {
id: number;
name: string;
description: string | null;
};
export function serializeSubscriptionLevel(level: {
id: number;
name: string;
description: string | null;
}): V2SubscriptionLevel {
return { id: level.id, name: level.name, description: level.description };
}
export type V2License = {
key: string;
email_address: string;
subscription_level: { id: number | null; name: string; description: string | null };
};
/** Build the POST /license response. `subscription_level` is always an object;
* when no SubscriptionLevel row matches the license's level name, fall back to
* a structurally consistent object with a null id/description. */
export function serializeLicense(opts: {
key: string;
emailAddress: string;
levelName: string;
level: { id: number; name: string; description: string | null } | null;
}): V2License {
return {
key: opts.key,
email_address: opts.emailAddress,
subscription_level: opts.level
? { id: opts.level.id, name: opts.level.name, description: opts.level.description }
: { id: null, name: opts.levelName, description: null }
};
}
export type V2ColorPalette = {
solfeggioFrequencyId: number;
colors: string[];
};
export function serializeColorPalette(palette: {
solfeggioFrequencyId: number;
colors: string[];
}): V2ColorPalette {
return { solfeggioFrequencyId: palette.solfeggioFrequencyId, colors: palette.colors };
}
+120
View File
@@ -0,0 +1,120 @@
import { describe, it, expect, beforeEach } from 'vitest';
import {
computeSignature,
buildCanonicalRequest,
verifyRequestSignature,
_clearNonces
} from './v2-signature';
const SECRET = 'test-onboarding-secret';
function signedRequest(opts: {
now?: Date;
timestampOffsetSec?: number;
tamper?: Partial<Record<'signature' | 'nonce' | 'timestamp' | 'body', string>>;
}) {
const method = 'POST';
const path = '/api/v2/automations/create/account';
const timestamp = String(Math.floor((opts.now ?? new Date()).getTime() / 1000));
const nonce = 'a48c0f2e-5f34-4b0b-9a12-3c7d6b8e1f00';
const body = '{"email":"user@example.com","subscription_level":"Basic"}';
let ts = timestamp;
let nonceValue = nonce;
if (opts.tamper?.timestamp) ts = opts.tamper.timestamp;
if (opts.tamper?.nonce) nonceValue = opts.tamper.nonce;
let sig = computeSignature(SECRET, buildCanonicalRequest(method, path, ts, nonceValue, body));
if (opts.tamper?.body)
sig = computeSignature(
SECRET,
buildCanonicalRequest(method, path, ts, nonceValue, opts.tamper.body)
);
if (opts.tamper?.signature) sig = opts.tamper.signature;
const headers = new Headers({
'content-type': 'application/json',
'x-timestamp': ts,
'x-nonce': nonceValue,
'x-signature': sig
});
return { method, path, headers, rawBody: body };
}
describe('verifyRequestSignature', () => {
beforeEach(() => {
_clearNonces();
});
it('accepts a correctly signed request', () => {
const { method, path, headers, rawBody } = signedRequest({});
const result = verifyRequestSignature({ method, path, headers, rawBody, secret: SECRET });
expect(result.ok).toBe(true);
});
it('rejects a request with a wrong signature', () => {
const { method, path, headers, rawBody } = signedRequest({
tamper: { signature: 'deadbeef'.repeat(8) }
});
const result = verifyRequestSignature({ method, path, headers, rawBody, secret: SECRET });
expect(result.ok).toBe(false);
if (!result.ok) expect(result.reason).toBe('invalid signature');
});
it('rejects a request signed with the wrong secret', () => {
const { method, path, headers, rawBody } = signedRequest({});
const result = verifyRequestSignature({
method,
path,
headers,
rawBody,
secret: 'other-secret'
});
expect(result.ok).toBe(false);
});
it('rejects missing signature headers', () => {
const { method, path, rawBody } = signedRequest({});
const result = verifyRequestSignature({
method,
path,
headers: new Headers(),
rawBody,
secret: SECRET
});
expect(result.ok).toBe(false);
});
it('rejects an expired timestamp (>300s skew)', () => {
const now = new Date();
const { method, path, headers, rawBody } = signedRequest({
tamper: { timestamp: String(Math.floor(now.getTime() / 1000) - 600) }
});
const result = verifyRequestSignature({ method, path, headers, rawBody, secret: SECRET, now });
expect(result.ok).toBe(false);
if (!result.ok) expect(result.reason).toBe('expired timestamp');
});
it('accepts a timestamp within the 300s skew', () => {
const now = new Date();
const { method, path, headers, rawBody } = signedRequest({
tamper: { timestamp: String(Math.floor(now.getTime() / 1000) - 120) }
});
const result = verifyRequestSignature({ method, path, headers, rawBody, secret: SECRET, now });
expect(result.ok).toBe(true);
});
it('rejects a replayed nonce', () => {
const { method, path, headers, rawBody } = signedRequest({});
expect(verifyRequestSignature({ method, path, headers, rawBody, secret: SECRET }).ok).toBe(
true
);
const replay = verifyRequestSignature({ method, path, headers, rawBody, secret: SECRET });
expect(replay.ok).toBe(false);
if (!replay.ok) expect(replay.reason).toBe('replayed nonce');
});
});
+96
View File
@@ -0,0 +1,96 @@
import { createHmac, timingSafeEqual } from 'node:crypto';
export const SIGNATURE_MAX_SKEW_SECONDS = 300;
export function computeSignature(secret: string, canonicalRequest: string): string {
return createHmac('sha256', secret).update(canonicalRequest, 'utf8').digest('hex');
}
/** Canonical request string covered by the HMAC: method, path, timestamp,
* nonce, and the raw body, newline-separated. */
export function buildCanonicalRequest(
method: string,
path: string,
timestamp: string,
nonce: string,
body: string
): string {
return [method, path, timestamp, nonce, body].join('\n');
}
export function safeEqual(a: string, b: string): boolean {
const bufA = Buffer.from(a, 'utf8');
const bufB = Buffer.from(b, 'utf8');
if (bufA.length !== bufB.length) return false;
return timingSafeEqual(bufA, bufB);
}
// In-memory nonce store. Prunes entries older than twice the allowed skew.
const seenNonces = new Map<string, number>();
export function isNonceReplayed(nonce: string, now = Date.now()): boolean {
const seenAt = seenNonces.get(nonce);
if (seenAt === undefined) return false;
// Keep treating it as replayed only while within the replay window; beyond
// that the entry is pruned and the nonce could in theory be reused, but the
// timestamp skew check still bounds it.
return now - seenAt < SIGNATURE_MAX_SKEW_SECONDS * 2 * 1000;
}
export function recordNonce(nonce: string, now = Date.now()): void {
seenNonces.set(nonce, now);
// Opportunistically prune stale entries.
const cutoff = now - SIGNATURE_MAX_SKEW_SECONDS * 2 * 1000;
for (const [key, seenAt] of seenNonces) {
if (seenAt < cutoff) seenNonces.delete(key);
}
}
export type SignatureVerification = { ok: true } | { ok: false; reason: string };
export function verifyRequestSignature(opts: {
method: string;
path: string;
headers: Headers;
rawBody: string;
secret: string;
now?: Date;
}): SignatureVerification {
const { method, path, headers, rawBody, secret } = opts;
const timestamp = headers.get('x-timestamp');
const nonce = headers.get('x-nonce');
const signature = headers.get('x-signature');
if (!timestamp || !nonce || !signature) {
return { ok: false, reason: 'missing signature headers' };
}
const ts = Number(timestamp);
if (!Number.isFinite(ts)) {
return { ok: false, reason: 'invalid timestamp' };
}
const now = (opts.now ?? new Date()).getTime() / 1000;
if (Math.abs(now - ts) > SIGNATURE_MAX_SKEW_SECONDS) {
return { ok: false, reason: 'expired timestamp' };
}
if (isNonceReplayed(nonce)) {
return { ok: false, reason: 'replayed nonce' };
}
const canonical = buildCanonicalRequest(method, path, timestamp, nonce, rawBody);
const expected = computeSignature(secret, canonical);
if (!safeEqual(expected, signature)) {
return { ok: false, reason: 'invalid signature' };
}
recordNonce(nonce);
return { ok: true };
}
/** Test hook: clears the in-memory nonce store. */
export function _clearNonces(): void {
seenNonces.clear();
}