@verdant-web/common 2.3.3 → 2.4.0-next.0
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/LICENSE +650 -21
- package/dist/esm/authz.d.ts +25 -0
- package/dist/esm/authz.js +54 -0
- package/dist/esm/authz.js.map +1 -0
- package/dist/esm/baseline.d.ts +1 -0
- package/dist/esm/baseline.js +3 -0
- package/dist/esm/baseline.js.map +1 -1
- package/dist/esm/files.d.ts +4 -0
- package/dist/esm/files.js +18 -0
- package/dist/esm/files.js.map +1 -1
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/indexes.js +1 -1
- package/dist/esm/indexes.js.map +1 -1
- package/dist/esm/indexes.test.js +1 -1
- package/dist/esm/indexes.test.js.map +1 -1
- package/dist/esm/migration.d.ts +4 -2
- package/dist/esm/migration.js.map +1 -1
- package/dist/esm/oids.d.ts +6 -24
- package/dist/esm/oids.js +18 -107
- package/dist/esm/oids.js.map +1 -1
- package/dist/esm/oids.test.js +1 -188
- package/dist/esm/oids.test.js.map +1 -1
- package/dist/esm/oidsLegacy.d.ts +18 -0
- package/dist/esm/oidsLegacy.js +72 -0
- package/dist/esm/oidsLegacy.js.map +1 -0
- package/dist/esm/oidsLegacy.test.d.ts +1 -0
- package/dist/esm/oidsLegacy.test.js +115 -0
- package/dist/esm/oidsLegacy.test.js.map +1 -0
- package/dist/esm/operation.d.ts +28 -4
- package/dist/esm/operation.js +70 -35
- package/dist/esm/operation.js.map +1 -1
- package/dist/esm/operation.test.js.map +1 -1
- package/dist/esm/presence.d.ts +0 -2
- package/dist/esm/schema/fields.js +1 -1
- package/dist/esm/schema/fields.js.map +1 -1
- package/dist/esm/schema/validation.js +14 -7
- package/dist/esm/schema/validation.js.map +1 -1
- package/dist/esm/utils.d.ts +1 -0
- package/dist/esm/utils.js +21 -0
- package/dist/esm/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/authz.ts +67 -0
- package/src/baseline.ts +5 -4
- package/src/files.ts +25 -0
- package/src/index.ts +2 -0
- package/src/indexes.test.ts +1 -1
- package/src/indexes.ts +1 -1
- package/src/migration.ts +5 -1
- package/src/oids.test.ts +0 -241
- package/src/oids.ts +24 -122
- package/src/oidsLegacy.test.ts +147 -0
- package/src/oidsLegacy.ts +87 -0
- package/src/operation.test.ts +0 -1
- package/src/operation.ts +202 -103
- package/src/presence.ts +0 -2
- package/src/schema/fields.ts +1 -1
- package/src/schema/validation.ts +23 -14
- package/src/utils.ts +26 -0
package/src/oids.ts
CHANGED
|
@@ -29,10 +29,7 @@ import { isObject, assert } from './utils.js';
|
|
|
29
29
|
|
|
30
30
|
export type ObjectIdentifier = string;
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
export const OID_KEY = '@@id';
|
|
34
|
-
|
|
35
|
-
const COLLECTION_SEPARATOR = '/';
|
|
32
|
+
const SEGMENT_SEPARATOR = '/';
|
|
36
33
|
const RANDOM_SEPARATOR = ':';
|
|
37
34
|
|
|
38
35
|
/**
|
|
@@ -54,7 +51,7 @@ export function maybeGetOid(obj: any): ObjectIdentifier | undefined {
|
|
|
54
51
|
if (!isObject(obj)) {
|
|
55
52
|
return undefined;
|
|
56
53
|
}
|
|
57
|
-
return oidMap.get(obj)
|
|
54
|
+
return oidMap.get(obj);
|
|
58
55
|
}
|
|
59
56
|
|
|
60
57
|
export function assignOid(obj: any, oid: ObjectIdentifier) {
|
|
@@ -78,10 +75,6 @@ export function removeOid(obj: any) {
|
|
|
78
75
|
return obj;
|
|
79
76
|
}
|
|
80
77
|
|
|
81
|
-
export function isOidKey(key: string) {
|
|
82
|
-
return key === OID_KEY || key === LEGACY_OID_KEY;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
78
|
/**
|
|
86
79
|
* For sub-objects, assign a random sub-OID if no OID
|
|
87
80
|
* is already assigned.
|
|
@@ -141,6 +134,11 @@ function unsanitizeFragment(id: string) {
|
|
|
141
134
|
.replace(/˙/g, '.');
|
|
142
135
|
}
|
|
143
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Creates an OID for the document with a particular ID.
|
|
139
|
+
* To create a sub-object OID, use createSubOid and pass
|
|
140
|
+
* the root OID.
|
|
141
|
+
*/
|
|
144
142
|
export function createOid(
|
|
145
143
|
collection: string,
|
|
146
144
|
documentId: string,
|
|
@@ -148,7 +146,7 @@ export function createOid(
|
|
|
148
146
|
) {
|
|
149
147
|
let oid =
|
|
150
148
|
sanitizeFragment(collection) +
|
|
151
|
-
|
|
149
|
+
SEGMENT_SEPARATOR +
|
|
152
150
|
sanitizeFragment(documentId);
|
|
153
151
|
if (subId) {
|
|
154
152
|
oid += RANDOM_SEPARATOR + subId;
|
|
@@ -169,18 +167,26 @@ export function decomposeOid(oid: ObjectIdentifier): {
|
|
|
169
167
|
id: string;
|
|
170
168
|
subId?: string;
|
|
171
169
|
} {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
//
|
|
170
|
+
let [collection, coreId, ...others] = oid.split('/');
|
|
171
|
+
// if 'others' exists, something's off, but maybe we can recover...
|
|
172
|
+
// by assuming the last segment is the authz and bolting the rest onto coreId
|
|
175
173
|
if (others.length) {
|
|
176
|
-
|
|
174
|
+
console.error(
|
|
175
|
+
`OID ${oid} has more than 3 segments. Attempting to parse it anyway.`,
|
|
176
|
+
);
|
|
177
|
+
coreId += '/' + others.join('/');
|
|
177
178
|
}
|
|
179
|
+
|
|
180
|
+
const [idOrLegacyPathId, random] = coreId.split(RANDOM_SEPARATOR);
|
|
181
|
+
|
|
178
182
|
let id;
|
|
183
|
+
// legacy path handling. shouldn't be necessary anymore.
|
|
179
184
|
if (idOrLegacyPathId.includes('.')) {
|
|
180
185
|
id = idOrLegacyPathId.slice(0, idOrLegacyPathId.indexOf('.'));
|
|
181
186
|
} else {
|
|
182
187
|
id = idOrLegacyPathId;
|
|
183
188
|
}
|
|
189
|
+
|
|
184
190
|
return {
|
|
185
191
|
collection: unsanitizeFragment(collection),
|
|
186
192
|
id: unsanitizeFragment(id),
|
|
@@ -230,84 +236,6 @@ export function assignOidsToAllSubObjects(
|
|
|
230
236
|
}
|
|
231
237
|
}
|
|
232
238
|
|
|
233
|
-
export function assignOidProperty(obj: any, oid: ObjectIdentifier) {
|
|
234
|
-
assert(
|
|
235
|
-
isObject(obj),
|
|
236
|
-
`Only objects can be assigned OIDs, received ${JSON.stringify(obj)}`,
|
|
237
|
-
);
|
|
238
|
-
obj[OID_KEY] = oid;
|
|
239
|
-
return obj;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
export function maybeGetOidProperty(obj: any) {
|
|
243
|
-
if (!isObject(obj)) {
|
|
244
|
-
return undefined;
|
|
245
|
-
}
|
|
246
|
-
return obj[OID_KEY] || obj[LEGACY_OID_KEY];
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
function removeOidProperty(obj: any) {
|
|
250
|
-
if (!isObject(obj)) {
|
|
251
|
-
return obj;
|
|
252
|
-
}
|
|
253
|
-
delete obj[LEGACY_OID_KEY];
|
|
254
|
-
delete obj[OID_KEY];
|
|
255
|
-
return obj;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
function transferOidFromSystemToProperty(obj: any) {
|
|
259
|
-
const oid = maybeGetOid(obj);
|
|
260
|
-
if (oid) {
|
|
261
|
-
assignOidProperty(obj, oid);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Assigns a special property to all objects in the given object
|
|
267
|
-
* which have an OID
|
|
268
|
-
*/
|
|
269
|
-
export function assignOidPropertiesToAllSubObjects(obj: any) {
|
|
270
|
-
transferOidFromSystemToProperty(obj);
|
|
271
|
-
|
|
272
|
-
if (Array.isArray(obj)) {
|
|
273
|
-
for (let i = 0; i < obj.length; i++) {
|
|
274
|
-
assignOidPropertiesToAllSubObjects(obj[i]);
|
|
275
|
-
}
|
|
276
|
-
} else if (isObject(obj)) {
|
|
277
|
-
for (const key of Object.keys(obj)) {
|
|
278
|
-
assignOidPropertiesToAllSubObjects(obj[key]);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
function copyOidFromPropertyToSystem(obj: any) {
|
|
284
|
-
const oid = maybeGetOidProperty(obj);
|
|
285
|
-
if (oid) {
|
|
286
|
-
assignOid(obj, oid);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
/**
|
|
291
|
-
*
|
|
292
|
-
* Removes the special property from all objects in the given object
|
|
293
|
-
* which have an OID, transferring the OID from the property to the OID
|
|
294
|
-
* system in-memory.
|
|
295
|
-
*/
|
|
296
|
-
export function removeOidPropertiesFromAllSubObjects(obj: any) {
|
|
297
|
-
copyOidFromPropertyToSystem(obj);
|
|
298
|
-
removeOidProperty(obj);
|
|
299
|
-
|
|
300
|
-
if (Array.isArray(obj)) {
|
|
301
|
-
for (let i = 0; i < obj.length; i++) {
|
|
302
|
-
removeOidPropertiesFromAllSubObjects(obj[i]);
|
|
303
|
-
}
|
|
304
|
-
} else if (isObject(obj)) {
|
|
305
|
-
for (const key of Object.keys(obj)) {
|
|
306
|
-
removeOidPropertiesFromAllSubObjects(obj[key]);
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
239
|
export function removeOidsFromAllSubObjects(obj: any) {
|
|
312
240
|
removeOid(obj);
|
|
313
241
|
|
|
@@ -442,10 +370,6 @@ export function getOidSubIdRange(oid: ObjectIdentifier) {
|
|
|
442
370
|
const lastSubId = createSubOid(root, () => '\uffff');
|
|
443
371
|
return [`${root}${RANDOM_SEPARATOR}`, lastSubId];
|
|
444
372
|
}
|
|
445
|
-
export function getLegacyDotOidSubIdRange(oid: ObjectIdentifier) {
|
|
446
|
-
const root = getOidRoot(oid);
|
|
447
|
-
return [`${root}.`, `${root}.\uffff`];
|
|
448
|
-
}
|
|
449
373
|
|
|
450
374
|
export function getRoots(oids: ObjectIdentifier[]) {
|
|
451
375
|
const set = new Set<ObjectIdentifier>();
|
|
@@ -459,6 +383,10 @@ export function areOidsRelated(oidA: ObjectIdentifier, oidB: ObjectIdentifier) {
|
|
|
459
383
|
return getOidRoot(oidA) === getOidRoot(oidB);
|
|
460
384
|
}
|
|
461
385
|
|
|
386
|
+
export function isRootOid(oid: ObjectIdentifier) {
|
|
387
|
+
return !oid.includes(RANDOM_SEPARATOR);
|
|
388
|
+
}
|
|
389
|
+
|
|
462
390
|
/**
|
|
463
391
|
* Recursively rewrites any OIDs in an object which are 'foreign' -
|
|
464
392
|
* i.e. relate to some other object/entity - to be local to the
|
|
@@ -493,29 +421,3 @@ function migrateForeignOid(parentOid: ObjectIdentifier, child: any) {
|
|
|
493
421
|
);
|
|
494
422
|
}
|
|
495
423
|
}
|
|
496
|
-
|
|
497
|
-
export function isLegacyDotOid(oid: ObjectIdentifier) {
|
|
498
|
-
const partBeforeRandomSep = oid.split(RANDOM_SEPARATOR)[0];
|
|
499
|
-
return partBeforeRandomSep.includes('.');
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
export function convertLegacyOid(oid: ObjectIdentifier) {
|
|
503
|
-
const { collection, id, subId } = decomposeOid(oid);
|
|
504
|
-
return createOid(collection, id, subId);
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
export const MATCH_LEGACY_OID_JSON_STRING = /"\w+\/[^"]+?(\.[^"]+)+\:[\S]+?"/g;
|
|
508
|
-
export function replaceLegacyOidsInJsonString(string: string) {
|
|
509
|
-
// replace every match of a legacy OID, converting to a new OID
|
|
510
|
-
return string.replaceAll(MATCH_LEGACY_OID_JSON_STRING, (match) => {
|
|
511
|
-
const legacyOid = match.slice(1, match.length - 1);
|
|
512
|
-
return `"${convertLegacyOid(legacyOid)}"`;
|
|
513
|
-
});
|
|
514
|
-
}
|
|
515
|
-
export function replaceLegacyOidsInObject(obj: any) {
|
|
516
|
-
return JSON.parse(replaceLegacyOidsInJsonString(JSON.stringify(obj)));
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
export function isRootOid(oid: ObjectIdentifier) {
|
|
520
|
-
return !oid.includes(RANDOM_SEPARATOR);
|
|
521
|
-
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import {
|
|
3
|
+
getLegacyDotOidSubIdRange,
|
|
4
|
+
MATCH_LEGACY_OID_JSON_STRING,
|
|
5
|
+
replaceLegacyOidsInObject,
|
|
6
|
+
} from './oidsLegacy.js';
|
|
7
|
+
import {
|
|
8
|
+
areOidsRelated,
|
|
9
|
+
createSubOid,
|
|
10
|
+
getOidRoot,
|
|
11
|
+
ObjectIdentifier,
|
|
12
|
+
} from './oids.js';
|
|
13
|
+
|
|
14
|
+
describe('handling legacy OIDs', () => {
|
|
15
|
+
it('should get the root OID for a legacy OID', () => {
|
|
16
|
+
expect(getOidRoot('items/clabgyjfh00003968qycsq3ld.inputs.#')).toEqual(
|
|
17
|
+
'items/clabgyjfh00003968qycsq3ld',
|
|
18
|
+
);
|
|
19
|
+
});
|
|
20
|
+
it('should create sub-ids for legacy OIDs in new format', () => {
|
|
21
|
+
expect(
|
|
22
|
+
createSubOid(
|
|
23
|
+
'items/clabgyjfh00003968qycsq3ld.inputs.#',
|
|
24
|
+
() => 'pseudorandom',
|
|
25
|
+
),
|
|
26
|
+
).toEqual('items/clabgyjfh00003968qycsq3ld:pseudorandom');
|
|
27
|
+
});
|
|
28
|
+
it('should identify new sub-OIDs as related to the legacy root OID', () => {
|
|
29
|
+
expect(
|
|
30
|
+
areOidsRelated(
|
|
31
|
+
'items/clabgyjfh00003968qycsq3ld.inputs.#',
|
|
32
|
+
'items/clabgyjfh00003968qycsq3ld:pseudorandom',
|
|
33
|
+
),
|
|
34
|
+
).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
it.each([
|
|
37
|
+
['items/clabgyjfh00003968qycsq3ld.inputs.#:baz', true],
|
|
38
|
+
// include more unicode chars
|
|
39
|
+
['items/clabgyjfh00003968qycsq3ld\ufea3.inputs\u39fc.#:baz!!!', true],
|
|
40
|
+
// not matching new oids
|
|
41
|
+
['items/clabgyjfh00003968qycsq3ld', false],
|
|
42
|
+
['items/clabgyjfh00003968qycsq3ld:baz', false],
|
|
43
|
+
['items/clabgyjfh00003968qycsq3ld:baz1111', false],
|
|
44
|
+
// not matching anything else
|
|
45
|
+
[
|
|
46
|
+
'PREPARE SOUS VIDE BATH: Fill container or pot with water. Set the temperature to 130F/54.4C – 132F/55.5C (for very moist and tender) and allow water to heat to that temperature.Tip: start with hot tap water instead of cold water to reduce heating time. Note 4 for other temperatures.',
|
|
47
|
+
false,
|
|
48
|
+
],
|
|
49
|
+
])('matches legacy oids', (oid, match) => {
|
|
50
|
+
expect(MATCH_LEGACY_OID_JSON_STRING.test('"' + oid + '"'), oid).toBe(match);
|
|
51
|
+
// regex are stateful 🙄
|
|
52
|
+
MATCH_LEGACY_OID_JSON_STRING.lastIndex = 0;
|
|
53
|
+
});
|
|
54
|
+
it.each([
|
|
55
|
+
[
|
|
56
|
+
{ op: 'delete', oid: 'items/clabgyjfh00003968qycsq3ld.inputs.#:baz' },
|
|
57
|
+
{ op: 'delete', oid: 'items/clabgyjfh00003968qycsq3ld:baz' },
|
|
58
|
+
],
|
|
59
|
+
[
|
|
60
|
+
{
|
|
61
|
+
op: 'list-push',
|
|
62
|
+
oid: 'items/clabgyjfh00003968qycsq3ld.inputs.#:baz',
|
|
63
|
+
value: {
|
|
64
|
+
'@@type': 'ref',
|
|
65
|
+
id: 'items/clabgyjfh00003968qycsq3ld.inputs.#:qux',
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
op: 'list-push',
|
|
70
|
+
oid: 'items/clabgyjfh00003968qycsq3ld:baz',
|
|
71
|
+
value: { '@@type': 'ref', id: 'items/clabgyjfh00003968qycsq3ld:qux' },
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
[
|
|
75
|
+
{
|
|
76
|
+
op: 'list-remove',
|
|
77
|
+
oid: 'items/clabgyjfh00003968qycsq3ld.inputs.#:baz',
|
|
78
|
+
value: {
|
|
79
|
+
'@@type': 'ref',
|
|
80
|
+
id: 'items/clabgyjfh00003968qycsq3ld.inputs.#:qux',
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
op: 'list-remove',
|
|
85
|
+
oid: 'items/clabgyjfh00003968qycsq3ld:baz',
|
|
86
|
+
value: { '@@type': 'ref', id: 'items/clabgyjfh00003968qycsq3ld:qux' },
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
[
|
|
90
|
+
{
|
|
91
|
+
oid: 'items/clabgyjfh00003968qycsq3ld.inputs.#:baz',
|
|
92
|
+
timestamp: '2021-03-04T21:00:00.000Z',
|
|
93
|
+
snapshot: {
|
|
94
|
+
foo: 1,
|
|
95
|
+
bar: {
|
|
96
|
+
'@@type': 'ref',
|
|
97
|
+
id: 'items/clabgyjfh00003968qycsq3ld.inputs.#:qux',
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
oid: 'items/clabgyjfh00003968qycsq3ld:baz',
|
|
103
|
+
timestamp: '2021-03-04T21:00:00.000Z',
|
|
104
|
+
snapshot: {
|
|
105
|
+
foo: 1,
|
|
106
|
+
bar: { '@@type': 'ref', id: 'items/clabgyjfh00003968qycsq3ld:qux' },
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
[
|
|
111
|
+
{ oid: 'test/what if.boo.blah so what:fajsdfj' },
|
|
112
|
+
{ oid: 'test/what if:fajsdfj' },
|
|
113
|
+
],
|
|
114
|
+
])(
|
|
115
|
+
'should replace legacy OIDs in a JSON string with new OIDs',
|
|
116
|
+
(from, to) => {
|
|
117
|
+
expect(replaceLegacyOidsInObject(from), JSON.stringify(from)).toEqual(to);
|
|
118
|
+
},
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
it('should accommodate legacy dot style oids when computing ranges', () => {
|
|
122
|
+
function isWithin(
|
|
123
|
+
oid: ObjectIdentifier,
|
|
124
|
+
start: ObjectIdentifier,
|
|
125
|
+
end: ObjectIdentifier,
|
|
126
|
+
) {
|
|
127
|
+
return oid >= start && oid <= end;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const [start, end] = getLegacyDotOidSubIdRange('test/a.foo:barrrr');
|
|
131
|
+
expect(start).toEqual('test/a.');
|
|
132
|
+
expect(end).toEqual('test/a.\uffff');
|
|
133
|
+
expect(start < end).toBe(true);
|
|
134
|
+
expect(isWithin('test/a.foo:0', start, end)).toBe(true);
|
|
135
|
+
expect(isWithin('test/a.foo:1', start, end)).toBe(true);
|
|
136
|
+
expect(isWithin('test/a.bar:zzzzzzzzzzzzzzzzzzzzzzz', start, end)).toBe(
|
|
137
|
+
true,
|
|
138
|
+
);
|
|
139
|
+
expect(isWithin('test/a.aff:\uffff', start, end)).toBe(true);
|
|
140
|
+
expect(isWithin('test1/a', start, end)).toBe(false);
|
|
141
|
+
expect(isWithin('test/b', start, end)).toBe(false);
|
|
142
|
+
expect(isWithin('test/ ', start, end)).toBe(false);
|
|
143
|
+
expect(isWithin('test/a1', start, end)).toBe(false);
|
|
144
|
+
expect(isWithin('test/a1:3', start, end)).toBe(false);
|
|
145
|
+
expect(isWithin('test/a.foo:barrrr', start, end)).toBe(true);
|
|
146
|
+
});
|
|
147
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import {
|
|
2
|
+
assignOid,
|
|
3
|
+
createOid,
|
|
4
|
+
decomposeOid,
|
|
5
|
+
getOidRoot,
|
|
6
|
+
ObjectIdentifier,
|
|
7
|
+
} from './oids.js';
|
|
8
|
+
import { isObject } from './utils.js';
|
|
9
|
+
|
|
10
|
+
export const LEGACY_OID_KEY = '__@@oid_do_not_use';
|
|
11
|
+
export const OID_KEY = '@@id';
|
|
12
|
+
|
|
13
|
+
export function maybeGetOidProperty(obj: any) {
|
|
14
|
+
if (!isObject(obj)) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
return obj[OID_KEY] || obj[LEGACY_OID_KEY];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function removeOidProperty(obj: any) {
|
|
21
|
+
if (!isObject(obj)) {
|
|
22
|
+
return obj;
|
|
23
|
+
}
|
|
24
|
+
delete obj[LEGACY_OID_KEY];
|
|
25
|
+
delete obj[OID_KEY];
|
|
26
|
+
return obj;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function copyOidFromPropertyToSystem(obj: any) {
|
|
30
|
+
const oid = maybeGetOidProperty(obj);
|
|
31
|
+
if (oid) {
|
|
32
|
+
assignOid(obj, oid);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
*
|
|
38
|
+
* Removes the special property from all objects in the given object
|
|
39
|
+
* which have an OID, transferring the OID from the property to the OID
|
|
40
|
+
* system in-memory.
|
|
41
|
+
*/
|
|
42
|
+
export function removeOidPropertiesFromAllSubObjects(obj: any) {
|
|
43
|
+
copyOidFromPropertyToSystem(obj);
|
|
44
|
+
removeOidProperty(obj);
|
|
45
|
+
|
|
46
|
+
if (Array.isArray(obj)) {
|
|
47
|
+
for (let i = 0; i < obj.length; i++) {
|
|
48
|
+
removeOidPropertiesFromAllSubObjects(obj[i]);
|
|
49
|
+
}
|
|
50
|
+
} else if (isObject(obj)) {
|
|
51
|
+
for (const key of Object.keys(obj)) {
|
|
52
|
+
removeOidPropertiesFromAllSubObjects(obj[key]);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function isLegacyDotOid(oid: ObjectIdentifier) {
|
|
58
|
+
const partBeforeRandomSep = oid.split(':')[0];
|
|
59
|
+
return partBeforeRandomSep.includes('.');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function convertLegacyOid(oid: ObjectIdentifier) {
|
|
63
|
+
const { collection, id, subId } = decomposeOid(oid);
|
|
64
|
+
return createOid(collection, id, subId);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// NOTE: all legacy OIDs should now be gone.
|
|
68
|
+
export const MATCH_LEGACY_OID_JSON_STRING = /"\w+\/[^"]+?(\.[^"]+)+\:[\S]+?"/g;
|
|
69
|
+
export function replaceLegacyOidsInJsonString(string: string) {
|
|
70
|
+
// replace every match of a legacy OID, converting to a new OID
|
|
71
|
+
return string.replaceAll(MATCH_LEGACY_OID_JSON_STRING, (match) => {
|
|
72
|
+
const legacyOid = match.slice(1, match.length - 1);
|
|
73
|
+
return `"${convertLegacyOid(legacyOid)}"`;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
export function replaceLegacyOidsInObject(obj: any) {
|
|
77
|
+
return JSON.parse(replaceLegacyOidsInJsonString(JSON.stringify(obj)));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function getLegacyDotOidSubIdRange(oid: ObjectIdentifier) {
|
|
81
|
+
const root = getOidRoot(oid);
|
|
82
|
+
return [`${root}.`, `${root}.\uffff`];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function isOidKey(key: string) {
|
|
86
|
+
return key === OID_KEY || key === LEGACY_OID_KEY;
|
|
87
|
+
}
|