@rws-framework/db 2.4.1 → 2.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,12 @@
1
- import { IDbConfigHandler } from '../types/DbConfigHandler';
1
+ import { IDbConfigHandler, IDbConfigParams, IdGeneratorOptions } from '../types/DbConfigHandler';
2
2
  import { IMetaOpts, OpModelType } from '../models/_model';
3
3
  import { DBService } from '../services/DBService';
4
4
  export declare class DbHelper {
5
+ static dbUrlVarName: string;
5
6
  static installPrisma(configService: IDbConfigHandler, dbService: DBService, leaveFile?: boolean): Promise<void>;
6
- static generateModelSections(model: OpModelType<any>): Promise<string>;
7
+ static generateId(dbType: IDbConfigParams['db_type'], options?: IdGeneratorOptions): string;
8
+ static detectInstaller(): string;
9
+ static pushDBModels(configService: IDbConfigHandler, dbService: DBService, leaveFile?: boolean): Promise<void>;
10
+ static generateModelSections(model: OpModelType<any>, configService: IDbConfigHandler): Promise<string>;
7
11
  static toConfigCase(modelType: IMetaOpts): string;
8
12
  }
@@ -21,12 +21,12 @@ class DbHelper {
21
21
  }\n\n`;
22
22
  template += `\ndatasource db {\n
23
23
  provider = "${dbType}"\n
24
- url = env("PRISMA_DB_URL")\n
24
+ url = env("${this.dbUrlVarName}")\n
25
25
  }\n\n`;
26
26
  const dbModels = configService.get('db_models');
27
27
  if (dbModels) {
28
28
  for (const model of dbModels) {
29
- const modelSection = await DbHelper.generateModelSections(model);
29
+ const modelSection = await DbHelper.generateModelSections(model, configService);
30
30
  template += '\n\n' + modelSection;
31
31
  log(chalk_1.default.green('[RWS]'), chalk_1.default.blue('Building DB Model'), model.name);
32
32
  // if(RWSModel.isSubclass(model as any, TimeSeriesModel)){
@@ -48,11 +48,25 @@ class DbHelper {
48
48
  fs_1.default.unlinkSync(schemaPath);
49
49
  }
50
50
  fs_1.default.writeFileSync(schemaPath, template);
51
- process.env.DB_URL = dbUrl;
52
- const endPrisma = 'npx prisma';
53
- // console.log({cwd: process.cwd()})
54
- // const clientPath = path.join(rwsPath.findRootWorkspacePath(), 'node_modules', '.prisma', 'client');
55
- await console_1.rwsShell.runCommand(`${endPrisma} generate --schema=${schemaPath}`, process.cwd());
51
+ process.env = { ...process.env, [this.dbUrlVarName]: dbUrl };
52
+ // Use npx directly with the full path to prisma
53
+ const npxPath = path_1.default.join(workspaceRoot, 'node_modules', '.bin', 'npx');
54
+ const prismaPath = path_1.default.join(workspaceRoot, 'node_modules', '.bin', 'prisma');
55
+ try {
56
+ // Try using npx with the full path
57
+ await console_1.rwsShell.runCommand(`"${npxPath}" prisma generate --schema="${schemaPath}"`, process.cwd());
58
+ }
59
+ catch (error) {
60
+ // If that fails, try using the prisma binary directly
61
+ try {
62
+ await console_1.rwsShell.runCommand(`"${prismaPath}" generate --schema="${schemaPath}"`, process.cwd());
63
+ }
64
+ catch (innerError) {
65
+ // If both fail, try using node to run prisma
66
+ const nodePrismaPath = path_1.default.join(workspaceRoot, 'node_modules', 'prisma', 'build', 'index.js');
67
+ await console_1.rwsShell.runCommand(`node "${nodePrismaPath}" generate --schema="${schemaPath}"`, process.cwd());
68
+ }
69
+ }
56
70
  leaveFile = false;
57
71
  log(chalk_1.default.green('[RWS Init]') + ' prisma schema generated from ', schemaPath);
58
72
  if (!leaveFile) {
@@ -60,13 +74,46 @@ class DbHelper {
60
74
  }
61
75
  }
62
76
  }
63
- static async generateModelSections(model) {
77
+ static generateId(dbType, options = {}) {
78
+ const { useUuid = false, customType } = options;
79
+ if (customType) {
80
+ return `id ${customType} @id`;
81
+ }
82
+ switch (dbType) {
83
+ case 'mongodb':
84
+ return 'id String @id @default(auto()) @map("_id") @db.ObjectId';
85
+ case 'mysql':
86
+ return useUuid
87
+ ? 'id String @id @default(uuid())'
88
+ : 'id Int @id @default(autoincrement())';
89
+ case 'sqlite':
90
+ return 'id Int @id @default(autoincrement())';
91
+ default:
92
+ throw new Error('Kurwa, nieobsługiwany typ bazy danych!');
93
+ }
94
+ }
95
+ static detectInstaller() {
96
+ if (fs_1.default.existsSync(path_1.default.join(workspaceRoot, 'yarn.lock'))) {
97
+ return 'yarn';
98
+ }
99
+ return 'npx';
100
+ }
101
+ static async pushDBModels(configService, dbService, leaveFile = false) {
102
+ process.env = { ...process.env, [this.dbUrlVarName]: configService.get('db_url') };
103
+ const schemaDir = path_1.default.join(moduleDir, 'prisma');
104
+ const schemaPath = path_1.default.join(schemaDir, 'schema.prisma');
105
+ // Use npx directly with the full path to prisma
106
+ const execCmdPath = path_1.default.join(workspaceRoot, 'node_modules', '.bin', 'yarn.cmd');
107
+ const execPrismaPath = path_1.default.join(workspaceRoot, 'node_modules', '.bin', 'yarn.cmd');
108
+ await console_1.rwsShell.runCommand(`${this.detectInstaller()} prisma db push --schema="${schemaPath}"`, process.cwd());
109
+ }
110
+ static async generateModelSections(model, configService) {
64
111
  var _a, _b;
65
112
  let section = '';
66
113
  const modelMetadatas = await _model_1.RWSModel.getModelAnnotations(model);
67
114
  const modelName = model._collection;
68
115
  section += `model ${modelName} {\n`;
69
- section += '\tid String @map("_id") @id @default(auto()) @db.ObjectId\n';
116
+ section += `\t${this.generateId(configService.get('db_type'))}\n`;
70
117
  for (const key in modelMetadatas) {
71
118
  const modelMetadata = modelMetadatas[key].metadata;
72
119
  let requiredString = modelMetadata.required ? '' : '?';
@@ -139,3 +186,4 @@ class DbHelper {
139
186
  }
140
187
  }
141
188
  exports.DbHelper = DbHelper;
189
+ DbHelper.dbUrlVarName = 'PRISMA_DB_URL';
package/dist/index.d.ts CHANGED
@@ -5,8 +5,8 @@ import { DbHelper } from './helper/DbHelper';
5
5
  import { FieldsHelper } from './helper/FieldsHelper';
6
6
  import type { FindByType } from './types/FindParams';
7
7
  import type { ITimeSeries } from './types/ITimeSeries';
8
- import type { IDbConfigHandler } from './types/DbConfigHandler';
8
+ import type { IDbConfigHandler, IDbConfigParams } from './types/DbConfigHandler';
9
9
  import type { IRWSModel } from './types/IRWSModel';
10
10
  import { RWSCollection, IRWSCollectionMeta, IRWSCollectionOpts } from "./decorators/RWSCollection";
11
- export type { IRWSCollectionMeta, IRWSCollectionOpts, IRWSModel, IMetaOpts, OpModelType, IDbConfigHandler, ITimeSeries, };
11
+ export type { IRWSCollectionMeta, IRWSCollectionOpts, IRWSModel, IMetaOpts, OpModelType, IDbConfigHandler, IDbConfigParams, ITimeSeries, };
12
12
  export { RWSModel, RWSCollection, DBService, FindByType, InverseRelation, Relation, TrackType, InverseTimeSeries, DbHelper, FieldsHelper };
@@ -6,13 +6,13 @@ import { DBService } from '../../services/DBService';
6
6
  declare class RWSModel<T> implements IModel {
7
7
  static services: IRWSModelServices;
8
8
  [key: string]: any;
9
- id: string;
9
+ id: string | number;
10
10
  static _collection: string;
11
11
  static _RELATIONS: {};
12
12
  static _BANNED_KEYS: string[];
13
13
  static allModels: OpModelType<any>[];
14
14
  static _CUT_KEYS: string[];
15
- constructor(data: any);
15
+ constructor(data?: any);
16
16
  checkForInclusionWithThrow(): void;
17
17
  static checkForInclusionWithThrow(this: OpModelType<any>, checkModelType: string): void;
18
18
  checkForInclusion(): boolean;
@@ -21,7 +21,7 @@ declare class RWSModel<T> implements IModel {
21
21
  protected hasRelation(key: string): boolean;
22
22
  protected bindRelation(key: string, relatedModel: RWSModel<any>): {
23
23
  connect: {
24
- id: string;
24
+ id: string | number;
25
25
  };
26
26
  };
27
27
  _asyncFill(data: any, fullDataMode?: boolean, allowRelations?: boolean): Promise<T>;
@@ -16,7 +16,7 @@ const RelationUtils_1 = require("../utils/RelationUtils");
16
16
  const TimeSeriesUtils_1 = require("../utils/TimeSeriesUtils");
17
17
  const ModelUtils_1 = require("../utils/ModelUtils");
18
18
  class RWSModel {
19
- constructor(data) {
19
+ constructor(data = null) {
20
20
  if (!this.getCollection()) {
21
21
  throw new Error('Model must have a collection defined');
22
22
  }
@@ -396,5 +396,5 @@ RWSModel.allModels = [];
396
396
  RWSModel._CUT_KEYS = [];
397
397
  __decorate([
398
398
  (0, decorators_1.TrackType)(String),
399
- __metadata("design:type", String)
399
+ __metadata("design:type", Object)
400
400
  ], RWSModel.prototype, "id", void 0);
@@ -2,7 +2,7 @@ import { IDbConfigHandler } from '../../types/DbConfigHandler';
2
2
  import { DBService } from '../../services/DBService';
3
3
  export interface IModel {
4
4
  [key: string]: any;
5
- id: string | null;
5
+ id: string | number | null;
6
6
  save: () => void;
7
7
  getDb: () => DBService;
8
8
  getCollection: () => string | null;
@@ -6,7 +6,7 @@ export declare class RelationUtils {
6
6
  static getRelationManyMeta(model: RWSModel<any>, classFields: string[]): Promise<RelManyMetaType<IRWSModel>>;
7
7
  static bindRelation(relatedModel: RWSModel<any>): {
8
8
  connect: {
9
- id: string;
9
+ id: string | number;
10
10
  };
11
11
  };
12
12
  static hasRelation(model: RWSModel<any>, key: string): boolean;
@@ -2,9 +2,13 @@ import { OpModelType } from "../models/interfaces/OpModelType";
2
2
  export interface IDbConfigParams {
3
3
  db_url?: string;
4
4
  db_name?: string;
5
- db_type?: string;
5
+ db_type?: 'mongodb' | 'mysql' | 'sqlite';
6
6
  db_models?: OpModelType<any>[];
7
7
  }
8
+ export interface IdGeneratorOptions {
9
+ useUuid?: boolean;
10
+ customType?: string;
11
+ }
8
12
  export interface IDbConfigHandler {
9
13
  get<K extends keyof IDbConfigParams>(key: K): IDbConfigParams[K];
10
14
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rws-framework/db",
3
3
  "private": false,
4
- "version": "2.4.1",
4
+ "version": "2.4.2",
5
5
  "description": "",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -3,7 +3,7 @@ import chalk from 'chalk';
3
3
  import path from 'path';
4
4
  import fs from 'fs';
5
5
 
6
- import { IDbConfigHandler } from '../types/DbConfigHandler';
6
+ import { IDbConfigHandler, IDbConfigParams, IdGeneratorOptions } from '../types/DbConfigHandler';
7
7
  import { IMetaOpts, OpModelType, RWSModel } from '../models/_model';
8
8
  // import TimeSeriesModel from '../models/core/TimeSeriesModel';
9
9
  import { DBService } from '../services/DBService';
@@ -15,6 +15,8 @@ const workspaceRoot = rwsPath.findRootWorkspacePath();
15
15
  const moduleDir = path.resolve(workspaceRoot, 'node_modules', '@rws-framework', 'db');
16
16
 
17
17
  export class DbHelper {
18
+ static dbUrlVarName: string = 'PRISMA_DB_URL';
19
+
18
20
  static async installPrisma(configService: IDbConfigHandler, dbService: DBService, leaveFile = false): Promise<void>
19
21
  {
20
22
  const dbUrl = configService.get('db_url');
@@ -26,7 +28,7 @@ export class DbHelper {
26
28
 
27
29
  template += `\ndatasource db {\n
28
30
  provider = "${dbType}"\n
29
- url = env("PRISMA_DB_URL")\n
31
+ url = env("${this.dbUrlVarName}")\n
30
32
  }\n\n`;
31
33
 
32
34
  const dbModels: OpModelType<unknown>[] | null = configService.get('db_models');
@@ -34,7 +36,7 @@ export class DbHelper {
34
36
  if(dbModels){
35
37
 
36
38
  for (const model of dbModels){
37
- const modelSection = await DbHelper.generateModelSections(model);
39
+ const modelSection = await DbHelper.generateModelSections(model, configService);
38
40
 
39
41
  template += '\n\n' + modelSection;
40
42
 
@@ -65,12 +67,25 @@ export class DbHelper {
65
67
  }
66
68
 
67
69
  fs.writeFileSync(schemaPath, template);
68
- process.env.DB_URL = dbUrl;
69
- const endPrisma = 'npx prisma';
70
-
71
- // console.log({cwd: process.cwd()})
72
- // const clientPath = path.join(rwsPath.findRootWorkspacePath(), 'node_modules', '.prisma', 'client');
73
- await rwsShell.runCommand(`${endPrisma} generate --schema=${schemaPath}`, process.cwd());
70
+ process.env = { ...process.env, [this.dbUrlVarName]: dbUrl }
71
+
72
+ // Use npx directly with the full path to prisma
73
+ const npxPath = path.join(workspaceRoot, 'node_modules', '.bin', 'npx');
74
+ const prismaPath = path.join(workspaceRoot, 'node_modules', '.bin', 'prisma');
75
+
76
+ try {
77
+ // Try using npx with the full path
78
+ await rwsShell.runCommand(`"${npxPath}" prisma generate --schema="${schemaPath}"`, process.cwd());
79
+ } catch (error) {
80
+ // If that fails, try using the prisma binary directly
81
+ try {
82
+ await rwsShell.runCommand(`"${prismaPath}" generate --schema="${schemaPath}"`, process.cwd());
83
+ } catch (innerError) {
84
+ // If both fail, try using node to run prisma
85
+ const nodePrismaPath = path.join(workspaceRoot, 'node_modules', 'prisma', 'build', 'index.js');
86
+ await rwsShell.runCommand(`node "${nodePrismaPath}" generate --schema="${schemaPath}"`, process.cwd());
87
+ }
88
+ }
74
89
 
75
90
  leaveFile = false;
76
91
  log(chalk.green('[RWS Init]') + ' prisma schema generated from ', schemaPath);
@@ -81,14 +96,64 @@ export class DbHelper {
81
96
  }
82
97
  }
83
98
 
84
- static async generateModelSections(model: OpModelType<any>): Promise<string> {
99
+ static generateId(
100
+ dbType: IDbConfigParams['db_type'],
101
+ options: IdGeneratorOptions = {}
102
+ ): string {
103
+ const { useUuid = false, customType } = options;
104
+
105
+ if (customType) {
106
+ return `id ${customType} @id`;
107
+ }
108
+
109
+ switch(dbType) {
110
+ case 'mongodb':
111
+ return 'id String @id @default(auto()) @map("_id") @db.ObjectId';
112
+
113
+ case 'mysql':
114
+ return useUuid
115
+ ? 'id String @id @default(uuid())'
116
+ : 'id Int @id @default(autoincrement())';
117
+
118
+ case 'sqlite':
119
+ return 'id Int @id @default(autoincrement())';
120
+
121
+ default:
122
+ throw new Error('Kurwa, nieobsługiwany typ bazy danych!');
123
+ }
124
+ }
125
+
126
+ static detectInstaller(): string
127
+ {
128
+
129
+ if (fs.existsSync(path.join(workspaceRoot, 'yarn.lock'))){
130
+ return 'yarn';
131
+ }
132
+
133
+ return 'npx';
134
+ }
135
+
136
+ static async pushDBModels(configService: IDbConfigHandler, dbService: DBService, leaveFile = false){
137
+ process.env = { ...process.env, [this.dbUrlVarName]: configService.get('db_url') }
138
+ const schemaDir = path.join(moduleDir, 'prisma');
139
+ const schemaPath = path.join(schemaDir, 'schema.prisma');
140
+
141
+ // Use npx directly with the full path to prisma
142
+ const execCmdPath = path.join(workspaceRoot, 'node_modules', '.bin', 'yarn.cmd');
143
+ const execPrismaPath = path.join(workspaceRoot, 'node_modules', '.bin', 'yarn.cmd');
144
+
145
+ await rwsShell.runCommand(`${this.detectInstaller()} prisma db push --schema="${schemaPath}"`, process.cwd());
146
+
147
+ }
148
+
149
+ static async generateModelSections(model: OpModelType<any>, configService: IDbConfigHandler): Promise<string> {
85
150
  let section = '';
86
151
  const modelMetadatas: Record<string, {annotationType: string, metadata: any}> = await RWSModel.getModelAnnotations(model);
87
152
 
88
153
  const modelName: string = (model as any)._collection;
89
154
 
90
155
  section += `model ${modelName} {\n`;
91
- section += '\tid String @map("_id") @id @default(auto()) @db.ObjectId\n';
156
+ section += `\t${this.generateId(configService.get('db_type'))}\n`;
92
157
 
93
158
  for (const key in modelMetadatas) {
94
159
  const modelMetadata = modelMetadatas[key].metadata;
@@ -175,4 +240,4 @@ export class DbHelper {
175
240
 
176
241
  return resultField;
177
242
  }
178
- }
243
+ }
package/src/index.ts CHANGED
@@ -8,7 +8,7 @@ import { FieldsHelper } from './helper/FieldsHelper';
8
8
 
9
9
  import type { FindByType } from './types/FindParams';
10
10
  import type { ITimeSeries } from './types/ITimeSeries';
11
- import type { IDbConfigHandler } from './types/DbConfigHandler';
11
+ import type { IDbConfigHandler, IDbConfigParams } from './types/DbConfigHandler';
12
12
  import type { IRWSModel } from './types/IRWSModel';
13
13
  import { RWSCollection, IRWSCollectionMeta, IRWSCollectionOpts } from "./decorators/RWSCollection";
14
14
 
@@ -18,6 +18,7 @@ export type {
18
18
  IMetaOpts,
19
19
  OpModelType,
20
20
  IDbConfigHandler,
21
+ IDbConfigParams,
21
22
  ITimeSeries,
22
23
  }
23
24
 
@@ -16,14 +16,14 @@ class RWSModel<T> implements IModel {
16
16
 
17
17
  [key: string]: any;
18
18
  @TrackType(String)
19
- id: string;
19
+ id: string | number;
20
20
  static _collection: string = null;
21
21
  static _RELATIONS = {};
22
22
  static _BANNED_KEYS = ['_collection'];
23
23
  static allModels: OpModelType<any>[] = [];
24
24
  static _CUT_KEYS: string[] = [];
25
25
 
26
- constructor(data: any) {
26
+ constructor(data: any = null) {
27
27
  if(!this.getCollection()){
28
28
  throw new Error('Model must have a collection defined');
29
29
  }
@@ -89,7 +89,7 @@ class RWSModel<T> implements IModel {
89
89
  return RelationUtils.hasRelation(this, key);
90
90
  }
91
91
 
92
- protected bindRelation(key: string, relatedModel: RWSModel<any>): { connect: { id: string } } {
92
+ protected bindRelation(key: string, relatedModel: RWSModel<any>): { connect: { id: string | number } } {
93
93
  return RelationUtils.bindRelation(relatedModel);
94
94
  }
95
95
 
@@ -3,7 +3,7 @@ import { DBService } from '../../services/DBService';
3
3
 
4
4
  export interface IModel {
5
5
  [key: string]: any;
6
- id: string | null;
6
+ id: string |number | null;
7
7
  save: () => void;
8
8
  getDb: () => DBService;
9
9
  getCollection: () => string | null;
@@ -56,7 +56,7 @@ export class RelationUtils {
56
56
  return relIds;
57
57
  }
58
58
 
59
- static bindRelation(relatedModel: RWSModel<any>): { connect: { id: string } } {
59
+ static bindRelation(relatedModel: RWSModel<any>): { connect: { id: string | number } } {
60
60
  return {
61
61
  connect: {
62
62
  id: relatedModel.id
@@ -3,10 +3,15 @@ import { OpModelType } from "../models/interfaces/OpModelType";
3
3
  export interface IDbConfigParams {
4
4
  db_url?: string;
5
5
  db_name?: string;
6
- db_type?: string;
6
+ db_type?: 'mongodb' | 'mysql' | 'sqlite';
7
7
  db_models?: OpModelType<any>[]
8
8
  }
9
9
 
10
+ export interface IdGeneratorOptions {
11
+ useUuid?: boolean; // dla MySQL
12
+ customType?: string; // dla custom typów
13
+ }
14
+
10
15
  export interface IDbConfigHandler {
11
16
  get<K extends keyof IDbConfigParams>(key: K): IDbConfigParams[K];
12
17
  }