forge-sql-orm 1.0.1

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.
@@ -0,0 +1,31 @@
1
+ import type { EntityName, LoggingOptions } from "@mikro-orm/core";
2
+ import type { EntitySchema } from "@mikro-orm/core/metadata/EntitySchema";
3
+ import type { AnyEntity, EntityClass, EntityClassGroup } from "@mikro-orm/core/typings";
4
+ import type { QueryBuilder } from "@mikro-orm/knex/query";
5
+ import { CRUDForgeSQL, SchemaSqlForgeSql } from "./ForgeSQLQueryBuilder";
6
+ import type { Knex } from "knex";
7
+ /**
8
+ * Public class that acts as a wrapper around the private ForgeSQLORMImpl.
9
+ */
10
+ declare class ForgeSQLORM {
11
+ private readonly ormInstance;
12
+ constructor(entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[]);
13
+ /**
14
+ * Proxies the `crud` method from `ForgeSQLORMImpl`.
15
+ * @returns CRUD operations.
16
+ */
17
+ crud(): CRUDForgeSQL;
18
+ /**
19
+ * Proxies the `fetch` method from `ForgeSQLORMImpl`.
20
+ * @returns Fetch operations.
21
+ */
22
+ fetch(): SchemaSqlForgeSql;
23
+ getKnex(): Knex<any, any[]>;
24
+ /**
25
+ * Proxies the `createQueryBuilder` method from `ForgeSQLORMImpl`.
26
+ * @returns A new query builder instance.
27
+ */
28
+ createQueryBuilder<Entity extends object, RootAlias extends string = never>(entityName: EntityName<Entity> | QueryBuilder<Entity>, alias?: RootAlias, loggerContext?: LoggingOptions): QueryBuilder<Entity, RootAlias>;
29
+ }
30
+ export default ForgeSQLORM;
31
+ //# sourceMappingURL=ForgeSQLORM.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForgeSQLORM.d.ts","sourceRoot":"","sources":["../../src/core/ForgeSQLORM.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACxF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAG1D,OAAO,EAAE,YAAY,EAAqB,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE5F,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAkGjC;;GAEG;AACH,cAAM,WAAW;IACf,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;gBAEpC,QAAQ,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,gBAAgB,CAAC,SAAS,CAAC,GAAG,YAAY,CAAC,EAAE;IAI7F;;;OAGG;IACH,IAAI,IAAI,YAAY;IAIpB;;;OAGG;IACH,KAAK,IAAI,iBAAiB;IAI1B,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;IAI3B;;;OAGG;IACH,kBAAkB,CAAC,MAAM,SAAS,MAAM,EAAE,SAAS,SAAS,MAAM,GAAG,KAAK,EACxE,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,EACrD,KAAK,CAAC,EAAE,SAAS,EACjB,aAAa,CAAC,EAAE,cAAc,GAC7B,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC;CAGnC;AAED,eAAe,WAAW,CAAC"}
@@ -0,0 +1,83 @@
1
+ import { UpdateQueryResponse } from "@forge/sql";
2
+ import type { EntityName, LoggingOptions } from "..";
3
+ import type { EntitySchema } from "@mikro-orm/core/metadata/EntitySchema";
4
+ import type { QueryBuilder } from "@mikro-orm/knex/query";
5
+ import type { Knex } from "knex";
6
+ /**
7
+ * Interface representing the main ForgeSQL operations.
8
+ */
9
+ export interface ForgeSqlOperation extends QueryBuilderForgeSql {
10
+ /**
11
+ * Provides CRUD operations.
12
+ */
13
+ crud(): CRUDForgeSQL;
14
+ /**
15
+ * Provides schema-level SQL fetch operations.
16
+ */
17
+ fetch(): SchemaSqlForgeSql;
18
+ }
19
+ /**
20
+ * Interface for schema-level SQL operations.
21
+ */
22
+ export interface SchemaSqlForgeSql {
23
+ /**
24
+ * Executes a schema-bound SQL query and maps the result to the specified entity schema.
25
+ * @param query - The SQL query to execute.
26
+ * @param schema - The entity schema.
27
+ * @returns A list of mapped entity objects.
28
+ */
29
+ executeSchemaSQL<T extends object>(query: string, schema: EntitySchema<T>): Promise<T[]>;
30
+ /**
31
+ * Executes a raw SQL query and returns the results.
32
+ * @param query - The raw SQL query.
33
+ * @returns A list of results as objects.
34
+ */
35
+ executeRawSQL<T extends object | unknown>(query: string): Promise<T[]>;
36
+ /**
37
+ * Executes a raw SQL update query.
38
+ * @param query - The raw SQL update query.
39
+ * @returns The update response containing affected rows.
40
+ */
41
+ executeRawUpdateSQL(query: string): Promise<UpdateQueryResponse>;
42
+ }
43
+ /**
44
+ * Interface for CRUD (Create, Read, Update, Delete) operations.
45
+ */
46
+ export interface CRUDForgeSQL {
47
+ /**
48
+ * Inserts multiple records into the database.
49
+ * @param schema - The entity schema.
50
+ * @param models - The list of entities to insert.
51
+ * @param updateIfExists - Whether to update the row if it already exists.
52
+ * @returns The number of inserted rows.
53
+ */
54
+ insert<T extends object>(schema: EntitySchema<T>, models: T[], updateIfExists?: boolean): Promise<number>;
55
+ /**
56
+ * Deletes a record by its ID.
57
+ * @param id - The ID of the record to delete.
58
+ * @param schema - The entity schema.
59
+ * @returns The number of rows affected.
60
+ */
61
+ deleteById<T extends object>(id: unknown, schema: EntitySchema<T>): Promise<number>;
62
+ /**
63
+ * Updates a record by its ID.
64
+ * @param entity - The entity with updated values.
65
+ * @param schema - The entity schema.
66
+ */
67
+ updateById<T extends object>(entity: T, schema: EntitySchema<T>): Promise<void>;
68
+ }
69
+ /**
70
+ * Interface for Query Builder operations.
71
+ */
72
+ export interface QueryBuilderForgeSql {
73
+ /**
74
+ * Creates a new query builder for the given entity.
75
+ * @param entityName - The entity name or an existing query builder.
76
+ * @param alias - The alias for the entity.
77
+ * @param loggerContext - Logging options.
78
+ * @returns The query builder instance.
79
+ */
80
+ createQueryBuilder<Entity extends object, RootAlias extends string = never>(entityName: EntityName<Entity> | QueryBuilder<Entity>, alias?: RootAlias, loggerContext?: LoggingOptions): QueryBuilder<Entity, RootAlias>;
81
+ getKnex(): Knex<any, any[]>;
82
+ }
83
+ //# sourceMappingURL=ForgeSQLQueryBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForgeSQLQueryBuilder.d.ts","sourceRoot":"","sources":["../../src/core/ForgeSQLQueryBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAEjC;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,oBAAoB;IAC7D;;OAEG;IACH,IAAI,IAAI,YAAY,CAAC;IAErB;;OAEG;IACH,KAAK,IAAI,iBAAiB,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAEzF;;;;OAIG;IACH,aAAa,CAAC,CAAC,SAAS,MAAM,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAEvE;;;;OAIG;IACH,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;CAClE;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;OAMG;IACH,MAAM,CAAC,CAAC,SAAS,MAAM,EACrB,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EACvB,MAAM,EAAE,CAAC,EAAE,EACX,cAAc,CAAC,EAAE,OAAO,GACvB,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnB;;;;;OAKG;IACH,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEpF;;;;OAIG;IACH,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjF;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;;OAMG;IACH,kBAAkB,CAAC,MAAM,SAAS,MAAM,EAAE,SAAS,SAAS,MAAM,GAAG,KAAK,EACxE,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,EACrD,KAAK,CAAC,EAAE,SAAS,EACjB,aAAa,CAAC,EAAE,cAAc,GAC7B,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAEnC,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;CAC7B"}
@@ -0,0 +1,25 @@
1
+ import { UpdateQueryResponse } from "@forge/sql";
2
+ import type { EntitySchema } from "@mikro-orm/core/metadata/EntitySchema";
3
+ import { SchemaSqlForgeSql } from "./ForgeSQLQueryBuilder";
4
+ export declare class ForgeSQLSelectOperations implements SchemaSqlForgeSql {
5
+ /**
6
+ * Executes a schema-based SQL query and maps the result to the entity schema.
7
+ * @param query - The SQL query to execute.
8
+ * @param schema - The entity schema defining the structure.
9
+ * @returns A list of mapped entity objects.
10
+ */
11
+ executeSchemaSQL<T extends object>(query: string, schema: EntitySchema<T>): Promise<T[]>;
12
+ /**
13
+ * Executes a raw SQL query and returns the results.
14
+ * @param query - The raw SQL query to execute.
15
+ * @returns A list of results as objects.
16
+ */
17
+ executeRawSQL<T extends object | unknown>(query: string): Promise<T[]>;
18
+ /**
19
+ * Executes a raw SQL update query.
20
+ * @param query - The raw SQL update query.
21
+ * @returns The update response containing affected rows.
22
+ */
23
+ executeRawUpdateSQL(query: string): Promise<UpdateQueryResponse>;
24
+ }
25
+ //# sourceMappingURL=ForgeSQLSelectOperations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForgeSQLSelectOperations.d.ts","sourceRoot":"","sources":["../../src/core/ForgeSQLSelectOperations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAE1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,qBAAa,wBAAyB,YAAW,iBAAiB;IAChE;;;;;OAKG;IACG,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAoC9F;;;;OAIG;IACG,aAAa,CAAC,CAAC,SAAS,MAAM,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAO5E;;;;OAIG;IACG,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAMvE"}
@@ -0,0 +1,8 @@
1
+ import ForgeSQLORM from "./core/ForgeSQLORM";
2
+ export * from "./core/ForgeSQLQueryBuilder";
3
+ export * from "./core/ForgeSQLCrudOperations";
4
+ export * from "./core/ForgeSQLSelectOperations";
5
+ export * from "@mikro-orm/mysql";
6
+ export * from "@mikro-orm/entity-generator";
7
+ export default ForgeSQLORM;
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,oBAAoB,CAAC;AAE7C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAE5C,eAAe,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,332 @@
1
+ "use strict";
2
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
+ const mysql = require("@mikro-orm/mysql");
4
+ const sql = require("@forge/sql");
5
+ const moment = require("moment");
6
+ const entityGenerator = require("@mikro-orm/entity-generator");
7
+ const transformValue = (value) => {
8
+ switch (value.type) {
9
+ case "text":
10
+ case "string":
11
+ return `'${value.value}'`;
12
+ case "datetime":
13
+ return `'${moment(value.value).format("YYYY-MM-DDTHH:mm:ss.SSS")}'`;
14
+ case "date":
15
+ return `'${moment(value.value).format("YYYY-MM-DD")}'`;
16
+ case "time":
17
+ return `'${moment(value.value).format("HH:mm:ss.SSS")}'`;
18
+ default:
19
+ return value.value;
20
+ }
21
+ };
22
+ const parseDateTime = (value, format) => {
23
+ return moment(value, format).toDate();
24
+ };
25
+ class ForgeSQLCrudOperations {
26
+ forgeOperations;
27
+ constructor(forgeSqlOperations) {
28
+ this.forgeOperations = forgeSqlOperations;
29
+ }
30
+ /**
31
+ * Generates an SQL insert query with values.
32
+ * @param schema - The entity schema.
33
+ * @param models - The list of entities to insert.
34
+ * @param updateIfExists - Whether to update the row if it already exists.
35
+ * @returns An object containing the SQL query, fields, and values.
36
+ */
37
+ async generateInsertScript(schema, models, updateIfExists) {
38
+ const fieldNames = /* @__PURE__ */ new Set();
39
+ const fieldValueMaps = [];
40
+ models.forEach((model) => {
41
+ const fieldValueMap = {};
42
+ schema.meta.props.forEach((p) => {
43
+ const modelValue = model[p.name];
44
+ if (p.kind === "scalar" && modelValue !== void 0) {
45
+ fieldNames.add(p.fieldNames[0] || p.name);
46
+ fieldValueMap[p.fieldNames[0]] = {
47
+ type: p.type,
48
+ value: modelValue
49
+ };
50
+ }
51
+ });
52
+ fieldValueMaps.push(fieldValueMap);
53
+ });
54
+ const fields = Array.from(fieldNames);
55
+ const values = fieldValueMaps.flatMap(
56
+ (fieldValueMap) => fields.map(
57
+ (f) => fieldValueMap[f] || {
58
+ type: "string",
59
+ value: null
60
+ }
61
+ )
62
+ );
63
+ return {
64
+ sql: `INSERT INTO ${schema.meta.collection} (${fields.join(",")}) VALUES ${fieldValueMaps.map(
65
+ (fieldValueMap) => `(${fields.map(
66
+ (f) => transformValue(
67
+ fieldValueMap[f] || {
68
+ type: "string",
69
+ value: null
70
+ }
71
+ )
72
+ ).join(",")})`
73
+ ).join(
74
+ ", "
75
+ )} ${updateIfExists ? `ON DUPLICATE KEY UPDATE ${fields.map((f) => `${f} = VALUES(${f})`).join(",")}` : ""}`,
76
+ fields,
77
+ values
78
+ };
79
+ }
80
+ /**
81
+ * Inserts records into the database.
82
+ * @param schema - The entity schema.
83
+ * @param models - The list of entities to insert.
84
+ * @param updateIfExists - Whether to update the row if it already exists.
85
+ * @returns The ID of the inserted row.
86
+ */
87
+ async insert(schema, models, updateIfExists = false) {
88
+ if (!models || models.length === 0) return 0;
89
+ const query = await this.generateInsertScript(schema, models, updateIfExists);
90
+ console.debug("INSERT SQL: " + query.sql);
91
+ console.debug("INSERT VALUES: " + JSON.stringify(query.values));
92
+ const sqlStatement = sql.sql.prepare(query.sql);
93
+ const updateQueryResponseResult = await sqlStatement.execute();
94
+ return updateQueryResponseResult.rows.insertId;
95
+ }
96
+ /**
97
+ * Retrieves the primary keys for the given entity schema.
98
+ * @param schema - The entity schema.
99
+ * @returns An array of primary key properties.
100
+ * @throws If no primary keys are found.
101
+ */
102
+ getPrimaryKeys(schema) {
103
+ const primaryKeys = schema.meta.props.filter((p) => p.primary);
104
+ if (!primaryKeys.length) {
105
+ throw new Error(`No primary keys found for schema: ${schema.meta.className}`);
106
+ }
107
+ return primaryKeys;
108
+ }
109
+ /**
110
+ * Deletes a record by its ID.
111
+ * @param id - The ID of the record to delete.
112
+ * @param schema - The entity schema.
113
+ * @returns The number of rows affected.
114
+ * @throws If the entity has more than one primary key.
115
+ */
116
+ async deleteById(id, schema) {
117
+ const primaryKeys = this.getPrimaryKeys(schema);
118
+ if (primaryKeys.length > 1) {
119
+ throw new Error("Only one primary key is supported");
120
+ }
121
+ const primaryKey = primaryKeys[0];
122
+ const queryBuilder = this.forgeOperations.createQueryBuilder(schema.meta.class).delete();
123
+ queryBuilder.andWhere({ [primaryKey.name]: { $eq: id } });
124
+ const query = queryBuilder.getFormattedQuery();
125
+ console.debug("DELETE SQL: " + query);
126
+ const sqlStatement = sql.sql.prepare(query);
127
+ const updateQueryResponseResult = await sqlStatement.execute();
128
+ return updateQueryResponseResult.rows.affectedRows;
129
+ }
130
+ /**
131
+ * Updates a record by its ID.
132
+ * @param entity - The entity with updated values.
133
+ * @param schema - The entity schema.
134
+ * @throws If the primary key value is missing in the entity.
135
+ */
136
+ async updateById(entity, schema) {
137
+ const primaryKeys = this.getPrimaryKeys(schema);
138
+ const queryBuilder = this.forgeOperations.createQueryBuilder(schema.meta.class).update(entity);
139
+ primaryKeys.forEach((pk) => {
140
+ const value = entity[pk.name];
141
+ if (value === null || value === void 0) {
142
+ throw new Error(`Primary Key ${pk.name} must exist in the model`);
143
+ }
144
+ queryBuilder.andWhere({ [pk.name]: { $eq: value } });
145
+ });
146
+ const query = queryBuilder.getFormattedQuery();
147
+ console.debug("UPDATE SQL: " + query);
148
+ await this.forgeOperations.fetch().executeRawUpdateSQL(query);
149
+ }
150
+ }
151
+ class ForgeSQLSelectOperations {
152
+ /**
153
+ * Executes a schema-based SQL query and maps the result to the entity schema.
154
+ * @param query - The SQL query to execute.
155
+ * @param schema - The entity schema defining the structure.
156
+ * @returns A list of mapped entity objects.
157
+ */
158
+ async executeSchemaSQL(query, schema) {
159
+ const datas = await this.executeRawSQL(query);
160
+ if (!datas.length) return [];
161
+ return datas.map((r) => {
162
+ const rawModel = r;
163
+ const newModel = {};
164
+ schema.meta.props.filter((p) => p.kind === "scalar").forEach((p) => {
165
+ const fieldName = p.name;
166
+ const fieldNames = p.fieldNames;
167
+ const rawFieldName = fieldNames && Array.isArray(fieldNames) ? fieldNames[0] : p.name;
168
+ switch (p.type) {
169
+ case "datetime":
170
+ newModel[fieldName] = parseDateTime(
171
+ rawModel[rawFieldName],
172
+ "YYYY-MM-DDTHH:mm:ss.SSS"
173
+ );
174
+ break;
175
+ case "date":
176
+ newModel[fieldName] = parseDateTime(rawModel[rawFieldName], "YYYY-MM-DD");
177
+ break;
178
+ case "time":
179
+ newModel[fieldName] = parseDateTime(rawModel[rawFieldName], "HH:mm:ss.SSS");
180
+ break;
181
+ default:
182
+ newModel[fieldName] = rawModel[rawFieldName];
183
+ }
184
+ });
185
+ return newModel;
186
+ });
187
+ }
188
+ /**
189
+ * Executes a raw SQL query and returns the results.
190
+ * @param query - The raw SQL query to execute.
191
+ * @returns A list of results as objects.
192
+ */
193
+ async executeRawSQL(query) {
194
+ console.debug("Executing raw SQL: " + query);
195
+ const sqlStatement = await sql.sql.prepare(query).execute();
196
+ console.debug("Query result: " + JSON.stringify(sqlStatement));
197
+ return sqlStatement.rows;
198
+ }
199
+ /**
200
+ * Executes a raw SQL update query.
201
+ * @param query - The raw SQL update query.
202
+ * @returns The update response containing affected rows.
203
+ */
204
+ async executeRawUpdateSQL(query) {
205
+ console.debug("Executing update SQL: " + query);
206
+ const sqlStatement = sql.sql.prepare(query);
207
+ const updateQueryResponseResults = await sqlStatement.execute();
208
+ return updateQueryResponseResults.rows;
209
+ }
210
+ }
211
+ class ForgeSQLORMImpl {
212
+ static instance = null;
213
+ mikroORM;
214
+ crudOperations;
215
+ fetchOperations;
216
+ /**
217
+ * Private constructor to enforce singleton behavior.
218
+ * @param entities - The list of entities for ORM initialization.
219
+ */
220
+ constructor(entities) {
221
+ console.debug("Initializing ForgeSQLORM...");
222
+ try {
223
+ this.mikroORM = mysql.MikroORM.initSync({
224
+ dbName: "inmemory",
225
+ schemaGenerator: {
226
+ disableForeignKeys: false
227
+ },
228
+ discovery: {
229
+ warnWhenNoEntities: true
230
+ },
231
+ resultCache: {
232
+ adapter: mysql.NullCacheAdapter
233
+ },
234
+ metadataCache: {
235
+ enabled: false,
236
+ adapter: mysql.MemoryCacheAdapter
237
+ },
238
+ entities,
239
+ preferTs: false
240
+ });
241
+ this.crudOperations = new ForgeSQLCrudOperations(this);
242
+ this.fetchOperations = new ForgeSQLSelectOperations();
243
+ } catch (error) {
244
+ console.error("ForgeSQLORM initialization failed:", error);
245
+ throw error;
246
+ }
247
+ }
248
+ /**
249
+ * Returns the singleton instance of ForgeSQLORMImpl.
250
+ * @param entities - List of entities (required only on first initialization).
251
+ * @returns The singleton instance of ForgeSQLORMImpl.
252
+ */
253
+ static getInstance(entities) {
254
+ if (!ForgeSQLORMImpl.instance) {
255
+ ForgeSQLORMImpl.instance = new ForgeSQLORMImpl(entities);
256
+ }
257
+ return ForgeSQLORMImpl.instance;
258
+ }
259
+ /**
260
+ * Retrieves the CRUD operations instance.
261
+ * @returns CRUD operations.
262
+ */
263
+ crud() {
264
+ return this.crudOperations;
265
+ }
266
+ /**
267
+ * Retrieves the fetch operations instance.
268
+ * @returns Fetch operations.
269
+ */
270
+ fetch() {
271
+ return this.fetchOperations;
272
+ }
273
+ /**
274
+ * Creates a new query builder for the given entity.
275
+ * @param entityName - The entity name or an existing query builder.
276
+ * @param alias - The alias for the entity.
277
+ * @param loggerContext - Logging options.
278
+ * @returns The query builder instance.
279
+ */
280
+ createQueryBuilder(entityName, alias, loggerContext) {
281
+ return this.mikroORM.em.createQueryBuilder(entityName, alias, void 0, loggerContext);
282
+ }
283
+ getKnex() {
284
+ return this.mikroORM.em.getKnex();
285
+ }
286
+ }
287
+ class ForgeSQLORM {
288
+ ormInstance;
289
+ constructor(entities) {
290
+ this.ormInstance = ForgeSQLORMImpl.getInstance(entities);
291
+ }
292
+ /**
293
+ * Proxies the `crud` method from `ForgeSQLORMImpl`.
294
+ * @returns CRUD operations.
295
+ */
296
+ crud() {
297
+ return this.ormInstance.crud();
298
+ }
299
+ /**
300
+ * Proxies the `fetch` method from `ForgeSQLORMImpl`.
301
+ * @returns Fetch operations.
302
+ */
303
+ fetch() {
304
+ return this.ormInstance.fetch();
305
+ }
306
+ getKnex() {
307
+ return this.ormInstance.getKnex();
308
+ }
309
+ /**
310
+ * Proxies the `createQueryBuilder` method from `ForgeSQLORMImpl`.
311
+ * @returns A new query builder instance.
312
+ */
313
+ createQueryBuilder(entityName, alias, loggerContext) {
314
+ return this.ormInstance.createQueryBuilder(entityName, alias, loggerContext);
315
+ }
316
+ }
317
+ exports.ForgeSQLCrudOperations = ForgeSQLCrudOperations;
318
+ exports.ForgeSQLSelectOperations = ForgeSQLSelectOperations;
319
+ exports.default = ForgeSQLORM;
320
+ Object.keys(mysql).forEach((k) => {
321
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
322
+ enumerable: true,
323
+ get: () => mysql[k]
324
+ });
325
+ });
326
+ Object.keys(entityGenerator).forEach((k) => {
327
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
328
+ enumerable: true,
329
+ get: () => entityGenerator[k]
330
+ });
331
+ });
332
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/utils/sqlUtils.ts","../src/core/ForgeSQLCrudOperations.ts","../src/core/ForgeSQLSelectOperations.ts","../src/core/ForgeSQLORM.ts"],"sourcesContent":["import { types } from \"@mikro-orm/core/types\";\nimport moment from \"moment\";\nimport { AnyString } from \"@mikro-orm/core/typings\";\n\nexport const transformValue = (value: {\n type: keyof typeof types | AnyString;\n value: unknown;\n}): unknown => {\n switch (value.type) {\n case \"text\":\n case \"string\":\n return `'${value.value}'`;\n case \"datetime\":\n return `'${moment(value.value as Date).format(\"YYYY-MM-DDTHH:mm:ss.SSS\")}'`;\n case \"date\":\n return `'${moment(value.value as Date).format(\"YYYY-MM-DD\")}'`;\n case \"time\":\n return `'${moment(value.value as Date).format(\"HH:mm:ss.SSS\")}'`;\n default:\n return value.value;\n }\n};\nexport const parseDateTime = (value: string, format: string): Date => {\n return moment(value, format).toDate();\n};\n","import { UpdateQueryResponse, sql } from \"@forge/sql\";\nimport { EntityProperty, EntitySchema } from \"..\";\nimport type { types } from \"@mikro-orm/core/types\";\nimport { transformValue } from \"../utils/sqlUtils\";\nimport { CRUDForgeSQL, ForgeSqlOperation } from \"./ForgeSQLQueryBuilder\";\n\nexport class ForgeSQLCrudOperations implements CRUDForgeSQL {\n private readonly forgeOperations: ForgeSqlOperation;\n\n constructor(forgeSqlOperations: ForgeSqlOperation) {\n this.forgeOperations = forgeSqlOperations;\n }\n\n /**\n * Generates an SQL insert query with values.\n * @param schema - The entity schema.\n * @param models - The list of entities to insert.\n * @param updateIfExists - Whether to update the row if it already exists.\n * @returns An object containing the SQL query, fields, and values.\n */\n private async generateInsertScript<T extends object>(\n schema: EntitySchema<T>,\n models: T[],\n updateIfExists: boolean,\n ): Promise<{\n sql: string;\n fields: string[];\n values: { type: keyof typeof types; value: unknown }[];\n }> {\n const fieldNames: Set<string> = new Set();\n const fieldValueMaps: Record<string, { type: keyof typeof types; value: unknown }>[] = [];\n\n models.forEach((model) => {\n const fieldValueMap: Record<string, { type: keyof typeof types; value: unknown }> = {};\n schema.meta.props.forEach((p) => {\n const modelValue = model[p.name];\n if (p.kind === \"scalar\" && modelValue !== undefined) {\n fieldNames.add(p.fieldNames[0] || p.name);\n fieldValueMap[p.fieldNames[0]] = {\n type: p.type as keyof typeof types,\n value: modelValue,\n };\n }\n });\n fieldValueMaps.push(fieldValueMap);\n });\n\n const fields = Array.from(fieldNames);\n const values = fieldValueMaps.flatMap((fieldValueMap) =>\n fields.map(\n (f) =>\n fieldValueMap[f] || {\n type: \"string\",\n value: null,\n },\n ),\n );\n\n return {\n sql: `INSERT INTO ${schema.meta.collection} (${fields.join(\",\")}) VALUES ${fieldValueMaps\n .map(\n (fieldValueMap) =>\n `(${fields\n .map((f) =>\n transformValue(\n fieldValueMap[f] || {\n type: \"string\",\n value: null,\n },\n ),\n )\n .join(\",\")})`,\n )\n .join(\n \", \",\n )} ${updateIfExists ? `ON DUPLICATE KEY UPDATE ${fields.map((f) => `${f} = VALUES(${f})`).join(\",\")}` : \"\"}`,\n fields,\n values,\n };\n }\n\n /**\n * Inserts records into the database.\n * @param schema - The entity schema.\n * @param models - The list of entities to insert.\n * @param updateIfExists - Whether to update the row if it already exists.\n * @returns The ID of the inserted row.\n */\n async insert<T extends object>(\n schema: EntitySchema<T>,\n models: T[],\n updateIfExists: boolean = false,\n ): Promise<number> {\n if (!models || models.length === 0) return 0;\n\n const query = await this.generateInsertScript(schema, models, updateIfExists);\n console.debug(\"INSERT SQL: \" + query.sql);\n console.debug(\"INSERT VALUES: \" + JSON.stringify(query.values));\n const sqlStatement = sql.prepare<UpdateQueryResponse>(query.sql);\n const updateQueryResponseResult = await sqlStatement.execute();\n return updateQueryResponseResult.rows.insertId;\n }\n\n /**\n * Retrieves the primary keys for the given entity schema.\n * @param schema - The entity schema.\n * @returns An array of primary key properties.\n * @throws If no primary keys are found.\n */\n private getPrimaryKeys<T extends object>(schema: EntitySchema<T>): EntityProperty<T, unknown>[] {\n const primaryKeys = schema.meta.props.filter((p) => p.primary);\n if (!primaryKeys.length) {\n throw new Error(`No primary keys found for schema: ${schema.meta.className}`);\n }\n return primaryKeys;\n }\n\n /**\n * Deletes a record by its ID.\n * @param id - The ID of the record to delete.\n * @param schema - The entity schema.\n * @returns The number of rows affected.\n * @throws If the entity has more than one primary key.\n */\n async deleteById<T extends object>(id: unknown, schema: EntitySchema<T>): Promise<number> {\n const primaryKeys = this.getPrimaryKeys(schema);\n if (primaryKeys.length > 1) {\n throw new Error(\"Only one primary key is supported\");\n }\n\n const primaryKey = primaryKeys[0];\n const queryBuilder = this.forgeOperations.createQueryBuilder(schema.meta.class).delete();\n queryBuilder.andWhere({ [primaryKey.name]: { $eq: id } });\n\n const query = queryBuilder.getFormattedQuery();\n console.debug(\"DELETE SQL: \" + query);\n\n const sqlStatement = sql.prepare<UpdateQueryResponse>(query);\n const updateQueryResponseResult = await sqlStatement.execute();\n return updateQueryResponseResult.rows.affectedRows;\n }\n\n /**\n * Updates a record by its ID.\n * @param entity - The entity with updated values.\n * @param schema - The entity schema.\n * @throws If the primary key value is missing in the entity.\n */\n async updateById<T extends object>(entity: T, schema: EntitySchema<T>): Promise<void> {\n const primaryKeys = this.getPrimaryKeys(schema);\n const queryBuilder = this.forgeOperations.createQueryBuilder(schema.meta.class).update(entity);\n\n primaryKeys.forEach((pk) => {\n const value = entity[pk.name];\n if (value === null || value === undefined) {\n throw new Error(`Primary Key ${pk.name} must exist in the model`);\n }\n queryBuilder.andWhere({ [pk.name]: { $eq: value } });\n });\n const query = queryBuilder.getFormattedQuery();\n console.debug(\"UPDATE SQL: \" + query);\n await this.forgeOperations.fetch().executeRawUpdateSQL(query);\n }\n}\n","import { sql, UpdateQueryResponse } from \"@forge/sql\";\nimport type { EntitySchema } from \"@mikro-orm/core/metadata/EntitySchema\";\nimport { parseDateTime } from \"../utils/sqlUtils\";\nimport { SchemaSqlForgeSql } from \"./ForgeSQLQueryBuilder\";\n\nexport class ForgeSQLSelectOperations implements SchemaSqlForgeSql {\n /**\n * Executes a schema-based SQL query and maps the result to the entity schema.\n * @param query - The SQL query to execute.\n * @param schema - The entity schema defining the structure.\n * @returns A list of mapped entity objects.\n */\n async executeSchemaSQL<T extends object>(query: string, schema: EntitySchema<T>): Promise<T[]> {\n const datas = await this.executeRawSQL<unknown>(query);\n if (!datas.length) return [];\n\n return datas.map((r) => {\n const rawModel = r as Record<string, unknown>;\n const newModel: Record<string, unknown> = {};\n\n schema.meta.props\n .filter((p) => p.kind === \"scalar\")\n .forEach((p) => {\n const fieldName = p.name;\n const fieldNames = p.fieldNames;\n const rawFieldName = fieldNames && Array.isArray(fieldNames)? fieldNames[0]: p.name;\n\n switch (p.type) {\n case \"datetime\":\n newModel[fieldName] = parseDateTime(\n rawModel[rawFieldName] as string,\n \"YYYY-MM-DDTHH:mm:ss.SSS\",\n );\n break;\n case \"date\":\n newModel[fieldName] = parseDateTime(rawModel[rawFieldName] as string, \"YYYY-MM-DD\");\n break;\n case \"time\":\n newModel[fieldName] = parseDateTime(rawModel[rawFieldName] as string, \"HH:mm:ss.SSS\");\n break;\n default:\n newModel[fieldName] = rawModel[rawFieldName];\n }\n });\n return newModel as T;\n });\n }\n\n /**\n * Executes a raw SQL query and returns the results.\n * @param query - The raw SQL query to execute.\n * @returns A list of results as objects.\n */\n async executeRawSQL<T extends object | unknown>(query: string): Promise<T[]> {\n console.debug(\"Executing raw SQL: \" + query);\n const sqlStatement = await sql.prepare<T>(query).execute();\n console.debug(\"Query result: \" + JSON.stringify(sqlStatement));\n return sqlStatement.rows as T[];\n }\n\n /**\n * Executes a raw SQL update query.\n * @param query - The raw SQL update query.\n * @returns The update response containing affected rows.\n */\n async executeRawUpdateSQL(query: string): Promise<UpdateQueryResponse> {\n console.debug(\"Executing update SQL: \" + query);\n const sqlStatement = sql.prepare<UpdateQueryResponse>(query);\n const updateQueryResponseResults = await sqlStatement.execute();\n return updateQueryResponseResults.rows;\n }\n}\n","import type { EntityName, LoggingOptions } from \"@mikro-orm/core\";\nimport type { EntitySchema } from \"@mikro-orm/core/metadata/EntitySchema\";\nimport type { AnyEntity, EntityClass, EntityClassGroup } from \"@mikro-orm/core/typings\";\nimport type { QueryBuilder } from \"@mikro-orm/knex/query\";\nimport { MemoryCacheAdapter, MikroORM, NullCacheAdapter } from \"@mikro-orm/mysql\";\nimport { ForgeSQLCrudOperations } from \"./ForgeSQLCrudOperations\";\nimport { CRUDForgeSQL, ForgeSqlOperation, SchemaSqlForgeSql } from \"./ForgeSQLQueryBuilder\";\nimport { ForgeSQLSelectOperations } from \"./ForgeSQLSelectOperations\";\nimport type { Knex } from \"knex\";\n\n/**\n * Implementation of ForgeSQLORM that interacts with MikroORM.\n */\nclass ForgeSQLORMImpl implements ForgeSqlOperation {\n private static instance: ForgeSQLORMImpl | null = null;\n private readonly mikroORM: MikroORM;\n private readonly crudOperations: CRUDForgeSQL;\n private readonly fetchOperations: SchemaSqlForgeSql;\n\n /**\n * Private constructor to enforce singleton behavior.\n * @param entities - The list of entities for ORM initialization.\n */\n private constructor(\n entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[],\n ) {\n console.debug(\"Initializing ForgeSQLORM...\");\n\n try {\n this.mikroORM = MikroORM.initSync({\n dbName: \"inmemory\",\n schemaGenerator: {\n disableForeignKeys: false,\n },\n discovery: {\n warnWhenNoEntities: true,\n },\n resultCache: {\n adapter: NullCacheAdapter,\n },\n metadataCache: {\n enabled: false,\n adapter: MemoryCacheAdapter,\n },\n entities: entities,\n preferTs: false,\n });\n\n this.crudOperations = new ForgeSQLCrudOperations(this);\n this.fetchOperations = new ForgeSQLSelectOperations();\n } catch (error) {\n console.error(\"ForgeSQLORM initialization failed:\", error);\n throw error; // Prevents inconsistent state\n }\n }\n\n /**\n * Returns the singleton instance of ForgeSQLORMImpl.\n * @param entities - List of entities (required only on first initialization).\n * @returns The singleton instance of ForgeSQLORMImpl.\n */\n static getInstance(\n entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[],\n ): ForgeSqlOperation {\n if (!ForgeSQLORMImpl.instance) {\n ForgeSQLORMImpl.instance = new ForgeSQLORMImpl(entities);\n }\n return ForgeSQLORMImpl.instance;\n }\n\n /**\n * Retrieves the CRUD operations instance.\n * @returns CRUD operations.\n */\n crud(): CRUDForgeSQL {\n return this.crudOperations;\n }\n\n /**\n * Retrieves the fetch operations instance.\n * @returns Fetch operations.\n */\n fetch(): SchemaSqlForgeSql {\n return this.fetchOperations;\n }\n\n /**\n * Creates a new query builder for the given entity.\n * @param entityName - The entity name or an existing query builder.\n * @param alias - The alias for the entity.\n * @param loggerContext - Logging options.\n * @returns The query builder instance.\n */\n createQueryBuilder<Entity extends object, RootAlias extends string = never>(\n entityName: EntityName<Entity> | QueryBuilder<Entity>,\n alias?: RootAlias,\n loggerContext?: LoggingOptions,\n ): QueryBuilder<Entity, RootAlias> {\n return this.mikroORM.em.createQueryBuilder(entityName, alias, undefined, loggerContext);\n }\n\n getKnex(): Knex<any, any[]> {\n return this.mikroORM.em.getKnex();\n }\n}\n\n/**\n * Public class that acts as a wrapper around the private ForgeSQLORMImpl.\n */\nclass ForgeSQLORM {\n private readonly ormInstance: ForgeSqlOperation;\n\n constructor(entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[]) {\n this.ormInstance = ForgeSQLORMImpl.getInstance(entities);\n }\n\n /**\n * Proxies the `crud` method from `ForgeSQLORMImpl`.\n * @returns CRUD operations.\n */\n crud(): CRUDForgeSQL {\n return this.ormInstance.crud();\n }\n\n /**\n * Proxies the `fetch` method from `ForgeSQLORMImpl`.\n * @returns Fetch operations.\n */\n fetch(): SchemaSqlForgeSql {\n return this.ormInstance.fetch();\n }\n\n getKnex(): Knex<any, any[]> {\n return this.ormInstance.getKnex();\n }\n\n /**\n * Proxies the `createQueryBuilder` method from `ForgeSQLORMImpl`.\n * @returns A new query builder instance.\n */\n createQueryBuilder<Entity extends object, RootAlias extends string = never>(\n entityName: EntityName<Entity> | QueryBuilder<Entity>,\n alias?: RootAlias,\n loggerContext?: LoggingOptions,\n ): QueryBuilder<Entity, RootAlias> {\n return this.ormInstance.createQueryBuilder(entityName, alias, loggerContext);\n }\n}\n\nexport default ForgeSQLORM;\n"],"names":["sql","MikroORM","NullCacheAdapter","MemoryCacheAdapter"],"mappings":"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"}