import type { ALLOWED_CONTENT_TYPE, ALLOWED_EXTENSION, AnyObject, ColumnInfo, DBSchema, JSONB, StrictUnion } from "prostgles-types"; import type { JoinInfo, LocalParams } from "../DboBuilder/DboBuilder"; import type { TableHandler } from "../DboBuilder/TableHandler/TableHandler"; import type { DBOFullyTyped } from "../DBSchemaBuilder/DBSchemaBuilder"; import type { DB, DBHandlerServer, Prostgles } from "../Prostgles"; import type { InsertRule, SyncConfig, ValidateRowArgsCommon, ValidateRowsArgsCommon } from "../PublishParser/PublishParser"; type ColExtraInfo = { min?: string | number; max?: string | number; hint?: string; }; type LangToTranslation = Record; export declare const parseI18N: (params: { config?: Config | string; lang?: string; defaultLang: string; defaultValue: string | undefined; }) => undefined | string; type BaseTableDefinition = { info?: { label?: string | LangToTranslation; }; dropIfExistsCascade?: boolean; dropIfExists?: boolean; syncConfig?: SyncConfig; hooks?: { /** * Hook used to run custom logic before inserting a row. * The returned row must satisfy the table schema */ getPreInsertRow?: (args: GetPreInsertRowArgs) => Promise<{ row: AnyObject; onInserted: Promise; }>; afterEach?: { commands: Partial>; changedFields?: string[]; validate: (params: ValidateRowArgsCommon & { localParams: undefined | LocalParams; }) => Promise; }[]; afterAll?: { commands: Partial>; changedFields?: string[]; validate: (params: ValidateRowsArgsCommon & { localParams: undefined | LocalParams; }) => Promise; }[]; }; triggers?: { [triggerName: string]: { /** * Use "before" when you need to change the data before the action */ type: "before" | "after" | "instead of"; actions: ("insert" | "update" | "delete")[]; forEach: "statement" | "row"; /** * @example * DECLARE x_rec record; BEGIN raise notice '=operation: % =', TG_OP; IF (TG_OP = 'UPDATE' OR TG_OP = 'DELETE') THEN FOR x_rec IN SELECT * FROM old_table LOOP raise notice 'OLD: %', x_rec; END loop; END IF; IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN FOR x_rec IN SELECT * FROM new_table LOOP raise notice 'NEW: %', x_rec; END loop; END IF; RETURN NULL; END; */ query: string; }; }; }; type LookupTableDefinition = BaseTableDefinition & { isLookupTable: { values: { [id_value: string]: {} | { [lang_id in keyof LANG_IDS]: string; }; }; }; }; export type BaseColumn = { /** * Will add these values to .getColumns() result */ info?: ColExtraInfo; label?: string | Partial<{ [lang_id in keyof LANG_IDS]: string; }>; }; type SQLDefColumn = { /** * Raw sql statement used in creating/adding column */ sqlDefinition?: string; }; export type BaseColumnTypes = { defaultValue?: string | number | boolean | Record; nullable?: boolean; }; type TextColumn = BaseColumnTypes & { isText: true; /** * Value will be trimmed before update/insert */ trimmed?: boolean; /** * Value will be lower cased before update/insert */ lowerCased?: boolean; }; export type JSONBColumnDef = BaseColumnTypes & ({ jsonbSchema: JSONB.JSONBSchema; jsonbSchemaType?: undefined; } | { jsonbSchema?: undefined; jsonbSchemaType: JSONB.ObjectType["type"]; }); /** * Allows referencing media to this table. * Requires this table to have a primary key AND a valid fileTable config */ type MediaColumn = { name: string; label?: string; files: "one" | "many"; } & ({ /** * https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept */ allowedContentType?: Record, 1>; } | { allowedExtensions?: Record, 1>; }); type ReferencedColumn = BaseColumnTypes & { /** * Will create a lookup table that this column will reference */ references?: { tableName: string; /** * Defaults to id */ columnName?: string; onDelete?: "CASCADE" | "SET NULL" | "RESTRICT" | "NO ACTION" | "SET DEFAULT"; onUpdate?: "CASCADE" | "SET NULL" | "RESTRICT" | "NO ACTION" | "SET DEFAULT"; }; }; type JoinDef = { sourceTable: string; targetTable: string; on: JoinInfo["paths"][number]["on"]; }; /** * Used in specifying a join path to a table. This column name can then be used in select */ type NamedJoinColumn = { label?: string; joinDef: JoinDef[]; }; type Enum = { enum: T[] | readonly T[]; nullable?: boolean; defaultValue?: T; }; export type ColumnConfig = string | StrictUnion & (SQLDefColumn | ReferencedColumn | TextColumn | JSONBColumnDef | Enum))>; export type ColumnConfigs = { sql: string | (BaseColumn & SQLDefColumn); join: BaseColumn & NamedJoinColumn; media: BaseColumn & MediaColumn; referenced: BaseColumn & ReferencedColumn; text: BaseColumn & TextColumn; jsonb: BaseColumn & JSONBColumnDef; enum: BaseColumn & Enum; }; type ConstraintType = "PRIMARY KEY" | "UNIQUE" | "CHECK" | "FOREIGN KEY"; /** * Each column definition cannot reference to tables that appear later in the table definition. * These references should be specified in constraints property */ export type TableDefinition = BaseTableDefinition & { onMount?: (params: { dbo: DBHandlerServer; _db: DB; }) => Promise void; }>; columns?: { [column_name: string]: ColumnConfig; }; constraints?: string[] | { [constraint_name: string]: string | { type: ConstraintType; dropIfExists?: boolean; /** * E.g.: * colname * col1, col2 * col1 > col3 */ content: string; }; }; /** * Similar to unique constraints but expressions are allowed inside definition */ replaceUniqueIndexes?: boolean; indexes?: { [index_name: string]: { /** * If true then will drop any existing index with this name * Overrides replaceUniqueIndexes */ replace?: boolean; /** * Causes the system to check for duplicate values in the table when the index is created (if data already exist) and each time data is added. * Attempts to insert or update data which would result in duplicate entries will generate an error. */ unique?: boolean; /** * When this option is used, PostgreSQL will build the index without taking any locks that prevent * concurrent inserts, updates, or deletes on the table; whereas a standard index build locks out writes (but not reads) on the table until it's done. * There are several caveats to be aware of when using this option — see Building Indexes Concurrently. */ concurrently?: boolean; /** * Table name */ /** * Column list * @example: col1, col2 */ columns: string; /** * Where clause without the "where" * Used to create a partial index. A partial index is an index that contains entries for only a portion of a table * Another possible application is to use WHERE with UNIQUE to enforce uniqueness over a subset of a table */ where?: string; /** * The name of the index method to be used. * Choices are btree, hash, gist, and gin. The default method is btree. */ using?: "btree" | "hash" | "gist" | "gin"; }; }; }; type GetPreInsertRowArgs = Omit & { validate: InsertRule["validate"]; localParams: LocalParams | undefined; }; export type TableConfig = S extends DBSchema ? Partial<{ [TableName in keyof S]: TableDefinition> | LookupTableDefinition; }> : { [table_name: string]: TableDefinition | LookupTableDefinition; }; /** * Will be run between initSQL and fileTable */ export default class TableConfigurator { instanceId: number; get config(): { [table_name: string]: TableDefinition<{ en: 1; }, AnyObject, DBHandlerServer> | LookupTableDefinition<{ en: 1; }>; }; get dbo(): DBHandlerServer; get db(): DB; prostgles: Prostgles; constructor(prostgles: Prostgles); destroy: () => Promise; tableOnMounts: Record void | Promise; }>; setTableOnMounts: () => Promise; getColumnConfig: (tableName: string, colName: string) => ColumnConfig | undefined; getTableSyncConfig: (tableName: string) => { batch_size: number; throttle: number; id_fields: string[]; synced_field: string; } | undefined; getTableLabel: (params: { tableName: string; lang?: string; }) => string | undefined; getColInfo: (params: { col: string; table: string; lang?: string; }) => (ColExtraInfo & { label?: string; } & Pick) | undefined; checkColVal: (params: { col: string; table: string; value?: number | string; }) => void; getJoinInfo: (sourceTable: string, targetTable: string) => JoinInfo | undefined; getPreInsertRow: (tableHandler: TableHandler, args: Pick) => Promise; prevInitQueryHistory?: string[]; initialising: boolean; init: () => Promise; } export {}; //# sourceMappingURL=TableConfig.d.ts.map