Socket
Socket
Sign inDemoInstall

@strapi/codemods

Package Overview
Dependencies
557
Maintainers
11
Versions
7
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.2 to 1.1.0

lib/v4/migration-helpers/__tests__/get-relation-object.test.js

6

bin/commands/migrate.js

@@ -10,3 +10,4 @@ // Node.js core

const { migratePlugin, migrateApiFolder, migrateDependencies } = v4.migrationHelpers;
const { migratePlugin, migrateApiFolder, migrateDependencies, migrateApplicationFolderStructure } =
v4.migrationHelpers;

@@ -21,3 +22,3 @@ // Global utils

logger.error(`${chalk.yellow(resolve(path))} does not exist`);
process.exit(1)
process.exit(1);
}

@@ -58,2 +59,3 @@

await migrateDependencies(projectPath);
await migrateApplicationFolderStructure(projectPath);
await migrateApiFolder(projectPath);

@@ -60,0 +62,0 @@ };

@@ -18,3 +18,3 @@ const { resolve } = require('path');

try {
const { stdout } = await execa('git', ['status', '--porcelain']);
const { stdout } = await execa('git', [`--git-dir=${path}/.git`, `--work-tree=${path}`, 'status', '--porcelain']);
if (stdout.length)

@@ -21,0 +21,0 @@ throw Error(

@@ -1,26 +0,28 @@

module.exports = [
{
method: 'GET',
path: '/test',
handler: 'test.index',
config: {
policies: [],
module.exports = {
routes: [
{
method: 'GET',
path: '/test',
handler: 'test.index',
config: {
policies: [],
},
},
},
{
method: 'POST',
path: '/test/create',
handler: 'test.create',
config: {
policies: [],
{
method: 'POST',
path: '/test/create',
handler: 'test.create',
config: {
policies: [],
},
},
},
{
method: 'PUT',
path: '/test/:id',
handler: 'test.update',
config: {
policies: [],
{
method: 'PUT',
path: '/test/:id',
handler: 'test.update',
config: {
policies: [],
},
},
},
];
],
};

@@ -5,2 +5,9 @@ jest.mock('../convert-models-to-content-types', () => jest.fn());

jest.mock('../../utils/run-jscodeshift', () => jest.fn());
jest.mock('../update-api-folder-structure/utils', () => ({
cleanEmptyDirectories: jest.fn(() => Promise.resolve()),
getDirsAtPath: jest.fn(() => [
{ name: 'test', isDirectory: jest.fn(() => true) },
{ name: 'test-two', isDirectory: jest.fn(() => true) },
]),
}));

@@ -20,7 +27,2 @@ const { join, resolve } = require('path');

jest.spyOn(console, 'log').mockImplementation(() => {});
fs.readdir.mockReturnValueOnce([
{ name: 'test', isDirectory: jest.fn(() => true) },
{ name: 'test-two', isDirectory: jest.fn(() => true) },
{ name: 'test.js', isDirectory: jest.fn(() => false) },
]);
});

@@ -32,3 +34,3 @@

it('copies the v3 api to src directory', async () => {
it('copies the v3 api to a v3 directory for safe keeping', async () => {
const appPath = 'test-dir';

@@ -38,6 +40,16 @@

const expectedV4Path = join(resolve(appPath), 'src', 'api-copy');
expect(fs.copy).toHaveBeenCalledWith(join(resolve(appPath), 'api'), expectedV4Path);
const expectedv3CopyPath = join(resolve(appPath), 'v3', 'api');
expect(fs.copy).toHaveBeenCalledWith(join(resolve(appPath), 'api'), expectedv3CopyPath);
});
it('moves the v3 api to v4 src directory', async () => {
const appPath = 'test-dir';
await updateApiFolderStructure(appPath);
const expectedV4Path = join(resolve(appPath), 'src', 'api');
expect(fs.move).toHaveBeenCalledWith(join(resolve(appPath), 'api'), expectedV4Path);
});
it('converts models to content types', async () => {

@@ -48,4 +60,8 @@ const appPath = 'test-dir';

const expectedV4Path = join(resolve(appPath), 'src', 'api-copy');
const expectedV4Path = join(resolve(appPath), 'src', 'api');
const expectedv4ExtensionsPath = join(resolve(appPath), 'src', 'extensions');
expect(updateContentTypes).toBeCalled();
expect(updateContentTypes.mock.calls).toEqual([
[join(expectedv4ExtensionsPath, 'test')],
[join(expectedv4ExtensionsPath, 'test-two')],
[join(expectedV4Path, 'test')],

@@ -61,6 +77,6 @@ [join(expectedV4Path, 'test-two')],

const expectedV4Path = join(resolve(appPath), 'src', 'api-copy');
const expectedV4Path = join(resolve(appPath), 'src', 'api');
expect(updateRoutes.mock.calls).toEqual([
[join(expectedV4Path, 'test'), 'test'],
[join(expectedV4Path, 'test-two'), 'test-two'],
[join(expectedV4Path, 'test'), 'test', 'test'],
[join(expectedV4Path, 'test-two'), 'test-two', 'test-two'],
]);

@@ -74,3 +90,3 @@ });

const expectedV4Path = join(resolve(appPath), 'src', 'api-copy');
const expectedV4Path = join(resolve(appPath), 'src', 'api');
expect(updatePolicies.mock.calls).toEqual([

@@ -87,3 +103,3 @@ [join(expectedV4Path, 'test')],

const expectedV4Path = join(resolve(appPath), 'src', 'api-copy');
const expectedV4Path = join(resolve(appPath), 'src', 'api');
expect(runJscodeshift.mock.calls).toEqual([

@@ -90,0 +106,0 @@ [join(expectedV4Path, 'test', 'services'), 'convert-object-export-to-function'],

/**
* Migrate API folder structure to v4
*/
const { join } = require('path');

@@ -10,3 +9,5 @@ const fs = require('fs-extra');

const { isPlural, isSingular } = pluralize;
const logger = require('../../global/utils/logger');
const getRelationObject = require('./get-relation-object');

@@ -29,3 +30,3 @@ /**

const v4SchemaJsonPath = join(apiPath, 'content-types', contentTypeName, 'schema.json');
try {

@@ -45,2 +46,49 @@ // Read the settings.json file

_.set(schemaJson, 'info', infoUpdate);
if (schemaJson.attributes) {
Object.entries(schemaJson.attributes).forEach(([key, attribute]) => {
// Not a relation, return early
if (!attribute.via && !attribute.collection && !attribute.model) return;
if (
attribute.plugin === 'upload' &&
(attribute.model === 'file' || attribute.collection === 'file')
) {
// Handle the Media Plugin
attribute = {
type: 'media',
allowedTypes: attribute.allowedTypes,
multiple: _.has(attribute, 'collection'),
required: attribute.required,
private: attribute.private,
};
} else if (attribute.via && attribute.model && isSingular(attribute.via)) {
// One-To-One
attribute = getRelationObject('oneToOne', { ...attribute, inversed: true });
} else if (attribute.model && !attribute.via && !attribute.collection) {
// One-To-One (One-Way)
attribute = getRelationObject('oneToOne', { ...attribute, inversed: false });
} else if (attribute.via && attribute.model && isPlural(attribute.via)) {
// Many-To-One
attribute = getRelationObject('manyToOne', { ...attribute, inversed: true });
} else if (attribute.via && attribute.collection && isPlural(attribute.via)) {
// Many-To-Many
attribute = getRelationObject('manyToMany', {
...attribute,
inversed: attribute.dominant,
});
} else if (attribute.collection && !attribute.via && !attribute.model) {
// Many-Way
attribute = getRelationObject('oneToMany', attribute);
} else if (attribute.via && attribute.collection) {
// One-To-Many
attribute = getRelationObject('oneToMany', { ...attribute, inversed: false });
} else {
logger.warn(`unknown relation type, please fix manually: ${key}`);
}
_.set(schemaJson, `attributes.${key}`, attribute);
});
}
// Create the new content-types/api/schema.json file

@@ -47,0 +95,0 @@ await fs.ensureFile(v4SchemaJsonPath);

const migrateApiFolder = require('./update-api-folder-structure');
const migrateDependencies = require('./update-package-dependencies');
const migratePlugin = require('./update-plugin-folder-structure');
const migrateApplicationFolderStructure = require('./update-application-folder-structure');

@@ -9,2 +10,3 @@ module.exports = {

migratePlugin,
migrateApplicationFolderStructure,
};

@@ -13,3 +13,3 @@ const { join } = require('path');

*/
module.exports = async (apiPath, apiName) => {
module.exports = async (apiPath, apiName, renamedFrom) => {
const v3RoutePath = join(apiPath, 'config', 'routes.json');

@@ -34,4 +34,9 @@ const v4RoutePath = join(apiPath, 'routes', `${apiName}.js`);

const renamedRoutes = updatedRoutes.map((route) => {
route.handler = route.handler.replace(renamedFrom, apiName);
return route;
});
// Transform objects to strings
const routesToString = inspect(updatedRoutes, { depth: Infinity });
const routesToString = inspect({ routes: renamedRoutes }, { depth: Infinity });

@@ -38,0 +43,0 @@ // Export routes from create js file

{
"name": "@strapi/codemods",
"version": "1.0.2",
"version": "1.1.0",
"main": "bin/cli.js",

@@ -5,0 +5,0 @@ "license": "MIT",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc