Skip to content

Commit

Permalink
Merge pull request #89 from tyler-neal/main
Browse files Browse the repository at this point in the history
Add maxLength to column decorator for types string | string[]
  • Loading branch information
jgeurts committed Jan 5, 2024
2 parents 6efa9c6 + cb6afde commit 98df33b
Show file tree
Hide file tree
Showing 7 changed files with 383 additions and 5 deletions.
28 changes: 28 additions & 0 deletions src/SqlHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,20 @@ export function getInsertQueryAndParams<T extends Entity, K extends string & key
}
} else {
includePropertyName = true;

// Check and enforce max length for applicable types
const { maxLength, type } = column as ColumnTypeMetadata;

if (maxLength && ['string', 'string[]'].includes(type)) {
const entityValues = entity[column.propertyName as string & keyof CreateUpdateParams<T>];
const normalizedValues = (Array.isArray(entityValues) ? entityValues : [entityValues]) as string[];

for (const normalizedValue of normalizedValues) {
if (normalizedValue.length > maxLength) {
throw new QueryError(`Create statement for "${model.name}" contains a value that exceeds maxLength on field: ${column.propertyName}`, model);
}
}
}
}
}

Expand Down Expand Up @@ -434,6 +448,20 @@ export function getUpdateQueryAndParams<T extends Entity>({
} else {
const isJsonArray = (column as ColumnTypeMetadata).type === 'json' && _.isArray(value);
const relatedModelName = (column as ColumnModelMetadata).model;

// Check and enforce max length for applicable types
const { maxLength, type } = column as ColumnTypeMetadata;

if (maxLength && ['string', 'string[]'].includes(type)) {
const normalizedValues = (Array.isArray(value) ? value : [value]) as string[];

for (const normalizedValue of normalizedValues) {
if (normalizedValue.length > maxLength) {
throw new QueryError(`Update statement for "${model.name}" contains a value that exceeds maxLength on field: ${column.propertyName}`, model);
}
}
}

if (relatedModelName && _.isObject(value)) {
const relatedModelRepository = repositoriesByModelNameLowered[relatedModelName.toLowerCase()];

Expand Down
6 changes: 6 additions & 0 deletions src/decorators/ColumnTypeOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,10 @@ export interface ColumnTypeOptions extends ColumnBaseOptions {
* Array of possible enumerated values
*/
enum?: string[];
/**
* If set, enforces a maximum length check on the column
*
* Applies to types: string | string[]
*/
maxLength?: number;
}
1 change: 1 addition & 0 deletions src/decorators/column.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export function column(dbColumnNameOrOptions?: ColumnOptions | string, options?:
type: columnTypeOptions.type,
defaultsTo: columnTypeOptions.defaultsTo,
enum: columnTypeOptions.enum,
maxLength: columnTypeOptions.maxLength,
}),
);
};
Expand Down
14 changes: 14 additions & 0 deletions src/metadata/ColumnTypeMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ export interface ColumnTypeMetadataOptions extends ColumnBaseMetadataOptions {
* Array of possible enumerated values
*/
enum?: string[];
/**
* If set, enforces a maximum length check on the column
*
* Applies to types: string | string[]
*/
maxLength?: number;
}

export class ColumnTypeMetadata extends ColumnBaseMetadata {
Expand All @@ -32,6 +38,13 @@ export class ColumnTypeMetadata extends ColumnBaseMetadata {
*/
public enum?: string[];

/**
* If set, enforces a maximum length check on the column
*
* Applies to types: string | string[]
*/
public maxLength?: number;

public constructor(options: ColumnTypeMetadataOptions) {
super({
target: options.target,
Expand All @@ -49,5 +62,6 @@ export class ColumnTypeMetadata extends ColumnBaseMetadata {
this.type = options.type;
this.defaultsTo = options.defaultsTo;
this.enum = options.enum;
this.maxLength = options.maxLength;
}
}
47 changes: 47 additions & 0 deletions tests/models/ImportedItem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { column, primaryColumn, table, Entity } from '../../src';

@table({
name: 'imported_item',
})
export class ImportedItem extends Entity {
@primaryColumn({ type: 'string' })
public id!: string;

@column({
type: 'string',
required: true,
name: 'name',
})
public name!: string;

@column({
type: 'string',
required: false,
name: 'external_id_no_max_length',
})
public externalIdNoMaxLength?: string;

@column({
type: 'string',
required: false,
name: 'external_id_string',
maxLength: 5,
})
public externalIdString?: string;

@column({
type: 'string[]',
required: false,
name: 'external_id_string_array',
maxLength: 10,
})
public externalIdStringArray?: string[];

@column({
type: 'integer',
required: false,
name: 'unrelated',
maxLength: 2,
})
public unrelated?: number;
}
3 changes: 2 additions & 1 deletion tests/models/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
export * from './Category';
export * from './Classroom';
export * from './ImportedItem';
export * from './KitchenSink';
export * from './LevelOne';
export * from './LevelTwo';
export * from './LevelThree';
export * from './LevelTwo';
export * from './ParkingLot';
export * from './ParkingSpace';
export * from './Product';
Expand Down
Loading

0 comments on commit 98df33b

Please sign in to comment.