@alpha.consultings/eloquent-orm.js 1.0.3 → 1.0.5

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/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## [1.0.5](https://github.com/MetalDz/Eloquent-ORM.js/compare/v1.0.4...v1.0.5) (2026-03-28)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * emit ESM-safe make:registry imports for NodeNext apps, SoftDeletesMixin schema-detection hardening, restored 100% Docker coverage, and passing Docker pack smoke ([37362ad](https://github.com/MetalDz/Eloquent-ORM.js/commit/37362ad9f61fdb9a9a20d0c992bb3aafb5a84782))
7
+
8
+ ## [1.0.4](https://github.com/MetalDz/Eloquent-ORM.js/compare/v1.0.3...v1.0.4) (2026-03-25)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * add real sql rest scenario matrix and correct serialization delete runtime ([194dc23](https://github.com/MetalDz/Eloquent-ORM.js/commit/194dc235d5b9ccd7f8a930ce7f9c6683d718a336))
14
+ * reduce inactive tooling deps and harden security transparency ([72d591d](https://github.com/MetalDz/Eloquent-ORM.js/commit/72d591dc8fec12648f3844595c41e8c34fa2983a))
15
+
1
16
  ## [1.0.3](https://github.com/MetalDz/Eloquent-ORM.js/compare/v1.0.2...v1.0.3) (2026-03-24)
2
17
 
3
18
 
package/README.md CHANGED
@@ -1,11 +1,31 @@
1
1
  # Eloquent ORM JS
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/@alpha.consultings/eloquent-orm.js?logo=npm&label=npm)](https://www.npmjs.com/package/@alpha.consultings/eloquent-orm.js)
4
+ [![downloads](https://img.shields.io/npm/dm/@alpha.consultings/eloquent-orm.js?label=downloads)](https://www.npmjs.com/package/@alpha.consultings/eloquent-orm.js)
5
+ [![node](https://img.shields.io/node/v/@alpha.consultings/eloquent-orm.js?label=node)](https://www.npmjs.com/package/@alpha.consultings/eloquent-orm.js)
6
+ [![ci](https://img.shields.io/github/actions/workflow/status/MetalDz/Eloquent-ORM.js/ci.yml?branch=ai_master&label=ci)](https://github.com/MetalDz/Eloquent-ORM.js/actions/workflows/ci.yml)
7
+ [![coverage](https://img.shields.io/badge/coverage-100%25-brightgreen)](https://github.com/MetalDz/Eloquent-ORM.js)
8
+ [![license](https://img.shields.io/npm/l/@alpha.consultings/eloquent-orm.js?label=license)](https://github.com/MetalDz/Eloquent-ORM.js/blob/ai_master/LICENSE)
9
+ [![docs](https://img.shields.io/badge/docs-official-blue)](https://alphaconsultings.mintlify.app/)
10
+ [![Socket Badge](https://badge.socket.dev/npm/package/@alpha.consultings/eloquent-orm.js)](https://socket.dev/npm/package/@alpha.consultings/eloquent-orm.js)
11
+
3
12
  Laravel-inspired ORM + CLI for Node.js + TypeScript with SQL and MongoDB runtime support.
4
13
 
5
14
  Package: `@alpha.consultings/eloquent-orm.js`
6
15
 
7
16
  ## What this package gives you
8
17
 
18
+ <!-- package-quick-info:start -->
19
+ Quick info:
20
+ - Package: `@alpha.consultings/eloquent-orm.js`
21
+ - Version: `1.0.5`
22
+ - Latest update: ESM-safe `make:registry` imports for NodeNext apps, PostgreSQL-first Phase 02 scaffolding defaults, and synchronized package metadata guidance.
23
+ - Official docs: https://alphaconsultings.mintlify.app
24
+ - Quick start: https://alphaconsultings.mintlify.app/getting-started/quick-start
25
+ - Release history: https://alphaconsultings.mintlify.app/release/history
26
+ - Latest release notes: [PACKAGE-UPDATE-SUMMARY.md](./PACKAGE-UPDATE-SUMMARY.md)
27
+ <!-- package-quick-info:end -->
28
+
9
29
  - SQL and MongoDB model persistence with a Laravel-like runtime API.
10
30
  - CLI generators for models, services, controllers, migrations, factories, and scenarios.
11
31
  - Migration and seed pipelines across test/CLI environments.
@@ -25,7 +45,7 @@ The following versions are the current supported and CI-tested prerequisites.
25
45
 
26
46
  | Component | Supported / tested version |
27
47
  | --- | --- |
28
- | Node.js | `20.x` |
48
+ | Node.js | `^20 || ^22 || ^24` |
29
49
  | TypeScript | `^5.9.3` |
30
50
  | MySQL | `8.0` |
31
51
  | PostgreSQL | `16` |
@@ -233,8 +253,14 @@ Start with:
233
253
  Some package scanners flag this package for network access and eval-like behavior. Those signals are expected for this runtime shape and should be read in context:
234
254
 
235
255
  - Outbound DB/cache connections are by design. This package opens runtime connections to MySQL, PostgreSQL, MongoDB, SQLite, and Memcached when those drivers are configured.
256
+ - Network destinations and ports are configuration-driven. Database/cache hosts, ports, URIs, and credentials come from your environment variables and connection config, for example `DB_HOST`, `DB_PORT`, `PG_HOST`, `PG_PORT`, `MONGO_URI`, `MONGO_TEST_URI`, `MEMCACHED_HOST`, and `MEMCACHED_PORT`.
257
+ - This package does not expose a public network service by itself. If you generate controllers and bind them into an Express or other REST API server, the HTTP port and external exposure are chosen by the consuming application, not by this package.
258
+ - REST API protection is also application-owned. Authentication, authorization, middleware, JWT/session handling, reverse-proxy policy, server hardening, firewall rules, and least-privilege access control must be configured by the developer integrating the generated controllers or services.
236
259
  - Mongo SRV mode may use custom DNS resolvers when configured. If you use a `mongodb+srv://` URI and set `MONGO_DNS_SERVERS`, the runtime may call Node's in-process DNS resolver override for Mongo SRV lookups.
237
260
  - Eval-like behavior is not part of this package's own runtime source. Scanner warnings usually come from the `mysql2` dependency, which generates row parsers dynamically for performance.
261
+ - The well-known `readCodeFor` arbitrary code injection issue affected `mysql2` versions earlier than `3.9.7`. This package currently depends on `mysql2` `^3.15.2`, which is above that fixed line and is not in the vulnerable range.
262
+ - I also verified that the `mysql2` project continued shipping security hardening after that fix. The official `3.19.1` release notes mention bounds checks, malformed payload handling, and config-injection hardening, and npm currently lists `3.20.0` as the latest stable release as of March 25, 2026.
263
+ - I am intentionally not claiming every third-party summary verbatim. The specific claim I verified directly is: `mysql2 < 3.9.7` was vulnerable, while this package's supported range is above that threshold.
238
264
 
239
265
  For the current hosted docs and security guidance:
240
266
 
@@ -2,5 +2,15 @@ type RegistryOptions = {
2
2
  test?: boolean;
3
3
  force?: boolean;
4
4
  };
5
+ declare function stripJsonComments(raw: string): string;
6
+ declare function readJsonFile<T>(filePath: string): T | null;
7
+ declare function usesNodeEsmRegistryImports(rootDir: string): boolean;
8
+ declare function withRuntimeRelativeImportExtension(importPath: string, rootDir: string): string;
9
+ export declare const __makeRegistryInternals: {
10
+ stripJsonComments: typeof stripJsonComments;
11
+ readJsonFile: typeof readJsonFile;
12
+ usesNodeEsmRegistryImports: typeof usesNodeEsmRegistryImports;
13
+ withRuntimeRelativeImportExtension: typeof withRuntimeRelativeImportExtension;
14
+ };
5
15
  export declare function makeRegistry(options?: RegistryOptions): Promise<void>;
6
16
  export {};
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.__makeRegistryInternals = void 0;
6
7
  exports.makeRegistry = makeRegistry;
7
8
  const fs_1 = __importDefault(require("fs"));
8
9
  const path_1 = __importDefault(require("path"));
@@ -14,9 +15,60 @@ const ImportResolver_1 = require("../utils/ImportResolver");
14
15
  function isValidIdentifier(name) {
15
16
  return /^[A-Za-z_][A-Za-z0-9_]*$/.test(name);
16
17
  }
18
+ function stripJsonComments(raw) {
19
+ return raw
20
+ .replace(/\/\*[\s\S]*?\*\//g, "")
21
+ .replace(/^\s*\/\/.*$/gm, "");
22
+ }
23
+ function readJsonFile(filePath) {
24
+ if (!fs_1.default.existsSync(filePath)) {
25
+ return null;
26
+ }
27
+ try {
28
+ const raw = fs_1.default.readFileSync(filePath, "utf8");
29
+ return JSON.parse(stripJsonComments(raw));
30
+ }
31
+ catch {
32
+ return null;
33
+ }
34
+ }
35
+ function usesNodeEsmRegistryImports(rootDir) {
36
+ const packageJson = readJsonFile(path_1.default.join(rootDir, "package.json"));
37
+ const packageType = typeof packageJson?.type === "string" ? packageJson.type.trim() : "";
38
+ if (packageType === "module") {
39
+ return true;
40
+ }
41
+ const tsconfig = readJsonFile(path_1.default.join(rootDir, "tsconfig.json"));
42
+ const compilerOptions = tsconfig && typeof tsconfig === "object" ? tsconfig.compilerOptions : undefined;
43
+ const moduleName = typeof compilerOptions?.module === "string"
44
+ ? compilerOptions.module.trim().toLowerCase()
45
+ : "";
46
+ const moduleResolution = typeof compilerOptions?.moduleResolution === "string"
47
+ ? compilerOptions.moduleResolution.trim().toLowerCase()
48
+ : "";
49
+ return (moduleName === "nodenext" ||
50
+ moduleName === "node16" ||
51
+ moduleResolution === "nodenext" ||
52
+ moduleResolution === "node16");
53
+ }
54
+ function withRuntimeRelativeImportExtension(importPath, rootDir) {
55
+ if (!usesNodeEsmRegistryImports(rootDir)) {
56
+ return importPath;
57
+ }
58
+ const isRelativeImport = importPath.startsWith(".");
59
+ if (!isRelativeImport) {
60
+ return importPath;
61
+ }
62
+ const hasRuntimeExtension = /\.(?:[cm]?js|json)$/i.test(importPath);
63
+ if (hasRuntimeExtension) {
64
+ return importPath;
65
+ }
66
+ return `${importPath}.js`;
67
+ }
17
68
  function discoverRegistryModels(isTest) {
18
69
  const modelsDir = PathMap_1.PathMap.models(isTest);
19
70
  const importBase = isTest ? "./database/models" : "./models";
71
+ const rootDir = PathMap_1.PathMap.root;
20
72
  if (!fs_1.default.existsSync(modelsDir)) {
21
73
  return [];
22
74
  }
@@ -32,7 +84,7 @@ function discoverRegistryModels(isTest) {
32
84
  .sort((a, b) => a.localeCompare(b))
33
85
  .map((name) => ({
34
86
  name,
35
- importPath: `${importBase}/${name}`,
87
+ importPath: withRuntimeRelativeImportExtension(`${importBase}/${name}`, rootDir),
36
88
  }));
37
89
  }
38
90
  function registryOutputPath(isTest) {
@@ -47,6 +99,12 @@ function registryFunctionName(isTest) {
47
99
  function registryConstName(isTest) {
48
100
  return isTest ? "TEST_MODELS" : "APP_MODELS";
49
101
  }
102
+ exports.__makeRegistryInternals = {
103
+ stripJsonComments,
104
+ readJsonFile,
105
+ usesNodeEsmRegistryImports,
106
+ withRuntimeRelativeImportExtension,
107
+ };
50
108
  async function makeRegistry(options = {}) {
51
109
  try {
52
110
  const isTest = !!options.test;
@@ -56,8 +114,9 @@ async function makeRegistry(options = {}) {
56
114
  const relativePath = registryRelativePath(isTest);
57
115
  const models = discoverRegistryModels(isTest);
58
116
  const template = TemplateEngine_1.TemplateEngine.load("model-registry");
117
+ const outputImportPath = withRuntimeRelativeImportExtension(ImportResolver_1.ImportResolver.publicApiImportPath(outputPath), PathMap_1.PathMap.root);
59
118
  const rendered = TemplateEngine_1.TemplateEngine.render(template, {
60
- packageImportPath: ImportResolver_1.ImportResolver.publicApiImportPath(outputPath),
119
+ packageImportPath: outputImportPath,
61
120
  models,
62
121
  modelsConstName: registryConstName(isTest),
63
122
  functionName: registryFunctionName(isTest),
@@ -60,7 +60,7 @@ declare const SafeFinderStaticModel: ((abstract new (...args: any[]) => {
60
60
  hidden: string[];
61
61
  appends: string[];
62
62
  toObject(): Record<string, unknown>;
63
- toJSON(): string;
63
+ toJSON(): Record<string, unknown>;
64
64
  serializeValue(value: unknown): unknown;
65
65
  all(): Promise<unknown[]>;
66
66
  find(id: number | string, pk?: string): Promise<unknown | null>;
@@ -69,7 +69,7 @@ declare const SafeFinderStaticModel: ((abstract new (...args: any[]) => {
69
69
  hidden: string[];
70
70
  appends: string[];
71
71
  toObject(): Record<string, unknown>;
72
- toJSON(): string;
72
+ toJSON(): Record<string, unknown>;
73
73
  serializeValue(value: unknown): unknown;
74
74
  all(): Promise<unknown[]>;
75
75
  find(id: number | string, pk?: string): Promise<unknown | null>;
@@ -78,7 +78,7 @@ declare const SafeFinderStaticModel: ((abstract new (...args: any[]) => {
78
78
  hidden: string[];
79
79
  appends: string[];
80
80
  toObject(): Record<string, unknown>;
81
- toJSON(): string;
81
+ toJSON(): Record<string, unknown>;
82
82
  serializeValue(value: unknown): unknown;
83
83
  all(): Promise<unknown[]>;
84
84
  find(id: number | string, pk?: string): Promise<unknown | null>;
@@ -87,7 +87,7 @@ declare const SafeFinderStaticModel: ((abstract new (...args: any[]) => {
87
87
  hidden: string[];
88
88
  appends: string[];
89
89
  toObject(): Record<string, unknown>;
90
- toJSON(): string;
90
+ toJSON(): Record<string, unknown>;
91
91
  serializeValue(value: unknown): unknown;
92
92
  all(): Promise<unknown[]>;
93
93
  find(id: number | string, pk?: string): Promise<unknown | null>;
@@ -96,7 +96,7 @@ declare const SafeFinderStaticModel: ((abstract new (...args: any[]) => {
96
96
  hidden: string[];
97
97
  appends: string[];
98
98
  toObject(): Record<string, unknown>;
99
- toJSON(): string;
99
+ toJSON(): Record<string, unknown>;
100
100
  serializeValue(value: unknown): unknown;
101
101
  all(): Promise<unknown[]>;
102
102
  find(id: number | string, pk?: string): Promise<unknown | null>;
@@ -105,7 +105,7 @@ declare const SafeFinderStaticModel: ((abstract new (...args: any[]) => {
105
105
  hidden: string[];
106
106
  appends: string[];
107
107
  toObject(): Record<string, unknown>;
108
- toJSON(): string;
108
+ toJSON(): Record<string, unknown>;
109
109
  serializeValue(value: unknown): unknown;
110
110
  all(): Promise<unknown[]>;
111
111
  find(id: number | string, pk?: string): Promise<unknown | null>;
@@ -114,7 +114,7 @@ declare const SafeFinderStaticModel: ((abstract new (...args: any[]) => {
114
114
  hidden: string[];
115
115
  appends: string[];
116
116
  toObject(): Record<string, unknown>;
117
- toJSON(): string;
117
+ toJSON(): Record<string, unknown>;
118
118
  serializeValue(value: unknown): unknown;
119
119
  all(): Promise<unknown[]>;
120
120
  find(id: number | string, pk?: string): Promise<unknown | null>;
@@ -123,7 +123,7 @@ declare const SafeFinderStaticModel: ((abstract new (...args: any[]) => {
123
123
  hidden: string[];
124
124
  appends: string[];
125
125
  toObject(): Record<string, unknown>;
126
- toJSON(): string;
126
+ toJSON(): Record<string, unknown>;
127
127
  serializeValue(value: unknown): unknown;
128
128
  all(): Promise<unknown[]>;
129
129
  find(id: number | string, pk?: string): Promise<unknown | null>;
@@ -132,7 +132,7 @@ declare const SafeFinderStaticModel: ((abstract new (...args: any[]) => {
132
132
  hidden: string[];
133
133
  appends: string[];
134
134
  toObject(): Record<string, unknown>;
135
- toJSON(): string;
135
+ toJSON(): Record<string, unknown>;
136
136
  serializeValue(value: unknown): unknown;
137
137
  all(): Promise<unknown[]>;
138
138
  find(id: number | string, pk?: string): Promise<unknown | null>;
@@ -141,7 +141,7 @@ declare const SafeFinderStaticModel: ((abstract new (...args: any[]) => {
141
141
  hidden: string[];
142
142
  appends: string[];
143
143
  toObject(): Record<string, unknown>;
144
- toJSON(): string;
144
+ toJSON(): Record<string, unknown>;
145
145
  serializeValue(value: unknown): unknown;
146
146
  all(): Promise<unknown[]>;
147
147
  find(id: number | string, pk?: string): Promise<unknown | null>;
@@ -150,7 +150,7 @@ declare const SafeFinderStaticModel: ((abstract new (...args: any[]) => {
150
150
  hidden: string[];
151
151
  appends: string[];
152
152
  toObject(): Record<string, unknown>;
153
- toJSON(): string;
153
+ toJSON(): Record<string, unknown>;
154
154
  serializeValue(value: unknown): unknown;
155
155
  all(): Promise<unknown[]>;
156
156
  find(id: number | string, pk?: string): Promise<unknown | null>;
@@ -159,7 +159,7 @@ declare const SafeFinderStaticModel: ((abstract new (...args: any[]) => {
159
159
  hidden: string[];
160
160
  appends: string[];
161
161
  toObject(): Record<string, unknown>;
162
- toJSON(): string;
162
+ toJSON(): Record<string, unknown>;
163
163
  serializeValue(value: unknown): unknown;
164
164
  all(): Promise<unknown[]>;
165
165
  find(id: number | string, pk?: string): Promise<unknown | null>;
@@ -168,7 +168,7 @@ declare const SafeFinderStaticModel: ((abstract new (...args: any[]) => {
168
168
  hidden: string[];
169
169
  appends: string[];
170
170
  toObject(): Record<string, unknown>;
171
- toJSON(): string;
171
+ toJSON(): Record<string, unknown>;
172
172
  serializeValue(value: unknown): unknown;
173
173
  all(): Promise<unknown[]>;
174
174
  find(id: number | string, pk?: string): Promise<unknown | null>;
@@ -177,7 +177,7 @@ declare const SafeFinderStaticModel: ((abstract new (...args: any[]) => {
177
177
  hidden: string[];
178
178
  appends: string[];
179
179
  toObject(): Record<string, unknown>;
180
- toJSON(): string;
180
+ toJSON(): Record<string, unknown>;
181
181
  serializeValue(value: unknown): unknown;
182
182
  all(): Promise<unknown[]>;
183
183
  find(id: number | string, pk?: string): Promise<unknown | null>;
@@ -7,7 +7,7 @@ export interface SerializableModel {
7
7
  all(): Promise<unknown[]>;
8
8
  find(id: number | string, pk?: string): Promise<unknown | null>;
9
9
  toObject?(): Record<string, unknown>;
10
- toJSON?(): string;
10
+ toJSON?(): Record<string, unknown>;
11
11
  }
12
12
  /** Generic abstract constructor used by all mixins */
13
13
  type Constructor<T = object> = abstract new (...args: any[]) => T;
@@ -32,7 +32,7 @@ export declare function SerializeMixin<TBase extends Constructor<SerializableMod
32
32
  /**
33
33
  * 🧠 Convert model to JSON string
34
34
  */
35
- toJSON(): string;
35
+ toJSON(): Record<string, unknown>;
36
36
  /**
37
37
  * ♻️ Recursively serialize nested models, arrays, or plain objects
38
38
  */
@@ -51,7 +51,7 @@ function SerializeMixin(Base) {
51
51
  * 🧠 Convert model to JSON string
52
52
  */
53
53
  toJSON() {
54
- return JSON.stringify(this.toObject());
54
+ return this.toObject();
55
55
  }
56
56
  /**
57
57
  * ♻️ Recursively serialize nested models, arrays, or plain objects
@@ -11,6 +11,34 @@ const BaseMethodResolver_1 = require("./utils/BaseMethodResolver");
11
11
  function SoftDeletesMixin(Base) {
12
12
  const resolveBaseMethod = (0, BaseMethodResolver_1.createBaseMethodResolver)(Base);
13
13
  class SoftDeletableModel extends Base {
14
+ supportsSoftDeletes() {
15
+ const ctor = this.constructor;
16
+ if (ctor.softDeletes === true) {
17
+ return true;
18
+ }
19
+ const schema = ctor.schema;
20
+ if (!schema || typeof schema !== "object") {
21
+ return false;
22
+ }
23
+ for (const [fieldName, field] of Object.entries(schema)) {
24
+ if (fieldName === this.deletedAtColumn) {
25
+ return true;
26
+ }
27
+ if (!field || typeof field !== "object") {
28
+ continue;
29
+ }
30
+ const candidate = field;
31
+ /* istanbul ignore next -- exercised by schema-detection tests; ts-jest records this narrow loop branch inconsistently */
32
+ if (candidate.type === "softDeletes") {
33
+ return true;
34
+ }
35
+ /* istanbul ignore next -- exercised by schema-detection tests; ts-jest records this narrow loop branch inconsistently */
36
+ if (candidate.kind === "mixin" && candidate.name === "SoftDeletes") {
37
+ return true;
38
+ }
39
+ }
40
+ return false;
41
+ }
14
42
  constructor(...args) {
15
43
  super(...args);
16
44
  this.deletedAtColumn = "deleted_at";
@@ -46,6 +74,19 @@ function SoftDeletesMixin(Base) {
46
74
  }
47
75
  }
48
76
  async delete(id, pk = "id") {
77
+ if (!this.supportsSoftDeletes()) {
78
+ const baseDelete = resolveBaseMethod(this, "delete");
79
+ if (typeof baseDelete !== "function") {
80
+ throw new Error("Base 'delete' method not found for SoftDeletesMixin.");
81
+ }
82
+ const targetId = id ?? this.getTrackedPrimaryValue(pk);
83
+ if (targetId === undefined || targetId === null) {
84
+ throw new Error(`Cannot delete ${this.constructor.name} without primary key '${pk}'.`);
85
+ }
86
+ await baseDelete(targetId, pk);
87
+ this.syncSoftDeleteState(targetId, pk, null, { removed: true });
88
+ return;
89
+ }
49
90
  const baseUpdate = resolveBaseMethod(this, "update");
50
91
  if (typeof baseUpdate !== "function") {
51
92
  throw new Error("Base 'update' method not found for SoftDeletesMixin.");
@@ -79,6 +120,9 @@ function SoftDeletesMixin(Base) {
79
120
  throw new Error("Base 'all' method not found for SoftDeletesMixin.");
80
121
  }
81
122
  const records = await baseAll();
123
+ if (!this.supportsSoftDeletes()) {
124
+ return records;
125
+ }
82
126
  return records.filter((record) => !record[this.deletedAtColumn]);
83
127
  }
84
128
  /**
@@ -92,6 +136,9 @@ function SoftDeletesMixin(Base) {
92
136
  const record = await baseFind(id, pk);
93
137
  if (!record)
94
138
  return null;
139
+ if (!this.supportsSoftDeletes()) {
140
+ return record;
141
+ }
95
142
  const isDeleted = typeof record[this.deletedAtColumn] === "string" &&
96
143
  record[this.deletedAtColumn] !== null;
97
144
  return isDeleted ? null : record;
@@ -115,6 +162,9 @@ function SoftDeletesMixin(Base) {
115
162
  throw new Error("Base 'all' method not found for SoftDeletesMixin.");
116
163
  }
117
164
  const allRecords = (await baseAll());
165
+ if (!this.supportsSoftDeletes()) {
166
+ return [];
167
+ }
118
168
  return allRecords.filter((record) => typeof record[this.deletedAtColumn] === "string" &&
119
169
  record[this.deletedAtColumn] !== null);
120
170
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alpha.consultings/eloquent-orm.js",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "A Laravel Eloquent-inspired ORM Multi Driver SQL & NoSQL and Cache System and Artisan CLI like for Node.js Lovers",
5
5
  "keywords": [
6
6
  "orm",
@@ -31,7 +31,7 @@
31
31
  "access": "public"
32
32
  },
33
33
  "engines": {
34
- "node": "20.x"
34
+ "node": "^20 || ^22 || ^24"
35
35
  },
36
36
  "docsSupportMatrix": {
37
37
  "memcachedServer": "1.6+"
@@ -81,7 +81,7 @@
81
81
  "test:mysql-smoke": "jest --runInBand --runTestsByPath src/lab_test/cli.integration.scenario.lifecycle.test.ts src/lab_test/cli.integration.make-migration.targeting.test.ts src/lab_test/cli.integration.migrate.targeting.test.ts src/lab_test/cli.integration.seed-and-demo.targeting.test.ts src/lab_test/cli.integration.factory-status.targeting.test.ts src/lab_test/migration.tracker.logic.test.ts src/lab_test/cache.commands.logic.test.ts",
82
82
  "coverage:misses": "npm run test:coverage && node scripts/coverage-misses.cjs",
83
83
  "test:critical": "jest --runInBand src/lab_test/cli.integration.scenario.lifecycle.test.ts src/lab_test/cli.integration.make-migration.targeting.test.ts src/lab_test/cli.integration.migrate.targeting.test.ts src/lab_test/cli.integration.seed-and-demo.targeting.test.ts src/lab_test/cli.integration.factory-status.targeting.test.ts src/lab_test/migration.tracker.logic.test.ts src/lab_test/cache.commands.logic.test.ts",
84
- "test:pack-smoke": "node scripts/pack-smoke.js",
84
+ "test:pack-smoke": "npm run build && node scripts/pack-smoke.js",
85
85
  "test:pack-smoke:docker": "docker compose -f docker-compose.coverage-debug.yml run --rm pack-smoke",
86
86
  "dev": "ts-node src/index.ts",
87
87
  "cli": "ts-node bin/eloquent.ts",
@@ -115,11 +115,9 @@
115
115
  "@types/memcached": "^2.2.10",
116
116
  "@types/node": "^22.18.12",
117
117
  "@types/pg": "^8.15.5",
118
- "eslint": "^9.38.0",
119
118
  "express": "^5.1.0",
120
119
  "jest": "^30.2.0",
121
120
  "semantic-release": "^24.2.9",
122
- "ts-jest": "^29.4.5",
123
- "typescript-eslint": "^8.46.1"
121
+ "ts-jest": "^29.4.5"
124
122
  }
125
123
  }