@owox/backend 0.25.0 → 0.26.0-next-20260515073306
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/src/data-marts/data-destination-types/google-sheets/services/google-sheets-report-writer.js +1 -1
- package/dist/src/data-marts/data-storage-types/interfaces/__fixtures__/blended-query-builder-fixtures.d.ts +3 -1
- package/dist/src/data-marts/data-storage-types/interfaces/__fixtures__/blended-query-builder-fixtures.js +5 -0
- package/dist/src/data-marts/data-storage-types/interfaces/abstract-blended-query-builder.js +13 -13
- package/dist/src/data-marts/data-storage-types/interfaces/blended-query-builder.interface.d.ts +1 -0
- package/dist/src/data-marts/services/blended-report-data.service.js +18 -16
- package/dist/src/data-marts/use-cases/copy-report-as-data-mart.service.d.ts +9 -7
- package/dist/src/data-marts/use-cases/copy-report-as-data-mart.service.js +15 -21
- package/package.json +5 -5
|
@@ -210,6 +210,7 @@ let GoogleSheetsReportWriter = GoogleSheetsReportWriter_1 = class GoogleSheetsRe
|
|
|
210
210
|
}
|
|
211
211
|
}
|
|
212
212
|
async initializeService(report) {
|
|
213
|
+
this.report = report;
|
|
213
214
|
return this.executeWithErrorHandling(async () => {
|
|
214
215
|
if (!(0, data_destination_config_guards_1.isGoogleSheetsConfig)(report.destinationConfig)) {
|
|
215
216
|
throw new Error('Invalid Google Sheets destination configuration provided');
|
|
@@ -241,7 +242,6 @@ let GoogleSheetsReportWriter = GoogleSheetsReportWriter_1 = class GoogleSheetsRe
|
|
|
241
242
|
this.availableColumnsCount = sheet.properties?.gridProperties?.columnCount ?? 0;
|
|
242
243
|
this.spreadsheetTimeZone = spreadsheet.properties?.timeZone ?? 'UTC';
|
|
243
244
|
this.dataMartTitle = report.dataMart.title;
|
|
244
|
-
this.report = report;
|
|
245
245
|
}, 'Initializing Google Sheets service and locating target sheet');
|
|
246
246
|
}
|
|
247
247
|
async prepareSheetColumns(columnsCount) {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { DataMartRelationship } from '../../../entities/data-mart-relationship.entity';
|
|
2
2
|
import { BlendedQueryContext, ResolvedRelationshipChain } from '../blended-query-builder.interface';
|
|
3
3
|
export declare function makeRelationship(overrides?: Partial<DataMartRelationship>): DataMartRelationship;
|
|
4
|
-
export declare function makeChain(partial: Omit<ResolvedRelationshipChain, 'targetDataMartTitle' | 'targetDataMartUrl'>
|
|
4
|
+
export declare function makeChain(partial: Omit<ResolvedRelationshipChain, 'targetDataMartTitle' | 'targetDataMartUrl' | 'cteName'> & {
|
|
5
|
+
cteName?: string;
|
|
6
|
+
}): ResolvedRelationshipChain;
|
|
5
7
|
export declare function createBuildContext(mainTableReference: string): (chains: ResolvedRelationshipChain[], columns: string[]) => BlendedQueryContext;
|
|
@@ -17,8 +17,13 @@ function makeRelationship(overrides = {}) {
|
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
19
|
function makeChain(partial) {
|
|
20
|
+
const cteName = partial.cteName ??
|
|
21
|
+
(partial.parentAlias === 'main'
|
|
22
|
+
? partial.relationship.targetAlias
|
|
23
|
+
: `${partial.parentAlias}_${partial.relationship.targetAlias}`);
|
|
20
24
|
return {
|
|
21
25
|
...partial,
|
|
26
|
+
cteName,
|
|
22
27
|
targetDataMartTitle: 'Test Subsidiary',
|
|
23
28
|
targetDataMartUrl: '/ui/proj/data-marts/sub-1/data-setup',
|
|
24
29
|
};
|
|
@@ -53,11 +53,11 @@ class AbstractBlendedQueryBuilder {
|
|
|
53
53
|
buildTree(chains) {
|
|
54
54
|
const nodeMap = new Map();
|
|
55
55
|
for (const chain of chains) {
|
|
56
|
-
nodeMap.set(chain.
|
|
56
|
+
nodeMap.set(chain.cteName, { chain, children: [] });
|
|
57
57
|
}
|
|
58
58
|
const roots = [];
|
|
59
59
|
for (const chain of chains) {
|
|
60
|
-
const node = nodeMap.get(chain.
|
|
60
|
+
const node = nodeMap.get(chain.cteName);
|
|
61
61
|
if (chain.parentAlias === 'main') {
|
|
62
62
|
roots.push(node);
|
|
63
63
|
}
|
|
@@ -75,10 +75,10 @@ class AbstractBlendedQueryBuilder {
|
|
|
75
75
|
for (const child of node.children) {
|
|
76
76
|
const childResult = this.buildSubtreeCtes(child);
|
|
77
77
|
ctes.push(...childResult.ctes);
|
|
78
|
-
childPassthroughs.set(child.chain.
|
|
78
|
+
childPassthroughs.set(child.chain.cteName, childResult.passthroughFields);
|
|
79
79
|
}
|
|
80
80
|
const { chain } = node;
|
|
81
|
-
const alias = chain.
|
|
81
|
+
const alias = chain.cteName;
|
|
82
82
|
const subsidiaryColumns = this.collectSubsidiaryReferences(chain, node.children);
|
|
83
83
|
ctes.push(this.buildRawCte(`${alias}_raw`, chain.targetTableReference, chain.targetDataMartTitle, chain.targetDataMartUrl, subsidiaryColumns));
|
|
84
84
|
const hasChildren = node.children.length > 0;
|
|
@@ -110,7 +110,7 @@ class AbstractBlendedQueryBuilder {
|
|
|
110
110
|
}
|
|
111
111
|
buildJoinedCte(node, childPassthroughs) {
|
|
112
112
|
const { chain } = node;
|
|
113
|
-
const alias = chain.
|
|
113
|
+
const alias = chain.cteName;
|
|
114
114
|
const rawAlias = `${alias}_raw`;
|
|
115
115
|
const joinedAlias = `${alias}_joined`;
|
|
116
116
|
const quotedRawAlias = this.quoteIdentifier(rawAlias);
|
|
@@ -129,7 +129,7 @@ class AbstractBlendedQueryBuilder {
|
|
|
129
129
|
}
|
|
130
130
|
const joinClauses = [];
|
|
131
131
|
for (const child of node.children) {
|
|
132
|
-
const childAlias = child.chain.
|
|
132
|
+
const childAlias = child.chain.cteName;
|
|
133
133
|
const quotedChildAlias = this.quoteIdentifier(childAlias);
|
|
134
134
|
for (const pt of childPassthroughs.get(childAlias) ?? []) {
|
|
135
135
|
selectParts.push(`${quotedChildAlias}.${this.quoteIdentifier(pt.outputAlias)}`);
|
|
@@ -194,11 +194,11 @@ class AbstractBlendedQueryBuilder {
|
|
|
194
194
|
return Array.from(refs).sort();
|
|
195
195
|
}
|
|
196
196
|
buildAggregationCte(chain, hasChildren, passthroughFields) {
|
|
197
|
-
const { relationship, blendedFields } = chain;
|
|
198
|
-
const alias = this.quoteIdentifier(
|
|
197
|
+
const { relationship, blendedFields, cteName } = chain;
|
|
198
|
+
const alias = this.quoteIdentifier(cteName);
|
|
199
199
|
const sourceAlias = hasChildren
|
|
200
|
-
? this.quoteIdentifier(`${
|
|
201
|
-
: this.quoteIdentifier(`${
|
|
200
|
+
? this.quoteIdentifier(`${cteName}_joined`)
|
|
201
|
+
: this.quoteIdentifier(`${cteName}_raw`);
|
|
202
202
|
const parentJoinKeys = relationship.joinConditions.map(jc => this.quoteFieldRef(jc.targetFieldName));
|
|
203
203
|
const groupByKeys = [...parentJoinKeys];
|
|
204
204
|
const aggregatedParts = blendedFields.map(field => {
|
|
@@ -222,7 +222,7 @@ class AbstractBlendedQueryBuilder {
|
|
|
222
222
|
const parts = [];
|
|
223
223
|
const outputAliasToRoot = new Map();
|
|
224
224
|
for (const root of roots) {
|
|
225
|
-
this.mapOutputAliasesToRoot(root, root.chain.
|
|
225
|
+
this.mapOutputAliasesToRoot(root, root.chain.cteName, outputAliasToRoot);
|
|
226
226
|
}
|
|
227
227
|
for (const col of columnSet) {
|
|
228
228
|
const rootAlias = outputAliasToRoot.get(col);
|
|
@@ -246,8 +246,8 @@ class AbstractBlendedQueryBuilder {
|
|
|
246
246
|
}
|
|
247
247
|
buildJoinParts(roots) {
|
|
248
248
|
return roots.map(root => {
|
|
249
|
-
const { relationship, parentAlias } = root.chain;
|
|
250
|
-
const alias = this.quoteIdentifier(
|
|
249
|
+
const { relationship, parentAlias, cteName } = root.chain;
|
|
250
|
+
const alias = this.quoteIdentifier(cteName);
|
|
251
251
|
const parent = this.quoteIdentifier(parentAlias);
|
|
252
252
|
const onParts = relationship.joinConditions.map(jc => `${parent}.${this.quoteFieldRef(jc.sourceFieldName)} = ${alias}.${this.quoteFieldRef(jc.targetFieldName)}`);
|
|
253
253
|
const onClause = onParts.join(' AND ');
|
package/dist/src/data-marts/data-storage-types/interfaces/blended-query-builder.interface.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export interface ResolvedRelationshipChain {
|
|
|
14
14
|
relationship: DataMartRelationship;
|
|
15
15
|
targetTableReference: string;
|
|
16
16
|
parentAlias: string;
|
|
17
|
+
cteName: string;
|
|
17
18
|
blendedFields: BlendedFieldConfig[];
|
|
18
19
|
targetDataMartTitle: string;
|
|
19
20
|
targetDataMartUrl: string;
|
|
@@ -56,7 +56,7 @@ let BlendedReportDataService = class BlendedReportDataService {
|
|
|
56
56
|
const publicOrigin = this.publicOriginService.getPublicOrigin();
|
|
57
57
|
const mainDataMartUrl = (0, data_mart_url_helper_1.buildDataMartUrl)(publicOrigin, dataMart.projectId, dataMart.id, '/data-setup');
|
|
58
58
|
const allRelationships = await this.relationshipService.findBySourceDataMartId(dataMart.id);
|
|
59
|
-
const chains = await this.buildRelationshipChains(columnConfig, referencedColumns, blendableSchema.blendedFields, blendableSchema.availableSources, allRelationships, dataMart.
|
|
59
|
+
const chains = await this.buildRelationshipChains(columnConfig, referencedColumns, blendableSchema.blendedFields, blendableSchema.availableSources, allRelationships, dataMart.projectId, publicOrigin);
|
|
60
60
|
const blendedResult = await this.blendedQueryBuilderFacade.buildBlendedQuery(dataMart.storage.type, {
|
|
61
61
|
mainTableReference,
|
|
62
62
|
mainDataMartTitle: dataMart.title,
|
|
@@ -88,7 +88,7 @@ let BlendedReportDataService = class BlendedReportDataService {
|
|
|
88
88
|
}
|
|
89
89
|
return headers;
|
|
90
90
|
}
|
|
91
|
-
async buildRelationshipChains(columnConfig, referencedColumns, blendedFields, availableSources, directRelationships,
|
|
91
|
+
async buildRelationshipChains(columnConfig, referencedColumns, blendedFields, availableSources, directRelationships, projectId, publicOrigin) {
|
|
92
92
|
const requestedBlendedFields = blendedFields.filter(f => referencedColumns.has(f.name));
|
|
93
93
|
if (requestedBlendedFields.length === 0) {
|
|
94
94
|
return [];
|
|
@@ -116,25 +116,25 @@ let BlendedReportDataService = class BlendedReportDataService {
|
|
|
116
116
|
relationshipsById.set(rel.id, rel);
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
|
-
const
|
|
119
|
+
const fieldsByAliasPath = new Map();
|
|
120
120
|
for (const field of requestedBlendedFields) {
|
|
121
|
-
const bucket =
|
|
121
|
+
const bucket = fieldsByAliasPath.get(field.aliasPath) ?? [];
|
|
122
122
|
bucket.push(field);
|
|
123
|
-
|
|
123
|
+
fieldsByAliasPath.set(field.aliasPath, bucket);
|
|
124
124
|
}
|
|
125
125
|
const sortedSources = [...neededSources].sort((a, b) => a.depth - b.depth);
|
|
126
|
-
const dataMartAliasMap = new Map();
|
|
127
|
-
dataMartAliasMap.set(rootDataMartId, 'main');
|
|
128
126
|
const columnConfigSet = new Set(columnConfig);
|
|
129
127
|
const chains = [];
|
|
130
128
|
for (const src of sortedSources) {
|
|
131
129
|
const rel = relationshipsById.get(src.relationshipId);
|
|
132
130
|
if (!rel)
|
|
133
131
|
continue;
|
|
134
|
-
const
|
|
132
|
+
const segments = src.aliasPath.split('.');
|
|
133
|
+
const cteName = segments.join('_');
|
|
134
|
+
const parentAlias = segments.length === 1 ? 'main' : segments.slice(0, -1).join('_');
|
|
135
135
|
const targetTableReference = await this.tableReferenceService.resolveTableName(rel.targetDataMart.id, projectId);
|
|
136
136
|
const targetDataMartUrl = (0, data_mart_url_helper_1.buildDataMartUrl)(publicOrigin, projectId, rel.targetDataMart.id, '/data-setup');
|
|
137
|
-
const chainBlendedFields = (
|
|
137
|
+
const chainBlendedFields = (fieldsByAliasPath.get(src.aliasPath) ?? []).map(f => ({
|
|
138
138
|
targetFieldName: f.originalFieldName,
|
|
139
139
|
outputAlias: f.name,
|
|
140
140
|
isHidden: f.isHidden || !columnConfigSet.has(f.name),
|
|
@@ -144,26 +144,28 @@ let BlendedReportDataService = class BlendedReportDataService {
|
|
|
144
144
|
relationship: rel,
|
|
145
145
|
targetTableReference,
|
|
146
146
|
parentAlias,
|
|
147
|
+
cteName,
|
|
147
148
|
blendedFields: chainBlendedFields,
|
|
148
149
|
targetDataMartTitle: rel.targetDataMart.title,
|
|
149
150
|
targetDataMartUrl,
|
|
150
151
|
});
|
|
151
|
-
dataMartAliasMap.set(rel.targetDataMart.id, rel.targetAlias);
|
|
152
152
|
}
|
|
153
153
|
this.assertNoChainCollisions(chains);
|
|
154
154
|
return chains;
|
|
155
155
|
}
|
|
156
156
|
assertNoChainCollisions(chains) {
|
|
157
|
-
const
|
|
157
|
+
const cteNameOwners = new Map();
|
|
158
158
|
for (const chain of chains) {
|
|
159
|
-
const owners =
|
|
159
|
+
const owners = cteNameOwners.get(chain.cteName) ?? [];
|
|
160
160
|
owners.push(chain.relationship.id);
|
|
161
|
-
|
|
161
|
+
cteNameOwners.set(chain.cteName, owners);
|
|
162
162
|
}
|
|
163
|
-
for (const [
|
|
163
|
+
for (const [cteName, owners] of cteNameOwners) {
|
|
164
164
|
if (owners.length > 1) {
|
|
165
|
-
throw new business_violation_exception_1.BusinessViolationException(`Duplicate CTE name:
|
|
166
|
-
`
|
|
165
|
+
throw new business_violation_exception_1.BusinessViolationException(`Duplicate CTE name: cteName "${cteName}" is produced by multiple relationship chains. ` +
|
|
166
|
+
`This typically means two relationship targetAlias values flatten to the same identifier ` +
|
|
167
|
+
`(e.g. "a_b" at one level vs "a"+"b" at two levels). ` +
|
|
168
|
+
`Rename the targetAlias on one of these relationships so each chain produces a unique CTE.`, { cteName, relationshipIds: owners });
|
|
167
169
|
}
|
|
168
170
|
}
|
|
169
171
|
const outputAliasOwners = new Map();
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { Repository } from 'typeorm';
|
|
2
|
-
import { Report } from '../entities/report.entity';
|
|
3
|
-
import { DataMart } from '../entities/data-mart.entity';
|
|
4
|
-
import { DataMartService } from '../services/data-mart.service';
|
|
5
|
-
import { ReportSqlComposerService } from '../services/report-sql-composer.service';
|
|
6
2
|
import { CopyReportAsDataMartCommand } from '../dto/domain/copy-report-as-data-mart.command';
|
|
3
|
+
import { DataMartDto } from '../dto/domain/data-mart.dto';
|
|
4
|
+
import { Report } from '../entities/report.entity';
|
|
7
5
|
import { AccessDecisionService } from '../services/access-decision';
|
|
6
|
+
import { ReportSqlComposerService } from '../services/report-sql-composer.service';
|
|
7
|
+
import { CreateDataMartService } from './create-data-mart.service';
|
|
8
|
+
import { UpdateDataMartDefinitionService } from './update-data-mart-definition.service';
|
|
8
9
|
export declare class CopyReportAsDataMartService {
|
|
9
10
|
private readonly reportRepository;
|
|
10
11
|
private readonly reportSqlComposerService;
|
|
11
|
-
private readonly
|
|
12
|
+
private readonly createDataMartService;
|
|
13
|
+
private readonly updateDataMartDefinitionService;
|
|
12
14
|
private readonly accessDecisionService;
|
|
13
|
-
constructor(reportRepository: Repository<Report>, reportSqlComposerService: ReportSqlComposerService,
|
|
14
|
-
run(command: CopyReportAsDataMartCommand): Promise<
|
|
15
|
+
constructor(reportRepository: Repository<Report>, reportSqlComposerService: ReportSqlComposerService, createDataMartService: CreateDataMartService, updateDataMartDefinitionService: UpdateDataMartDefinitionService, accessDecisionService: AccessDecisionService);
|
|
16
|
+
run(command: CopyReportAsDataMartCommand): Promise<DataMartDto>;
|
|
15
17
|
}
|
|
@@ -18,22 +18,26 @@ const typeorm_1 = require("@nestjs/typeorm");
|
|
|
18
18
|
const typeorm_2 = require("typeorm");
|
|
19
19
|
const typeorm_transactional_1 = require("typeorm-transactional");
|
|
20
20
|
const business_violation_exception_1 = require("../../common/exceptions/business-violation.exception");
|
|
21
|
+
const copy_report_as_data_mart_command_1 = require("../dto/domain/copy-report-as-data-mart.command");
|
|
22
|
+
const create_data_mart_command_1 = require("../dto/domain/create-data-mart.command");
|
|
23
|
+
const update_data_mart_definition_command_1 = require("../dto/domain/update-data-mart-definition.command");
|
|
21
24
|
const report_entity_1 = require("../entities/report.entity");
|
|
22
25
|
const data_mart_definition_type_enum_1 = require("../enums/data-mart-definition-type.enum");
|
|
23
|
-
const data_mart_status_enum_1 = require("../enums/data-mart-status.enum");
|
|
24
|
-
const data_mart_service_1 = require("../services/data-mart.service");
|
|
25
|
-
const report_sql_composer_service_1 = require("../services/report-sql-composer.service");
|
|
26
|
-
const copy_report_as_data_mart_command_1 = require("../dto/domain/copy-report-as-data-mart.command");
|
|
27
26
|
const access_decision_1 = require("../services/access-decision");
|
|
27
|
+
const report_sql_composer_service_1 = require("../services/report-sql-composer.service");
|
|
28
|
+
const create_data_mart_service_1 = require("./create-data-mart.service");
|
|
29
|
+
const update_data_mart_definition_service_1 = require("./update-data-mart-definition.service");
|
|
28
30
|
let CopyReportAsDataMartService = class CopyReportAsDataMartService {
|
|
29
31
|
reportRepository;
|
|
30
32
|
reportSqlComposerService;
|
|
31
|
-
|
|
33
|
+
createDataMartService;
|
|
34
|
+
updateDataMartDefinitionService;
|
|
32
35
|
accessDecisionService;
|
|
33
|
-
constructor(reportRepository, reportSqlComposerService,
|
|
36
|
+
constructor(reportRepository, reportSqlComposerService, createDataMartService, updateDataMartDefinitionService, accessDecisionService) {
|
|
34
37
|
this.reportRepository = reportRepository;
|
|
35
38
|
this.reportSqlComposerService = reportSqlComposerService;
|
|
36
|
-
this.
|
|
39
|
+
this.createDataMartService = createDataMartService;
|
|
40
|
+
this.updateDataMartDefinitionService = updateDataMartDefinitionService;
|
|
37
41
|
this.accessDecisionService = accessDecisionService;
|
|
38
42
|
}
|
|
39
43
|
async run(command) {
|
|
@@ -64,19 +68,8 @@ let CopyReportAsDataMartService = class CopyReportAsDataMartService {
|
|
|
64
68
|
if (!sql.trim()) {
|
|
65
69
|
throw new business_violation_exception_1.BusinessViolationException('Unable to copy this report: generated SQL is empty. Ensure the report has a valid column configuration.', { reportId: command.reportId });
|
|
66
70
|
}
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
const newDataMart = this.dataMartService.create({
|
|
70
|
-
title: `Copy of ${report.title}`,
|
|
71
|
-
projectId: command.projectId,
|
|
72
|
-
createdById: command.userId,
|
|
73
|
-
technicalOwnerIds: [command.userId],
|
|
74
|
-
storage: sourceDataMart.storage,
|
|
75
|
-
definitionType: data_mart_definition_type_enum_1.DataMartDefinitionType.SQL,
|
|
76
|
-
definition,
|
|
77
|
-
status: data_mart_status_enum_1.DataMartStatus.DRAFT,
|
|
78
|
-
});
|
|
79
|
-
return this.dataMartService.save(newDataMart);
|
|
71
|
+
const createdDataMart = await this.createDataMartService.run(new create_data_mart_command_1.CreateDataMartCommand(command.projectId, command.userId, `Copy of ${report.title}`, report.dataMart.storage.id, command.roles));
|
|
72
|
+
return this.updateDataMartDefinitionService.run(new update_data_mart_definition_command_1.UpdateDataMartDefinitionCommand(createdDataMart.id, command.projectId, data_mart_definition_type_enum_1.DataMartDefinitionType.SQL, { sqlQuery: sql }, undefined, undefined, command.userId, command.roles));
|
|
80
73
|
}
|
|
81
74
|
};
|
|
82
75
|
exports.CopyReportAsDataMartService = CopyReportAsDataMartService;
|
|
@@ -91,7 +84,8 @@ exports.CopyReportAsDataMartService = CopyReportAsDataMartService = __decorate([
|
|
|
91
84
|
__param(0, (0, typeorm_1.InjectRepository)(report_entity_1.Report)),
|
|
92
85
|
__metadata("design:paramtypes", [typeorm_2.Repository,
|
|
93
86
|
report_sql_composer_service_1.ReportSqlComposerService,
|
|
94
|
-
|
|
87
|
+
create_data_mart_service_1.CreateDataMartService,
|
|
88
|
+
update_data_mart_definition_service_1.UpdateDataMartDefinitionService,
|
|
95
89
|
access_decision_1.AccessDecisionService])
|
|
96
90
|
], CopyReportAsDataMartService);
|
|
97
91
|
//# sourceMappingURL=copy-report-as-data-mart.service.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owox/backend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0-next-20260515073306",
|
|
4
4
|
"description": "OWOX Data Marts Backend - Full-stack data orchestration platform",
|
|
5
5
|
"author": "OWOX",
|
|
6
6
|
"license": "ELv2",
|
|
@@ -78,9 +78,9 @@
|
|
|
78
78
|
"@nestjs/schedule": "^6.0.0",
|
|
79
79
|
"@nestjs/swagger": "^11.2.0",
|
|
80
80
|
"@nestjs/typeorm": "^11.0.0",
|
|
81
|
-
"@owox/connectors": "0.
|
|
82
|
-
"@owox/idp-protocol": "0.
|
|
83
|
-
"@owox/internal-helpers": "0.
|
|
81
|
+
"@owox/connectors": "0.26.0-next-20260515073306",
|
|
82
|
+
"@owox/idp-protocol": "0.26.0-next-20260515073306",
|
|
83
|
+
"@owox/internal-helpers": "0.26.0-next-20260515073306",
|
|
84
84
|
"better-sqlite3": "^12.2.0",
|
|
85
85
|
"class-transformer": "^0.5.1",
|
|
86
86
|
"class-validator": "^0.14.2",
|
|
@@ -139,7 +139,7 @@
|
|
|
139
139
|
"ts-node": "^10.9.2",
|
|
140
140
|
"tsconfig-paths": "^4.2.0",
|
|
141
141
|
"typeorm-ts-node-commonjs": "^0.3.20",
|
|
142
|
-
"@owox/test-utils": "
|
|
142
|
+
"@owox/test-utils": "5.0.0-next-20260515073306"
|
|
143
143
|
},
|
|
144
144
|
"jest": {
|
|
145
145
|
"moduleFileExtensions": [
|