Skip to content

Commit

Permalink
clone the inputs
Browse files Browse the repository at this point in the history
Signed-off-by: Matteo Collina <[email protected]>
  • Loading branch information
mcollina committed Mar 8, 2024
1 parent 86e21ad commit 04b009d
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 3 deletions.
16 changes: 16 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
"borp": "^0.10.0",
"desm": "^1.3.1",
"prettier": "^3.2.5",
"@types/rfdc": "^1.2.0",
"@types/semver": "^7.5.8",
"typescript": "^5.3.3"
},
"prettier": {
Expand All @@ -57,7 +59,7 @@
"main": "./dist/semgrator.js",
"types": "./dist/semgrator.d.ts",
"dependencies": {
"@types/semver": "^7.5.8",
"rfdc": "^1.3.1",
"semver": "^7.6.0"
}
}
5 changes: 4 additions & 1 deletion src/lib/semgrator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import semver from 'semver'
import { join } from 'node:path'
import { pathToFileURL } from 'node:url'
import { readdir } from 'node:fs/promises'
import rfdc from 'rfdc'

const clone = rfdc()

export type Migration<Input, Output = Input> = {
version: string
Expand Down Expand Up @@ -87,7 +90,7 @@ async function* processMigrations<Input, Output>(
for await (const migration of migrations) {
if (semver.gt(migration.version, lastVersion)) {
// @ts-expect-error
result = await migration.up(result)
result = await migration.up(clone(result))
lastVersion = migration.toVersion || migration.version
changed = true
}
Expand Down
47 changes: 46 additions & 1 deletion src/test/semgrator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ import { test } from 'node:test'
import { semgrator, Migration } from '../lib/semgrator.js'
import { tspl } from '@matteo.collina/tspl'
import { throws } from 'node:assert/strict'
import { equal, deepEqual } from 'node:assert/strict'

type SeenBy = {
foo: string
seenBy?: string
deep?: {
seenBy?: string
}
}

test('apply all migrations', async t => {
test('apply all migrations', async t => {
const plan = tspl(t, { plan: 4 })
const m1: Migration<SeenBy> = {
version: '2.0.0',
Expand Down Expand Up @@ -207,3 +211,44 @@ test('throws if version is missing', async t => {
},
)
})

test('clones at each step', async t => {
const m1: Migration<SeenBy> = {
version: '2.0.0',
async up(input) {
input.seenBy = '2.0.0'
input.deep ||= {}
input.deep.seenBy = '2.0.0'
return input
},
}

const input = {
foo: 'bar',
deep: {
seenBy: '1.0.0',
},
}

const res = await semgrator<SeenBy, SeenBy>({
version: '1.0.0',
migrations: [m1],
input,
})

equal(res.version, '2.0.0')
equal(res.changed, true)
deepEqual(res.result, {
foo: 'bar',
seenBy: '2.0.0',
deep: {
seenBy: '2.0.0',
},
})
deepEqual(input, {
foo: 'bar',
deep: {
seenBy: '1.0.0',
},
})
})

0 comments on commit 04b009d

Please sign in to comment.