@strapi/data-transfer 5.51.1 → 5.52.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/dist/file/providers/source/index.js +3 -3
- package/dist/file/providers/source/index.js.map +1 -1
- package/dist/file/providers/source/index.mjs +3 -3
- package/dist/file/providers/source/index.mjs.map +1 -1
- package/dist/strapi/providers/local-destination/index.js +1 -1
- package/dist/strapi/providers/local-destination/index.js.map +1 -1
- package/dist/strapi/providers/local-destination/index.mjs +1 -1
- package/dist/strapi/providers/local-destination/index.mjs.map +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/configuration.js +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/configuration.js.map +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/configuration.mjs +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/configuration.mjs.map +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/index.js +1 -0
- package/dist/strapi/providers/local-destination/strategies/restore/index.js.map +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/index.mjs +1 -0
- package/dist/strapi/providers/local-destination/strategies/restore/index.mjs.map +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/links.d.ts +1 -0
- package/dist/strapi/providers/local-destination/strategies/restore/links.d.ts.map +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/links.js +57 -4
- package/dist/strapi/providers/local-destination/strategies/restore/links.js.map +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/links.mjs +57 -5
- package/dist/strapi/providers/local-destination/strategies/restore/links.mjs.map +1 -1
- package/dist/strapi/providers/local-source/index.d.ts.map +1 -1
- package/dist/strapi/providers/local-source/index.js +6 -1
- package/dist/strapi/providers/local-source/index.js.map +1 -1
- package/dist/strapi/providers/local-source/index.mjs +6 -1
- package/dist/strapi/providers/local-source/index.mjs.map +1 -1
- package/dist/strapi/providers/local-source/links.d.ts +4 -1
- package/dist/strapi/providers/local-source/links.d.ts.map +1 -1
- package/dist/strapi/providers/local-source/links.js +16 -2
- package/dist/strapi/providers/local-source/links.js.map +1 -1
- package/dist/strapi/providers/local-source/links.mjs +16 -3
- package/dist/strapi/providers/local-source/links.mjs.map +1 -1
- package/dist/strapi/queries/link.d.ts +4 -1
- package/dist/strapi/queries/link.d.ts.map +1 -1
- package/dist/strapi/queries/link.js +271 -64
- package/dist/strapi/queries/link.js.map +1 -1
- package/dist/strapi/queries/link.mjs +271 -64
- package/dist/strapi/queries/link.mjs.map +1 -1
- package/dist/strapi/remote/handlers/utils.js +1 -1
- package/dist/strapi/remote/handlers/utils.js.map +1 -1
- package/dist/strapi/remote/handlers/utils.mjs +1 -1
- package/dist/strapi/remote/handlers/utils.mjs.map +1 -1
- package/dist/utils/capped-warnings.d.ts +9 -0
- package/dist/utils/capped-warnings.d.ts.map +1 -0
- package/dist/utils/capped-warnings.js +28 -0
- package/dist/utils/capped-warnings.js.map +1 -0
- package/dist/utils/capped-warnings.mjs +25 -0
- package/dist/utils/capped-warnings.mjs.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +1 -0
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +8 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../../../src/strapi/providers/local-source/index.ts"],"sourcesContent":["import { Readable } from 'stream';\nimport { chain } from 'stream-chain';\nimport type { Core, Struct } from '@strapi/types';\n\nimport type { IMetadata, ISourceProvider, ProviderType, TransferStage } from '../../../types';\nimport type { IDiagnosticReporter } from '../../../utils/diagnostic';\nimport { createEntitiesStream, createEntitiesTransformStream } from './entities';\nimport { createLinksStream } from './links';\nimport { createConfigurationStream } from './configuration';\nimport { createAssetsStream } from './assets';\nimport { estimateAssetTotals } from './estimate-asset-totals';\nimport * as utils from '../../../utils';\nimport { assertValidStrapi } from '../../../utils/providers';\n\nexport interface ILocalStrapiSourceProviderOptions {\n getStrapi(): Core.Strapi | Promise<Core.Strapi>; // return an initialized instance of Strapi\n\n autoDestroy?: boolean; // shut down the instance returned by getStrapi() at the end of the transfer\n}\n\nexport const createLocalStrapiSourceProvider = (options: ILocalStrapiSourceProviderOptions) => {\n return new LocalStrapiSourceProvider(options);\n};\n\nclass LocalStrapiSourceProvider implements ISourceProvider {\n name = 'source::local-strapi';\n\n type: ProviderType = 'source';\n\n options: ILocalStrapiSourceProviderOptions;\n\n strapi?: Core.Strapi;\n\n #diagnostics?: IDiagnosticReporter;\n\n constructor(options: ILocalStrapiSourceProviderOptions) {\n this.options = options;\n }\n\n async bootstrap(diagnostics?: IDiagnosticReporter): Promise<void> {\n this.#diagnostics = diagnostics;\n this.strapi = await this.options.getStrapi();\n this.strapi.db.lifecycles.disable();\n }\n\n #reportInfo(message: string) {\n this.#diagnostics?.report({\n details: {\n createdAt: new Date(),\n message,\n origin: 'local-source-provider',\n },\n kind: 'info',\n });\n }\n\n #reportWarning(message: string) {\n this.#diagnostics?.report({\n details: {\n createdAt: new Date(),\n message,\n origin: 'local-source-provider',\n },\n kind: 'warning',\n });\n }\n\n /**\n * Reports an error to the diagnostic reporter.\n */\n #reportError(message: string, error: Error) {\n this.#diagnostics?.report({\n details: {\n createdAt: new Date(),\n message,\n error,\n severity: 'fatal',\n name: error.name,\n },\n kind: 'error',\n });\n }\n\n /**\n * Handles errors that occur in read streams.\n */\n #handleStreamError(streamType: string, err: Error) {\n const { message, stack } = err;\n const errorMessage = `[Data transfer] Error in ${streamType} read stream: ${message}`;\n const formattedError = {\n message: errorMessage,\n stack,\n timestamp: new Date().toISOString(),\n };\n\n this.strapi?.log.error(formattedError);\n this.#reportError(formattedError.message, err);\n }\n\n async close(): Promise<void> {\n const { autoDestroy } = this.options;\n assertValidStrapi(this.strapi);\n this.strapi.db.lifecycles.enable();\n // Basically `!== false` but more deterministic\n if (autoDestroy === undefined || autoDestroy === true) {\n await this.strapi?.destroy();\n }\n }\n\n getMetadata(): IMetadata {\n this.#reportInfo('getting metadata');\n assertValidStrapi(this.strapi);\n const strapiVersion = this.strapi.config.get<string>('info.strapi');\n const createdAt = new Date().toISOString();\n\n return {\n createdAt,\n strapi: {\n version: strapiVersion,\n },\n };\n }\n\n async createEntitiesReadStream(): Promise<Readable> {\n assertValidStrapi(this.strapi, 'Not able to stream entities');\n this.#reportInfo('creating entities read stream');\n return chain([\n // Entities stream\n createEntitiesStream(this.strapi, {\n onWarning: (message) => {\n this.strapi?.log.warn(message);\n this.#reportWarning(message);\n },\n }),\n\n // Transform stream\n createEntitiesTransformStream(),\n ]);\n }\n\n createLinksReadStream(): Readable {\n assertValidStrapi(this.strapi, 'Not able to stream links');\n this.#reportInfo('creating links read stream');\n\n return createLinksStream(this.strapi);\n }\n\n createConfigurationReadStream(): Readable {\n assertValidStrapi(this.strapi, 'Not able to stream configuration');\n this.#reportInfo('creating configuration read stream');\n return createConfigurationStream(this.strapi);\n }\n\n getSchemas(): Record<string, Struct.Schema> {\n assertValidStrapi(this.strapi, 'Not able to get Schemas');\n this.#reportInfo('getting schemas');\n const schemas = utils.schema.schemasToValidJSON({\n ...this.strapi.contentTypes,\n ...this.strapi.components,\n });\n\n return utils.schema.mapSchemasValues(schemas);\n }\n\n createSchemasReadStream(): Readable {\n return Readable.from(Object.values(this.getSchemas()));\n }\n\n createAssetsReadStream(): Readable {\n assertValidStrapi(this.strapi, 'Not able to stream assets');\n this.#reportInfo('creating assets read stream');\n\n const stream = createAssetsStream(this.strapi, {\n onWarning: (message) => this.#reportWarning(message),\n });\n stream.on('error', (err) => {\n this.#handleStreamError('assets', err);\n });\n\n return stream;\n }\n\n async getStageTotals(stage: TransferStage) {\n if (stage !== 'assets') {\n return null;\n }\n assertValidStrapi(this.strapi, 'Not able to estimate asset totals');\n return estimateAssetTotals(this.strapi);\n }\n}\n\nexport type ILocalStrapiSourceProvider = InstanceType<typeof LocalStrapiSourceProvider>;\n\nexport { estimateAssetTotals } from './estimate-asset-totals';\n"],"names":["createLocalStrapiSourceProvider","options","LocalStrapiSourceProvider","bootstrap","diagnostics","strapi","getStrapi","db","lifecycles","disable","close","autoDestroy","assertValidStrapi","enable","undefined","destroy","getMetadata","strapiVersion","config","get","createdAt","Date","toISOString","version","createEntitiesReadStream","chain","createEntitiesStream","onWarning","message","log","warn","createEntitiesTransformStream","createLinksReadStream","createLinksStream","createConfigurationReadStream","createConfigurationStream","getSchemas","schemas","utils","contentTypes","components","createSchemasReadStream","Readable","from","Object","values","createAssetsReadStream","stream","createAssetsStream","on","err","getStageTotals","stage","estimateAssetTotals","name","type","report","details","origin","kind","error","severity","streamType","stack","errorMessage","formattedError","timestamp"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../../../src/strapi/providers/local-source/index.ts"],"sourcesContent":["import { Readable } from 'stream';\nimport { chain } from 'stream-chain';\nimport type { Core, Struct } from '@strapi/types';\n\nimport type { IMetadata, ISourceProvider, ProviderType, TransferStage } from '../../../types';\nimport type { IDiagnosticReporter } from '../../../utils/diagnostic';\nimport { createEntitiesStream, createEntitiesTransformStream } from './entities';\nimport { createLinksStream } from './links';\nimport { createConfigurationStream } from './configuration';\nimport { createAssetsStream } from './assets';\nimport { estimateAssetTotals } from './estimate-asset-totals';\nimport * as utils from '../../../utils';\nimport { assertValidStrapi } from '../../../utils/providers';\n\nexport interface ILocalStrapiSourceProviderOptions {\n getStrapi(): Core.Strapi | Promise<Core.Strapi>; // return an initialized instance of Strapi\n\n autoDestroy?: boolean; // shut down the instance returned by getStrapi() at the end of the transfer\n}\n\nexport const createLocalStrapiSourceProvider = (options: ILocalStrapiSourceProviderOptions) => {\n return new LocalStrapiSourceProvider(options);\n};\n\nclass LocalStrapiSourceProvider implements ISourceProvider {\n name = 'source::local-strapi';\n\n type: ProviderType = 'source';\n\n options: ILocalStrapiSourceProviderOptions;\n\n strapi?: Core.Strapi;\n\n #diagnostics?: IDiagnosticReporter;\n\n constructor(options: ILocalStrapiSourceProviderOptions) {\n this.options = options;\n }\n\n async bootstrap(diagnostics?: IDiagnosticReporter): Promise<void> {\n this.#diagnostics = diagnostics;\n this.strapi = await this.options.getStrapi();\n this.strapi.db.lifecycles.disable();\n }\n\n #reportInfo(message: string) {\n this.#diagnostics?.report({\n details: {\n createdAt: new Date(),\n message,\n origin: 'local-source-provider',\n },\n kind: 'info',\n });\n }\n\n #reportWarning(message: string) {\n this.#diagnostics?.report({\n details: {\n createdAt: new Date(),\n message,\n origin: 'local-source-provider',\n },\n kind: 'warning',\n });\n }\n\n /**\n * Reports an error to the diagnostic reporter.\n */\n #reportError(message: string, error: Error) {\n this.#diagnostics?.report({\n details: {\n createdAt: new Date(),\n message,\n error,\n severity: 'fatal',\n name: error.name,\n },\n kind: 'error',\n });\n }\n\n /**\n * Handles errors that occur in read streams.\n */\n #handleStreamError(streamType: string, err: Error) {\n const { message, stack } = err;\n const errorMessage = `[Data transfer] Error in ${streamType} read stream: ${message}`;\n const formattedError = {\n message: errorMessage,\n stack,\n timestamp: new Date().toISOString(),\n };\n\n this.strapi?.log.error(formattedError);\n this.#reportError(formattedError.message, err);\n }\n\n async close(): Promise<void> {\n const { autoDestroy } = this.options;\n assertValidStrapi(this.strapi);\n this.strapi.db.lifecycles.enable();\n // Basically `!== false` but more deterministic\n if (autoDestroy === undefined || autoDestroy === true) {\n await this.strapi?.destroy();\n }\n }\n\n getMetadata(): IMetadata {\n this.#reportInfo('getting metadata');\n assertValidStrapi(this.strapi);\n const strapiVersion = this.strapi.config.get<string>('info.strapi');\n const createdAt = new Date().toISOString();\n\n return {\n createdAt,\n strapi: {\n version: strapiVersion,\n },\n };\n }\n\n async createEntitiesReadStream(): Promise<Readable> {\n assertValidStrapi(this.strapi, 'Not able to stream entities');\n this.#reportInfo('creating entities read stream');\n return chain([\n // Entities stream\n createEntitiesStream(this.strapi, {\n onWarning: (message) => {\n this.strapi?.log.warn(message);\n this.#reportWarning(message);\n },\n }),\n\n // Transform stream\n createEntitiesTransformStream(),\n ]);\n }\n\n createLinksReadStream(): Readable {\n assertValidStrapi(this.strapi, 'Not able to stream links');\n this.#reportInfo('creating links read stream');\n\n return createLinksStream(this.strapi, {\n onWarning: (message) => {\n this.strapi?.log.warn(message);\n this.#reportWarning(message);\n },\n });\n }\n\n createConfigurationReadStream(): Readable {\n assertValidStrapi(this.strapi, 'Not able to stream configuration');\n this.#reportInfo('creating configuration read stream');\n return createConfigurationStream(this.strapi);\n }\n\n getSchemas(): Record<string, Struct.Schema> {\n assertValidStrapi(this.strapi, 'Not able to get Schemas');\n this.#reportInfo('getting schemas');\n const schemas = utils.schema.schemasToValidJSON({\n ...this.strapi.contentTypes,\n ...this.strapi.components,\n });\n\n return utils.schema.mapSchemasValues(schemas);\n }\n\n createSchemasReadStream(): Readable {\n return Readable.from(Object.values(this.getSchemas()));\n }\n\n createAssetsReadStream(): Readable {\n assertValidStrapi(this.strapi, 'Not able to stream assets');\n this.#reportInfo('creating assets read stream');\n\n const stream = createAssetsStream(this.strapi, {\n onWarning: (message) => this.#reportWarning(message),\n });\n stream.on('error', (err) => {\n this.#handleStreamError('assets', err);\n });\n\n return stream;\n }\n\n async getStageTotals(stage: TransferStage) {\n if (stage !== 'assets') {\n return null;\n }\n assertValidStrapi(this.strapi, 'Not able to estimate asset totals');\n return estimateAssetTotals(this.strapi);\n }\n}\n\nexport type ILocalStrapiSourceProvider = InstanceType<typeof LocalStrapiSourceProvider>;\n\nexport { estimateAssetTotals } from './estimate-asset-totals';\n"],"names":["createLocalStrapiSourceProvider","options","LocalStrapiSourceProvider","bootstrap","diagnostics","strapi","getStrapi","db","lifecycles","disable","close","autoDestroy","assertValidStrapi","enable","undefined","destroy","getMetadata","strapiVersion","config","get","createdAt","Date","toISOString","version","createEntitiesReadStream","chain","createEntitiesStream","onWarning","message","log","warn","createEntitiesTransformStream","createLinksReadStream","createLinksStream","createConfigurationReadStream","createConfigurationStream","getSchemas","schemas","utils","contentTypes","components","createSchemasReadStream","Readable","from","Object","values","createAssetsReadStream","stream","createAssetsStream","on","err","getStageTotals","stage","estimateAssetTotals","name","type","report","details","origin","kind","error","severity","streamType","stack","errorMessage","formattedError","timestamp"],"mappings":"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"}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { Readable } from 'stream';
|
|
2
2
|
import type { Core } from '@strapi/types';
|
|
3
|
+
export declare const formatOrphanedLinksExportSummary: (count: number) => string;
|
|
3
4
|
/**
|
|
4
5
|
* Create a Readable which will stream all the links from a Strapi instance
|
|
5
6
|
*/
|
|
6
|
-
export declare const createLinksStream: (strapi: Core.Strapi
|
|
7
|
+
export declare const createLinksStream: (strapi: Core.Strapi, options?: {
|
|
8
|
+
onWarning?: (message: string) => void;
|
|
9
|
+
}) => Readable;
|
|
7
10
|
//# sourceMappingURL=links.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../../../../src/strapi/providers/local-source/links.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../../../../src/strapi/providers/local-source/links.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAS1C,eAAO,MAAM,gCAAgC,GAAI,OAAO,MAAM,WACkE,CAAC;AAEjI;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,IAAI,CAAC,MAAM,EACnB,UAAS;IAAE,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAAO,aA6BxD,CAAC"}
|
|
@@ -1,26 +1,40 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var stream = require('stream');
|
|
4
|
+
var cappedWarnings = require('../../../utils/capped-warnings.js');
|
|
4
5
|
var link = require('../../queries/link.js');
|
|
5
6
|
|
|
7
|
+
const formatOrphanedExportLinkWarning = (link)=>`Omitting link ${link.left.type}:${link.left.ref} -> ${link.right.type}:${link.right.ref} from export because a referenced entity no longer exists in the database.`;
|
|
8
|
+
const formatOrphanedLinksExportSummary = (count)=>`Links export omitted ${count} relation(s) pointing at missing entities. Verify relations after import if this is unexpected.`;
|
|
6
9
|
/**
|
|
7
10
|
* Create a Readable which will stream all the links from a Strapi instance
|
|
8
|
-
*/ const createLinksStream = (strapi)=>{
|
|
11
|
+
*/ const createLinksStream = (strapi, options = {})=>{
|
|
9
12
|
const uids = [
|
|
10
13
|
...Object.keys(strapi.contentTypes),
|
|
11
14
|
...Object.keys(strapi.components)
|
|
12
15
|
];
|
|
16
|
+
let orphanedLinkCount = 0;
|
|
17
|
+
const warnings = cappedWarnings.createCappedWarningReporter(options.onWarning);
|
|
18
|
+
const query = link.createLinkQuery(strapi, undefined, {
|
|
19
|
+
onOrphanedLink (link) {
|
|
20
|
+
orphanedLinkCount += 1;
|
|
21
|
+
warnings.warn(formatOrphanedExportLinkWarning(link));
|
|
22
|
+
}
|
|
23
|
+
});
|
|
13
24
|
// Async generator stream that returns every link from a Strapi instance
|
|
14
25
|
return stream.Readable.from(async function* linkGenerator() {
|
|
15
|
-
const query = link.createLinkQuery(strapi);
|
|
16
26
|
for (const uid of uids){
|
|
17
27
|
const generator = query().generateAll(uid);
|
|
18
28
|
for await (const link of generator){
|
|
19
29
|
yield link;
|
|
20
30
|
}
|
|
21
31
|
}
|
|
32
|
+
if (orphanedLinkCount > 0) {
|
|
33
|
+
options.onWarning?.(formatOrphanedLinksExportSummary(orphanedLinkCount));
|
|
34
|
+
}
|
|
22
35
|
}());
|
|
23
36
|
};
|
|
24
37
|
|
|
25
38
|
exports.createLinksStream = createLinksStream;
|
|
39
|
+
exports.formatOrphanedLinksExportSummary = formatOrphanedLinksExportSummary;
|
|
26
40
|
//# sourceMappingURL=links.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"links.js","sources":["../../../../src/strapi/providers/local-source/links.ts"],"sourcesContent":["import { Readable } from 'stream';\nimport type { Core } from '@strapi/types';\n\nimport type { ILink } from '../../../types';\nimport { createLinkQuery } from '../../queries/link';\n\n/**\n * Create a Readable which will stream all the links from a Strapi instance\n */\nexport const createLinksStream = (strapi: Core.Strapi
|
|
1
|
+
{"version":3,"file":"links.js","sources":["../../../../src/strapi/providers/local-source/links.ts"],"sourcesContent":["import { Readable } from 'stream';\nimport type { Core } from '@strapi/types';\n\nimport type { ILink } from '../../../types';\nimport { createCappedWarningReporter } from '../../../utils/capped-warnings';\nimport { createLinkQuery } from '../../queries/link';\n\nconst formatOrphanedExportLinkWarning = (link: ILink) =>\n `Omitting link ${link.left.type}:${link.left.ref} -> ${link.right.type}:${link.right.ref} from export because a referenced entity no longer exists in the database.`;\n\nexport const formatOrphanedLinksExportSummary = (count: number) =>\n `Links export omitted ${count} relation(s) pointing at missing entities. Verify relations after import if this is unexpected.`;\n\n/**\n * Create a Readable which will stream all the links from a Strapi instance\n */\nexport const createLinksStream = (\n strapi: Core.Strapi,\n options: { onWarning?: (message: string) => void } = {}\n) => {\n const uids = [...Object.keys(strapi.contentTypes), ...Object.keys(strapi.components)] as string[];\n let orphanedLinkCount = 0;\n const warnings = createCappedWarningReporter(options.onWarning);\n\n const query = createLinkQuery(strapi, undefined, {\n onOrphanedLink(link) {\n orphanedLinkCount += 1;\n warnings.warn(formatOrphanedExportLinkWarning(link));\n },\n });\n\n // Async generator stream that returns every link from a Strapi instance\n return Readable.from(\n (async function* linkGenerator(): AsyncGenerator<ILink> {\n for (const uid of uids) {\n const generator = query().generateAll(uid);\n\n for await (const link of generator) {\n yield link;\n }\n }\n\n if (orphanedLinkCount > 0) {\n options.onWarning?.(formatOrphanedLinksExportSummary(orphanedLinkCount));\n }\n })()\n );\n};\n"],"names":["formatOrphanedExportLinkWarning","link","left","type","ref","right","formatOrphanedLinksExportSummary","count","createLinksStream","strapi","options","uids","Object","keys","contentTypes","components","orphanedLinkCount","warnings","createCappedWarningReporter","onWarning","query","createLinkQuery","undefined","onOrphanedLink","warn","Readable","from","linkGenerator","uid","generator","generateAll"],"mappings":";;;;;;AAOA,MAAMA,+BAAAA,GAAkC,CAACC,IAAAA,GACvC,CAAC,cAAc,EAAEA,IAAAA,CAAKC,IAAI,CAACC,IAAI,CAAC,CAAC,EAAEF,KAAKC,IAAI,CAACE,GAAG,CAAC,IAAI,EAAEH,IAAAA,CAAKI,KAAK,CAACF,IAAI,CAAC,CAAC,EAAEF,KAAKI,KAAK,CAACD,GAAG,CAAC,0EAA0E,CAAC;AAE/J,MAAME,gCAAAA,GAAmC,CAACC,KAAAA,GAC/C,CAAC,qBAAqB,EAAEA,KAAAA,CAAM,+FAA+F;AAE/H;;AAEC,IACM,MAAMC,iBAAAA,GAAoB,CAC/BC,MAAAA,EACAC,OAAAA,GAAqD,EAAE,GAAA;AAEvD,IAAA,MAAMC,IAAAA,GAAO;WAAIC,MAAAA,CAAOC,IAAI,CAACJ,MAAAA,CAAOK,YAAY,CAAA;WAAMF,MAAAA,CAAOC,IAAI,CAACJ,MAAAA,CAAOM,UAAU;AAAE,KAAA;AACrF,IAAA,IAAIC,iBAAAA,GAAoB,CAAA;IACxB,MAAMC,QAAAA,GAAWC,0CAAAA,CAA4BR,OAAAA,CAAQS,SAAS,CAAA;IAE9D,MAAMC,KAAAA,GAAQC,oBAAAA,CAAgBZ,MAAAA,EAAQa,SAAAA,EAAW;AAC/CC,QAAAA,cAAAA,CAAAA,CAAetB,IAAI,EAAA;YACjBe,iBAAAA,IAAqB,CAAA;YACrBC,QAAAA,CAASO,IAAI,CAACxB,+BAAAA,CAAgCC,IAAAA,CAAAA,CAAAA;AAChD,QAAA;AACF,KAAA,CAAA;;AAGA,IAAA,OAAOwB,eAAAA,CAASC,IAAI,CACjB,gBAAgBC,aAAAA,GAAAA;QACf,KAAK,MAAMC,OAAOjB,IAAAA,CAAM;YACtB,MAAMkB,SAAAA,GAAYT,KAAAA,EAAAA,CAAQU,WAAW,CAACF,GAAAA,CAAAA;YAEtC,WAAW,MAAM3B,QAAQ4B,SAAAA,CAAW;gBAClC,MAAM5B,IAAAA;AACR,YAAA;AACF,QAAA;AAEA,QAAA,IAAIe,oBAAoB,CAAA,EAAG;YACzBN,OAAAA,CAAQS,SAAS,GAAGb,gCAAAA,CAAiCU,iBAAAA,CAAAA,CAAAA;AACvD,QAAA;AACF,IAAA,CAAA,EAAA,CAAA;AAEJ;;;;;"}
|
|
@@ -1,24 +1,37 @@
|
|
|
1
1
|
import { Readable } from 'stream';
|
|
2
|
+
import { createCappedWarningReporter } from '../../../utils/capped-warnings.mjs';
|
|
2
3
|
import { createLinkQuery } from '../../queries/link.mjs';
|
|
3
4
|
|
|
5
|
+
const formatOrphanedExportLinkWarning = (link)=>`Omitting link ${link.left.type}:${link.left.ref} -> ${link.right.type}:${link.right.ref} from export because a referenced entity no longer exists in the database.`;
|
|
6
|
+
const formatOrphanedLinksExportSummary = (count)=>`Links export omitted ${count} relation(s) pointing at missing entities. Verify relations after import if this is unexpected.`;
|
|
4
7
|
/**
|
|
5
8
|
* Create a Readable which will stream all the links from a Strapi instance
|
|
6
|
-
*/ const createLinksStream = (strapi)=>{
|
|
9
|
+
*/ const createLinksStream = (strapi, options = {})=>{
|
|
7
10
|
const uids = [
|
|
8
11
|
...Object.keys(strapi.contentTypes),
|
|
9
12
|
...Object.keys(strapi.components)
|
|
10
13
|
];
|
|
14
|
+
let orphanedLinkCount = 0;
|
|
15
|
+
const warnings = createCappedWarningReporter(options.onWarning);
|
|
16
|
+
const query = createLinkQuery(strapi, undefined, {
|
|
17
|
+
onOrphanedLink (link) {
|
|
18
|
+
orphanedLinkCount += 1;
|
|
19
|
+
warnings.warn(formatOrphanedExportLinkWarning(link));
|
|
20
|
+
}
|
|
21
|
+
});
|
|
11
22
|
// Async generator stream that returns every link from a Strapi instance
|
|
12
23
|
return Readable.from(async function* linkGenerator() {
|
|
13
|
-
const query = createLinkQuery(strapi);
|
|
14
24
|
for (const uid of uids){
|
|
15
25
|
const generator = query().generateAll(uid);
|
|
16
26
|
for await (const link of generator){
|
|
17
27
|
yield link;
|
|
18
28
|
}
|
|
19
29
|
}
|
|
30
|
+
if (orphanedLinkCount > 0) {
|
|
31
|
+
options.onWarning?.(formatOrphanedLinksExportSummary(orphanedLinkCount));
|
|
32
|
+
}
|
|
20
33
|
}());
|
|
21
34
|
};
|
|
22
35
|
|
|
23
|
-
export { createLinksStream };
|
|
36
|
+
export { createLinksStream, formatOrphanedLinksExportSummary };
|
|
24
37
|
//# sourceMappingURL=links.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"links.mjs","sources":["../../../../src/strapi/providers/local-source/links.ts"],"sourcesContent":["import { Readable } from 'stream';\nimport type { Core } from '@strapi/types';\n\nimport type { ILink } from '../../../types';\nimport { createLinkQuery } from '../../queries/link';\n\n/**\n * Create a Readable which will stream all the links from a Strapi instance\n */\nexport const createLinksStream = (strapi: Core.Strapi
|
|
1
|
+
{"version":3,"file":"links.mjs","sources":["../../../../src/strapi/providers/local-source/links.ts"],"sourcesContent":["import { Readable } from 'stream';\nimport type { Core } from '@strapi/types';\n\nimport type { ILink } from '../../../types';\nimport { createCappedWarningReporter } from '../../../utils/capped-warnings';\nimport { createLinkQuery } from '../../queries/link';\n\nconst formatOrphanedExportLinkWarning = (link: ILink) =>\n `Omitting link ${link.left.type}:${link.left.ref} -> ${link.right.type}:${link.right.ref} from export because a referenced entity no longer exists in the database.`;\n\nexport const formatOrphanedLinksExportSummary = (count: number) =>\n `Links export omitted ${count} relation(s) pointing at missing entities. Verify relations after import if this is unexpected.`;\n\n/**\n * Create a Readable which will stream all the links from a Strapi instance\n */\nexport const createLinksStream = (\n strapi: Core.Strapi,\n options: { onWarning?: (message: string) => void } = {}\n) => {\n const uids = [...Object.keys(strapi.contentTypes), ...Object.keys(strapi.components)] as string[];\n let orphanedLinkCount = 0;\n const warnings = createCappedWarningReporter(options.onWarning);\n\n const query = createLinkQuery(strapi, undefined, {\n onOrphanedLink(link) {\n orphanedLinkCount += 1;\n warnings.warn(formatOrphanedExportLinkWarning(link));\n },\n });\n\n // Async generator stream that returns every link from a Strapi instance\n return Readable.from(\n (async function* linkGenerator(): AsyncGenerator<ILink> {\n for (const uid of uids) {\n const generator = query().generateAll(uid);\n\n for await (const link of generator) {\n yield link;\n }\n }\n\n if (orphanedLinkCount > 0) {\n options.onWarning?.(formatOrphanedLinksExportSummary(orphanedLinkCount));\n }\n })()\n );\n};\n"],"names":["formatOrphanedExportLinkWarning","link","left","type","ref","right","formatOrphanedLinksExportSummary","count","createLinksStream","strapi","options","uids","Object","keys","contentTypes","components","orphanedLinkCount","warnings","createCappedWarningReporter","onWarning","query","createLinkQuery","undefined","onOrphanedLink","warn","Readable","from","linkGenerator","uid","generator","generateAll"],"mappings":";;;;AAOA,MAAMA,+BAAAA,GAAkC,CAACC,IAAAA,GACvC,CAAC,cAAc,EAAEA,IAAAA,CAAKC,IAAI,CAACC,IAAI,CAAC,CAAC,EAAEF,KAAKC,IAAI,CAACE,GAAG,CAAC,IAAI,EAAEH,IAAAA,CAAKI,KAAK,CAACF,IAAI,CAAC,CAAC,EAAEF,KAAKI,KAAK,CAACD,GAAG,CAAC,0EAA0E,CAAC;AAE/J,MAAME,gCAAAA,GAAmC,CAACC,KAAAA,GAC/C,CAAC,qBAAqB,EAAEA,KAAAA,CAAM,+FAA+F;AAE/H;;AAEC,IACM,MAAMC,iBAAAA,GAAoB,CAC/BC,MAAAA,EACAC,OAAAA,GAAqD,EAAE,GAAA;AAEvD,IAAA,MAAMC,IAAAA,GAAO;WAAIC,MAAAA,CAAOC,IAAI,CAACJ,MAAAA,CAAOK,YAAY,CAAA;WAAMF,MAAAA,CAAOC,IAAI,CAACJ,MAAAA,CAAOM,UAAU;AAAE,KAAA;AACrF,IAAA,IAAIC,iBAAAA,GAAoB,CAAA;IACxB,MAAMC,QAAAA,GAAWC,2BAAAA,CAA4BR,OAAAA,CAAQS,SAAS,CAAA;IAE9D,MAAMC,KAAAA,GAAQC,eAAAA,CAAgBZ,MAAAA,EAAQa,SAAAA,EAAW;AAC/CC,QAAAA,cAAAA,CAAAA,CAAetB,IAAI,EAAA;YACjBe,iBAAAA,IAAqB,CAAA;YACrBC,QAAAA,CAASO,IAAI,CAACxB,+BAAAA,CAAgCC,IAAAA,CAAAA,CAAAA;AAChD,QAAA;AACF,KAAA,CAAA;;AAGA,IAAA,OAAOwB,QAAAA,CAASC,IAAI,CACjB,gBAAgBC,aAAAA,GAAAA;QACf,KAAK,MAAMC,OAAOjB,IAAAA,CAAM;YACtB,MAAMkB,SAAAA,GAAYT,KAAAA,EAAAA,CAAQU,WAAW,CAACF,GAAAA,CAAAA;YAEtC,WAAW,MAAM3B,QAAQ4B,SAAAA,CAAW;gBAClC,MAAM5B,IAAAA;AACR,YAAA;AACF,QAAA;AAEA,QAAA,IAAIe,oBAAoB,CAAA,EAAG;YACzBN,OAAAA,CAAQS,SAAS,GAAGb,gCAAAA,CAAiCU,iBAAAA,CAAAA,CAAAA;AACvD,QAAA;AACF,IAAA,CAAA,EAAA,CAAA;AAEJ;;;;"}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { Knex } from 'knex';
|
|
2
2
|
import type { Core } from '@strapi/types';
|
|
3
3
|
import { ILink } from '../../types';
|
|
4
|
-
export
|
|
4
|
+
export interface LinkQueryOptions {
|
|
5
|
+
onOrphanedLink?: (link: ILink) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare const createLinkQuery: (strapi: Core.Strapi, trx?: Knex.Transaction, options?: LinkQueryOptions) => () => {
|
|
5
8
|
generateAll: (uid: string) => AsyncGenerator<ILink>;
|
|
6
9
|
generateAllForAttribute: (uid: string, fieldName: string) => AsyncGenerator<ILink>;
|
|
7
10
|
insert: (link: ILink) => Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../../src/strapi/queries/link.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAEjC,OAAO,KAAK,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../../src/strapi/queries/link.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAEjC,OAAO,KAAK,EAAE,IAAI,EAAO,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAkHpC,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC;CACxC;AAOD,eAAO,MAAM,eAAe,GAC1B,QAAQ,IAAI,CAAC,MAAM,EACnB,MAAM,IAAI,CAAC,WAAW,EACtB,UAAU,gBAAgB;uBAgVS,MAAM,KAAG,cAAc,CAAC,KAAK,CAAC;mCAnUlB,MAAM,aAAa,MAAM,KAAG,cAAc,CAAC,KAAK,CAAC;mBAmVlE,KAAK;CA+GpC,CAAC;AAEF,eAAO,MAAM,+BAA+B,GAAI,YAAY,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,wBAY9E,CAAC"}
|
|
@@ -3,7 +3,105 @@
|
|
|
3
3
|
var fp = require('lodash/fp');
|
|
4
4
|
|
|
5
5
|
// TODO: Remove any types when we'll have types for DB metadata
|
|
6
|
-
const
|
|
6
|
+
const TARGET_EXISTS_ALIAS = '__target_exists';
|
|
7
|
+
const LEFT_EXISTS_ALIAS = '__left_exists';
|
|
8
|
+
const RIGHT_EXISTS_ALIAS = '__right_exists';
|
|
9
|
+
const EXISTENCE_CHECK_CHUNK_SIZE = 1000;
|
|
10
|
+
const getMetadataTableName = (strapi, uid)=>{
|
|
11
|
+
const metadata = strapi.db.metadata.get(uid);
|
|
12
|
+
if (!metadata) {
|
|
13
|
+
throw new Error(`No metadata found for ${uid}`);
|
|
14
|
+
}
|
|
15
|
+
return metadata.tableName;
|
|
16
|
+
};
|
|
17
|
+
const refKey = (ref)=>`${typeof ref}:${ref}`;
|
|
18
|
+
/**
|
|
19
|
+
* Batch-load which refs exist for a content type. Handles numeric `id` refs and
|
|
20
|
+
* string `documentId` refs separately, chunked to keep `IN (...)` lists bounded.
|
|
21
|
+
*/ const loadExistingRefs = async (strapi, uid, refs)=>{
|
|
22
|
+
const existing = new Set();
|
|
23
|
+
// Stale morph type UIDs (removed components/CTs) have no metadata — treat as orphaned.
|
|
24
|
+
if (!strapi.db.metadata.has(uid)) {
|
|
25
|
+
return existing;
|
|
26
|
+
}
|
|
27
|
+
const uniqueRefs = [
|
|
28
|
+
...new Set(refs)
|
|
29
|
+
];
|
|
30
|
+
const numericIds = uniqueRefs.filter((ref)=>typeof ref === 'number');
|
|
31
|
+
const documentIds = uniqueRefs.filter((ref)=>typeof ref === 'string');
|
|
32
|
+
for(let i = 0; i < numericIds.length; i += EXISTENCE_CHECK_CHUNK_SIZE){
|
|
33
|
+
const chunk = numericIds.slice(i, i + EXISTENCE_CHECK_CHUNK_SIZE);
|
|
34
|
+
const rows = await strapi.db.query(uid).findMany({
|
|
35
|
+
select: [
|
|
36
|
+
'id'
|
|
37
|
+
],
|
|
38
|
+
where: {
|
|
39
|
+
id: {
|
|
40
|
+
$in: chunk
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
for (const row of rows){
|
|
45
|
+
existing.add(refKey(row.id));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
for(let i = 0; i < documentIds.length; i += EXISTENCE_CHECK_CHUNK_SIZE){
|
|
49
|
+
const chunk = documentIds.slice(i, i + EXISTENCE_CHECK_CHUNK_SIZE);
|
|
50
|
+
const rows = await strapi.db.query(uid).findMany({
|
|
51
|
+
select: [
|
|
52
|
+
'id',
|
|
53
|
+
'documentId'
|
|
54
|
+
],
|
|
55
|
+
where: {
|
|
56
|
+
documentId: {
|
|
57
|
+
$in: chunk
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
for (const row of rows){
|
|
62
|
+
if (row.documentId != null) {
|
|
63
|
+
existing.add(refKey(row.documentId));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return existing;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Filter morph links in batches. The morph owner (`left`) is not checked:
|
|
71
|
+
* morphColumn rows come from the owner table itself, and morph join-table
|
|
72
|
+
* owners are FK-backed. Only dynamic morph targets (`right`) need existence
|
|
73
|
+
* checks, and those have no DB-level FK.
|
|
74
|
+
*/ const filterMorphLinksByTargetExistence = async function* filterMorphLinksByTargetExistence(strapi, links, onOrphanedLink) {
|
|
75
|
+
const refsByType = new Map();
|
|
76
|
+
for (const link of links){
|
|
77
|
+
const { type, ref } = link.right;
|
|
78
|
+
if (ref == null || type == null) {
|
|
79
|
+
onOrphanedLink?.(link);
|
|
80
|
+
} else {
|
|
81
|
+
const bucket = refsByType.get(type) ?? [];
|
|
82
|
+
bucket.push(ref);
|
|
83
|
+
refsByType.set(type, bucket);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const existingByType = new Map();
|
|
87
|
+
for (const [type, refs] of refsByType){
|
|
88
|
+
existingByType.set(type, await loadExistingRefs(strapi, type, refs));
|
|
89
|
+
}
|
|
90
|
+
for (const link of links){
|
|
91
|
+
const { type, ref } = link.right;
|
|
92
|
+
if (ref == null || type == null) ; else if (existingByType.get(type)?.has(refKey(ref))) {
|
|
93
|
+
yield link;
|
|
94
|
+
} else {
|
|
95
|
+
onOrphanedLink?.(link);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
const aliasColumn = (tableAlias, column)=>`${tableAlias}.${column}`;
|
|
100
|
+
const selectAliasedColumns = (tableAlias, columns)=>columns.map((column)=>({
|
|
101
|
+
[column]: aliasColumn(tableAlias, column)
|
|
102
|
+
}));
|
|
103
|
+
const createLinkQuery = (strapi, trx, options)=>{
|
|
104
|
+
const { onOrphanedLink } = options ?? {};
|
|
7
105
|
const query = ()=>{
|
|
8
106
|
const { connection } = strapi.db;
|
|
9
107
|
// TODO: Export utils from database and use the addSchema that is already written
|
|
@@ -27,7 +125,34 @@ const createLinkQuery = (strapi, trx)=>{
|
|
|
27
125
|
// TODO: handle manyToOne joinColumn
|
|
28
126
|
if (attribute.joinColumn) {
|
|
29
127
|
const joinColumnName = attribute.joinColumn.name;
|
|
30
|
-
const
|
|
128
|
+
const referencedColumn = attribute.joinColumn.referencedColumn ?? 'id';
|
|
129
|
+
const ownerAlias = 'owner';
|
|
130
|
+
const targetAlias = 'target';
|
|
131
|
+
const ownerTable = addSchema(metadata.tableName);
|
|
132
|
+
const targetTable = addSchema(getMetadataTableName(strapi, target));
|
|
133
|
+
// Use EXISTS (not JOIN): joining on non-unique referencedColumn (e.g. i18n
|
|
134
|
+
// document_id) multiplies owner rows by matching target locales.
|
|
135
|
+
const targetExistsSubquery = ()=>connection.queryBuilder().select(connection.raw('1')).from({
|
|
136
|
+
[targetAlias]: targetTable
|
|
137
|
+
}).whereRaw('??.?? = ??.??', [
|
|
138
|
+
targetAlias,
|
|
139
|
+
referencedColumn,
|
|
140
|
+
ownerAlias,
|
|
141
|
+
joinColumnName
|
|
142
|
+
]);
|
|
143
|
+
const qb = connection.queryBuilder().select(`${ownerAlias}.id`, `${ownerAlias}.${joinColumnName} as ${joinColumnName}`, ...onOrphanedLink ? // becomes `exists ((select ...))`, which SQLite rejects in a SELECT
|
|
144
|
+
// list. Wrap the EXISTS expression so the compiled SQL is valid.
|
|
145
|
+
[
|
|
146
|
+
connection.raw('(exists ?) as ??', [
|
|
147
|
+
targetExistsSubquery(),
|
|
148
|
+
TARGET_EXISTS_ALIAS
|
|
149
|
+
])
|
|
150
|
+
] : []).from({
|
|
151
|
+
[ownerAlias]: ownerTable
|
|
152
|
+
}).whereNotNull(aliasColumn(ownerAlias, joinColumnName));
|
|
153
|
+
if (!onOrphanedLink) {
|
|
154
|
+
qb.whereExists(targetExistsSubquery());
|
|
155
|
+
}
|
|
31
156
|
if (trx) {
|
|
32
157
|
qb.transacting(trx);
|
|
33
158
|
}
|
|
@@ -35,27 +160,30 @@ const createLinkQuery = (strapi, trx)=>{
|
|
|
35
160
|
const entries = await qb;
|
|
36
161
|
for (const entry of entries){
|
|
37
162
|
const ref = entry[joinColumnName];
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
163
|
+
const link = {
|
|
164
|
+
kind,
|
|
165
|
+
relation,
|
|
166
|
+
left: {
|
|
167
|
+
type: uid,
|
|
168
|
+
ref: entry.id,
|
|
169
|
+
field: fieldName
|
|
170
|
+
},
|
|
171
|
+
right: {
|
|
172
|
+
type: target,
|
|
173
|
+
ref
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
// EXISTS yields 0/1 (or boolean); treat falsy as orphaned.
|
|
177
|
+
if (onOrphanedLink && !entry[TARGET_EXISTS_ALIAS]) {
|
|
178
|
+
onOrphanedLink(link);
|
|
179
|
+
} else {
|
|
180
|
+
yield link;
|
|
52
181
|
}
|
|
53
182
|
}
|
|
54
183
|
}
|
|
55
184
|
// The relation uses a join table
|
|
56
185
|
if (attribute.joinTable) {
|
|
57
186
|
const { name, joinColumn, inverseJoinColumn, orderColumnName, morphColumn, inverseOrderColumnName } = attribute.joinTable;
|
|
58
|
-
const qb = connection.queryBuilder().from(addSchema(name));
|
|
59
187
|
const columns = {
|
|
60
188
|
left: {
|
|
61
189
|
ref: null
|
|
@@ -80,56 +208,137 @@ const createLinkQuery = (strapi, trx)=>{
|
|
|
80
208
|
if (inverseOrderColumnName) {
|
|
81
209
|
columns.right.order = inverseOrderColumnName;
|
|
82
210
|
}
|
|
211
|
+
const joinAlias = 'join';
|
|
212
|
+
const leftAlias = 'left';
|
|
213
|
+
const rightAlias = 'right';
|
|
214
|
+
const joinTable = addSchema(name);
|
|
215
|
+
const leftTable = addSchema(metadata.tableName);
|
|
216
|
+
const rightTable = addSchema(getMetadataTableName(strapi, attribute.target));
|
|
217
|
+
const leftReferencedColumn = aliasColumn(leftAlias, joinColumn.referencedColumn ?? 'id');
|
|
218
|
+
const rightReferencedColumn = aliasColumn(rightAlias, inverseJoinColumn.referencedColumn ?? 'id');
|
|
219
|
+
const validColumns = [
|
|
220
|
+
columns.left.ref,
|
|
221
|
+
columns.left.order,
|
|
222
|
+
columns.right.ref,
|
|
223
|
+
columns.right.order
|
|
224
|
+
].filter((column)=>!fp.isNil(column));
|
|
225
|
+
const buildJoinTableLink = (entry)=>{
|
|
226
|
+
const linkLeft = {
|
|
227
|
+
type: uid,
|
|
228
|
+
field: fieldName
|
|
229
|
+
};
|
|
230
|
+
const linkRight = {
|
|
231
|
+
type: attribute.target,
|
|
232
|
+
field: attribute.inversedBy
|
|
233
|
+
};
|
|
234
|
+
if (columns.left.ref) {
|
|
235
|
+
linkLeft.ref = entry[columns.left.ref];
|
|
236
|
+
}
|
|
237
|
+
if (columns.right.ref) {
|
|
238
|
+
linkRight.ref = entry[columns.right.ref];
|
|
239
|
+
}
|
|
240
|
+
if (columns.left.order) {
|
|
241
|
+
linkLeft.pos = entry[columns.left.order];
|
|
242
|
+
}
|
|
243
|
+
if (columns.right.order) {
|
|
244
|
+
linkRight.pos = entry[columns.right.order];
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
kind,
|
|
248
|
+
relation,
|
|
249
|
+
left: fp.clone(linkLeft),
|
|
250
|
+
right: fp.clone(linkRight)
|
|
251
|
+
};
|
|
252
|
+
};
|
|
253
|
+
const selectColumns = [
|
|
254
|
+
...selectAliasedColumns(joinAlias, validColumns),
|
|
255
|
+
...onOrphanedLink ? [
|
|
256
|
+
{
|
|
257
|
+
[LEFT_EXISTS_ALIAS]: leftReferencedColumn
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
[RIGHT_EXISTS_ALIAS]: rightReferencedColumn
|
|
261
|
+
}
|
|
262
|
+
] : []
|
|
263
|
+
];
|
|
264
|
+
const joinQb = connection.queryBuilder().select(selectColumns).from({
|
|
265
|
+
[joinAlias]: joinTable
|
|
266
|
+
});
|
|
267
|
+
if (onOrphanedLink) {
|
|
268
|
+
joinQb.leftJoin({
|
|
269
|
+
[leftAlias]: leftTable
|
|
270
|
+
}, aliasColumn(joinAlias, joinColumn.name), leftReferencedColumn).leftJoin({
|
|
271
|
+
[rightAlias]: rightTable
|
|
272
|
+
}, aliasColumn(joinAlias, inverseJoinColumn.name), rightReferencedColumn);
|
|
273
|
+
} else {
|
|
274
|
+
joinQb.innerJoin({
|
|
275
|
+
[leftAlias]: leftTable
|
|
276
|
+
}, aliasColumn(joinAlias, joinColumn.name), leftReferencedColumn).innerJoin({
|
|
277
|
+
[rightAlias]: rightTable
|
|
278
|
+
}, aliasColumn(joinAlias, inverseJoinColumn.name), rightReferencedColumn);
|
|
279
|
+
}
|
|
280
|
+
if (trx) {
|
|
281
|
+
joinQb.transacting(trx);
|
|
282
|
+
}
|
|
283
|
+
const entries = await joinQb;
|
|
284
|
+
for (const entry of entries){
|
|
285
|
+
const link = buildJoinTableLink(entry);
|
|
286
|
+
if (onOrphanedLink && (entry[LEFT_EXISTS_ALIAS] == null || entry[RIGHT_EXISTS_ALIAS] == null)) {
|
|
287
|
+
onOrphanedLink(link);
|
|
288
|
+
} else {
|
|
289
|
+
yield link;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
83
292
|
}
|
|
84
293
|
if (kind === 'relation.morph') {
|
|
294
|
+
const qb = connection.queryBuilder().from(addSchema(name));
|
|
85
295
|
columns.left.ref = joinColumn.name;
|
|
86
296
|
columns.right.ref = morphColumn.idColumn.name;
|
|
87
297
|
columns.right.type = morphColumn.typeColumn.name;
|
|
88
298
|
columns.right.field = 'field';
|
|
89
299
|
columns.right.order = 'order';
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
qb.select(validColumns);
|
|
102
|
-
if (trx) {
|
|
103
|
-
qb.transacting(trx);
|
|
104
|
-
}
|
|
105
|
-
// TODO: stream the query to improve performances
|
|
106
|
-
const entries = await qb;
|
|
107
|
-
for (const entry of entries){
|
|
108
|
-
if (columns.left.ref) {
|
|
109
|
-
left.ref = entry[columns.left.ref];
|
|
110
|
-
}
|
|
111
|
-
if (columns.right.ref) {
|
|
112
|
-
right.ref = entry[columns.right.ref];
|
|
300
|
+
const validColumns = [
|
|
301
|
+
columns.left.ref,
|
|
302
|
+
columns.left.order,
|
|
303
|
+
columns.right.ref,
|
|
304
|
+
columns.right.type,
|
|
305
|
+
columns.right.field,
|
|
306
|
+
columns.right.order
|
|
307
|
+
].filter((column)=>!fp.isNil(column));
|
|
308
|
+
qb.select(validColumns);
|
|
309
|
+
if (trx) {
|
|
310
|
+
qb.transacting(trx);
|
|
113
311
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
312
|
+
// TODO: stream the query to improve performances
|
|
313
|
+
const entries = await qb;
|
|
314
|
+
const morphLinks = [];
|
|
315
|
+
for (const entry of entries){
|
|
316
|
+
if (columns.left.ref) {
|
|
317
|
+
left.ref = entry[columns.left.ref];
|
|
318
|
+
}
|
|
319
|
+
if (columns.right.ref) {
|
|
320
|
+
right.ref = entry[columns.right.ref];
|
|
321
|
+
}
|
|
322
|
+
if (columns.left.order) {
|
|
323
|
+
left.pos = entry[columns.left.order];
|
|
324
|
+
}
|
|
325
|
+
if (columns.right.order) {
|
|
326
|
+
right.pos = entry[columns.right.order];
|
|
327
|
+
}
|
|
328
|
+
if (columns.right.type) {
|
|
329
|
+
right.type = entry[columns.right.type];
|
|
330
|
+
}
|
|
331
|
+
if (columns.right.field) {
|
|
332
|
+
right.field = entry[columns.right.field];
|
|
333
|
+
}
|
|
334
|
+
morphLinks.push({
|
|
335
|
+
kind,
|
|
336
|
+
relation,
|
|
337
|
+
left: fp.clone(left),
|
|
338
|
+
right: fp.clone(right)
|
|
339
|
+
});
|
|
125
340
|
}
|
|
126
|
-
|
|
127
|
-
kind,
|
|
128
|
-
relation,
|
|
129
|
-
left: fp.clone(left),
|
|
130
|
-
right: fp.clone(right)
|
|
131
|
-
};
|
|
132
|
-
yield link;
|
|
341
|
+
yield* filterMorphLinksByTargetExistence(strapi, morphLinks, onOrphanedLink);
|
|
133
342
|
}
|
|
134
343
|
}
|
|
135
344
|
if (attribute.morphColumn) {
|
|
@@ -139,9 +348,7 @@ const createLinkQuery = (strapi, trx)=>{
|
|
|
139
348
|
qb.transacting(trx);
|
|
140
349
|
}
|
|
141
350
|
const entries = await qb;
|
|
142
|
-
|
|
143
|
-
const ref = entry[idColumn.name];
|
|
144
|
-
yield {
|
|
351
|
+
const morphLinks = entries.map((entry)=>({
|
|
145
352
|
kind,
|
|
146
353
|
relation,
|
|
147
354
|
left: {
|
|
@@ -151,10 +358,10 @@ const createLinkQuery = (strapi, trx)=>{
|
|
|
151
358
|
},
|
|
152
359
|
right: {
|
|
153
360
|
type: entry[typeColumn.name],
|
|
154
|
-
ref
|
|
361
|
+
ref: entry[idColumn.name]
|
|
155
362
|
}
|
|
156
|
-
};
|
|
157
|
-
|
|
363
|
+
}));
|
|
364
|
+
yield* filterMorphLinksByTargetExistence(strapi, morphLinks, onOrphanedLink);
|
|
158
365
|
}
|
|
159
366
|
}
|
|
160
367
|
async function* generateAll(uid) {
|