@strapi/data-transfer
Version:
Data transfer capabilities for Strapi
81 lines (77 loc) • 3.64 kB
JavaScript
;
var stream = require('stream');
var providers = require('../../../../../errors/providers.js');
var link = require('../../../../queries/link.js');
var resolveLinkRef = require('./resolve-link-ref.js');
const isErrorWithCode = (error)=>{
return error && typeof error.code === 'string';
};
const isForeignKeyConstraintError = (e)=>{
const MYSQL_FK_ERROR_CODES = [
'1452',
'1557',
'1216',
'1217',
'1451'
];
const POSTGRES_FK_ERROR_CODE = '23503';
const SQLITE_FK_ERROR_CODE = 'SQLITE_CONSTRAINT_FOREIGNKEY';
if (isErrorWithCode(e) && e.code) {
return [
SQLITE_FK_ERROR_CODE,
POSTGRES_FK_ERROR_CODE,
...MYSQL_FK_ERROR_CODES
].includes(e.code);
}
return e.message.toLowerCase().includes('foreign key constraint');
};
const createLinksWriteStream = (mapID, strapi, transaction, onWarning)=>{
return new stream.Writable({
objectMode: true,
async write (link$1, _encoding, callback) {
await transaction?.attach(async (trx)=>{
const { left, right } = link$1;
const query = link.createLinkQuery(strapi, trx);
const originalLeftRef = left.ref;
const originalRightRef = right.ref;
const mappedLeftRef = resolveLinkRef.resolveLinkRef(strapi, link$1, 'left', mapID);
const mappedRightRef = resolveLinkRef.resolveLinkRef(strapi, link$1, 'right', mapID);
// A missing mapping means the referenced row was never transferred
// during the entities stage (e.g. an orphaned component or a dangling
// reference in the source database). Falling back to the original ID
// would either violate a foreign key constraint — which aborts the
// whole transaction on PostgreSQL — or silently attach the link to an
// unrelated row, so the link is skipped instead.
if (mappedLeftRef === undefined || mappedRightRef === undefined) {
const missingRefs = [
...mappedLeftRef === undefined ? [
`${left.type}:${originalLeftRef}`
] : [],
...mappedRightRef === undefined ? [
`${right.type}:${originalRightRef}`
] : []
].join(' and ');
onWarning?.(`Skipping link ${left.type}:${originalLeftRef} -> ${right.type}:${originalRightRef} because ${missingRefs} was not transferred during the entities stage.`);
return callback(null);
}
left.ref = mappedLeftRef;
right.ref = mappedRightRef;
try {
await query().insert(link$1);
} catch (e) {
if (e instanceof Error) {
if (isForeignKeyConstraintError(e)) {
onWarning?.(`Skipping link ${left.type}:${originalLeftRef} -> ${right.type}:${originalRightRef} due to a foreign key constraint.`);
return callback(null);
}
return callback(e);
}
return callback(new providers.ProviderTransferError(`An error happened while trying to import a ${left.type} link.`));
}
callback(null);
});
}
});
};
exports.createLinksWriteStream = createLinksWriteStream;
//# sourceMappingURL=links.js.map