@dotinc/ogre 0.1.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.
Files changed (61) hide show
  1. package/.nyc_output/34733e82-2b34-4674-aa72-94cab1c84e85.json +1 -0
  2. package/.nyc_output/3fb03278-d8e2-4673-abde-3cce50eb4143.json +1 -0
  3. package/.nyc_output/438de35e-20e6-470d-bfdb-d9b5fbc62f85.json +1 -0
  4. package/.nyc_output/61ba5903-4249-44c6-afe4-60e536bb69e0.json +1 -0
  5. package/.nyc_output/67c0b0a0-d3e0-4e7d-85e9-140cf10bf6e9.json +1 -0
  6. package/.nyc_output/77ec015f-70ab-47be-9757-17b5a39f4100.json +1 -0
  7. package/.nyc_output/processinfo/34733e82-2b34-4674-aa72-94cab1c84e85.json +1 -0
  8. package/.nyc_output/processinfo/3fb03278-d8e2-4673-abde-3cce50eb4143.json +1 -0
  9. package/.nyc_output/processinfo/438de35e-20e6-470d-bfdb-d9b5fbc62f85.json +1 -0
  10. package/.nyc_output/processinfo/61ba5903-4249-44c6-afe4-60e536bb69e0.json +1 -0
  11. package/.nyc_output/processinfo/67c0b0a0-d3e0-4e7d-85e9-140cf10bf6e9.json +1 -0
  12. package/.nyc_output/processinfo/77ec015f-70ab-47be-9757-17b5a39f4100.json +1 -0
  13. package/.nyc_output/processinfo/index.json +1 -0
  14. package/.turbo/turbo-build.log +5 -0
  15. package/CHANGELOG.md +22 -0
  16. package/coverage/lcov-report/base.css +224 -0
  17. package/coverage/lcov-report/block-navigation.js +87 -0
  18. package/coverage/lcov-report/commit.ts.html +220 -0
  19. package/coverage/lcov-report/favicon.png +0 -0
  20. package/coverage/lcov-report/hash.ts.html +331 -0
  21. package/coverage/lcov-report/index.html +176 -0
  22. package/coverage/lcov-report/prettify.css +1 -0
  23. package/coverage/lcov-report/prettify.js +2 -0
  24. package/coverage/lcov-report/ref.ts.html +115 -0
  25. package/coverage/lcov-report/repository.ts.html +1648 -0
  26. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  27. package/coverage/lcov-report/sorter.js +196 -0
  28. package/coverage/lcov-report/test.utils.ts.html +223 -0
  29. package/coverage/lcov.info +660 -0
  30. package/lib/commit.d.ts +18 -0
  31. package/lib/commit.js +8 -0
  32. package/lib/hash.d.ts +23 -0
  33. package/lib/hash.js +82 -0
  34. package/lib/index.d.ts +5 -0
  35. package/lib/index.js +7 -0
  36. package/lib/interfaces.d.ts +14 -0
  37. package/lib/interfaces.js +2 -0
  38. package/lib/ref.d.ts +2 -0
  39. package/lib/ref.js +13 -0
  40. package/lib/repository.d.ts +29 -0
  41. package/lib/repository.js +455 -0
  42. package/lib/size.d.ts +4 -0
  43. package/lib/size.js +31 -0
  44. package/lib/test.utils.d.ts +17 -0
  45. package/lib/test.utils.js +41 -0
  46. package/package.json +49 -0
  47. package/src/branch.test.ts +58 -0
  48. package/src/checkout.test.ts +101 -0
  49. package/src/commit.test.ts +168 -0
  50. package/src/commit.ts +45 -0
  51. package/src/hash.ts +82 -0
  52. package/src/index.ts +5 -0
  53. package/src/interfaces.ts +19 -0
  54. package/src/merge.test.ts +38 -0
  55. package/src/ref.ts +10 -0
  56. package/src/repository.test.ts +26 -0
  57. package/src/repository.ts +521 -0
  58. package/src/size.ts +26 -0
  59. package/src/test.utils.ts +46 -0
  60. package/tsconfig.build.json +6 -0
  61. package/tsconfig.json +16 -0
@@ -0,0 +1,521 @@
1
+ import { Change, History, Reference } from './interfaces'
2
+ import { calculateHash, Commit } from './commit'
3
+ import { validBranch } from './ref'
4
+
5
+ const REFS_HEAD = 'HEAD'
6
+ const REFS_MAIN = 'refs/heads/main'
7
+ const refPrefix = 'ref: '
8
+
9
+ export interface RepositoryOptions<T> {
10
+ history?: History
11
+ }
12
+
13
+ export interface RepositoryObject<T> {
14
+ data: T
15
+
16
+ getHistory(): History
17
+
18
+ // It returns the reference where we are currently at
19
+ head(): string
20
+
21
+ // Returns the commit hash to which a reference points
22
+ ref(reference: string): string | undefined
23
+
24
+ commit(message: string, author: string, amend?: boolean): Promise<string>
25
+
26
+ checkout(shaish: string, createBranch?: boolean): void
27
+
28
+ logs(commits?: number): Commit[]
29
+
30
+ createBranch(name: string): string
31
+
32
+ merge(source: string | RepositoryObject<T> | History): string
33
+
34
+ branch(): string
35
+
36
+ }
37
+
38
+ export interface RespositoryObjectType {
39
+ new<T>(obj: T, options: RepositoryOptions<T>): RepositoryObject<T>
40
+ }
41
+
42
+ /**
43
+ * A repository recording and managing the state transitions of an object
44
+ */
45
+ export const Repository = function <T extends { [k: PropertyKey]: any }>(
46
+ this: RepositoryObject<T>,
47
+ obj: T,
48
+ options: RepositoryOptions<T>
49
+ ) {
50
+ let savedLength: number | undefined
51
+ let version = 0
52
+ const refs: Map<string, Reference> = options.history?.refs ?? new Map<string, Reference>([[REFS_HEAD, {
53
+ name: REFS_HEAD,
54
+ value: `ref: ${REFS_MAIN}`
55
+ }]])
56
+ const changeLog: Change[] = []
57
+ const targets: any[] = []
58
+ const commits: Commit[] = options.history?.commits ?? []
59
+ const hash: Map<T, any[]> = new Map([[obj, []]])
60
+ const handler = {
61
+ get: function(target: T, property: PropertyKey): any {
62
+ const x = target[property]
63
+ if (Object(x) !== x) return x
64
+ const arr = hash.get(target) ?? []
65
+ hash.set(x, [...arr, property])
66
+ return new Proxy(x, handler)
67
+ },
68
+ set: update,
69
+ deleteProperty: update
70
+ }
71
+
72
+ function gotoVersion(newVersion: number) {
73
+ newVersion = Math.max(0, Math.min(changeLog.length, newVersion))
74
+ let chg
75
+ let target
76
+ let path
77
+ let property
78
+
79
+ const val = newVersion > version ? 'newValue' : 'oldValue'
80
+ while (version !== newVersion) {
81
+ if (version > newVersion) version--
82
+ chg = changeLog[version]
83
+ path = [...chg.path]
84
+ property = path.pop()
85
+ target =
86
+ targets[version] ||
87
+ (targets[version] = path.reduce((o, p) => o[p], obj))
88
+ if (chg.hasOwnProperty(val)) {
89
+ const oldValue = chg[val]
90
+ // Some additional care concerning the length property of arrays:
91
+ // @nadilas workaround: array trim to empty array should not set 0:undefined
92
+ // console.log('warn: not setting array[0]=undefined', target, property, oldValue)
93
+ if (
94
+ !(
95
+ Array.isArray(target) &&
96
+ target.length === 0 &&
97
+ oldValue === undefined
98
+ )
99
+ ) {
100
+ target[property] = oldValue
101
+ }
102
+ } else {
103
+ delete target[property]
104
+ }
105
+
106
+ if (version < newVersion) {
107
+ version++
108
+ }
109
+ }
110
+
111
+ return true
112
+ }
113
+
114
+ function gotoLastVersion() {
115
+ return gotoVersion(changeLog.length)
116
+ }
117
+
118
+ function update(target: T, property: PropertyKey, value?: any) {
119
+ // only last version can be modified
120
+ gotoLastVersion()
121
+ const changes = hash.get(target) ?? []
122
+ const change: Change = {
123
+ path: [...changes, property],
124
+ newValue: undefined,
125
+ oldValue: undefined
126
+ }
127
+
128
+ if (arguments.length > 2) change.newValue = value
129
+ // Some care concerning the length property of arrays:
130
+ if (Array.isArray(target) && Number(property) >= target.length) {
131
+ savedLength = target.length
132
+ }
133
+
134
+ if (property in target) {
135
+ if (property === 'length' && savedLength !== undefined) {
136
+ change.oldValue = savedLength
137
+ savedLength = undefined
138
+ } else {
139
+ change.oldValue = target[property]
140
+ }
141
+ }
142
+
143
+ changeLog.push(change)
144
+ targets.push(target)
145
+ return gotoLastVersion()
146
+ }
147
+
148
+ this.data = new Proxy(obj, handler)
149
+
150
+ // region Read state read
151
+ this.head = () => {
152
+ const ref = refs.get(REFS_HEAD)
153
+ if (!ref) {
154
+ throw new Error(`unreachable: HEAD is not present`)
155
+ }
156
+ return cleanRefValue(ref.value)
157
+ }
158
+ this.ref = (reference) => {
159
+ const ref = refs.get(reference)?.value
160
+ return ref ? cleanRefValue(ref) : undefined
161
+ }
162
+ this.branch = () => {
163
+ const currentHeadRef = refs.get(REFS_HEAD)
164
+ if (!currentHeadRef) {
165
+ throw new Error('unreachable: ref HEAD not available')
166
+ }
167
+
168
+ if (currentHeadRef.value.includes(refPrefix)) {
169
+ const refName = cleanRefValue(currentHeadRef.value)
170
+ if (refs.has(refName))
171
+ return getLastItem(refName)
172
+ }
173
+
174
+ return REFS_HEAD // detached state
175
+ }
176
+ // endregion
177
+
178
+ // region History functions
179
+ const collectCommits = () => {
180
+ const commit = commitAtHead()
181
+ if (!commit) {
182
+ return []
183
+ }
184
+ // traverse backwards and build commit tree
185
+ let c: Commit | undefined = commit
186
+ let commitsList: Commit[] = []
187
+ while (c !== undefined) {
188
+ commitsList = [c, ...commitsList]
189
+ c = commits.find(parent => parent.hash === c?.parent)
190
+ }
191
+ return commitsList
192
+ }
193
+ const rebuildChangeLog = (commit: Commit) => {
194
+ // clear current state
195
+ changeLog.splice(0)
196
+ version = 0
197
+
198
+ // traverse backwards and build changelog
199
+ let clog = traverseAndCollectChangelog(commit, commits)
200
+ changeLog.push(...clog)
201
+
202
+ // process new changelog
203
+ gotoLastVersion()
204
+ }
205
+ this.logs = (numberOfCommits) => {
206
+ const logs: Commit[] = []
207
+ const limit = numberOfCommits ?? -1
208
+ let c = commitAtHead()
209
+ let counter = 0
210
+ while(c !== undefined && (limit === -1 || counter < limit)) {
211
+ logs.push(c, ...logs)
212
+ counter++
213
+ c = commits.find(parent => parent.hash === c?.parent)
214
+ }
215
+ return logs
216
+ }
217
+ // endregion
218
+
219
+ this.getHistory = (): History => {
220
+ // only send back shallow copies of changelog and commits up to current version
221
+ return {
222
+ refs: new Map(refs),
223
+ commits: collectCommits()
224
+ }
225
+ }
226
+
227
+ // region Commit lookups
228
+ const commitAtHead = () => {
229
+ return commitAtHeadIn(REFS_HEAD, refs, commits)
230
+ }
231
+ const mustCommitAtHead = () => {
232
+ const commitHead = commitAtHead()
233
+ if (!commitHead) {
234
+ throw new Error(`unreachable: HEAD or its target ref not present`)
235
+ }
236
+ return commitHead
237
+ }
238
+ // endregion
239
+
240
+ this.commit = async (message, author, amend = false): Promise<string> => {
241
+ let parent = commitAtHead()
242
+ if (amend && !parent) {
243
+ throw new Error(`no commit to amend`)
244
+ }
245
+ if (parent) {
246
+ if (amend) {
247
+ [parent] = parent.parent ? shaishToCommit(parent.parent, refs, commits) : [undefined]
248
+ }
249
+ }
250
+ const changesSinceLastCommit = changeLog.slice(parent?.to)
251
+ if (changesSinceLastCommit.length === 0) {
252
+ throw new Error(`no changes to commit`)
253
+ }
254
+
255
+ const timestamp = new Date()
256
+ const changes = [...changesSinceLastCommit]
257
+ const sha = await calculateHash({
258
+ message,
259
+ author,
260
+ changes,
261
+ parentRef: parent?.hash,
262
+ timestamp
263
+ })
264
+
265
+ const commit = {
266
+ hash: sha,
267
+ message,
268
+ author,
269
+ changes: changes,
270
+ parent: parent?.hash,
271
+ timestamp,
272
+ to: version
273
+ }
274
+ if (amend) {
275
+ const idx = commits.findIndex(c => c === parent)
276
+ commits.splice(idx, 1)
277
+ }
278
+ commits.push(commit)
279
+
280
+ const headRef = this.head()
281
+ if (headRef.includes('refs')) {
282
+ // but move ref: refs/heads/main
283
+ moveRef(headRef, commit)
284
+ } else {
285
+ // move detached HEAD to new commit
286
+ moveRef(REFS_HEAD, commit)
287
+ }
288
+
289
+ return sha
290
+ }
291
+
292
+ // region Graph manipulation
293
+ this.checkout = (shaish, createBranch = false) => {
294
+ if (createBranch) {
295
+ validateBranchName(shaish)
296
+ let branchRef = brancheNameToRef(shaish)
297
+ const commit = commitAtHead()
298
+ if (commit) {
299
+ moveRef(branchRef, commit)
300
+ }
301
+ moveRef(REFS_HEAD, branchRef)
302
+ } else {
303
+ const [commit, isRef, refKey] = shaishToCommit(shaish, refs, commits)
304
+ rebuildChangeLog(commit)
305
+ moveRef(REFS_HEAD, isRef && refKey !== undefined ? refKey : commit)
306
+ }
307
+ }
308
+ this.createBranch = (name) => {
309
+ validateBranchName(name)
310
+ const refName = brancheNameToRef(name)
311
+ const headCommit = commitAtHead()
312
+ if (!headCommit) {
313
+ const headRef = this.head()
314
+ if (!headRef) {
315
+ throw new Error(`unreachable: HEAD not present`)
316
+ }
317
+ throw new Error(`fatal: not a valid object name: '${getLastItem(headRef)}'`)
318
+ }
319
+ refs.set(refName, { name: name, value: headCommit.hash })
320
+ return refName
321
+ }
322
+ const moveRef = (refName: string, value: string | Commit) => {
323
+ let ref = refs.get(refName)
324
+ const val = typeof value === 'string' ? `${refPrefix}${value}` : value.hash
325
+ if (!ref) {
326
+ ref = { name: getLastItem(refName), value: val }
327
+ } else {
328
+ ref.value = val
329
+ }
330
+ refs.set(refName, ref)
331
+ }
332
+ this.merge = source => {
333
+ // inspiration
334
+ // http://think-like-a-git.net
335
+ // also check isomorphic-git
336
+ // for fancier merge tree
337
+ // https://github.com/isomorphic-git/isomorphic-git/blob/a623133345a5d8b6bb7a8352ea9702ce425d8266/src/utils/mergeTree.js#L33
338
+
339
+ if (typeof source !== 'string') {
340
+ // const srcHead = commitAtHeadIn(REFS_HEAD, src.refs, src.commits)
341
+ throw new Error(`fatal: source type (${source instanceof Repository ? 'Repository' : 'History'}) not implemented`)
342
+ }
343
+
344
+ const [srcCommit] = shaishToCommit(source, refs, commits)
345
+ const headCommit = mustCommitAtHead()
346
+
347
+ // no change
348
+ // *---* (master)
349
+ // |
350
+ // * (foo)
351
+ if (headCommit.hash === srcCommit.hash) {
352
+ throw new Error(`already up to date`)
353
+ }
354
+
355
+ // fast-forward
356
+ // *---* (master)
357
+ // \
358
+ // *---*---* (foo)
359
+ // result:
360
+ // *---*
361
+ // \
362
+ // *---*---* (master, foo)
363
+ const [isAncestor] = mapPath(headCommit, srcCommit, commits)
364
+ if (isAncestor) {
365
+ moveRef(this.head(), srcCommit)
366
+ rebuildChangeLog(srcCommit)
367
+ return srcCommit.hash
368
+ }
369
+
370
+ // todo diverge
371
+ // *---*---* (master)
372
+ // \
373
+ // *---*---* (foo)
374
+ // result:
375
+ // ↓
376
+ // *---*---*-------* (master)
377
+ // \ /
378
+ // *---*---* (foo)
379
+ // if (false) {
380
+ // throw new Error('diverge not implemented yet')
381
+ // }
382
+
383
+ throw new Error('unknown merge type: not implemented yet')
384
+ }
385
+ // endregion
386
+
387
+ // apply change log at the end of the constructor
388
+ const headCommit = commitAtHead()
389
+ if (headCommit) {
390
+ rebuildChangeLog(headCommit)
391
+ }
392
+ } as any as RespositoryObjectType
393
+
394
+ const getLastItem = (thePath: string) => thePath.substring(thePath.lastIndexOf('/') + 1)
395
+ const cleanRefValue = (ref: string) => ref.replace(refPrefix, '')
396
+ const brancheNameToRef = (name: string) => {
397
+ return `refs/heads/${name}`
398
+ }
399
+ const validateBranchName = (name: string) => {
400
+ if (!validBranch(name)) {
401
+ throw new Error(`invalid ref name`)
402
+ }
403
+ }
404
+
405
+ /**
406
+ * Traverses the commit tree backwards and reassembles the changelog
407
+ * @param commit
408
+ * @param commitsList
409
+ */
410
+ const traverseAndCollectChangelog = (commit: Commit, commitsList: Commit[]) => {
411
+ let c: Commit | undefined = commit
412
+ let clog: Change[] = []
413
+ while (c !== undefined) {
414
+ clog = [...commit.changes, ...clog]
415
+ c = commitsList.find(parent => parent.hash === c?.parent)
416
+ }
417
+ return clog
418
+ }
419
+
420
+ const mapPath = (from: Commit, to: Commit, commits: Commit[]): [isAncestor: boolean] => {
421
+ let c: Commit | undefined = to
422
+ while (c !== undefined) {
423
+ c = commits.find(parent => parent.hash === c?.parent)
424
+ if (c?.hash === from.hash) {
425
+ return [true]
426
+ }
427
+ }
428
+ return [false]
429
+ }
430
+
431
+ /**
432
+ * Returns the commit to which the provided ref is pointing
433
+ * @param ref - needs to be in key format, e.g. refs/heads/... or refs/tags/...
434
+ * @param references
435
+ * @param commitsList
436
+ */
437
+ const commitAtHeadIn = (ref: string, references: Map<string, Reference>, commitsList: Commit[]) => {
438
+ const reference = references.get(ref)
439
+ if (!reference) {
440
+ throw new Error(`unreachable: '${ref}' is not present`)
441
+ }
442
+ let commitHash
443
+ if (reference.value.includes(refPrefix)) {
444
+ const refKey = cleanRefValue(reference.value)
445
+ const targetRef = references.get(refKey)
446
+ if (!targetRef) {
447
+ // target branch may not have been saved yet
448
+ return undefined
449
+ }
450
+ commitHash = targetRef.value
451
+ } else {
452
+ commitHash = reference.value
453
+ }
454
+ for (const c of commitsList) {
455
+ if (c.hash === commitHash) {
456
+ return c
457
+ }
458
+ }
459
+ return undefined
460
+ }
461
+
462
+ /**
463
+ * Accepts a shaish expression (e.g. refs (branches, tags), commitSha) and returns
464
+ * - a commit of type Commit
465
+ * - isRef boolean whether it is a direct reference
466
+ * - ref the key of the reference
467
+ */
468
+ const shaishToCommit = (shaish: string, references: Map<string, Reference>, commitsList: Commit[]): [commit: Commit, isRef: boolean, ref: string | undefined] => {
469
+ let sha = shaish
470
+ let isRef = false
471
+ let refKey: string | undefined = undefined
472
+
473
+ // check for refs
474
+ for (const [name, ref] of references.entries()) {
475
+ // match on
476
+ if (ref.name === shaish || name === shaish) {
477
+ isRef = true
478
+ refKey = name
479
+ sha = ref.value
480
+ if (sha.includes(refPrefix)) {
481
+ const cleanedRef = cleanRefValue(sha)
482
+ const c = commitAtHeadIn(cleanedRef, references, commitsList)
483
+ if (!c) {
484
+ throw new Error(`${cleanedRef} points to non-existing commit`)
485
+ }
486
+ return [c, isRef, refKey]
487
+ }
488
+ break
489
+ }
490
+ }
491
+ // check for partial sha matches
492
+ const found = commitsList.filter(c => c.hash.indexOf(sha) > -1)
493
+ if (found.length === 0) {
494
+ throw new Error(`pathspec '${shaish}' did not match any known refs`)
495
+ }
496
+ // but sha should be specific enough to resolve to 1 commit
497
+ if (found.length > 1) {
498
+ throw new Error(`commit `)
499
+ }
500
+ return [found[0], isRef, refKey]
501
+ }
502
+
503
+ /**
504
+ * Prints the underlying changelog of a repository
505
+ * @param repository
506
+ */
507
+ export const printChangeLog = <T>(repository: RepositoryObject<T>) => {
508
+ console.log('----------------------------------------------------------')
509
+ console.log(`Changelog at ${repository.head()}`)
510
+ const history = repository.getHistory()
511
+ const head = commitAtHeadIn(repository.head(), history.refs, history.commits)
512
+ if (!head) {
513
+ throw new Error(`fatal: HEAD is not defined`)
514
+ }
515
+ const changeLog = traverseAndCollectChangelog(head, history.commits)
516
+ for (const [, chg] of changeLog.entries()) {
517
+ console.log(` ${JSON.stringify(chg)}`)
518
+ }
519
+
520
+ console.log('----------------------------------------------------------')
521
+ }
package/src/size.ts ADDED
@@ -0,0 +1,26 @@
1
+ export const getSizeInBytes = (obj: string | any) => {
2
+ let str: string
3
+ if (typeof obj === 'string') {
4
+ // If obj is a string, then use it
5
+ str = obj
6
+ } else {
7
+ // Else, make obj into a string
8
+ str = JSON.stringify(obj)
9
+ }
10
+ // Get the length of the Uint8Array
11
+ return new TextEncoder().encode(str).length // in bytes
12
+ }
13
+
14
+ export const sizeInBytes = (obj: any) => {
15
+ return getSizeInBytes(obj) // B
16
+ }
17
+
18
+ export const sizeInKilobytes = (obj: any) => {
19
+ const bytes = getSizeInBytes(obj)
20
+ return (bytes / 1000) // kB
21
+ }
22
+
23
+ export const sizeInMegabytes = (obj: any) => {
24
+ const bytes = getSizeInBytes(obj)
25
+ return (bytes / 1000 / 1000) // mB
26
+ }
@@ -0,0 +1,46 @@
1
+ import { v4 as uuid4 } from 'uuid'
2
+ import { Repository, RepositoryObject } from './repository'
3
+ import { Commit } from './commit'
4
+
5
+ export class NestedObject {
6
+ public name: string | undefined
7
+ public uuid: string | undefined
8
+ }
9
+
10
+ export class ComplexObject {
11
+ public uuid: string | undefined
12
+ public name: string | undefined
13
+ public description: string | undefined
14
+ public nested: NestedObject[] = []
15
+ }
16
+
17
+ export const testAuthor = 'User name <name@domain.com>'
18
+
19
+ export async function getBaseline(): Promise<[RepositoryObject<ComplexObject>, ComplexObject]> {
20
+ const co = new ComplexObject()
21
+ const repo = new Repository(co, {})
22
+ return [repo, repo.data]
23
+ }
24
+
25
+ export function updateHeaderData(wrapped: ComplexObject) {
26
+ wrapped.uuid = uuid4()
27
+ wrapped.name = 'my first process template'
28
+ wrapped.description = 'now we have a description'
29
+
30
+ return 3 // change entries
31
+ }
32
+
33
+ export function addOneStep(wrapped: ComplexObject) {
34
+ const pe = new NestedObject()
35
+ pe.uuid = uuid4()
36
+ pe.name = 'first name'
37
+
38
+ wrapped.nested.push(pe)
39
+ wrapped.nested[0].name = 'new name'
40
+
41
+ return 3 // change entries
42
+ }
43
+
44
+ export function sumChanges(commits: Commit[] | undefined) {
45
+ return commits?.map(c => c.changes.length).reduce((p, c) => p + c, 0)
46
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "exclude": [
4
+ "**/*.test.ts"
5
+ ]
6
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "compilerOptions": {
3
+ "declaration": true,
4
+ "importHelpers": true,
5
+ "module": "commonjs",
6
+ "outDir": "./lib",
7
+ "rootDir": "./src",
8
+ "strict": true,
9
+ "target": "es2019",
10
+ "downlevelIteration": true
11
+ },
12
+ "include": [
13
+ "./src/**/*.ts"
14
+ ],
15
+ "exclude": ["lib", "node_modules"]
16
+ }