@nest-yalc-2/omnikernel-module 2.2.2 → 2.2.6
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,36 +1,36 @@
|
|
|
1
|
-
import { describe, expect, it } from '@jest/globals';
|
|
2
|
-
import { getMetadataArgsStorage } from 'typeorm';
|
|
3
|
-
|
|
4
|
-
import { OmniBaseEntity } from '../base/omni-base.entity.js';
|
|
5
|
-
import {
|
|
6
|
-
OmniExternalRefEntity,
|
|
7
|
-
} from '../base/omni-external-ref.entity.js';
|
|
8
|
-
|
|
9
|
-
describe('OmniExternalRefEntity', () => {
|
|
10
|
-
it('extends OmniBaseEntity', () => {
|
|
11
|
-
expect(new OmniExternalRefEntity()).toBeInstanceOf(OmniBaseEntity);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it('registers external mapping columns', () => {
|
|
15
|
-
const metadata = getMetadataArgsStorage();
|
|
16
|
-
const table = metadata.tables.find(
|
|
17
|
-
(item) => item.target === OmniExternalRefEntity,
|
|
18
|
-
);
|
|
19
|
-
const entityColumns = metadata.columns
|
|
20
|
-
.filter((item) => item.target === OmniExternalRefEntity)
|
|
21
|
-
.map((item) => item.propertyName);
|
|
22
|
-
|
|
23
|
-
expect(table?.name).toBe('omni-external-ref');
|
|
24
|
-
expect(entityColumns).toEqual(
|
|
25
|
-
expect.arrayContaining([
|
|
26
|
-
'internalType',
|
|
27
|
-
'internalId',
|
|
28
|
-
'provider',
|
|
29
|
-
'account',
|
|
30
|
-
'container',
|
|
31
|
-
'externalId',
|
|
32
|
-
'payload',
|
|
33
|
-
]),
|
|
34
|
-
);
|
|
35
|
-
});
|
|
36
|
-
});
|
|
1
|
+
import { describe, expect, it } from '@jest/globals';
|
|
2
|
+
import { getMetadataArgsStorage } from 'typeorm';
|
|
3
|
+
|
|
4
|
+
import { OmniBaseEntity } from '../base/omni-base.entity.js';
|
|
5
|
+
import {
|
|
6
|
+
OmniExternalRefEntity,
|
|
7
|
+
} from '../base/omni-external-ref.entity.js';
|
|
8
|
+
|
|
9
|
+
describe('OmniExternalRefEntity', () => {
|
|
10
|
+
it('extends OmniBaseEntity', () => {
|
|
11
|
+
expect(new OmniExternalRefEntity()).toBeInstanceOf(OmniBaseEntity);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('registers external mapping columns', () => {
|
|
15
|
+
const metadata = getMetadataArgsStorage();
|
|
16
|
+
const table = metadata.tables.find(
|
|
17
|
+
(item) => item.target === OmniExternalRefEntity,
|
|
18
|
+
);
|
|
19
|
+
const entityColumns = metadata.columns
|
|
20
|
+
.filter((item) => item.target === OmniExternalRefEntity)
|
|
21
|
+
.map((item) => item.propertyName);
|
|
22
|
+
|
|
23
|
+
expect(table?.name).toBe('omni-external-ref');
|
|
24
|
+
expect(entityColumns).toEqual(
|
|
25
|
+
expect.arrayContaining([
|
|
26
|
+
'internalType',
|
|
27
|
+
'internalId',
|
|
28
|
+
'provider',
|
|
29
|
+
'account',
|
|
30
|
+
'container',
|
|
31
|
+
'externalId',
|
|
32
|
+
'payload',
|
|
33
|
+
]),
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -1,252 +1,252 @@
|
|
|
1
|
-
import { describe, expect, it, jest } from "@jest/globals";
|
|
2
|
-
|
|
3
|
-
import { OmniExternalRefService } from '../omni-external-ref.service.js';
|
|
4
|
-
import { OmniExternalRefEntity } from '../base/omni-external-ref.entity.js';
|
|
5
|
-
import { OmniExternalRefInternalType } from '../omni-external-ref-internal-type.enum.js';
|
|
6
|
-
|
|
7
|
-
const bindingValidator = {
|
|
8
|
-
assertTarget: jest.fn(async () => ({})),
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
const createRepositoryPair = () => {
|
|
12
|
-
const readRepository = {
|
|
13
|
-
target: OmniExternalRefEntity,
|
|
14
|
-
findOne: jest.fn(),
|
|
15
|
-
find: jest.fn(),
|
|
16
|
-
findOneOrFail: jest.fn(),
|
|
17
|
-
getId: jest.fn((entity: OmniExternalRefEntity) => ({ guid: entity.guid })),
|
|
18
|
-
};
|
|
19
|
-
const writeRepository = {
|
|
20
|
-
target: OmniExternalRefEntity,
|
|
21
|
-
create: jest.fn((input: unknown) => input),
|
|
22
|
-
insert: jest.fn(async () => ({
|
|
23
|
-
identifiers: [{ guid: "eeeeeeee-1111-1111-1111-111111111111" }],
|
|
24
|
-
})),
|
|
25
|
-
update: jest.fn(async () => ({ affected: 1 })),
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
return { readRepository, writeRepository };
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
describe("OmniExternalRefService", () => {
|
|
32
|
-
it('requires a binding validator instead of silently bypassing target validation', () => {
|
|
33
|
-
const { readRepository, writeRepository } = createRepositoryPair();
|
|
34
|
-
|
|
35
|
-
expect(
|
|
36
|
-
() =>
|
|
37
|
-
new OmniExternalRefService(
|
|
38
|
-
readRepository as never,
|
|
39
|
-
writeRepository as never,
|
|
40
|
-
'hard',
|
|
41
|
-
undefined as never,
|
|
42
|
-
),
|
|
43
|
-
).toThrow('requires an OmniExternalRefBindingValidator');
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it("looks up references by provider/external identity", async () => {
|
|
47
|
-
const { readRepository, writeRepository } = createRepositoryPair();
|
|
48
|
-
const service = new OmniExternalRefService(
|
|
49
|
-
readRepository as never,
|
|
50
|
-
writeRepository as never,
|
|
51
|
-
'hard',
|
|
52
|
-
bindingValidator as never,
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
await service.findByExternalIdentity({
|
|
56
|
-
provider: "github",
|
|
57
|
-
externalId: "123",
|
|
58
|
-
account: "acme",
|
|
59
|
-
container: "kb",
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
expect(readRepository.findOne).toHaveBeenCalledWith({
|
|
63
|
-
where: {
|
|
64
|
-
scopeId: "default",
|
|
65
|
-
provider: "github",
|
|
66
|
-
externalId: "123",
|
|
67
|
-
account: "acme",
|
|
68
|
-
container: "kb",
|
|
69
|
-
},
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it("returns all references for an internal record", async () => {
|
|
74
|
-
const { readRepository, writeRepository } = createRepositoryPair();
|
|
75
|
-
const service = new OmniExternalRefService(
|
|
76
|
-
readRepository as never,
|
|
77
|
-
writeRepository as never,
|
|
78
|
-
'hard',
|
|
79
|
-
bindingValidator as never,
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
await service.findForInternalRecord(
|
|
83
|
-
OmniExternalRefInternalType.Document,
|
|
84
|
-
"doc-1",
|
|
85
|
-
"github",
|
|
86
|
-
);
|
|
87
|
-
|
|
88
|
-
expect(readRepository.find).toHaveBeenCalledWith({
|
|
89
|
-
where: {
|
|
90
|
-
scopeId: "default",
|
|
91
|
-
internalType: OmniExternalRefInternalType.Document,
|
|
92
|
-
internalId: "doc-1",
|
|
93
|
-
provider: "github",
|
|
94
|
-
},
|
|
95
|
-
order: {
|
|
96
|
-
createdAt: "ASC",
|
|
97
|
-
},
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it("creates a new external ref when the identity does not exist", async () => {
|
|
102
|
-
const { readRepository, writeRepository } = createRepositoryPair();
|
|
103
|
-
readRepository.findOne.mockResolvedValue(null);
|
|
104
|
-
const service = new OmniExternalRefService(
|
|
105
|
-
readRepository as never,
|
|
106
|
-
writeRepository as never,
|
|
107
|
-
'hard',
|
|
108
|
-
bindingValidator as never,
|
|
109
|
-
);
|
|
110
|
-
const createSpy = jest
|
|
111
|
-
.spyOn(service, "createEntity")
|
|
112
|
-
.mockResolvedValue({ guid: "created" } as OmniExternalRefEntity);
|
|
113
|
-
|
|
114
|
-
const result = await service.upsertExternalRef({
|
|
115
|
-
internalType: OmniExternalRefInternalType.Document,
|
|
116
|
-
internalId: "doc-1",
|
|
117
|
-
provider: "github",
|
|
118
|
-
externalId: "123",
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
expect(createSpy).toHaveBeenCalledWith(
|
|
122
|
-
expect.objectContaining({
|
|
123
|
-
internalType: OmniExternalRefInternalType.Document,
|
|
124
|
-
internalId: "doc-1",
|
|
125
|
-
}),
|
|
126
|
-
);
|
|
127
|
-
expect(result.guid).toBe("created");
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
it("validates record bindings without changing legacy non-record bindings", async () => {
|
|
131
|
-
const { readRepository, writeRepository } = createRepositoryPair();
|
|
132
|
-
readRepository.findOne.mockResolvedValue(null);
|
|
133
|
-
const validator = {
|
|
134
|
-
assertTarget: jest.fn(async () => ({})),
|
|
135
|
-
};
|
|
136
|
-
const service = new OmniExternalRefService(
|
|
137
|
-
readRepository as never,
|
|
138
|
-
writeRepository as never,
|
|
139
|
-
"hard",
|
|
140
|
-
validator as never,
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
await service.createEntity({
|
|
144
|
-
guid: "eeeeeeee-1111-1111-1111-111111111112",
|
|
145
|
-
provider: "example",
|
|
146
|
-
externalId: "record",
|
|
147
|
-
internalType: OmniExternalRefInternalType.Record,
|
|
148
|
-
internalId: "aaaaaaaa-1111-1111-1111-111111111111",
|
|
149
|
-
});
|
|
150
|
-
expect(validator.assertTarget).toHaveBeenCalledWith({
|
|
151
|
-
internalType: OmniExternalRefInternalType.Record,
|
|
152
|
-
internalId: "aaaaaaaa-1111-1111-1111-111111111111",
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
await service.createEntity({
|
|
156
|
-
guid: "eeeeeeee-1111-1111-1111-111111111113",
|
|
157
|
-
provider: "example",
|
|
158
|
-
externalId: "legacy-document",
|
|
159
|
-
internalType: OmniExternalRefInternalType.Document,
|
|
160
|
-
internalId: "aaaaaaaa-1111-1111-1111-111111111112",
|
|
161
|
-
});
|
|
162
|
-
expect(validator.assertTarget).toHaveBeenCalledTimes(1);
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
it("updates an existing external ref when the identity already exists", async () => {
|
|
166
|
-
const { readRepository, writeRepository } = createRepositoryPair();
|
|
167
|
-
readRepository.findOne.mockResolvedValue({
|
|
168
|
-
guid: "existing-guid",
|
|
169
|
-
internalType: OmniExternalRefInternalType.Document,
|
|
170
|
-
internalId: "doc-1",
|
|
171
|
-
});
|
|
172
|
-
const service = new OmniExternalRefService(
|
|
173
|
-
readRepository as never,
|
|
174
|
-
writeRepository as never,
|
|
175
|
-
'hard',
|
|
176
|
-
bindingValidator as never,
|
|
177
|
-
);
|
|
178
|
-
const updateSpy = jest
|
|
179
|
-
.spyOn(service, "updateEntity")
|
|
180
|
-
.mockResolvedValue({ guid: "existing-guid" } as OmniExternalRefEntity);
|
|
181
|
-
|
|
182
|
-
const result = await service.upsertExternalRef({
|
|
183
|
-
internalType: OmniExternalRefInternalType.Document,
|
|
184
|
-
internalId: "doc-1",
|
|
185
|
-
provider: "github",
|
|
186
|
-
externalId: "123",
|
|
187
|
-
payload: { synced: true },
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
expect(updateSpy).toHaveBeenCalledWith(
|
|
191
|
-
{ guid: "existing-guid" },
|
|
192
|
-
expect.objectContaining({
|
|
193
|
-
payload: { synced: true },
|
|
194
|
-
}),
|
|
195
|
-
);
|
|
196
|
-
expect(result.guid).toBe("existing-guid");
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
it("rejects blank provider or external identity during upsert", async () => {
|
|
200
|
-
const { readRepository, writeRepository } = createRepositoryPair();
|
|
201
|
-
const service = new OmniExternalRefService(
|
|
202
|
-
readRepository as never,
|
|
203
|
-
writeRepository as never,
|
|
204
|
-
'hard',
|
|
205
|
-
bindingValidator as never,
|
|
206
|
-
);
|
|
207
|
-
|
|
208
|
-
await expect(
|
|
209
|
-
service.upsertExternalRef({
|
|
210
|
-
internalType: OmniExternalRefInternalType.Document,
|
|
211
|
-
internalId: "doc-1",
|
|
212
|
-
provider: "",
|
|
213
|
-
externalId: "123",
|
|
214
|
-
}),
|
|
215
|
-
).rejects.toThrow("OmniExternalRef.provider is required");
|
|
216
|
-
|
|
217
|
-
await expect(
|
|
218
|
-
service.upsertExternalRef({
|
|
219
|
-
internalType: OmniExternalRefInternalType.Document,
|
|
220
|
-
internalId: "doc-1",
|
|
221
|
-
provider: "github",
|
|
222
|
-
externalId: " ",
|
|
223
|
-
}),
|
|
224
|
-
).rejects.toThrow("OmniExternalRef.externalId is required");
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
it("syncs document references with the document internal type", async () => {
|
|
228
|
-
const { readRepository, writeRepository } = createRepositoryPair();
|
|
229
|
-
const service = new OmniExternalRefService(
|
|
230
|
-
readRepository as never,
|
|
231
|
-
writeRepository as never,
|
|
232
|
-
'hard',
|
|
233
|
-
bindingValidator as never,
|
|
234
|
-
);
|
|
235
|
-
const upsertSpy = jest
|
|
236
|
-
.spyOn(service, "upsertExternalRef")
|
|
237
|
-
.mockResolvedValue({ guid: "doc-ref" } as OmniExternalRefEntity);
|
|
238
|
-
|
|
239
|
-
await service.syncDocumentReference("doc-1", {
|
|
240
|
-
provider: "github",
|
|
241
|
-
externalId: "123",
|
|
242
|
-
account: "acme",
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
expect(upsertSpy).toHaveBeenCalledWith(
|
|
246
|
-
expect.objectContaining({
|
|
247
|
-
internalType: OmniExternalRefInternalType.Document,
|
|
248
|
-
internalId: "doc-1",
|
|
249
|
-
}),
|
|
250
|
-
);
|
|
251
|
-
});
|
|
252
|
-
});
|
|
1
|
+
import { describe, expect, it, jest } from "@jest/globals";
|
|
2
|
+
|
|
3
|
+
import { OmniExternalRefService } from '../omni-external-ref.service.js';
|
|
4
|
+
import { OmniExternalRefEntity } from '../base/omni-external-ref.entity.js';
|
|
5
|
+
import { OmniExternalRefInternalType } from '../omni-external-ref-internal-type.enum.js';
|
|
6
|
+
|
|
7
|
+
const bindingValidator = {
|
|
8
|
+
assertTarget: jest.fn(async () => ({})),
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const createRepositoryPair = () => {
|
|
12
|
+
const readRepository = {
|
|
13
|
+
target: OmniExternalRefEntity,
|
|
14
|
+
findOne: jest.fn(),
|
|
15
|
+
find: jest.fn(),
|
|
16
|
+
findOneOrFail: jest.fn(),
|
|
17
|
+
getId: jest.fn((entity: OmniExternalRefEntity) => ({ guid: entity.guid })),
|
|
18
|
+
};
|
|
19
|
+
const writeRepository = {
|
|
20
|
+
target: OmniExternalRefEntity,
|
|
21
|
+
create: jest.fn((input: unknown) => input),
|
|
22
|
+
insert: jest.fn(async () => ({
|
|
23
|
+
identifiers: [{ guid: "eeeeeeee-1111-1111-1111-111111111111" }],
|
|
24
|
+
})),
|
|
25
|
+
update: jest.fn(async () => ({ affected: 1 })),
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
return { readRepository, writeRepository };
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
describe("OmniExternalRefService", () => {
|
|
32
|
+
it('requires a binding validator instead of silently bypassing target validation', () => {
|
|
33
|
+
const { readRepository, writeRepository } = createRepositoryPair();
|
|
34
|
+
|
|
35
|
+
expect(
|
|
36
|
+
() =>
|
|
37
|
+
new OmniExternalRefService(
|
|
38
|
+
readRepository as never,
|
|
39
|
+
writeRepository as never,
|
|
40
|
+
'hard',
|
|
41
|
+
undefined as never,
|
|
42
|
+
),
|
|
43
|
+
).toThrow('requires an OmniExternalRefBindingValidator');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("looks up references by provider/external identity", async () => {
|
|
47
|
+
const { readRepository, writeRepository } = createRepositoryPair();
|
|
48
|
+
const service = new OmniExternalRefService(
|
|
49
|
+
readRepository as never,
|
|
50
|
+
writeRepository as never,
|
|
51
|
+
'hard',
|
|
52
|
+
bindingValidator as never,
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
await service.findByExternalIdentity({
|
|
56
|
+
provider: "github",
|
|
57
|
+
externalId: "123",
|
|
58
|
+
account: "acme",
|
|
59
|
+
container: "kb",
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
expect(readRepository.findOne).toHaveBeenCalledWith({
|
|
63
|
+
where: {
|
|
64
|
+
scopeId: "default",
|
|
65
|
+
provider: "github",
|
|
66
|
+
externalId: "123",
|
|
67
|
+
account: "acme",
|
|
68
|
+
container: "kb",
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("returns all references for an internal record", async () => {
|
|
74
|
+
const { readRepository, writeRepository } = createRepositoryPair();
|
|
75
|
+
const service = new OmniExternalRefService(
|
|
76
|
+
readRepository as never,
|
|
77
|
+
writeRepository as never,
|
|
78
|
+
'hard',
|
|
79
|
+
bindingValidator as never,
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
await service.findForInternalRecord(
|
|
83
|
+
OmniExternalRefInternalType.Document,
|
|
84
|
+
"doc-1",
|
|
85
|
+
"github",
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
expect(readRepository.find).toHaveBeenCalledWith({
|
|
89
|
+
where: {
|
|
90
|
+
scopeId: "default",
|
|
91
|
+
internalType: OmniExternalRefInternalType.Document,
|
|
92
|
+
internalId: "doc-1",
|
|
93
|
+
provider: "github",
|
|
94
|
+
},
|
|
95
|
+
order: {
|
|
96
|
+
createdAt: "ASC",
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("creates a new external ref when the identity does not exist", async () => {
|
|
102
|
+
const { readRepository, writeRepository } = createRepositoryPair();
|
|
103
|
+
readRepository.findOne.mockResolvedValue(null);
|
|
104
|
+
const service = new OmniExternalRefService(
|
|
105
|
+
readRepository as never,
|
|
106
|
+
writeRepository as never,
|
|
107
|
+
'hard',
|
|
108
|
+
bindingValidator as never,
|
|
109
|
+
);
|
|
110
|
+
const createSpy = jest
|
|
111
|
+
.spyOn(service, "createEntity")
|
|
112
|
+
.mockResolvedValue({ guid: "created" } as OmniExternalRefEntity);
|
|
113
|
+
|
|
114
|
+
const result = await service.upsertExternalRef({
|
|
115
|
+
internalType: OmniExternalRefInternalType.Document,
|
|
116
|
+
internalId: "doc-1",
|
|
117
|
+
provider: "github",
|
|
118
|
+
externalId: "123",
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
expect(createSpy).toHaveBeenCalledWith(
|
|
122
|
+
expect.objectContaining({
|
|
123
|
+
internalType: OmniExternalRefInternalType.Document,
|
|
124
|
+
internalId: "doc-1",
|
|
125
|
+
}),
|
|
126
|
+
);
|
|
127
|
+
expect(result.guid).toBe("created");
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it("validates record bindings without changing legacy non-record bindings", async () => {
|
|
131
|
+
const { readRepository, writeRepository } = createRepositoryPair();
|
|
132
|
+
readRepository.findOne.mockResolvedValue(null);
|
|
133
|
+
const validator = {
|
|
134
|
+
assertTarget: jest.fn(async () => ({})),
|
|
135
|
+
};
|
|
136
|
+
const service = new OmniExternalRefService(
|
|
137
|
+
readRepository as never,
|
|
138
|
+
writeRepository as never,
|
|
139
|
+
"hard",
|
|
140
|
+
validator as never,
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
await service.createEntity({
|
|
144
|
+
guid: "eeeeeeee-1111-1111-1111-111111111112",
|
|
145
|
+
provider: "example",
|
|
146
|
+
externalId: "record",
|
|
147
|
+
internalType: OmniExternalRefInternalType.Record,
|
|
148
|
+
internalId: "aaaaaaaa-1111-1111-1111-111111111111",
|
|
149
|
+
});
|
|
150
|
+
expect(validator.assertTarget).toHaveBeenCalledWith({
|
|
151
|
+
internalType: OmniExternalRefInternalType.Record,
|
|
152
|
+
internalId: "aaaaaaaa-1111-1111-1111-111111111111",
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
await service.createEntity({
|
|
156
|
+
guid: "eeeeeeee-1111-1111-1111-111111111113",
|
|
157
|
+
provider: "example",
|
|
158
|
+
externalId: "legacy-document",
|
|
159
|
+
internalType: OmniExternalRefInternalType.Document,
|
|
160
|
+
internalId: "aaaaaaaa-1111-1111-1111-111111111112",
|
|
161
|
+
});
|
|
162
|
+
expect(validator.assertTarget).toHaveBeenCalledTimes(1);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it("updates an existing external ref when the identity already exists", async () => {
|
|
166
|
+
const { readRepository, writeRepository } = createRepositoryPair();
|
|
167
|
+
readRepository.findOne.mockResolvedValue({
|
|
168
|
+
guid: "existing-guid",
|
|
169
|
+
internalType: OmniExternalRefInternalType.Document,
|
|
170
|
+
internalId: "doc-1",
|
|
171
|
+
});
|
|
172
|
+
const service = new OmniExternalRefService(
|
|
173
|
+
readRepository as never,
|
|
174
|
+
writeRepository as never,
|
|
175
|
+
'hard',
|
|
176
|
+
bindingValidator as never,
|
|
177
|
+
);
|
|
178
|
+
const updateSpy = jest
|
|
179
|
+
.spyOn(service, "updateEntity")
|
|
180
|
+
.mockResolvedValue({ guid: "existing-guid" } as OmniExternalRefEntity);
|
|
181
|
+
|
|
182
|
+
const result = await service.upsertExternalRef({
|
|
183
|
+
internalType: OmniExternalRefInternalType.Document,
|
|
184
|
+
internalId: "doc-1",
|
|
185
|
+
provider: "github",
|
|
186
|
+
externalId: "123",
|
|
187
|
+
payload: { synced: true },
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
expect(updateSpy).toHaveBeenCalledWith(
|
|
191
|
+
{ guid: "existing-guid" },
|
|
192
|
+
expect.objectContaining({
|
|
193
|
+
payload: { synced: true },
|
|
194
|
+
}),
|
|
195
|
+
);
|
|
196
|
+
expect(result.guid).toBe("existing-guid");
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it("rejects blank provider or external identity during upsert", async () => {
|
|
200
|
+
const { readRepository, writeRepository } = createRepositoryPair();
|
|
201
|
+
const service = new OmniExternalRefService(
|
|
202
|
+
readRepository as never,
|
|
203
|
+
writeRepository as never,
|
|
204
|
+
'hard',
|
|
205
|
+
bindingValidator as never,
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
await expect(
|
|
209
|
+
service.upsertExternalRef({
|
|
210
|
+
internalType: OmniExternalRefInternalType.Document,
|
|
211
|
+
internalId: "doc-1",
|
|
212
|
+
provider: "",
|
|
213
|
+
externalId: "123",
|
|
214
|
+
}),
|
|
215
|
+
).rejects.toThrow("OmniExternalRef.provider is required");
|
|
216
|
+
|
|
217
|
+
await expect(
|
|
218
|
+
service.upsertExternalRef({
|
|
219
|
+
internalType: OmniExternalRefInternalType.Document,
|
|
220
|
+
internalId: "doc-1",
|
|
221
|
+
provider: "github",
|
|
222
|
+
externalId: " ",
|
|
223
|
+
}),
|
|
224
|
+
).rejects.toThrow("OmniExternalRef.externalId is required");
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it("syncs document references with the document internal type", async () => {
|
|
228
|
+
const { readRepository, writeRepository } = createRepositoryPair();
|
|
229
|
+
const service = new OmniExternalRefService(
|
|
230
|
+
readRepository as never,
|
|
231
|
+
writeRepository as never,
|
|
232
|
+
'hard',
|
|
233
|
+
bindingValidator as never,
|
|
234
|
+
);
|
|
235
|
+
const upsertSpy = jest
|
|
236
|
+
.spyOn(service, "upsertExternalRef")
|
|
237
|
+
.mockResolvedValue({ guid: "doc-ref" } as OmniExternalRefEntity);
|
|
238
|
+
|
|
239
|
+
await service.syncDocumentReference("doc-1", {
|
|
240
|
+
provider: "github",
|
|
241
|
+
externalId: "123",
|
|
242
|
+
account: "acme",
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
expect(upsertSpy).toHaveBeenCalledWith(
|
|
246
|
+
expect.objectContaining({
|
|
247
|
+
internalType: OmniExternalRefInternalType.Document,
|
|
248
|
+
internalId: "doc-1",
|
|
249
|
+
}),
|
|
250
|
+
);
|
|
251
|
+
});
|
|
252
|
+
});
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
import { describe, expect, it } from '@jest/globals';
|
|
2
|
-
import { getMetadataArgsStorage } from 'typeorm';
|
|
3
|
-
|
|
4
|
-
import { OmniBaseEntity } from '../base/omni-base.entity.js';
|
|
5
|
-
import { OmniNamedEntity } from '../base/omni-named.entity.js';
|
|
6
|
-
|
|
7
|
-
describe('OmniNamedEntity', () => {
|
|
8
|
-
it('extends OmniBaseEntity', () => {
|
|
9
|
-
expect(new OmniNamedEntity()).toBeInstanceOf(OmniBaseEntity);
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
it('registers the expected table and columns', () => {
|
|
13
|
-
const metadata = getMetadataArgsStorage();
|
|
14
|
-
const table = metadata.tables.find(
|
|
15
|
-
(item) => item.target === OmniNamedEntity,
|
|
16
|
-
);
|
|
17
|
-
const baseColumns = metadata.columns
|
|
18
|
-
.filter((item) => item.target === OmniBaseEntity)
|
|
19
|
-
.map((item) => item.propertyName);
|
|
20
|
-
const entityColumns = metadata.columns
|
|
21
|
-
.filter((item) => item.target === OmniNamedEntity)
|
|
22
|
-
.map((item) => item.propertyName);
|
|
23
|
-
|
|
24
|
-
expect(table?.name).toBe('omni-named');
|
|
25
|
-
expect(baseColumns).toEqual(expect.arrayContaining(['guid']));
|
|
26
|
-
expect(metadata.columns.map((item) => item.propertyName)).toEqual(
|
|
27
|
-
expect.arrayContaining(['createdAt', 'updatedAt']),
|
|
28
|
-
);
|
|
29
|
-
expect(entityColumns).toEqual(
|
|
30
|
-
expect.arrayContaining(['externalId', 'title', 'slug']),
|
|
31
|
-
);
|
|
32
|
-
});
|
|
33
|
-
});
|
|
1
|
+
import { describe, expect, it } from '@jest/globals';
|
|
2
|
+
import { getMetadataArgsStorage } from 'typeorm';
|
|
3
|
+
|
|
4
|
+
import { OmniBaseEntity } from '../base/omni-base.entity.js';
|
|
5
|
+
import { OmniNamedEntity } from '../base/omni-named.entity.js';
|
|
6
|
+
|
|
7
|
+
describe('OmniNamedEntity', () => {
|
|
8
|
+
it('extends OmniBaseEntity', () => {
|
|
9
|
+
expect(new OmniNamedEntity()).toBeInstanceOf(OmniBaseEntity);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('registers the expected table and columns', () => {
|
|
13
|
+
const metadata = getMetadataArgsStorage();
|
|
14
|
+
const table = metadata.tables.find(
|
|
15
|
+
(item) => item.target === OmniNamedEntity,
|
|
16
|
+
);
|
|
17
|
+
const baseColumns = metadata.columns
|
|
18
|
+
.filter((item) => item.target === OmniBaseEntity)
|
|
19
|
+
.map((item) => item.propertyName);
|
|
20
|
+
const entityColumns = metadata.columns
|
|
21
|
+
.filter((item) => item.target === OmniNamedEntity)
|
|
22
|
+
.map((item) => item.propertyName);
|
|
23
|
+
|
|
24
|
+
expect(table?.name).toBe('omni-named');
|
|
25
|
+
expect(baseColumns).toEqual(expect.arrayContaining(['guid']));
|
|
26
|
+
expect(metadata.columns.map((item) => item.propertyName)).toEqual(
|
|
27
|
+
expect.arrayContaining(['createdAt', 'updatedAt']),
|
|
28
|
+
);
|
|
29
|
+
expect(entityColumns).toEqual(
|
|
30
|
+
expect.arrayContaining(['externalId', 'title', 'slug']),
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
});
|