@autofleet/sadot 1.6.18-beta.2 → 1.6.18-beta.21
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/_virtual/_@oxc-project_runtime@0.103.0/helpers/decorate.cjs +11 -0
- package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/decorate.js +10 -0
- package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/decorateMetadata.cjs +8 -0
- package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/decorateMetadata.js +7 -0
- package/dist/_virtual/rolldown_runtime.cjs +43 -0
- package/dist/{chunk-DJulfCLt.js → _virtual/rolldown_runtime.js} +1 -2
- package/dist/api/index.cjs +12 -0
- package/dist/api/index.js +11 -0
- package/dist/api/v1/definition/index.cjs +113 -0
- package/dist/api/v1/definition/index.js +112 -0
- package/dist/api/v1/definition/validations.cjs +128 -0
- package/dist/api/v1/definition/validations.js +125 -0
- package/dist/api/v1/errors.cjs +14 -0
- package/dist/api/v1/errors.js +13 -0
- package/dist/api/v1/field-policies/index.cjs +104 -0
- package/dist/api/v1/field-policies/index.js +103 -0
- package/dist/api/v1/index.cjs +16 -0
- package/dist/api/v1/index.js +15 -0
- package/dist/api/v1/validator/index.cjs +132 -0
- package/dist/api/v1/validator/index.js +131 -0
- package/dist/api/v1/validator/validations.cjs +40 -0
- package/dist/api/v1/validator/validations.d.cts +22 -0
- package/dist/api/v1/validator/validations.d.ts +22 -0
- package/dist/api/v1/validator/validations.js +38 -0
- package/dist/errors/index.cjs +62 -0
- package/dist/errors/index.js +55 -0
- package/dist/events/index.cjs +52 -0
- package/dist/events/index.js +50 -0
- package/dist/hooks/enrich.cjs +175 -0
- package/dist/hooks/enrich.js +175 -0
- package/dist/hooks/find.cjs +22 -0
- package/dist/hooks/find.js +22 -0
- package/dist/hooks/hooks.cjs +310 -0
- package/dist/hooks/hooks.js +302 -0
- package/dist/hooks/index.cjs +3 -0
- package/dist/hooks/index.js +5 -0
- package/dist/hooks/utils/updateInstanceValues.cjs +27 -0
- package/dist/hooks/utils/updateInstanceValues.js +27 -0
- package/dist/index.cjs +48 -33508
- package/dist/index.d.cts +13 -396
- package/dist/index.d.ts +14 -394
- package/dist/index.js +21 -33435
- package/dist/init-state.cjs +56 -0
- package/dist/init-state.d.cts +35 -0
- package/dist/init-state.d.ts +35 -0
- package/dist/init-state.js +55 -0
- package/dist/mat-path-state.cjs +10 -0
- package/dist/mat-path-state.js +9 -0
- package/dist/migrations/001-create-core-tables.cjs +70 -0
- package/dist/migrations/001-create-core-tables.js +68 -0
- package/dist/migrations/002-create-custom-field-entries.cjs +27 -0
- package/dist/migrations/002-create-custom-field-entries.js +25 -0
- package/dist/migrations/003-create-custom-field-model-type-map.cjs +35 -0
- package/dist/migrations/003-create-custom-field-model-type-map.js +33 -0
- package/dist/migrations/004-create-field-policy-tables.cjs +29 -0
- package/dist/migrations/004-create-field-policy-tables.js +27 -0
- package/dist/migrations/005-add-entity-type-to-field-policies.cjs +20 -0
- package/dist/migrations/005-add-entity-type-to-field-policies.js +18 -0
- package/dist/migrations/index.cjs +94 -0
- package/dist/migrations/index.js +95 -0
- package/dist/models/CustomFieldDefinition.cjs +147 -0
- package/dist/models/CustomFieldDefinition.d.cts +40 -0
- package/dist/models/CustomFieldDefinition.d.ts +40 -0
- package/dist/models/CustomFieldDefinition.js +146 -0
- package/dist/models/CustomFieldEntries.cjs +71 -0
- package/dist/models/CustomFieldEntries.d.cts +15 -0
- package/dist/models/CustomFieldEntries.d.ts +15 -0
- package/dist/models/CustomFieldEntries.js +70 -0
- package/dist/models/CustomFieldModelTypeMap.cjs +62 -0
- package/dist/models/CustomFieldModelTypeMap.d.cts +14 -0
- package/dist/models/CustomFieldModelTypeMap.d.ts +14 -0
- package/dist/models/CustomFieldModelTypeMap.js +61 -0
- package/dist/models/CustomFieldValue.cjs +109 -0
- package/dist/models/CustomFieldValue.d.cts +20 -0
- package/dist/models/CustomFieldValue.d.ts +20 -0
- package/dist/models/CustomFieldValue.js +108 -0
- package/dist/models/CustomValidator.cjs +68 -0
- package/dist/models/CustomValidator.d.cts +18 -0
- package/dist/models/CustomValidator.d.ts +18 -0
- package/dist/models/CustomValidator.js +67 -0
- package/dist/models/FieldPolicy.cjs +54 -0
- package/dist/models/FieldPolicy.d.cts +25 -0
- package/dist/models/FieldPolicy.d.ts +25 -0
- package/dist/models/FieldPolicy.js +53 -0
- package/dist/models/index.cjs +163 -0
- package/dist/models/index.d.ts +11 -0
- package/dist/models/index.js +161 -0
- package/dist/models/tests/AssociatedTestModel.cjs +51 -0
- package/dist/models/tests/AssociatedTestModel.d.ts +2 -0
- package/dist/models/tests/AssociatedTestModel.js +50 -0
- package/dist/models/tests/TestModel.cjs +43 -0
- package/dist/models/tests/TestModel.d.ts +2 -0
- package/dist/models/tests/TestModel.js +42 -0
- package/dist/models/tests/contextAwareModels/ContextAwareTestModel.cjs +35 -0
- package/dist/models/tests/contextAwareModels/ContextAwareTestModel.d.ts +2 -0
- package/dist/models/tests/contextAwareModels/ContextAwareTestModel.js +34 -0
- package/dist/models/tests/contextAwareModels/ContextTestModel.cjs +33 -0
- package/dist/models/tests/contextAwareModels/ContextTestModel.d.ts +1 -0
- package/dist/models/tests/contextAwareModels/ContextTestModel.js +32 -0
- package/dist/repository/definition.cjs +221 -0
- package/dist/repository/definition.js +212 -0
- package/dist/repository/entries.cjs +69 -0
- package/dist/repository/entries.js +67 -0
- package/dist/repository/field-policy.cjs +69 -0
- package/dist/repository/field-policy.d.cts +35 -0
- package/dist/repository/field-policy.d.ts +35 -0
- package/dist/repository/field-policy.js +59 -0
- package/dist/repository/utils/formatValues.cjs +14 -0
- package/dist/repository/utils/formatValues.js +14 -0
- package/dist/repository/validator.cjs +85 -0
- package/dist/repository/validator.js +78 -0
- package/dist/repository/value.cjs +77 -0
- package/dist/repository/value.js +76 -0
- package/dist/scopes/filter.cjs +56 -0
- package/dist/scopes/filter.d.cts +22 -0
- package/dist/scopes/filter.d.ts +22 -0
- package/dist/scopes/filter.js +54 -0
- package/dist/scopes/helpers/filter.helpers.cjs +152 -0
- package/dist/scopes/helpers/filter.helpers.d.cts +16 -0
- package/dist/scopes/helpers/filter.helpers.d.ts +16 -0
- package/dist/scopes/helpers/filter.helpers.js +147 -0
- package/dist/scopes/index.cjs +1 -0
- package/dist/scopes/index.js +3 -0
- package/dist/types/index.d.cts +75 -0
- package/dist/types/index.d.ts +76 -0
- package/dist/utils/constants/index.cjs +32 -0
- package/dist/utils/constants/index.d.cts +23 -0
- package/dist/utils/constants/index.d.ts +23 -0
- package/dist/utils/constants/index.js +29 -0
- package/dist/utils/db/index.cjs +15 -0
- package/dist/utils/db/index.js +14 -0
- package/dist/utils/helpers/index.cjs +23 -0
- package/dist/utils/helpers/index.d.cts +30 -0
- package/dist/utils/helpers/index.d.ts +30 -0
- package/dist/utils/helpers/index.js +21 -0
- package/dist/utils/init.cjs +115 -0
- package/dist/utils/init.js +111 -0
- package/dist/utils/logger/index.cjs +15 -0
- package/dist/utils/logger/index.js +12 -0
- package/dist/utils/scopeAttributes.cjs +12 -0
- package/dist/utils/scopeAttributes.js +11 -0
- package/dist/utils/validations/index.cjs +34 -0
- package/dist/utils/validations/index.js +32 -0
- package/dist/utils/validations/schema/custom-fields.cjs +9 -0
- package/dist/utils/validations/schema/custom-fields.d.cts +6 -0
- package/dist/utils/validations/schema/custom-fields.d.ts +6 -0
- package/dist/utils/validations/schema/custom-fields.js +7 -0
- package/dist/utils/validations/schema/validator-schema.cjs +102 -0
- package/dist/utils/validations/schema/validator-schema.js +99 -0
- package/dist/utils/validations/validators/index.cjs +45 -0
- package/dist/utils/validations/validators/index.js +42 -0
- package/dist/utils/validations/validators/multi-select-dropdown.validator.cjs +7 -0
- package/dist/utils/validations/validators/multi-select-dropdown.validator.js +7 -0
- package/dist/utils/validations/validators/multi-select-status.validator.cjs +10 -0
- package/dist/utils/validations/validators/multi-select-status.validator.js +10 -0
- package/dist/utils/validations/validators/multi-select.helpers.cjs +12 -0
- package/dist/utils/validations/validators/multi-select.helpers.js +10 -0
- package/dist/utils/validations/validators/select.validator.cjs +12 -0
- package/dist/utils/validations/validators/select.validator.js +10 -0
- package/dist/utils/validations/validators/status.validator.cjs +12 -0
- package/dist/utils/validations/validators/status.validator.js +10 -0
- package/package.json +4 -4
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/init-state.ts
|
|
3
|
+
/**
|
|
4
|
+
* Tracks the initialization state of sadot's useCustomFields function
|
|
5
|
+
* Allows HealthManager to wait for initialization before passing readiness checks
|
|
6
|
+
*/
|
|
7
|
+
var SadotInitializationState = class {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.initPromise = null;
|
|
10
|
+
this.initError = null;
|
|
11
|
+
this.isInitialized = false;
|
|
12
|
+
this.sequelizeInstance = null;
|
|
13
|
+
this.ownsSequelizeInstance = false;
|
|
14
|
+
}
|
|
15
|
+
/** Set the initialization promise */
|
|
16
|
+
setInitPromise(promise, ownsSequelize) {
|
|
17
|
+
this.initPromise = promise;
|
|
18
|
+
this.ownsSequelizeInstance = ownsSequelize;
|
|
19
|
+
promise.then((sequelize) => {
|
|
20
|
+
this.sequelizeInstance = sequelize;
|
|
21
|
+
this.isInitialized = true;
|
|
22
|
+
}, (error) => this.initError = error);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get the Sequelize instance
|
|
26
|
+
* Returns null if initialization hasn't completed yet, or in cases where it failed.
|
|
27
|
+
*/
|
|
28
|
+
get sequelize() {
|
|
29
|
+
return this.sequelizeInstance;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Wait for initialization to complete and return the Sequelize instance
|
|
33
|
+
* Returns the Sequelize instance only if Sadot created it (owns it)
|
|
34
|
+
* Returns undefined if the Sequelize instance was provided externally
|
|
35
|
+
* Rejects when initialization fails
|
|
36
|
+
*/
|
|
37
|
+
async waitForInitialization() {
|
|
38
|
+
if (this.isInitialized && this.sequelizeInstance) return this.ownsSequelizeInstance ? this.sequelizeInstance : void 0;
|
|
39
|
+
if (this.initError) throw this.initError;
|
|
40
|
+
if (!this.initPromise) throw new Error("Sadot initialization has not started");
|
|
41
|
+
const sequelize = await this.initPromise;
|
|
42
|
+
if (this.initError) throw this.initError;
|
|
43
|
+
return this.ownsSequelizeInstance ? sequelize : void 0;
|
|
44
|
+
}
|
|
45
|
+
/** Check if initialization is complete and successful */
|
|
46
|
+
get isReady() {
|
|
47
|
+
return this.isInitialized && !this.initError;
|
|
48
|
+
}
|
|
49
|
+
/** Get the initialization error if one occurred */
|
|
50
|
+
get error() {
|
|
51
|
+
return this.initError;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
//#endregion
|
|
56
|
+
exports.SadotInitializationState = SadotInitializationState;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Sequelize } from "sequelize-typescript";
|
|
2
|
+
|
|
3
|
+
//#region src/init-state.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Tracks the initialization state of sadot's useCustomFields function
|
|
7
|
+
* Allows HealthManager to wait for initialization before passing readiness checks
|
|
8
|
+
*/
|
|
9
|
+
declare class SadotInitializationState {
|
|
10
|
+
private initPromise;
|
|
11
|
+
private initError;
|
|
12
|
+
private isInitialized;
|
|
13
|
+
private sequelizeInstance;
|
|
14
|
+
private ownsSequelizeInstance;
|
|
15
|
+
/** Set the initialization promise */
|
|
16
|
+
setInitPromise(promise: Promise<Sequelize>, ownsSequelize: boolean): void;
|
|
17
|
+
/**
|
|
18
|
+
* Get the Sequelize instance
|
|
19
|
+
* Returns null if initialization hasn't completed yet, or in cases where it failed.
|
|
20
|
+
*/
|
|
21
|
+
get sequelize(): Sequelize | null;
|
|
22
|
+
/**
|
|
23
|
+
* Wait for initialization to complete and return the Sequelize instance
|
|
24
|
+
* Returns the Sequelize instance only if Sadot created it (owns it)
|
|
25
|
+
* Returns undefined if the Sequelize instance was provided externally
|
|
26
|
+
* Rejects when initialization fails
|
|
27
|
+
*/
|
|
28
|
+
waitForInitialization(): Promise<Sequelize | undefined>;
|
|
29
|
+
/** Check if initialization is complete and successful */
|
|
30
|
+
get isReady(): boolean;
|
|
31
|
+
/** Get the initialization error if one occurred */
|
|
32
|
+
get error(): Error | null;
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { SadotInitializationState };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Sequelize } from "sequelize-typescript";
|
|
2
|
+
|
|
3
|
+
//#region src/init-state.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Tracks the initialization state of sadot's useCustomFields function
|
|
7
|
+
* Allows HealthManager to wait for initialization before passing readiness checks
|
|
8
|
+
*/
|
|
9
|
+
declare class SadotInitializationState {
|
|
10
|
+
private initPromise;
|
|
11
|
+
private initError;
|
|
12
|
+
private isInitialized;
|
|
13
|
+
private sequelizeInstance;
|
|
14
|
+
private ownsSequelizeInstance;
|
|
15
|
+
/** Set the initialization promise */
|
|
16
|
+
setInitPromise(promise: Promise<Sequelize>, ownsSequelize: boolean): void;
|
|
17
|
+
/**
|
|
18
|
+
* Get the Sequelize instance
|
|
19
|
+
* Returns null if initialization hasn't completed yet, or in cases where it failed.
|
|
20
|
+
*/
|
|
21
|
+
get sequelize(): Sequelize | null;
|
|
22
|
+
/**
|
|
23
|
+
* Wait for initialization to complete and return the Sequelize instance
|
|
24
|
+
* Returns the Sequelize instance only if Sadot created it (owns it)
|
|
25
|
+
* Returns undefined if the Sequelize instance was provided externally
|
|
26
|
+
* Rejects when initialization fails
|
|
27
|
+
*/
|
|
28
|
+
waitForInitialization(): Promise<Sequelize | undefined>;
|
|
29
|
+
/** Check if initialization is complete and successful */
|
|
30
|
+
get isReady(): boolean;
|
|
31
|
+
/** Get the initialization error if one occurred */
|
|
32
|
+
get error(): Error | null;
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { SadotInitializationState };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
//#region src/init-state.ts
|
|
2
|
+
/**
|
|
3
|
+
* Tracks the initialization state of sadot's useCustomFields function
|
|
4
|
+
* Allows HealthManager to wait for initialization before passing readiness checks
|
|
5
|
+
*/
|
|
6
|
+
var SadotInitializationState = class {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.initPromise = null;
|
|
9
|
+
this.initError = null;
|
|
10
|
+
this.isInitialized = false;
|
|
11
|
+
this.sequelizeInstance = null;
|
|
12
|
+
this.ownsSequelizeInstance = false;
|
|
13
|
+
}
|
|
14
|
+
/** Set the initialization promise */
|
|
15
|
+
setInitPromise(promise, ownsSequelize) {
|
|
16
|
+
this.initPromise = promise;
|
|
17
|
+
this.ownsSequelizeInstance = ownsSequelize;
|
|
18
|
+
promise.then((sequelize) => {
|
|
19
|
+
this.sequelizeInstance = sequelize;
|
|
20
|
+
this.isInitialized = true;
|
|
21
|
+
}, (error) => this.initError = error);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get the Sequelize instance
|
|
25
|
+
* Returns null if initialization hasn't completed yet, or in cases where it failed.
|
|
26
|
+
*/
|
|
27
|
+
get sequelize() {
|
|
28
|
+
return this.sequelizeInstance;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Wait for initialization to complete and return the Sequelize instance
|
|
32
|
+
* Returns the Sequelize instance only if Sadot created it (owns it)
|
|
33
|
+
* Returns undefined if the Sequelize instance was provided externally
|
|
34
|
+
* Rejects when initialization fails
|
|
35
|
+
*/
|
|
36
|
+
async waitForInitialization() {
|
|
37
|
+
if (this.isInitialized && this.sequelizeInstance) return this.ownsSequelizeInstance ? this.sequelizeInstance : void 0;
|
|
38
|
+
if (this.initError) throw this.initError;
|
|
39
|
+
if (!this.initPromise) throw new Error("Sadot initialization has not started");
|
|
40
|
+
const sequelize = await this.initPromise;
|
|
41
|
+
if (this.initError) throw this.initError;
|
|
42
|
+
return this.ownsSequelizeInstance ? sequelize : void 0;
|
|
43
|
+
}
|
|
44
|
+
/** Check if initialization is complete and successful */
|
|
45
|
+
get isReady() {
|
|
46
|
+
return this.isInitialized && !this.initError;
|
|
47
|
+
}
|
|
48
|
+
/** Get the initialization error if one occurred */
|
|
49
|
+
get error() {
|
|
50
|
+
return this.initError;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
//#endregion
|
|
55
|
+
export { SadotInitializationState };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/mat-path-state.ts
|
|
3
|
+
/**
|
|
4
|
+
* Module-scoped holder for the optional `isMatPathEnabled` predicate so route handlers can
|
|
5
|
+
* read it without threading the option through every layer. Set once during `useCustomFields()`.
|
|
6
|
+
*/
|
|
7
|
+
const matPathState = {};
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
exports.matPathState = matPathState;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/mat-path-state.ts
|
|
2
|
+
/**
|
|
3
|
+
* Module-scoped holder for the optional `isMatPathEnabled` predicate so route handlers can
|
|
4
|
+
* read it without threading the option through every layer. Set once during `useCustomFields()`.
|
|
5
|
+
*/
|
|
6
|
+
const matPathState = {};
|
|
7
|
+
|
|
8
|
+
//#endregion
|
|
9
|
+
export { matPathState };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/migrations/001-create-core-tables.ts
|
|
3
|
+
const up = async ({ context: queryInterface }) => {
|
|
4
|
+
const { sequelize } = queryInterface;
|
|
5
|
+
await sequelize.query(`
|
|
6
|
+
CREATE TABLE IF NOT EXISTS "custom_field_definitions" (
|
|
7
|
+
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
|
|
8
|
+
"name" VARCHAR NOT NULL,
|
|
9
|
+
"display_name" VARCHAR,
|
|
10
|
+
"field_type" VARCHAR NOT NULL,
|
|
11
|
+
"validation" JSONB,
|
|
12
|
+
"entity_id" UUID NOT NULL,
|
|
13
|
+
"entity_type" VARCHAR NOT NULL,
|
|
14
|
+
"model_type" VARCHAR NOT NULL,
|
|
15
|
+
"description" TEXT,
|
|
16
|
+
"required" BOOLEAN DEFAULT false,
|
|
17
|
+
"disabled" BOOLEAN DEFAULT false,
|
|
18
|
+
"default_value" JSONB,
|
|
19
|
+
"block_editing_from_u_i" BOOLEAN NOT NULL DEFAULT false,
|
|
20
|
+
"created_at" TIMESTAMPTZ NOT NULL,
|
|
21
|
+
"updated_at" TIMESTAMPTZ,
|
|
22
|
+
"deleted_at" TIMESTAMPTZ,
|
|
23
|
+
PRIMARY KEY ("id")
|
|
24
|
+
)
|
|
25
|
+
`);
|
|
26
|
+
await sequelize.query(`
|
|
27
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "unique_name_model_type"
|
|
28
|
+
ON "custom_field_definitions" ("model_type", "entity_id", "name")
|
|
29
|
+
`);
|
|
30
|
+
await sequelize.query(`
|
|
31
|
+
CREATE TABLE IF NOT EXISTS "custom_field_values" (
|
|
32
|
+
"model_id" UUID NOT NULL,
|
|
33
|
+
"custom_field_definition_id" UUID NOT NULL
|
|
34
|
+
REFERENCES "custom_field_definitions" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
|
35
|
+
"value" JSONB,
|
|
36
|
+
"created_at" TIMESTAMPTZ NOT NULL,
|
|
37
|
+
"updated_at" TIMESTAMPTZ,
|
|
38
|
+
"deleted_at" TIMESTAMPTZ,
|
|
39
|
+
PRIMARY KEY ("model_id", "custom_field_definition_id")
|
|
40
|
+
)
|
|
41
|
+
`);
|
|
42
|
+
await sequelize.query(`
|
|
43
|
+
CREATE INDEX IF NOT EXISTS "idx_custom_field_values_active_definition_id"
|
|
44
|
+
ON "custom_field_values" ("custom_field_definition_id")
|
|
45
|
+
WHERE "deleted_at" IS NULL
|
|
46
|
+
`);
|
|
47
|
+
await sequelize.query(`
|
|
48
|
+
CREATE TABLE IF NOT EXISTS "custom_validators" (
|
|
49
|
+
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
|
|
50
|
+
"entity_id" UUID NOT NULL,
|
|
51
|
+
"entity_type" VARCHAR NOT NULL,
|
|
52
|
+
"model_type" VARCHAR NOT NULL,
|
|
53
|
+
"schema" JSONB NOT NULL,
|
|
54
|
+
"disabled" BOOLEAN NOT NULL DEFAULT false,
|
|
55
|
+
"created_at" TIMESTAMPTZ NOT NULL,
|
|
56
|
+
"updated_at" TIMESTAMPTZ,
|
|
57
|
+
PRIMARY KEY ("id")
|
|
58
|
+
)
|
|
59
|
+
`);
|
|
60
|
+
};
|
|
61
|
+
const down = async ({ context: queryInterface }) => {
|
|
62
|
+
const { sequelize } = queryInterface;
|
|
63
|
+
await sequelize.query("DROP TABLE IF EXISTS \"custom_field_values\"");
|
|
64
|
+
await sequelize.query("DROP TABLE IF EXISTS \"custom_field_definitions\"");
|
|
65
|
+
await sequelize.query("DROP TABLE IF EXISTS \"custom_validators\"");
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
//#endregion
|
|
69
|
+
exports.down = down;
|
|
70
|
+
exports.up = up;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
//#region src/migrations/001-create-core-tables.ts
|
|
2
|
+
const up = async ({ context: queryInterface }) => {
|
|
3
|
+
const { sequelize } = queryInterface;
|
|
4
|
+
await sequelize.query(`
|
|
5
|
+
CREATE TABLE IF NOT EXISTS "custom_field_definitions" (
|
|
6
|
+
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
|
|
7
|
+
"name" VARCHAR NOT NULL,
|
|
8
|
+
"display_name" VARCHAR,
|
|
9
|
+
"field_type" VARCHAR NOT NULL,
|
|
10
|
+
"validation" JSONB,
|
|
11
|
+
"entity_id" UUID NOT NULL,
|
|
12
|
+
"entity_type" VARCHAR NOT NULL,
|
|
13
|
+
"model_type" VARCHAR NOT NULL,
|
|
14
|
+
"description" TEXT,
|
|
15
|
+
"required" BOOLEAN DEFAULT false,
|
|
16
|
+
"disabled" BOOLEAN DEFAULT false,
|
|
17
|
+
"default_value" JSONB,
|
|
18
|
+
"block_editing_from_u_i" BOOLEAN NOT NULL DEFAULT false,
|
|
19
|
+
"created_at" TIMESTAMPTZ NOT NULL,
|
|
20
|
+
"updated_at" TIMESTAMPTZ,
|
|
21
|
+
"deleted_at" TIMESTAMPTZ,
|
|
22
|
+
PRIMARY KEY ("id")
|
|
23
|
+
)
|
|
24
|
+
`);
|
|
25
|
+
await sequelize.query(`
|
|
26
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "unique_name_model_type"
|
|
27
|
+
ON "custom_field_definitions" ("model_type", "entity_id", "name")
|
|
28
|
+
`);
|
|
29
|
+
await sequelize.query(`
|
|
30
|
+
CREATE TABLE IF NOT EXISTS "custom_field_values" (
|
|
31
|
+
"model_id" UUID NOT NULL,
|
|
32
|
+
"custom_field_definition_id" UUID NOT NULL
|
|
33
|
+
REFERENCES "custom_field_definitions" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
|
34
|
+
"value" JSONB,
|
|
35
|
+
"created_at" TIMESTAMPTZ NOT NULL,
|
|
36
|
+
"updated_at" TIMESTAMPTZ,
|
|
37
|
+
"deleted_at" TIMESTAMPTZ,
|
|
38
|
+
PRIMARY KEY ("model_id", "custom_field_definition_id")
|
|
39
|
+
)
|
|
40
|
+
`);
|
|
41
|
+
await sequelize.query(`
|
|
42
|
+
CREATE INDEX IF NOT EXISTS "idx_custom_field_values_active_definition_id"
|
|
43
|
+
ON "custom_field_values" ("custom_field_definition_id")
|
|
44
|
+
WHERE "deleted_at" IS NULL
|
|
45
|
+
`);
|
|
46
|
+
await sequelize.query(`
|
|
47
|
+
CREATE TABLE IF NOT EXISTS "custom_validators" (
|
|
48
|
+
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
|
|
49
|
+
"entity_id" UUID NOT NULL,
|
|
50
|
+
"entity_type" VARCHAR NOT NULL,
|
|
51
|
+
"model_type" VARCHAR NOT NULL,
|
|
52
|
+
"schema" JSONB NOT NULL,
|
|
53
|
+
"disabled" BOOLEAN NOT NULL DEFAULT false,
|
|
54
|
+
"created_at" TIMESTAMPTZ NOT NULL,
|
|
55
|
+
"updated_at" TIMESTAMPTZ,
|
|
56
|
+
PRIMARY KEY ("id")
|
|
57
|
+
)
|
|
58
|
+
`);
|
|
59
|
+
};
|
|
60
|
+
const down = async ({ context: queryInterface }) => {
|
|
61
|
+
const { sequelize } = queryInterface;
|
|
62
|
+
await sequelize.query("DROP TABLE IF EXISTS \"custom_field_values\"");
|
|
63
|
+
await sequelize.query("DROP TABLE IF EXISTS \"custom_field_definitions\"");
|
|
64
|
+
await sequelize.query("DROP TABLE IF EXISTS \"custom_validators\"");
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
//#endregion
|
|
68
|
+
export { down, up };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/migrations/002-create-custom-field-entries.ts
|
|
3
|
+
const up = async ({ context: queryInterface }) => {
|
|
4
|
+
const { sequelize } = queryInterface;
|
|
5
|
+
await sequelize.query(`
|
|
6
|
+
CREATE TABLE IF NOT EXISTS "custom_field_entries" (
|
|
7
|
+
"model_id" UUID NOT NULL,
|
|
8
|
+
"entity_id" UUID NOT NULL,
|
|
9
|
+
"custom_fields" JSONB NOT NULL DEFAULT '{}',
|
|
10
|
+
"model_type" VARCHAR NOT NULL,
|
|
11
|
+
"created_at" TIMESTAMPTZ NOT NULL,
|
|
12
|
+
"updated_at" TIMESTAMPTZ,
|
|
13
|
+
PRIMARY KEY ("model_id")
|
|
14
|
+
)
|
|
15
|
+
`);
|
|
16
|
+
await sequelize.query(`
|
|
17
|
+
CREATE INDEX IF NOT EXISTS "idx_cfe_custom_fields"
|
|
18
|
+
ON "custom_field_entries" USING gin ("custom_fields" jsonb_path_ops)
|
|
19
|
+
`);
|
|
20
|
+
};
|
|
21
|
+
const down = async ({ context: queryInterface }) => {
|
|
22
|
+
await queryInterface.sequelize.query("DROP TABLE IF EXISTS \"custom_field_entries\"");
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
exports.down = down;
|
|
27
|
+
exports.up = up;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region src/migrations/002-create-custom-field-entries.ts
|
|
2
|
+
const up = async ({ context: queryInterface }) => {
|
|
3
|
+
const { sequelize } = queryInterface;
|
|
4
|
+
await sequelize.query(`
|
|
5
|
+
CREATE TABLE IF NOT EXISTS "custom_field_entries" (
|
|
6
|
+
"model_id" UUID NOT NULL,
|
|
7
|
+
"entity_id" UUID NOT NULL,
|
|
8
|
+
"custom_fields" JSONB NOT NULL DEFAULT '{}',
|
|
9
|
+
"model_type" VARCHAR NOT NULL,
|
|
10
|
+
"created_at" TIMESTAMPTZ NOT NULL,
|
|
11
|
+
"updated_at" TIMESTAMPTZ,
|
|
12
|
+
PRIMARY KEY ("model_id")
|
|
13
|
+
)
|
|
14
|
+
`);
|
|
15
|
+
await sequelize.query(`
|
|
16
|
+
CREATE INDEX IF NOT EXISTS "idx_cfe_custom_fields"
|
|
17
|
+
ON "custom_field_entries" USING gin ("custom_fields" jsonb_path_ops)
|
|
18
|
+
`);
|
|
19
|
+
};
|
|
20
|
+
const down = async ({ context: queryInterface }) => {
|
|
21
|
+
await queryInterface.sequelize.query("DROP TABLE IF EXISTS \"custom_field_entries\"");
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
//#endregion
|
|
25
|
+
export { down, up };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/migrations/003-create-custom-field-model-type-map.ts
|
|
3
|
+
const up = async ({ context: queryInterface }) => {
|
|
4
|
+
const { sequelize } = queryInterface;
|
|
5
|
+
await sequelize.query(`
|
|
6
|
+
CREATE TABLE IF NOT EXISTS "custom_field_model_type_map" (
|
|
7
|
+
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
|
|
8
|
+
"model_type_id" UUID NOT NULL,
|
|
9
|
+
"custom_field_definition_id" UUID NOT NULL
|
|
10
|
+
REFERENCES "custom_field_definitions" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
|
11
|
+
"created_at" TIMESTAMPTZ NOT NULL,
|
|
12
|
+
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
13
|
+
PRIMARY KEY ("id")
|
|
14
|
+
)
|
|
15
|
+
`);
|
|
16
|
+
await sequelize.query(`
|
|
17
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "unique_model_type_custom_field"
|
|
18
|
+
ON "custom_field_model_type_map" ("model_type_id", "custom_field_definition_id")
|
|
19
|
+
`);
|
|
20
|
+
await sequelize.query(`
|
|
21
|
+
CREATE INDEX IF NOT EXISTS "idx_custom_field_model_type_map_definition_id"
|
|
22
|
+
ON "custom_field_model_type_map" ("custom_field_definition_id")
|
|
23
|
+
`);
|
|
24
|
+
await sequelize.query(`
|
|
25
|
+
CREATE INDEX IF NOT EXISTS "idx_custom_field_model_type_map_type_id"
|
|
26
|
+
ON "custom_field_model_type_map" ("model_type_id")
|
|
27
|
+
`);
|
|
28
|
+
};
|
|
29
|
+
const down = async ({ context: queryInterface }) => {
|
|
30
|
+
await queryInterface.sequelize.query("DROP TABLE IF EXISTS \"custom_field_model_type_map\"");
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
//#endregion
|
|
34
|
+
exports.down = down;
|
|
35
|
+
exports.up = up;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
//#region src/migrations/003-create-custom-field-model-type-map.ts
|
|
2
|
+
const up = async ({ context: queryInterface }) => {
|
|
3
|
+
const { sequelize } = queryInterface;
|
|
4
|
+
await sequelize.query(`
|
|
5
|
+
CREATE TABLE IF NOT EXISTS "custom_field_model_type_map" (
|
|
6
|
+
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
|
|
7
|
+
"model_type_id" UUID NOT NULL,
|
|
8
|
+
"custom_field_definition_id" UUID NOT NULL
|
|
9
|
+
REFERENCES "custom_field_definitions" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
|
10
|
+
"created_at" TIMESTAMPTZ NOT NULL,
|
|
11
|
+
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
12
|
+
PRIMARY KEY ("id")
|
|
13
|
+
)
|
|
14
|
+
`);
|
|
15
|
+
await sequelize.query(`
|
|
16
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "unique_model_type_custom_field"
|
|
17
|
+
ON "custom_field_model_type_map" ("model_type_id", "custom_field_definition_id")
|
|
18
|
+
`);
|
|
19
|
+
await sequelize.query(`
|
|
20
|
+
CREATE INDEX IF NOT EXISTS "idx_custom_field_model_type_map_definition_id"
|
|
21
|
+
ON "custom_field_model_type_map" ("custom_field_definition_id")
|
|
22
|
+
`);
|
|
23
|
+
await sequelize.query(`
|
|
24
|
+
CREATE INDEX IF NOT EXISTS "idx_custom_field_model_type_map_type_id"
|
|
25
|
+
ON "custom_field_model_type_map" ("model_type_id")
|
|
26
|
+
`);
|
|
27
|
+
};
|
|
28
|
+
const down = async ({ context: queryInterface }) => {
|
|
29
|
+
await queryInterface.sequelize.query("DROP TABLE IF EXISTS \"custom_field_model_type_map\"");
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
//#endregion
|
|
33
|
+
export { down, up };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/migrations/004-create-field-policy-tables.ts
|
|
3
|
+
const up = async ({ context: queryInterface }) => {
|
|
4
|
+
const { sequelize } = queryInterface;
|
|
5
|
+
await sequelize.query(`
|
|
6
|
+
CREATE TABLE IF NOT EXISTS "field_policies" (
|
|
7
|
+
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
|
|
8
|
+
"context_id" UUID NOT NULL,
|
|
9
|
+
"name" VARCHAR NOT NULL,
|
|
10
|
+
"fields" JSONB NOT NULL DEFAULT '[]',
|
|
11
|
+
"models" JSONB NOT NULL DEFAULT '[]',
|
|
12
|
+
"created_at" TIMESTAMPTZ NOT NULL,
|
|
13
|
+
"updated_at" TIMESTAMPTZ,
|
|
14
|
+
PRIMARY KEY ("id")
|
|
15
|
+
)
|
|
16
|
+
`);
|
|
17
|
+
await sequelize.query(`
|
|
18
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "unique_context_policy"
|
|
19
|
+
ON "field_policies" ("context_id", "name")
|
|
20
|
+
`);
|
|
21
|
+
};
|
|
22
|
+
const down = async ({ context: queryInterface }) => {
|
|
23
|
+
const { sequelize } = queryInterface;
|
|
24
|
+
await sequelize.query("DROP TABLE IF EXISTS \"field_policies\"");
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
exports.down = down;
|
|
29
|
+
exports.up = up;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//#region src/migrations/004-create-field-policy-tables.ts
|
|
2
|
+
const up = async ({ context: queryInterface }) => {
|
|
3
|
+
const { sequelize } = queryInterface;
|
|
4
|
+
await sequelize.query(`
|
|
5
|
+
CREATE TABLE IF NOT EXISTS "field_policies" (
|
|
6
|
+
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
|
|
7
|
+
"context_id" UUID NOT NULL,
|
|
8
|
+
"name" VARCHAR NOT NULL,
|
|
9
|
+
"fields" JSONB NOT NULL DEFAULT '[]',
|
|
10
|
+
"models" JSONB NOT NULL DEFAULT '[]',
|
|
11
|
+
"created_at" TIMESTAMPTZ NOT NULL,
|
|
12
|
+
"updated_at" TIMESTAMPTZ,
|
|
13
|
+
PRIMARY KEY ("id")
|
|
14
|
+
)
|
|
15
|
+
`);
|
|
16
|
+
await sequelize.query(`
|
|
17
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "unique_context_policy"
|
|
18
|
+
ON "field_policies" ("context_id", "name")
|
|
19
|
+
`);
|
|
20
|
+
};
|
|
21
|
+
const down = async ({ context: queryInterface }) => {
|
|
22
|
+
const { sequelize } = queryInterface;
|
|
23
|
+
await sequelize.query("DROP TABLE IF EXISTS \"field_policies\"");
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
//#endregion
|
|
27
|
+
export { down, up };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/migrations/005-add-entity-type-to-field-policies.ts
|
|
3
|
+
const up = async ({ context: queryInterface }) => {
|
|
4
|
+
const { sequelize } = queryInterface;
|
|
5
|
+
await sequelize.query(`
|
|
6
|
+
ALTER TABLE "field_policies"
|
|
7
|
+
ADD COLUMN IF NOT EXISTS "entity_type" VARCHAR
|
|
8
|
+
`);
|
|
9
|
+
};
|
|
10
|
+
const down = async ({ context: queryInterface }) => {
|
|
11
|
+
const { sequelize } = queryInterface;
|
|
12
|
+
await sequelize.query(`
|
|
13
|
+
ALTER TABLE "field_policies"
|
|
14
|
+
DROP COLUMN IF EXISTS "entity_type"
|
|
15
|
+
`);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
exports.down = down;
|
|
20
|
+
exports.up = up;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/migrations/005-add-entity-type-to-field-policies.ts
|
|
2
|
+
const up = async ({ context: queryInterface }) => {
|
|
3
|
+
const { sequelize } = queryInterface;
|
|
4
|
+
await sequelize.query(`
|
|
5
|
+
ALTER TABLE "field_policies"
|
|
6
|
+
ADD COLUMN IF NOT EXISTS "entity_type" VARCHAR
|
|
7
|
+
`);
|
|
8
|
+
};
|
|
9
|
+
const down = async ({ context: queryInterface }) => {
|
|
10
|
+
const { sequelize } = queryInterface;
|
|
11
|
+
await sequelize.query(`
|
|
12
|
+
ALTER TABLE "field_policies"
|
|
13
|
+
DROP COLUMN IF EXISTS "entity_type"
|
|
14
|
+
`);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { down, up };
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const require_index = require('../utils/logger/index.cjs');
|
|
2
|
+
const require_001_create_core_tables = require('./001-create-core-tables.cjs');
|
|
3
|
+
const require_002_create_custom_field_entries = require('./002-create-custom-field-entries.cjs');
|
|
4
|
+
const require_003_create_custom_field_model_type_map = require('./003-create-custom-field-model-type-map.cjs');
|
|
5
|
+
const require_004_create_field_policy_tables = require('./004-create-field-policy-tables.cjs');
|
|
6
|
+
const require_005_add_entity_type_to_field_policies = require('./005-add-entity-type-to-field-policies.cjs');
|
|
7
|
+
|
|
8
|
+
//#region src/migrations/index.ts
|
|
9
|
+
const { Umzug, SequelizeStorage } = require("umzug");
|
|
10
|
+
const buildMigrationList = (options) => {
|
|
11
|
+
const { useCustomFieldsEntries = false, useModelTypeMapping = false } = options;
|
|
12
|
+
return [
|
|
13
|
+
{
|
|
14
|
+
name: "001-create-core-tables",
|
|
15
|
+
up: require_001_create_core_tables.up,
|
|
16
|
+
down: require_001_create_core_tables.down
|
|
17
|
+
},
|
|
18
|
+
...useCustomFieldsEntries ? [{
|
|
19
|
+
name: "002-create-custom-field-entries",
|
|
20
|
+
up: require_002_create_custom_field_entries.up,
|
|
21
|
+
down: require_002_create_custom_field_entries.down
|
|
22
|
+
}] : [],
|
|
23
|
+
...useModelTypeMapping ? [{
|
|
24
|
+
name: "003-create-custom-field-model-type-map",
|
|
25
|
+
up: require_003_create_custom_field_model_type_map.up,
|
|
26
|
+
down: require_003_create_custom_field_model_type_map.down
|
|
27
|
+
}] : [],
|
|
28
|
+
{
|
|
29
|
+
name: "004-create-field-policy-tables",
|
|
30
|
+
up: require_004_create_field_policy_tables.up,
|
|
31
|
+
down: require_004_create_field_policy_tables.down
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: "005-add-entity-type-to-field-policies",
|
|
35
|
+
up: require_005_add_entity_type_to_field_policies.up,
|
|
36
|
+
down: require_005_add_entity_type_to_field_policies.down
|
|
37
|
+
}
|
|
38
|
+
];
|
|
39
|
+
};
|
|
40
|
+
const SADOT_MIGRATION_LOCK_ID = 839274628;
|
|
41
|
+
/**
|
|
42
|
+
* Runs sadot migrations via umzug. All migrations use IF NOT EXISTS / IF EXISTS,
|
|
43
|
+
* so they are fully idempotent — safe to run against both fresh and existing
|
|
44
|
+
* databases (including DBs previously managed by the legacy sync() path).
|
|
45
|
+
*
|
|
46
|
+
* A PostgreSQL advisory lock is acquired before running migrations so that when
|
|
47
|
+
* multiple pods start concurrently only one of them executes the migrations.
|
|
48
|
+
* The remaining pods block until the lock is released, then proceed — Umzug will
|
|
49
|
+
* see the migrations have already been applied and skip them.
|
|
50
|
+
*/
|
|
51
|
+
const runSadotMigrations = async (sequelize, options = {}) => {
|
|
52
|
+
const queryInterface = sequelize.getQueryInterface();
|
|
53
|
+
const storage = new SequelizeStorage({
|
|
54
|
+
sequelize,
|
|
55
|
+
tableName: "sadot_migrations"
|
|
56
|
+
});
|
|
57
|
+
const migrator = new Umzug({
|
|
58
|
+
migrations: buildMigrationList(options),
|
|
59
|
+
context: queryInterface,
|
|
60
|
+
storage,
|
|
61
|
+
logger: {
|
|
62
|
+
info: (msg) => require_index.default.info(`[sadot] ${JSON.stringify(msg)}`),
|
|
63
|
+
warn: (msg) => require_index.default.warn(`[sadot] ${JSON.stringify(msg)}`),
|
|
64
|
+
error: (msg) => require_index.default.error(`[sadot] ${JSON.stringify(msg)}`),
|
|
65
|
+
debug: (msg) => require_index.default.debug(`[sadot] ${JSON.stringify(msg)}`)
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
const pending = await migrator.pending();
|
|
69
|
+
if (pending.length === 0) {
|
|
70
|
+
require_index.default.info("[sadot] no pending migrations, skipping");
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
require_index.default.info("[sadot] pending migrations detected", { pending: pending.map((m) => m.name) });
|
|
74
|
+
if ((sequelize.options?.pool?.max ?? 5) < 2) {
|
|
75
|
+
require_index.default.info("[sadot] connection pool too small for advisory lock, running migrations directly");
|
|
76
|
+
await migrator.up();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
require_index.default.info("[sadot] acquiring advisory lock");
|
|
80
|
+
const transaction = await sequelize.transaction();
|
|
81
|
+
try {
|
|
82
|
+
await sequelize.query(`SELECT pg_advisory_lock(${SADOT_MIGRATION_LOCK_ID})`, { transaction });
|
|
83
|
+
require_index.default.info("[sadot] advisory lock acquired");
|
|
84
|
+
if ((await migrator.pending()).length > 0) await migrator.up();
|
|
85
|
+
else require_index.default.info("[sadot] migrations already applied by another instance, skipping");
|
|
86
|
+
} finally {
|
|
87
|
+
await sequelize.query(`SELECT pg_advisory_unlock(${SADOT_MIGRATION_LOCK_ID})`, { transaction });
|
|
88
|
+
await transaction.commit();
|
|
89
|
+
require_index.default.info("[sadot] advisory lock released");
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
//#endregion
|
|
94
|
+
exports.runSadotMigrations = runSadotMigrations;
|