@entity-access/entity-access 1.0.26 → 1.0.28
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/common/EntityAccessError.d.ts +3 -1
- package/dist/common/EntityAccessError.d.ts.map +1 -1
- package/dist/common/EntityAccessError.js +8 -1
- package/dist/common/EntityAccessError.js.map +1 -1
- package/dist/common/ErrorModel.d.ts +13 -0
- package/dist/common/ErrorModel.d.ts.map +1 -0
- package/dist/common/ErrorModel.js +17 -0
- package/dist/common/ErrorModel.js.map +1 -0
- package/dist/decorators/IColumn.d.ts +5 -0
- package/dist/decorators/IColumn.d.ts.map +1 -1
- package/dist/decorators/IIndex.d.ts +25 -0
- package/dist/decorators/IIndex.d.ts.map +1 -0
- package/dist/decorators/IIndex.js +2 -0
- package/dist/decorators/IIndex.js.map +1 -0
- package/dist/decorators/Index.d.ts +4 -0
- package/dist/decorators/Index.d.ts.map +1 -0
- package/dist/decorators/Index.js +27 -0
- package/dist/decorators/Index.js.map +1 -0
- package/dist/drivers/postgres/PostgreSqlDriver.js +1 -1
- package/dist/drivers/postgres/PostgreSqlDriver.js.map +1 -1
- package/dist/drivers/sql-server/SqlServerDriver.js +1 -1
- package/dist/drivers/sql-server/SqlServerDriver.js.map +1 -1
- package/dist/entity-query/EntityType.d.ts +2 -0
- package/dist/entity-query/EntityType.d.ts.map +1 -1
- package/dist/entity-query/EntityType.js +1 -0
- package/dist/entity-query/EntityType.js.map +1 -1
- package/dist/migrations/Migrations.d.ts +7 -1
- package/dist/migrations/Migrations.d.ts.map +1 -1
- package/dist/migrations/Migrations.js +11 -0
- package/dist/migrations/Migrations.js.map +1 -1
- package/dist/migrations/postgres/PostgresAutomaticMigrations.d.ts +3 -1
- package/dist/migrations/postgres/PostgresAutomaticMigrations.d.ts.map +1 -1
- package/dist/migrations/postgres/PostgresAutomaticMigrations.js +28 -12
- package/dist/migrations/postgres/PostgresAutomaticMigrations.js.map +1 -1
- package/dist/migrations/sql-server/SqlServerAutomaticMigrations.d.ts +3 -1
- package/dist/migrations/sql-server/SqlServerAutomaticMigrations.d.ts.map +1 -1
- package/dist/migrations/sql-server/SqlServerAutomaticMigrations.js +31 -15
- package/dist/migrations/sql-server/SqlServerAutomaticMigrations.js.map +1 -1
- package/dist/model/changes/ChangeEntry.d.ts.map +1 -1
- package/dist/model/changes/ChangeEntry.js +30 -4
- package/dist/model/changes/ChangeEntry.js.map +1 -1
- package/dist/model/changes/ChangeSet.d.ts.map +1 -1
- package/dist/model/changes/ChangeSet.js +6 -1
- package/dist/model/changes/ChangeSet.js.map +1 -1
- package/dist/tests/model/ShoppingContext.d.ts +1 -0
- package/dist/tests/model/ShoppingContext.d.ts.map +1 -1
- package/dist/tests/model/ShoppingContext.js +12 -1
- package/dist/tests/model/ShoppingContext.js.map +1 -1
- package/dist/tests/model/createContext.d.ts.map +1 -1
- package/dist/tests/model/createContext.js +10 -2
- package/dist/tests/model/createContext.js.map +1 -1
- package/dist/tests/security/tests/place-order.js +2 -2
- package/dist/tests/security/tests/place-order.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/common/EntityAccessError.ts +11 -2
- package/src/common/ErrorModel.ts +24 -0
- package/src/decorators/IColumn.ts +5 -0
- package/src/decorators/IIndex.ts +24 -0
- package/src/decorators/Index.ts +42 -0
- package/src/drivers/postgres/PostgreSqlDriver.ts +1 -1
- package/src/drivers/sql-server/SqlServerDriver.ts +1 -1
- package/src/entity-query/EntityType.ts +3 -0
- package/src/migrations/Migrations.ts +18 -1
- package/src/migrations/postgres/PostgresAutomaticMigrations.ts +30 -14
- package/src/migrations/sql-server/SqlServerAutomaticMigrations.ts +33 -17
- package/src/model/changes/ChangeEntry.ts +33 -4
- package/src/model/changes/ChangeSet.ts +6 -1
- package/src/tests/model/ShoppingContext.ts +9 -0
- package/src/tests/model/createContext.ts +10 -2
- package/src/tests/security/tests/place-order.ts +2 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IColumn } from "../../decorators/IColumn.js";
|
|
2
|
+
import { IIndex } from "../../decorators/IIndex.js";
|
|
2
3
|
import { BaseDriver } from "../../drivers/base/BaseDriver.js";
|
|
3
4
|
import { SqlServerLiteral } from "../../drivers/sql-server/SqlServerLiteral.js";
|
|
4
5
|
import EntityType from "../../entity-query/EntityType.js";
|
|
@@ -21,27 +22,21 @@ export default class SqlServerAutomaticMigrations extends SqlServerMigrations {
|
|
|
21
22
|
|
|
22
23
|
await this.createColumns(driver, type, nonKeyColumns);
|
|
23
24
|
|
|
24
|
-
await this.createIndexes(
|
|
25
|
+
await this.createIndexes(context, type, nonKeyColumns.filter((x) => x.fkRelation && !x.fkRelation?.dotNotCreateIndex));
|
|
25
26
|
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
async createIndexes(
|
|
29
|
-
|
|
30
|
-
const name = type.schema
|
|
31
|
-
? SqlServerLiteral.quotedLiteral(type.schema) + "." + SqlServerLiteral.quotedLiteral(type.name)
|
|
32
|
-
: SqlServerLiteral.quotedLiteral(type.name);
|
|
33
|
-
|
|
29
|
+
async createIndexes(context: EntityContext, type: EntityType, fkColumns: IColumn[]) {
|
|
34
30
|
for (const iterator of fkColumns) {
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
await driver.executeQuery(query);
|
|
31
|
+
const filter = iterator.nullable
|
|
32
|
+
? `${ SqlServerLiteral.quotedLiteral(iterator.columnName)} IS NOT NULL`
|
|
33
|
+
: "";
|
|
34
|
+
const indexDef: IIndex = {
|
|
35
|
+
name: `IX_${type.name}_${iterator.columnName}`,
|
|
36
|
+
columns: [{ name: iterator.columnName, descending: iterator.indexOrder !== "ascending"}],
|
|
37
|
+
filter
|
|
38
|
+
};
|
|
39
|
+
await this.migrateIndex(context, indexDef, type);
|
|
45
40
|
}
|
|
46
41
|
}
|
|
47
42
|
|
|
@@ -101,5 +96,26 @@ export default class SqlServerAutomaticMigrations extends SqlServerMigrations {
|
|
|
101
96
|
|
|
102
97
|
}
|
|
103
98
|
|
|
99
|
+
async migrateIndex(context: EntityContext, index: IIndex, type: EntityType) {
|
|
100
|
+
const driver = context.driver;
|
|
101
|
+
const name = type.schema
|
|
102
|
+
? SqlServerLiteral.quotedLiteral(type.schema) + "." + SqlServerLiteral.quotedLiteral(type.name)
|
|
103
|
+
: SqlServerLiteral.quotedLiteral(type.name);
|
|
104
|
+
const indexName = SqlServerLiteral.quotedLiteral(index.name);
|
|
105
|
+
const columns = [];
|
|
106
|
+
for (const column of index.columns) {
|
|
107
|
+
const columnName = SqlServerLiteral.quotedLiteral(column.name);
|
|
108
|
+
columns.push(`${columnName} ${column.descending ? "DESC" : "ASC"}`);
|
|
109
|
+
}
|
|
110
|
+
let query = `IF NOT EXISTS(SELECT * FROM sys.indexes WHERE name = '${indexName}' AND object_id = OBJECT_ID('${name}'))
|
|
111
|
+
BEGIN
|
|
112
|
+
CREATE ${index.unique ? "UNIQUE" : ""} INDEX ${indexName} ON ${name} ( ${columns.join(", ")})`;
|
|
113
|
+
if (index.filter) {
|
|
114
|
+
query += ` WHERE (${index.filter})`;
|
|
115
|
+
}
|
|
116
|
+
query += `\nEND`;
|
|
117
|
+
await driver.executeQuery(query);
|
|
118
|
+
}
|
|
119
|
+
|
|
104
120
|
|
|
105
121
|
}
|
|
@@ -49,12 +49,36 @@ export default class ChangeEntry implements IChanges {
|
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
const { type: { columns }, entity
|
|
52
|
+
const { type: { columns, keys }, entity } = this;
|
|
53
|
+
let { original } = this;
|
|
53
54
|
|
|
54
55
|
if (original === void 0) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
|
|
57
|
+
// check if all keys are set or not...
|
|
58
|
+
|
|
59
|
+
let keysSet = true;
|
|
60
|
+
let autoGenerate = false;
|
|
61
|
+
for (const iterator of keys) {
|
|
62
|
+
autoGenerate ||= iterator.autoGenerate;
|
|
63
|
+
if(entity[iterator.name] === void 0) {
|
|
64
|
+
keysSet = false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (keysSet) {
|
|
69
|
+
if (!autoGenerate) {
|
|
70
|
+
this.status = "inserted";
|
|
71
|
+
this.detectDependencies();
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
} else if (autoGenerate) {
|
|
75
|
+
this.status = "inserted";
|
|
76
|
+
this.detectDependencies();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
this.original = { ... entity };
|
|
81
|
+
original = this.original;
|
|
58
82
|
}
|
|
59
83
|
|
|
60
84
|
this.detectDependencies();
|
|
@@ -133,6 +157,11 @@ export default class ChangeEntry implements IChanges {
|
|
|
133
157
|
// if related has key defined.. set it...
|
|
134
158
|
const rKey = iterator.relatedEntity.keys[0];
|
|
135
159
|
|
|
160
|
+
// lets set the prototype...
|
|
161
|
+
const prototype = iterator.relatedTypeClass.prototype;
|
|
162
|
+
if (Object.getPrototypeOf(related) !== prototype) {
|
|
163
|
+
Object.setPrototypeOf(related, prototype);
|
|
164
|
+
}
|
|
136
165
|
const relatedChanges = this.changeSet.getEntry(related);
|
|
137
166
|
|
|
138
167
|
const keyValue = related[rKey.name];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import EntityAccessError from "../../common/EntityAccessError.js";
|
|
1
2
|
import SchemaRegistry from "../../decorators/SchemaRegistry.js";
|
|
2
3
|
import EntityContext from "../EntityContext.js";
|
|
3
4
|
import IdentityService, { identityMapSymbol } from "../identity/IdentityService.js";
|
|
@@ -47,7 +48,11 @@ export default class ChangeSet {
|
|
|
47
48
|
if (entry) {
|
|
48
49
|
return entry;
|
|
49
50
|
}
|
|
50
|
-
const
|
|
51
|
+
const c = Object.getPrototypeOf(entity).constructor;
|
|
52
|
+
if (c === Object) {
|
|
53
|
+
throw new EntityAccessError("Entity type not set");
|
|
54
|
+
}
|
|
55
|
+
const type = SchemaRegistry.model(c);
|
|
51
56
|
const jsonKey = IdentityService.getIdentity(entity);
|
|
52
57
|
if (jsonKey) {
|
|
53
58
|
const existing = this.identityMap.get(jsonKey);
|
|
@@ -2,6 +2,7 @@ import EntityContext from "../../model/EntityContext.js";
|
|
|
2
2
|
import Column from "../../decorators/Column.js";
|
|
3
3
|
import { RelateTo } from "../../decorators/Relate.js";
|
|
4
4
|
import Table from "../../decorators/Table.js";
|
|
5
|
+
import Index from "../../decorators/Index.js";
|
|
5
6
|
|
|
6
7
|
export const statusPublished = "published";
|
|
7
8
|
|
|
@@ -24,6 +25,11 @@ export class ShoppingContext extends EntityContext {
|
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
@Table("Users")
|
|
28
|
+
@Index({
|
|
29
|
+
name: "IX_Unique_Users",
|
|
30
|
+
columns: [(x) => x.userName],
|
|
31
|
+
unique: true
|
|
32
|
+
})
|
|
27
33
|
export class User {
|
|
28
34
|
|
|
29
35
|
@Column({ key: true , autoGenerate: true, dataType: "BigInt" })
|
|
@@ -32,6 +38,9 @@ export class User {
|
|
|
32
38
|
@Column({})
|
|
33
39
|
public dateCreated: Date;
|
|
34
40
|
|
|
41
|
+
@Column({ dataType: "Char", length: 200 })
|
|
42
|
+
public userName: string;
|
|
43
|
+
|
|
35
44
|
public ownedProducts: Product[];
|
|
36
45
|
|
|
37
46
|
public orders: Order[];
|
|
@@ -17,6 +17,7 @@ export async function createContext(driver: BaseDriver) {
|
|
|
17
17
|
|
|
18
18
|
await seed(context);
|
|
19
19
|
|
|
20
|
+
driver.connectionString.database = context.driver.connectionString.database;
|
|
20
21
|
return context;
|
|
21
22
|
|
|
22
23
|
}
|
|
@@ -29,9 +30,15 @@ async function seed(context: ShoppingContext) {
|
|
|
29
30
|
const now = new Date();
|
|
30
31
|
|
|
31
32
|
// add admin user...
|
|
32
|
-
context.users.add({
|
|
33
|
+
context.users.add({
|
|
34
|
+
userName: "admin",
|
|
35
|
+
dateCreated: new Date()
|
|
36
|
+
});
|
|
33
37
|
// add seller
|
|
34
|
-
const seller = context.users.add({
|
|
38
|
+
const seller = context.users.add({
|
|
39
|
+
userName: "self",
|
|
40
|
+
dateCreated: new Date()
|
|
41
|
+
});
|
|
35
42
|
|
|
36
43
|
addHeadPhones(context, now, seller);
|
|
37
44
|
|
|
@@ -45,6 +52,7 @@ async function seed(context: ShoppingContext) {
|
|
|
45
52
|
const productPrice = product.prices[0];
|
|
46
53
|
|
|
47
54
|
const user = context.users.add({
|
|
55
|
+
userName: "customer1",
|
|
48
56
|
dateCreated: new Date(),
|
|
49
57
|
orders: [
|
|
50
58
|
context.orders.add({
|
|
@@ -94,11 +94,11 @@ async function addNewOrder(this: TestConfig, customer: User, userID?) {
|
|
|
94
94
|
|
|
95
95
|
async function createUser(config: TestConfig) {
|
|
96
96
|
const context = await createContext(config.driver);
|
|
97
|
-
config.driver.connectionString.database = context.driver.connectionString.database;
|
|
98
97
|
const user = context.users.add({
|
|
98
|
+
userName: "customer",
|
|
99
99
|
dateCreated: new Date()
|
|
100
100
|
});
|
|
101
101
|
await context.saveChanges();
|
|
102
|
-
return user;
|
|
102
|
+
return { ... user };
|
|
103
103
|
}
|
|
104
104
|
|