@sentzunhat/zacatl 0.0.20 → 0.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/README.md +16 -0
  2. package/build/index.d.ts +1 -0
  3. package/build/index.d.ts.map +1 -1
  4. package/build/index.js +1 -0
  5. package/build/index.js.map +1 -1
  6. package/build/orm-exports.d.ts +5 -0
  7. package/build/orm-exports.d.ts.map +1 -0
  8. package/build/orm-exports.js +3 -0
  9. package/build/orm-exports.js.map +1 -0
  10. package/build/service/architecture/infrastructure/orm/adapter-loader.d.ts +5 -0
  11. package/build/service/architecture/infrastructure/orm/adapter-loader.d.ts.map +1 -0
  12. package/build/service/architecture/infrastructure/orm/adapter-loader.js +25 -0
  13. package/build/service/architecture/infrastructure/orm/adapter-loader.js.map +1 -0
  14. package/build/service/architecture/infrastructure/orm/adapters/mongoose-adapter.d.ts +1 -1
  15. package/build/service/architecture/infrastructure/orm/adapters/mongoose-adapter.d.ts.map +1 -1
  16. package/build/service/architecture/infrastructure/orm/adapters/mongoose-adapter.js +2 -4
  17. package/build/service/architecture/infrastructure/orm/adapters/mongoose-adapter.js.map +1 -1
  18. package/build/service/architecture/infrastructure/repositories/abstract.d.ts +3 -2
  19. package/build/service/architecture/infrastructure/repositories/abstract.d.ts.map +1 -1
  20. package/build/service/architecture/infrastructure/repositories/abstract.js +7 -6
  21. package/build/service/architecture/infrastructure/repositories/abstract.js.map +1 -1
  22. package/build/test/tsconfig.tsbuildinfo +1 -1
  23. package/package.json +50 -7
  24. package/src/index.ts +3 -0
  25. package/src/orm-exports.ts +23 -0
  26. package/src/service/architecture/infrastructure/orm/adapter-loader.ts +52 -0
  27. package/src/service/architecture/infrastructure/orm/adapters/mongoose-adapter.ts +10 -11
  28. package/src/service/architecture/infrastructure/repositories/abstract.ts +21 -14
package/package.json CHANGED
@@ -4,8 +4,36 @@
4
4
  "main": "build/index.js",
5
5
  "module": "build/index.js",
6
6
  "types": "build/index.d.ts",
7
- "version": "0.0.20",
7
+ "version": "0.0.21",
8
8
  "packageManager": "npm@10.9.0",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./build/index.js",
12
+ "types": "./build/index.d.ts"
13
+ },
14
+ "./infrastructure": {
15
+ "import": "./build/service/architecture/infrastructure/repositories/abstract.js",
16
+ "types": "./build/service/architecture/infrastructure/repositories/abstract.d.ts"
17
+ },
18
+ "./domain": {
19
+ "import": "./build/service/architecture/domain/index.js",
20
+ "types": "./build/service/architecture/domain/index.d.ts"
21
+ },
22
+ "./application": {
23
+ "import": "./build/service/architecture/application/index.js",
24
+ "types": "./build/service/architecture/application/index.d.ts"
25
+ },
26
+ "./errors": {
27
+ "import": "./build/error/index.js",
28
+ "types": "./build/error/index.d.ts"
29
+ },
30
+ "./config": {
31
+ "import": "./build/configuration/index.js",
32
+ "types": "./build/configuration/index.d.ts"
33
+ },
34
+ "./build/*": "./build/*",
35
+ "./package.json": "./package.json"
36
+ },
9
37
  "repository": {
10
38
  "type": "git",
11
39
  "url": "https://github.com/sentzunhat/zacatl.git"
@@ -70,9 +98,14 @@
70
98
  "test": "NODE_ENV=test ENV=test vitest run",
71
99
  "test:watch": "NODE_ENV=test ENV=test vitest",
72
100
  "test:coverage": "npm run test -- --coverage",
101
+ "test:bun": "bun test",
102
+ "test:node": "vitest run",
73
103
  "type:check": "tsc -p ./tsconfig.json && tsc -p test/tsconfig.json",
74
104
  "lint": "DEBUG=eslint:cli-engine bun eslint .",
75
- "publish:latest": "npm i && npm run test && npm run test:coverage && npm run type:check && npm run lint && npm run build && npm publish --access public --tag latest"
105
+ "prepublish": "npm run test:coverage && npm run type:check && npm run lint && npm run build",
106
+ "publish:latest": "npm run prepublish && npm publish --access public --tag latest",
107
+ "publish:otp": "npm run prepublish && npm publish --access public --tag latest --otp",
108
+ "publish:dry": "npm run prepublish && npm publish --dry-run"
76
109
  },
77
110
  "devDependencies": {
78
111
  "@eslint/eslintrc": "^3.3.3",
@@ -102,6 +135,21 @@
102
135
  "README.md",
103
136
  "LICENSE"
104
137
  ],
138
+ "peerDependencies": {
139
+ "mongoose": "^9.0.0",
140
+ "sequelize": "^6.0.0"
141
+ },
142
+ "peerDependenciesMeta": {
143
+ "mongoose": {
144
+ "optional": true
145
+ },
146
+ "sequelize": {
147
+ "optional": true
148
+ },
149
+ "better-sqlite3": {
150
+ "optional": true
151
+ }
152
+ },
105
153
  "dependencies": {
106
154
  "@fastify/http-proxy": "^11.4.1",
107
155
  "@fastify/static": "^8.3.0",
@@ -124,11 +172,6 @@
124
172
  "uuid": "^13.0.0",
125
173
  "zod": "^4.3.6"
126
174
  },
127
- "peerDependenciesMeta": {
128
- "better-sqlite3": {
129
- "optional": true
130
- }
131
- },
132
175
  "optionalDependencies": {
133
176
  "@types/better-sqlite3": "^7.6.13",
134
177
  "better-sqlite3": "^12.6.2"
package/src/index.ts CHANGED
@@ -30,5 +30,8 @@ export type { DependencyContainer } from "tsyringe";
30
30
  export { z } from "zod";
31
31
  export type { ZodSchema, ZodType, ZodError } from "zod";
32
32
 
33
+ // Re-export ORMs (included as dependencies)
34
+ export * from "./orm-exports";
35
+
33
36
  // Note: TypeScript utility types (Partial, Required, Readonly, etc.)
34
37
  // are globally available and don't need re-export
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Re-export ORM dependencies for convenience
3
+ * These are included as dependencies (currently) for backward compatibility
4
+ * Future versions may move them to pure peer dependencies
5
+ */
6
+
7
+ // Mongoose exports - full re-export
8
+ export {
9
+ default as mongoose,
10
+ Mongoose,
11
+ Schema,
12
+ Model,
13
+ Document,
14
+ connect,
15
+ connection,
16
+ } from "mongoose";
17
+
18
+ // Sequelize exports - full re-export
19
+ export { Sequelize, Model as SequelizeModel, DataTypes, Op } from "sequelize";
20
+
21
+ // Type-only exports for convenience
22
+ export type { Model as MongooseModel } from "mongoose";
23
+ export type { ModelStatic, Options as SequelizeOptions } from "sequelize";
@@ -0,0 +1,52 @@
1
+ import type { Model } from "sequelize";
2
+ import type {
3
+ MongooseRepositoryConfig,
4
+ SequelizeRepositoryConfig,
5
+ ORMAdapter,
6
+ } from "../repositories/types";
7
+
8
+ /**
9
+ * Loads MongooseAdapter dynamically - only when needed
10
+ * Throws helpful error if mongoose is not installed
11
+ */
12
+ export function loadMongooseAdapter<D, I, O>(
13
+ config: MongooseRepositoryConfig<D>,
14
+ ): ORMAdapter<D, I, O> {
15
+ try {
16
+ // Dynamic import - only loads when Mongoose is actually used
17
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
18
+ const adapters =
19
+ require("./adapters/mongoose-adapter") as typeof import("./adapters/mongoose-adapter");
20
+ return new adapters.MongooseAdapter<D, I, O>(config);
21
+ } catch (error: any) {
22
+ if (error.code === "MODULE_NOT_FOUND") {
23
+ throw new Error(
24
+ "Mongoose is not installed. Install it with: npm install mongoose",
25
+ );
26
+ }
27
+ throw error;
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Loads SequelizeAdapter dynamically - only when needed
33
+ * Throws helpful error if sequelize is not installed
34
+ */
35
+ export function loadSequelizeAdapter<D extends Model, I, O>(
36
+ config: SequelizeRepositoryConfig<D>,
37
+ ): ORMAdapter<D, I, O> {
38
+ try {
39
+ // Dynamic import - only loads when Sequelize is actually used
40
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
41
+ const adapters =
42
+ require("./adapters/sequelize-adapter") as typeof import("./adapters/sequelize-adapter");
43
+ return new adapters.SequelizeAdapter<D, I, O>(config);
44
+ } catch (error: any) {
45
+ if (error.code === "MODULE_NOT_FOUND") {
46
+ throw new Error(
47
+ "Sequelize is not installed. Install it with: npm install sequelize",
48
+ );
49
+ }
50
+ throw error;
51
+ }
52
+ }
@@ -1,8 +1,5 @@
1
- import importedMongoose, {
2
- connection,
3
- Model as MongooseModel,
4
- Mongoose,
5
- } from "mongoose";
1
+ import type { Model as MongooseModel } from "mongoose";
2
+ import { Mongoose } from "mongoose";
6
3
  import { v4 as uuidv4 } from "uuid";
7
4
  import { container } from "tsyringe";
8
5
  import type {
@@ -14,9 +11,11 @@ import type {
14
11
  /**
15
12
  * MongooseAdapter - Handles Mongoose-specific ORM operations
16
13
  *
17
- * This adapter wraps Mongoose model operations and provides a consistent
18
- * interface for the repository layer. It handles document transformation,
19
- * ID normalization, and timestamp management.
14
+ * Provides consistent interface for repository layer with:
15
+ * - Document transformation
16
+ * - ID normalization
17
+ * - Timestamp management
18
+ * - Connection instance from DI container
20
19
  */
21
20
  export class MongooseAdapter<D, I, O> implements ORMAdapter<D, I, O> {
22
21
  public readonly model: MongooseModel<D>;
@@ -24,9 +23,9 @@ export class MongooseAdapter<D, I, O> implements ORMAdapter<D, I, O> {
24
23
 
25
24
  constructor(config: MongooseRepositoryConfig<D>) {
26
25
  this.config = config;
27
- const mongoose = connection.db?.databaseName
28
- ? importedMongoose
29
- : container.resolve<Mongoose>(Mongoose);
26
+ // Get mongoose instance from DI container - allows per-database configuration
27
+ // Connection strings should be set up before repository instantiation
28
+ const mongoose = container.resolve<Mongoose>(Mongoose);
30
29
 
31
30
  const { name, schema } = this.config;
32
31
 
@@ -1,5 +1,5 @@
1
- import { Model as MongooseModel } from "mongoose";
2
- import { Model, ModelStatic } from "sequelize";
1
+ import type { Model as MongooseModel } from "mongoose";
2
+ import type { Model, ModelStatic } from "sequelize";
3
3
  import {
4
4
  BaseRepositoryConfig,
5
5
  Repository,
@@ -8,8 +8,10 @@ import {
8
8
  ORMAdapter,
9
9
  ORMType,
10
10
  } from "./types";
11
- import { MongooseAdapter } from "../orm/adapters/mongoose-adapter";
12
- import { SequelizeAdapter } from "../orm/adapters/sequelize-adapter";
11
+ import {
12
+ loadMongooseAdapter,
13
+ loadSequelizeAdapter,
14
+ } from "../orm/adapter-loader";
13
15
 
14
16
  export * from "./types";
15
17
 
@@ -34,22 +36,27 @@ const isSequelizeConfig = <D extends Model>(
34
36
  /**
35
37
  * BaseRepository - Abstract base class for all repositories
36
38
  *
37
- * Uses the adapter pattern to support multiple ORMs (Mongoose, Sequelize, etc.)
38
- * without circular dependencies. Adapters are imported from separate files in
39
- * the orm/ folder.
39
+ * Supports multiple ORMs (Mongoose, Sequelize) through adapter pattern.
40
+ * Adapters are lazy-loaded - only the ORM you use gets imported.
41
+ * This allows projects to install only one ORM without unused dependencies.
40
42
  */
41
43
  export abstract class BaseRepository<D, I, O> implements Repository<D, I, O> {
42
44
  private adapter: ORMAdapter<D, I, O>;
45
+ private readonly ormType: ORMType;
43
46
 
44
47
  constructor(config: BaseRepositoryConfig<D>) {
48
+ this.ormType = config.type;
49
+
45
50
  if (isMongooseConfig<D>(config)) {
46
- // TypeScript knows config is MongooseRepositoryConfig<D>
47
- this.adapter = new MongooseAdapter<D, I, O>(config);
51
+ this.adapter = loadMongooseAdapter<D, I, O>(config);
48
52
  } else if (isSequelizeConfig(config)) {
49
- // TypeScript knows config is SequelizeRepositoryConfig
50
- this.adapter = new SequelizeAdapter<Model, I, O>(config);
53
+ // Type assertion needed here because D could be either Mongoose or Sequelize model
54
+ this.adapter = loadSequelizeAdapter<Model, I, O>(config) as ORMAdapter<
55
+ D,
56
+ I,
57
+ O
58
+ >;
51
59
  } else {
52
- // Exhaustiveness check - should never reach here with proper types
53
60
  const exhaustive: never = config;
54
61
  throw new Error(
55
62
  `Invalid repository configuration. Received: ${JSON.stringify(exhaustive)}`,
@@ -62,11 +69,11 @@ export abstract class BaseRepository<D, I, O> implements Repository<D, I, O> {
62
69
  }
63
70
 
64
71
  public isMongoose(): boolean {
65
- return this.adapter instanceof MongooseAdapter;
72
+ return this.ormType === ORMType.Mongoose;
66
73
  }
67
74
 
68
75
  public isSequelize(): boolean {
69
- return this.adapter instanceof SequelizeAdapter;
76
+ return this.ormType === ORMType.Sequelize;
70
77
  }
71
78
 
72
79
  public getMongooseModel(): MongooseModel<D> {