@verdant-web/common 2.8.0 → 2.9.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.
@@ -1,5 +1,6 @@
1
- import { isFile, isFileData } from '../files.js';
1
+ import { isFile, isFileData, isFileRef } from '../files.js';
2
2
  import { OID_KEY } from '../oidsLegacy.js';
3
+ import { isObjectRef } from '../operation.js';
3
4
  import { isObject } from '../utils.js';
4
5
  import { hasDefault, isNullable } from './fields.js';
5
6
  export function validateEntity(schema, entity) {
@@ -26,12 +27,15 @@ export function validateEntity(schema, entity) {
26
27
  }
27
28
  return;
28
29
  }
29
- export function validateEntityField({ field, value, fieldPath = [], depth, requireDefaults, }) {
30
+ export function validateEntityField({ field, value, fieldPath = [], depth, requireDefaults, expectRefs, hasPassedFirstLevel, }) {
31
+ // we only _actually_ start expecting refs after the first validation level.
32
+ // TODO: something more... elegant?
33
+ const actuallyExpectRefs = expectRefs && hasPassedFirstLevel;
30
34
  if (depth !== undefined && depth <= 0)
31
35
  return;
32
- if (isNullable(field) && value === null)
36
+ if (isNullable(field) && (value === null || value === undefined))
33
37
  return;
34
- if (value === null) {
38
+ if (value === null || value === undefined) {
35
39
  if (requireDefaults || !hasDefault(field)) {
36
40
  return {
37
41
  type: 'no-default',
@@ -41,71 +45,117 @@ export function validateEntityField({ field, value, fieldPath = [], depth, requi
41
45
  }
42
46
  }
43
47
  if (field.type === 'object') {
44
- if (!isObject(value)) {
45
- return {
46
- type: 'invalid-type',
47
- fieldPath,
48
- message: `Expected object ${field.nullable ? 'or null ' : ''}for field ${formatField(fieldPath)}, got ${value}`,
49
- };
48
+ if (actuallyExpectRefs) {
49
+ if (!isObjectRef(value)) {
50
+ return {
51
+ type: 'invalid-type',
52
+ fieldPath,
53
+ message: `Expected ref for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,
54
+ };
55
+ }
50
56
  }
51
- for (const [key, subField] of Object.entries(field.properties)) {
52
- // legacy -- old objects sometimes accidentally include this key
53
- if (key === OID_KEY)
54
- continue;
55
- if (value[key]) {
56
- validateEntityField({
57
+ else {
58
+ if (!isObject(value)) {
59
+ return {
60
+ type: 'invalid-type',
61
+ fieldPath,
62
+ message: `Expected object ${field.nullable ? 'or null ' : ''}for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,
63
+ };
64
+ }
65
+ for (const [key, subField] of Object.entries(field.properties)) {
66
+ // legacy -- old objects sometimes accidentally include this key
67
+ if (key === OID_KEY)
68
+ continue;
69
+ const error = validateEntityField({
57
70
  field: subField,
58
71
  value: value[key],
59
72
  fieldPath: [...fieldPath, key],
60
73
  depth: depth !== undefined ? depth - 1 : undefined,
74
+ expectRefs,
75
+ hasPassedFirstLevel: true,
61
76
  });
77
+ if (error) {
78
+ return error;
79
+ }
62
80
  }
63
- }
64
- // check for unexpected keys
65
- for (const key of Object.keys(value)) {
66
- if (!field.properties[key]) {
67
- return {
68
- type: 'invalid-key',
69
- fieldPath: [...fieldPath, key],
70
- message: `Invalid unexpected field "${key}" on value ${formatField(fieldPath)}`,
71
- };
81
+ // check for unexpected keys
82
+ for (const key of Object.keys(value)) {
83
+ if (!field.properties[key]) {
84
+ return {
85
+ type: 'invalid-key',
86
+ fieldPath: [...fieldPath, key],
87
+ message: `Invalid unexpected field "${key}" on value ${formatField(fieldPath)}`,
88
+ };
89
+ }
72
90
  }
73
91
  }
74
92
  }
75
93
  else if (field.type === 'array') {
76
- if (!Array.isArray(value)) {
77
- if (value === null && field.nullable)
78
- return;
79
- return {
80
- type: 'invalid-value',
81
- fieldPath,
82
- message: `Expected array ${field.nullable ? 'or null ' : ''}for field ${formatField(fieldPath)}, got ${value}`,
83
- };
94
+ if (actuallyExpectRefs) {
95
+ if (!isObjectRef(value)) {
96
+ return {
97
+ type: 'invalid-type',
98
+ fieldPath,
99
+ message: `Expected ref for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,
100
+ };
101
+ }
84
102
  }
85
- for (const item of value) {
86
- validateEntityField({
87
- field: field.items,
88
- value: item,
89
- fieldPath: [...fieldPath, '[]'],
90
- depth: depth !== undefined ? depth - 1 : undefined,
91
- });
103
+ else {
104
+ if (!Array.isArray(value)) {
105
+ if (value === null && field.nullable)
106
+ return;
107
+ return {
108
+ type: 'invalid-value',
109
+ fieldPath,
110
+ message: `Expected array ${field.nullable ? 'or null ' : ''}for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,
111
+ };
112
+ }
113
+ for (const item of value) {
114
+ const error = validateEntityField({
115
+ field: field.items,
116
+ value: item,
117
+ fieldPath: [...fieldPath, '[]'],
118
+ depth: depth !== undefined ? depth - 1 : undefined,
119
+ expectRefs,
120
+ hasPassedFirstLevel: true,
121
+ });
122
+ if (error) {
123
+ return error;
124
+ }
125
+ }
92
126
  }
93
127
  }
94
128
  else if (field.type === 'map') {
95
- if (!isObject(value)) {
96
- return {
97
- type: 'invalid-type',
98
- fieldPath,
99
- message: `Expected map for field ${formatField(fieldPath)}, got ${value}`,
100
- };
129
+ if (actuallyExpectRefs) {
130
+ if (!isObjectRef(value)) {
131
+ return {
132
+ type: 'invalid-type',
133
+ fieldPath,
134
+ message: `Expected ref for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,
135
+ };
136
+ }
101
137
  }
102
- for (const [key, item] of Object.entries(value)) {
103
- validateEntityField({
104
- field: field.values,
105
- value: item,
106
- fieldPath: [...fieldPath, key],
107
- depth: depth !== undefined ? depth - 1 : undefined,
108
- });
138
+ else {
139
+ if (!isObject(value)) {
140
+ return {
141
+ type: 'invalid-type',
142
+ fieldPath,
143
+ message: `Expected map for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,
144
+ };
145
+ }
146
+ for (const [key, item] of Object.entries(value)) {
147
+ const error = validateEntityField({
148
+ field: field.values,
149
+ value: item,
150
+ fieldPath: [...fieldPath, key],
151
+ depth: depth !== undefined ? depth - 1 : undefined,
152
+ expectRefs,
153
+ hasPassedFirstLevel: true,
154
+ });
155
+ if (error) {
156
+ return error;
157
+ }
158
+ }
109
159
  }
110
160
  }
111
161
  else if (field.type === 'string') {
@@ -113,14 +163,14 @@ export function validateEntityField({ field, value, fieldPath = [], depth, requi
113
163
  return {
114
164
  type: 'invalid-type',
115
165
  fieldPath,
116
- message: `Expected string ${field.nullable ? 'or null ' : ''}for field ${formatField(fieldPath)}, got ${value}`,
166
+ message: `Expected string ${field.nullable ? 'or null ' : ''}for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,
117
167
  };
118
168
  }
119
169
  if (field.options && !field.options.includes(value)) {
120
170
  return {
121
171
  type: 'invalid-value',
122
172
  fieldPath,
123
- message: `Expected one of ${field.options.join(', ')} for field ${formatField(fieldPath)}, got ${value}`,
173
+ message: `Expected one of ${field.options.join(', ')} for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,
124
174
  };
125
175
  }
126
176
  }
@@ -129,7 +179,7 @@ export function validateEntityField({ field, value, fieldPath = [], depth, requi
129
179
  return {
130
180
  type: 'invalid-type',
131
181
  fieldPath,
132
- message: `Expected boolean ${field.nullable ? 'or null ' : ''}for field ${formatField(fieldPath)}, got ${value}`,
182
+ message: `Expected boolean ${field.nullable ? 'or null ' : ''}for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,
133
183
  };
134
184
  }
135
185
  }
@@ -138,20 +188,40 @@ export function validateEntityField({ field, value, fieldPath = [], depth, requi
138
188
  return {
139
189
  type: 'invalid-type',
140
190
  fieldPath,
141
- message: `Expected number ${field.nullable ? 'or null ' : ''}for field ${formatField(fieldPath)}, got ${value}`,
191
+ message: `Expected number ${field.nullable ? 'or null ' : ''}for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,
142
192
  };
143
193
  }
144
194
  }
145
195
  else if (field.type === 'file') {
146
- if (!isFile(value) && !isFileData(value)) {
147
- return {
148
- type: 'invalid-type',
149
- fieldPath,
150
- message: `Expected file ${field.nullable ? 'or null ' : ''}for field ${formatField(fieldPath)}, got ${value}`,
151
- };
196
+ if (actuallyExpectRefs) {
197
+ if (!isFileRef(value)) {
198
+ return {
199
+ type: 'invalid-type',
200
+ fieldPath,
201
+ message: `Expected file ref for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,
202
+ };
203
+ }
204
+ }
205
+ else {
206
+ if (!isFile(value) && !isFileData(value)) {
207
+ return {
208
+ type: 'invalid-type',
209
+ fieldPath,
210
+ message: `Expected file ${field.nullable ? 'or null ' : ''}for field ${formatField(fieldPath)}, got ${safeStringify(value)}`,
211
+ };
212
+ }
152
213
  }
153
214
  }
154
215
  }
216
+ function safeStringify(value) {
217
+ try {
218
+ return JSON.stringify(value);
219
+ }
220
+ catch (err) {
221
+ // for example, recursive objects can't be stringified
222
+ return String(value);
223
+ }
224
+ }
155
225
  function formatField(fieldPath) {
156
226
  if (fieldPath.length === 0)
157
227
  return 'root';
@@ -1 +1 @@
1
- {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../src/schema/validation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../src/schema/validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,60 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { createFileRef } from '../files.js';
3
+ import { createRef } from '../oids.js';
4
+ import { schema, validateEntityField } from './index.js';
5
+ describe('validation', () => {
6
+ it('validates shallowly with refs', () => {
7
+ const fieldSchema = schema.fields.object({
8
+ fields: {
9
+ obj: schema.fields.object({
10
+ fields: {},
11
+ }),
12
+ file: schema.fields.file(),
13
+ },
14
+ });
15
+ expect(validateEntityField({
16
+ field: fieldSchema,
17
+ value: {
18
+ obj: createRef('some/id:1'),
19
+ file: createFileRef('somefile'),
20
+ },
21
+ fieldPath: [],
22
+ expectRefs: true,
23
+ })).toBeUndefined();
24
+ expect(validateEntityField({
25
+ field: fieldSchema,
26
+ value: {
27
+ obj: createRef('some/id:1'),
28
+ file: createRef('some/object:1'),
29
+ },
30
+ fieldPath: [],
31
+ expectRefs: true,
32
+ })).toMatchInlineSnapshot(`
33
+ {
34
+ "fieldPath": [
35
+ "file",
36
+ ],
37
+ "message": "Expected file ref for field file, got {"@@type":"ref","id":"some/object:1"}",
38
+ "type": "invalid-type",
39
+ }
40
+ `);
41
+ expect(validateEntityField({
42
+ field: fieldSchema,
43
+ value: {
44
+ obj: 'foo',
45
+ file: createFileRef('somefile'),
46
+ },
47
+ fieldPath: [],
48
+ expectRefs: true,
49
+ })).toMatchInlineSnapshot(`
50
+ {
51
+ "fieldPath": [
52
+ "obj",
53
+ ],
54
+ "message": "Expected ref for field obj, got "foo"",
55
+ "type": "invalid-type",
56
+ }
57
+ `);
58
+ });
59
+ });
60
+ //# sourceMappingURL=validation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.test.js","sourceRoot":"","sources":["../../../src/schema/validation.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEzD,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACxC,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;YACxC,MAAM,EAAE;gBACP,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;oBACzB,MAAM,EAAE,EAAE;iBACV,CAAC;gBACF,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;aAC1B;SACD,CAAC,CAAC;QACH,MAAM,CACL,mBAAmB,CAAC;YACnB,KAAK,EAAE,WAAW;YAClB,KAAK,EAAE;gBACN,GAAG,EAAE,SAAS,CAAC,WAAW,CAAC;gBAC3B,IAAI,EAAE,aAAa,CAAC,UAAU,CAAC;aAC/B;YACD,SAAS,EAAE,EAAE;YACb,UAAU,EAAE,IAAI;SAChB,CAAC,CACF,CAAC,aAAa,EAAE,CAAC;QAClB,MAAM,CACL,mBAAmB,CAAC;YACnB,KAAK,EAAE,WAAW;YAClB,KAAK,EAAE;gBACN,GAAG,EAAE,SAAS,CAAC,WAAW,CAAC;gBAC3B,IAAI,EAAE,SAAS,CAAC,eAAe,CAAC;aAChC;YACD,SAAS,EAAE,EAAE;YACb,UAAU,EAAE,IAAI;SAChB,CAAC,CACF,CAAC,qBAAqB,CAAC;;;;;;;;GAQvB,CAAC,CAAC;QACH,MAAM,CACL,mBAAmB,CAAC;YACnB,KAAK,EAAE,WAAW;YAClB,KAAK,EAAE;gBACN,GAAG,EAAE,KAAK;gBACV,IAAI,EAAE,aAAa,CAAC,UAAU,CAAC;aAC/B;YACD,SAAS,EAAE,EAAE;YACb,UAAU,EAAE,IAAI;SAChB,CAAC,CACF,CAAC,qBAAqB,CAAC;;;;;;;;GAQvB,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { AuthorizationKey } from './authz.js';
1
2
  import { ObjectIdentifier } from './oids.js';
2
3
  import { Operation } from './operation.js';
3
- export declare function getUndoOperations(oid: ObjectIdentifier, initial: any, operations: Operation[], getNow: () => string): Operation[];
4
+ export declare function getUndoOperations(oid: ObjectIdentifier, initial: any, operations: Operation[], getNow: () => string, getSubId?: () => string, authz?: AuthorizationKey): Operation[];
package/dist/esm/undo.js CHANGED
@@ -1,6 +1,9 @@
1
1
  import { applyPatch } from './operation.js';
2
+ import { PatchCreator } from './patch.js';
3
+ import { isRef } from './refs.js';
2
4
  import { cloneDeep } from './utils.js';
3
- export function getUndoOperations(oid, initial, operations, getNow) {
5
+ export function getUndoOperations(oid, initial, operations, getNow, getSubId, authz) {
6
+ const patchCreator = new PatchCreator(getNow, getSubId);
4
7
  if (initial === undefined || initial === null) {
5
8
  // if the initial state is nothing, then the undo is to delete everything.
6
9
  // there's nothing else to worry about!
@@ -11,6 +14,7 @@ export function getUndoOperations(oid, initial, operations, getNow) {
11
14
  data: {
12
15
  op: 'delete',
13
16
  },
17
+ authz,
14
18
  },
15
19
  ];
16
20
  }
@@ -20,203 +24,93 @@ export function getUndoOperations(oid, initial, operations, getNow) {
20
24
  let state = cloneDeep(initial);
21
25
  const undoOperations = [];
22
26
  for (const operation of operations) {
23
- const undo = getUndoOperation(oid, state, operation, getNow);
27
+ const undo = getUndoOperation(oid, state, operation, patchCreator, authz);
24
28
  undoOperations.unshift(...undo);
25
29
  applyPatch(state, operation.data);
26
30
  }
27
31
  return undoOperations;
28
32
  }
29
- function getUndoOperation(oid, initial, operation, getNow) {
33
+ function getUndoOperation(oid, initial, operation, patchCreator, authz) {
34
+ var _a, _b;
30
35
  const data = operation.data;
31
36
  switch (data.op) {
32
37
  case 'set':
38
+ if (initial[data.name] === undefined) {
39
+ return patchCreator.createRemove(oid, data.name, authz);
40
+ }
41
+ return patchCreator.createSet(oid, data.name, initial[data.name], authz);
33
42
  case 'remove':
34
- return [
35
- {
36
- oid,
37
- timestamp: getNow(),
38
- data: {
39
- op: 'set',
40
- name: data.name,
41
- value: initial[data.name],
42
- },
43
- },
44
- ];
43
+ if (initial[data.name] === undefined) {
44
+ return [];
45
+ }
46
+ return patchCreator.createSet(oid, data.name, initial[data.name], authz);
45
47
  case 'list-insert':
46
- return [
47
- {
48
- oid,
49
- timestamp: getNow(),
50
- data: {
51
- op: 'list-delete',
52
- index: data.index,
53
- count: 1,
54
- },
55
- },
56
- ];
48
+ if (data.value === undefined && ((_a = data.values) === null || _a === void 0 ? void 0 : _a.length) === 0)
49
+ return [];
50
+ return patchCreator.createListDelete(oid, data.index, data.value ? 1 : ((_b = data.values) === null || _b === void 0 ? void 0 : _b.length) || 0, authz);
57
51
  case 'list-delete':
58
- return [
59
- {
60
- oid,
61
- timestamp: getNow(),
62
- data: {
63
- op: 'list-insert',
64
- index: data.index,
65
- values: initial.slice(data.index, data.count),
66
- },
67
- },
68
- ];
52
+ return patchCreator.createListInsertMany(oid, data.index, initial.slice(data.index, data.index + data.count), authz);
69
53
  case 'list-move-by-ref':
70
- return [
71
- {
72
- oid,
73
- timestamp: getNow(),
74
- data: {
75
- op: 'list-move-by-ref',
76
- value: data.value,
77
- index: initial.indexOf(data.value),
78
- },
79
- },
80
- ];
54
+ return patchCreator.createListMoveByRef(oid, data.value, findItemRefIndex(initial, data.value), authz);
81
55
  case 'list-move-by-index':
82
- return [
83
- {
84
- oid,
85
- timestamp: getNow(),
86
- data: {
87
- op: 'list-move-by-index',
88
- from: data.to,
89
- to: data.from,
90
- },
91
- },
92
- ];
56
+ return patchCreator.createListMoveByIndex(oid, data.to, data.from, authz);
93
57
  case 'delete':
94
- return [
95
- {
96
- oid,
97
- timestamp: getNow(),
98
- data: {
99
- op: 'initialize',
100
- value: initial,
101
- },
102
- },
103
- ];
58
+ return patchCreator.createInitialize(initial, oid, authz, true);
104
59
  case 'list-push':
105
- return [
106
- {
107
- oid,
108
- timestamp: getNow(),
109
- data: {
110
- op: 'list-remove',
111
- value: data.value,
112
- // best heuristic here - remove the last instance of the item.
113
- only: 'last',
114
- },
115
- },
116
- ];
60
+ return patchCreator.createListRemove(oid, data.value, 'last', authz);
117
61
  case 'list-remove':
118
62
  if (data.only === 'last') {
119
- const index = initial.lastIndexOf(data.value);
120
- return [
121
- {
122
- oid,
123
- timestamp: getNow(),
124
- data: {
125
- op: 'list-insert',
126
- index,
127
- values: [data.value],
128
- },
129
- },
130
- ];
63
+ const index = findItemRefIndex(initial, data.value, 0, 'backward');
64
+ if (index === -1) {
65
+ // if the value isn't in the list, then there's nothing to undo.
66
+ return [];
67
+ }
68
+ return patchCreator.createListInsert(oid, index, data.value, authz);
131
69
  }
132
70
  else if (data.only === 'first') {
133
- const index = initial.indexOf(data.value);
134
- return [
135
- {
136
- oid,
137
- timestamp: getNow(),
138
- data: {
139
- op: 'list-insert',
140
- index,
141
- values: [data.value],
142
- },
143
- },
144
- ];
71
+ const index = findItemRefIndex(initial, data.value);
72
+ if (index === -1) {
73
+ // if the value isn't in the list, then there's nothing to undo.
74
+ return [];
75
+ }
76
+ return patchCreator.createListInsert(oid, index, data.value, authz);
145
77
  }
146
78
  else {
147
79
  // find all instances of value and restore them at their
148
80
  // original index
149
81
  const indexesOfValue = [];
150
- let index = initial.indexOf(data.value);
82
+ let index = findItemRefIndex(initial, data.value);
151
83
  while (index !== -1) {
152
84
  indexesOfValue.push(index);
153
- index = initial.indexOf(data.value, index + 1);
85
+ index = findItemRefIndex(initial, data.value, index + 1);
154
86
  }
155
- return indexesOfValue.map((index) => ({
156
- oid,
157
- timestamp: getNow(),
158
- data: {
159
- op: 'list-insert',
160
- index,
161
- value: data.value,
162
- },
163
- }));
87
+ return indexesOfValue.flatMap((index) => patchCreator.createListInsert(oid, index, data.value, authz));
164
88
  }
165
89
  case 'list-add':
166
90
  // this one is kind of ambiguous. in theory the set may have
167
91
  // already included the value and so no change happened. but
168
92
  // basically we infer the intent is to remove what was meant
169
93
  // to be added by this change.
170
- return [
171
- {
172
- oid,
173
- timestamp: getNow(),
174
- data: {
175
- op: 'list-remove',
176
- value: data.value,
177
- only: 'last',
178
- },
179
- },
180
- ];
94
+ return patchCreator.createListRemove(oid, data.value, 'last', authz);
181
95
  case 'list-set':
182
- if (initial[data.index]) {
183
- return [
184
- {
185
- oid,
186
- timestamp: getNow(),
187
- data: {
188
- op: 'list-set',
189
- index: data.index,
190
- value: initial[data.index],
191
- },
192
- },
193
- ];
96
+ if (initial[data.index] !== undefined) {
97
+ return patchCreator.createListSet(oid, data.index, initial[data.index], authz);
194
98
  }
195
- return [
196
- {
197
- oid,
198
- timestamp: getNow(),
199
- data: {
200
- op: 'list-delete',
201
- index: data.index,
202
- count: 1,
203
- },
204
- },
205
- ];
99
+ return patchCreator.createListDelete(oid, data.index, 1, authz);
206
100
  case 'initialize':
207
- return [
208
- {
209
- oid,
210
- timestamp: getNow(),
211
- data: {
212
- op: 'delete',
213
- },
214
- },
215
- ];
101
+ return patchCreator.createDelete(oid, authz);
216
102
  case 'touch':
217
103
  return [];
218
104
  default:
219
105
  throw new Error(`Cannot undo operation type: ${data.op}`);
220
106
  }
221
107
  }
108
+ function findItemRefIndex(list, item, from = 0, dir = 'forward') {
109
+ const method = dir === 'forward' ? 'findIndex' : 'findLastIndex';
110
+ // for object items, attempt to find the matching item by OID.
111
+ if (isRef(item)) {
112
+ return list[method]((i, idx) => isRef(i) && i.id === item.id && idx >= from);
113
+ }
114
+ return list[method]((i, idx) => i === item && idx >= from);
115
+ }
222
116
  //# sourceMappingURL=undo.js.map