@orion-js/migrations 4.0.0-next.2 → 4.0.0-next.4

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Orionjs Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/index.cjs CHANGED
@@ -1,7 +1,13 @@
1
+ var __create = Object.create;
1
2
  var __defProp = Object.defineProperty;
2
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
7
+ var __typeError = (msg) => {
8
+ throw TypeError(msg);
9
+ };
10
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
5
11
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
12
  var __export = (target, all) => {
7
13
  for (var name in all)
@@ -16,6 +22,45 @@ var __copyProps = (to, from, except, desc) => {
16
22
  return to;
17
23
  };
18
24
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
25
+ var __decoratorStart = (base) => [, , , __create((base == null ? void 0 : base[__knownSymbol("metadata")]) ?? null)];
26
+ var __decoratorStrings = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"];
27
+ var __expectFn = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError("Function expected") : fn;
28
+ var __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: (fn) => done._ ? __typeError("Already initialized") : fns.push(__expectFn(fn || null)) });
29
+ var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol("metadata"), array[3]);
30
+ var __runInitializers = (array, flags, self, value) => {
31
+ for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) flags & 1 ? fns[i].call(self) : value = fns[i].call(self, value);
32
+ return value;
33
+ };
34
+ var __decorateElement = (array, flags, name, decorators, target, extra) => {
35
+ var fn, it, done, ctx, access, k = flags & 7, s = !!(flags & 8), p = !!(flags & 16);
36
+ var j = k > 3 ? array.length + 1 : k ? s ? 1 : 2 : 0, key = __decoratorStrings[k + 5];
37
+ var initializers = k > 3 && (array[j - 1] = []), extraInitializers = array[j] || (array[j] = []);
38
+ var desc = k && (!p && !s && (target = target.prototype), k < 5 && (k > 3 || !p) && __getOwnPropDesc(k < 4 ? target : { get [name]() {
39
+ return __privateGet(this, extra);
40
+ }, set [name](x) {
41
+ return __privateSet(this, extra, x);
42
+ } }, name));
43
+ k ? p && k < 4 && __name(extra, (k > 2 ? "set " : k > 1 ? "get " : "") + name) : __name(target, name);
44
+ for (var i = decorators.length - 1; i >= 0; i--) {
45
+ ctx = __decoratorContext(k, name, done = {}, array[3], extraInitializers);
46
+ if (k) {
47
+ ctx.static = s, ctx.private = p, access = ctx.access = { has: p ? (x) => __privateIn(target, x) : (x) => name in x };
48
+ if (k ^ 3) access.get = p ? (x) => (k ^ 1 ? __privateGet : __privateMethod)(x, target, k ^ 4 ? extra : desc.get) : (x) => x[name];
49
+ if (k > 2) access.set = p ? (x, y) => __privateSet(x, target, y, k ^ 4 ? extra : desc.set) : (x, y) => x[name] = y;
50
+ }
51
+ it = (0, decorators[i])(k ? k < 4 ? p ? extra : desc[key] : k > 4 ? void 0 : { get: desc.get, set: desc.set } : target, ctx), done._ = 1;
52
+ if (k ^ 4 || it === void 0) __expectFn(it) && (k > 4 ? initializers.unshift(it) : k ? p ? extra = it : desc[key] = it : target = it);
53
+ else if (typeof it !== "object" || it === null) __typeError("Object expected");
54
+ else __expectFn(fn = it.get) && (desc.get = fn), __expectFn(fn = it.set) && (desc.set = fn), __expectFn(fn = it.init) && initializers.unshift(fn);
55
+ }
56
+ return k || __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target;
57
+ };
58
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
59
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
60
+ var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError('Cannot use the "in" operator on this value') : member.has(obj);
61
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
62
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
63
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
19
64
 
20
65
  // src/index.ts
21
66
  var index_exports = {};
@@ -31,53 +76,28 @@ module.exports = __toCommonJS(index_exports);
31
76
 
32
77
  // src/Schema.ts
33
78
  var import_typed_model = require("@orion-js/typed-model");
34
- function _ts_decorate(decorators, target, key, desc) {
35
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
36
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
37
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
38
- return c > 3 && r && Object.defineProperty(target, key, r), r;
39
- }
40
- __name(_ts_decorate, "_ts_decorate");
41
- function _ts_metadata(k, v) {
42
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
- }
44
- __name(_ts_metadata, "_ts_metadata");
45
- var _MigrationSchema = class _MigrationSchema {
46
- _id;
47
- name;
48
- completedAt;
79
+ var _completedAt_dec, _name_dec, __id_dec, _MigrationSchema_decorators, _init;
80
+ _MigrationSchema_decorators = [(0, import_typed_model.TypedSchema)()], __id_dec = [(0, import_typed_model.Prop)({ type: "string" })], _name_dec = [(0, import_typed_model.Prop)({ type: String })], _completedAt_dec = [(0, import_typed_model.Prop)({ type: Date })];
81
+ var MigrationSchema = class {
82
+ constructor() {
83
+ __publicField(this, "_id", __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);
84
+ __publicField(this, "name", __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);
85
+ __publicField(this, "completedAt", __runInitializers(_init, 16, this)), __runInitializers(_init, 19, this);
86
+ }
49
87
  };
50
- __name(_MigrationSchema, "MigrationSchema");
51
- var MigrationSchema = _MigrationSchema;
52
- _ts_decorate([
53
- (0, import_typed_model.Prop)({
54
- type: "string"
55
- }),
56
- _ts_metadata("design:type", typeof MigrationId === "undefined" ? Object : MigrationId)
57
- ], MigrationSchema.prototype, "_id", void 0);
58
- _ts_decorate([
59
- (0, import_typed_model.Prop)(),
60
- _ts_metadata("design:type", String)
61
- ], MigrationSchema.prototype, "name", void 0);
62
- _ts_decorate([
63
- (0, import_typed_model.Prop)(),
64
- _ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
65
- ], MigrationSchema.prototype, "completedAt", void 0);
66
- MigrationSchema = _ts_decorate([
67
- (0, import_typed_model.TypedSchema)()
68
- ], MigrationSchema);
88
+ _init = __decoratorStart(null);
89
+ __decorateElement(_init, 5, "_id", __id_dec, MigrationSchema);
90
+ __decorateElement(_init, 5, "name", _name_dec, MigrationSchema);
91
+ __decorateElement(_init, 5, "completedAt", _completedAt_dec, MigrationSchema);
92
+ MigrationSchema = __decorateElement(_init, 0, "MigrationSchema", _MigrationSchema_decorators, MigrationSchema);
93
+ __runInitializers(_init, 1, MigrationSchema);
69
94
 
70
95
  // src/Repo.ts
71
96
  var import_mongodb = require("@orion-js/mongodb");
72
97
  var import_services = require("@orion-js/services");
73
- function _ts_decorate2(decorators, target, key, desc) {
74
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
75
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
76
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
77
- return c > 3 && r && Object.defineProperty(target, key, r), r;
78
- }
79
- __name(_ts_decorate2, "_ts_decorate");
80
- var _MigrationsRepo = class _MigrationsRepo {
98
+ var _MigrationsRepo_decorators, _init2;
99
+ _MigrationsRepo_decorators = [(0, import_services.Service)()];
100
+ var MigrationsRepo = class {
81
101
  collection = (0, import_mongodb.createCollection)({
82
102
  name: "orionjs.migrations",
83
103
  schema: MigrationSchema,
@@ -89,17 +109,12 @@ var _MigrationsRepo = class _MigrationsRepo {
89
109
  return migrations.map((m) => m.name);
90
110
  }
91
111
  async saveCompletedMigration(name) {
92
- await this.collection.insertOne({
93
- name,
94
- completedAt: /* @__PURE__ */ new Date()
95
- });
112
+ await this.collection.insertOne({ name, completedAt: /* @__PURE__ */ new Date() });
96
113
  }
97
114
  };
98
- __name(_MigrationsRepo, "MigrationsRepo");
99
- var MigrationsRepo = _MigrationsRepo;
100
- MigrationsRepo = _ts_decorate2([
101
- (0, import_services.Service)()
102
- ], MigrationsRepo);
115
+ _init2 = __decoratorStart(null);
116
+ MigrationsRepo = __decorateElement(_init2, 0, "MigrationsRepo", _MigrationsRepo_decorators, MigrationsRepo);
117
+ __runInitializers(_init2, 1, MigrationsRepo);
103
118
 
104
119
  // src/loadMigrations/index.ts
105
120
  var import_dogs = require("@orion-js/dogs");
@@ -107,28 +122,31 @@ var import_dogs = require("@orion-js/dogs");
107
122
  // src/service/index.ts
108
123
  var import_services2 = require("@orion-js/services");
109
124
  var import_services3 = require("@orion-js/services");
125
+ var serviceMetadata = /* @__PURE__ */ new WeakMap();
110
126
  function MigrationService(options) {
111
- return function(target) {
112
- (0, import_services3.Service)()(target);
113
- target.prototype.service = target;
114
- target.prototype.options = options;
115
- target.prototype.serviceType = "migration";
127
+ return function(target, context) {
128
+ (0, import_services3.Service)()(target, context);
129
+ context.addInitializer(function() {
130
+ serviceMetadata.set(this, { _serviceType: "migrations", options });
131
+ });
116
132
  };
117
133
  }
118
- __name(MigrationService, "MigrationService");
119
134
  function getMigrationsFromServices(services) {
120
- return services.filter((service) => service.prototype.serviceType === "migration").map((service) => {
121
- const options = service.prototype.options;
135
+ return services.map((service) => {
136
+ const instance = (0, import_services2.getInstance)(service);
137
+ const options = serviceMetadata.get(instance.constructor);
138
+ if (!options._serviceType || options._serviceType !== "migrations") {
139
+ throw new Error(`Service ${service.name} is not a migration service`);
140
+ }
122
141
  return {
123
- ...options,
124
- runMigration: /* @__PURE__ */ __name(async (context) => {
125
- const instance = (0, import_services2.getInstance)(service);
126
- return await instance.runMigration(context);
127
- }, "runMigration")
142
+ ...options.options,
143
+ runMigration: async (context) => {
144
+ const instance2 = (0, import_services2.getInstance)(service);
145
+ return await instance2.runMigration(context);
146
+ }
128
147
  };
129
148
  });
130
149
  }
131
- __name(getMigrationsFromServices, "getMigrationsFromServices");
132
150
 
133
151
  // src/loadMigrations/index.ts
134
152
  var import_services5 = require("@orion-js/services");
@@ -136,19 +154,12 @@ var import_services5 = require("@orion-js/services");
136
154
  // src/MigrationsService.ts
137
155
  var import_services4 = require("@orion-js/services");
138
156
  var import_logger = require("@orion-js/logger");
139
- function _ts_decorate3(decorators, target, key, desc) {
140
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
141
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
142
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
143
- return c > 3 && r && Object.defineProperty(target, key, r), r;
144
- }
145
- __name(_ts_decorate3, "_ts_decorate");
146
- function _ts_metadata2(k, v) {
147
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
148
- }
149
- __name(_ts_metadata2, "_ts_metadata");
150
- var _MigrationsService = class _MigrationsService {
151
- migrationsRepo;
157
+ var _migrationsRepo_dec, _MigrationsService_decorators, _init3;
158
+ _MigrationsService_decorators = [(0, import_services4.Service)()], _migrationsRepo_dec = [(0, import_services4.Inject)(() => MigrationsRepo)];
159
+ var MigrationsService = class {
160
+ constructor() {
161
+ __publicField(this, "migrationsRepo", __runInitializers(_init3, 8, this)), __runInitializers(_init3, 11, this);
162
+ }
152
163
  async getNextMigration(migrationsList) {
153
164
  const completedNames = await this.migrationsRepo.getCompletedMigrationNames();
154
165
  for (const migrationExecutable of migrationsList) {
@@ -159,17 +170,13 @@ var _MigrationsService = class _MigrationsService {
159
170
  async runMigrations(migrationsList, context) {
160
171
  const next = await this.getNextMigration(migrationsList);
161
172
  if (!next) return;
162
- import_logger.logger.info("[orionjs/migrations] Running migration...", {
163
- name: next.name
164
- });
173
+ import_logger.logger.info("[orionjs/migrations] Running migration...", { name: next.name });
165
174
  if (next.useMongoTransactions) {
166
175
  await this.runAsTransaction(next.runMigration, context);
167
176
  } else {
168
177
  await this.runMigration(next.runMigration, context);
169
178
  }
170
- import_logger.logger.info("[orionjs/migrations] Migration executed correctly", {
171
- name: next.name
172
- });
179
+ import_logger.logger.info("[orionjs/migrations] Migration executed correctly", { name: next.name });
173
180
  await this.migrationsRepo.saveCompletedMigration(next.name);
174
181
  await this.runMigrations(migrationsList, context);
175
182
  }
@@ -195,15 +202,10 @@ var _MigrationsService = class _MigrationsService {
195
202
  session.endSession();
196
203
  }
197
204
  };
198
- __name(_MigrationsService, "MigrationsService");
199
- var MigrationsService = _MigrationsService;
200
- _ts_decorate3([
201
- (0, import_services4.Inject)(() => MigrationsRepo),
202
- _ts_metadata2("design:type", typeof MigrationsRepoType === "undefined" ? Object : MigrationsRepoType)
203
- ], MigrationsService.prototype, "migrationsRepo", void 0);
204
- MigrationsService = _ts_decorate3([
205
- (0, import_services4.Service)()
206
- ], MigrationsService);
205
+ _init3 = __decoratorStart(null);
206
+ __decorateElement(_init3, 5, "migrationsRepo", _migrationsRepo_dec, MigrationsService);
207
+ MigrationsService = __decorateElement(_init3, 0, "MigrationsService", _MigrationsService_decorators, MigrationsService);
208
+ __runInitializers(_init3, 1, MigrationsService);
207
209
 
208
210
  // src/loadMigrations/index.ts
209
211
  function loadMigrations(migrationServices, options) {
@@ -212,13 +214,14 @@ function loadMigrations(migrationServices, options) {
212
214
  (0, import_dogs.startWorkers)({
213
215
  cooldownPeriod: 1e3,
214
216
  lockTime: 1e3 * 60 * 20,
217
+ // 20 min
215
218
  workersCount: 1,
216
219
  pollInterval: 10 * 1e3,
217
220
  jobs: {
218
221
  orionjsRunMigrations: (0, import_dogs.defineJob)({
219
222
  type: "recurrent",
220
223
  runEvery: 30 * 1e3,
221
- async resolve(params, context) {
224
+ async resolve(_params, context) {
222
225
  const instance = (0, import_services5.getInstance)(MigrationsService);
223
226
  await instance.runMigrations(migrations, context);
224
227
  }
@@ -227,7 +230,6 @@ function loadMigrations(migrationServices, options) {
227
230
  });
228
231
  return migrations;
229
232
  }
230
- __name(loadMigrations, "loadMigrations");
231
233
  // Annotate the CommonJS export names for ESM import in node:
232
234
  0 && (module.exports = {
233
235
  MigrationSchema,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/Schema.ts","../src/Repo.ts","../src/loadMigrations/index.ts","../src/service/index.ts","../src/MigrationsService.ts"],"sourcesContent":["export * from './Schema'\nexport * from './Repo'\nexport * from './loadMigrations'\nexport * from './service'\nexport * from './MigrationsService'\n","import {TypedSchema, Prop} from '@orion-js/typed-model'\n\nexport type MigrationId = `scnmg-${string}`\n\n@TypedSchema()\nexport class MigrationSchema {\n @Prop({type: 'string'})\n _id: MigrationId\n\n @Prop()\n name: string\n\n @Prop()\n completedAt: Date\n}\n","import {MongoCollection, Repository, Collection, createCollection} from '@orion-js/mongodb'\nimport {MigrationSchema} from './Schema'\nimport { Service } from '@orion-js/services'\n\n@Service()\nexport class MigrationsRepo {\n public collection = createCollection<MigrationSchema>({\n name: 'orionjs.migrations',\n schema: MigrationSchema,\n idPrefix: 'scnmg-',\n indexes: []\n })\n\n async getCompletedMigrationNames() {\n const migrations = await this.collection.find().toArray()\n return migrations.map(m => m.name)\n }\n\n async saveCompletedMigration(name: string) {\n await this.collection.insertOne({name, completedAt: new Date()})\n }\n}\n","import {defineJob, startWorkers} from '@orion-js/dogs'\nimport {getMigrationsFromServices} from '../service'\nimport {getInstance} from '@orion-js/services'\nimport {MigrationsService} from '../MigrationsService'\n\nexport interface Options {\n lockTime?: number\n omitJob?: boolean\n}\n\nexport function loadMigrations(migrationServices: any[], options?: Options) {\n const migrations = getMigrationsFromServices(migrationServices)\n if (options?.omitJob) return migrations\n\n startWorkers({\n cooldownPeriod: 1000,\n lockTime: 1000 * 60 * 20, // 20 min\n workersCount: 1,\n pollInterval: 10 * 1000,\n jobs: {\n orionjsRunMigrations: defineJob({\n type: 'recurrent',\n runEvery: 30 * 1000,\n async resolve(params, context) {\n const instance = getInstance(MigrationsService)\n await instance.runMigrations(migrations, context)\n }\n })\n }\n })\n\n return migrations\n}\n","import {ExecutionContext} from '@orion-js/dogs'\nimport {getInstance} from '@orion-js/services'\nimport {Service} from '@orion-js/services'\n\nexport interface MigrationServiceOptions {\n name: string\n useMongoTransactions: false\n}\n\nexport function MigrationService(options: MigrationServiceOptions): ClassDecorator {\n return function (target: any) {\n Service()(target)\n target.prototype.service = target\n target.prototype.options = options\n target.prototype.serviceType = 'migration'\n }\n}\n\nexport type MigrationExecutable = {\n runMigration(context: ExecutionContext): Promise<void>\n} & MigrationServiceOptions\n\nexport function getMigrationsFromServices(services: any[]): MigrationExecutable[] {\n return services\n .filter(service => service.prototype.serviceType === 'migration')\n .map(service => {\n const options = service.prototype.options\n return {\n ...options,\n runMigration: async (context: ExecutionContext) => {\n const instance = getInstance(service) as any\n return await instance.runMigration(context)\n }\n }\n })\n}\n","import {Inject, Service} from '@orion-js/services'\nimport type {MigrationsRepo as MigrationsRepoType} from './Repo'\nimport {MigrationsRepo} from './Repo'\nimport {logger} from '@orion-js/logger'\nimport {MigrationExecutable} from './service'\nimport {ExecutionContext} from '@orion-js/dogs'\n\n@Service()\nexport class MigrationsService {\n @Inject(() => MigrationsRepo)\n private migrationsRepo: MigrationsRepoType\n\n async getNextMigration(migrationsList: MigrationExecutable[]) {\n const completedNames = await this.migrationsRepo.getCompletedMigrationNames()\n\n for (const migrationExecutable of migrationsList) {\n if (completedNames.includes(migrationExecutable.name)) continue\n return migrationExecutable\n }\n }\n\n async runMigrations(migrationsList: MigrationExecutable[], context: ExecutionContext) {\n const next = await this.getNextMigration(migrationsList)\n if (!next) return\n\n logger.info('[orionjs/migrations] Running migration...', {name: next.name})\n\n if (next.useMongoTransactions) {\n await this.runAsTransaction(next.runMigration, context)\n } else {\n await this.runMigration(next.runMigration, context)\n }\n\n logger.info('[orionjs/migrations] Migration executed correctly', {name: next.name})\n\n await this.migrationsRepo.saveCompletedMigration(next.name)\n\n await this.runMigrations(migrationsList, context)\n }\n\n async runMigration(\n func: (context: ExecutionContext) => Promise<void>,\n context: ExecutionContext\n ) {\n try {\n await func(context)\n } catch (error) {\n logger.error('[orionjs/migrations] Error running migration', error)\n throw error\n }\n }\n\n async runAsTransaction(\n func: (context: ExecutionContext) => Promise<void>,\n context: ExecutionContext\n ) {\n const {client} = this.migrationsRepo.collection.client\n const session = client.startSession()\n\n await session.withTransaction(async () => {\n try {\n await func(context)\n } catch (error) {\n logger.error('[orionjs/migrations] Error running migration, will abort transaction', error)\n throw error\n }\n })\n\n session.endSession()\n }\n}\n"],"mappings":"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","names":["MigrationSchema","_id","name","completedAt","type","MigrationsRepo","collection","createCollection","name","schema","MigrationSchema","idPrefix","indexes","getCompletedMigrationNames","migrations","find","toArray","map","m","saveCompletedMigration","insertOne","completedAt","Date","import_services","MigrationService","options","target","Service","prototype","service","serviceType","getMigrationsFromServices","services","filter","map","runMigration","context","instance","getInstance","import_services","import_services","MigrationsService","migrationsRepo","getNextMigration","migrationsList","completedNames","getCompletedMigrationNames","migrationExecutable","includes","name","runMigrations","context","next","logger","info","useMongoTransactions","runAsTransaction","runMigration","saveCompletedMigration","func","error","client","collection","session","startSession","withTransaction","endSession","MigrationsRepo","loadMigrations","migrationServices","options","migrations","getMigrationsFromServices","omitJob","startWorkers","cooldownPeriod","lockTime","workersCount","pollInterval","jobs","orionjsRunMigrations","defineJob","type","runEvery","resolve","params","context","instance","getInstance","MigrationsService","runMigrations"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/Schema.ts","../src/Repo.ts","../src/loadMigrations/index.ts","../src/service/index.ts","../src/MigrationsService.ts"],"sourcesContent":["export * from './Schema'\nexport * from './Repo'\nexport * from './loadMigrations'\nexport * from './service'\nexport * from './MigrationsService'\n","import {TypedSchema, Prop} from '@orion-js/typed-model'\n\nexport type MigrationId = `scnmg-${string}`\n\n@TypedSchema()\nexport class MigrationSchema {\n @Prop({type: 'string'})\n _id: MigrationId\n\n @Prop({type: String})\n name: string\n\n @Prop({type: Date})\n completedAt: Date\n}\n","import {createCollection} from '@orion-js/mongodb'\nimport {MigrationSchema} from './Schema'\nimport {Service} from '@orion-js/services'\n\n@Service()\nexport class MigrationsRepo {\n public collection = createCollection<MigrationSchema>({\n name: 'orionjs.migrations',\n schema: MigrationSchema,\n idPrefix: 'scnmg-',\n indexes: [],\n })\n\n async getCompletedMigrationNames() {\n const migrations = await this.collection.find().toArray()\n return migrations.map(m => m.name)\n }\n\n async saveCompletedMigration(name: string) {\n await this.collection.insertOne({name, completedAt: new Date()})\n }\n}\n","import {defineJob, startWorkers} from '@orion-js/dogs'\nimport {getMigrationsFromServices} from '../service'\nimport {getInstance} from '@orion-js/services'\nimport {MigrationsService} from '../MigrationsService'\n\nexport interface Options {\n lockTime?: number\n omitJob?: boolean\n}\n\nexport function loadMigrations(migrationServices: any[], options?: Options) {\n const migrations = getMigrationsFromServices(migrationServices)\n if (options?.omitJob) return migrations\n\n startWorkers({\n cooldownPeriod: 1000,\n lockTime: 1000 * 60 * 20, // 20 min\n workersCount: 1,\n pollInterval: 10 * 1000,\n jobs: {\n orionjsRunMigrations: defineJob({\n type: 'recurrent',\n runEvery: 30 * 1000,\n async resolve(_params, context) {\n const instance = getInstance(MigrationsService)\n await instance.runMigrations(migrations, context)\n },\n }),\n },\n })\n\n return migrations\n}\n","import {ExecutionContext} from '@orion-js/dogs'\nimport {getInstance} from '@orion-js/services'\nimport {Service} from '@orion-js/services'\n\nexport interface MigrationServiceOptions {\n name: string\n useMongoTransactions: false\n}\n\n// Define metadata storage using WeakMaps\nconst serviceMetadata = new WeakMap<any, {_serviceType: string; options: MigrationServiceOptions}>()\n\nexport function MigrationService(options: MigrationServiceOptions) {\n return function (target: any, context: ClassDecoratorContext<any>) {\n Service()(target, context)\n\n context.addInitializer(function (this) {\n serviceMetadata.set(this, {_serviceType: 'migrations', options: options})\n })\n }\n}\n\nexport type MigrationExecutable = {\n runMigration(context: ExecutionContext): Promise<void>\n} & MigrationServiceOptions\n\nexport function getMigrationsFromServices(services: any[]): MigrationExecutable[] {\n return services.map(service => {\n const instance = getInstance(service)\n const options = serviceMetadata.get(instance.constructor)\n if (!options._serviceType || options._serviceType !== 'migrations') {\n throw new Error(`Service ${service.name} is not a migration service`)\n }\n\n return {\n ...options.options,\n runMigration: async (context: ExecutionContext) => {\n const instance = getInstance(service) as any\n return await instance.runMigration(context)\n },\n }\n })\n}\n","import {Inject, Service} from '@orion-js/services'\nimport type {MigrationsRepo as MigrationsRepoType} from './Repo'\nimport {MigrationsRepo} from './Repo'\nimport {logger} from '@orion-js/logger'\nimport {MigrationExecutable} from './service'\nimport {ExecutionContext} from '@orion-js/dogs'\n\n@Service()\nexport class MigrationsService {\n @Inject(() => MigrationsRepo)\n private migrationsRepo: MigrationsRepoType\n\n async getNextMigration(migrationsList: MigrationExecutable[]) {\n const completedNames = await this.migrationsRepo.getCompletedMigrationNames()\n\n for (const migrationExecutable of migrationsList) {\n if (completedNames.includes(migrationExecutable.name)) continue\n return migrationExecutable\n }\n }\n\n async runMigrations(migrationsList: MigrationExecutable[], context: ExecutionContext) {\n const next = await this.getNextMigration(migrationsList)\n if (!next) return\n\n logger.info('[orionjs/migrations] Running migration...', {name: next.name})\n\n if (next.useMongoTransactions) {\n await this.runAsTransaction(next.runMigration, context)\n } else {\n await this.runMigration(next.runMigration, context)\n }\n\n logger.info('[orionjs/migrations] Migration executed correctly', {name: next.name})\n\n await this.migrationsRepo.saveCompletedMigration(next.name)\n\n await this.runMigrations(migrationsList, context)\n }\n\n async runMigration(\n func: (context: ExecutionContext) => Promise<void>,\n context: ExecutionContext,\n ) {\n try {\n await func(context)\n } catch (error) {\n logger.error('[orionjs/migrations] Error running migration', error)\n throw error\n }\n }\n\n async runAsTransaction(\n func: (context: ExecutionContext) => Promise<void>,\n context: ExecutionContext,\n ) {\n const {client} = this.migrationsRepo.collection.client\n const session = client.startSession()\n\n await session.withTransaction(async () => {\n try {\n await func(context)\n } catch (error) {\n logger.error('[orionjs/migrations] Error running migration, will abort transaction', error)\n throw error\n }\n })\n\n session.endSession()\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,yBAAgC;AAAhC;AAIA,mCAAC,gCAAY,IAEX,gBAAC,yBAAK,EAAC,MAAM,SAAQ,CAAC,IAGtB,iBAAC,yBAAK,EAAC,MAAM,OAAM,CAAC,IAGpB,wBAAC,yBAAK,EAAC,MAAM,KAAI,CAAC;AAPb,IAAM,kBAAN,MAAsB;AAAA,EAAtB;AAEL;AAGA;AAGA;AAAA;AACF;AATO;AAEL,mCADA,UADW;AAKX,oCADA,WAJW;AAQX,2CADA,kBAPW;AAAA,kBAAN,+CADP,6BACa;AAAN,4BAAM;;;ACLb,qBAA+B;AAE/B,sBAAsB;AAFtB,gCAAAA;AAIA,kCAAC,yBAAQ;AACF,IAAM,iBAAN,MAAqB;AAAA,EACnB,iBAAa,iCAAkC;AAAA,IACpD,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,SAAS,CAAC;AAAA,EACZ,CAAC;AAAA,EAED,MAAM,6BAA6B;AACjC,UAAM,aAAa,MAAM,KAAK,WAAW,KAAK,EAAE,QAAQ;AACxD,WAAO,WAAW,IAAI,OAAK,EAAE,IAAI;AAAA,EACnC;AAAA,EAEA,MAAM,uBAAuB,MAAc;AACzC,UAAM,KAAK,WAAW,UAAU,EAAC,MAAM,aAAa,oBAAI,KAAK,EAAC,CAAC;AAAA,EACjE;AACF;AAhBOA,SAAA;AAAM,iBAAN,kBAAAA,QAAA,qBADP,4BACa;AAAN,kBAAAA,QAAA,GAAM;;;ACLb,kBAAsC;;;ACCtC,IAAAC,mBAA0B;AAC1B,IAAAA,mBAAsB;AAQtB,IAAM,kBAAkB,oBAAI,QAAuE;AAE5F,SAAS,iBAAiB,SAAkC;AACjE,SAAO,SAAU,QAAa,SAAqC;AACjE,kCAAQ,EAAE,QAAQ,OAAO;AAEzB,YAAQ,eAAe,WAAgB;AACrC,sBAAgB,IAAI,MAAM,EAAC,cAAc,cAAc,QAAgB,CAAC;AAAA,IAC1E,CAAC;AAAA,EACH;AACF;AAMO,SAAS,0BAA0B,UAAwC;AAChF,SAAO,SAAS,IAAI,aAAW;AAC7B,UAAM,eAAW,8BAAY,OAAO;AACpC,UAAM,UAAU,gBAAgB,IAAI,SAAS,WAAW;AACxD,QAAI,CAAC,QAAQ,gBAAgB,QAAQ,iBAAiB,cAAc;AAClE,YAAM,IAAI,MAAM,WAAW,QAAQ,IAAI,6BAA6B;AAAA,IACtE;AAEA,WAAO;AAAA,MACL,GAAG,QAAQ;AAAA,MACX,cAAc,OAAO,YAA8B;AACjD,cAAMC,gBAAW,8BAAY,OAAO;AACpC,eAAO,MAAMA,UAAS,aAAa,OAAO;AAAA,MAC5C;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;ADxCA,IAAAC,mBAA0B;;;AEF1B,IAAAC,mBAA8B;AAG9B,oBAAqB;AAHrB,wDAAAC;AAOA,qCAAC,0BAAQ,IAEP,2BAAC,yBAAO,MAAM,cAAc;AADvB,IAAM,oBAAN,MAAwB;AAAA,EAAxB;AAEL,wBAAQ,kBAAR,kBAAAA,QAAA,6BAAAA,QAAA;AAAA;AAAA,EAEA,MAAM,iBAAiB,gBAAuC;AAC5D,UAAM,iBAAiB,MAAM,KAAK,eAAe,2BAA2B;AAE5E,eAAW,uBAAuB,gBAAgB;AAChD,UAAI,eAAe,SAAS,oBAAoB,IAAI,EAAG;AACvD,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,gBAAuC,SAA2B;AACpF,UAAM,OAAO,MAAM,KAAK,iBAAiB,cAAc;AACvD,QAAI,CAAC,KAAM;AAEX,yBAAO,KAAK,6CAA6C,EAAC,MAAM,KAAK,KAAI,CAAC;AAE1E,QAAI,KAAK,sBAAsB;AAC7B,YAAM,KAAK,iBAAiB,KAAK,cAAc,OAAO;AAAA,IACxD,OAAO;AACL,YAAM,KAAK,aAAa,KAAK,cAAc,OAAO;AAAA,IACpD;AAEA,yBAAO,KAAK,qDAAqD,EAAC,MAAM,KAAK,KAAI,CAAC;AAElF,UAAM,KAAK,eAAe,uBAAuB,KAAK,IAAI;AAE1D,UAAM,KAAK,cAAc,gBAAgB,OAAO;AAAA,EAClD;AAAA,EAEA,MAAM,aACJ,MACA,SACA;AACA,QAAI;AACF,YAAM,KAAK,OAAO;AAAA,IACpB,SAAS,OAAO;AACd,2BAAO,MAAM,gDAAgD,KAAK;AAClE,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,iBACJ,MACA,SACA;AACA,UAAM,EAAC,OAAM,IAAI,KAAK,eAAe,WAAW;AAChD,UAAM,UAAU,OAAO,aAAa;AAEpC,UAAM,QAAQ,gBAAgB,YAAY;AACxC,UAAI;AACF,cAAM,KAAK,OAAO;AAAA,MACpB,SAAS,OAAO;AACd,6BAAO,MAAM,wEAAwE,KAAK;AAC1F,cAAM;AAAA,MACR;AAAA,IACF,CAAC;AAED,YAAQ,WAAW;AAAA,EACrB;AACF;AA9DOA,SAAA;AAEL,kBAAAA,QAAA,GAAQ,kBADR,qBADW;AAAA,oBAAN,kBAAAA,QAAA,wBADP,+BACa;AAAN,kBAAAA,QAAA,GAAM;;;AFEN,SAAS,eAAe,mBAA0B,SAAmB;AAC1E,QAAM,aAAa,0BAA0B,iBAAiB;AAC9D,MAAI,mCAAS,QAAS,QAAO;AAE7B,gCAAa;AAAA,IACX,gBAAgB;AAAA,IAChB,UAAU,MAAO,KAAK;AAAA;AAAA,IACtB,cAAc;AAAA,IACd,cAAc,KAAK;AAAA,IACnB,MAAM;AAAA,MACJ,0BAAsB,uBAAU;AAAA,QAC9B,MAAM;AAAA,QACN,UAAU,KAAK;AAAA,QACf,MAAM,QAAQ,SAAS,SAAS;AAC9B,gBAAM,eAAW,8BAAY,iBAAiB;AAC9C,gBAAM,SAAS,cAAc,YAAY,OAAO;AAAA,QAClD;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,SAAO;AACT;","names":["_init","import_services","instance","import_services","import_services","_init"]}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { Collection } from '@orion-js/mongodb';
1
+ import * as _orion_js_mongodb from '@orion-js/mongodb';
2
2
  import { ExecutionContext } from '@orion-js/dogs';
3
3
 
4
4
  type MigrationId = `scnmg-${string}`;
@@ -9,7 +9,7 @@ declare class MigrationSchema {
9
9
  }
10
10
 
11
11
  declare class MigrationsRepo {
12
- collection: Collection<MigrationSchema>;
12
+ collection: _orion_js_mongodb.Collection<_orion_js_mongodb.DocumentWithId<MigrationSchema>>;
13
13
  getCompletedMigrationNames(): Promise<string[]>;
14
14
  saveCompletedMigration(name: string): Promise<void>;
15
15
  }
@@ -24,7 +24,7 @@ interface MigrationServiceOptions {
24
24
  name: string;
25
25
  useMongoTransactions: false;
26
26
  }
27
- declare function MigrationService(options: MigrationServiceOptions): ClassDecorator;
27
+ declare function MigrationService(options: MigrationServiceOptions): (target: any, context: ClassDecoratorContext<any>) => void;
28
28
  type MigrationExecutable = {
29
29
  runMigration(context: ExecutionContext): Promise<void>;
30
30
  } & MigrationServiceOptions;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Collection } from '@orion-js/mongodb';
1
+ import * as _orion_js_mongodb from '@orion-js/mongodb';
2
2
  import { ExecutionContext } from '@orion-js/dogs';
3
3
 
4
4
  type MigrationId = `scnmg-${string}`;
@@ -9,7 +9,7 @@ declare class MigrationSchema {
9
9
  }
10
10
 
11
11
  declare class MigrationsRepo {
12
- collection: Collection<MigrationSchema>;
12
+ collection: _orion_js_mongodb.Collection<_orion_js_mongodb.DocumentWithId<MigrationSchema>>;
13
13
  getCompletedMigrationNames(): Promise<string[]>;
14
14
  saveCompletedMigration(name: string): Promise<void>;
15
15
  }
@@ -24,7 +24,7 @@ interface MigrationServiceOptions {
24
24
  name: string;
25
25
  useMongoTransactions: false;
26
26
  }
27
- declare function MigrationService(options: MigrationServiceOptions): ClassDecorator;
27
+ declare function MigrationService(options: MigrationServiceOptions): (target: any, context: ClassDecoratorContext<any>) => void;
28
28
  type MigrationExecutable = {
29
29
  runMigration(context: ExecutionContext): Promise<void>;
30
30
  } & MigrationServiceOptions;
package/dist/index.js CHANGED
@@ -1,55 +1,76 @@
1
+ var __create = Object.create;
1
2
  var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
5
+ var __typeError = (msg) => {
6
+ throw TypeError(msg);
7
+ };
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2
9
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
10
+ var __decoratorStart = (base) => [, , , __create((base == null ? void 0 : base[__knownSymbol("metadata")]) ?? null)];
11
+ var __decoratorStrings = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"];
12
+ var __expectFn = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError("Function expected") : fn;
13
+ var __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: (fn) => done._ ? __typeError("Already initialized") : fns.push(__expectFn(fn || null)) });
14
+ var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol("metadata"), array[3]);
15
+ var __runInitializers = (array, flags, self, value) => {
16
+ for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) flags & 1 ? fns[i].call(self) : value = fns[i].call(self, value);
17
+ return value;
18
+ };
19
+ var __decorateElement = (array, flags, name, decorators, target, extra) => {
20
+ var fn, it, done, ctx, access, k = flags & 7, s = !!(flags & 8), p = !!(flags & 16);
21
+ var j = k > 3 ? array.length + 1 : k ? s ? 1 : 2 : 0, key = __decoratorStrings[k + 5];
22
+ var initializers = k > 3 && (array[j - 1] = []), extraInitializers = array[j] || (array[j] = []);
23
+ var desc = k && (!p && !s && (target = target.prototype), k < 5 && (k > 3 || !p) && __getOwnPropDesc(k < 4 ? target : { get [name]() {
24
+ return __privateGet(this, extra);
25
+ }, set [name](x) {
26
+ return __privateSet(this, extra, x);
27
+ } }, name));
28
+ k ? p && k < 4 && __name(extra, (k > 2 ? "set " : k > 1 ? "get " : "") + name) : __name(target, name);
29
+ for (var i = decorators.length - 1; i >= 0; i--) {
30
+ ctx = __decoratorContext(k, name, done = {}, array[3], extraInitializers);
31
+ if (k) {
32
+ ctx.static = s, ctx.private = p, access = ctx.access = { has: p ? (x) => __privateIn(target, x) : (x) => name in x };
33
+ if (k ^ 3) access.get = p ? (x) => (k ^ 1 ? __privateGet : __privateMethod)(x, target, k ^ 4 ? extra : desc.get) : (x) => x[name];
34
+ if (k > 2) access.set = p ? (x, y) => __privateSet(x, target, y, k ^ 4 ? extra : desc.set) : (x, y) => x[name] = y;
35
+ }
36
+ it = (0, decorators[i])(k ? k < 4 ? p ? extra : desc[key] : k > 4 ? void 0 : { get: desc.get, set: desc.set } : target, ctx), done._ = 1;
37
+ if (k ^ 4 || it === void 0) __expectFn(it) && (k > 4 ? initializers.unshift(it) : k ? p ? extra = it : desc[key] = it : target = it);
38
+ else if (typeof it !== "object" || it === null) __typeError("Object expected");
39
+ else __expectFn(fn = it.get) && (desc.get = fn), __expectFn(fn = it.set) && (desc.set = fn), __expectFn(fn = it.init) && initializers.unshift(fn);
40
+ }
41
+ return k || __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target;
42
+ };
43
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
44
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
45
+ var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError('Cannot use the "in" operator on this value') : member.has(obj);
46
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
47
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
48
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
3
49
 
4
50
  // src/Schema.ts
5
51
  import { TypedSchema, Prop } from "@orion-js/typed-model";
6
- function _ts_decorate(decorators, target, key, desc) {
7
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
8
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
9
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
10
- return c > 3 && r && Object.defineProperty(target, key, r), r;
11
- }
12
- __name(_ts_decorate, "_ts_decorate");
13
- function _ts_metadata(k, v) {
14
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
15
- }
16
- __name(_ts_metadata, "_ts_metadata");
17
- var _MigrationSchema = class _MigrationSchema {
18
- _id;
19
- name;
20
- completedAt;
52
+ var _completedAt_dec, _name_dec, __id_dec, _MigrationSchema_decorators, _init;
53
+ _MigrationSchema_decorators = [TypedSchema()], __id_dec = [Prop({ type: "string" })], _name_dec = [Prop({ type: String })], _completedAt_dec = [Prop({ type: Date })];
54
+ var MigrationSchema = class {
55
+ constructor() {
56
+ __publicField(this, "_id", __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);
57
+ __publicField(this, "name", __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);
58
+ __publicField(this, "completedAt", __runInitializers(_init, 16, this)), __runInitializers(_init, 19, this);
59
+ }
21
60
  };
22
- __name(_MigrationSchema, "MigrationSchema");
23
- var MigrationSchema = _MigrationSchema;
24
- _ts_decorate([
25
- Prop({
26
- type: "string"
27
- }),
28
- _ts_metadata("design:type", typeof MigrationId === "undefined" ? Object : MigrationId)
29
- ], MigrationSchema.prototype, "_id", void 0);
30
- _ts_decorate([
31
- Prop(),
32
- _ts_metadata("design:type", String)
33
- ], MigrationSchema.prototype, "name", void 0);
34
- _ts_decorate([
35
- Prop(),
36
- _ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
37
- ], MigrationSchema.prototype, "completedAt", void 0);
38
- MigrationSchema = _ts_decorate([
39
- TypedSchema()
40
- ], MigrationSchema);
61
+ _init = __decoratorStart(null);
62
+ __decorateElement(_init, 5, "_id", __id_dec, MigrationSchema);
63
+ __decorateElement(_init, 5, "name", _name_dec, MigrationSchema);
64
+ __decorateElement(_init, 5, "completedAt", _completedAt_dec, MigrationSchema);
65
+ MigrationSchema = __decorateElement(_init, 0, "MigrationSchema", _MigrationSchema_decorators, MigrationSchema);
66
+ __runInitializers(_init, 1, MigrationSchema);
41
67
 
42
68
  // src/Repo.ts
43
69
  import { createCollection } from "@orion-js/mongodb";
44
70
  import { Service } from "@orion-js/services";
45
- function _ts_decorate2(decorators, target, key, desc) {
46
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
47
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
48
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
49
- return c > 3 && r && Object.defineProperty(target, key, r), r;
50
- }
51
- __name(_ts_decorate2, "_ts_decorate");
52
- var _MigrationsRepo = class _MigrationsRepo {
71
+ var _MigrationsRepo_decorators, _init2;
72
+ _MigrationsRepo_decorators = [Service()];
73
+ var MigrationsRepo = class {
53
74
  collection = createCollection({
54
75
  name: "orionjs.migrations",
55
76
  schema: MigrationSchema,
@@ -61,17 +82,12 @@ var _MigrationsRepo = class _MigrationsRepo {
61
82
  return migrations.map((m) => m.name);
62
83
  }
63
84
  async saveCompletedMigration(name) {
64
- await this.collection.insertOne({
65
- name,
66
- completedAt: /* @__PURE__ */ new Date()
67
- });
85
+ await this.collection.insertOne({ name, completedAt: /* @__PURE__ */ new Date() });
68
86
  }
69
87
  };
70
- __name(_MigrationsRepo, "MigrationsRepo");
71
- var MigrationsRepo = _MigrationsRepo;
72
- MigrationsRepo = _ts_decorate2([
73
- Service()
74
- ], MigrationsRepo);
88
+ _init2 = __decoratorStart(null);
89
+ MigrationsRepo = __decorateElement(_init2, 0, "MigrationsRepo", _MigrationsRepo_decorators, MigrationsRepo);
90
+ __runInitializers(_init2, 1, MigrationsRepo);
75
91
 
76
92
  // src/loadMigrations/index.ts
77
93
  import { defineJob, startWorkers } from "@orion-js/dogs";
@@ -79,28 +95,31 @@ import { defineJob, startWorkers } from "@orion-js/dogs";
79
95
  // src/service/index.ts
80
96
  import { getInstance } from "@orion-js/services";
81
97
  import { Service as Service2 } from "@orion-js/services";
98
+ var serviceMetadata = /* @__PURE__ */ new WeakMap();
82
99
  function MigrationService(options) {
83
- return function(target) {
84
- Service2()(target);
85
- target.prototype.service = target;
86
- target.prototype.options = options;
87
- target.prototype.serviceType = "migration";
100
+ return function(target, context) {
101
+ Service2()(target, context);
102
+ context.addInitializer(function() {
103
+ serviceMetadata.set(this, { _serviceType: "migrations", options });
104
+ });
88
105
  };
89
106
  }
90
- __name(MigrationService, "MigrationService");
91
107
  function getMigrationsFromServices(services) {
92
- return services.filter((service) => service.prototype.serviceType === "migration").map((service) => {
93
- const options = service.prototype.options;
108
+ return services.map((service) => {
109
+ const instance = getInstance(service);
110
+ const options = serviceMetadata.get(instance.constructor);
111
+ if (!options._serviceType || options._serviceType !== "migrations") {
112
+ throw new Error(`Service ${service.name} is not a migration service`);
113
+ }
94
114
  return {
95
- ...options,
96
- runMigration: /* @__PURE__ */ __name(async (context) => {
97
- const instance = getInstance(service);
98
- return await instance.runMigration(context);
99
- }, "runMigration")
115
+ ...options.options,
116
+ runMigration: async (context) => {
117
+ const instance2 = getInstance(service);
118
+ return await instance2.runMigration(context);
119
+ }
100
120
  };
101
121
  });
102
122
  }
103
- __name(getMigrationsFromServices, "getMigrationsFromServices");
104
123
 
105
124
  // src/loadMigrations/index.ts
106
125
  import { getInstance as getInstance2 } from "@orion-js/services";
@@ -108,19 +127,12 @@ import { getInstance as getInstance2 } from "@orion-js/services";
108
127
  // src/MigrationsService.ts
109
128
  import { Inject, Service as Service3 } from "@orion-js/services";
110
129
  import { logger } from "@orion-js/logger";
111
- function _ts_decorate3(decorators, target, key, desc) {
112
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
113
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
114
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
115
- return c > 3 && r && Object.defineProperty(target, key, r), r;
116
- }
117
- __name(_ts_decorate3, "_ts_decorate");
118
- function _ts_metadata2(k, v) {
119
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
120
- }
121
- __name(_ts_metadata2, "_ts_metadata");
122
- var _MigrationsService = class _MigrationsService {
123
- migrationsRepo;
130
+ var _migrationsRepo_dec, _MigrationsService_decorators, _init3;
131
+ _MigrationsService_decorators = [Service3()], _migrationsRepo_dec = [Inject(() => MigrationsRepo)];
132
+ var MigrationsService = class {
133
+ constructor() {
134
+ __publicField(this, "migrationsRepo", __runInitializers(_init3, 8, this)), __runInitializers(_init3, 11, this);
135
+ }
124
136
  async getNextMigration(migrationsList) {
125
137
  const completedNames = await this.migrationsRepo.getCompletedMigrationNames();
126
138
  for (const migrationExecutable of migrationsList) {
@@ -131,17 +143,13 @@ var _MigrationsService = class _MigrationsService {
131
143
  async runMigrations(migrationsList, context) {
132
144
  const next = await this.getNextMigration(migrationsList);
133
145
  if (!next) return;
134
- logger.info("[orionjs/migrations] Running migration...", {
135
- name: next.name
136
- });
146
+ logger.info("[orionjs/migrations] Running migration...", { name: next.name });
137
147
  if (next.useMongoTransactions) {
138
148
  await this.runAsTransaction(next.runMigration, context);
139
149
  } else {
140
150
  await this.runMigration(next.runMigration, context);
141
151
  }
142
- logger.info("[orionjs/migrations] Migration executed correctly", {
143
- name: next.name
144
- });
152
+ logger.info("[orionjs/migrations] Migration executed correctly", { name: next.name });
145
153
  await this.migrationsRepo.saveCompletedMigration(next.name);
146
154
  await this.runMigrations(migrationsList, context);
147
155
  }
@@ -167,15 +175,10 @@ var _MigrationsService = class _MigrationsService {
167
175
  session.endSession();
168
176
  }
169
177
  };
170
- __name(_MigrationsService, "MigrationsService");
171
- var MigrationsService = _MigrationsService;
172
- _ts_decorate3([
173
- Inject(() => MigrationsRepo),
174
- _ts_metadata2("design:type", typeof MigrationsRepoType === "undefined" ? Object : MigrationsRepoType)
175
- ], MigrationsService.prototype, "migrationsRepo", void 0);
176
- MigrationsService = _ts_decorate3([
177
- Service3()
178
- ], MigrationsService);
178
+ _init3 = __decoratorStart(null);
179
+ __decorateElement(_init3, 5, "migrationsRepo", _migrationsRepo_dec, MigrationsService);
180
+ MigrationsService = __decorateElement(_init3, 0, "MigrationsService", _MigrationsService_decorators, MigrationsService);
181
+ __runInitializers(_init3, 1, MigrationsService);
179
182
 
180
183
  // src/loadMigrations/index.ts
181
184
  function loadMigrations(migrationServices, options) {
@@ -184,13 +187,14 @@ function loadMigrations(migrationServices, options) {
184
187
  startWorkers({
185
188
  cooldownPeriod: 1e3,
186
189
  lockTime: 1e3 * 60 * 20,
190
+ // 20 min
187
191
  workersCount: 1,
188
192
  pollInterval: 10 * 1e3,
189
193
  jobs: {
190
194
  orionjsRunMigrations: defineJob({
191
195
  type: "recurrent",
192
196
  runEvery: 30 * 1e3,
193
- async resolve(params, context) {
197
+ async resolve(_params, context) {
194
198
  const instance = getInstance2(MigrationsService);
195
199
  await instance.runMigrations(migrations, context);
196
200
  }
@@ -199,7 +203,6 @@ function loadMigrations(migrationServices, options) {
199
203
  });
200
204
  return migrations;
201
205
  }
202
- __name(loadMigrations, "loadMigrations");
203
206
  export {
204
207
  MigrationSchema,
205
208
  MigrationService,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/Schema.ts","../src/Repo.ts","../src/loadMigrations/index.ts","../src/service/index.ts","../src/MigrationsService.ts"],"sourcesContent":["import {TypedSchema, Prop} from '@orion-js/typed-model'\n\nexport type MigrationId = `scnmg-${string}`\n\n@TypedSchema()\nexport class MigrationSchema {\n @Prop({type: 'string'})\n _id: MigrationId\n\n @Prop()\n name: string\n\n @Prop()\n completedAt: Date\n}\n","import {MongoCollection, Repository, Collection, createCollection} from '@orion-js/mongodb'\nimport {MigrationSchema} from './Schema'\nimport { Service } from '@orion-js/services'\n\n@Service()\nexport class MigrationsRepo {\n public collection = createCollection<MigrationSchema>({\n name: 'orionjs.migrations',\n schema: MigrationSchema,\n idPrefix: 'scnmg-',\n indexes: []\n })\n\n async getCompletedMigrationNames() {\n const migrations = await this.collection.find().toArray()\n return migrations.map(m => m.name)\n }\n\n async saveCompletedMigration(name: string) {\n await this.collection.insertOne({name, completedAt: new Date()})\n }\n}\n","import {defineJob, startWorkers} from '@orion-js/dogs'\nimport {getMigrationsFromServices} from '../service'\nimport {getInstance} from '@orion-js/services'\nimport {MigrationsService} from '../MigrationsService'\n\nexport interface Options {\n lockTime?: number\n omitJob?: boolean\n}\n\nexport function loadMigrations(migrationServices: any[], options?: Options) {\n const migrations = getMigrationsFromServices(migrationServices)\n if (options?.omitJob) return migrations\n\n startWorkers({\n cooldownPeriod: 1000,\n lockTime: 1000 * 60 * 20, // 20 min\n workersCount: 1,\n pollInterval: 10 * 1000,\n jobs: {\n orionjsRunMigrations: defineJob({\n type: 'recurrent',\n runEvery: 30 * 1000,\n async resolve(params, context) {\n const instance = getInstance(MigrationsService)\n await instance.runMigrations(migrations, context)\n }\n })\n }\n })\n\n return migrations\n}\n","import {ExecutionContext} from '@orion-js/dogs'\nimport {getInstance} from '@orion-js/services'\nimport {Service} from '@orion-js/services'\n\nexport interface MigrationServiceOptions {\n name: string\n useMongoTransactions: false\n}\n\nexport function MigrationService(options: MigrationServiceOptions): ClassDecorator {\n return function (target: any) {\n Service()(target)\n target.prototype.service = target\n target.prototype.options = options\n target.prototype.serviceType = 'migration'\n }\n}\n\nexport type MigrationExecutable = {\n runMigration(context: ExecutionContext): Promise<void>\n} & MigrationServiceOptions\n\nexport function getMigrationsFromServices(services: any[]): MigrationExecutable[] {\n return services\n .filter(service => service.prototype.serviceType === 'migration')\n .map(service => {\n const options = service.prototype.options\n return {\n ...options,\n runMigration: async (context: ExecutionContext) => {\n const instance = getInstance(service) as any\n return await instance.runMigration(context)\n }\n }\n })\n}\n","import {Inject, Service} from '@orion-js/services'\nimport type {MigrationsRepo as MigrationsRepoType} from './Repo'\nimport {MigrationsRepo} from './Repo'\nimport {logger} from '@orion-js/logger'\nimport {MigrationExecutable} from './service'\nimport {ExecutionContext} from '@orion-js/dogs'\n\n@Service()\nexport class MigrationsService {\n @Inject(() => MigrationsRepo)\n private migrationsRepo: MigrationsRepoType\n\n async getNextMigration(migrationsList: MigrationExecutable[]) {\n const completedNames = await this.migrationsRepo.getCompletedMigrationNames()\n\n for (const migrationExecutable of migrationsList) {\n if (completedNames.includes(migrationExecutable.name)) continue\n return migrationExecutable\n }\n }\n\n async runMigrations(migrationsList: MigrationExecutable[], context: ExecutionContext) {\n const next = await this.getNextMigration(migrationsList)\n if (!next) return\n\n logger.info('[orionjs/migrations] Running migration...', {name: next.name})\n\n if (next.useMongoTransactions) {\n await this.runAsTransaction(next.runMigration, context)\n } else {\n await this.runMigration(next.runMigration, context)\n }\n\n logger.info('[orionjs/migrations] Migration executed correctly', {name: next.name})\n\n await this.migrationsRepo.saveCompletedMigration(next.name)\n\n await this.runMigrations(migrationsList, context)\n }\n\n async runMigration(\n func: (context: ExecutionContext) => Promise<void>,\n context: ExecutionContext\n ) {\n try {\n await func(context)\n } catch (error) {\n logger.error('[orionjs/migrations] Error running migration', error)\n throw error\n }\n }\n\n async runAsTransaction(\n func: (context: ExecutionContext) => Promise<void>,\n context: ExecutionContext\n ) {\n const {client} = this.migrationsRepo.collection.client\n const session = client.startSession()\n\n await session.withTransaction(async () => {\n try {\n await func(context)\n } catch (error) {\n logger.error('[orionjs/migrations] Error running migration, will abort transaction', error)\n throw error\n }\n })\n\n session.endSession()\n }\n}\n"],"mappings":"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","names":["TypedSchema","Prop","MigrationSchema","_id","name","completedAt","type","createCollection","Service","MigrationsRepo","collection","createCollection","name","schema","MigrationSchema","idPrefix","indexes","getCompletedMigrationNames","migrations","find","toArray","map","m","saveCompletedMigration","insertOne","completedAt","Date","defineJob","startWorkers","getInstance","Service","MigrationService","options","target","Service","prototype","service","serviceType","getMigrationsFromServices","services","filter","map","runMigration","context","instance","getInstance","getInstance","Inject","Service","logger","MigrationsService","migrationsRepo","getNextMigration","migrationsList","completedNames","getCompletedMigrationNames","migrationExecutable","includes","name","runMigrations","context","next","logger","info","useMongoTransactions","runAsTransaction","runMigration","saveCompletedMigration","func","error","client","collection","session","startSession","withTransaction","endSession","MigrationsRepo","loadMigrations","migrationServices","options","migrations","getMigrationsFromServices","omitJob","startWorkers","cooldownPeriod","lockTime","workersCount","pollInterval","jobs","orionjsRunMigrations","defineJob","type","runEvery","resolve","params","context","instance","getInstance","MigrationsService","runMigrations"]}
1
+ {"version":3,"sources":["../src/Schema.ts","../src/Repo.ts","../src/loadMigrations/index.ts","../src/service/index.ts","../src/MigrationsService.ts"],"sourcesContent":["import {TypedSchema, Prop} from '@orion-js/typed-model'\n\nexport type MigrationId = `scnmg-${string}`\n\n@TypedSchema()\nexport class MigrationSchema {\n @Prop({type: 'string'})\n _id: MigrationId\n\n @Prop({type: String})\n name: string\n\n @Prop({type: Date})\n completedAt: Date\n}\n","import {createCollection} from '@orion-js/mongodb'\nimport {MigrationSchema} from './Schema'\nimport {Service} from '@orion-js/services'\n\n@Service()\nexport class MigrationsRepo {\n public collection = createCollection<MigrationSchema>({\n name: 'orionjs.migrations',\n schema: MigrationSchema,\n idPrefix: 'scnmg-',\n indexes: [],\n })\n\n async getCompletedMigrationNames() {\n const migrations = await this.collection.find().toArray()\n return migrations.map(m => m.name)\n }\n\n async saveCompletedMigration(name: string) {\n await this.collection.insertOne({name, completedAt: new Date()})\n }\n}\n","import {defineJob, startWorkers} from '@orion-js/dogs'\nimport {getMigrationsFromServices} from '../service'\nimport {getInstance} from '@orion-js/services'\nimport {MigrationsService} from '../MigrationsService'\n\nexport interface Options {\n lockTime?: number\n omitJob?: boolean\n}\n\nexport function loadMigrations(migrationServices: any[], options?: Options) {\n const migrations = getMigrationsFromServices(migrationServices)\n if (options?.omitJob) return migrations\n\n startWorkers({\n cooldownPeriod: 1000,\n lockTime: 1000 * 60 * 20, // 20 min\n workersCount: 1,\n pollInterval: 10 * 1000,\n jobs: {\n orionjsRunMigrations: defineJob({\n type: 'recurrent',\n runEvery: 30 * 1000,\n async resolve(_params, context) {\n const instance = getInstance(MigrationsService)\n await instance.runMigrations(migrations, context)\n },\n }),\n },\n })\n\n return migrations\n}\n","import {ExecutionContext} from '@orion-js/dogs'\nimport {getInstance} from '@orion-js/services'\nimport {Service} from '@orion-js/services'\n\nexport interface MigrationServiceOptions {\n name: string\n useMongoTransactions: false\n}\n\n// Define metadata storage using WeakMaps\nconst serviceMetadata = new WeakMap<any, {_serviceType: string; options: MigrationServiceOptions}>()\n\nexport function MigrationService(options: MigrationServiceOptions) {\n return function (target: any, context: ClassDecoratorContext<any>) {\n Service()(target, context)\n\n context.addInitializer(function (this) {\n serviceMetadata.set(this, {_serviceType: 'migrations', options: options})\n })\n }\n}\n\nexport type MigrationExecutable = {\n runMigration(context: ExecutionContext): Promise<void>\n} & MigrationServiceOptions\n\nexport function getMigrationsFromServices(services: any[]): MigrationExecutable[] {\n return services.map(service => {\n const instance = getInstance(service)\n const options = serviceMetadata.get(instance.constructor)\n if (!options._serviceType || options._serviceType !== 'migrations') {\n throw new Error(`Service ${service.name} is not a migration service`)\n }\n\n return {\n ...options.options,\n runMigration: async (context: ExecutionContext) => {\n const instance = getInstance(service) as any\n return await instance.runMigration(context)\n },\n }\n })\n}\n","import {Inject, Service} from '@orion-js/services'\nimport type {MigrationsRepo as MigrationsRepoType} from './Repo'\nimport {MigrationsRepo} from './Repo'\nimport {logger} from '@orion-js/logger'\nimport {MigrationExecutable} from './service'\nimport {ExecutionContext} from '@orion-js/dogs'\n\n@Service()\nexport class MigrationsService {\n @Inject(() => MigrationsRepo)\n private migrationsRepo: MigrationsRepoType\n\n async getNextMigration(migrationsList: MigrationExecutable[]) {\n const completedNames = await this.migrationsRepo.getCompletedMigrationNames()\n\n for (const migrationExecutable of migrationsList) {\n if (completedNames.includes(migrationExecutable.name)) continue\n return migrationExecutable\n }\n }\n\n async runMigrations(migrationsList: MigrationExecutable[], context: ExecutionContext) {\n const next = await this.getNextMigration(migrationsList)\n if (!next) return\n\n logger.info('[orionjs/migrations] Running migration...', {name: next.name})\n\n if (next.useMongoTransactions) {\n await this.runAsTransaction(next.runMigration, context)\n } else {\n await this.runMigration(next.runMigration, context)\n }\n\n logger.info('[orionjs/migrations] Migration executed correctly', {name: next.name})\n\n await this.migrationsRepo.saveCompletedMigration(next.name)\n\n await this.runMigrations(migrationsList, context)\n }\n\n async runMigration(\n func: (context: ExecutionContext) => Promise<void>,\n context: ExecutionContext,\n ) {\n try {\n await func(context)\n } catch (error) {\n logger.error('[orionjs/migrations] Error running migration', error)\n throw error\n }\n }\n\n async runAsTransaction(\n func: (context: ExecutionContext) => Promise<void>,\n context: ExecutionContext,\n ) {\n const {client} = this.migrationsRepo.collection.client\n const session = client.startSession()\n\n await session.withTransaction(async () => {\n try {\n await func(context)\n } catch (error) {\n logger.error('[orionjs/migrations] Error running migration, will abort transaction', error)\n throw error\n }\n })\n\n session.endSession()\n }\n}\n"],"mappings":"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","names":["_init","Service","instance","getInstance","Service","_init","Service","getInstance"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orion-js/migrations",
3
- "version": "4.0.0-next.2",
3
+ "version": "4.0.0-next.4",
4
4
  "main": "./dist/index.cjs",
5
5
  "types": "./dist/index.d.ts",
6
6
  "files": [
@@ -9,16 +9,15 @@
9
9
  "author": "nicolaslopezj",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
- "@orion-js/dogs": "4.0.0-next.2",
13
- "@orion-js/mongodb": "4.0.0-next.2",
14
- "@orion-js/helpers": "4.0.0-next.2",
15
- "@orion-js/services": "4.0.0-next.2",
16
- "@orion-js/typed-model": "4.0.0-next.2",
17
- "@orion-js/logger": "4.0.0-next.2"
12
+ "@orion-js/dogs": "4.0.0-next.4",
13
+ "@orion-js/helpers": "4.0.0-next.4",
14
+ "@orion-js/typed-model": "4.0.0-next.4",
15
+ "@orion-js/mongodb": "4.0.0-next.4",
16
+ "@orion-js/services": "4.0.0-next.4",
17
+ "@orion-js/logger": "4.0.0-next.4"
18
18
  },
19
19
  "devDependencies": {
20
20
  "@types/lodash": "4.14.195",
21
- "reflect-metadata": "^0.1.13",
22
21
  "typescript": "^5.4.5",
23
22
  "@types/node": "^18.0.0",
24
23
  "tsup": "^8.0.1",