@solidxai/core 0.1.6-beta.11 → 0.1.6-beta.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts +4 -3
- package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts.map +1 -1
- package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js +14 -18
- package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js.map +1 -1
- package/package.json +1 -1
- package/src/services/computed-fields/entity/sequence-num-computed-field-provider.ts +22 -37
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { CommonEntity } from "src/entities/common.entity";
|
|
2
2
|
import { ComputedFieldMetadata } from "src/helpers/solid-registry";
|
|
3
|
-
import {
|
|
3
|
+
import { IEntityPostComputeFieldProvider } from "src/interfaces";
|
|
4
4
|
import { DataSource } from "typeorm";
|
|
5
5
|
export interface SequenceNumComputedFieldContext {
|
|
6
6
|
sequenceName: string;
|
|
7
7
|
}
|
|
8
|
-
export declare class SequenceNumComputedFieldProvider<T extends CommonEntity> implements
|
|
8
|
+
export declare class SequenceNumComputedFieldProvider<T extends CommonEntity> implements IEntityPostComputeFieldProvider<T, SequenceNumComputedFieldContext> {
|
|
9
9
|
private readonly dataSource;
|
|
10
10
|
constructor(dataSource: DataSource);
|
|
11
11
|
name(): string;
|
|
12
12
|
help(): string;
|
|
13
|
-
|
|
13
|
+
private generateSequenceValue;
|
|
14
|
+
postComputeAndSaveValue(triggerEntity: T, computedFieldMetadata: ComputedFieldMetadata<SequenceNumComputedFieldContext>): Promise<void>;
|
|
14
15
|
}
|
|
15
16
|
//# sourceMappingURL=sequence-num-computed-field-provider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequence-num-computed-field-provider.d.ts","sourceRoot":"","sources":["../../../../src/services/computed-fields/entity/sequence-num-computed-field-provider.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"sequence-num-computed-field-provider.d.ts","sourceRoot":"","sources":["../../../../src/services/computed-fields/entity/sequence-num-computed-field-provider.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAiB,MAAM,SAAS,CAAC;AAGpD,MAAM,WAAW,+BAA+B;IAC5C,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,qBAEa,gCAAgC,CAAC,CAAC,SAAS,YAAY,CAAE,YAAW,+BAA+B,CAAC,CAAC,EAAE,+BAA+B,CAAC;IAG5I,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,UAAU;IAG3C,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;YAIA,qBAAqB;IA2B7B,uBAAuB,CAAC,aAAa,EAAE,CAAC,EAAE,qBAAqB,EAAE,qBAAqB,CAAC,+BAA+B,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAahJ"}
|
|
@@ -28,13 +28,9 @@ let SequenceNumComputedFieldProvider = class SequenceNumComputedFieldProvider {
|
|
|
28
28
|
help() {
|
|
29
29
|
return "Computed field provider used to create fields whose value is based on some prefix, padding & sequence number.";
|
|
30
30
|
}
|
|
31
|
-
async
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
throw new Error("sequenceName is required for sequence computation");
|
|
35
|
-
}
|
|
36
|
-
await this.dataSource.transaction(async (manager) => {
|
|
37
|
-
const modelSequenceRepo = manager.getRepository(model_sequence_entity_1.ModelSequence);
|
|
31
|
+
async generateSequenceValue(sequenceName, manager) {
|
|
32
|
+
const run = async (mgr) => {
|
|
33
|
+
const modelSequenceRepo = mgr.getRepository(model_sequence_entity_1.ModelSequence);
|
|
38
34
|
const modelSequence = await modelSequenceRepo.findOne({
|
|
39
35
|
where: { sequenceName },
|
|
40
36
|
lock: { mode: "pessimistic_write" }
|
|
@@ -47,19 +43,19 @@ let SequenceNumComputedFieldProvider = class SequenceNumComputedFieldProvider {
|
|
|
47
43
|
const prefix = modelSequence.prefix ?? "";
|
|
48
44
|
const separator = modelSequence.separator ?? "";
|
|
49
45
|
const sequenceString = `${prefix}${separator}${paddedValue}`;
|
|
50
|
-
const entityRepo = manager.getRepository(triggerEntity.constructor);
|
|
51
|
-
const existing = await entityRepo.findOne({
|
|
52
|
-
where: {
|
|
53
|
-
[computedFieldMetadata.fieldName]: sequenceString,
|
|
54
|
-
},
|
|
55
|
-
});
|
|
56
|
-
if (existing) {
|
|
57
|
-
throw new Error(`Duplicate Sequence generated: ${sequenceString}`);
|
|
58
|
-
}
|
|
59
|
-
triggerEntity[computedFieldMetadata.fieldName] = sequenceString;
|
|
60
46
|
modelSequence.currentValue = nextValue;
|
|
61
47
|
await modelSequenceRepo.save(modelSequence);
|
|
62
|
-
|
|
48
|
+
return { sequenceString, currentValue: nextValue };
|
|
49
|
+
};
|
|
50
|
+
return manager ? run(manager) : this.dataSource.transaction(run);
|
|
51
|
+
}
|
|
52
|
+
async postComputeAndSaveValue(triggerEntity, computedFieldMetadata) {
|
|
53
|
+
const { sequenceName } = computedFieldMetadata.computedFieldValueProviderCtxt ?? {};
|
|
54
|
+
if (!sequenceName) {
|
|
55
|
+
throw new Error("sequenceName is required for sequence computation");
|
|
56
|
+
}
|
|
57
|
+
const { sequenceString } = await this.generateSequenceValue(sequenceName);
|
|
58
|
+
await this.dataSource.manager.update(triggerEntity.constructor, triggerEntity.id, { [computedFieldMetadata.fieldName]: sequenceString });
|
|
63
59
|
}
|
|
64
60
|
};
|
|
65
61
|
exports.SequenceNumComputedFieldProvider = SequenceNumComputedFieldProvider;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequence-num-computed-field-provider.js","sourceRoot":"","sources":["../../../../src/services/computed-fields/entity/sequence-num-computed-field-provider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA4C;AAC5C,6CAAmD;AACnD,6GAAyF;AAEzF,mFAAmE;AAGnE,
|
|
1
|
+
{"version":3,"file":"sequence-num-computed-field-provider.js","sourceRoot":"","sources":["../../../../src/services/computed-fields/entity/sequence-num-computed-field-provider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA4C;AAC5C,6CAAmD;AACnD,6GAAyF;AAEzF,mFAAmE;AAGnE,qCAAoD;AAS7C,IAAM,gCAAgC,GAAtC,MAAM,gCAAgC;IACzC,YAEqB,UAAsB;QAAtB,eAAU,GAAV,UAAU,CAAY;IACvC,CAAC;IAEL,IAAI;QACA,OAAO,kCAAkC,CAAC;IAC9C,CAAC;IAED,IAAI;QACA,OAAO,+GAA+G,CAAC;IAC3H,CAAC;IAEO,KAAK,CAAC,qBAAqB,CAAC,YAAoB,EAAE,OAAuB;QAC7E,MAAM,GAAG,GAAG,KAAK,EAAE,GAAkB,EAAE,EAAE;YACrC,MAAM,iBAAiB,GAAG,GAAG,CAAC,aAAa,CAAC,qCAAa,CAAC,CAAC;YAC3D,MAAM,aAAa,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC;gBAClD,KAAK,EAAE,EAAE,YAAY,EAAE;gBACvB,IAAI,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE;aACtC,CAAC,CAAC;YAEH,IAAI,CAAC,aAAa,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,+BAA+B,YAAY,EAAE,CAAC,CAAC;YACnE,CAAC;YAED,MAAM,SAAS,GAAG,aAAa,CAAC,YAAY,GAAG,CAAC,CAAC;YACjD,MAAM,WAAW,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;YAChF,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,IAAI,EAAE,CAAC;YAC1C,MAAM,SAAS,GAAG,aAAa,CAAC,SAAS,IAAI,EAAE,CAAC;YAChD,MAAM,cAAc,GAAG,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,EAAE,CAAC;YAE7D,aAAa,CAAC,YAAY,GAAG,SAAS,CAAC;YACvC,MAAM,iBAAiB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAE5C,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;QACvD,CAAC,CAAC;QAEF,OAAO,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,uBAAuB,CAAC,aAAgB,EAAE,qBAA6E;QACzH,MAAM,EAAE,YAAY,EAAE,GAAG,qBAAqB,CAAC,8BAA8B,IAAI,EAAE,CAAC;QAEpF,IAAI,CAAC,YAAY,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACzE,CAAC;QAED,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC;QAG1E,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,WAAW,EAAE,aAAa,CAAC,EAAE,EAAE,EAAE,CAAC,qBAAqB,CAAC,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC;IAC7I,CAAC;CAEJ,CAAA;AAtDY,4EAAgC;2CAAhC,gCAAgC;IAF5C,IAAA,yDAAqB,GAAE;IACvB,IAAA,mBAAU,GAAE;IAGJ,WAAA,IAAA,0BAAgB,GAAE,CAAA;qCACU,oBAAU;GAHlC,gCAAgC,CAsD5C","sourcesContent":["import { Injectable } from \"@nestjs/common\";\nimport { InjectDataSource } from \"@nestjs/typeorm\";\nimport { ComputedFieldProvider } from \"src/decorators/computed-field-provider.decorator\";\nimport { CommonEntity } from \"src/entities/common.entity\";\nimport { ModelSequence } from \"src/entities/model-sequence.entity\";\nimport { ComputedFieldMetadata } from \"src/helpers/solid-registry\";\nimport { IEntityPostComputeFieldProvider } from \"src/interfaces\";\nimport { DataSource, EntityManager } from \"typeorm\";\n\n\nexport interface SequenceNumComputedFieldContext {\n sequenceName: string; // The separator to use between concatenated values\n}\n\n@ComputedFieldProvider()\n@Injectable()\nexport class SequenceNumComputedFieldProvider<T extends CommonEntity> implements IEntityPostComputeFieldProvider<T, SequenceNumComputedFieldContext> {\n constructor(\n @InjectDataSource()\n private readonly dataSource: DataSource\n ) { }\n\n name(): string {\n return \"SequenceNumComputedFieldProvider\";\n }\n\n help(): string {\n return \"Computed field provider used to create fields whose value is based on some prefix, padding & sequence number.\";\n }\n\n private async generateSequenceValue(sequenceName: string, manager?: EntityManager): Promise<{ sequenceString: string; currentValue: number }> {\n const run = async (mgr: EntityManager) => {\n const modelSequenceRepo = mgr.getRepository(ModelSequence);\n const modelSequence = await modelSequenceRepo.findOne({\n where: { sequenceName },\n lock: { mode: \"pessimistic_write\" }\n });\n\n if (!modelSequence) {\n throw new Error(`ModelSequence not found for ${sequenceName}`);\n }\n\n const nextValue = modelSequence.currentValue + 1;\n const paddedValue = String(nextValue).padStart(modelSequence.padding ?? 5, \"0\");\n const prefix = modelSequence.prefix ?? \"\";\n const separator = modelSequence.separator ?? \"\";\n const sequenceString = `${prefix}${separator}${paddedValue}`;\n\n modelSequence.currentValue = nextValue;\n await modelSequenceRepo.save(modelSequence);\n\n return { sequenceString, currentValue: nextValue };\n };\n\n return manager ? run(manager) : this.dataSource.transaction(run);\n }\n\n async postComputeAndSaveValue(triggerEntity: T, computedFieldMetadata: ComputedFieldMetadata<SequenceNumComputedFieldContext>): Promise<void> {\n const { sequenceName } = computedFieldMetadata.computedFieldValueProviderCtxt ?? {};\n\n if (!sequenceName) {\n throw new Error(\"sequenceName is required for sequence computation\");\n }\n\n const { sequenceString } = await this.generateSequenceValue(sequenceName);\n\n // Update the entity with the computed field value. update is preferred to avoid the post update hooks getting triggered again and causing an infinite loop\n await this.dataSource.manager.update(triggerEntity.constructor, triggerEntity.id, { [computedFieldMetadata.fieldName]: sequenceString });\n }\n\n}"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidxai/core",
|
|
3
|
-
"version": "0.1.6-beta.
|
|
3
|
+
"version": "0.1.6-beta.12",
|
|
4
4
|
"description": "This module is a NestJS module containing all the required core providers required by a Solid application",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -4,8 +4,8 @@ import { ComputedFieldProvider } from "src/decorators/computed-field-provider.de
|
|
|
4
4
|
import { CommonEntity } from "src/entities/common.entity";
|
|
5
5
|
import { ModelSequence } from "src/entities/model-sequence.entity";
|
|
6
6
|
import { ComputedFieldMetadata } from "src/helpers/solid-registry";
|
|
7
|
-
import {
|
|
8
|
-
import { DataSource,
|
|
7
|
+
import { IEntityPostComputeFieldProvider } from "src/interfaces";
|
|
8
|
+
import { DataSource, EntityManager } from "typeorm";
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
export interface SequenceNumComputedFieldContext {
|
|
@@ -14,7 +14,7 @@ export interface SequenceNumComputedFieldContext {
|
|
|
14
14
|
|
|
15
15
|
@ComputedFieldProvider()
|
|
16
16
|
@Injectable()
|
|
17
|
-
export class SequenceNumComputedFieldProvider<T extends CommonEntity> implements
|
|
17
|
+
export class SequenceNumComputedFieldProvider<T extends CommonEntity> implements IEntityPostComputeFieldProvider<T, SequenceNumComputedFieldContext> {
|
|
18
18
|
constructor(
|
|
19
19
|
@InjectDataSource()
|
|
20
20
|
private readonly dataSource: DataSource
|
|
@@ -28,20 +28,9 @@ export class SequenceNumComputedFieldProvider<T extends CommonEntity> implements
|
|
|
28
28
|
return "Computed field provider used to create fields whose value is based on some prefix, padding & sequence number.";
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
async
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (!sequenceName) {
|
|
36
|
-
throw new Error("sequenceName is required for sequence computation");
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
await this.dataSource.transaction(async (manager) => {
|
|
40
|
-
/**
|
|
41
|
-
* 1️⃣ Lock sequence row (prevents race conditions)
|
|
42
|
-
*/
|
|
43
|
-
// 1️⃣ Fetch sequence row
|
|
44
|
-
const modelSequenceRepo = manager.getRepository(ModelSequence)
|
|
31
|
+
private async generateSequenceValue(sequenceName: string, manager?: EntityManager): Promise<{ sequenceString: string; currentValue: number }> {
|
|
32
|
+
const run = async (mgr: EntityManager) => {
|
|
33
|
+
const modelSequenceRepo = mgr.getRepository(ModelSequence);
|
|
45
34
|
const modelSequence = await modelSequenceRepo.findOne({
|
|
46
35
|
where: { sequenceName },
|
|
47
36
|
lock: { mode: "pessimistic_write" }
|
|
@@ -51,36 +40,32 @@ export class SequenceNumComputedFieldProvider<T extends CommonEntity> implements
|
|
|
51
40
|
throw new Error(`ModelSequence not found for ${sequenceName}`);
|
|
52
41
|
}
|
|
53
42
|
|
|
54
|
-
// 2️⃣ Generate next sequence value
|
|
55
43
|
const nextValue = modelSequence.currentValue + 1;
|
|
56
|
-
|
|
57
44
|
const paddedValue = String(nextValue).padStart(modelSequence.padding ?? 5, "0");
|
|
58
|
-
|
|
59
45
|
const prefix = modelSequence.prefix ?? "";
|
|
60
46
|
const separator = modelSequence.separator ?? "";
|
|
61
|
-
|
|
62
47
|
const sequenceString = `${prefix}${separator}${paddedValue}`;
|
|
63
48
|
|
|
64
|
-
|
|
65
|
-
|
|
49
|
+
modelSequence.currentValue = nextValue;
|
|
50
|
+
await modelSequenceRepo.save(modelSequence);
|
|
51
|
+
|
|
52
|
+
return { sequenceString, currentValue: nextValue };
|
|
53
|
+
};
|
|
66
54
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
[computedFieldMetadata.fieldName]: sequenceString,
|
|
70
|
-
},
|
|
71
|
-
});
|
|
55
|
+
return manager ? run(manager) : this.dataSource.transaction(run);
|
|
56
|
+
}
|
|
72
57
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
58
|
+
async postComputeAndSaveValue(triggerEntity: T, computedFieldMetadata: ComputedFieldMetadata<SequenceNumComputedFieldContext>): Promise<void> {
|
|
59
|
+
const { sequenceName } = computedFieldMetadata.computedFieldValueProviderCtxt ?? {};
|
|
60
|
+
|
|
61
|
+
if (!sequenceName) {
|
|
62
|
+
throw new Error("sequenceName is required for sequence computation");
|
|
63
|
+
}
|
|
76
64
|
|
|
77
|
-
|
|
78
|
-
(triggerEntity as any)[computedFieldMetadata.fieldName] = sequenceString;
|
|
65
|
+
const { sequenceString } = await this.generateSequenceValue(sequenceName);
|
|
79
66
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
await modelSequenceRepo.save(modelSequence);
|
|
83
|
-
});
|
|
67
|
+
// Update the entity with the computed field value. update is preferred to avoid the post update hooks getting triggered again and causing an infinite loop
|
|
68
|
+
await this.dataSource.manager.update(triggerEntity.constructor, triggerEntity.id, { [computedFieldMetadata.fieldName]: sequenceString });
|
|
84
69
|
}
|
|
85
70
|
|
|
86
71
|
}
|