@ooneex/cli 1.15.2 → 1.16.0

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.js CHANGED
@@ -7295,7 +7295,8 @@ class MakeAppCommand {
7295
7295
  });
7296
7296
  const appModulePackagePath = join7(destination, "modules", "app", "package.json");
7297
7297
  const appModulePackageJson = await Bun.file(appModulePackagePath).json();
7298
- appModulePackageJson.scripts.dev = "bun --hot run ./src/index.ts";
7298
+ appModulePackageJson.scripts.dev = "docker compose up -d && bun --hot run ./src/index.ts";
7299
+ appModulePackageJson.scripts["docker:stop"] = "docker compose down";
7299
7300
  appModulePackageJson.scripts.build = "bun build ./src/index.ts --outdir ./dist --target bun";
7300
7301
  await Bun.write(appModulePackagePath, JSON.stringify(appModulePackageJson, null, 2));
7301
7302
  const envContent = env_default.replace(/^DATABASE_URL=/m, 'DATABASE_URL="postgresql://ooneex:ooneex@localhost:5432/ooneex"').replace(/^CACHE_REDIS_URL=/m, 'CACHE_REDIS_URL="redis://localhost:6379"').replace(/^PUBSUB_REDIS_URL=/m, 'PUBSUB_REDIS_URL="redis://localhost:6379"').replace(/^RATE_LIMIT_REDIS_URL=/m, 'RATE_LIMIT_REDIS_URL="redis://localhost:6379"').replace(/^DATABASE_REDIS_URL=/m, 'DATABASE_REDIS_URL="redis://localhost:6379"');
@@ -7728,7 +7729,7 @@ var make_cron_md_default = "---\nname: make:cron\ndescription: Generate a new cr
7728
7729
  var make_database_md_default = "---\nname: make:database\ndescription: Generate a new database class with its test file, then complete the generated code. Use when creating a new database adapter that extends TypeormDatabase from @ooneex/database.\n---\n\n# Make Database Class\n\nGenerate a new database class and its test file using the `make:database` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the database class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:database --name=<name> --module=<module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/databases/<Name>Database.ts` - The database class file (or `modules/<module>/src/databases/<Name>Database.ts` with `--module`)\n- `tests/databases/<Name>Database.spec.ts` - The test file (or `modules/<module>/tests/databases/<Name>Database.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the database class\n\nEdit `src/databases/<Name>Database.ts` to complete the implementation:\n\n- Add entity imports and register them in the `entities` array\n- Adjust the database path if needed (default is `\"var/db\"`)\n- Configure DataSource options as appropriate (type, synchronize, etc.)\n- Inject any required dependencies via the constructor\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { DataSource } from \"typeorm\";\nimport { TypeormDatabase, DatabaseException, decorator } from \"@ooneex/database\";\n\n@decorator.database()\nexport class <Name>Database extends TypeormDatabase {\n public getSource(database?: string): DataSource {\n database = database || \"var/db\";\n\n this.source = new DataSource({\n synchronize: false,\n entities: [\n // TODO: Load your entities here\n ],\n enableWAL: true,\n busyErrorRetry: 2000,\n busyTimeout: 30_000,\n database,\n type: \"sqlite\",\n });\n\n return this.source;\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/databases/<Name>Database.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, getSource method)\n- Add tests relevant to the specific database class behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Database } from \"@/databases/<Name>Database\";\n\ndescribe(\"<Name>Database\", () => {\n test(\"should have class name ending with 'Database'\", () => {\n expect(<Name>Database.name.endsWith(\"Database\")).toBe(true);\n });\n\n test(\"should have 'getSource' method\", () => {\n expect(<Name>Database.prototype.getSource).toBeDefined();\n expect(typeof <Name>Database.prototype.getSource).toBe(\"function\");\n });\n});\n```\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/databases/<Name>Database.ts tests/databases/<Name>Database.spec.ts\n```\n";
7729
7730
 
7730
7731
  // src/templates/claude/skills/make.entity.md.txt
7731
- var make_entity_md_default = "---\nname: make:entity\ndescription: Generate a new TypeORM entity class with its test file, then complete the generated code. Use when creating a new database entity with columns, relations, and table mapping.\n---\n\n# Make Entity Class\n\nGenerate a new entity class and its test file using the `make:entity` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the entity class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:entity --name=<name> --module=<module> --table-name=<table_name>\n```\n\nWhere `<name>` is the name provided by the user. The `--table-name` option is optional \u2014 if omitted, it defaults to the snake_case pluralized form of the name (e.g., `UserProfile` becomes `user_profiles`). The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/entities/<Name>Entity.ts` - The entity class file (or `modules/<module>/src/entities/<Name>Entity.ts` with `--module`)\n- `tests/entities/<Name>Entity.spec.ts` - The test file (or `modules/<module>/tests/entities/<Name>Entity.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the entity class\n\nEdit `src/entities/<Name>Entity.ts` to complete the implementation:\n\n- Add entity-specific columns with appropriate TypeORM decorators (`@Column`)\n- Add relations if needed (`@ManyToOne`, `@OneToMany`, `@ManyToMany`, etc.)\n- Remove any scaffolded columns that are not relevant to the entity\n- Adjust column types, lengths, and constraints as needed\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport type { LocaleType } from \"@ooneex/translation\";\nimport { random } from \"@ooneex/utils\";\nimport { Column, CreateDateColumn, DeleteDateColumn, PrimaryColumn, UpdateDateColumn } from \"typeorm\";\n\n@Entity({\n name: \"<table_name>\",\n})\nexport class <Name>Entity extends BaseEntity {\n @PrimaryColumn({ name: \"id\", type: \"varchar\", length: 25 })\n id: string = random.nanoid(25);\n\n @Column({\n name: \"is_locked\",\n type: \"boolean\",\n default: false,\n nullable: true,\n })\n isLocked?: boolean;\n\n @Column({ name: \"locked_at\", type: \"timestamptz\", nullable: true })\n lockedAt?: Date;\n\n @Column({\n name: \"is_blocked\",\n type: \"boolean\",\n default: false,\n nullable: true,\n })\n isBlocked?: boolean;\n\n @Column({ name: \"blocked_at\", type: \"timestamptz\", nullable: true })\n blockedAt?: Date;\n\n @Column({ name: \"block_reason\", type: \"text\", nullable: true })\n blockReason?: string;\n\n @Column({ name: \"is_public\", type: \"boolean\", default: true, nullable: true })\n isPublic?: boolean;\n\n @Column({ name: \"lang\", type: \"varchar\", length: 10, nullable: true })\n lang?: LocaleType;\n\n @CreateDateColumn({ name: \"created_at\" })\n createdAt?: Date;\n\n @UpdateDateColumn({ name: \"updated_at\" })\n updatedAt?: Date;\n\n @DeleteDateColumn({ name: \"deleted_at\" })\n deletedAt?: Date;\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/entities/<Name>Entity.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, id, default columns)\n- Add tests for any new entity-specific columns and relations\n- Update tests if scaffolded columns were removed\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Entity } from \"@/entities/<Name>Entity\";\n\ndescribe(\"<Name>Entity\", () => {\n test(\"should have class name ending with 'Entity'\", () => {\n expect(<Name>Entity.name.endsWith(\"Entity\")).toBe(true);\n });\n\n test(\"should have 'id' property with default nanoid\", () => {\n const entity = new <Name>Entity();\n expect(entity.id).toBeDefined();\n expect(typeof entity.id).toBe(\"string\");\n expect(entity.id.length).toBe(25);\n });\n\n test(\"should have 'isLocked' property\", () => {\n const entity = new <Name>Entity();\n expect(\"isLocked\" in entity).toBe(true);\n });\n\n // ... additional property tests\n});\n```\n\n### 5. Register the entity in the module\n\nAdd the new entity to the module's `entities` array in `src/<PascalModuleName>Module.ts` (e.g., `src/BookModule.ts` for the `book` module):\n\n```typescript\nimport type { ModuleType } from \"@ooneex/module\";\nimport { <Name>Entity } from \"./entities/<Name>Entity\";\n\nexport const <PascalModuleName>Module: ModuleType = {\n controllers: [],\n entities: [<Name>Entity],\n middlewares: [],\n cronJobs: [],\n events: [],\n};\n```\n\nThe module file uses PascalCase naming: `<PascalModuleName>Module.ts` with export `<PascalModuleName>Module`.\n\nIf the module already has other entities registered, append the new entity to the existing `entities` array and add the import alongside existing imports.\n\n### 6. Create a migration for the entity\n\nAfter creating or updating an entity, generate a migration to apply the corresponding schema changes to the database.\n\nRun the generator:\n\n```bash\nbunx @ooneex/cli@latest make:migration\n```\n\nThen read the generated migration file in `src/migrations/` and complete it:\n\n- In the `up` method, write the SQL to create the table (or alter it if updating an existing entity). Include all columns, types, constraints, defaults, and indexes matching the entity definition.\n- In the `down` method, write the reverse SQL to undo the changes (e.g., `DROP TABLE` or `ALTER TABLE DROP COLUMN`).\n- If the migration depends on another migration (e.g., a foreign key referencing another table), add that migration class to the `getDependencies()` return array.\n\nExample `up` method for a new entity:\n\n```typescript\npublic async up(tx: TransactionSQL): Promise<void> {\n await tx`\n CREATE TABLE IF NOT EXISTS <table_name> (\n id VARCHAR(25) PRIMARY KEY,\n is_locked BOOLEAN DEFAULT false,\n locked_at TIMESTAMPTZ,\n is_blocked BOOLEAN DEFAULT false,\n blocked_at TIMESTAMPTZ,\n block_reason TEXT,\n is_public BOOLEAN DEFAULT true,\n lang VARCHAR(10),\n created_at TIMESTAMPTZ DEFAULT NOW(),\n updated_at TIMESTAMPTZ DEFAULT NOW(),\n deleted_at TIMESTAMPTZ\n )\n `;\n}\n```\n\n### 7. Create a repository for the entity\n\nAfter creating the entity, generate a repository to handle database operations for it.\n\nRun the generator:\n\n```bash\nbunx @ooneex/cli@latest make:repository --name=<name>\n```\n\nWhere `<name>` is the same name used for the entity. The command will generate:\n- `src/repositories/<Name>Repository.ts` - The repository class\n- `tests/repositories/<Name>Repository.spec.ts` - The test file\n\nThen read the generated files and complete the repository implementation:\n\n- Adjust search fields in the `find()` method to match the entity's searchable columns\n- Customize relations loading in `findOne`/`findOneBy` if the entity has relations\n- Add any domain-specific methods relevant to the entity\n- Remove methods that don't apply to the entity\n- Update tests to match the final repository methods\n\n### 8. Lint and format\n\nRun linting and formatting on all generated files:\n\n```bash\nbunx biome check --fix src/entities/<Name>Entity.ts tests/entities/<Name>Entity.spec.ts src/repositories/<Name>Repository.ts tests/repositories/<Name>Repository.spec.ts src/migrations/\n```\n";
7732
+ var make_entity_md_default = "---\nname: make:entity\ndescription: Generate a new TypeORM entity class with its test file, then complete the generated code. Use when creating a new database entity with columns, relations, and table mapping.\n---\n\n# Make Entity Class\n\nGenerate a new entity class and its test file using the `make:entity` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n- Avoid non-null assertions (`!`). For example, `public name!: string;` should be `public name: string;`\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the entity class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:entity --name=<name> --module=<module> --table-name=<table_name>\n```\n\nWhere `<name>` is the name provided by the user. The `--table-name` option is optional \u2014 if omitted, it defaults to the snake_case pluralized form of the name (e.g., `UserProfile` becomes `user_profiles`). The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/entities/<Name>Entity.ts` - The entity class file (or `modules/<module>/src/entities/<Name>Entity.ts` with `--module`)\n- `tests/entities/<Name>Entity.spec.ts` - The test file (or `modules/<module>/tests/entities/<Name>Entity.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the entity class\n\nEdit `src/entities/<Name>Entity.ts` to complete the implementation:\n\n- Add entity-specific columns with appropriate TypeORM decorators (`@Column`)\n- Add relations if needed (`@ManyToOne`, `@OneToMany`, `@ManyToMany`, etc.)\n- Remove any scaffolded columns that are not relevant to the entity\n- Adjust column types, lengths, and constraints as needed\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport type { LocaleType } from \"@ooneex/translation\";\nimport { random } from \"@ooneex/utils\";\nimport { Column, CreateDateColumn, DeleteDateColumn, PrimaryColumn, UpdateDateColumn } from \"typeorm\";\n\n@Entity({\n name: \"<table_name>\",\n})\nexport class <Name>Entity extends BaseEntity {\n @PrimaryColumn({ name: \"id\", type: \"varchar\", length: 25 })\n id: string = random.nanoid(25);\n\n @Column({\n name: \"is_locked\",\n type: \"boolean\",\n default: false,\n nullable: true,\n })\n isLocked?: boolean;\n\n @Column({ name: \"locked_at\", type: \"timestamptz\", nullable: true })\n lockedAt?: Date;\n\n @Column({\n name: \"is_blocked\",\n type: \"boolean\",\n default: false,\n nullable: true,\n })\n isBlocked?: boolean;\n\n @Column({ name: \"blocked_at\", type: \"timestamptz\", nullable: true })\n blockedAt?: Date;\n\n @Column({ name: \"block_reason\", type: \"text\", nullable: true })\n blockReason?: string;\n\n @Column({ name: \"is_public\", type: \"boolean\", default: true, nullable: true })\n isPublic?: boolean;\n\n @Column({ name: \"lang\", type: \"varchar\", length: 10, nullable: true })\n lang?: LocaleType;\n\n @CreateDateColumn({ name: \"created_at\" })\n createdAt?: Date;\n\n @UpdateDateColumn({ name: \"updated_at\" })\n updatedAt?: Date;\n\n @DeleteDateColumn({ name: \"deleted_at\" })\n deletedAt?: Date;\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/entities/<Name>Entity.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, id, default columns)\n- Add tests for any new entity-specific columns and relations\n- Update tests if scaffolded columns were removed\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Entity } from \"@/entities/<Name>Entity\";\n\ndescribe(\"<Name>Entity\", () => {\n test(\"should have class name ending with 'Entity'\", () => {\n expect(<Name>Entity.name.endsWith(\"Entity\")).toBe(true);\n });\n\n test(\"should have 'id' property with default nanoid\", () => {\n const entity = new <Name>Entity();\n expect(entity.id).toBeDefined();\n expect(typeof entity.id).toBe(\"string\");\n expect(entity.id.length).toBe(25);\n });\n\n test(\"should have 'isLocked' property\", () => {\n const entity = new <Name>Entity();\n expect(\"isLocked\" in entity).toBe(true);\n });\n\n // ... additional property tests\n});\n```\n\n### 5. Register the entity in the module\n\nAdd the new entity to the module's `entities` array in `src/<PascalModuleName>Module.ts` (e.g., `src/BookModule.ts` for the `book` module):\n\n```typescript\nimport type { ModuleType } from \"@ooneex/module\";\nimport { <Name>Entity } from \"./entities/<Name>Entity\";\n\nexport const <PascalModuleName>Module: ModuleType = {\n controllers: [],\n entities: [<Name>Entity],\n middlewares: [],\n cronJobs: [],\n events: [],\n};\n```\n\nThe module file uses PascalCase naming: `<PascalModuleName>Module.ts` with export `<PascalModuleName>Module`.\n\nIf the module already has other entities registered, append the new entity to the existing `entities` array and add the import alongside existing imports.\n\n### 6. Create a migration for the entity\n\nAfter creating or updating an entity, generate a migration to apply the corresponding schema changes to the database.\n\nRun the generator:\n\n```bash\nbunx @ooneex/cli@latest make:migration\n```\n\nThen read the generated migration file in `src/migrations/` and complete it:\n\n- In the `up` method, write the SQL to create the table (or alter it if updating an existing entity). Include all columns, types, constraints, defaults, and indexes matching the entity definition.\n- In the `down` method, write the reverse SQL to undo the changes (e.g., `DROP TABLE` or `ALTER TABLE DROP COLUMN`).\n- If the migration depends on another migration (e.g., a foreign key referencing another table), add that migration class to the `getDependencies()` return array.\n\nExample `up` method for a new entity:\n\n```typescript\npublic async up(tx: TransactionSQL): Promise<void> {\n await tx`\n CREATE TABLE IF NOT EXISTS <table_name> (\n id VARCHAR(25) PRIMARY KEY,\n is_locked BOOLEAN DEFAULT false,\n locked_at TIMESTAMPTZ,\n is_blocked BOOLEAN DEFAULT false,\n blocked_at TIMESTAMPTZ,\n block_reason TEXT,\n is_public BOOLEAN DEFAULT true,\n lang VARCHAR(10),\n created_at TIMESTAMPTZ DEFAULT NOW(),\n updated_at TIMESTAMPTZ DEFAULT NOW(),\n deleted_at TIMESTAMPTZ\n )\n `;\n}\n```\n\n### 7. Create a repository for the entity\n\nAfter creating the entity, generate a repository to handle database operations for it.\n\nRun the generator:\n\n```bash\nbunx @ooneex/cli@latest make:repository --name=<name>\n```\n\nWhere `<name>` is the same name used for the entity. The command will generate:\n- `src/repositories/<Name>Repository.ts` - The repository class\n- `tests/repositories/<Name>Repository.spec.ts` - The test file\n\nThen read the generated files and complete the repository implementation:\n\n- Adjust search fields in the `find()` method to match the entity's searchable columns\n- Customize relations loading in `findOne`/`findOneBy` if the entity has relations\n- Add any domain-specific methods relevant to the entity\n- Remove methods that don't apply to the entity\n- Update tests to match the final repository methods\n\n### 8. Lint and format\n\nRun linting and formatting on all generated files:\n\n```bash\nbunx biome check --fix src/entities/<Name>Entity.ts tests/entities/<Name>Entity.spec.ts src/repositories/<Name>Repository.ts tests/repositories/<Name>Repository.spec.ts src/migrations/\n```\n";
7732
7733
 
7733
7734
  // src/templates/claude/skills/make.logger.md.txt
7734
7735
  var make_logger_md_default = "---\nname: make:logger\ndescription: Generate a new logger class with its test file, then complete the generated code. Use when creating a new logger that implements the ILogger interface from @ooneex/logger.\n---\n\n# Make Logger Class\n\nGenerate a new logger class and its test file using the `make:logger` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the logger class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:logger --name=<name> --module=<module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/loggers/<Name>Logger.ts` - The logger class file (or `modules/<module>/src/loggers/<Name>Logger.ts` with `--module`)\n- `tests/loggers/<Name>Logger.spec.ts` - The test file (or `modules/<module>/tests/loggers/<Name>Logger.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the logger class\n\nEdit `src/loggers/<Name>Logger.ts` to complete the implementation:\n\n- Implement the `init()` method to set up the logger (e.g., open file handles, configure transports)\n- Implement `log`, `debug`, `info`, `success`, `warn`, and `error` methods with actual logging logic\n- Inject any required dependencies via the constructor\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport type { IException } from \"@ooneex/exception\";\nimport { type ILogger, decorator } from \"@ooneex/logger\";\nimport type { ScalarType } from \"@ooneex/types\";\n\n@decorator.logger()\nexport class <Name>Logger implements ILogger {\n public async init(): Promise<void> {\n // Initialize your logger here\n }\n\n public log(message: string, data?: Record<string, ScalarType>): void {\n // Handle general logging\n }\n\n public debug(message: string, data?: Record<string, ScalarType>): void {\n // Handle debug logging\n }\n\n public info(message: string, data?: Record<string, ScalarType>): void {\n // Handle info logging\n }\n\n public success(message: string, data?: Record<string, ScalarType>): void {\n // Handle success logging\n }\n\n public warn(message: string, data?: Record<string, ScalarType>): void {\n // Handle warning logging\n }\n\n public error(message: string | IException, data?: Record<string, ScalarType>): void {\n // Handle error logging\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/loggers/<Name>Logger.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, init, log, debug, info, success, warn, error methods)\n- Add tests relevant to the specific logger class behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Logger } from \"@/loggers/<Name>Logger\";\n\ndescribe(\"<Name>Logger\", () => {\n test(\"should have class name ending with 'Logger'\", () => {\n expect(<Name>Logger.name.endsWith(\"Logger\")).toBe(true);\n });\n\n test(\"should have 'init' method\", () => {\n expect(<Name>Logger.prototype.init).toBeDefined();\n expect(typeof <Name>Logger.prototype.init).toBe(\"function\");\n });\n\n test(\"should have 'log' method\", () => {\n expect(<Name>Logger.prototype.log).toBeDefined();\n expect(typeof <Name>Logger.prototype.log).toBe(\"function\");\n });\n\n test(\"should have 'debug' method\", () => {\n expect(<Name>Logger.prototype.debug).toBeDefined();\n expect(typeof <Name>Logger.prototype.debug).toBe(\"function\");\n });\n\n test(\"should have 'info' method\", () => {\n expect(<Name>Logger.prototype.info).toBeDefined();\n expect(typeof <Name>Logger.prototype.info).toBe(\"function\");\n });\n\n test(\"should have 'success' method\", () => {\n expect(<Name>Logger.prototype.success).toBeDefined();\n expect(typeof <Name>Logger.prototype.success).toBe(\"function\");\n });\n\n test(\"should have 'warn' method\", () => {\n expect(<Name>Logger.prototype.warn).toBeDefined();\n expect(typeof <Name>Logger.prototype.warn).toBe(\"function\");\n });\n\n test(\"should have 'error' method\", () => {\n expect(<Name>Logger.prototype.error).toBeDefined();\n expect(typeof <Name>Logger.prototype.error).toBe(\"function\");\n });\n});\n```\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/loggers/<Name>Logger.ts tests/loggers/<Name>Logger.spec.ts\n```\n";
@@ -7752,7 +7753,7 @@ var make_pubsub_md_default = "---\nname: make:pubsub\ndescription: Generate a ne
7752
7753
  var make_repository_md_default = "---\nname: make:repository\ndescription: Generate a new repository class with its test file, then complete the generated code. Use when creating a new TypeORM repository for database operations on an entity.\n---\n\n# Make Repository Class\n\nGenerate a new repository class and its test file using the `make:repository` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the repository class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:repository --name=<name> --module=<module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/repositories/<Name>Repository.ts` - The repository class file (or `modules/<module>/src/repositories/<Name>Repository.ts` with `--module`)\n- `tests/repositories/<Name>Repository.spec.ts` - The test file (or `modules/<module>/tests/repositories/<Name>Repository.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the repository class\n\nEdit `src/repositories/<Name>Repository.ts` to complete the implementation:\n\n- Verify the entity import path matches the actual entity location\n- Adjust the `find` method's search fields (default searches `name` with `ILike`)\n- Customize relations loading in `findOne`/`findOneBy` if needed\n\n#### Adding methods\n\nLook at the entity's fields, relations, and business context to determine if custom domain-specific methods are needed. For example:\n- A `SessionRepository` might need `revokeSession(sessionId: string)` and `revokeAllUserSessions(userId: string)`\n- A `NotificationRepository` might need `markAsRead(id: string)` and `markAllAsRead(userId: string)`\n- Entities with status fields may need methods like `archive(id: string)` or `activate(id: string)`\n\nRead related entities, services, or actions in the module to understand what operations the repository should support, then add the appropriate methods.\n\n#### Removing methods\n\nRemove scaffolded methods that don't make sense for the entity's context:\n- Remove `createMany`/`updateMany` if the entity is always managed individually (e.g., user profiles, settings)\n- Remove `delete` if the entity uses soft deletes only (use a custom `softDelete` or `archive` method instead)\n- Remove `find` if the entity is only ever accessed by ID or specific criteria (e.g., singleton config entities)\n- Remove `count` if there's no use case for counting records of this entity\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { inject } from \"@ooneex/container\";\nimport type { ITypeormDatabase } from \"@ooneex/database\";\nimport { decorator } from \"@ooneex/repository\";\nimport type { FilterResultType } from \"@ooneex/types\";\nimport type { FindManyOptions, FindOptionsWhere, Repository, SaveOptions, UpdateResult } from \"typeorm\";\nimport { ILike } from \"typeorm\";\nimport { <Name>Entity } from \"../entities/<Name>Entity\";\n\n@decorator.repository()\nexport class <Name>Repository {\n constructor(\n @inject(\"database\")\n private readonly database: ITypeormDatabase,\n ) {}\n\n public async open(): Promise<Repository<<Name>Entity>> {\n return await this.database.open(<Name>Entity);\n }\n\n public async close(): Promise<void> {\n await this.database.close();\n }\n\n public async find(\n criteria: FindManyOptions<<Name>Entity> & { page?: number; limit?: number; q?: string },\n ): Promise<FilterResultType<<Name>Entity>> {\n // ... pagination and search logic\n }\n\n public async findOne(id: string): Promise<<Name>Entity | null> { ... }\n public async findOneBy(criteria: FindOptionsWhere<<Name>Entity>): Promise<<Name>Entity | null> { ... }\n public async create(entity: <Name>Entity, options?: SaveOptions): Promise<<Name>Entity> { ... }\n public async createMany(entities: <Name>Entity[], options?: SaveOptions): Promise<<Name>Entity[]> { ... }\n public async update(entity: <Name>Entity, options?: SaveOptions): Promise<<Name>Entity> { ... }\n public async updateMany(entities: <Name>Entity[], options?: SaveOptions): Promise<<Name>Entity[]> { ... }\n public async delete(criteria: FindOptionsWhere<<Name>Entity> | FindOptionsWhere<<Name>Entity>[]): Promise<UpdateResult> { ... }\n public async count(criteria?: FindOptionsWhere<<Name>Entity> | FindOptionsWhere<<Name>Entity>[]): Promise<number> { ... }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/repositories/<Name>Repository.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep scaffolded tests for methods that remain in the repository (remove tests for methods that were removed)\n- Add tests for any custom domain-specific methods added to the repository\n- Add tests relevant to the specific repository behavior\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/repositories/<Name>Repository.ts tests/repositories/<Name>Repository.spec.ts\n```\n";
7753
7754
 
7754
7755
  // src/templates/claude/skills/make.seed.md.txt
7755
- var make_seed_md_default = "---\nname: make:seed\ndescription: Generate a new database seed file with its test file, then complete the generated code. Use when creating seed data for populating the database using @ooneex/seeds.\n---\n\n# Make Seed\n\nGenerate a new seed file and its test file using the `make:seed` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the seed file and test files:\n\n```bash\nbunx @ooneex/cli@latest make:seed --name=<name> --module=<module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/seeds/<Name>Seed.ts` - The seed class file (or `modules/<module>/src/seeds/<Name>Seed.ts` with `--module`)\n- `tests/seeds/<Name>Seed.spec.ts` - The test file (or `modules/<module>/tests/seeds/<Name>Seed.spec.ts` with `--module`)\n\nIt will also:\n- Generate a `seeds.ts` root export file in the seeds directory\n- Add a `seed:run` script to `package.json` if not already present\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the seed\n\nEdit `src/seeds/<Name>Seed.ts` to implement:\n\n- Import the relevant entity classes\n- Create seed data with hardcoded nanoid values for `id` fields (generate via `bun -e \"import { random } from '@ooneex/utils'; console.log(random.nanoid())\"`)\n- Do NOT use sequential IDs like `\"item-1\"`, `\"item-2\"`\n- Ensure the same entity uses the same ID everywhere it appears\n\n### 4. Complete the test file\n\nEdit `tests/seeds/<Name>Seed.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, run, isActive, getDependencies methods)\n- Add tests relevant to the specific seed behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Seed } from \"@/seeds/<Name>Seed\";\n\ndescribe(\"<Name>Seed\", () => {\n test(\"should have class name ending with 'Seed'\", () => {\n expect(<Name>Seed.name.endsWith(\"Seed\")).toBe(true);\n });\n\n test(\"should have 'run' method\", () => {\n expect(<Name>Seed.prototype.run).toBeDefined();\n expect(typeof <Name>Seed.prototype.run).toBe(\"function\");\n });\n\n test(\"should have 'isActive' method\", () => {\n expect(<Name>Seed.prototype.isActive).toBeDefined();\n expect(typeof <Name>Seed.prototype.isActive).toBe(\"function\");\n });\n\n test(\"should have 'getDependencies' method\", () => {\n expect(<Name>Seed.prototype.getDependencies).toBeDefined();\n expect(typeof <Name>Seed.prototype.getDependencies).toBe(\"function\");\n });\n});\n```\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/seeds/<Name>Seed.ts tests/seeds/<Name>Seed.spec.ts\n```\n";
7756
+ var make_seed_md_default = "---\nname: make:seed\ndescription: Generate a new database seed file with its test file, then complete the generated code. Use when creating seed data for populating the database using @ooneex/seeds.\n---\n\n# Make Seed\n\nGenerate a new seed file and its test file using the `make:seed` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the seed file and test files:\n\n```bash\nbunx @ooneex/cli@latest make:seed --name=<name> --module=<module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/seeds/<Name>Seed.ts` - The seed class file (or `modules/<module>/src/seeds/<Name>Seed.ts` with `--module`)\n- `src/seeds/<name-seed>.yml` - The seed data file in kebab-case (or `modules/<module>/src/seeds/<name-seed>.yml` with `--module`)\n- `tests/seeds/<Name>Seed.spec.ts` - The test file (or `modules/<module>/tests/seeds/<Name>Seed.spec.ts` with `--module`)\n\nIt will also:\n- Generate a `seeds.ts` root export file in the seeds directory\n- Add a `seed:run` script to `package.json` if not already present\n\n### 2. Read the generated files\n\nRead all generated files to understand the scaffolded code.\n\n### 3. Complete the seed data\n\nEdit `src/seeds/<name-seed>.yml` to add the seed data entries. Each entry should have hardcoded nanoid values for `id` fields (generate via `bun -e \"import { random } from '@ooneex/utils'; console.log(random.nanoid())\"`)\n\n- Do NOT use sequential IDs like `\"item-1\"`, `\"item-2\"`\n- Ensure the same entity uses the same ID everywhere it appears\n\n### 4. Complete the seed class\n\nEdit `src/seeds/<Name>Seed.ts` to implement:\n\n- Import the relevant entity classes and repository\n- Use `resolve()` from `@ooneex/container` to get the repository instance\n- Map the imported YAML data to entity instances\n- Use the repository to persist the entities\n\n### 5. Complete the test file\n\nEdit `tests/seeds/<Name>Seed.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, run, isActive, getDependencies, data yml file)\n- Add tests relevant to the specific seed behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Seed } from \"@/seeds/<Name>Seed\";\n\ndescribe(\"<Name>Seed\", () => {\n test(\"should have class name ending with 'Seed'\", () => {\n expect(<Name>Seed.name.endsWith(\"Seed\")).toBe(true);\n });\n\n test(\"should have 'run' method\", () => {\n expect(<Name>Seed.prototype.run).toBeDefined();\n expect(typeof <Name>Seed.prototype.run).toBe(\"function\");\n });\n\n test(\"should have 'isActive' method\", () => {\n expect(<Name>Seed.prototype.isActive).toBeDefined();\n expect(typeof <Name>Seed.prototype.isActive).toBe(\"function\");\n });\n\n test(\"should have 'getDependencies' method\", () => {\n expect(<Name>Seed.prototype.getDependencies).toBeDefined();\n expect(typeof <Name>Seed.prototype.getDependencies).toBe(\"function\");\n });\n\n test(\"should have a data yml file\", () => {\n const dataFile = join(__dirname, \"..\", \"src\", \"seeds\", \"<name-seed>.yml\");\n expect(existsSync(dataFile)).toBe(true);\n });\n});\n```\n\n### 6. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/seeds/<Name>Seed.ts src/seeds/<name-seed>.yml tests/seeds/<Name>Seed.spec.ts\n```\n";
7756
7757
 
7757
7758
  // src/templates/claude/skills/make.service.md.txt
7758
7759
  var make_service_md_default = "---\nname: make:service\ndescription: Generate a new service class with its test file, then complete the generated code. Use when creating a new business logic service that implements IService from @ooneex/service.\n---\n\n# Make Service Class\n\nGenerate a new service class and its test file using the `make:service` CLI command, then complete the generated code with proper implementation.\n\n## Coding Conventions\n\n- Always explicitly show visibility on class methods and properties (`private`, `public`, `protected`)\n- Always use arrow functions when possible, but NOT for class methods (class methods use regular method syntax)\n- End type names with the `Type` suffix (e.g., `ExceptionStackFrameType`, `ServiceDataType`)\n- Start interface names with the `I` prefix (e.g., `IException`, `IService`, `IAiChat`)\n- For Entity class, if property is optional, add `null` to its type.\n\n## Steps\n\n### 1. Run the generator\n\nRun the following command to scaffold the service class and test files:\n\n```bash\nbunx @ooneex/cli@latest make:service --name=<name> --module=<module>\n```\n\nWhere `<name>` is the name provided by the user. The `--module` option is optional \u2014 if provided, files are generated under `modules/<module>/` instead of the project root. The command will generate:\n- `src/services/<Name>Service.ts` - The service class file (or `modules/<module>/src/services/<Name>Service.ts` with `--module`)\n- `tests/services/<Name>Service.spec.ts` - The test file (or `modules/<module>/tests/services/<Name>Service.spec.ts` with `--module`)\n\n### 2. Read the generated files\n\nRead both generated files to understand the scaffolded code.\n\n### 3. Complete the service class\n\nEdit `src/services/<Name>Service.ts` to complete the implementation:\n\n- Define a proper type for `ServiceDataType` instead of `Record<string, unknown>`\n- Implement the `execute()` method with actual business logic\n- Inject any required dependencies (repositories, other services, etc.) via the constructor\n\nThe generated class structure follows this pattern:\n\n```typescript\nimport { type IService, decorator } from \"@ooneex/service\";\n\ntype ServiceDataType = Record<string, unknown>;\n\n@decorator.service()\nexport class <Name>Service implements IService {\n public async execute(data?: ServiceDataType): Promise<void> {\n // TODO: Implement service logic\n }\n}\n```\n\n### 4. Complete the test file\n\nEdit `tests/services/<Name>Service.spec.ts` to add meaningful tests beyond the scaffolded ones:\n\n- Keep the existing scaffolded tests (class name, execute method)\n- Add tests relevant to the specific service behavior\n\nThe generated test structure follows this pattern:\n\n```typescript\nimport { describe, expect, test } from \"bun:test\";\nimport { <Name>Service } from \"@/services/<Name>Service\";\n\ndescribe(\"<Name>Service\", () => {\n test(\"should have class name ending with 'Service'\", () => {\n expect(<Name>Service.name.endsWith(\"Service\")).toBe(true);\n });\n\n test(\"should have 'execute' method\", () => {\n expect(<Name>Service.prototype.execute).toBeDefined();\n expect(typeof <Name>Service.prototype.execute).toBe(\"function\");\n });\n});\n```\n\n### 5. Lint and format\n\nRun linting and formatting on the generated files:\n\n```bash\nbunx biome check --fix src/services/<Name>Service.ts tests/services/<Name>Service.spec.ts\n```\n";
@@ -9385,7 +9386,7 @@ class MakeMigrationCommand {
9385
9386
  if (!await binMigrationUpFile.exists()) {
9386
9387
  await Bun.write(binMigrationUpPath, migration_up_default);
9387
9388
  }
9388
- const packageJsonPath = join18(process.cwd(), "package.json");
9389
+ const packageJsonPath = join18(process.cwd(), base, "package.json");
9389
9390
  const packageJsonFile = Bun.file(packageJsonPath);
9390
9391
  if (await packageJsonFile.exists()) {
9391
9392
  const packageJson = await packageJsonFile.json();
@@ -9409,7 +9410,7 @@ class MakeMigrationCommand {
9409
9410
  const devDeps = pkgJson.devDependencies ?? {};
9410
9411
  if (!deps["@ooneex/migrations"] && !devDeps["@ooneex/migrations"]) {
9411
9412
  const install = Bun.spawn(["bun", "add", "--dev", "@ooneex/migrations"], {
9412
- cwd: process.cwd(),
9413
+ cwd: join18(process.cwd(), base),
9413
9414
  stdout: "ignore",
9414
9415
  stderr: "inherit"
9415
9416
  });
@@ -11085,7 +11086,7 @@ class MakeSeedCommand {
11085
11086
  await ensureModule(module);
11086
11087
  }
11087
11088
  const base = module ? join25("modules", module) : ".";
11088
- const { seedPath: filePath } = await seedCreate({
11089
+ const { seedPath: filePath, dataPath } = await seedCreate({
11089
11090
  name,
11090
11091
  seedsDir: join25(base, "src", "seeds"),
11091
11092
  testsDir: join25(base, "tests", "seeds")
@@ -11095,7 +11096,7 @@ class MakeSeedCommand {
11095
11096
  if (!await binSeedRunFile.exists()) {
11096
11097
  await Bun.write(binSeedRunPath, seed_run_default);
11097
11098
  }
11098
- const packageJsonPath = join25(process.cwd(), "package.json");
11099
+ const packageJsonPath = join25(process.cwd(), base, "package.json");
11099
11100
  const packageJsonFile = Bun.file(packageJsonPath);
11100
11101
  if (await packageJsonFile.exists()) {
11101
11102
  const packageJson = await packageJsonFile.json();
@@ -11109,6 +11110,11 @@ class MakeSeedCommand {
11109
11110
  showArrow: false,
11110
11111
  useSymbol: true
11111
11112
  });
11113
+ logger.success(`${dataPath} created successfully`, undefined, {
11114
+ showTimestamp: false,
11115
+ showArrow: false,
11116
+ useSymbol: true
11117
+ });
11112
11118
  logger.info("Run 'bun run seed:run' to execute seeds", undefined, {
11113
11119
  showTimestamp: false,
11114
11120
  showArrow: true,
@@ -11119,7 +11125,7 @@ class MakeSeedCommand {
11119
11125
  const devDeps = pkgJson.devDependencies ?? {};
11120
11126
  if (!deps["@ooneex/seeds"] && !devDeps["@ooneex/seeds"]) {
11121
11127
  const install = Bun.spawn(["bun", "add", "--dev", "@ooneex/seeds"], {
11122
- cwd: process.cwd(),
11128
+ cwd: join25(process.cwd(), base),
11123
11129
  stdout: "ignore",
11124
11130
  stderr: "inherit"
11125
11131
  });
@@ -11389,4 +11395,4 @@ MakeVectorDatabaseCommand = __legacyDecorateClassTS([
11389
11395
  // src/index.ts
11390
11396
  await run();
11391
11397
 
11392
- //# debugId=813EA09F8A5BE6E864756E2164756E21
11398
+ //# debugId=14FC8E204F5BE58B64756E2164756E21