@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,94 +1,94 @@
|
|
|
1
|
-
import { describe, expect, it, jest } from "@jest/globals";
|
|
2
|
-
|
|
3
|
-
import { collectOmniKernelQueryPlanEvidence } from '../omnikernel.diagnostics.js';
|
|
4
|
-
|
|
5
|
-
const sample = {
|
|
6
|
-
scopeId: "scope-alpha",
|
|
7
|
-
recordKind: "generic",
|
|
8
|
-
recordStatus: "active",
|
|
9
|
-
sourceRecordId: "record-1",
|
|
10
|
-
relationKind: "references",
|
|
11
|
-
relationStatus: "active",
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
describe("OmniKernel query-plan diagnostics", () => {
|
|
15
|
-
it("records sqlite index evidence for the bounded generated read shapes", async () => {
|
|
16
|
-
const query = jest
|
|
17
|
-
.fn()
|
|
18
|
-
.mockResolvedValueOnce([
|
|
19
|
-
{
|
|
20
|
-
detail:
|
|
21
|
-
"SEARCH omni-record USING INDEX omni_record_scope_kind_status_guid_idx",
|
|
22
|
-
},
|
|
23
|
-
])
|
|
24
|
-
.mockResolvedValueOnce([
|
|
25
|
-
{
|
|
26
|
-
detail:
|
|
27
|
-
"SEARCH omni-relation USING INDEX omni_relation_scope_source_kind_status_created_guid_idx",
|
|
28
|
-
},
|
|
29
|
-
]);
|
|
30
|
-
|
|
31
|
-
const evidence = await collectOmniKernelQueryPlanEvidence(
|
|
32
|
-
{ options: { type: "sqlite" }, query } as never,
|
|
33
|
-
sample,
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
expect(evidence).toMatchObject({
|
|
37
|
-
dialect: "sqlite",
|
|
38
|
-
usesRecordGridIndex: true,
|
|
39
|
-
usesRelationSourceIndex: true,
|
|
40
|
-
});
|
|
41
|
-
expect(query.mock.calls[0][0]).toContain("EXPLAIN QUERY PLAN");
|
|
42
|
-
expect(query.mock.calls[1][1]).toEqual([
|
|
43
|
-
sample.scopeId,
|
|
44
|
-
sample.sourceRecordId,
|
|
45
|
-
sample.relationKind,
|
|
46
|
-
sample.relationStatus,
|
|
47
|
-
]);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it("records PostgreSQL JSON-plan index evidence", async () => {
|
|
51
|
-
const query = jest
|
|
52
|
-
.fn()
|
|
53
|
-
.mockResolvedValueOnce([
|
|
54
|
-
{
|
|
55
|
-
"QUERY PLAN": [
|
|
56
|
-
{
|
|
57
|
-
Plan: { "Index Name": "omni_record_scope_kind_status_guid_idx" },
|
|
58
|
-
},
|
|
59
|
-
],
|
|
60
|
-
},
|
|
61
|
-
])
|
|
62
|
-
.mockResolvedValueOnce([
|
|
63
|
-
{
|
|
64
|
-
"QUERY PLAN": [
|
|
65
|
-
{
|
|
66
|
-
Plan: {
|
|
67
|
-
"Index Name":
|
|
68
|
-
"omni_relation_scope_source_kind_status_created_guid_idx",
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
],
|
|
72
|
-
},
|
|
73
|
-
]);
|
|
74
|
-
|
|
75
|
-
const evidence = await collectOmniKernelQueryPlanEvidence(
|
|
76
|
-
{ options: { type: "postgres" }, query } as never,
|
|
77
|
-
sample,
|
|
78
|
-
);
|
|
79
|
-
|
|
80
|
-
expect(evidence.dialect).toBe("postgres");
|
|
81
|
-
expect(evidence.usesRecordGridIndex).toBe(true);
|
|
82
|
-
expect(evidence.usesRelationSourceIndex).toBe(true);
|
|
83
|
-
expect(query.mock.calls[0][0]).toContain("EXPLAIN (FORMAT JSON)");
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it("rejects unsupported drivers instead of guessing their query-plan syntax", async () => {
|
|
87
|
-
await expect(
|
|
88
|
-
collectOmniKernelQueryPlanEvidence(
|
|
89
|
-
{ options: { type: "mysql" }, query: jest.fn() } as never,
|
|
90
|
-
sample,
|
|
91
|
-
),
|
|
92
|
-
).rejects.toThrow("sqlite and postgres only");
|
|
93
|
-
});
|
|
94
|
-
});
|
|
1
|
+
import { describe, expect, it, jest } from "@jest/globals";
|
|
2
|
+
|
|
3
|
+
import { collectOmniKernelQueryPlanEvidence } from '../omnikernel.diagnostics.js';
|
|
4
|
+
|
|
5
|
+
const sample = {
|
|
6
|
+
scopeId: "scope-alpha",
|
|
7
|
+
recordKind: "generic",
|
|
8
|
+
recordStatus: "active",
|
|
9
|
+
sourceRecordId: "record-1",
|
|
10
|
+
relationKind: "references",
|
|
11
|
+
relationStatus: "active",
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
describe("OmniKernel query-plan diagnostics", () => {
|
|
15
|
+
it("records sqlite index evidence for the bounded generated read shapes", async () => {
|
|
16
|
+
const query = jest
|
|
17
|
+
.fn()
|
|
18
|
+
.mockResolvedValueOnce([
|
|
19
|
+
{
|
|
20
|
+
detail:
|
|
21
|
+
"SEARCH omni-record USING INDEX omni_record_scope_kind_status_guid_idx",
|
|
22
|
+
},
|
|
23
|
+
])
|
|
24
|
+
.mockResolvedValueOnce([
|
|
25
|
+
{
|
|
26
|
+
detail:
|
|
27
|
+
"SEARCH omni-relation USING INDEX omni_relation_scope_source_kind_status_created_guid_idx",
|
|
28
|
+
},
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
const evidence = await collectOmniKernelQueryPlanEvidence(
|
|
32
|
+
{ options: { type: "sqlite" }, query } as never,
|
|
33
|
+
sample,
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
expect(evidence).toMatchObject({
|
|
37
|
+
dialect: "sqlite",
|
|
38
|
+
usesRecordGridIndex: true,
|
|
39
|
+
usesRelationSourceIndex: true,
|
|
40
|
+
});
|
|
41
|
+
expect(query.mock.calls[0][0]).toContain("EXPLAIN QUERY PLAN");
|
|
42
|
+
expect(query.mock.calls[1][1]).toEqual([
|
|
43
|
+
sample.scopeId,
|
|
44
|
+
sample.sourceRecordId,
|
|
45
|
+
sample.relationKind,
|
|
46
|
+
sample.relationStatus,
|
|
47
|
+
]);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("records PostgreSQL JSON-plan index evidence", async () => {
|
|
51
|
+
const query = jest
|
|
52
|
+
.fn()
|
|
53
|
+
.mockResolvedValueOnce([
|
|
54
|
+
{
|
|
55
|
+
"QUERY PLAN": [
|
|
56
|
+
{
|
|
57
|
+
Plan: { "Index Name": "omni_record_scope_kind_status_guid_idx" },
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
])
|
|
62
|
+
.mockResolvedValueOnce([
|
|
63
|
+
{
|
|
64
|
+
"QUERY PLAN": [
|
|
65
|
+
{
|
|
66
|
+
Plan: {
|
|
67
|
+
"Index Name":
|
|
68
|
+
"omni_relation_scope_source_kind_status_created_guid_idx",
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
]);
|
|
74
|
+
|
|
75
|
+
const evidence = await collectOmniKernelQueryPlanEvidence(
|
|
76
|
+
{ options: { type: "postgres" }, query } as never,
|
|
77
|
+
sample,
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
expect(evidence.dialect).toBe("postgres");
|
|
81
|
+
expect(evidence.usesRecordGridIndex).toBe(true);
|
|
82
|
+
expect(evidence.usesRelationSourceIndex).toBe(true);
|
|
83
|
+
expect(query.mock.calls[0][0]).toContain("EXPLAIN (FORMAT JSON)");
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("rejects unsupported drivers instead of guessing their query-plan syntax", async () => {
|
|
87
|
+
await expect(
|
|
88
|
+
collectOmniKernelQueryPlanEvidence(
|
|
89
|
+
{ options: { type: "mysql" }, query: jest.fn() } as never,
|
|
90
|
+
sample,
|
|
91
|
+
),
|
|
92
|
+
).rejects.toThrow("sqlite and postgres only");
|
|
93
|
+
});
|
|
94
|
+
});
|
|
@@ -1,40 +1,38 @@
|
|
|
1
|
-
import { describe, expect, it, jest } from '@jest/globals';
|
|
2
|
-
import 'reflect-metadata';
|
|
3
|
-
import { OmniKernelQueryService } from '../omnikernel.query.service.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import * as
|
|
7
|
-
import * as
|
|
8
|
-
import * as
|
|
9
|
-
import * as
|
|
10
|
-
import * as
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
expect(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
'
|
|
31
|
-
'
|
|
32
|
-
'
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
});
|
|
40
|
-
});
|
|
1
|
+
import { describe, expect, it, jest } from '@jest/globals';
|
|
2
|
+
import 'reflect-metadata';
|
|
3
|
+
import { OmniKernelQueryService } from '../omnikernel.query.service.js';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
import * as OmniNamedBackend from '../omni-named.backend.js';
|
|
7
|
+
import * as OmniRecordBackend from '../omni-record.backend.js';
|
|
8
|
+
import * as OmniRelationBackend from '../omni-relation.backend.js';
|
|
9
|
+
import * as OmniCollectionBackend from '../omni-collection.backend.js';
|
|
10
|
+
import * as OmniDocumentBackend from '../omni-document.backend.js';
|
|
11
|
+
import * as OmniExternalRefBackend from '../omni-external-ref.backend.js';
|
|
12
|
+
|
|
13
|
+
const omniNamedBackendProvidersFactory = OmniNamedBackend.omniNamedBackendProvidersFactory as jest.Mock;
|
|
14
|
+
const omniRecordBackendProvidersFactory = OmniRecordBackend.omniRecordBackendProvidersFactory as jest.Mock;
|
|
15
|
+
const omniRelationBackendProvidersFactory = OmniRelationBackend.omniRelationBackendProvidersFactory as jest.Mock;
|
|
16
|
+
const omniCollectionBackendProvidersFactory = OmniCollectionBackend.omniCollectionBackendProvidersFactory as jest.Mock;
|
|
17
|
+
const omniDocumentBackendProvidersFactory = OmniDocumentBackend.omniDocumentBackendProvidersFactory as jest.Mock;
|
|
18
|
+
const omniExternalRefBackendProvidersFactory = OmniExternalRefBackend.omniExternalRefBackendProvidersFactory as jest.Mock;
|
|
19
|
+
|
|
20
|
+
import { OmniKernelModule } from '../omnikernel.module.js';
|
|
21
|
+
|
|
22
|
+
describe('OmniKernelModule', () => {
|
|
23
|
+
it('registers only backend substrate providers', () => {
|
|
24
|
+
const module = OmniKernelModule.register('test');
|
|
25
|
+
|
|
26
|
+
expect(module).toBeDefined();
|
|
27
|
+
|
|
28
|
+
expect(module.providers).toEqual(
|
|
29
|
+
expect.arrayContaining([
|
|
30
|
+
expect.objectContaining({ provide: 'OmniNamedEntityGenericService' }),
|
|
31
|
+
expect.objectContaining({ provide: 'OmniRecordEntityGenericService' }),
|
|
32
|
+
expect.objectContaining({ provide: 'OmniRelationEntityGenericService' }),
|
|
33
|
+
expect.objectContaining({ provide: OmniKernelQueryService }),
|
|
34
|
+
]),
|
|
35
|
+
);
|
|
36
|
+
expect(module.controllers).toBeUndefined();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
@@ -1,154 +1,154 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it } from '@jest/globals';
|
|
2
|
-
import { DataSource } from 'typeorm';
|
|
3
|
-
|
|
4
|
-
import { OmniNamedEntity } from '../base/omni-named.entity.js';
|
|
5
|
-
import { OmniRecordEntity } from '../base/omni-record.entity.js';
|
|
6
|
-
import { OmniRelationEntity } from '../base/omni-relation.entity.js';
|
|
7
|
-
import { OmniCollectionEntity } from '../omni-collection.entity.js';
|
|
8
|
-
import { OmniCollectionKind } from '../omni-collection-kind.enum.js';
|
|
9
|
-
import { OmniDocumentEntity } from '../omni-document.entity.js';
|
|
10
|
-
import { OmniDocumentKind } from '../omni-document-kind.enum.js';
|
|
11
|
-
import { OmniRecordStatus } from '../omni-record-status.enum.js';
|
|
12
|
-
import { OmniRelationKind } from '../omni-relation-kind.enum.js';
|
|
13
|
-
import { OmniRelationStatus } from '../omni-relation-status.enum.js';
|
|
14
|
-
|
|
15
|
-
describe('OmniKernel persistence', () => {
|
|
16
|
-
let dataSource: DataSource;
|
|
17
|
-
|
|
18
|
-
beforeEach(async () => {
|
|
19
|
-
dataSource = new DataSource({
|
|
20
|
-
type: 'sqlite',
|
|
21
|
-
database: ':memory:',
|
|
22
|
-
dropSchema: true,
|
|
23
|
-
synchronize: true,
|
|
24
|
-
entities: [
|
|
25
|
-
OmniNamedEntity,
|
|
26
|
-
OmniRecordEntity,
|
|
27
|
-
OmniCollectionEntity,
|
|
28
|
-
OmniDocumentEntity,
|
|
29
|
-
OmniRelationEntity,
|
|
30
|
-
],
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
await dataSource.initialize();
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
afterEach(async () => {
|
|
37
|
-
if (dataSource.isInitialized) {
|
|
38
|
-
await dataSource.destroy();
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('stores collections and documents in omni-record and resolves graph links back through the shared record hierarchy', async () => {
|
|
43
|
-
const recordRepo = dataSource.getRepository(OmniRecordEntity);
|
|
44
|
-
const collectionRepo = dataSource.getRepository(OmniCollectionEntity);
|
|
45
|
-
const documentRepo = dataSource.getRepository(OmniDocumentEntity);
|
|
46
|
-
const relationRepo = dataSource.getRepository(OmniRelationEntity);
|
|
47
|
-
|
|
48
|
-
await recordRepo.insert(
|
|
49
|
-
recordRepo.create({
|
|
50
|
-
guid: '11111111-1111-1111-1111-111111111111',
|
|
51
|
-
title: 'Task record',
|
|
52
|
-
kind: 'task',
|
|
53
|
-
status: OmniRecordStatus.Draft,
|
|
54
|
-
}),
|
|
55
|
-
);
|
|
56
|
-
await documentRepo.insert(
|
|
57
|
-
documentRepo.create({
|
|
58
|
-
guid: '22222222-2222-2222-2222-222222222222',
|
|
59
|
-
title: 'Document record',
|
|
60
|
-
status: OmniRecordStatus.Draft,
|
|
61
|
-
documentKind: OmniDocumentKind.Note,
|
|
62
|
-
}),
|
|
63
|
-
);
|
|
64
|
-
await collectionRepo.insert(
|
|
65
|
-
collectionRepo.create({
|
|
66
|
-
guid: '44444444-4444-4444-4444-444444444444',
|
|
67
|
-
title: 'Knowledge base',
|
|
68
|
-
status: OmniRecordStatus.Active,
|
|
69
|
-
collectionKind: OmniCollectionKind.Folder,
|
|
70
|
-
summary: 'Primary document container',
|
|
71
|
-
}),
|
|
72
|
-
);
|
|
73
|
-
await relationRepo.insert(
|
|
74
|
-
relationRepo.create({
|
|
75
|
-
guid: '33333333-3333-3333-3333-333333333333',
|
|
76
|
-
sourceRecordId: '11111111-1111-1111-1111-111111111111',
|
|
77
|
-
targetRecordId: '22222222-2222-2222-2222-222222222222',
|
|
78
|
-
kind: OmniRelationKind.References,
|
|
79
|
-
status: OmniRelationStatus.Active,
|
|
80
|
-
}),
|
|
81
|
-
);
|
|
82
|
-
await relationRepo.insert(
|
|
83
|
-
relationRepo.create({
|
|
84
|
-
guid: '55555555-5555-5555-5555-555555555555',
|
|
85
|
-
sourceRecordId: '44444444-4444-4444-4444-444444444444',
|
|
86
|
-
targetRecordId: '22222222-2222-2222-2222-222222222222',
|
|
87
|
-
kind: OmniRelationKind.Contains,
|
|
88
|
-
status: OmniRelationStatus.Active,
|
|
89
|
-
}),
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
const rows = await dataSource.query(
|
|
93
|
-
'select guid, kind, recordType, collectionKind, documentKind from "omni-record" order by guid',
|
|
94
|
-
);
|
|
95
|
-
|
|
96
|
-
expect(rows).toEqual(
|
|
97
|
-
expect.arrayContaining([
|
|
98
|
-
expect.objectContaining({
|
|
99
|
-
guid: '11111111-1111-1111-1111-111111111111',
|
|
100
|
-
kind: 'task',
|
|
101
|
-
}),
|
|
102
|
-
expect.objectContaining({
|
|
103
|
-
guid: '22222222-2222-2222-2222-222222222222',
|
|
104
|
-
kind: OmniDocumentKind.Document,
|
|
105
|
-
recordType: OmniDocumentKind.Document,
|
|
106
|
-
documentKind: OmniDocumentKind.Note,
|
|
107
|
-
}),
|
|
108
|
-
expect.objectContaining({
|
|
109
|
-
guid: '44444444-4444-4444-4444-444444444444',
|
|
110
|
-
kind: OmniCollectionKind.Collection,
|
|
111
|
-
recordType: OmniCollectionKind.Collection,
|
|
112
|
-
collectionKind: OmniCollectionKind.Folder,
|
|
113
|
-
}),
|
|
114
|
-
]),
|
|
115
|
-
);
|
|
116
|
-
|
|
117
|
-
const relation = await relationRepo.findOneOrFail({
|
|
118
|
-
where: { guid: '33333333-3333-3333-3333-333333333333' },
|
|
119
|
-
relations: {
|
|
120
|
-
sourceRecord: true,
|
|
121
|
-
targetRecord: true,
|
|
122
|
-
},
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
expect(relation.sourceRecord.guid).toBe(
|
|
126
|
-
'11111111-1111-1111-1111-111111111111',
|
|
127
|
-
);
|
|
128
|
-
expect(relation.targetRecord).toBeInstanceOf(OmniDocumentEntity);
|
|
129
|
-
expect(relation.targetRecord.guid).toBe(
|
|
130
|
-
'22222222-2222-2222-2222-222222222222',
|
|
131
|
-
);
|
|
132
|
-
expect((relation.targetRecord as OmniDocumentEntity).kind).toBe(
|
|
133
|
-
OmniDocumentKind.Document,
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
const membershipRelation = await relationRepo.findOneOrFail({
|
|
137
|
-
where: { guid: '55555555-5555-5555-5555-555555555555' },
|
|
138
|
-
relations: {
|
|
139
|
-
sourceRecord: true,
|
|
140
|
-
targetRecord: true,
|
|
141
|
-
},
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
expect(membershipRelation.sourceRecord).toBeInstanceOf(OmniCollectionEntity);
|
|
145
|
-
expect(membershipRelation.sourceRecord.guid).toBe(
|
|
146
|
-
'44444444-4444-4444-4444-444444444444',
|
|
147
|
-
);
|
|
148
|
-
expect((membershipRelation.sourceRecord as OmniCollectionEntity).kind).toBe(
|
|
149
|
-
OmniCollectionKind.Collection,
|
|
150
|
-
);
|
|
151
|
-
expect(membershipRelation.targetRecord).toBeInstanceOf(OmniDocumentEntity);
|
|
152
|
-
expect(membershipRelation.kind).toBe(OmniRelationKind.Contains);
|
|
153
|
-
});
|
|
154
|
-
});
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it } from '@jest/globals';
|
|
2
|
+
import { DataSource } from 'typeorm';
|
|
3
|
+
|
|
4
|
+
import { OmniNamedEntity } from '../base/omni-named.entity.js';
|
|
5
|
+
import { OmniRecordEntity } from '../base/omni-record.entity.js';
|
|
6
|
+
import { OmniRelationEntity } from '../base/omni-relation.entity.js';
|
|
7
|
+
import { OmniCollectionEntity } from '../omni-collection.entity.js';
|
|
8
|
+
import { OmniCollectionKind } from '../omni-collection-kind.enum.js';
|
|
9
|
+
import { OmniDocumentEntity } from '../omni-document.entity.js';
|
|
10
|
+
import { OmniDocumentKind } from '../omni-document-kind.enum.js';
|
|
11
|
+
import { OmniRecordStatus } from '../omni-record-status.enum.js';
|
|
12
|
+
import { OmniRelationKind } from '../omni-relation-kind.enum.js';
|
|
13
|
+
import { OmniRelationStatus } from '../omni-relation-status.enum.js';
|
|
14
|
+
|
|
15
|
+
describe('OmniKernel persistence', () => {
|
|
16
|
+
let dataSource: DataSource;
|
|
17
|
+
|
|
18
|
+
beforeEach(async () => {
|
|
19
|
+
dataSource = new DataSource({
|
|
20
|
+
type: 'sqlite',
|
|
21
|
+
database: ':memory:',
|
|
22
|
+
dropSchema: true,
|
|
23
|
+
synchronize: true,
|
|
24
|
+
entities: [
|
|
25
|
+
OmniNamedEntity,
|
|
26
|
+
OmniRecordEntity,
|
|
27
|
+
OmniCollectionEntity,
|
|
28
|
+
OmniDocumentEntity,
|
|
29
|
+
OmniRelationEntity,
|
|
30
|
+
],
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
await dataSource.initialize();
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
afterEach(async () => {
|
|
37
|
+
if (dataSource.isInitialized) {
|
|
38
|
+
await dataSource.destroy();
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('stores collections and documents in omni-record and resolves graph links back through the shared record hierarchy', async () => {
|
|
43
|
+
const recordRepo = dataSource.getRepository(OmniRecordEntity);
|
|
44
|
+
const collectionRepo = dataSource.getRepository(OmniCollectionEntity);
|
|
45
|
+
const documentRepo = dataSource.getRepository(OmniDocumentEntity);
|
|
46
|
+
const relationRepo = dataSource.getRepository(OmniRelationEntity);
|
|
47
|
+
|
|
48
|
+
await recordRepo.insert(
|
|
49
|
+
recordRepo.create({
|
|
50
|
+
guid: '11111111-1111-1111-1111-111111111111',
|
|
51
|
+
title: 'Task record',
|
|
52
|
+
kind: 'task',
|
|
53
|
+
status: OmniRecordStatus.Draft,
|
|
54
|
+
}),
|
|
55
|
+
);
|
|
56
|
+
await documentRepo.insert(
|
|
57
|
+
documentRepo.create({
|
|
58
|
+
guid: '22222222-2222-2222-2222-222222222222',
|
|
59
|
+
title: 'Document record',
|
|
60
|
+
status: OmniRecordStatus.Draft,
|
|
61
|
+
documentKind: OmniDocumentKind.Note,
|
|
62
|
+
}),
|
|
63
|
+
);
|
|
64
|
+
await collectionRepo.insert(
|
|
65
|
+
collectionRepo.create({
|
|
66
|
+
guid: '44444444-4444-4444-4444-444444444444',
|
|
67
|
+
title: 'Knowledge base',
|
|
68
|
+
status: OmniRecordStatus.Active,
|
|
69
|
+
collectionKind: OmniCollectionKind.Folder,
|
|
70
|
+
summary: 'Primary document container',
|
|
71
|
+
}),
|
|
72
|
+
);
|
|
73
|
+
await relationRepo.insert(
|
|
74
|
+
relationRepo.create({
|
|
75
|
+
guid: '33333333-3333-3333-3333-333333333333',
|
|
76
|
+
sourceRecordId: '11111111-1111-1111-1111-111111111111',
|
|
77
|
+
targetRecordId: '22222222-2222-2222-2222-222222222222',
|
|
78
|
+
kind: OmniRelationKind.References,
|
|
79
|
+
status: OmniRelationStatus.Active,
|
|
80
|
+
}),
|
|
81
|
+
);
|
|
82
|
+
await relationRepo.insert(
|
|
83
|
+
relationRepo.create({
|
|
84
|
+
guid: '55555555-5555-5555-5555-555555555555',
|
|
85
|
+
sourceRecordId: '44444444-4444-4444-4444-444444444444',
|
|
86
|
+
targetRecordId: '22222222-2222-2222-2222-222222222222',
|
|
87
|
+
kind: OmniRelationKind.Contains,
|
|
88
|
+
status: OmniRelationStatus.Active,
|
|
89
|
+
}),
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
const rows = await dataSource.query(
|
|
93
|
+
'select guid, kind, recordType, collectionKind, documentKind from "omni-record" order by guid',
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
expect(rows).toEqual(
|
|
97
|
+
expect.arrayContaining([
|
|
98
|
+
expect.objectContaining({
|
|
99
|
+
guid: '11111111-1111-1111-1111-111111111111',
|
|
100
|
+
kind: 'task',
|
|
101
|
+
}),
|
|
102
|
+
expect.objectContaining({
|
|
103
|
+
guid: '22222222-2222-2222-2222-222222222222',
|
|
104
|
+
kind: OmniDocumentKind.Document,
|
|
105
|
+
recordType: OmniDocumentKind.Document,
|
|
106
|
+
documentKind: OmniDocumentKind.Note,
|
|
107
|
+
}),
|
|
108
|
+
expect.objectContaining({
|
|
109
|
+
guid: '44444444-4444-4444-4444-444444444444',
|
|
110
|
+
kind: OmniCollectionKind.Collection,
|
|
111
|
+
recordType: OmniCollectionKind.Collection,
|
|
112
|
+
collectionKind: OmniCollectionKind.Folder,
|
|
113
|
+
}),
|
|
114
|
+
]),
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
const relation = await relationRepo.findOneOrFail({
|
|
118
|
+
where: { guid: '33333333-3333-3333-3333-333333333333' },
|
|
119
|
+
relations: {
|
|
120
|
+
sourceRecord: true,
|
|
121
|
+
targetRecord: true,
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
expect(relation.sourceRecord.guid).toBe(
|
|
126
|
+
'11111111-1111-1111-1111-111111111111',
|
|
127
|
+
);
|
|
128
|
+
expect(relation.targetRecord).toBeInstanceOf(OmniDocumentEntity);
|
|
129
|
+
expect(relation.targetRecord.guid).toBe(
|
|
130
|
+
'22222222-2222-2222-2222-222222222222',
|
|
131
|
+
);
|
|
132
|
+
expect((relation.targetRecord as OmniDocumentEntity).kind).toBe(
|
|
133
|
+
OmniDocumentKind.Document,
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
const membershipRelation = await relationRepo.findOneOrFail({
|
|
137
|
+
where: { guid: '55555555-5555-5555-5555-555555555555' },
|
|
138
|
+
relations: {
|
|
139
|
+
sourceRecord: true,
|
|
140
|
+
targetRecord: true,
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
expect(membershipRelation.sourceRecord).toBeInstanceOf(OmniCollectionEntity);
|
|
145
|
+
expect(membershipRelation.sourceRecord.guid).toBe(
|
|
146
|
+
'44444444-4444-4444-4444-444444444444',
|
|
147
|
+
);
|
|
148
|
+
expect((membershipRelation.sourceRecord as OmniCollectionEntity).kind).toBe(
|
|
149
|
+
OmniCollectionKind.Collection,
|
|
150
|
+
);
|
|
151
|
+
expect(membershipRelation.targetRecord).toBeInstanceOf(OmniDocumentEntity);
|
|
152
|
+
expect(membershipRelation.kind).toBe(OmniRelationKind.Contains);
|
|
153
|
+
});
|
|
154
|
+
});
|