@dotinc/ogre 0.6.0 → 0.7.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/.tap/processinfo/{86009ac9-5819-45bf-b53f-0448d4b7ef56.json → 21e0110c-397c-4c38-a84a-89c55de41e7e.json} +6 -6
- package/.tap/processinfo/{9e67801c-9248-4793-994c-a9b4f59ebc4f.json → 36da4059-ca5e-4b70-a993-7f99f94f7588.json} +6 -6
- package/.tap/processinfo/{31ca0767-30d5-4c1b-aab3-1a456fd51558.json → 4aa37d99-4038-4033-9d38-beea00272892.json} +6 -6
- package/.tap/processinfo/{65d66b6b-127f-4a35-b64a-5b0ac1df524c.json → 51b87298-fd44-42a9-b0f8-d4533e58fd1c.json} +30 -30
- package/.tap/processinfo/{f9080426-4139-4a9a-a59f-ccbfa4cadf7d.json → 75459f57-2341-476b-8576-587b93699d8b.json} +6 -6
- package/.tap/processinfo/{77376985-2ddf-4b47-9631-c637b0ecbcdd.json → 9656a0a0-72ab-4ea7-abb7-7415cd3842b4.json} +22 -22
- package/.tap/processinfo/{52683acc-91e1-4d54-9715-1cbaf91964a7.json → d1b618cb-a921-4f1c-ae4a-6bca359b5909.json} +6 -6
- package/.tap/test-results/src/branch.test.ts.tap +6 -6
- package/.tap/test-results/src/checkout.test.ts.tap +9 -9
- package/.tap/test-results/src/commit.test.ts.tap +24 -18
- package/.tap/test-results/src/merge.test.ts.tap +2 -2
- package/.tap/test-results/src/repository.test.ts.tap +31 -31
- package/.tap/test-results/src/tag.test.ts.tap +3 -3
- package/.tap/test-results/src/utils.test.ts.tap +7 -7
- package/CHANGELOG.md +20 -0
- package/lib/git2json.d.ts +1 -1
- package/lib/interfaces.d.ts +1 -4
- package/lib/repository.d.ts +13 -7
- package/lib/repository.js +35 -6
- package/package.json +2 -2
- package/src/commit.test.ts +17 -1
- package/src/commit.ts +7 -7
- package/src/git2json.ts +1 -1
- package/src/interfaces.ts +1 -2
- package/src/repository.test.ts +39 -43
- package/src/repository.ts +48 -11
package/src/interfaces.ts
CHANGED
package/src/repository.test.ts
CHANGED
|
@@ -163,7 +163,7 @@ test("history", async (t) => {
|
|
|
163
163
|
original: co,
|
|
164
164
|
refs: new Map<string, Reference>(),
|
|
165
165
|
commits: [],
|
|
166
|
-
} as History
|
|
166
|
+
} as History,
|
|
167
167
|
}),
|
|
168
168
|
{
|
|
169
169
|
message: "unreachable: 'HEAD' is not present",
|
|
@@ -201,17 +201,29 @@ test("status", async (t) => {
|
|
|
201
201
|
const [repo] = await getBaseline({ name: "base name" });
|
|
202
202
|
repo.data.name = "changed name";
|
|
203
203
|
const dirtyState = repo.status();
|
|
204
|
-
t.equal(
|
|
204
|
+
t.equal(
|
|
205
|
+
dirtyState.length,
|
|
206
|
+
1,
|
|
207
|
+
`Status doesn't contain the expected # of changes: ${JSON.stringify(dirtyState)}`,
|
|
208
|
+
);
|
|
205
209
|
});
|
|
206
|
-
t.test("reading status
|
|
210
|
+
t.test("reading status shouldn't clean observer", async (t) => {
|
|
207
211
|
const [repo] = await getBaseline({ name: "base name" });
|
|
208
212
|
repo.data.name = "changed name";
|
|
209
213
|
const dirtyState = repo.status();
|
|
210
|
-
t.equal(
|
|
214
|
+
t.equal(
|
|
215
|
+
dirtyState.length,
|
|
216
|
+
1,
|
|
217
|
+
`Status doesn't contain the expected # of changes: ${JSON.stringify(dirtyState)}`,
|
|
218
|
+
);
|
|
211
219
|
|
|
212
220
|
const dirtyState2 = repo.status();
|
|
213
|
-
t.equal(
|
|
214
|
-
|
|
221
|
+
t.equal(
|
|
222
|
+
dirtyState2.length,
|
|
223
|
+
1,
|
|
224
|
+
`Status doesn't contain the expected # of changes: ${JSON.stringify(dirtyState)}`,
|
|
225
|
+
);
|
|
226
|
+
t.match(dirtyState2, dirtyState2, "why different pending changes??");
|
|
215
227
|
});
|
|
216
228
|
t.test("after commit no change", async (t) => {
|
|
217
229
|
const [repo] = await getBaseline();
|
|
@@ -275,43 +287,27 @@ test("apply", async (t) => {
|
|
|
275
287
|
t.match(dirtyState, patches, "It should have the right changes");
|
|
276
288
|
});
|
|
277
289
|
|
|
278
|
-
t.test(
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
op: "replace",
|
|
300
|
-
path: "/name",
|
|
301
|
-
value: "a name",
|
|
302
|
-
},
|
|
303
|
-
},
|
|
304
|
-
"Failed to apply patch",
|
|
305
|
-
);
|
|
306
|
-
t.notMatch(
|
|
307
|
-
repo.data,
|
|
308
|
-
targetState,
|
|
309
|
-
"The final state shoould not match up, because patch failed",
|
|
310
|
-
);
|
|
311
|
-
const dirtyState = repo.status();
|
|
312
|
-
t.equal(dirtyState.length, 0, "Status doesn't contain changes");
|
|
313
|
-
},
|
|
314
|
-
);
|
|
290
|
+
t.test("patch for undefined props with workaround", async (t) => {
|
|
291
|
+
// solution for workaround from: https://github.com/Starcounter-Jack/JSON-Patch/issues/280
|
|
292
|
+
const [repo] = await getBaseline();
|
|
293
|
+
const cleanState = repo.status();
|
|
294
|
+
t.match(cleanState, [], "Shouldn't have pending changes");
|
|
295
|
+
|
|
296
|
+
const targetState: ComplexObject = {
|
|
297
|
+
uuid: undefined,
|
|
298
|
+
description: undefined,
|
|
299
|
+
name: "a name",
|
|
300
|
+
nested: [],
|
|
301
|
+
};
|
|
302
|
+
const patches = compare(repo.data, targetState);
|
|
303
|
+
// this should record changes on the observer
|
|
304
|
+
const err = repo.apply(patches);
|
|
305
|
+
t.equal(err, undefined, "Failed to apply patch");
|
|
306
|
+
|
|
307
|
+
t.match(repo.data, targetState, "The final state should match up");
|
|
308
|
+
const dirtyState = repo.status();
|
|
309
|
+
t.equal(dirtyState.length, 1, "Status should contain 1 change");
|
|
310
|
+
});
|
|
315
311
|
|
|
316
312
|
t.test("multiple patches", async (t) => {
|
|
317
313
|
const [repo] = await getBaseline({ name: "base name" });
|
package/src/repository.ts
CHANGED
|
@@ -24,13 +24,13 @@ export const REFS_HEAD_KEY = "HEAD";
|
|
|
24
24
|
export const REFS_MAIN_KEY = `${headsRefPathPrefix}main`;
|
|
25
25
|
|
|
26
26
|
export interface RepositoryOptions<T extends { [k: string]: any }> {
|
|
27
|
-
history?: History
|
|
27
|
+
history?: History;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
export interface RepositoryObject<T extends { [k: string]: any }> {
|
|
31
31
|
data: T;
|
|
32
32
|
|
|
33
|
-
getHistory(): History
|
|
33
|
+
getHistory(): History;
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* Returns the diff between the current HEAD and provided shaish expression
|
|
@@ -65,7 +65,7 @@ export interface RepositoryObject<T extends { [k: string]: any }> {
|
|
|
65
65
|
|
|
66
66
|
createBranch(name: string): string;
|
|
67
67
|
|
|
68
|
-
merge(source: string | RepositoryObject<T> | History
|
|
68
|
+
merge(source: string | RepositoryObject<T> | History): string;
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
71
|
* Branch returns the current branch name
|
|
@@ -80,6 +80,11 @@ export interface RepositoryObject<T extends { [k: string]: any }> {
|
|
|
80
80
|
* @param shaish
|
|
81
81
|
*/
|
|
82
82
|
reset(mode?: "soft" | "hard", shaish?: string): void;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Returns the remote references from the initialization of the repository
|
|
86
|
+
*/
|
|
87
|
+
remote(): Map<string, Reference> | undefined;
|
|
83
88
|
}
|
|
84
89
|
|
|
85
90
|
/**
|
|
@@ -88,10 +93,13 @@ export interface RepositoryObject<T extends { [k: string]: any }> {
|
|
|
88
93
|
export class Repository<T extends { [k: PropertyKey]: any }>
|
|
89
94
|
implements RepositoryObject<T>
|
|
90
95
|
{
|
|
91
|
-
constructor(obj: T
|
|
96
|
+
constructor(obj: Partial<T>, options: RepositoryOptions<T>) {
|
|
97
|
+
// FIXME: move this to refs/remote as git would do?
|
|
98
|
+
this.remoteRefs = options.history?.refs;
|
|
92
99
|
this.original = deepClone(obj);
|
|
93
|
-
|
|
94
|
-
this.
|
|
100
|
+
// store js ref, so obj can still be modified without going through repo.data
|
|
101
|
+
this.data = obj as T;
|
|
102
|
+
this.observer = observe(obj as T);
|
|
95
103
|
this.refs =
|
|
96
104
|
options.history?.refs ??
|
|
97
105
|
new Map<string, Reference>([
|
|
@@ -119,11 +127,18 @@ export class Repository<T extends { [k: PropertyKey]: any }>
|
|
|
119
127
|
|
|
120
128
|
data: T;
|
|
121
129
|
|
|
130
|
+
// stores the remote state upon initialization
|
|
131
|
+
private readonly remoteRefs: Map<string, Reference> | undefined;
|
|
132
|
+
|
|
122
133
|
private observer: Observer<T>;
|
|
123
134
|
|
|
124
135
|
private readonly refs: Map<string, Reference>;
|
|
125
136
|
private readonly commits: Commit[];
|
|
126
137
|
|
|
138
|
+
remote(): Map<string, Reference> | undefined {
|
|
139
|
+
return this.remoteRefs;
|
|
140
|
+
}
|
|
141
|
+
|
|
127
142
|
private moveTo(commit: Commit) {
|
|
128
143
|
const targetTree = treeToObject(commit.tree);
|
|
129
144
|
const patchToTarget = compare(this.data, targetTree);
|
|
@@ -136,9 +151,32 @@ export class Repository<T extends { [k: PropertyKey]: any }>
|
|
|
136
151
|
}
|
|
137
152
|
|
|
138
153
|
apply(patch: Operation[]): JsonPatchError | undefined {
|
|
139
|
-
const
|
|
154
|
+
const p = deepClone(patch) as Operation[];
|
|
155
|
+
const err = validate(p, this.data);
|
|
140
156
|
if (err) {
|
|
141
|
-
|
|
157
|
+
// credit goes to @NicBright
|
|
158
|
+
// https://github.com/Starcounter-Jack/JSON-Patch/issues/280#issuecomment-1980435509
|
|
159
|
+
if (err.name === "OPERATION_PATH_UNRESOLVABLE") {
|
|
160
|
+
if (err.operation.op === "replace") {
|
|
161
|
+
// can happen e.g. when states are like this:
|
|
162
|
+
// from.x = undefined
|
|
163
|
+
// to.x = 'something'
|
|
164
|
+
const op = p.find(
|
|
165
|
+
(o) => o.path === err.operation.path && o.op === err.operation.op,
|
|
166
|
+
);
|
|
167
|
+
if (!op) return err;
|
|
168
|
+
// try it once more with operation 'add' instead
|
|
169
|
+
op.op = "add";
|
|
170
|
+
return this.apply(p);
|
|
171
|
+
} else if (err.operation.op === "remove") {
|
|
172
|
+
// Can happen e.g. when states are like this:
|
|
173
|
+
// from.entity.reason = null;
|
|
174
|
+
// to.entity.reason = undefined;
|
|
175
|
+
// we don't do anything in this case because "to" is already in a good state!
|
|
176
|
+
}
|
|
177
|
+
} else {
|
|
178
|
+
return err;
|
|
179
|
+
}
|
|
142
180
|
}
|
|
143
181
|
applyPatch(this.data, patch);
|
|
144
182
|
// const changed = patch.reduce(applyReducer, this.data);
|
|
@@ -347,9 +385,8 @@ export class Repository<T extends { [k: PropertyKey]: any }>
|
|
|
347
385
|
return commitsList;
|
|
348
386
|
}
|
|
349
387
|
|
|
350
|
-
getHistory(): History
|
|
388
|
+
getHistory(): History {
|
|
351
389
|
return {
|
|
352
|
-
original: this.original,
|
|
353
390
|
refs: new Map(this.refs),
|
|
354
391
|
commits: this.collectCommits(),
|
|
355
392
|
};
|
|
@@ -370,7 +407,7 @@ export class Repository<T extends { [k: PropertyKey]: any }>
|
|
|
370
407
|
|
|
371
408
|
// endregion
|
|
372
409
|
|
|
373
|
-
merge(source: string | RepositoryObject<T> | History
|
|
410
|
+
merge(source: string | RepositoryObject<T> | History): string {
|
|
374
411
|
// inspiration
|
|
375
412
|
// http://think-like-a-git.net
|
|
376
413
|
// also check isomorphic-git
|