@nest-yalc-2/omnikernel-module 2.2.2 → 2.2.4
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/package.json +17 -15
- package/src/__tests__/omni-collection.entity.spec.ts +49 -49
- package/src/__tests__/omni-collection.service.spec.ts +83 -83
- package/src/__tests__/omni-document.entity.spec.ts +55 -55
- package/src/__tests__/omni-document.service.spec.ts +83 -83
- package/src/__tests__/omni-extension-projection-constraints.spec.ts +518 -518
- package/src/__tests__/omni-extension-projection.registration.spec.ts +947 -946
- package/src/__tests__/omni-extension-projection.service.spec.ts +806 -806
- package/src/__tests__/omni-external-ref.entity.spec.ts +36 -36
- package/src/__tests__/omni-external-ref.service.spec.ts +252 -252
- package/src/__tests__/omni-named.entity.spec.ts +33 -33
- package/src/__tests__/omni-record.entity.spec.ts +32 -32
- package/src/__tests__/omni-record.service.spec.ts +107 -107
- package/src/__tests__/omni-relation-semantics.spec.ts +102 -102
- package/src/__tests__/omni-relation.entity.spec.ts +38 -38
- package/src/__tests__/omni-scope-substrate.spec.ts +81 -81
- package/src/__tests__/omni-scoped.backend.spec.ts +115 -115
- package/src/__tests__/omni-scoped.service.spec.ts +354 -354
- package/src/__tests__/omnikernel.diagnostics.spec.ts +94 -94
- package/src/__tests__/omnikernel.module.spec.ts +38 -40
- package/src/__tests__/omnikernel.persistence.spec.ts +154 -154
- package/src/__tests__/omnikernel.public-api.spec.ts +238 -238
- package/src/__tests__/omnikernel.query.service.spec.ts +155 -155
- package/src/base/omni-base.entity.ts +41 -41
- package/src/base/omni-external-ref.entity.ts +53 -53
- package/src/base/omni-named.entity.ts +16 -16
- package/src/base/omni-record.entity.ts +51 -51
- package/src/base/omni-relation.entity.ts +72 -72
- package/src/index.ts +49 -49
- package/src/omni-collection-kind.enum.ts +10 -10
- package/src/omni-collection.backend.ts +16 -16
- package/src/omni-collection.dto.ts +170 -170
- package/src/omni-collection.entity.ts +21 -21
- package/src/omni-collection.service.ts +75 -75
- package/src/omni-document-kind.enum.ts +12 -12
- package/src/omni-document.backend.ts +16 -16
- package/src/omni-document.dto.ts +198 -198
- package/src/omni-document.entity.ts +30 -30
- package/src/omni-document.service.ts +75 -75
- package/src/omni-dto.helpers.ts +21 -21
- package/src/omni-extension-projection.definition.ts +294 -294
- package/src/omni-extension-projection.resource.ts +274 -274
- package/src/omni-extension-projection.service.ts +452 -452
- package/src/omni-external-ref-binding.validator.ts +53 -53
- package/src/omni-external-ref-internal-type.enum.ts +11 -11
- package/src/omni-external-ref.backend.ts +25 -25
- package/src/omni-external-ref.dto.ts +128 -128
- package/src/omni-external-ref.service.ts +255 -255
- package/src/omni-migration.ts +365 -365
- package/src/omni-named.backend.ts +11 -11
- package/src/omni-named.dto.ts +86 -86
- package/src/omni-projection.catalog.ts +345 -345
- package/src/omni-projection.lifecycle.ts +53 -53
- package/src/omni-record-status.enum.ts +11 -11
- package/src/omni-record.backend.ts +19 -19
- package/src/omni-record.dto.ts +157 -157
- package/src/omni-record.service.ts +113 -113
- package/src/omni-relation-kind.contract.ts +49 -49
- package/src/omni-relation-kind.enum.ts +12 -12
- package/src/omni-relation-projection.definition.ts +166 -166
- package/src/omni-relation-projection.resource.ts +360 -360
- package/src/omni-relation-projection.service.ts +610 -610
- package/src/omni-relation-semantics.ts +52 -52
- package/src/omni-relation-status.enum.ts +11 -11
- package/src/omni-relation.backend.ts +21 -21
- package/src/omni-relation.dto.ts +142 -142
- package/src/omni-relation.service.ts +159 -159
- package/src/omni-scope.ts +161 -161
- package/src/omni-scoped.backend.ts +110 -110
- package/src/omni-scoped.repository.ts +34 -34
- package/src/omni-scoped.service.ts +338 -338
- package/src/omnikernel.diagnostics.ts +83 -83
- package/src/omnikernel.module.ts +97 -97
- package/src/omnikernel.query.service.ts +108 -108
|
@@ -1,255 +1,255 @@
|
|
|
1
|
-
import { ConflictException } from '@nestjs/common';
|
|
2
|
-
import type { CrudGenFindManyOptions } from '@nest-yalc-2/crud-gen/api-graphql/crud-gen-gql.interface.js';
|
|
3
|
-
import type { DeepPartial, FindOptionsWhere } from 'typeorm';
|
|
4
|
-
import { OmniExternalRefEntity } from './base/omni-external-ref.entity.js';
|
|
5
|
-
import { OmniExternalRefBindingValidator } from './omni-external-ref-binding.validator.js';
|
|
6
|
-
import { OmniExternalRefInternalType } from './omni-external-ref-internal-type.enum.js';
|
|
7
|
-
import { OmniScopedService } from './omni-scoped.service.js';
|
|
8
|
-
import type { OmniDeletePolicy, OmniScope } from './omni-scope.js';
|
|
9
|
-
|
|
10
|
-
function hasOwn(input: object, key: string): boolean {
|
|
11
|
-
return Object.prototype.hasOwnProperty.call(input, key);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface OmniExternalRefLookup {
|
|
15
|
-
provider: string;
|
|
16
|
-
externalId: string;
|
|
17
|
-
account?: string | null;
|
|
18
|
-
container?: string | null;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface OmniExternalRefSyncInput extends OmniExternalRefLookup {
|
|
22
|
-
payload?: Record<string, unknown> | null;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export type OmniExternalRefUpsertInput = Omit<
|
|
26
|
-
DeepPartial<OmniExternalRefEntity>,
|
|
27
|
-
'provider' | 'externalId' | 'internalType' | 'internalId'
|
|
28
|
-
> &
|
|
29
|
-
Pick<
|
|
30
|
-
OmniExternalRefEntity,
|
|
31
|
-
'provider' | 'externalId' | 'internalType' | 'internalId'
|
|
32
|
-
>;
|
|
33
|
-
|
|
34
|
-
export class OmniExternalRefService extends OmniScopedService<OmniExternalRefEntity> {
|
|
35
|
-
constructor(
|
|
36
|
-
repository: any,
|
|
37
|
-
scopeOrRepositoryWrite: OmniScope | any | undefined,
|
|
38
|
-
deletion: OmniDeletePolicy,
|
|
39
|
-
private readonly bindingValidator: OmniExternalRefBindingValidator,
|
|
40
|
-
) {
|
|
41
|
-
if (!bindingValidator) {
|
|
42
|
-
throw new TypeError(
|
|
43
|
-
'OmniExternalRefService requires an OmniExternalRefBindingValidator.',
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
super(repository, scopeOrRepositoryWrite, deletion);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async findByExternalIdentity({
|
|
50
|
-
provider,
|
|
51
|
-
externalId,
|
|
52
|
-
account = null,
|
|
53
|
-
container = null,
|
|
54
|
-
}: OmniExternalRefLookup): Promise<OmniExternalRefEntity | null> {
|
|
55
|
-
return this.getRepository().findOne({
|
|
56
|
-
where: {
|
|
57
|
-
scopeId: this.scopeId,
|
|
58
|
-
provider,
|
|
59
|
-
externalId,
|
|
60
|
-
account: account ?? '',
|
|
61
|
-
container: container ?? '',
|
|
62
|
-
},
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async findForInternalRecord(
|
|
67
|
-
internalType: OmniExternalRefInternalType,
|
|
68
|
-
internalId: string,
|
|
69
|
-
provider?: string,
|
|
70
|
-
): Promise<OmniExternalRefEntity[]> {
|
|
71
|
-
return this.getRepository().find({
|
|
72
|
-
where: {
|
|
73
|
-
scopeId: this.scopeId,
|
|
74
|
-
internalType,
|
|
75
|
-
internalId,
|
|
76
|
-
...(provider ? { provider } : {}),
|
|
77
|
-
},
|
|
78
|
-
order: {
|
|
79
|
-
createdAt: 'ASC',
|
|
80
|
-
},
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async upsertExternalRef(
|
|
85
|
-
input: OmniExternalRefUpsertInput,
|
|
86
|
-
): Promise<OmniExternalRefEntity> {
|
|
87
|
-
if (input.provider.trim().length === 0) {
|
|
88
|
-
throw new Error('OmniExternalRef.provider is required');
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (input.externalId.trim().length === 0) {
|
|
92
|
-
throw new Error('OmniExternalRef.externalId is required');
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const existing = await this.findByExternalIdentity({
|
|
96
|
-
provider: input.provider,
|
|
97
|
-
externalId: input.externalId,
|
|
98
|
-
account: input.account ?? null,
|
|
99
|
-
container: input.container ?? null,
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
if (existing) {
|
|
103
|
-
if (
|
|
104
|
-
existing.internalType !== input.internalType ||
|
|
105
|
-
existing.internalId !== input.internalId
|
|
106
|
-
) {
|
|
107
|
-
throw new ConflictException(
|
|
108
|
-
'External reference binding is immutable after creation.',
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
const {
|
|
112
|
-
internalType: _internalType,
|
|
113
|
-
internalId: _internalId,
|
|
114
|
-
...update
|
|
115
|
-
} = this.normalizeExternalIdentity(input);
|
|
116
|
-
return this.updateEntity(
|
|
117
|
-
{ guid: existing.guid },
|
|
118
|
-
update,
|
|
119
|
-
) as Promise<OmniExternalRefEntity>;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return this.createEntity(
|
|
123
|
-
this.normalizeExternalIdentity(input),
|
|
124
|
-
) as Promise<OmniExternalRefEntity>;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
async syncDocumentReference(
|
|
128
|
-
internalId: string,
|
|
129
|
-
input: OmniExternalRefSyncInput,
|
|
130
|
-
): Promise<OmniExternalRefEntity> {
|
|
131
|
-
return this.upsertExternalRef({
|
|
132
|
-
...input,
|
|
133
|
-
internalType: OmniExternalRefInternalType.Document,
|
|
134
|
-
internalId,
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
async syncCollectionReference(
|
|
139
|
-
internalId: string,
|
|
140
|
-
input: OmniExternalRefSyncInput,
|
|
141
|
-
): Promise<OmniExternalRefEntity> {
|
|
142
|
-
return this.upsertExternalRef({
|
|
143
|
-
...input,
|
|
144
|
-
internalType: OmniExternalRefInternalType.Collection,
|
|
145
|
-
internalId,
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
override async createEntity(
|
|
150
|
-
input: DeepPartial<OmniExternalRefEntity>,
|
|
151
|
-
findOptions?: CrudGenFindManyOptions<OmniExternalRefEntity>,
|
|
152
|
-
returnEntity?: true,
|
|
153
|
-
): Promise<OmniExternalRefEntity>;
|
|
154
|
-
override async createEntity(
|
|
155
|
-
input: DeepPartial<OmniExternalRefEntity>,
|
|
156
|
-
findOptions?: CrudGenFindManyOptions<OmniExternalRefEntity>,
|
|
157
|
-
returnEntity?: boolean,
|
|
158
|
-
): Promise<OmniExternalRefEntity | boolean>;
|
|
159
|
-
override async createEntity(
|
|
160
|
-
input: DeepPartial<OmniExternalRefEntity>,
|
|
161
|
-
findOptions?: CrudGenFindManyOptions<OmniExternalRefEntity>,
|
|
162
|
-
returnEntity = true,
|
|
163
|
-
): Promise<OmniExternalRefEntity | boolean> {
|
|
164
|
-
const normalized = this.normalizeExternalIdentity(input);
|
|
165
|
-
this.rejectServerFields(normalized as object);
|
|
166
|
-
await this.assertBinding(normalized);
|
|
167
|
-
if (
|
|
168
|
-
typeof normalized.provider === 'string' &&
|
|
169
|
-
typeof normalized.externalId === 'string'
|
|
170
|
-
) {
|
|
171
|
-
const existing = await this.findByExternalIdentity({
|
|
172
|
-
provider: normalized.provider,
|
|
173
|
-
externalId: normalized.externalId,
|
|
174
|
-
account: normalized.account ?? null,
|
|
175
|
-
container: normalized.container ?? null,
|
|
176
|
-
});
|
|
177
|
-
if (existing) {
|
|
178
|
-
throw new ConflictException(
|
|
179
|
-
'External reference identity already exists in this scope.',
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
return super.createEntity(normalized, findOptions, returnEntity);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
override async updateEntity(
|
|
187
|
-
conditions: FindOptionsWhere<OmniExternalRefEntity>,
|
|
188
|
-
input: DeepPartial<OmniExternalRefEntity>,
|
|
189
|
-
findOptions?: CrudGenFindManyOptions<OmniExternalRefEntity>,
|
|
190
|
-
returnEntity?: true,
|
|
191
|
-
): Promise<OmniExternalRefEntity>;
|
|
192
|
-
override async updateEntity(
|
|
193
|
-
conditions: FindOptionsWhere<OmniExternalRefEntity>,
|
|
194
|
-
input: DeepPartial<OmniExternalRefEntity>,
|
|
195
|
-
findOptions?: CrudGenFindManyOptions<OmniExternalRefEntity>,
|
|
196
|
-
returnEntity?: boolean,
|
|
197
|
-
): Promise<OmniExternalRefEntity | boolean>;
|
|
198
|
-
override async updateEntity(
|
|
199
|
-
conditions: FindOptionsWhere<OmniExternalRefEntity>,
|
|
200
|
-
input: DeepPartial<OmniExternalRefEntity>,
|
|
201
|
-
findOptions?: CrudGenFindManyOptions<OmniExternalRefEntity>,
|
|
202
|
-
returnEntity = true,
|
|
203
|
-
): Promise<OmniExternalRefEntity | boolean> {
|
|
204
|
-
const normalized = this.normalizeExternalIdentity(input);
|
|
205
|
-
this.rejectBindingMutation(normalized as object);
|
|
206
|
-
return super.updateEntity(
|
|
207
|
-
conditions,
|
|
208
|
-
normalized,
|
|
209
|
-
findOptions,
|
|
210
|
-
returnEntity,
|
|
211
|
-
);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
private async assertBinding(
|
|
215
|
-
input: DeepPartial<OmniExternalRefEntity>,
|
|
216
|
-
): Promise<void> {
|
|
217
|
-
if (
|
|
218
|
-
typeof input.internalId !== 'string' ||
|
|
219
|
-
input.internalType === undefined
|
|
220
|
-
) {
|
|
221
|
-
throw new ConflictException(
|
|
222
|
-
'External reference binding requires internalType and internalId.',
|
|
223
|
-
);
|
|
224
|
-
}
|
|
225
|
-
if (input.internalType !== OmniExternalRefInternalType.Record) {
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
await this.bindingValidator.assertTarget({
|
|
229
|
-
internalId: input.internalId,
|
|
230
|
-
internalType: input.internalType,
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
private rejectBindingMutation(input: object): void {
|
|
235
|
-
if (hasOwn(input, 'internalType') || hasOwn(input, 'internalId')) {
|
|
236
|
-
throw new ConflictException(
|
|
237
|
-
'External reference binding is immutable after creation.',
|
|
238
|
-
);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
private normalizeExternalIdentity<
|
|
243
|
-
T extends DeepPartial<OmniExternalRefEntity>,
|
|
244
|
-
>(input: T): T {
|
|
245
|
-
return {
|
|
246
|
-
...input,
|
|
247
|
-
...(Object.prototype.hasOwnProperty.call(input, 'account')
|
|
248
|
-
? { account: input.account ?? '' }
|
|
249
|
-
: {}),
|
|
250
|
-
...(Object.prototype.hasOwnProperty.call(input, 'container')
|
|
251
|
-
? { container: input.container ?? '' }
|
|
252
|
-
: {}),
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
}
|
|
1
|
+
import { ConflictException } from '@nestjs/common';
|
|
2
|
+
import type { CrudGenFindManyOptions } from '@nest-yalc-2/crud-gen/api-graphql/crud-gen-gql.interface.js';
|
|
3
|
+
import type { DeepPartial, FindOptionsWhere } from 'typeorm';
|
|
4
|
+
import { OmniExternalRefEntity } from './base/omni-external-ref.entity.js';
|
|
5
|
+
import { OmniExternalRefBindingValidator } from './omni-external-ref-binding.validator.js';
|
|
6
|
+
import { OmniExternalRefInternalType } from './omni-external-ref-internal-type.enum.js';
|
|
7
|
+
import { OmniScopedService } from './omni-scoped.service.js';
|
|
8
|
+
import type { OmniDeletePolicy, OmniScope } from './omni-scope.js';
|
|
9
|
+
|
|
10
|
+
function hasOwn(input: object, key: string): boolean {
|
|
11
|
+
return Object.prototype.hasOwnProperty.call(input, key);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface OmniExternalRefLookup {
|
|
15
|
+
provider: string;
|
|
16
|
+
externalId: string;
|
|
17
|
+
account?: string | null;
|
|
18
|
+
container?: string | null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface OmniExternalRefSyncInput extends OmniExternalRefLookup {
|
|
22
|
+
payload?: Record<string, unknown> | null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type OmniExternalRefUpsertInput = Omit<
|
|
26
|
+
DeepPartial<OmniExternalRefEntity>,
|
|
27
|
+
'provider' | 'externalId' | 'internalType' | 'internalId'
|
|
28
|
+
> &
|
|
29
|
+
Pick<
|
|
30
|
+
OmniExternalRefEntity,
|
|
31
|
+
'provider' | 'externalId' | 'internalType' | 'internalId'
|
|
32
|
+
>;
|
|
33
|
+
|
|
34
|
+
export class OmniExternalRefService extends OmniScopedService<OmniExternalRefEntity> {
|
|
35
|
+
constructor(
|
|
36
|
+
repository: any,
|
|
37
|
+
scopeOrRepositoryWrite: OmniScope | any | undefined,
|
|
38
|
+
deletion: OmniDeletePolicy,
|
|
39
|
+
private readonly bindingValidator: OmniExternalRefBindingValidator,
|
|
40
|
+
) {
|
|
41
|
+
if (!bindingValidator) {
|
|
42
|
+
throw new TypeError(
|
|
43
|
+
'OmniExternalRefService requires an OmniExternalRefBindingValidator.',
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
super(repository, scopeOrRepositoryWrite, deletion);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async findByExternalIdentity({
|
|
50
|
+
provider,
|
|
51
|
+
externalId,
|
|
52
|
+
account = null,
|
|
53
|
+
container = null,
|
|
54
|
+
}: OmniExternalRefLookup): Promise<OmniExternalRefEntity | null> {
|
|
55
|
+
return this.getRepository().findOne({
|
|
56
|
+
where: {
|
|
57
|
+
scopeId: this.scopeId,
|
|
58
|
+
provider,
|
|
59
|
+
externalId,
|
|
60
|
+
account: account ?? '',
|
|
61
|
+
container: container ?? '',
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async findForInternalRecord(
|
|
67
|
+
internalType: OmniExternalRefInternalType,
|
|
68
|
+
internalId: string,
|
|
69
|
+
provider?: string,
|
|
70
|
+
): Promise<OmniExternalRefEntity[]> {
|
|
71
|
+
return this.getRepository().find({
|
|
72
|
+
where: {
|
|
73
|
+
scopeId: this.scopeId,
|
|
74
|
+
internalType,
|
|
75
|
+
internalId,
|
|
76
|
+
...(provider ? { provider } : {}),
|
|
77
|
+
},
|
|
78
|
+
order: {
|
|
79
|
+
createdAt: 'ASC',
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async upsertExternalRef(
|
|
85
|
+
input: OmniExternalRefUpsertInput,
|
|
86
|
+
): Promise<OmniExternalRefEntity> {
|
|
87
|
+
if (input.provider.trim().length === 0) {
|
|
88
|
+
throw new Error('OmniExternalRef.provider is required');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (input.externalId.trim().length === 0) {
|
|
92
|
+
throw new Error('OmniExternalRef.externalId is required');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const existing = await this.findByExternalIdentity({
|
|
96
|
+
provider: input.provider,
|
|
97
|
+
externalId: input.externalId,
|
|
98
|
+
account: input.account ?? null,
|
|
99
|
+
container: input.container ?? null,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
if (existing) {
|
|
103
|
+
if (
|
|
104
|
+
existing.internalType !== input.internalType ||
|
|
105
|
+
existing.internalId !== input.internalId
|
|
106
|
+
) {
|
|
107
|
+
throw new ConflictException(
|
|
108
|
+
'External reference binding is immutable after creation.',
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
const {
|
|
112
|
+
internalType: _internalType,
|
|
113
|
+
internalId: _internalId,
|
|
114
|
+
...update
|
|
115
|
+
} = this.normalizeExternalIdentity(input);
|
|
116
|
+
return this.updateEntity(
|
|
117
|
+
{ guid: existing.guid },
|
|
118
|
+
update,
|
|
119
|
+
) as Promise<OmniExternalRefEntity>;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return this.createEntity(
|
|
123
|
+
this.normalizeExternalIdentity(input),
|
|
124
|
+
) as Promise<OmniExternalRefEntity>;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async syncDocumentReference(
|
|
128
|
+
internalId: string,
|
|
129
|
+
input: OmniExternalRefSyncInput,
|
|
130
|
+
): Promise<OmniExternalRefEntity> {
|
|
131
|
+
return this.upsertExternalRef({
|
|
132
|
+
...input,
|
|
133
|
+
internalType: OmniExternalRefInternalType.Document,
|
|
134
|
+
internalId,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async syncCollectionReference(
|
|
139
|
+
internalId: string,
|
|
140
|
+
input: OmniExternalRefSyncInput,
|
|
141
|
+
): Promise<OmniExternalRefEntity> {
|
|
142
|
+
return this.upsertExternalRef({
|
|
143
|
+
...input,
|
|
144
|
+
internalType: OmniExternalRefInternalType.Collection,
|
|
145
|
+
internalId,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
override async createEntity(
|
|
150
|
+
input: DeepPartial<OmniExternalRefEntity>,
|
|
151
|
+
findOptions?: CrudGenFindManyOptions<OmniExternalRefEntity>,
|
|
152
|
+
returnEntity?: true,
|
|
153
|
+
): Promise<OmniExternalRefEntity>;
|
|
154
|
+
override async createEntity(
|
|
155
|
+
input: DeepPartial<OmniExternalRefEntity>,
|
|
156
|
+
findOptions?: CrudGenFindManyOptions<OmniExternalRefEntity>,
|
|
157
|
+
returnEntity?: boolean,
|
|
158
|
+
): Promise<OmniExternalRefEntity | boolean>;
|
|
159
|
+
override async createEntity(
|
|
160
|
+
input: DeepPartial<OmniExternalRefEntity>,
|
|
161
|
+
findOptions?: CrudGenFindManyOptions<OmniExternalRefEntity>,
|
|
162
|
+
returnEntity = true,
|
|
163
|
+
): Promise<OmniExternalRefEntity | boolean> {
|
|
164
|
+
const normalized = this.normalizeExternalIdentity(input);
|
|
165
|
+
this.rejectServerFields(normalized as object);
|
|
166
|
+
await this.assertBinding(normalized);
|
|
167
|
+
if (
|
|
168
|
+
typeof normalized.provider === 'string' &&
|
|
169
|
+
typeof normalized.externalId === 'string'
|
|
170
|
+
) {
|
|
171
|
+
const existing = await this.findByExternalIdentity({
|
|
172
|
+
provider: normalized.provider,
|
|
173
|
+
externalId: normalized.externalId,
|
|
174
|
+
account: normalized.account ?? null,
|
|
175
|
+
container: normalized.container ?? null,
|
|
176
|
+
});
|
|
177
|
+
if (existing) {
|
|
178
|
+
throw new ConflictException(
|
|
179
|
+
'External reference identity already exists in this scope.',
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return super.createEntity(normalized, findOptions, returnEntity);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
override async updateEntity(
|
|
187
|
+
conditions: FindOptionsWhere<OmniExternalRefEntity>,
|
|
188
|
+
input: DeepPartial<OmniExternalRefEntity>,
|
|
189
|
+
findOptions?: CrudGenFindManyOptions<OmniExternalRefEntity>,
|
|
190
|
+
returnEntity?: true,
|
|
191
|
+
): Promise<OmniExternalRefEntity>;
|
|
192
|
+
override async updateEntity(
|
|
193
|
+
conditions: FindOptionsWhere<OmniExternalRefEntity>,
|
|
194
|
+
input: DeepPartial<OmniExternalRefEntity>,
|
|
195
|
+
findOptions?: CrudGenFindManyOptions<OmniExternalRefEntity>,
|
|
196
|
+
returnEntity?: boolean,
|
|
197
|
+
): Promise<OmniExternalRefEntity | boolean>;
|
|
198
|
+
override async updateEntity(
|
|
199
|
+
conditions: FindOptionsWhere<OmniExternalRefEntity>,
|
|
200
|
+
input: DeepPartial<OmniExternalRefEntity>,
|
|
201
|
+
findOptions?: CrudGenFindManyOptions<OmniExternalRefEntity>,
|
|
202
|
+
returnEntity = true,
|
|
203
|
+
): Promise<OmniExternalRefEntity | boolean> {
|
|
204
|
+
const normalized = this.normalizeExternalIdentity(input);
|
|
205
|
+
this.rejectBindingMutation(normalized as object);
|
|
206
|
+
return super.updateEntity(
|
|
207
|
+
conditions,
|
|
208
|
+
normalized,
|
|
209
|
+
findOptions,
|
|
210
|
+
returnEntity,
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
private async assertBinding(
|
|
215
|
+
input: DeepPartial<OmniExternalRefEntity>,
|
|
216
|
+
): Promise<void> {
|
|
217
|
+
if (
|
|
218
|
+
typeof input.internalId !== 'string' ||
|
|
219
|
+
input.internalType === undefined
|
|
220
|
+
) {
|
|
221
|
+
throw new ConflictException(
|
|
222
|
+
'External reference binding requires internalType and internalId.',
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
if (input.internalType !== OmniExternalRefInternalType.Record) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
await this.bindingValidator.assertTarget({
|
|
229
|
+
internalId: input.internalId,
|
|
230
|
+
internalType: input.internalType,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
private rejectBindingMutation(input: object): void {
|
|
235
|
+
if (hasOwn(input, 'internalType') || hasOwn(input, 'internalId')) {
|
|
236
|
+
throw new ConflictException(
|
|
237
|
+
'External reference binding is immutable after creation.',
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
private normalizeExternalIdentity<
|
|
243
|
+
T extends DeepPartial<OmniExternalRefEntity>,
|
|
244
|
+
>(input: T): T {
|
|
245
|
+
return {
|
|
246
|
+
...input,
|
|
247
|
+
...(Object.prototype.hasOwnProperty.call(input, 'account')
|
|
248
|
+
? { account: input.account ?? '' }
|
|
249
|
+
: {}),
|
|
250
|
+
...(Object.prototype.hasOwnProperty.call(input, 'container')
|
|
251
|
+
? { container: input.container ?? '' }
|
|
252
|
+
: {}),
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
}
|