@meridianjs/framework-utils 0.1.1 → 0.1.2

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/index.d.mts CHANGED
@@ -156,12 +156,6 @@ type InferModel<M extends ModelDefinition> = M extends ModelDefinition<infer Sch
156
156
  */
157
157
  declare function MeridianService(models: Record<string, ModelDefinition>): new (container: MeridianContainer) => IModuleService;
158
158
 
159
- /**
160
- * Converts a DML ModelDefinition to a MikroORM EntitySchema.
161
- *
162
- * Automatically adds `created_at`, `updated_at`, and `deleted_at` timestamp
163
- * columns to every entity.
164
- */
165
159
  declare function dmlToEntitySchema(def: ModelDefinition): EntitySchema;
166
160
  /**
167
161
  * Wraps a MikroORM EntityManager into the Repository interface expected
package/dist/index.d.ts CHANGED
@@ -156,12 +156,6 @@ type InferModel<M extends ModelDefinition> = M extends ModelDefinition<infer Sch
156
156
  */
157
157
  declare function MeridianService(models: Record<string, ModelDefinition>): new (container: MeridianContainer) => IModuleService;
158
158
 
159
- /**
160
- * Converts a DML ModelDefinition to a MikroORM EntitySchema.
161
- *
162
- * Automatically adds `created_at`, `updated_at`, and `deleted_at` timestamp
163
- * columns to every entity.
164
- */
165
159
  declare function dmlToEntitySchema(def: ModelDefinition): EntitySchema;
166
160
  /**
167
161
  * Wraps a MikroORM EntityManager into the Repository interface expected
package/dist/index.js CHANGED
@@ -55,10 +55,10 @@ function Module(key, definition) {
55
55
 
56
56
  // src/define-link.ts
57
57
  function normalizeEndpoint(input) {
58
- if ("linkable" in input) {
59
- return input;
58
+ if ("tableName" in input) {
59
+ return { linkable: input };
60
60
  }
61
- return { linkable: input };
61
+ return input;
62
62
  }
63
63
  function defineLink(left, right, options) {
64
64
  const leftEndpoint = normalizeEndpoint(left);
@@ -184,6 +184,15 @@ var model = {
184
184
  };
185
185
 
186
186
  // src/service-factory.ts
187
+ var UPDATE_RESERVED = /* @__PURE__ */ new Set([
188
+ "id",
189
+ "created_at",
190
+ "updated_at",
191
+ "deleted_at",
192
+ "__proto__",
193
+ "constructor",
194
+ "prototype"
195
+ ]);
187
196
  function MeridianService(models) {
188
197
  class BaseService {
189
198
  // Use private class field to avoid conflicting with the index signature
@@ -200,21 +209,21 @@ function MeridianService(models) {
200
209
  if (!hasCustomMethod(listMethod)) {
201
210
  this[listMethod] = async (filters = {}, options = {}) => {
202
211
  const repo = this.#container.resolve(repoToken);
203
- return repo.find(filters, options);
212
+ return repo.find({ deleted_at: null, ...filters }, options);
204
213
  };
205
214
  }
206
215
  const listAndCountMethod = `listAndCount${capitalizedPlural}`;
207
216
  if (!hasCustomMethod(listAndCountMethod)) {
208
217
  this[listAndCountMethod] = async (filters = {}, options = {}) => {
209
218
  const repo = this.#container.resolve(repoToken);
210
- return repo.findAndCount(filters, options);
219
+ return repo.findAndCount({ deleted_at: null, ...filters }, options);
211
220
  };
212
221
  }
213
222
  const retrieveMethod = `retrieve${capitalized}`;
214
223
  if (!hasCustomMethod(retrieveMethod)) {
215
224
  this[retrieveMethod] = async (id) => {
216
225
  const repo = this.#container.resolve(repoToken);
217
- return repo.findOneOrFail({ id });
226
+ return repo.findOneOrFail({ id, deleted_at: null });
218
227
  };
219
228
  }
220
229
  const createMethod = `create${capitalized}`;
@@ -230,8 +239,11 @@ function MeridianService(models) {
230
239
  if (!hasCustomMethod(updateMethod)) {
231
240
  this[updateMethod] = async (id, data) => {
232
241
  const repo = this.#container.resolve(repoToken);
233
- const entity = await repo.findOneOrFail({ id });
234
- Object.assign(entity, data);
242
+ const entity = await repo.findOneOrFail({ id, deleted_at: null });
243
+ const safe = Object.fromEntries(
244
+ Object.entries(data).filter(([k]) => !UPDATE_RESERVED.has(k))
245
+ );
246
+ Object.assign(entity, safe);
235
247
  await repo.flush();
236
248
  return entity;
237
249
  };
@@ -248,7 +260,7 @@ function MeridianService(models) {
248
260
  if (!hasCustomMethod(softDeleteMethod)) {
249
261
  this[softDeleteMethod] = async (id) => {
250
262
  const repo = this.#container.resolve(repoToken);
251
- const entity = await repo.findOneOrFail({ id });
263
+ const entity = await repo.findOneOrFail({ id, deleted_at: null });
252
264
  entity.deleted_at = /* @__PURE__ */ new Date();
253
265
  await repo.flush();
254
266
  return entity;
@@ -262,7 +274,15 @@ function MeridianService(models) {
262
274
 
263
275
  // src/orm-utils.ts
264
276
  var import_core = require("@mikro-orm/core");
277
+ var RESERVED_TIMESTAMP_KEYS = ["created_at", "updated_at", "deleted_at"];
265
278
  function dmlToEntitySchema(def) {
279
+ for (const key of RESERVED_TIMESTAMP_KEYS) {
280
+ if (key in def.schema) {
281
+ throw new Error(
282
+ `Model "${def.tableName}" defines reserved column "${key}". Meridian automatically manages created_at, updated_at, and deleted_at.`
283
+ );
284
+ }
285
+ }
266
286
  const properties = {};
267
287
  for (const [key, prop] of Object.entries(def.schema)) {
268
288
  if (prop instanceof IdProperty) {
@@ -344,9 +364,10 @@ function createRepository(em, entityName) {
344
364
  return repo.find(filters, options);
345
365
  },
346
366
  async findAndCount(filters, options = {}) {
367
+ const { limit, offset, ...countOptions } = options;
347
368
  const [data, count] = await Promise.all([
348
369
  repo.find(filters, options),
349
- repo.count(filters)
370
+ repo.count(filters, countOptions)
350
371
  ]);
351
372
  return [data, count];
352
373
  },
package/dist/index.mjs CHANGED
@@ -5,10 +5,10 @@ function Module(key, definition) {
5
5
 
6
6
  // src/define-link.ts
7
7
  function normalizeEndpoint(input) {
8
- if ("linkable" in input) {
9
- return input;
8
+ if ("tableName" in input) {
9
+ return { linkable: input };
10
10
  }
11
- return { linkable: input };
11
+ return input;
12
12
  }
13
13
  function defineLink(left, right, options) {
14
14
  const leftEndpoint = normalizeEndpoint(left);
@@ -134,6 +134,15 @@ var model = {
134
134
  };
135
135
 
136
136
  // src/service-factory.ts
137
+ var UPDATE_RESERVED = /* @__PURE__ */ new Set([
138
+ "id",
139
+ "created_at",
140
+ "updated_at",
141
+ "deleted_at",
142
+ "__proto__",
143
+ "constructor",
144
+ "prototype"
145
+ ]);
137
146
  function MeridianService(models) {
138
147
  class BaseService {
139
148
  // Use private class field to avoid conflicting with the index signature
@@ -150,21 +159,21 @@ function MeridianService(models) {
150
159
  if (!hasCustomMethod(listMethod)) {
151
160
  this[listMethod] = async (filters = {}, options = {}) => {
152
161
  const repo = this.#container.resolve(repoToken);
153
- return repo.find(filters, options);
162
+ return repo.find({ deleted_at: null, ...filters }, options);
154
163
  };
155
164
  }
156
165
  const listAndCountMethod = `listAndCount${capitalizedPlural}`;
157
166
  if (!hasCustomMethod(listAndCountMethod)) {
158
167
  this[listAndCountMethod] = async (filters = {}, options = {}) => {
159
168
  const repo = this.#container.resolve(repoToken);
160
- return repo.findAndCount(filters, options);
169
+ return repo.findAndCount({ deleted_at: null, ...filters }, options);
161
170
  };
162
171
  }
163
172
  const retrieveMethod = `retrieve${capitalized}`;
164
173
  if (!hasCustomMethod(retrieveMethod)) {
165
174
  this[retrieveMethod] = async (id) => {
166
175
  const repo = this.#container.resolve(repoToken);
167
- return repo.findOneOrFail({ id });
176
+ return repo.findOneOrFail({ id, deleted_at: null });
168
177
  };
169
178
  }
170
179
  const createMethod = `create${capitalized}`;
@@ -180,8 +189,11 @@ function MeridianService(models) {
180
189
  if (!hasCustomMethod(updateMethod)) {
181
190
  this[updateMethod] = async (id, data) => {
182
191
  const repo = this.#container.resolve(repoToken);
183
- const entity = await repo.findOneOrFail({ id });
184
- Object.assign(entity, data);
192
+ const entity = await repo.findOneOrFail({ id, deleted_at: null });
193
+ const safe = Object.fromEntries(
194
+ Object.entries(data).filter(([k]) => !UPDATE_RESERVED.has(k))
195
+ );
196
+ Object.assign(entity, safe);
185
197
  await repo.flush();
186
198
  return entity;
187
199
  };
@@ -198,7 +210,7 @@ function MeridianService(models) {
198
210
  if (!hasCustomMethod(softDeleteMethod)) {
199
211
  this[softDeleteMethod] = async (id) => {
200
212
  const repo = this.#container.resolve(repoToken);
201
- const entity = await repo.findOneOrFail({ id });
213
+ const entity = await repo.findOneOrFail({ id, deleted_at: null });
202
214
  entity.deleted_at = /* @__PURE__ */ new Date();
203
215
  await repo.flush();
204
216
  return entity;
@@ -212,7 +224,15 @@ function MeridianService(models) {
212
224
 
213
225
  // src/orm-utils.ts
214
226
  import { EntitySchema } from "@mikro-orm/core";
227
+ var RESERVED_TIMESTAMP_KEYS = ["created_at", "updated_at", "deleted_at"];
215
228
  function dmlToEntitySchema(def) {
229
+ for (const key of RESERVED_TIMESTAMP_KEYS) {
230
+ if (key in def.schema) {
231
+ throw new Error(
232
+ `Model "${def.tableName}" defines reserved column "${key}". Meridian automatically manages created_at, updated_at, and deleted_at.`
233
+ );
234
+ }
235
+ }
216
236
  const properties = {};
217
237
  for (const [key, prop] of Object.entries(def.schema)) {
218
238
  if (prop instanceof IdProperty) {
@@ -294,9 +314,10 @@ function createRepository(em, entityName) {
294
314
  return repo.find(filters, options);
295
315
  },
296
316
  async findAndCount(filters, options = {}) {
317
+ const { limit, offset, ...countOptions } = options;
297
318
  const [data, count] = await Promise.all([
298
319
  repo.find(filters, options),
299
- repo.count(filters)
320
+ repo.count(filters, countOptions)
300
321
  ]);
301
322
  return [data, count];
302
323
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meridianjs/framework-utils",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Utilities for building Meridian modules: DML, service factory, defineModule, defineLink",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",