@alpha.consultings/eloquent-orm.js 1.0.4 → 1.0.6

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,12 @@
1
+ ## [1.0.6](https://github.com/MetalDz/Eloquent-ORM.js/compare/v1.0.5...v1.0.6) (2026-03-28)
2
+
3
+ ## [1.0.5](https://github.com/MetalDz/Eloquent-ORM.js/compare/v1.0.4...v1.0.5) (2026-03-28)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * 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))
9
+
1
10
  ## [1.0.4](https://github.com/MetalDz/Eloquent-ORM.js/compare/v1.0.3...v1.0.4) (2026-03-25)
2
11
 
3
12
 
package/README.md CHANGED
@@ -1,17 +1,31 @@
1
1
  # Eloquent ORM JS
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/%40alpha.consultings%2F@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/%40alpha.consultings%2F@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/%40alpha.consultings%2F@alpha.consultings/eloquent-orm.js?label=node)](https://www.npmjs.com/package/@alpha.consultings/eloquent-orm.js)
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
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
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/%40alpha.consultings%2F@alpha.consultings/eloquent-orm.js?label=license)](https://github.com/MetalDz/Eloquent-ORM.js/blob/ai_master/LICENSE)
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
9
  [![docs](https://img.shields.io/badge/docs-official-blue)](https://alphaconsultings.mintlify.app/)
10
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
11
 
12
+ Quick info:
13
+ - Package: `@alpha.consultings/eloquent-orm.js`
12
14
  Laravel-inspired ORM + CLI for Node.js + TypeScript with SQL and MongoDB runtime support.
13
15
 
14
- Package: `@alpha.consultings/eloquent-orm.js`
16
+ ## New release :
17
+ <!-- package-quick-info:start -->
18
+ Quick info:
19
+ - Package: `@alpha.consultings/eloquent-orm.js`
20
+ - Version: `1.0.6`
21
+ - Latest release: `v1.0.6 latest`
22
+ - Old release: `v1.0.5`
23
+ - Latest update: ESM-safe `make:registry` imports for NodeNext apps, `SoftDeletesMixin` schema-detection hardening, restored 100% Docker coverage, and passing Docker pack smoke.
24
+ - Official docs: https://alphaconsultings.mintlify.app
25
+ - Quick start: https://alphaconsultings.mintlify.app/getting-started/quick-start
26
+ - Release history: https://alphaconsultings.mintlify.app/release/history
27
+ - Latest release notes: [PACKAGE-UPDATE-SUMMARY.md](./PACKAGE-UPDATE-SUMMARY.md)
28
+ <!-- package-quick-info:end -->
15
29
 
16
30
  ## What this package gives you
17
31
 
@@ -34,7 +48,7 @@ The following versions are the current supported and CI-tested prerequisites.
34
48
 
35
49
  | Component | Supported / tested version |
36
50
  | --- | --- |
37
- | Node.js | `20.x` |
51
+ | Node.js | `^20 || ^22 || ^24` |
38
52
  | TypeScript | `^5.9.3` |
39
53
  | MySQL | `8.0` |
40
54
  | PostgreSQL | `16` |
@@ -242,6 +256,9 @@ Start with:
242
256
  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:
243
257
 
244
258
  - Outbound DB/cache connections are by design. This package opens runtime connections to MySQL, PostgreSQL, MongoDB, SQLite, and Memcached when those drivers are configured.
259
+ - 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`.
260
+ - 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.
261
+ - 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.
245
262
  - 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.
246
263
  - 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.
247
264
  - 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.
@@ -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),
@@ -20,17 +20,24 @@ function SoftDeletesMixin(Base) {
20
20
  if (!schema || typeof schema !== "object") {
21
21
  return false;
22
22
  }
23
- return Object.entries(schema).some(([fieldName, field]) => {
23
+ for (const [fieldName, field] of Object.entries(schema)) {
24
24
  if (fieldName === this.deletedAtColumn) {
25
25
  return true;
26
26
  }
27
27
  if (!field || typeof field !== "object") {
28
- return false;
28
+ continue;
29
29
  }
30
30
  const candidate = field;
31
- return (candidate.type === "softDeletes" ||
32
- (candidate.kind === "mixin" && candidate.name === "SoftDeletes"));
33
- });
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;
34
41
  }
35
42
  constructor(...args) {
36
43
  super(...args);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alpha.consultings/eloquent-orm.js",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
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+"