added format command and added trailing commas to reduce conflicts

This commit is contained in:
dswbx
2025-02-26 20:06:03 +01:00
parent 88b5359f1c
commit 7743f71a11
414 changed files with 3622 additions and 3610 deletions

View File

@@ -4,7 +4,7 @@ import type { Entity, EntityData, EntityManager } from "../entities";
import {
type EntityRelationAnchor,
type MutationInstructionResponse,
RelationHelper
RelationHelper,
} from "../relations";
import type { RepoQuery } from "../server/data-query-impl";
import type { RelationType } from "./relation-types";
@@ -25,7 +25,7 @@ export type BaseRelationConfig = Static<typeof EntityRelation.schema>;
// @todo: add generic type for relation config
export abstract class EntityRelation<
Schema extends typeof EntityRelation.schema = typeof EntityRelation.schema
Schema extends typeof EntityRelation.schema = typeof EntityRelation.schema,
> {
config: Static<Schema>;
@@ -39,14 +39,14 @@ export abstract class EntityRelation<
static schema = Type.Object({
mappedBy: Type.Optional(Type.String()),
inversedBy: Type.Optional(Type.String()),
required: Type.Optional(Type.Boolean())
required: Type.Optional(Type.Boolean()),
});
// don't make protected, App requires it to instantiatable
constructor(
source: EntityRelationAnchor,
target: EntityRelationAnchor,
config: Partial<Static<Schema>> = {}
config: Partial<Static<Schema>> = {},
) {
this.source = source;
this.target = target;
@@ -67,13 +67,13 @@ export abstract class EntityRelation<
*/
abstract buildWith(
entity: Entity,
reference: string
reference: string,
): (eb: ExpressionBuilder<any, any>) => KyselyQueryBuilder;
abstract buildJoin(
entity: Entity,
qb: KyselyQueryBuilder,
reference: string
reference: string,
): KyselyQueryBuilder;
getReferenceQuery(entity: Entity, id: number, reference: string): Partial<RepoQuery> {
@@ -105,7 +105,7 @@ export abstract class EntityRelation<
throw new Error(
`Entity "${entity_name}" is not part of the relation ` +
`"${this.source.entity.name} <-> ${this.target.entity.name}"`
`"${this.source.entity.name} <-> ${this.target.entity.name}"`,
);
}
@@ -141,7 +141,7 @@ export abstract class EntityRelation<
if (Array.isArray(hydrated) && hydrated.length > 1) {
throw new Error(
`Failed to hydrate "${anchor.entity.name}" ` +
`with value: ${JSON.stringify(value)} (cardinality: 1)`
`with value: ${JSON.stringify(value)} (cardinality: 1)`,
);
}
@@ -151,7 +151,7 @@ export abstract class EntityRelation<
if (!hydrated) {
throw new Error(
`Failed to hydrate "${anchor.entity.name}" ` +
`with value: ${JSON.stringify(value)} (cardinality: -)`
`with value: ${JSON.stringify(value)} (cardinality: -)`,
);
}
@@ -178,7 +178,7 @@ export abstract class EntityRelation<
async $set(
em: EntityManager<any>,
key: string,
value: unknown
value: unknown,
): Promise<void | MutationInstructionResponse> {
throw new Error("$set is not allowed");
}
@@ -186,7 +186,7 @@ export abstract class EntityRelation<
async $create(
em: EntityManager<any>,
key: string,
value: unknown
value: unknown,
): Promise<void | MutationInstructionResponse> {
throw new Error("$create is not allowed");
}
@@ -194,7 +194,7 @@ export abstract class EntityRelation<
async $attach(
em: EntityManager<any>,
key: string,
value: unknown
value: unknown,
): Promise<void | MutationInstructionResponse> {
throw new Error("$attach is not allowed");
}
@@ -202,7 +202,7 @@ export abstract class EntityRelation<
async $detach(
em: EntityManager<any>,
key: string,
value: unknown
value: unknown,
): Promise<void | MutationInstructionResponse> {
throw new Error("$detach is not allowed");
}
@@ -213,7 +213,7 @@ export abstract class EntityRelation<
this.source.entity.name,
this.target.entity.name,
this.config.mappedBy,
this.config.inversedBy
this.config.inversedBy,
].filter(Boolean);
return parts.join("_");
}
@@ -223,7 +223,7 @@ export abstract class EntityRelation<
type: this.type(),
source: this.source.entity.name,
target: this.target.entity.name,
config: this.config
config: this.config,
};
}
}

View File

@@ -21,19 +21,19 @@ export class ManyToManyRelation extends EntityRelation<typeof ManyToManyRelation
EntityRelation.schema,
Type.Object({
connectionTable: Type.Optional(Type.String()),
connectionTableMappedName: Type.Optional(Type.String())
})
connectionTableMappedName: Type.Optional(Type.String()),
}),
],
{
additionalProperties: false
}
additionalProperties: false,
},
);
constructor(
source: Entity,
target: Entity,
config?: ManyToManyRelationConfig,
additionalFields?: Field[]
additionalFields?: Field[],
) {
const connectionTable =
config?.connectionTable || ManyToManyRelation.defaultConnectionTable(source, target);
@@ -67,12 +67,12 @@ export class ManyToManyRelation extends EntityRelation<typeof ManyToManyRelation
getField(entity: Entity): RelationField {
const conn = this.connectionEntity;
const selfField = conn.fields.find(
(f) => f instanceof RelationField && f.target() === entity.name
(f) => f instanceof RelationField && f.target() === entity.name,
)!;
if (!selfField || !(selfField instanceof RelationField)) {
throw new Error(
`Connection entity "${conn.name}" does not have a relation to "${entity.name}"`
`Connection entity "${conn.name}" does not have a relation to "${entity.name}"`,
);
}
@@ -87,7 +87,7 @@ export class ManyToManyRelation extends EntityRelation<typeof ManyToManyRelation
const join = [
conn.name,
`${other.entity.name}.${other.entity.getPrimaryField().name}`,
`${conn.name}.${otherField.name}`
`${conn.name}.${otherField.name}`,
] as const;
const entityRef = `${entity.name}.${entity.getPrimaryField().name}`;
@@ -100,7 +100,7 @@ export class ManyToManyRelation extends EntityRelation<typeof ManyToManyRelation
join,
entityRef,
otherRef,
groupBy
groupBy,
};
}
@@ -109,9 +109,9 @@ export class ManyToManyRelation extends EntityRelation<typeof ManyToManyRelation
return {
where: {
[otherRef]: id
[otherRef]: id,
},
join: [other.reference]
join: [other.reference],
};
}
@@ -136,7 +136,7 @@ export class ManyToManyRelation extends EntityRelation<typeof ManyToManyRelation
const limit = 5;
const { other, join, entityRef, otherRef } = this.getQueryInfo(entity);
const additionalFields = this.connectionEntity.fields.filter(
(f) => !(f instanceof RelationField || f instanceof PrimaryField)
(f) => !(f instanceof RelationField || f instanceof PrimaryField),
);
return (eb: ExpressionBuilder<any, any>) =>
@@ -149,9 +149,9 @@ export class ManyToManyRelation extends EntityRelation<typeof ManyToManyRelation
select.push(
jsonBuildObject(
Object.fromEntries(
additionalFields.map((f) => [f.name, eb2.ref(`${conn}.${f.name}`)])
)
).as(this.connectionTableMappedName)
additionalFields.map((f) => [f.name, eb2.ref(`${conn}.${f.name}`)]),
),
).as(this.connectionTableMappedName),
);
}
@@ -186,7 +186,7 @@ export class ManyToManyRelation extends EntityRelation<typeof ManyToManyRelation
override getName(): string {
return [
super.getName(),
[this.connectionEntity.name, this.connectionTableMappedName].filter(Boolean)
[this.connectionEntity.name, this.connectionTableMappedName].filter(Boolean),
].join("_");
}
}

View File

@@ -23,7 +23,7 @@ export type ManyToOneRelationConfig = Static<typeof ManyToOneRelation.schema>;
export class ManyToOneRelation extends EntityRelation<typeof ManyToOneRelation.schema> {
private fieldConfig?: RelationFieldBaseConfig;
static DEFAULTS = {
with_limit: 5
with_limit: 5,
};
static override schema = Type.Composite(
@@ -32,24 +32,24 @@ export class ManyToOneRelation extends EntityRelation<typeof ManyToOneRelation.s
Type.Object({
sourceCardinality: Type.Optional(Type.Number()),
with_limit: Type.Optional(
Type.Number({ default: ManyToOneRelation.DEFAULTS.with_limit })
Type.Number({ default: ManyToOneRelation.DEFAULTS.with_limit }),
),
fieldConfig: Type.Optional(
Type.Object({
label: Type.String()
})
)
})
label: Type.String(),
}),
),
}),
],
{
additionalProperties: false
}
additionalProperties: false,
},
);
constructor(
source: Entity,
target: Entity,
config: Partial<Static<typeof ManyToOneRelation.schema>> = {}
config: Partial<Static<typeof ManyToOneRelation.schema>> = {},
) {
const mappedBy = config.mappedBy || target.name;
const inversedBy = config.inversedBy || source.name;
@@ -78,15 +78,15 @@ export class ManyToOneRelation extends EntityRelation<typeof ManyToOneRelation.s
// add required mapping field on source
const field = RelationField.create(this, this.target, {
label: defaultLabel,
...this.fieldConfig
...this.fieldConfig,
});
if (!this.source.entity.field(field.name)) {
this.source.entity.addField(
RelationField.create(this, this.target, {
label: defaultLabel,
...this.fieldConfig
})
...this.fieldConfig,
}),
);
}
}
@@ -100,7 +100,7 @@ export class ManyToOneRelation extends EntityRelation<typeof ManyToOneRelation.s
if (!(field instanceof RelationField)) {
throw new Error(
`Field "${this.target.reference}_${id}" not found on entity "${this.source.entity.name}"`
`Field "${this.target.reference}_${id}" not found on entity "${this.source.entity.name}"`,
);
}
@@ -133,7 +133,7 @@ export class ManyToOneRelation extends EntityRelation<typeof ManyToOneRelation.s
relationRef,
entityRef,
otherRef,
groupBy
groupBy,
};
}
@@ -145,9 +145,9 @@ export class ManyToOneRelation extends EntityRelation<typeof ManyToOneRelation.s
return {
where: {
[otherRef]: id
[otherRef]: id,
},
join: other.entity.name === self.entity.name ? [] : [other.entity.name]
join: other.entity.name === self.entity.name ? [] : [other.entity.name],
};
}
@@ -176,7 +176,7 @@ export class ManyToOneRelation extends EntityRelation<typeof ManyToOneRelation.s
override async $set(
em: EntityManager<any>,
key: string,
value: object
value: object,
): Promise<void | MutationInstructionResponse> {
if (typeof value !== "object") {
throw new Error(`Invalid value for relation field "${key}" given, expected object.`);
@@ -204,14 +204,14 @@ export class ManyToOneRelation extends EntityRelation<typeof ManyToOneRelation.s
}
const query = await em.repository(field.target()).exists({
[field.targetField()]: primaryReference as any
[field.targetField()]: primaryReference as any,
});
if (!query.exists) {
const idProp = field.targetField();
throw new Error(
`Cannot connect "${entity.name}.${key}" to ` +
`"${field.target()}.${idProp}" = "${primaryReference}": not found.`
`"${field.target()}.${idProp}" = "${primaryReference}": not found.`,
);
}

View File

@@ -22,7 +22,7 @@ export class OneToOneRelation extends ManyToOneRelation {
mappedBy,
inversedBy,
sourceCardinality: 1,
required
required,
});
}
@@ -41,7 +41,7 @@ export class OneToOneRelation extends ManyToOneRelation {
override async $set(
em: EntityManager<any>,
key: string,
value: object
value: object,
): Promise<MutationInstructionResponse> {
throw new Error("$set is not allowed");
}
@@ -49,7 +49,7 @@ export class OneToOneRelation extends ManyToOneRelation {
override async $create(
em: EntityManager<any>,
key: string,
value: unknown
value: unknown,
): Promise<void | MutationInstructionResponse> {
if (value === null || typeof value !== "object") {
throw new Error(`Invalid value for relation field "${key}" given, expected object.`);

View File

@@ -15,12 +15,12 @@ export class PolymorphicRelation extends EntityRelation<typeof PolymorphicRelati
[
EntityRelation.schema,
Type.Object({
targetCardinality: Type.Optional(Type.Number())
})
targetCardinality: Type.Optional(Type.Number()),
}),
],
{
additionalProperties: false
}
additionalProperties: false,
},
);
constructor(source: Entity, target: Entity, config: Partial<PolymorphicRelationConfig> = {}) {
@@ -63,7 +63,7 @@ export class PolymorphicRelation extends EntityRelation<typeof PolymorphicRelati
reference_other,
entityRef,
otherRef,
groupBy
groupBy,
};
}
@@ -72,7 +72,7 @@ export class PolymorphicRelation extends EntityRelation<typeof PolymorphicRelati
return qb
.innerJoin(other.entity.name, (join) =>
join.onRef(entityRef, "=", otherRef).on(whereLhs, "=", reference)
join.onRef(entityRef, "=", otherRef).on(whereLhs, "=", reference),
)
.groupBy(groupBy);
}
@@ -83,8 +83,8 @@ export class PolymorphicRelation extends EntityRelation<typeof PolymorphicRelati
return {
where: {
[this.getReferenceField().name]: info.reference_other,
[this.getEntityIdField().name]: id
}
[this.getEntityIdField().name]: id,
},
};
}

View File

@@ -12,8 +12,8 @@ export const relationFieldConfigSchema = Type.Composite([
reference: Type.String(),
target: Type.String(), // @todo: potentially has to be an instance!
target_field: Type.Optional(Type.String({ default: "id" })),
on_delete: Type.Optional(StringEnum(CASCADES, { default: "set null" }))
})
on_delete: Type.Optional(StringEnum(CASCADES, { default: "set null" })),
}),
]);
/*export const relationFieldConfigSchema = baseFieldConfigSchema.extend({
reference: z.string(),
@@ -44,11 +44,11 @@ export class RelationField extends Field<RelationFieldConfig> {
static create(
relation: EntityRelation,
target: EntityRelationAnchor,
config?: RelationFieldBaseConfig
config?: RelationFieldBaseConfig,
) {
const name = [
target.reference ?? target.entity.name,
target.entity.getPrimaryField().name
target.entity.getPrimaryField().name,
].join("_");
//console.log('name', name);
return new RelationField(name, {
@@ -56,7 +56,7 @@ export class RelationField extends Field<RelationFieldConfig> {
required: relation.required,
reference: target.reference,
target: target.entity.name,
target_field: target.entity.getPrimaryField().name
target_field: target.entity.getPrimaryField().name,
});
}
@@ -94,8 +94,8 @@ export class RelationField extends Field<RelationFieldConfig> {
override toJsonSchema() {
return this.toSchemaWrapIfRequired(
Type.Number({
$ref: `${this.config?.target}#/properties/${this.config?.target_field}`
})
$ref: `${this.config?.target}#/properties/${this.config?.target_field}`,
}),
);
}
}

View File

@@ -5,7 +5,7 @@ import {
ManyToManyRelation,
type MutationOperation,
MutationOperations,
RelationField
RelationField,
} from "../relations";
export type MutationInstructionResponse = [string, PrimaryFieldType | null];
@@ -13,7 +13,7 @@ export type MutationInstructionResponse = [string, PrimaryFieldType | null];
export class RelationMutator {
constructor(
protected entity: Entity,
protected em: EntityManager<any>
protected em: EntityManager<any>,
) {}
/**
@@ -32,11 +32,11 @@ export class RelationMutator {
// @todo: improve later
if (this.entity.type === "generated") {
const relation = this.em.relations.all.find(
(r) => r instanceof ManyToManyRelation && r.connectionEntity.name === this.entity.name
(r) => r instanceof ManyToManyRelation && r.connectionEntity.name === this.entity.name,
);
if (relation instanceof ManyToManyRelation) {
references.push(
...this.entity.fields.filter((f) => f.type === "relation").map((f) => f.name)
...this.entity.fields.filter((f) => f.type === "relation").map((f) => f.name),
);
}
}
@@ -53,7 +53,7 @@ export class RelationMutator {
async persistRelationField(
field: RelationField,
key: string,
value: PrimaryFieldType
value: PrimaryFieldType,
): Promise<MutationInstructionResponse> {
// allow empty if field is not required
if (value === null && !field.isRequired()) {
@@ -68,14 +68,14 @@ export class RelationMutator {
}
const query = await this.em.repository(field.target()).exists({
[field.targetField()]: value
[field.targetField()]: value,
});
if (!query.exists) {
const idProp = field.targetField();
throw new Error(
`Cannot connect "${this.entity.name}.${key}" to ` +
`"${field.target()}.${idProp}" = "${value}": not found.`
`"${field.target()}.${idProp}" = "${value}": not found.`,
);
}
@@ -85,11 +85,11 @@ export class RelationMutator {
async persistReference(
relation: EntityRelation,
key: string,
value: unknown
value: unknown,
): Promise<void | MutationInstructionResponse> {
if (typeof value !== "object" || value === null || typeof value === "undefined") {
throw new Error(
`Invalid value for relation "${key}" given, expected object to persist reference. Like '{$set: {id: 1}}'.`
`Invalid value for relation "${key}" given, expected object to persist reference. Like '{$set: {id: 1}}'.`,
);
}
@@ -97,7 +97,7 @@ export class RelationMutator {
if (!MutationOperations.includes(operation)) {
throw new Error(
`Invalid operation "${operation}" for relation "${key}". ` +
`Allowed: ${MutationOperations.join(", ")}`
`Allowed: ${MutationOperations.join(", ")}`,
);
}
@@ -131,7 +131,7 @@ export class RelationMutator {
throw new Error(
`Relation "${key}" failed to resolve on entity "${this.entity.name}": ` +
"Unable to resolve relation origin."
"Unable to resolve relation origin.",
);
}
}

View File

@@ -14,7 +14,7 @@ import {
RelationField,
type RelationFieldBaseConfig,
type RelationFieldConfig,
relationFieldConfigSchema
relationFieldConfigSchema,
} from "./RelationField";
export {
@@ -32,7 +32,7 @@ export {
RelationField,
relationFieldConfigSchema,
type RelationFieldBaseConfig,
type RelationFieldConfig
type RelationFieldConfig,
};
export const RelationClassMap = {
@@ -41,10 +41,10 @@ export const RelationClassMap = {
[RelationTypes.ManyToMany]: { schema: ManyToManyRelation.schema, cls: ManyToManyRelation },
[RelationTypes.Polymorphic]: {
schema: PolymorphicRelation.schema,
cls: PolymorphicRelation
}
cls: PolymorphicRelation,
},
} as const;
export const RelationFieldClassMap = {
relation: { schema: relationFieldConfigSchema, field: RelationField }
relation: { schema: relationFieldConfigSchema, field: RelationField },
} as const;