Read the source and its declared rule
The original record contains name plus an extensions map whose unknown members must survive migration. Rebuilding only the known name silently loses colour blue. Extensions cannot redefine reserved name; an empty extensions map is a deliberate retained shape.
| Record | Input JSON |
|---|---|
| Base input | {"name":"A","extensions":{"colour":"blue"}} |
Compare the actual paths
Correct output retains nameA with extensions colour blue. A conflicting extension nameB is held with the original input instead of choosing one value silently.
| Path | Output JSON |
|---|---|
| Misleading path | {"accepted":true,"record":{"name":"A"}} |
| Corrected path | {"accepted":true,"record":{"name":"A","extensions":{"colour":"blue"}}} |
import {DatabaseSync} from 'node:sqlite';
import {TextDecoder} from 'node:util';
import {inflateSync} from 'node:zlib';
import {posix} from 'node:path';
import {createHash} from 'node:crypto';
const rows=(db,sql)=>db.prepare(sql).all().map(r=>({...r}));
const failed=(action)=>{try{action();return null;}catch(e){return {code:e.errcode??e.code??e.name};}};
import assert from 'node:assert/strict';
const run=function run(i,corrected=true){
const {name,extensions}=i;
if(corrected&&Object.hasOwn(extensions,'name'))return {accepted:false,error:'reserved-extension-name',original:i};
const db=new DatabaseSync(':memory:');try{db.exec('CREATE TABLE target(name TEXT,extensions TEXT);');
if(corrected)db.prepare('INSERT INTO target VALUES(?,?)').run(name,JSON.stringify(extensions));
else db.prepare('INSERT INTO target(name) VALUES(?)').run(name);
const stored=db.prepare('SELECT * FROM target').get();
return {accepted:true,record:stored.extensions===null?{name:stored.name}:{name:stored.name,extensions:JSON.parse(stored.extensions)}};
}finally{db.close();}
};
const cases=[{"label":"misleading base","input":{"name":"A","extensions":{"colour":"blue"}},"expected":{"accepted":true,"record":{"name":"A"}},"corrected":false},{"label":"corrected base","input":{"name":"A","extensions":{"colour":"blue"}},"expected":{"accepted":true,"record":{"name":"A","extensions":{"colour":"blue"}}},"corrected":true},{"label":"reserved extension conflict","input":{"name":"A","extensions":{"name":"B"}},"expected":{"accepted":false,"error":"reserved-extension-name","original":{"name":"A","extensions":{"name":"B"}}},"corrected":true},{"label":"empty extension map","input":{"name":"A","extensions":{}},"expected":{"accepted":true,"record":{"name":"A","extensions":{}}},"corrected":true}];
for(const test of cases){
const actual=run(test.input,test.corrected);
assert.deepEqual(actual,test.expected,test.label);
console.log(test.label,actual);
}
Check boundaries before the next load
Reserved-name conflict rejects; an empty map remains {}, rather than disappearing or becoming null.
| Case | Input JSON | Expected output JSON |
|---|---|---|
| Reserved extension name conflict | {"name":"A","extensions":{"name":"B"}} | {"accepted":false,"error":"reserved-extension-name","original":{"name":"A","extensions":{"name":"B"}}} |
| Deliberately empty extension map | {"name":"A","extensions":{}} | {"accepted":true,"record":{"name":"A","extensions":{}}} |
May a known-fields-only copy count as a complete migration here?
Show the worked answer
No. The agreed extensions are part of the record. Preserve colour blue and the extensions map, including an explicitly empty map.