2022-12-16 17:04:22 +08:00
|
|
|
import path from 'path';
|
|
|
|
import { promisify } from 'util';
|
|
|
|
import { randomInt } from 'crypto';
|
|
|
|
|
|
|
|
import { Registry } from '@nocobase/utils';
|
|
|
|
import { Plugin } from '@nocobase/server';
|
|
|
|
import { Pattern, SequenceField } from './fields/sequence-field';
|
|
|
|
|
|
|
|
const asyncRandomInt = promisify(randomInt);
|
|
|
|
|
|
|
|
export default class SequenceFieldPlugin extends Plugin {
|
|
|
|
patternTypes = new Registry<Pattern>();
|
|
|
|
|
|
|
|
async load() {
|
|
|
|
const { app, db, options } = this;
|
|
|
|
|
|
|
|
db.registerFieldTypes({
|
2023-01-08 12:45:02 +08:00
|
|
|
sequence: SequenceField,
|
2022-12-16 17:04:22 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
db.addMigrations({
|
|
|
|
namespace: 'sequence-field',
|
|
|
|
directory: path.resolve(__dirname, 'migrations'),
|
|
|
|
context: {
|
|
|
|
plugin: this,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2023-01-08 12:45:02 +08:00
|
|
|
await this.importCollections(path.resolve(__dirname, 'collections'));
|
2022-12-16 17:04:22 +08:00
|
|
|
|
|
|
|
db.on('fields.beforeSave', async (field, { transaction }) => {
|
|
|
|
if (field.get('type') !== 'sequence') {
|
|
|
|
return;
|
|
|
|
}
|
2023-01-08 12:45:02 +08:00
|
|
|
const patterns = (field.get('patterns') || []).filter((p) => p.type === 'integer');
|
2022-12-16 17:04:22 +08:00
|
|
|
if (!patterns.length) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const SequenceRepo = db.getRepository('sequences');
|
2023-01-08 12:45:02 +08:00
|
|
|
await patterns.reduce(
|
|
|
|
(promise: Promise<any>, p) =>
|
|
|
|
promise.then(async () => {
|
|
|
|
if (p.options?.key == null) {
|
|
|
|
Object.assign(p, {
|
|
|
|
options: {
|
|
|
|
...p.options,
|
|
|
|
key: await asyncRandomInt(1 << 16),
|
|
|
|
},
|
|
|
|
});
|
2022-12-16 17:04:22 +08:00
|
|
|
}
|
2023-01-08 12:45:02 +08:00
|
|
|
}),
|
|
|
|
Promise.resolve(),
|
|
|
|
);
|
2022-12-16 17:04:22 +08:00
|
|
|
const sequences = await SequenceRepo.find({
|
|
|
|
filter: {
|
|
|
|
field: field.get('name'),
|
|
|
|
collection: field.get('collectionName'),
|
2023-01-08 12:45:02 +08:00
|
|
|
key: patterns.map((p) => p.options.key),
|
2022-12-16 17:04:22 +08:00
|
|
|
},
|
2023-01-08 12:45:02 +08:00
|
|
|
transaction,
|
2022-12-16 17:04:22 +08:00
|
|
|
});
|
2023-01-08 12:45:02 +08:00
|
|
|
await patterns.reduce(
|
|
|
|
(promise: Promise<any>, p) =>
|
|
|
|
promise.then(async () => {
|
|
|
|
if (!sequences.find((s) => s.get('key') === p.options.key)) {
|
|
|
|
await SequenceRepo.create({
|
|
|
|
values: {
|
|
|
|
field: field.get('name'),
|
|
|
|
collection: field.get('collectionName'),
|
|
|
|
key: p.options.key,
|
|
|
|
},
|
|
|
|
transaction,
|
|
|
|
});
|
|
|
|
await field.load({ transaction });
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
Promise.resolve(),
|
|
|
|
);
|
2022-12-16 17:04:22 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
db.on('fields.afterDestroy', async (field, { transaction }) => {
|
|
|
|
if (field.get('type') !== 'sequence') {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-01-08 12:45:02 +08:00
|
|
|
const patterns = (field.get('patterns') || []).filter((p) => p.type === 'integer');
|
2022-12-16 17:04:22 +08:00
|
|
|
if (!patterns.length) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const SequenceRepo = db.getRepository('sequences');
|
|
|
|
await SequenceRepo.destroy({
|
|
|
|
filter: {
|
|
|
|
field: field.get('name'),
|
|
|
|
collection: field.get('collectionName'),
|
2023-01-08 12:45:02 +08:00
|
|
|
key: patterns.map((p) => p.key),
|
2022-12-16 17:04:22 +08:00
|
|
|
},
|
2023-01-08 12:45:02 +08:00
|
|
|
transaction,
|
2022-12-16 17:04:22 +08:00
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
async install() {}
|
|
|
|
}
|