From 879e8908a039b8d68d8b0d5bf8b1e88e3bfc64f8 Mon Sep 17 00:00:00 2001 From: ppaoli <103750528+PhilippPaoli@users.noreply.github.com> Date: Wed, 3 May 2023 11:19:53 +0200 Subject: [PATCH 1/6] Modified Strapi Api calls for components Change Strapi Query Engine Api to Strapi entityService Api. Add parameter "populate" to plugin config. Use import and export with components logic. --- server/config/type.js | 62 +++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/server/config/type.js b/server/config/type.js index 74d15ca..9c2ff46 100644 --- a/server/config/type.js +++ b/server/config/type.js @@ -3,7 +3,7 @@ const { logMessage, sanitizeConfig, dynamicSort, noLimit, getCombinedUid, getCom const { difference, same } = require('../utils/getArrayDiff'); const ConfigType = class ConfigType { - constructor({ queryString, configName, uid, jsonFields, relations }) { + constructor({ queryString, configName, uid, jsonFields, relations, populate }) { if (!configName) { strapi.log.error(logMessage('A config type was registered without a config name.')); process.exit(0); @@ -25,6 +25,7 @@ const ConfigType = class ConfigType { this.configPrefix = configName; this.jsonFields = jsonFields || []; this.relations = relations || []; + this.populate = populate || []; } /** @@ -68,15 +69,11 @@ const ConfigType = class ConfigType { }); await Promise.all(relations.map(async (relation) => { - await strapi.query(queryString).delete({ - where: { id: relation.id }, - }); + await strapi.entityService.delete(this.queryString, relation.id); })); })); - await queryAPI.delete({ - where: { id: existingConfig.id }, - }); + await strapi.entityService.delete(this.queryString, existingConfig.id); return; } @@ -89,15 +86,17 @@ const ConfigType = class ConfigType { // Create entity. this.relations.map(({ relationName }) => delete query[relationName]); - const newEntity = await queryAPI.create({ data: query }); + const newEntity = await strapi.entityService.create(this.queryString, { + data: query, + }); // Create relation entities. await Promise.all(this.relations.map(async ({ queryString, relationName, parentName }) => { - const relationQueryApi = strapi.query(queryString); - await Promise.all(configContent[relationName].map(async (relationEntity) => { const relationQuery = { ...relationEntity, [parentName]: newEntity }; - await relationQueryApi.create({ data: relationQuery }); + await strapi.entityService.create(queryString, { + data: relationQuery, + }); })); })); } else { // Config does exist in DB --> update config in DB @@ -111,7 +110,21 @@ const ConfigType = class ConfigType { // Update entity. this.relations.map(({ relationName }) => delete query[relationName]); - const entity = await queryAPI.update({ where: combinedUidWhereFilter, data: query }); + + let entity; + switch (this.queryString) { + case "strapi::core-store": + entity = await queryAPI.update({ + where: combinedUidWhereFilter, + data: query, + }); + break; + default: + entity = await queryAPI.findOne({ where: combinedUidWhereFilter }); + await strapi.entityService.update(this.queryString, entity.id, { + data: query, + }); + } // Delete/create relations. await Promise.all(this.relations.map(async ({ queryString, relationName, parentName, relationSortFields }) => { @@ -137,7 +150,7 @@ const ConfigType = class ConfigType { })); await Promise.all(configToAdd.map(async (config) => { - await relationQueryApi.create({ + await strapi.entityService.create(queryString, { data: { ...config, [parentName]: entity.id }, }); })); @@ -192,7 +205,9 @@ const ConfigType = class ConfigType { * @returns {object} Object with key value pairs of configs. */ getAllFromDatabase = async () => { - const AllConfig = await noLimit(strapi.query(this.queryString), {}); + const AllConfig = await noLimit(strapi.query(this.queryString), { + populate: this.populate || null, + }); const configs = {}; await Promise.all(Object.values(AllConfig).map(async (config) => { @@ -221,6 +236,25 @@ const ConfigType = class ConfigType { formattedConfig[relationName] = relations; })); + this.populate + .filter((populatedFields) => !populatedFields.includes(".")) + .map((populatedFields) => { + formattedConfig[populatedFields] = formattedConfig[ + populatedFields + ].map((fields) => { + const sanitizeObjects = (fields) => { + sanitizeConfig(fields); + Object.keys(fields).map((key, index) => { + if (fields[key] && typeof fields[key] === "object") { + sanitizeObjects(fields[key]); + } + }); + }; + sanitizeObjects(fields); + return fields; + }); + }); + this.jsonFields.map((field) => formattedConfig[field] = JSON.parse(config[field])); configs[`${this.configPrefix}.${combinedUid}`] = formattedConfig; })); From 510312d3479a6d874219adb8b3d8c4a135f629e4 Mon Sep 17 00:00:00 2001 From: ppaoli Date: Thu, 10 Aug 2023 10:58:55 +0200 Subject: [PATCH 2/6] Fix small comments --- server/config/type.js | 46 +++++++++++++++++-------------------------- server/utils/index.js | 19 +++++++++++++----- 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/server/config/type.js b/server/config/type.js index 9c2ff46..7371a19 100644 --- a/server/config/type.js +++ b/server/config/type.js @@ -25,7 +25,7 @@ const ConfigType = class ConfigType { this.configPrefix = configName; this.jsonFields = jsonFields || []; this.relations = relations || []; - this.populate = populate || []; + this.populate = populate || null; } /** @@ -111,19 +111,15 @@ const ConfigType = class ConfigType { // Update entity. this.relations.map(({ relationName }) => delete query[relationName]); - let entity; - switch (this.queryString) { - case "strapi::core-store": - entity = await queryAPI.update({ - where: combinedUidWhereFilter, - data: query, - }); - break; - default: - entity = await queryAPI.findOne({ where: combinedUidWhereFilter }); - await strapi.entityService.update(this.queryString, entity.id, { - data: query, - }); + const entity = await queryAPI.findOne({ where: combinedUidWhereFilter }); + try { + await strapi.entityService.update(this.queryString, entity.id, { + data: query, + }); + } catch(error) { + console.warn(error); + console.log("Use Query Engine API instead of Entity Service API"); + await queryAPI.update({ where: combinedUidWhereFilter, data: query }); } // Delete/create relations. @@ -206,7 +202,7 @@ const ConfigType = class ConfigType { */ getAllFromDatabase = async () => { const AllConfig = await noLimit(strapi.query(this.queryString), { - populate: this.populate || null, + populate: this.populate, }); const configs = {}; @@ -236,24 +232,18 @@ const ConfigType = class ConfigType { formattedConfig[relationName] = relations; })); - this.populate - .filter((populatedFields) => !populatedFields.includes(".")) - .map((populatedFields) => { + if (Array.isArray(this.populate)) { + this.populate + .filter((populatedFields) => !populatedFields.includes(".")) + .map((populatedFields) => { formattedConfig[populatedFields] = formattedConfig[ populatedFields ].map((fields) => { - const sanitizeObjects = (fields) => { - sanitizeConfig(fields); - Object.keys(fields).map((key, index) => { - if (fields[key] && typeof fields[key] === "object") { - sanitizeObjects(fields[key]); - } - }); - }; - sanitizeObjects(fields); + sanitizeConfig(fields); return fields; }); - }); + }); + } this.jsonFields.map((field) => formattedConfig[field] = JSON.parse(config[field])); configs[`${this.configPrefix}.${combinedUid}`] = formattedConfig; diff --git a/server/utils/index.js b/server/utils/index.js index 4a6c6f9..ca61959 100644 --- a/server/utils/index.js +++ b/server/utils/index.js @@ -47,11 +47,6 @@ const dynamicSort = (property) => { }; const sanitizeConfig = (config, relation, relationSortFields) => { - delete config._id; - delete config.id; - delete config.updatedAt; - delete config.createdAt; - if (relation) { const formattedRelations = []; @@ -74,6 +69,20 @@ const sanitizeConfig = (config, relation, relationSortFields) => { config[relation] = formattedRelations; } + const sanitizeRecursive = (config) => { + delete config._id; + delete config.id; + delete config.updatedAt; + delete config.createdAt; + + Object.keys(config).map((key, index) => { + if (config[key] && typeof config[key] === "object") { + sanitizeRecursive(config[key]); + } + }); + }; + sanitizeRecursive(config); + return config; }; From 34426f5172eb7fea2c4b878f4572c4b02e7dc5ac Mon Sep 17 00:00:00 2001 From: ppaoli Date: Mon, 4 Sep 2023 13:04:08 +0200 Subject: [PATCH 3/6] Fixed ESLint warnings, change property naming Fixed ESLint Warnings Add Documentation for Components under "Custom types" Change property populate to components --- README.md | 15 +++++++++++++++ server/config/type.js | 18 +++++++++--------- server/utils/index.js | 18 +++++++++--------- 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 53e9a82..fdf537e 100644 --- a/README.md +++ b/README.md @@ -330,6 +330,21 @@ This property can accept an array of field names from the type. It is meant to s > `required:` NO | `type:` array +#### Components + +This property can accept an array of component names from the type. Strapi Components can be included in the export/import process. With "." nested components can also be included in the process. +``` +customTypes: [{ + configName: 'webhook', + queryString: 'webhook', + uid: 'name', + components: ['ParentComponentA', 'ParentComponentA.ChildComponent', 'ParentComponentB'] +}], + +###### Key: `components` + +> `required:` NO | `type:` array + ## 🔍 Naming convention All the config files written in the sync directory have the same naming convention. It goes as follows: diff --git a/server/config/type.js b/server/config/type.js index 7371a19..7c53d53 100644 --- a/server/config/type.js +++ b/server/config/type.js @@ -3,7 +3,7 @@ const { logMessage, sanitizeConfig, dynamicSort, noLimit, getCombinedUid, getCom const { difference, same } = require('../utils/getArrayDiff'); const ConfigType = class ConfigType { - constructor({ queryString, configName, uid, jsonFields, relations, populate }) { + constructor({ queryString, configName, uid, jsonFields, relations, components }) { if (!configName) { strapi.log.error(logMessage('A config type was registered without a config name.')); process.exit(0); @@ -25,7 +25,7 @@ const ConfigType = class ConfigType { this.configPrefix = configName; this.jsonFields = jsonFields || []; this.relations = relations || []; - this.populate = populate || null; + this.components = components || null; } /** @@ -202,7 +202,7 @@ const ConfigType = class ConfigType { */ getAllFromDatabase = async () => { const AllConfig = await noLimit(strapi.query(this.queryString), { - populate: this.populate, + populate: this.components, }); const configs = {}; @@ -232,12 +232,12 @@ const ConfigType = class ConfigType { formattedConfig[relationName] = relations; })); - if (Array.isArray(this.populate)) { - this.populate - .filter((populatedFields) => !populatedFields.includes(".")) - .map((populatedFields) => { - formattedConfig[populatedFields] = formattedConfig[ - populatedFields + if (Array.isArray(this.components)) { + this.components + .filter((componentFields) => !componentFields.includes(".")) + .map((componentFields) => { + formattedConfig[componentFields] = formattedConfig[ + componentFields ].map((fields) => { sanitizeConfig(fields); return fields; diff --git a/server/utils/index.js b/server/utils/index.js index ca61959..19291d1 100644 --- a/server/utils/index.js +++ b/server/utils/index.js @@ -69,19 +69,19 @@ const sanitizeConfig = (config, relation, relationSortFields) => { config[relation] = formattedRelations; } - const sanitizeRecursive = (config) => { - delete config._id; - delete config.id; - delete config.updatedAt; - delete config.createdAt; + const recursiveSanitizeConfig = (recursivedSanitizedConfig) => { + delete recursivedSanitizedConfig._id; + delete recursivedSanitizedConfig.id; + delete recursivedSanitizedConfig.updatedAt; + delete recursivedSanitizedConfig.createdAt; - Object.keys(config).map((key, index) => { - if (config[key] && typeof config[key] === "object") { - sanitizeRecursive(config[key]); + Object.keys(recursivedSanitizedConfig).map((key, index) => { + if (recursivedSanitizedConfig[key] && typeof recursivedSanitizedConfig[key] === "object") { + recursiveSanitizeConfig(recursivedSanitizedConfig[key]); } }); }; - sanitizeRecursive(config); + recursiveSanitizeConfig(config); return config; }; From b9527532b689976f49d0388ff2f7e073cd756a93 Mon Sep 17 00:00:00 2001 From: Boaz Poolman Date: Wed, 6 Sep 2023 16:09:23 +0200 Subject: [PATCH 4/6] fix: No need to additionally sanitize the components. They've allready been sanitized because their parent was santized. --- server/config/type.js | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/server/config/type.js b/server/config/type.js index 7c53d53..488cbad 100644 --- a/server/config/type.js +++ b/server/config/type.js @@ -232,19 +232,6 @@ const ConfigType = class ConfigType { formattedConfig[relationName] = relations; })); - if (Array.isArray(this.components)) { - this.components - .filter((componentFields) => !componentFields.includes(".")) - .map((componentFields) => { - formattedConfig[componentFields] = formattedConfig[ - componentFields - ].map((fields) => { - sanitizeConfig(fields); - return fields; - }); - }); - } - this.jsonFields.map((field) => formattedConfig[field] = JSON.parse(config[field])); configs[`${this.configPrefix}.${combinedUid}`] = formattedConfig; })); From 5199e7adc84d1408c86baca6042f89dfe205f010 Mon Sep 17 00:00:00 2001 From: Boaz Poolman Date: Wed, 6 Sep 2023 16:16:48 +0200 Subject: [PATCH 5/6] fix: Use strapi.log.warn instead of logging warnings with console.log --- server/config/type.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/server/config/type.js b/server/config/type.js index 488cbad..768744e 100644 --- a/server/config/type.js +++ b/server/config/type.js @@ -116,9 +116,8 @@ const ConfigType = class ConfigType { await strapi.entityService.update(this.queryString, entity.id, { data: query, }); - } catch(error) { - console.warn(error); - console.log("Use Query Engine API instead of Entity Service API"); + } catch (error) { + strapi.log.warn(logMessage(`Use Query Engine API instead of Entity Service API for type ${this.configPrefix}`)); await queryAPI.update({ where: combinedUidWhereFilter, data: query }); } From 8e9cbdd6aa19a6dd677915780bc676da4d5e336a Mon Sep 17 00:00:00 2001 From: Boaz Poolman Date: Wed, 6 Sep 2023 16:22:56 +0200 Subject: [PATCH 6/6] fix: Add missing env vars to playground --- playground/.env | 1 + playground/config/admin.js | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/playground/.env b/playground/.env index c53b44b..57cb1e7 100644 --- a/playground/.env +++ b/playground/.env @@ -3,4 +3,5 @@ PORT=1337 APP_KEYS=SIwLyqu+IpSHIuUBDQfPZg==,Nzqbq2C3ATsR19u5XEAJQA==,/Agk5Sn8M4EzfoSiIHcDlQ==,gSxT2T0k2zbQatKXUV0zCA== API_TOKEN_SALT=reQcUBbGXD2KWG2QpRn7DA== ADMIN_JWT_SECRET= 69mzgwRGfEBUhPEaas8EBA== +TRANSFER_TOKEN_SALT=/LTsSGpC5afHICjZu0oEuQ== JWT_SECRET=E0TTVdsr+M/FXAjfrNIgXA== diff --git a/playground/config/admin.js b/playground/config/admin.js index 54eaf4a..15a268c 100644 --- a/playground/config/admin.js +++ b/playground/config/admin.js @@ -5,4 +5,12 @@ module.exports = ({ env }) => ({ watchIgnoreFiles: [ '**/config/sync/**', ], + apiToken: { + salt: env('API_TOKEN_SALT'), + }, + transfer: { + token: { + salt: env('TRANSFER_TOKEN_SALT'), + }, + }, });