UNPKG

alepha

Version:

Easy-to-use modern TypeScript framework for building many kind of applications.

538 lines 21.8 kB
import { Alepha, Static, TNull, TObject, TOptional, TSchema, TUnion } from "alepha"; import { Page } from "alepha/orm"; import { BuildExtraConfigColumns, SQL } from "drizzle-orm"; import { PgColumnBuilderBase, PgSequenceOptions, PgTableExtraConfigValue, UpdateDeleteAction } from "drizzle-orm/pg-core"; import "drizzle-orm/pg-core/foreign-keys"; import "alepha/datetime"; import "drizzle-orm/pg-core/session"; import "alepha/crypto"; import "drizzle-kit/api"; import "drizzle-orm/d1"; import "drizzle-orm/sqlite-core"; //#region ../../src/orm/core/schemas/insertSchema.d.ts /** * Transforms a TObject schema for insert operations. * All default properties at the root level are made optional. * Generated columns are excluded entirely. * * @example * Before: { name: string; age: number(default=0); fullName: generated } * After: { name: string; age?: number; } */ type TObjectInsert<T extends TObject> = TObject<{ [K in keyof T["shape"] as T["shape"][K] extends { [PG_GENERATED]: any; } ? never : K]: T["shape"][K] extends { [PG_DEFAULT]: any; } | { [PG_ORGANIZATION]: any; } ? TOptional<Extract<T["shape"][K], TSchema>> : T["shape"][K]; }>; //#endregion //#region ../../src/orm/core/schemas/updateSchema.d.ts /** * Transforms a TObject schema for update operations. * All optional properties at the root level are made nullable (i.e., `T | null`). * Generated columns are excluded entirely. * * @example * Before: { name?: string; age: number; fullName: generated } * After: { name?: string | null; age: number; } */ type TObjectUpdate<T extends TObject> = TObject<{ [K in keyof T["shape"] as T["shape"][K] extends { [PG_GENERATED]: any; } ? never : K]: T["shape"][K] extends TOptional<infer U extends TSchema> ? TOptional<TUnion<[U, TNull]>> : T["shape"][K]; }>; //#endregion //#region ../../src/orm/core/primitives/$entity.d.ts interface EntityPrimitiveOptions<T extends TObject, Keys = keyof Static<T>> { /** * The database table name that will be created for this entity. * If not provided, name will be inferred from the $repository variable name. */ name: string; /** * TypeBox schema defining the table structure and column types. */ schema: T; /** * Database indexes to create for query optimization. */ indexes?: (Keys | { /** * Single column to index. */ column: Keys; /** * Whether this should be a unique index (enforces uniqueness constraint). */ unique?: boolean; /** * Custom name for the index. If not provided, generates name automatically. */ name?: string; /** * Partial index condition. Only rows matching this SQL expression are indexed. */ where?: SQL; } | { /** * Multiple columns for composite index (order matters for query optimization). */ columns: Keys[]; /** * Whether this should be a unique index (enforces uniqueness constraint). */ unique?: boolean; /** * Custom name for the index. If not provided, generates name automatically. */ name?: string; /** * Partial index condition. Only rows matching this SQL expression are indexed. */ where?: SQL; } | { /** * SQL expressions for expression-based indexes. * * Can include column references and SQL functions like `LOWER()`, `UPPER()`, etc. * Columns and expressions can be mixed together. * * @example * ```ts * // Case-insensitive unique username per realm * indexes: [{ * expressions: (self) => [self.realm, sql`LOWER(${self.username})`], * unique: true, * name: "users_realm_username_lower_idx", * }] * ``` */ expressions: (self: Record<Keys & string, any>) => (SQL | any)[]; /** * Whether this should be a unique index (enforces uniqueness constraint). */ unique?: boolean; /** * Custom name for the index. If not provided, generates name automatically. */ name: string; /** * Partial index condition. Only rows matching this SQL expression are indexed. */ where?: SQL; })[]; /** * Foreign key constraints to maintain referential integrity. */ foreignKeys?: Array<{ /** * Optional name for the foreign key constraint. */ name?: string; /** * Local columns that reference the foreign table. */ columns: Array<keyof Static<T>>; /** * Referenced columns in the foreign table. * Must be EntityColumn references from other entities. */ foreignColumns: Array<() => EntityColumn<any>>; }>; /** * Additional table constraints for data validation. * * Constraints enforce business rules at the database level, providing * an additional layer of data integrity beyond application validation. * * **Constraint Types**: * - **Unique constraints**: Prevent duplicate values across columns * - **Check constraints**: Enforce custom validation rules with SQL expressions * * @example * ```ts * constraints: [ * { * name: "unique_user_email", * columns: ["email"], * unique: true * }, * { * name: "valid_age_range", * columns: ["age"], * check: sql`age >= 0 AND age <= 150` * }, * { * name: "unique_user_username_per_tenant", * columns: ["tenantId", "username"], * unique: true * } * ] * ``` */ constraints?: Array<{ /** * Columns involved in this constraint. */ columns: Array<keyof Static<T>>; /** * Optional name for the constraint. */ name?: string; /** * Whether this is a unique constraint. */ unique?: boolean | {}; /** * SQL expression for check constraint validation. */ check?: SQL; }>; /** * Advanced Drizzle ORM configuration for complex table setups. */ config?: (self: BuildExtraConfigColumns<string, FromSchema<T>, "pg">) => PgTableExtraConfigValue[]; } declare class EntityPrimitive<T extends TObject = TObject> { readonly options: EntityPrimitiveOptions<T>; constructor(options: EntityPrimitiveOptions<T>); alias(alias: string): this; get cols(): EntityColumns<T>; get name(): string; get schema(): T; protected _insertSchema?: TObjectInsert<T>; get insertSchema(): TObjectInsert<T>; protected _updateSchema?: TObjectUpdate<T>; get updateSchema(): TObjectUpdate<T>; } /** * Convert a schema to columns. */ type FromSchema<T extends TObject> = { [key in keyof T["properties"]]: PgColumnBuilderBase; }; type EntityColumn<T extends TObject> = { name: string; entity: EntityPrimitive<T>; }; type EntityColumns<T extends TObject> = { [key in keyof T["properties"]]: EntityColumn<T>; }; //#endregion //#region ../../src/orm/core/constants/PG_SYMBOLS.d.ts declare const PG_DEFAULT: unique symbol; declare const PG_PRIMARY_KEY: unique symbol; declare const PG_CREATED_AT: unique symbol; declare const PG_UPDATED_AT: unique symbol; declare const PG_DELETED_AT: unique symbol; declare const PG_VERSION: unique symbol; declare const PG_IDENTITY: unique symbol; declare const PG_ENUM: unique symbol; declare const PG_REF: unique symbol; declare const PG_GENERATED: unique symbol; declare const PG_ORGANIZATION: unique symbol; /** * @deprecated Use `PG_IDENTITY` instead. */ declare const PG_SERIAL: unique symbol; type PgSymbols = { [PG_DEFAULT]: {}; [PG_PRIMARY_KEY]: {}; [PG_CREATED_AT]: {}; [PG_UPDATED_AT]: {}; [PG_DELETED_AT]: {}; [PG_VERSION]: {}; [PG_IDENTITY]: PgIdentityOptions; [PG_REF]: PgRefOptions; [PG_ENUM]: PgEnumOptions; [PG_GENERATED]: PgGeneratedOptions; [PG_ORGANIZATION]: PgOrganizationOptions; /** * @deprecated Use `PG_IDENTITY` instead. */ [PG_SERIAL]: {}; }; type PgSymbolKeys = keyof PgSymbols; interface PgOrganizationOptions { /** * Fail-closed tenant scoping. When `true`, the repository (a) refuses any * read/write with no resolved tenant instead of falling through to an * unfiltered "see/write everything" query, and (b) drops the * `OR organizationId IS NULL` "global row" escape — a scoped tenant never * sees NULL/global rows. Use for security-sensitive tables. Defaults to * `false` (the historic fail-open semantics). */ strict?: boolean; } type PgIdentityOptions = { mode: "always" | "byDefault"; } & PgSequenceOptions & { name?: string; }; interface PgEnumOptions { name?: string; description?: string; } interface PgGeneratedOptions { /** * SQL expression for the generated column. */ expression: SQL; /** * Storage mode for the generated column. * - `"stored"` — value is computed on write and stored on disk (default for PostgreSQL). * - `"virtual"` — value is computed on read (default for SQLite). */ mode?: "stored" | "virtual"; } interface PgRefOptions { ref: () => { name: string; entity: EntityPrimitive; }; actions?: { onUpdate?: UpdateDeleteAction; onDelete?: UpdateDeleteAction; }; } //#endregion //#region ../../src/orm/core/helpers/pgAttr.d.ts /** * Type representation. */ type PgAttr<T extends TSchema, TAttr extends PgSymbolKeys> = T & { [K in TAttr]: PgSymbols[K]; }; //#endregion //#region ../../src/orm/core/schemas/databaseEnvSchema.d.ts /** * Base database environment schema. * * Defines the `DATABASE_URL` connection string used by all ORM providers * to determine the database driver and connection target. * * Supported URL formats: * - `sqlite://:memory:` or `sqlite://./path/to/db` — SQLite (Node.js or Bun) * - `postgres://user:password@host:port/database` — PostgreSQL (Node.js or Bun) * - `pglite://:memory:` or `pglite://./path` — PGlite (embedded Postgres) * - `d1://BINDING_NAME` — Cloudflare D1 * - `hyperdrive://BINDING_NAME` — Cloudflare Hyperdrive */ declare const databaseEnvSchema: import("zod").ZodObject<{ DATABASE_URL: import("zod").ZodOptional<import("zod").ZodString>; DATABASE_SYNC: import("zod").ZodOptional<import("zod").ZodBoolean>; }, import("zod/v4/core").$strip>; declare module "alepha" { interface Env extends Partial<Static<typeof databaseEnvSchema>> {} } //#endregion //#region ../../src/api/organizations/entities/organizations.d.ts declare const organizations: import("alepha/orm").EntityPrimitive<import("zod").ZodObject<{ id: import("alepha/orm").PgAttr<import("alepha/orm").PgAttr<import("zod").ZodString, typeof import("alepha/orm").PG_PRIMARY_KEY>, typeof import("alepha/orm").PG_DEFAULT>; version: import("alepha/orm").PgAttr<import("alepha/orm").PgAttr<import("zod").ZodInt, typeof import("alepha/orm").PG_VERSION>, typeof import("alepha/orm").PG_DEFAULT>; createdAt: import("alepha/orm").PgAttr<import("alepha/orm").PgAttr<import("zod").ZodString, typeof import("alepha/orm").PG_CREATED_AT>, typeof import("alepha/orm").PG_DEFAULT>; updatedAt: import("alepha/orm").PgAttr<import("alepha/orm").PgAttr<import("zod").ZodString, typeof import("alepha/orm").PG_UPDATED_AT>, typeof import("alepha/orm").PG_DEFAULT>; name: import("zod").ZodString; slug: import("zod").ZodString; enabled: import("alepha/orm").PgAttr<import("zod").ZodBoolean, typeof import("alepha/orm").PG_DEFAULT>; }, import("zod/v4/core").$strip>>; type OrganizationEntity = Static<typeof organizations.schema>; //#endregion //#region ../../src/api/organizations/schemas/createOrganizationSchema.d.ts declare const createOrganizationSchema: import("zod").ZodObject<{ name: import("zod").ZodString; slug: import("zod").ZodString; enabled: import("zod").ZodOptional<import("zod").ZodBoolean>; }, import("zod/v4/core").$strip>; type CreateOrganization = Static<typeof createOrganizationSchema>; //#endregion //#region ../../src/api/organizations/schemas/organizationQuerySchema.d.ts declare const organizationQuerySchema: import("zod").ZodObject<{ page: import("zod").ZodOptional<import("zod").ZodDefault<import("zod").ZodInt>>; size: import("zod").ZodOptional<import("zod").ZodDefault<import("zod").ZodInt>>; sort: import("zod").ZodOptional<import("zod").ZodString>; name: import("zod").ZodOptional<import("zod").ZodString>; enabled: import("zod").ZodOptional<import("zod").ZodBoolean>; }, import("zod/v4/core").$strip>; type OrganizationQuery = Static<typeof organizationQuerySchema>; //#endregion //#region ../../src/api/organizations/schemas/updateOrganizationSchema.d.ts declare const updateOrganizationSchema: import("zod").ZodObject<{ name: import("zod").ZodOptional<import("zod").ZodString>; slug: import("zod").ZodOptional<import("zod").ZodString>; enabled: import("zod").ZodOptional<import("zod").ZodOptional<import("zod").ZodBoolean>>; }, import("zod/v4/core").$strip>; type UpdateOrganization = Static<typeof updateOrganizationSchema>; //#endregion //#region ../../src/api/organizations/services/OrganizationService.d.ts declare class OrganizationService { protected readonly alepha: Alepha; protected readonly log: import("alepha/logger").Logger; protected readonly repo: import("alepha/orm").Repository<import("zod").ZodObject<{ id: import("alepha/orm").PgAttr<import("alepha/orm").PgAttr<import("zod").ZodString, typeof import("alepha/orm").PG_PRIMARY_KEY>, typeof import("alepha/orm").PG_DEFAULT>; version: import("alepha/orm").PgAttr<import("alepha/orm").PgAttr<import("zod").ZodInt, typeof import("alepha/orm").PG_VERSION>, typeof import("alepha/orm").PG_DEFAULT>; createdAt: import("alepha/orm").PgAttr<import("alepha/orm").PgAttr<import("zod").ZodString, typeof import("alepha/orm").PG_CREATED_AT>, typeof import("alepha/orm").PG_DEFAULT>; updatedAt: import("alepha/orm").PgAttr<import("alepha/orm").PgAttr<import("zod").ZodString, typeof import("alepha/orm").PG_UPDATED_AT>, typeof import("alepha/orm").PG_DEFAULT>; name: import("zod").ZodString; slug: import("zod").ZodString; enabled: import("alepha/orm").PgAttr<import("zod").ZodBoolean, typeof import("alepha/orm").PG_DEFAULT>; }, import("zod/v4/core").$strip>>; /** * Find organizations with pagination and filtering. */ find(query?: OrganizationQuery): Promise<Page<OrganizationEntity>>; /** * Get an organization by ID. */ getById(id: string): Promise<OrganizationEntity>; /** * Get an organization by slug. */ getBySlug(slug: string): Promise<OrganizationEntity>; /** * Create a new organization. */ create(data: CreateOrganization): Promise<OrganizationEntity>; /** * Update an organization. */ update(id: string, data: UpdateOrganization): Promise<OrganizationEntity>; /** * Delete an organization. */ delete(id: string): Promise<void>; } //#endregion //#region ../../src/api/organizations/controllers/AdminOrganizationController.d.ts declare class AdminOrganizationController { protected readonly url = "/organizations"; protected readonly group = "admin:organizations"; protected readonly organizationService: OrganizationService; /** * Find organizations with pagination and filtering. */ readonly findOrganizations: import("alepha/server").ActionPrimitiveFn<{ query: import("zod").ZodObject<{ page: import("zod").ZodOptional<import("zod").ZodDefault<import("zod").ZodInt>>; size: import("zod").ZodOptional<import("zod").ZodDefault<import("zod").ZodInt>>; sort: import("zod").ZodOptional<import("zod").ZodString>; name: import("zod").ZodOptional<import("zod").ZodString>; enabled: import("zod").ZodOptional<import("zod").ZodBoolean>; }, import("zod/v4/core").$strip>; response: import("zod").ZodObject<{ content: import("zod").ZodArray<import("zod").ZodObject<{ id: PgAttr<PgAttr<import("zod").ZodString, typeof PG_PRIMARY_KEY>, typeof PG_DEFAULT>; version: PgAttr<PgAttr<import("zod").ZodInt, typeof PG_VERSION>, typeof PG_DEFAULT>; createdAt: PgAttr<PgAttr<import("zod").ZodString, typeof PG_CREATED_AT>, typeof PG_DEFAULT>; updatedAt: PgAttr<PgAttr<import("zod").ZodString, typeof PG_UPDATED_AT>, typeof PG_DEFAULT>; name: import("zod").ZodString; slug: import("zod").ZodString; enabled: PgAttr<import("zod").ZodBoolean, typeof PG_DEFAULT>; }, import("zod/v4/core").$strip>>; page: import("zod").ZodObject<{ number: import("zod").ZodInt; size: import("zod").ZodInt; offset: import("zod").ZodInt; numberOfElements: import("zod").ZodInt; totalElements: import("zod").ZodOptional<import("zod").ZodInt>; totalPages: import("zod").ZodOptional<import("zod").ZodInt>; isEmpty: import("zod").ZodBoolean; isFirst: import("zod").ZodBoolean; isLast: import("zod").ZodBoolean; }, import("zod/v4/core").$strip>; }, import("zod/v4/core").$strip>; }>; /** * Get an organization by ID. */ readonly getOrganization: import("alepha/server").ActionPrimitiveFn<{ params: import("zod").ZodObject<{ id: import("zod").ZodString; }, import("zod/v4/core").$strip>; response: import("zod").ZodObject<{ id: PgAttr<PgAttr<import("zod").ZodString, typeof PG_PRIMARY_KEY>, typeof PG_DEFAULT>; version: PgAttr<PgAttr<import("zod").ZodInt, typeof PG_VERSION>, typeof PG_DEFAULT>; createdAt: PgAttr<PgAttr<import("zod").ZodString, typeof PG_CREATED_AT>, typeof PG_DEFAULT>; updatedAt: PgAttr<PgAttr<import("zod").ZodString, typeof PG_UPDATED_AT>, typeof PG_DEFAULT>; name: import("zod").ZodString; slug: import("zod").ZodString; enabled: PgAttr<import("zod").ZodBoolean, typeof PG_DEFAULT>; }, import("zod/v4/core").$strip>; }>; /** * Create a new organization. */ readonly createOrganization: import("alepha/server").ActionPrimitiveFn<{ body: import("zod").ZodObject<{ name: import("zod").ZodString; slug: import("zod").ZodString; enabled: import("zod").ZodOptional<import("zod").ZodBoolean>; }, import("zod/v4/core").$strip>; response: import("zod").ZodObject<{ id: PgAttr<PgAttr<import("zod").ZodString, typeof PG_PRIMARY_KEY>, typeof PG_DEFAULT>; version: PgAttr<PgAttr<import("zod").ZodInt, typeof PG_VERSION>, typeof PG_DEFAULT>; createdAt: PgAttr<PgAttr<import("zod").ZodString, typeof PG_CREATED_AT>, typeof PG_DEFAULT>; updatedAt: PgAttr<PgAttr<import("zod").ZodString, typeof PG_UPDATED_AT>, typeof PG_DEFAULT>; name: import("zod").ZodString; slug: import("zod").ZodString; enabled: PgAttr<import("zod").ZodBoolean, typeof PG_DEFAULT>; }, import("zod/v4/core").$strip>; }>; /** * Update an organization. */ readonly updateOrganization: import("alepha/server").ActionPrimitiveFn<{ params: import("zod").ZodObject<{ id: import("zod").ZodString; }, import("zod/v4/core").$strip>; body: import("zod").ZodObject<{ name: import("zod").ZodOptional<import("zod").ZodString>; slug: import("zod").ZodOptional<import("zod").ZodString>; enabled: import("zod").ZodOptional<import("zod").ZodOptional<import("zod").ZodBoolean>>; }, import("zod/v4/core").$strip>; response: import("zod").ZodObject<{ id: PgAttr<PgAttr<import("zod").ZodString, typeof PG_PRIMARY_KEY>, typeof PG_DEFAULT>; version: PgAttr<PgAttr<import("zod").ZodInt, typeof PG_VERSION>, typeof PG_DEFAULT>; createdAt: PgAttr<PgAttr<import("zod").ZodString, typeof PG_CREATED_AT>, typeof PG_DEFAULT>; updatedAt: PgAttr<PgAttr<import("zod").ZodString, typeof PG_UPDATED_AT>, typeof PG_DEFAULT>; name: import("zod").ZodString; slug: import("zod").ZodString; enabled: PgAttr<import("zod").ZodBoolean, typeof PG_DEFAULT>; }, import("zod/v4/core").$strip>; }>; /** * Delete an organization. */ readonly deleteOrganization: import("alepha/server").ActionPrimitiveFn<{ params: import("zod").ZodObject<{ id: import("zod").ZodString; }, import("zod/v4/core").$strip>; response: import("zod").ZodObject<{ ok: import("zod").ZodBoolean; id: import("zod").ZodOptional<import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodInt]>>; count: import("zod").ZodOptional<import("zod").ZodNumber>; }, import("zod/v4/core").$strip>; }>; } //#endregion //#region ../../src/api/organizations/schemas/organizationResourceSchema.d.ts declare const organizationResourceSchema: import("zod").ZodObject<{ id: PgAttr<PgAttr<import("zod").ZodString, typeof PG_PRIMARY_KEY>, typeof PG_DEFAULT>; version: PgAttr<PgAttr<import("zod").ZodInt, typeof PG_VERSION>, typeof PG_DEFAULT>; createdAt: PgAttr<PgAttr<import("zod").ZodString, typeof PG_CREATED_AT>, typeof PG_DEFAULT>; updatedAt: PgAttr<PgAttr<import("zod").ZodString, typeof PG_UPDATED_AT>, typeof PG_DEFAULT>; name: import("zod").ZodString; slug: import("zod").ZodString; enabled: PgAttr<import("zod").ZodBoolean, typeof PG_DEFAULT>; }, import("zod/v4/core").$strip>; type OrganizationResource = Static<typeof organizationResourceSchema>; //#endregion //#region ../../src/api/organizations/index.d.ts /** * Organization management for multi-tenancy. * * **Features:** * - Admin CRUD for organizations * - Organization scoping via `db.organization()` on entities * - User with no organization = god mode (sees all resources) * - User with an organization = scoped to that organization * * @module alepha.api.organizations */ declare const AlephaApiOrganizations: import("alepha").Service<import("alepha").Module>; //#endregion export { AdminOrganizationController, AlephaApiOrganizations, CreateOrganization, OrganizationEntity, OrganizationQuery, OrganizationResource, OrganizationService, UpdateOrganization, createOrganizationSchema, organizationQuerySchema, organizationResourceSchema, organizations, updateOrganizationSchema }; //# sourceMappingURL=index.d.ts.map