@strapi/data-transfer 0.0.0 → 4.6.0-beta.1
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/encryption/decrypt.js +4 -4
- package/dist/encryption/encrypt.js +4 -4
- package/dist/engine/index.d.ts +11 -10
- package/dist/engine/index.js +145 -166
- package/dist/providers/{local-file-destination-provider.d.ts → local-file-destination-provider/index.d.ts} +9 -5
- package/dist/providers/{local-file-destination-provider.js → local-file-destination-provider/index.js} +54 -82
- package/dist/providers/local-file-destination-provider/utils.d.ts +9 -0
- package/dist/providers/local-file-destination-provider/utils.js +61 -0
- package/dist/providers/{local-file-source-provider.d.ts → local-file-source-provider/index.d.ts} +18 -22
- package/dist/providers/{local-file-source-provider.js → local-file-source-provider/index.js} +91 -36
- package/dist/providers/local-strapi-destination-provider/index.d.ts +31 -0
- package/dist/providers/local-strapi-destination-provider/index.js +187 -0
- package/dist/providers/local-strapi-destination-provider/strategies/index.d.ts +1 -0
- package/dist/providers/local-strapi-destination-provider/strategies/index.js +28 -0
- package/dist/providers/local-strapi-destination-provider/strategies/restore/configuration.d.ts +5 -0
- package/dist/providers/local-strapi-destination-provider/strategies/restore/configuration.js +44 -0
- package/dist/providers/local-strapi-destination-provider/strategies/restore/entities.d.ts +9 -0
- package/dist/providers/local-strapi-destination-provider/strategies/restore/entities.js +88 -0
- package/dist/providers/local-strapi-destination-provider/strategies/restore/index.d.ts +32 -0
- package/dist/providers/local-strapi-destination-provider/strategies/restore/index.js +106 -0
- package/dist/providers/local-strapi-destination-provider/strategies/restore/links.d.ts +3 -0
- package/dist/providers/local-strapi-destination-provider/strategies/restore/links.js +29 -0
- package/dist/providers/local-strapi-source-provider/assets.d.ts +5 -0
- package/dist/providers/local-strapi-source-provider/assets.js +31 -0
- package/dist/providers/local-strapi-source-provider/configuration.js +1 -1
- package/dist/providers/local-strapi-source-provider/entities.js +29 -9
- package/dist/providers/local-strapi-source-provider/index.d.ts +8 -7
- package/dist/providers/local-strapi-source-provider/index.js +32 -2
- package/dist/providers/local-strapi-source-provider/{links/index.d.ts → links.d.ts} +1 -1
- package/dist/providers/local-strapi-source-provider/links.js +23 -0
- package/dist/providers/shared/index.d.ts +1 -0
- package/dist/providers/shared/index.js +28 -0
- package/dist/providers/shared/strapi/entity.d.ts +19 -0
- package/dist/providers/shared/strapi/entity.js +130 -0
- package/dist/providers/shared/strapi/index.d.ts +2 -0
- package/dist/providers/shared/strapi/index.js +29 -0
- package/dist/providers/shared/strapi/link.d.ts +6 -0
- package/dist/providers/shared/strapi/link.js +201 -0
- package/dist/providers/test-utils/index.d.ts +111 -0
- package/dist/providers/test-utils/index.js +64 -0
- package/dist/strategies/index.d.ts +3 -3
- package/dist/strategies/index.js +27 -4
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +30 -0
- package/dist/utils/json.d.ts +23 -0
- package/dist/{utils.js → utils/json.js} +9 -38
- package/dist/utils/schema.d.ts +3 -0
- package/dist/utils/schema.js +22 -0
- package/dist/utils/stream.d.ts +10 -0
- package/dist/utils/stream.js +39 -0
- package/jest.config.js +3 -1
- package/package.json +5 -4
- package/dist/providers/local-strapi-destination-provider.d.ts +0 -22
- package/dist/providers/local-strapi-destination-provider.js +0 -78
- package/dist/providers/local-strapi-source-provider/links/index.js +0 -37
- package/dist/providers/local-strapi-source-provider/links/utils.d.ts +0 -27
- package/dist/providers/local-strapi-source-provider/links/utils.js +0 -155
- package/dist/utils.d.ts +0 -10
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="lodash" />
|
|
3
|
+
import { Readable } from 'stream';
|
|
2
4
|
import type { IMetadata, ISourceProvider, ProviderType } from '../../../types';
|
|
3
5
|
export interface ILocalStrapiSourceProviderOptions {
|
|
4
6
|
getStrapi(): Strapi.Strapi | Promise<Strapi.Strapi>;
|
|
@@ -14,13 +16,12 @@ declare class LocalStrapiSourceProvider implements ISourceProvider {
|
|
|
14
16
|
bootstrap(): Promise<void>;
|
|
15
17
|
close(): Promise<void>;
|
|
16
18
|
getMetadata(): IMetadata;
|
|
17
|
-
streamEntities(): Promise<
|
|
18
|
-
streamLinks():
|
|
19
|
-
streamConfiguration():
|
|
20
|
-
getSchemas():
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
streamSchemas(): NodeJS.ReadableStream;
|
|
19
|
+
streamEntities(): Promise<Readable>;
|
|
20
|
+
streamLinks(): Readable;
|
|
21
|
+
streamConfiguration(): Readable;
|
|
22
|
+
getSchemas(): import("lodash").Dictionary<Partial<import("@strapi/strapi").Schema>>;
|
|
23
|
+
streamSchemas(): Readable;
|
|
24
|
+
streamAssets(): Readable;
|
|
24
25
|
}
|
|
25
26
|
export declare type ILocalStrapiSourceProvider = InstanceType<typeof LocalStrapiSourceProvider>;
|
|
26
27
|
export {};
|
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
26
|
exports.createLocalStrapiSourceProvider = void 0;
|
|
4
27
|
const stream_chain_1 = require("stream-chain");
|
|
@@ -6,7 +29,8 @@ const stream_1 = require("stream");
|
|
|
6
29
|
const entities_1 = require("./entities");
|
|
7
30
|
const links_1 = require("./links");
|
|
8
31
|
const configuration_1 = require("./configuration");
|
|
9
|
-
const
|
|
32
|
+
const assets_1 = require("./assets");
|
|
33
|
+
const utils = __importStar(require("../../utils"));
|
|
10
34
|
const createLocalStrapiSourceProvider = (options) => {
|
|
11
35
|
return new LocalStrapiSourceProvider(options);
|
|
12
36
|
};
|
|
@@ -74,10 +98,16 @@ class LocalStrapiSourceProvider {
|
|
|
74
98
|
...this.strapi.contentTypes,
|
|
75
99
|
...this.strapi.components,
|
|
76
100
|
};
|
|
77
|
-
return
|
|
101
|
+
return utils.schema.mapSchemasValues(schemas);
|
|
78
102
|
}
|
|
79
103
|
streamSchemas() {
|
|
80
104
|
return stream_1.Readable.from(Object.values(this.getSchemas()));
|
|
81
105
|
}
|
|
106
|
+
streamAssets() {
|
|
107
|
+
if (!this.strapi) {
|
|
108
|
+
throw new Error('Not able to stream assets. Strapi instance not found');
|
|
109
|
+
}
|
|
110
|
+
return (0, assets_1.createAssetsStream)(this.strapi);
|
|
111
|
+
}
|
|
82
112
|
}
|
|
83
113
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Readable } from 'stream';
|
|
2
2
|
/**
|
|
3
|
-
* Create a
|
|
3
|
+
* Create a Readable which will stream all the links from a Strapi instance
|
|
4
4
|
*/
|
|
5
5
|
export declare const createLinksStream: (strapi: Strapi.Strapi) => Readable;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createLinksStream = void 0;
|
|
4
|
+
const stream_1 = require("stream");
|
|
5
|
+
const link_1 = require("../shared/strapi/link");
|
|
6
|
+
/**
|
|
7
|
+
* Create a Readable which will stream all the links from a Strapi instance
|
|
8
|
+
*/
|
|
9
|
+
const createLinksStream = (strapi) => {
|
|
10
|
+
const uids = [...Object.keys(strapi.contentTypes), ...Object.keys(strapi.components)];
|
|
11
|
+
// Async generator stream that returns every link from a Strapi instance
|
|
12
|
+
return stream_1.Readable.from((async function* linkGenerator() {
|
|
13
|
+
const query = (0, link_1.createLinkQuery)(strapi);
|
|
14
|
+
for (const uid of uids) {
|
|
15
|
+
const generator = query().generateAll(uid);
|
|
16
|
+
for await (const link of generator) {
|
|
17
|
+
yield link;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
})());
|
|
21
|
+
};
|
|
22
|
+
exports.createLinksStream = createLinksStream;
|
|
23
|
+
//# sourceMappingURL=links.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as strapi from './strapi';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.strapi = void 0;
|
|
27
|
+
exports.strapi = __importStar(require("./strapi"));
|
|
28
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ContentTypeSchema } from '@strapi/strapi';
|
|
2
|
+
declare const createEntityQuery: (strapi: Strapi.Strapi) => (uid: string) => {
|
|
3
|
+
create: <T extends {
|
|
4
|
+
data: U;
|
|
5
|
+
}, U extends object>(params: T) => Promise<any>;
|
|
6
|
+
createMany: <T_1 extends {
|
|
7
|
+
data: U_1[];
|
|
8
|
+
}, U_1 extends object>(params: T_1) => Promise<{
|
|
9
|
+
count: number;
|
|
10
|
+
}>;
|
|
11
|
+
deleteMany: <T_2 extends object>(params?: T_2 | undefined) => Promise<{
|
|
12
|
+
count: number;
|
|
13
|
+
} | null>;
|
|
14
|
+
getDeepPopulateComponentLikeQuery: (contentType: ContentTypeSchema, params?: {
|
|
15
|
+
select: string;
|
|
16
|
+
}) => any;
|
|
17
|
+
readonly deepPopulateComponentLikeQuery: any;
|
|
18
|
+
};
|
|
19
|
+
export { createEntityQuery };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.createEntityQuery = void 0;
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
28
|
+
// @ts-ignore
|
|
29
|
+
const componentsService = __importStar(require("@strapi/strapi/lib/services/entity-service/components"));
|
|
30
|
+
const fp_1 = require("lodash/fp");
|
|
31
|
+
const sanitizeComponentLikeAttributes = (model, data) => {
|
|
32
|
+
const { attributes } = model;
|
|
33
|
+
const componentLikeAttributesKey = Object.entries(attributes)
|
|
34
|
+
.filter(([, attribute]) => ['component', 'dynamiczone'].includes(attribute.type))
|
|
35
|
+
.map(([key]) => key);
|
|
36
|
+
return (0, fp_1.omit)(componentLikeAttributesKey, data);
|
|
37
|
+
};
|
|
38
|
+
const omitInvalidCreationAttributes = (0, fp_1.omit)(['id']);
|
|
39
|
+
const createEntityQuery = (strapi) => {
|
|
40
|
+
const components = {
|
|
41
|
+
async assignToEntity(uid, data) {
|
|
42
|
+
const model = strapi.getModel(uid);
|
|
43
|
+
const entityComponents = await componentsService.createComponents(uid, data);
|
|
44
|
+
const dataWithoutComponents = sanitizeComponentLikeAttributes(model, data);
|
|
45
|
+
return (0, fp_1.assign)(entityComponents, dataWithoutComponents);
|
|
46
|
+
},
|
|
47
|
+
async get(uid, entity) {
|
|
48
|
+
return componentsService.getComponents(uid, entity);
|
|
49
|
+
},
|
|
50
|
+
delete(uid, componentsToDelete) {
|
|
51
|
+
return componentsService.deleteComponents(uid, componentsToDelete, { loadComponents: false });
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
const query = (uid) => {
|
|
55
|
+
const create = async (params) => {
|
|
56
|
+
const dataWithComponents = await components.assignToEntity(uid, params.data);
|
|
57
|
+
const sanitizedData = omitInvalidCreationAttributes(dataWithComponents);
|
|
58
|
+
return strapi.db.query(uid).create({ ...params, data: sanitizedData });
|
|
59
|
+
};
|
|
60
|
+
const createMany = async (params) => {
|
|
61
|
+
return (Promise.resolve(params.data)
|
|
62
|
+
// Create components for each entity
|
|
63
|
+
.then((0, fp_1.map)((data) => components.assignToEntity(uid, data)))
|
|
64
|
+
// Remove unwanted attributes
|
|
65
|
+
.then((0, fp_1.map)(omitInvalidCreationAttributes))
|
|
66
|
+
// Execute a strapi db createMany query with all the entities + their created components
|
|
67
|
+
.then((data) => strapi.db.query(uid).createMany({ ...params, data })));
|
|
68
|
+
};
|
|
69
|
+
const deleteMany = async (params) => {
|
|
70
|
+
const entitiesToDelete = await strapi.db.query(uid).findMany(params ?? {});
|
|
71
|
+
if (!entitiesToDelete.length) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
const componentsToDelete = await Promise.all(entitiesToDelete.map((entityToDelete) => components.get(uid, entityToDelete)));
|
|
75
|
+
const deletedEntities = await strapi.db.query(uid).deleteMany(params);
|
|
76
|
+
await Promise.all(componentsToDelete.map((compos) => components.delete(uid, compos)));
|
|
77
|
+
return deletedEntities;
|
|
78
|
+
};
|
|
79
|
+
const getDeepPopulateComponentLikeQuery = (contentType, params = { select: '*' }) => {
|
|
80
|
+
const { attributes } = contentType;
|
|
81
|
+
const populate = {};
|
|
82
|
+
const entries = Object.entries(attributes);
|
|
83
|
+
for (const [key, attribute] of entries) {
|
|
84
|
+
if (attribute.type === 'component') {
|
|
85
|
+
const component = strapi.getModel(attribute.component);
|
|
86
|
+
const subPopulate = getDeepPopulateComponentLikeQuery(component, params);
|
|
87
|
+
if (((0, fp_1.isArray)(subPopulate) || (0, fp_1.isObject)(subPopulate)) && (0, fp_1.size)(subPopulate) > 0) {
|
|
88
|
+
populate[key] = { ...params, populate: subPopulate };
|
|
89
|
+
}
|
|
90
|
+
if ((0, fp_1.isArray)(subPopulate) && (0, fp_1.isEmpty)(subPopulate)) {
|
|
91
|
+
populate[key] = { ...params };
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (attribute.type === 'dynamiczone') {
|
|
95
|
+
const { components: componentsUID } = attribute;
|
|
96
|
+
const on = {};
|
|
97
|
+
for (const componentUID of componentsUID) {
|
|
98
|
+
const component = strapi.getModel(componentUID);
|
|
99
|
+
const subPopulate = getDeepPopulateComponentLikeQuery(component, params);
|
|
100
|
+
if (((0, fp_1.isArray)(subPopulate) || (0, fp_1.isObject)(subPopulate)) && (0, fp_1.size)(subPopulate) > 0) {
|
|
101
|
+
on[componentUID] = { ...params, populate: subPopulate };
|
|
102
|
+
}
|
|
103
|
+
if ((0, fp_1.isArray)(subPopulate) && (0, fp_1.isEmpty)(subPopulate)) {
|
|
104
|
+
on[componentUID] = { ...params };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
populate[key] = (0, fp_1.size)(on) > 0 ? { on } : true;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const values = Object.values(populate);
|
|
111
|
+
if (values.every((value) => value === true)) {
|
|
112
|
+
return Object.keys(populate);
|
|
113
|
+
}
|
|
114
|
+
return populate;
|
|
115
|
+
};
|
|
116
|
+
return {
|
|
117
|
+
create,
|
|
118
|
+
createMany,
|
|
119
|
+
deleteMany,
|
|
120
|
+
getDeepPopulateComponentLikeQuery,
|
|
121
|
+
get deepPopulateComponentLikeQuery() {
|
|
122
|
+
const contentType = strapi.getModel(uid);
|
|
123
|
+
return getDeepPopulateComponentLikeQuery(contentType);
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
return query;
|
|
128
|
+
};
|
|
129
|
+
exports.createEntityQuery = createEntityQuery;
|
|
130
|
+
//# sourceMappingURL=entity.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.link = exports.entity = void 0;
|
|
27
|
+
exports.entity = __importStar(require("./entity"));
|
|
28
|
+
exports.link = __importStar(require("./link"));
|
|
29
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ILink } from '../../../../types';
|
|
2
|
+
export declare const createLinkQuery: (strapi: Strapi.Strapi) => () => {
|
|
3
|
+
generateAll: (uid: string) => AsyncGenerator<ILink>;
|
|
4
|
+
generateAllForAttribute: (uid: string, fieldName: string) => AsyncGenerator<ILink>;
|
|
5
|
+
insert: (link: ILink) => Promise<void>;
|
|
6
|
+
};
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createLinkQuery = void 0;
|
|
4
|
+
const fp_1 = require("lodash/fp");
|
|
5
|
+
// TODO: Remove any types when we'll have types for DB metadata
|
|
6
|
+
const createLinkQuery = (strapi) => {
|
|
7
|
+
const query = () => {
|
|
8
|
+
const { connection } = strapi.db;
|
|
9
|
+
async function* generateAllForAttribute(uid, fieldName) {
|
|
10
|
+
const metadata = strapi.db.metadata.get(uid);
|
|
11
|
+
if (!metadata) {
|
|
12
|
+
throw new Error(`No metadata found for ${uid}`);
|
|
13
|
+
}
|
|
14
|
+
const attributes = filterValidRelationalAttributes(metadata.attributes);
|
|
15
|
+
if (!(fieldName in attributes)) {
|
|
16
|
+
throw new Error(`${fieldName} is not a valid relational attribute name`);
|
|
17
|
+
}
|
|
18
|
+
const attribute = attributes[fieldName];
|
|
19
|
+
const kind = getLinkKind(attribute, uid);
|
|
20
|
+
const { relation, target } = attribute;
|
|
21
|
+
// The relation is stored in the same table
|
|
22
|
+
// TODO: handle manyToOne joinColumn
|
|
23
|
+
if (attribute.joinColumn) {
|
|
24
|
+
const joinColumnName = attribute.joinColumn.name;
|
|
25
|
+
const qb = connection.queryBuilder().select('id', joinColumnName).from(metadata.tableName);
|
|
26
|
+
// TODO: stream the query to improve performances
|
|
27
|
+
const entries = await qb;
|
|
28
|
+
for (const entry of entries) {
|
|
29
|
+
const ref = entry[joinColumnName];
|
|
30
|
+
if (ref !== null) {
|
|
31
|
+
yield {
|
|
32
|
+
kind,
|
|
33
|
+
relation,
|
|
34
|
+
left: { type: uid, ref: entry.id, field: fieldName },
|
|
35
|
+
right: { type: target, ref },
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// The relation uses a join table
|
|
41
|
+
if (attribute.joinTable) {
|
|
42
|
+
const { name, joinColumn, inverseJoinColumn, orderColumnName, morphColumn, inverseOrderColumnName, } = attribute.joinTable;
|
|
43
|
+
const qb = connection.queryBuilder().from(name);
|
|
44
|
+
const columns = {
|
|
45
|
+
left: { ref: null },
|
|
46
|
+
right: { ref: null },
|
|
47
|
+
};
|
|
48
|
+
const left = { type: uid, field: fieldName };
|
|
49
|
+
const right = {};
|
|
50
|
+
if (kind === 'relation.basic' || kind === 'relation.circular') {
|
|
51
|
+
right.type = attribute.target;
|
|
52
|
+
right.field = attribute.inversedBy;
|
|
53
|
+
columns.left.ref = joinColumn.name;
|
|
54
|
+
columns.right.ref = inverseJoinColumn.name;
|
|
55
|
+
if (orderColumnName) {
|
|
56
|
+
columns.left.order = orderColumnName;
|
|
57
|
+
}
|
|
58
|
+
if (inverseOrderColumnName) {
|
|
59
|
+
columns.right.order = inverseOrderColumnName;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (kind === 'relation.morph') {
|
|
63
|
+
columns.left.ref = joinColumn.name;
|
|
64
|
+
columns.right.ref = morphColumn.idColumn.name;
|
|
65
|
+
columns.right.type = morphColumn.typeColumn.name;
|
|
66
|
+
columns.right.field = 'field';
|
|
67
|
+
columns.right.order = 'order';
|
|
68
|
+
}
|
|
69
|
+
const validColumns = [
|
|
70
|
+
// Left
|
|
71
|
+
columns.left.ref,
|
|
72
|
+
columns.left.order,
|
|
73
|
+
// Right
|
|
74
|
+
columns.right.ref,
|
|
75
|
+
columns.right.type,
|
|
76
|
+
columns.right.field,
|
|
77
|
+
columns.right.order,
|
|
78
|
+
].filter((column) => !(0, fp_1.isNil)(column));
|
|
79
|
+
qb.select(validColumns);
|
|
80
|
+
// TODO: stream the query to improve performances
|
|
81
|
+
const entries = await qb;
|
|
82
|
+
for (const entry of entries) {
|
|
83
|
+
if (columns.left.ref) {
|
|
84
|
+
left.ref = entry[columns.left.ref];
|
|
85
|
+
}
|
|
86
|
+
if (columns.right.ref) {
|
|
87
|
+
right.ref = entry[columns.right.ref];
|
|
88
|
+
}
|
|
89
|
+
if (columns.left.order) {
|
|
90
|
+
left.pos = entry[columns.left.order];
|
|
91
|
+
}
|
|
92
|
+
if (columns.right.order) {
|
|
93
|
+
right.pos = entry[columns.right.order];
|
|
94
|
+
}
|
|
95
|
+
if (columns.right.type) {
|
|
96
|
+
right.type = entry[columns.right.type];
|
|
97
|
+
}
|
|
98
|
+
if (columns.right.field) {
|
|
99
|
+
right.field = entry[columns.right.field];
|
|
100
|
+
}
|
|
101
|
+
const link = {
|
|
102
|
+
kind,
|
|
103
|
+
relation,
|
|
104
|
+
left: (0, fp_1.clone)(left),
|
|
105
|
+
right: (0, fp_1.clone)(right),
|
|
106
|
+
};
|
|
107
|
+
yield link;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
async function* generateAll(uid) {
|
|
112
|
+
const metadata = strapi.db.metadata.get(uid);
|
|
113
|
+
if (!metadata) {
|
|
114
|
+
throw new Error(`No metadata found for ${uid}`);
|
|
115
|
+
}
|
|
116
|
+
const attributes = filterValidRelationalAttributes(metadata.attributes);
|
|
117
|
+
for (const fieldName of Object.keys(attributes)) {
|
|
118
|
+
for await (const link of generateAllForAttribute(uid, fieldName)) {
|
|
119
|
+
yield link;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const insert = async (link) => {
|
|
124
|
+
const { kind, left, right } = link;
|
|
125
|
+
const metadata = strapi.db.metadata.get(left.type);
|
|
126
|
+
const attribute = metadata.attributes[left.field];
|
|
127
|
+
const payload = {};
|
|
128
|
+
if (attribute.joinColumn) {
|
|
129
|
+
const joinColumnName = attribute.joinColumn.name;
|
|
130
|
+
await connection(metadata.tableName)
|
|
131
|
+
.where('id', left.ref)
|
|
132
|
+
.update({ [joinColumnName]: right.ref });
|
|
133
|
+
}
|
|
134
|
+
if (attribute.joinTable) {
|
|
135
|
+
const { name, joinColumn, inverseJoinColumn, orderColumnName, inverseOrderColumnName, morphColumn, } = attribute.joinTable;
|
|
136
|
+
if (joinColumn) {
|
|
137
|
+
Object.assign(payload, { [joinColumn.name]: left.ref });
|
|
138
|
+
}
|
|
139
|
+
const assignInverseColumn = () => {
|
|
140
|
+
if (inverseJoinColumn) {
|
|
141
|
+
Object.assign(payload, {
|
|
142
|
+
[inverseJoinColumn.name]: right.ref,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
const assignOrderColumns = () => {
|
|
147
|
+
if (orderColumnName) {
|
|
148
|
+
Object.assign(payload, { [orderColumnName]: left.pos ?? null });
|
|
149
|
+
}
|
|
150
|
+
if (inverseOrderColumnName) {
|
|
151
|
+
Object.assign(payload, { [inverseOrderColumnName]: right.pos ?? null });
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
const assignMorphColumns = () => {
|
|
155
|
+
const { idColumn, typeColumn } = morphColumn ?? {};
|
|
156
|
+
if (idColumn) {
|
|
157
|
+
Object.assign(payload, { [idColumn.name]: right.ref });
|
|
158
|
+
}
|
|
159
|
+
if (typeColumn) {
|
|
160
|
+
Object.assign(payload, { [typeColumn.name]: right.type });
|
|
161
|
+
}
|
|
162
|
+
Object.assign(payload, { order: right.pos ?? null, field: right.field ?? null });
|
|
163
|
+
};
|
|
164
|
+
if (kind === 'relation.basic' || kind === 'relation.circular') {
|
|
165
|
+
assignInverseColumn();
|
|
166
|
+
}
|
|
167
|
+
if (kind === 'relation.morph') {
|
|
168
|
+
assignMorphColumns();
|
|
169
|
+
}
|
|
170
|
+
assignOrderColumns();
|
|
171
|
+
await connection.insert(payload).into(name);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
return { generateAll, generateAllForAttribute, insert };
|
|
175
|
+
};
|
|
176
|
+
return query;
|
|
177
|
+
};
|
|
178
|
+
exports.createLinkQuery = createLinkQuery;
|
|
179
|
+
const filterValidRelationalAttributes = (attributes) => {
|
|
180
|
+
const isOwner = (attribute) => {
|
|
181
|
+
return attribute.owner || (!attribute.mappedBy && !attribute.morphBy);
|
|
182
|
+
};
|
|
183
|
+
const isComponentLike = (attribute) => {
|
|
184
|
+
return attribute.component || attribute.components;
|
|
185
|
+
};
|
|
186
|
+
return Object.entries(attributes)
|
|
187
|
+
.filter(([, attribute]) => {
|
|
188
|
+
return attribute.type === 'relation' && isOwner(attribute) && !isComponentLike(attribute);
|
|
189
|
+
})
|
|
190
|
+
.reduce((acc, [key, attribute]) => ({ ...acc, [key]: attribute }), {});
|
|
191
|
+
};
|
|
192
|
+
const getLinkKind = (attribute, uid) => {
|
|
193
|
+
if (attribute.relation.startsWith('morph')) {
|
|
194
|
+
return 'relation.morph';
|
|
195
|
+
}
|
|
196
|
+
if (attribute.target === uid) {
|
|
197
|
+
return 'relation.circular';
|
|
198
|
+
}
|
|
199
|
+
return 'relation.basic';
|
|
200
|
+
};
|
|
201
|
+
//# sourceMappingURL=link.js.map
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="jest" />
|
|
3
|
+
import { Readable } from 'stream';
|
|
4
|
+
/**
|
|
5
|
+
* Collect every entity in a Readable stream
|
|
6
|
+
*/
|
|
7
|
+
export declare const collect: <T = unknown>(stream: Readable) => Promise<T[]>;
|
|
8
|
+
/**
|
|
9
|
+
* Create a "Strapi" like object factory based on the
|
|
10
|
+
* given params and cast it to the correct type
|
|
11
|
+
*/
|
|
12
|
+
export declare const getStrapiFactory: <T extends {
|
|
13
|
+
readonly EE?: unknown;
|
|
14
|
+
readonly config?: unknown;
|
|
15
|
+
readonly auth?: unknown;
|
|
16
|
+
readonly contentAPI?: unknown;
|
|
17
|
+
readonly sanitizers?: unknown;
|
|
18
|
+
readonly services?: unknown;
|
|
19
|
+
service?: unknown;
|
|
20
|
+
readonly controllers?: unknown;
|
|
21
|
+
controller?: unknown;
|
|
22
|
+
readonly contentTypes?: unknown;
|
|
23
|
+
contentType?: unknown;
|
|
24
|
+
readonly components?: unknown;
|
|
25
|
+
readonly customFields?: unknown;
|
|
26
|
+
readonly policies?: unknown;
|
|
27
|
+
policy?: unknown;
|
|
28
|
+
readonly middlewares?: unknown;
|
|
29
|
+
middleware?: unknown;
|
|
30
|
+
readonly plugins?: unknown;
|
|
31
|
+
plugin?: unknown;
|
|
32
|
+
readonly hooks?: unknown;
|
|
33
|
+
hook?: unknown;
|
|
34
|
+
readonly api?: unknown;
|
|
35
|
+
register?: unknown;
|
|
36
|
+
bootstrap?: unknown;
|
|
37
|
+
destroy?: unknown;
|
|
38
|
+
runLifecyclesFunctions?: unknown;
|
|
39
|
+
start?: unknown;
|
|
40
|
+
stopWithError?: unknown;
|
|
41
|
+
stop?: unknown;
|
|
42
|
+
load?: unknown;
|
|
43
|
+
reload?: unknown;
|
|
44
|
+
startWebhooks?: unknown;
|
|
45
|
+
postListen?: unknown;
|
|
46
|
+
listen?: unknown;
|
|
47
|
+
openAdmin?: unknown;
|
|
48
|
+
loadAdmin?: unknown;
|
|
49
|
+
loadPlugins?: unknown;
|
|
50
|
+
loadPolicies?: unknown;
|
|
51
|
+
loadAPIs?: unknown;
|
|
52
|
+
loadComponents?: unknown;
|
|
53
|
+
loadMiddlewares?: unknown;
|
|
54
|
+
loadApp?: unknown;
|
|
55
|
+
registerInternalHooks?: unknown;
|
|
56
|
+
getModel?: unknown;
|
|
57
|
+
query?: unknown;
|
|
58
|
+
container?: unknown;
|
|
59
|
+
dirs?: unknown;
|
|
60
|
+
isLoaded?: unknown;
|
|
61
|
+
server?: unknown;
|
|
62
|
+
fs?: unknown;
|
|
63
|
+
eventHub?: unknown;
|
|
64
|
+
startupLogger?: unknown;
|
|
65
|
+
log?: unknown;
|
|
66
|
+
cron?: unknown;
|
|
67
|
+
telemetry?: unknown;
|
|
68
|
+
db?: unknown;
|
|
69
|
+
store?: unknown;
|
|
70
|
+
entityValidator?: unknown;
|
|
71
|
+
entityService?: unknown;
|
|
72
|
+
}>(properties?: T | undefined) => () => import("@strapi/strapi").Strapi;
|
|
73
|
+
/**
|
|
74
|
+
* Union type used to represent the default content types available
|
|
75
|
+
*/
|
|
76
|
+
export declare type ContentType = 'foo' | 'bar';
|
|
77
|
+
/**
|
|
78
|
+
* Factory to get default content types test values
|
|
79
|
+
*/
|
|
80
|
+
export declare const getContentTypes: () => {
|
|
81
|
+
foo: {
|
|
82
|
+
uid: "foo";
|
|
83
|
+
attributes: {
|
|
84
|
+
[attribute: string]: unknown;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
bar: {
|
|
88
|
+
uid: "bar";
|
|
89
|
+
attributes: {
|
|
90
|
+
[attribute: string]: unknown;
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Create a factory of readable streams (wrapped with a jest mock function)
|
|
96
|
+
*/
|
|
97
|
+
export declare const createMockedReadableFactory: <T extends string = ContentType>(source: { [ct in T]: {
|
|
98
|
+
[key: string]: unknown;
|
|
99
|
+
id: number;
|
|
100
|
+
}[]; }) => jest.Mock<Readable, [uid: T]>;
|
|
101
|
+
/**
|
|
102
|
+
* Create a factory of mocked query builders
|
|
103
|
+
*/
|
|
104
|
+
export declare const createMockedQueryBuilder: <T extends string = ContentType>(data: { [key in T]: unknown[]; }) => jest.Mock<{
|
|
105
|
+
populate(populate: unknown): any;
|
|
106
|
+
stream(): Readable;
|
|
107
|
+
}, [uid: T]>;
|
|
108
|
+
/**
|
|
109
|
+
* Update the global store with the given strapi value
|
|
110
|
+
*/
|
|
111
|
+
export declare const setGlobalStrapi: (strapi: Strapi.Strapi) => void;
|