Skip to content

Commit

Permalink
fix publish type bug
Browse files Browse the repository at this point in the history
  • Loading branch information
prostgles committed Dec 21, 2024
1 parent ad34cab commit 1e834bb
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 156 deletions.
94 changes: 28 additions & 66 deletions lib/DBSchemaBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,22 @@ import {
} from "prostgles-types";
import prostgles from ".";
import { Auth } from "./Auth/AuthTypes";
import {
DboBuilder,
escapeTSNames,
postgresToTsType,
} from "./DboBuilder/DboBuilder";
import { DboBuilder, escapeTSNames, postgresToTsType } from "./DboBuilder/DboBuilder";
import {
PublishAllOrNothing,
PublishParams,
PublishTableRule,
PublishViewRule,
} from "./PublishParser/PublishParser";
import { getJSONBSchemaTSTypes } from "./JSONBValidation/validation";
import {
DBHandlerServer,
TableSchemaColumn,
TX,
} from "./DboBuilder/DboBuilderTypes";
import { DBHandlerServer, TableSchemaColumn, TX } from "./DboBuilder/DboBuilderTypes";

export const getDBSchema = (dboBuilder: DboBuilder): string => {
const tables: string[] = [];

const getColTypeForDBSchema = (
udt_name: TableSchemaColumn["udt_name"],
): string => {
const getColTypeForDBSchema = (udt_name: TableSchemaColumn["udt_name"]): string => {
if (udt_name === "interval") {
const units = [
"years",
"months",
"days",
"hours",
"minutes",
"seconds",
"milliseconds",
];
const units = ["years", "months", "days", "hours", "minutes", "seconds", "milliseconds"];

return `{ ${units.map((u) => `${u}?: number;`).join(" ")} }`;
}
Expand All @@ -56,23 +38,13 @@ export const getDBSchema = (dboBuilder: DboBuilder): string => {
?.slice(0)
.sort((a, b) => a.name.localeCompare(b.name))
.forEach((tov) => {
const cols = tov.columns
.slice(0)
.sort((a, b) => a.name.localeCompare(b.name));
const cols = tov.columns.slice(0).sort((a, b) => a.name.localeCompare(b.name));
const getColType = (c: (typeof cols)[number]) => {
let type: string =
(c.is_nullable ? "null | " : "") +
getColTypeForDBSchema(c.udt_name) +
";";
const colConf = dboBuilder.prostgles.tableConfigurator?.getColumnConfig(
tov.name,
c.name,
);
(c.is_nullable ? "null | " : "") + getColTypeForDBSchema(c.udt_name) + ";";
const colConf = dboBuilder.prostgles.tableConfigurator?.getColumnConfig(tov.name, c.name);
if (colConf) {
if (
isObject(colConf) &&
(colConf.jsonbSchema || colConf.jsonbSchemaType)
) {
if (isObject(colConf) && (colConf.jsonbSchema || colConf.jsonbSchemaType)) {
const schema: JSONB.JSONBSchema = colConf.jsonbSchema || {
...colConf,
type: colConf.jsonbSchemaType,
Expand All @@ -82,13 +54,11 @@ export const getDBSchema = (dboBuilder: DboBuilder): string => {
schema,
{ nullable: colConf.nullable },
" ",
dboBuilder.tablesOrViews ?? [],
dboBuilder.tablesOrViews ?? []
);
} else if (isObject(colConf) && "enum" in colConf) {
if (!colConf.enum) throw "colConf.enum missing";
const types = colConf.enum.map((t) =>
typeof t === "number" ? t : JSON.stringify(t),
);
const types = colConf.enum.map((t) => (typeof t === "number" ? t : JSON.stringify(t)));
if (colConf.nullable) {
types.unshift("null");
}
Expand All @@ -110,7 +80,7 @@ export const getDBSchema = (dboBuilder: DboBuilder): string => {
columns: {${cols
.map(
(c) => `
${getColType(c)}`,
${getColType(c)}`
)
.join("")}
};
Expand All @@ -132,11 +102,12 @@ type ServerTableHandler<
Schema extends DBSchema | void = void,
> = TableHandler<T, Schema> & { is_view: boolean };

export type DBTableHandlersFromSchema<Schema = void> = Schema extends DBSchema
? {
[tov_name in keyof Schema]: Schema[tov_name]["is_view"] extends true
? ServerViewHandler<Schema[tov_name]["columns"], Schema>
: ServerTableHandler<Schema[tov_name]["columns"], Schema>;
export type DBTableHandlersFromSchema<Schema = void> =
Schema extends DBSchema ?
{
[tov_name in keyof Schema]: Schema[tov_name]["is_view"] extends true ?
ServerViewHandler<Schema[tov_name]["columns"], Schema>
: ServerTableHandler<Schema[tov_name]["columns"], Schema>;
}
: Record<string, Partial<ServerTableHandler>>;

Expand All @@ -147,29 +118,20 @@ export type DBHandlerServerExtra<
sql: SQLHandler;
} & Partial<DbJoinMaker> &
(WithTransactions extends true ? { tx: TX<TH> } : Record<string, never>);
// export type DBOFullyTyped<Schema = void> = Schema extends DBSchema? (
// DBTableHandlersFromSchema<Schema> & DBHandlerServerExtra<DBTableHandlersFromSchema<Schema>>
// ) :
// DBHandlerServer;

export type DBOFullyTyped<Schema = void> = DBTableHandlersFromSchema<Schema> &
DBHandlerServerExtra<DBTableHandlersFromSchema<Schema>>;

export type PublishFullyTyped<Schema = void> = Schema extends DBSchema
?
| PublishAllOrNothing
| {
[tov_name in keyof Partial<Schema>]:
| PublishAllOrNothing
| (Schema[tov_name]["is_view"] extends true
? PublishViewRule<Schema[tov_name]["columns"], Schema>
: PublishTableRule<Schema[tov_name]["columns"], Schema>);
}
:
| PublishAllOrNothing
| Record<
string,
PublishViewRule | PublishTableRule | PublishAllOrNothing
>;
export type PublishFullyTyped<Schema = void> =
Schema extends DBSchema ?
{
[tov_name in keyof Partial<Schema>]:
| PublishAllOrNothing
| (Schema[tov_name]["is_view"] extends true ?
PublishViewRule<Schema[tov_name]["columns"], Schema>
: PublishTableRule<Schema[tov_name]["columns"], Schema>);
}
: Record<string, PublishViewRule | PublishTableRule | PublishAllOrNothing>;

/** Type checks */
() => {
Expand Down
13 changes: 8 additions & 5 deletions lib/PublishParser/PublishParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ import {
RULE_TO_METHODS,
TableRule,
} from "./publishTypesAndUtils";
import { ProstglesInitOptions } from "../ProstglesTypes";
import { PublishFullyTyped } from "../DBSchemaBuilder";

export class PublishParser {
publish: any;
publish: ProstglesInitOptions["publish"];
publishMethods?: PublishMethods<void, SessionUser> | undefined;
publishRawSQL?: any;
dbo: DBHandlerServer;
Expand Down Expand Up @@ -86,10 +88,11 @@ export class PublishParser {

/**
* Parses the first level of publish. (If false then nothing if * then all tables and views)
* @param socket
* @param user
*/
async getPublish(localParams: LocalParams, clientInfo?: AuthResult): Promise<PublishObject> {
async getPublish(
localParams: LocalParams,
clientInfo?: AuthResult
): Promise<PublishFullyTyped | undefined> {
const publishParams = await this.getPublishParams(localParams, clientInfo);
const _publish = await applyParamsIfFunc(this.publish, publishParams);

Expand All @@ -101,7 +104,7 @@ export class PublishParser {
return publish;
}

return _publish;
return _publish || undefined;
}
async getValidatedRequestRuleWusr({
tableName,
Expand Down
2 changes: 1 addition & 1 deletion lib/PublishParser/getSchemaFromPublish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export async function getSchemaFromPublish(
throw err;
}

if (Object.keys(_publish).length) {
if (_publish && Object.keys(_publish).length) {
let txKey = "tx";
if (!this.prostgles.opts.transactions) txKey = "";
if (typeof this.prostgles.opts.transactions === "string")
Expand Down
7 changes: 2 additions & 5 deletions lib/PublishParser/getTableRulesWithoutFileTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,11 @@ export async function getTableRulesWithoutFileTable(
): Promise<ParsedPublishTable | undefined> {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!localParams || !tableName)
throw {
stack: ["getTableRules()"],
message: "publish OR socket OR dbo OR tableName are missing",
};
throw new Error("publish OR socket OR dbo OR tableName are missing");

const _publish = overridenPublish ?? (await this.getPublish(localParams, clientInfo));

const raw_table_rules = _publish[tableName];
const raw_table_rules = _publish?.[tableName];
if (
!raw_table_rules ||
(isObject(raw_table_rules) && Object.values(raw_table_rules).every((v) => !v))
Expand Down
93 changes: 24 additions & 69 deletions lib/PublishParser/publishTypesAndUtils.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import {
AnyObject,
DBSchema,
FullFilter,
Method,
RULE_METHODS,
} from "prostgles-types";
import { AnyObject, DBSchema, FullFilter, Method, RULE_METHODS } from "prostgles-types";
import type { DBOFullyTyped, PublishFullyTyped } from "../DBSchemaBuilder";
import {
CommonTableRules,
Expand All @@ -15,11 +9,8 @@ import {
} from "../DboBuilder/DboBuilder";
import { DB, DBHandlerServer } from "../Prostgles";

export type PublishMethods<
S = void,
SUser extends SessionUser = SessionUser,
> = (
params: PublishParams<S, SUser>,
export type PublishMethods<S = void, SUser extends SessionUser = SessionUser> = (
params: PublishParams<S, SUser>
) => { [key: string]: Method } | Promise<{ [key: string]: Method } | null>;

export type Awaitable<T> = T | Promise<T>;
Expand Down Expand Up @@ -171,10 +162,7 @@ export type DeleteRequestData = {
filter: object;
returning: FieldFilter;
};
export type UpdateRequestDataOne<
R extends AnyObject,
S extends DBSchema | void = void,
> = {
export type UpdateRequestDataOne<R extends AnyObject, S extends DBSchema | void = void> = {
filter: FullFilter<R, S>;
data: Partial<R>;
returning: FieldFilter<R>;
Expand All @@ -195,42 +183,28 @@ export type ValidateRowArgs<R = AnyObject, DBX = DBHandlerServer> = {
dbx: DBX;
localParams: LocalParams;
};
export type ValidateUpdateRowArgs<
U = Partial<AnyObject>,
F = Filter,
DBX = DBHandlerServer,
> = {
export type ValidateUpdateRowArgs<U = Partial<AnyObject>, F = Filter, DBX = DBHandlerServer> = {
update: U;
filter: F;
dbx: DBX;
localParams: LocalParams;
};
export type ValidateRow<R extends AnyObject = AnyObject, S = void> = (
args: ValidateRowArgs<R, DBOFullyTyped<S>>,
args: ValidateRowArgs<R, DBOFullyTyped<S>>
) => R | Promise<R>;
export type PostValidateRow<R extends AnyObject = AnyObject, S = void> = (
args: ValidateRowArgs<R, DBOFullyTyped<S>>,
) => void | Promise<void>;
export type PostValidateRowBasic = (
args: ValidateRowArgs,
args: ValidateRowArgs<R, DBOFullyTyped<S>>
) => void | Promise<void>;
export type ValidateRowBasic = (
args: ValidateRowArgs,
) => AnyObject | Promise<AnyObject>;
export type ValidateUpdateRow<
R extends AnyObject = AnyObject,
S extends DBSchema | void = void,
> = (
args: ValidateUpdateRowArgs<Partial<R>, FullFilter<R, S>, DBOFullyTyped<S>>,
export type PostValidateRowBasic = (args: ValidateRowArgs) => void | Promise<void>;
export type ValidateRowBasic = (args: ValidateRowArgs) => AnyObject | Promise<AnyObject>;
export type ValidateUpdateRow<R extends AnyObject = AnyObject, S extends DBSchema | void = void> = (
args: ValidateUpdateRowArgs<Partial<R>, FullFilter<R, S>, DBOFullyTyped<S>>
) => Partial<R> | Promise<Partial<R>>;
export type ValidateUpdateRowBasic = (
args: ValidateUpdateRowArgs,
args: ValidateUpdateRowArgs
) => AnyObject | Promise<AnyObject>;

export type SelectRule<
Cols extends AnyObject = AnyObject,
S extends DBSchema | void = void,
> = {
export type SelectRule<Cols extends AnyObject = AnyObject, S extends DBSchema | void = void> = {
/**
* Fields allowed to be selected.
* Tip: Use false to exclude field
Expand Down Expand Up @@ -261,9 +235,7 @@ export type SelectRule<
/**
* Validation logic to check/update data for each request
*/
validate?(
args: SelectRequestData,
): SelectRequestData | Promise<SelectRequestData>;
validate?(args: SelectRequestData): SelectRequestData | Promise<SelectRequestData>;
};

export type CommonInsertUpdateRule<
Expand Down Expand Up @@ -311,9 +283,7 @@ export type InsertRule<
* Validation logic to check/update data after the insert.
* Happens in the same transaction so upon throwing an error the record will be deleted (not committed)
*/
postValidate?: S extends DBSchema
? PostValidateRow<Required<Cols>, S>
: PostValidateRowBasic;
postValidate?: S extends DBSchema ? PostValidateRow<Required<Cols>, S> : PostValidateRowBasic;

/**
* If defined then only nested inserts from these tables are allowed
Expand Down Expand Up @@ -365,23 +335,16 @@ export type UpdateRule<
/**
* Validation logic to check/update data for each request
*/
validate?: S extends DBSchema
? ValidateUpdateRow<Cols, S>
: ValidateUpdateRowBasic;
validate?: S extends DBSchema ? ValidateUpdateRow<Cols, S> : ValidateUpdateRowBasic;

/**
* Validation logic to check/update data after the insert.
* Happens in the same transaction so upon throwing an error the record will be deleted (not committed)
*/
postValidate?: S extends DBSchema
? PostValidateRow<Required<Cols>, S>
: PostValidateRowBasic;
postValidate?: S extends DBSchema ? PostValidateRow<Required<Cols>, S> : PostValidateRowBasic;
};

export type DeleteRule<
Cols extends AnyObject = AnyObject,
S extends DBSchema | void = void,
> = {
export type DeleteRule<Cols extends AnyObject = AnyObject, S extends DBSchema | void = void> = {
/**
* Filter added to every query (e.g. user_id) to restrict access
*/
Expand Down Expand Up @@ -448,10 +411,7 @@ export type TableRule<
sync?: SyncRule<RowType>;
subscribe?: SubscribeRule;
};
export type PublishViewRule<
Col extends AnyObject = AnyObject,
S extends DBSchema | void = void,
> = {
export type PublishViewRule<Col extends AnyObject = AnyObject, S extends DBSchema | void = void> = {
select?: SelectRule<Col, S> | PublishAllOrNothing;
getColumns?: PublishAllOrNothing;
getInfo?: PublishAllOrNothing;
Expand Down Expand Up @@ -495,19 +455,14 @@ export type PublishParams<S = void, SUser extends SessionUser = SessionUser> = {
export type RequestParams = { dbo?: DBHandlerServer; socket?: any };
export type PublishAllOrNothing = boolean | "*" | null;
export type PublishObject = {
[table_name: string]:
| PublishTableRule
| PublishViewRule
| PublishAllOrNothing;
[table_name: string]: PublishTableRule | PublishViewRule | PublishAllOrNothing;
};
export type ParsedPublishTables = {
[table_name: string]: ParsedPublishTable;
};
export type PublishedResult<Schema = void> =
| PublishAllOrNothing
| PublishFullyTyped<Schema>;

type PublishAllOrNothingRoot = Exclude<PublishAllOrNothing, boolean>;
export type PublishedResult<Schema = void> = PublishAllOrNothingRoot | PublishFullyTyped<Schema>;
export type Publish<Schema = void, SUser extends SessionUser = SessionUser> =
| PublishedResult<Schema>
| ((
params: PublishParams<Schema, SUser>,
) => Awaitable<PublishedResult<Schema>>);
| ((params: PublishParams<Schema, SUser>) => Awaitable<PublishedResult<Schema>>);
Loading

0 comments on commit 1e834bb

Please sign in to comment.