refactor: uuid & nanoid support default value configuration (#3830)

* refactor: uuid & nanoid support default value

* chore: autoFill attribute in uuid & nanoid field

* chore: test

---------

Co-authored-by: Chareice <chareice@live.com>
This commit is contained in:
katherinehhh 2024-03-30 20:45:27 +08:00 committed by GitHub
parent 8a1345a5b8
commit 2d7a427c5a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 85 additions and 18 deletions

View File

@ -1,5 +1,5 @@
import { CollectionFieldInterface } from '../../data-source/collection-field-interface/CollectionFieldInterface'; import { CollectionFieldInterface } from '../../data-source/collection-field-interface/CollectionFieldInterface';
import { operators } from './properties'; import { operators, autoFill } from './properties';
export class NanoidFieldInterface extends CollectionFieldInterface { export class NanoidFieldInterface extends CollectionFieldInterface {
name = 'nanoid'; name = 'nanoid';
type = 'object'; type = 'object';
@ -48,6 +48,7 @@ export class NanoidFieldInterface extends CollectionFieldInterface {
'x-decorator': 'FormItem', 'x-decorator': 'FormItem',
'x-component': 'InputNumber', 'x-component': 'InputNumber',
}, },
autoFill,
}; };
filterable = { filterable = {
operators: operators.string, operators: operators.string,

View File

@ -79,6 +79,15 @@ export const autoIncrement = {
'x-disabled': '{{ !createMainOnly }}', 'x-disabled': '{{ !createMainOnly }}',
}; };
export const autoFill = {
type: 'boolean',
title: '{{t("Default value")}}',
'x-content': '{{t("Automatically generate default values")}}',
'x-decorator': 'FormItem',
'x-component': 'Checkbox',
'x-disabled': '{{ !createMainOnly }}',
};
export const relationshipType: ISchema = { export const relationshipType: ISchema = {
type: 'string', type: 'string',
title: '{{t("Relationship type")}}', title: '{{t("Relationship type")}}',

View File

@ -1,5 +1,5 @@
import { CollectionFieldInterface } from '../../data-source/collection-field-interface/CollectionFieldInterface'; import { CollectionFieldInterface } from '../../data-source/collection-field-interface/CollectionFieldInterface';
import { operators } from './properties'; import { operators, autoFill } from './properties';
export class UUIDFieldInterface extends CollectionFieldInterface { export class UUIDFieldInterface extends CollectionFieldInterface {
name = 'uuid'; name = 'uuid';
@ -36,6 +36,7 @@ export class UUIDFieldInterface extends CollectionFieldInterface {
description: description:
"{{t('Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.')}}", "{{t('Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.')}}",
}, },
autoFill,
}; };
filterable = { filterable = {
operators: operators.string, operators: operators.string,

View File

@ -918,5 +918,6 @@
"Multiply by":"乘以", "Multiply by":"乘以",
"Divide by":"除以", "Divide by":"除以",
"Scientifix notation":"科学计数法", "Scientifix notation":"科学计数法",
"Normal":"常规" "Normal":"常规",
"Automatically generate default values":"随机生成默认值"
} }

View File

@ -25,7 +25,8 @@
"qs": "^6.11.2", "qs": "^6.11.2",
"semver": "^7.3.7", "semver": "^7.3.7",
"sequelize": "^6.26.0", "sequelize": "^6.26.0",
"umzug": "^3.1.1" "umzug": "^3.1.1",
"uuid": "^9.0.1"
}, },
"devDependencies": { "devDependencies": {
"@types/glob": "^7.2.0" "@types/glob": "^7.2.0"

View File

@ -36,4 +36,22 @@ describe('nanoid field', () => {
expect(test.id).toHaveLength(21); expect(test.id).toHaveLength(21);
expect(test.id2).toHaveLength(12); expect(test.id2).toHaveLength(12);
}); });
it('should set autofill attribute', async () => {
const Test = db.collection({
name: 'tests',
autoGenId: false,
fields: [
{
type: 'nanoid',
name: 'nanoid',
autoFill: false,
},
],
});
await Test.sync();
const item = await Test.model.create();
expect(item.get('nanoid')).toBeFalsy();
});
}); });

View File

@ -1,7 +1,7 @@
import { mockDatabase } from '../'; import { mockDatabase } from '../';
import { Database } from '../../database'; import { Database } from '../../database';
describe('string field', () => { describe('uuid field', () => {
let db: Database; let db: Database;
beforeEach(async () => { beforeEach(async () => {
@ -29,4 +29,21 @@ describe('string field', () => {
expect(item['uuid']).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/); expect(item['uuid']).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/);
}); });
it('should set autofill attribute', async () => {
const Test = db.collection({
name: 'tests',
fields: [
{
name: 'uuid',
type: 'uuid',
autoFill: false,
},
],
});
await Test.sync();
const item = await Test.model.create();
expect(item['uuid']).toBeFalsy();
});
}); });

View File

@ -9,11 +9,12 @@ export class NanoidField extends Field {
} }
init() { init() {
const { name, size, customAlphabet: customAlphabetOptions } = this.options; const { name, size, customAlphabet: customAlphabetOptions, autoFill } = this.options;
this.listener = async (instance) => { this.listener = async (instance) => {
const value = instance.get(name); const value = instance.get(name);
if (!value) {
if (!value && autoFill !== false) {
const nanoIdFunc = customAlphabetOptions ? customAlphabet(customAlphabetOptions) : nanoid; const nanoIdFunc = customAlphabetOptions ? customAlphabet(customAlphabetOptions) : nanoid;
instance.set(name, nanoIdFunc(size || DEFAULT_SIZE)); instance.set(name, nanoIdFunc(size || DEFAULT_SIZE));
} }
@ -37,4 +38,5 @@ export interface NanoidFieldOptions extends BaseColumnFieldOptions {
type: 'nanoid'; type: 'nanoid';
size?: number; size?: number;
customAlphabet?: string; customAlphabet?: string;
autoFill?: boolean;
} }

View File

@ -1,21 +1,38 @@
import { DataTypes } from 'sequelize'; import { DataTypes } from 'sequelize';
import { BaseColumnFieldOptions, Field, FieldContext } from './field'; import { BaseColumnFieldOptions, Field } from './field';
import { v4 as uuidv4 } from 'uuid';
export class UuidField extends Field { export class UuidField extends Field {
constructor(options?: any, context?: FieldContext) {
super(
{
defaultValue: new DataTypes.UUIDV4(),
...options,
},
context,
);
}
get dataType() { get dataType() {
return DataTypes.UUID; return DataTypes.UUID;
} }
init() {
const { name, autoFill } = this.options;
this.listener = async (instance) => {
const value = instance.get(name);
if (!value && autoFill !== false) {
instance.set(name, uuidv4());
}
};
}
bind() {
super.bind();
this.on('beforeCreate', this.listener);
this.on('beforeUpdate', this.listener);
}
unbind() {
super.unbind();
this.off('beforeCreate', this.listener);
this.off('beforeUpdate', this.listener);
}
} }
export interface UUIDFieldOptions extends BaseColumnFieldOptions { export interface UUIDFieldOptions extends BaseColumnFieldOptions {
type: 'uuid'; type: 'uuid';
autoFill?: boolean;
} }

View File

@ -25692,7 +25692,7 @@ uuid@^8.2.0, uuid@^8.3.2:
resolved "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" resolved "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
uuid@^9.0.0: uuid@^9.0.0, uuid@^9.0.1:
version "9.0.1" version "9.0.1"
resolved "https://registry.npmmirror.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" resolved "https://registry.npmmirror.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30"
integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==