Merge branch 'master' of github.com:pluginpal/strapi-plugin-config-sync

pull/185/head 3.1.2-beta.1
Boaz Poolman 2025-06-30 07:07:57 +02:00
commit 75e9f4cb04
33 changed files with 219 additions and 185 deletions

View File

@ -108,12 +108,13 @@ coverage
# Strapi
############################
# .env
license.txt
exports
*.cache
.strapi
dist
build
.strapi-updater.json
.strapi-cloud.json
# yalc
.yalc

View File

@ -1,16 +0,0 @@
/**
* This file was automatically generated by Strapi.
* Any modifications made will be discarded.
*/
import strapiCloud from "@strapi/plugin-cloud/strapi-admin";
import usersPermissions from "@strapi/plugin-users-permissions/strapi-admin";
import configSync from "strapi-plugin-config-sync/strapi-admin";
import { renderAdmin } from "@strapi/strapi/admin";
renderAdmin(document.getElementById("strapi"), {
plugins: {
"strapi-cloud": strapiCloud,
"users-permissions": usersPermissions,
"config-sync": configSync,
},
});

View File

@ -1,63 +0,0 @@
<!doctype html>
<html lang="en">
<!--
This file was automatically generated by Strapi.
Any modifications made will be discarded.
-->
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, viewport-fit=cover"
/>
<meta name="robots" content="noindex" />
<meta name="referrer" content="same-origin" />
<title>Strapi Admin</title>
<style>
html,
body,
#strapi {
height: 100%;
}
body {
margin: 0;
-webkit-font-smoothing: antialiased;
}
</style>
</head>
<body>
<div id="strapi"></div>
<noscript
><div class="strapi--root">
<div class="strapi--no-js">
<style type="text/css">
.strapi--root {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
background: #fff;
}
.strapi--no-js {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
font-family: helvetica, arial, sans-serif;
}
</style>
<h1>JavaScript disabled</h1>
<p>
Please
<a href="https://www.enable-javascript.com/">enable JavaScript</a>
in your browser and reload the page to proceed.
</p>
</div>
</div></noscript
>
<script type="module" src="/.strapi/client/app.js"></script>
</body>
</html>

View File

@ -58,4 +58,47 @@ describe('Test the config-sync CLI', () => {
}
expect(error).toHaveProperty('code', 1);
});
test('Import build project', async () => {
// First we make sure the dist folder is deleted.
await exec('mv dist .tmp');
await exec('yarn cs import -y');
const { stdout: buildOutput } = await exec('ls dist');
expect(buildOutput).toContain('config');
expect(buildOutput).toContain('src');
expect(buildOutput).toContain('tsconfig.tsbuildinfo');
// We restore the dist folder.
await exec('rm -rf dist');
await exec('mv .tmp/dist ./dist');
});
test('Import project already built', async () => {
// First we make sure the dist folder exists by doing an import.
await exec('yarn cs import -y');
const { stdout: lsDist } = await exec('ls dist');
expect(lsDist).toContain('config');
expect(lsDist).toContain('src');
expect(lsDist).toContain('tsconfig.tsbuildinfo');
// We remove on file from the dist folder
await exec('mv dist/tsconfig.tsbuildinfo .tmp');
// The new import should not rebuild the project.
await exec('yarn cs import -y');
const { stdout: buildOutput } = await exec('ls dist');
expect(buildOutput).toContain('config');
expect(buildOutput).toContain('src');
expect(buildOutput).not.toContain('tsconfig.tsbuildinfo');
// We restore the tsconfig.tsbuildinfo file.
await exec('mv .tmp/tsconfig.tsbuildinfo dist/tsconfig.tsbuildinfo');
});
});

View File

@ -7,7 +7,7 @@ jest.setTimeout(20000);
afterEach(async () => {
// Disable importOnBootstrap
await exec('sed -i "s/importOnBootstrap: true/importOnBootstrap: false/g" config/plugins.js');
await exec('sed -i "s/importOnBootstrap: true/importOnBootstrap: false/g" config/plugins.ts');
await cleanupStrapi();
await exec('rm -rf config/sync');
@ -19,8 +19,8 @@ describe('Test the importOnBootstrap feature', () => {
await exec('yarn cs export -y');
await exec('rm -rf .tmp');
// Manually change the plugins.js to enable importOnBoostrap.
await exec('sed -i "s/importOnBootstrap: false/importOnBootstrap: true/g" config/plugins.js');
// Manually change the plugins.ts to enable importOnBoostrap.
await exec('sed -i "s/importOnBootstrap: false/importOnBootstrap: true/g" config/plugins.ts');
// Start up Strapi to initiate the importOnBootstrap function.
await setupStrapi();
@ -33,8 +33,8 @@ describe('Test the importOnBootstrap feature', () => {
await exec('rm -rf .tmp');
await exec('yarn cs export -y');
// Manually change the plugins.js to enable importOnBoostrap.
await exec('sed -i "s/importOnBootstrap: false/importOnBootstrap: true/g" config/plugins.js');
// Manually change the plugins.ts to enable importOnBoostrap.
await exec('sed -i "s/importOnBootstrap: false/importOnBootstrap: true/g" config/plugins.ts');
// Remove a config file to make sure the importOnBoostrap
// function actually attempts to import.

View File

@ -1,4 +1,4 @@
module.exports = ({ env }) => ({
export default ({ env }) => ({
auth: {
secret: env('ADMIN_JWT_SECRET'),
},
@ -19,6 +19,5 @@ module.exports = ({ env }) => ({
},
watchIgnoreFiles: [
'!**/.yalc/**/server/**',
'**/config/sync/**',
]
],
});

View File

@ -1,4 +1,4 @@
module.exports = {
export default {
rest: {
defaultLimit: 25,
maxLimit: 100,

View File

@ -1,11 +0,0 @@
const path = require('path');
module.exports = ({ env }) => ({
connection: {
client: 'sqlite',
connection: {
filename: path.join(__dirname, '..', env('DATABASE_FILENAME', '.tmp/data.db')),
},
useNullAsDefault: true,
},
});

View File

@ -0,0 +1,15 @@
import path from 'path';
export default ({ env }) => {
return {
connection: {
client: 'sqlite',
connection: {
filename: path.join(__dirname, '..', '..', env('DATABASE_FILENAME', '.tmp/data.db')),
},
useNullAsDefault: true,
},
};
};

View File

@ -1,4 +1,4 @@
module.exports = [
export default [
'strapi::logger',
'strapi::errors',
'strapi::security',

View File

@ -1,4 +1,4 @@
module.exports = {
export default () => ({
'config-sync': {
enabled: true,
config: {
@ -6,4 +6,4 @@ module.exports = {
minify: true,
},
},
};
});

View File

@ -1,4 +1,4 @@
module.exports = ({ env }) => ({
export default ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
app: {

View File

@ -1,8 +0,0 @@
{
"compilerOptions": {
"moduleResolution": "nodenext",
"target": "ES2021",
"checkJs": true,
"allowJs": true
}
}

View File

@ -11,15 +11,19 @@
"cs": "config-sync"
},
"devDependencies": {
"@types/node": "^24.0.7",
"@types/react": "^19.1.8",
"@types/react-dom": "^19.1.6",
"jest": "^29.7.0",
"jest-cli": "^29.7.0",
"supertest": "^6.3.3",
"typescript": "^5.8.3",
"yalc": "^1.0.0-pre.53"
},
"dependencies": {
"@strapi/plugin-cloud": "5.0.4",
"@strapi/plugin-users-permissions": "5.0.4",
"@strapi/strapi": "5.0.4",
"@strapi/plugin-cloud": "5.16.0",
"@strapi/plugin-users-permissions": "5.16.0",
"@strapi/strapi": "5.16.0",
"better-sqlite3": "9.4.3",
"react": "^18.0.0",
"react-dom": "^18.0.0",

View File

@ -1,3 +1,5 @@
import type { StrapiApp } from '@strapi/strapi/admin';
export default {
config: {
locales: [
@ -29,7 +31,7 @@ export default {
// 'zh',
],
},
bootstrap(app) {
bootstrap(app: StrapiApp) {
console.log(app);
},
};

View File

@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": ["../plugins/**/admin/src/**/*", "./"],
"exclude": ["node_modules/", "build/", "dist/", "**/*.test.ts"]
}

View File

@ -1,9 +0,0 @@
'use strict';
/* eslint-disable no-unused-vars */
module.exports = (config, webpack) => {
// Note: we provide webpack above so you should not `require` it
// Perform customizations to webpack config
// Important: return the modified config
return config;
};

View File

@ -0,0 +1,12 @@
import { mergeConfig, type UserConfig } from 'vite';
export default (config: UserConfig) => {
// Important: always return the modified config
return mergeConfig(config, {
resolve: {
alias: {
'@': '/src',
},
},
});
};

View File

@ -1,9 +0,0 @@
'use strict';
/**
* home controller
*/
const { createCoreController } = require('@strapi/strapi').factories;
module.exports = createCoreController('api::home.home');

View File

@ -0,0 +1,7 @@
/**
* home controller
*/
import { factories } from '@strapi/strapi';
export default factories.createCoreController('api::home.home');

View File

@ -1,9 +0,0 @@
'use strict';
/**
* home router
*/
const { createCoreRouter } = require('@strapi/strapi').factories;
module.exports = createCoreRouter('api::home.home');

View File

@ -0,0 +1,8 @@
/**
* home router
*/
import { factories } from '@strapi/strapi';
export default factories.createCoreRouter('api::home.home');

View File

@ -1,9 +0,0 @@
'use strict';
/**
* home service
*/
const { createCoreService } = require('@strapi/strapi').factories;
module.exports = createCoreService('api::home.home');

View File

@ -0,0 +1,7 @@
/**
* home service
*/
import { factories } from '@strapi/strapi';
export default factories.createCoreService('api::home.home');

View File

@ -1,9 +0,0 @@
'use strict';
/**
* page controller
*/
const { createCoreController } = require('@strapi/strapi').factories;
module.exports = createCoreController('api::page.page');

View File

@ -0,0 +1,7 @@
/**
* page controller
*/
import { factories } from '@strapi/strapi';
export default factories.createCoreController('api::page.page');

View File

@ -1,9 +0,0 @@
'use strict';
/**
* page router
*/
const { createCoreRouter } = require('@strapi/strapi').factories;
module.exports = createCoreRouter('api::page.page');

View File

@ -0,0 +1,7 @@
/**
* page router
*/
import { factories } from '@strapi/strapi';
export default factories.createCoreRouter('api::page.page');

View File

@ -1,9 +0,0 @@
'use strict';
/**
* page service
*/
const { createCoreService } = require('@strapi/strapi').factories;
module.exports = createCoreService('api::page.page');

View File

@ -0,0 +1,7 @@
/**
* page service
*/
import { factories } from '@strapi/strapi';
module.exports = factories.createCoreService('api::page.page');

View File

@ -1,13 +1,13 @@
'use strict';
// import type { Core } from '@strapi/strapi';
module.exports = {
export default {
/**
* An asynchronous register function that runs before
* your application is initialized.
*
* This gives you an opportunity to extend code.
*/
register(/*{ strapi }*/) {},
register(/* { strapi }: { strapi: Core.Strapi } */) {},
/**
* An asynchronous bootstrap function that runs before
@ -16,5 +16,5 @@ module.exports = {
* This gives you an opportunity to set up your data model,
* run jobs, or perform some special logic.
*/
bootstrap(/*{ strapi }*/) {},
bootstrap(/* { strapi }: { strapi: Core.Strapi } */) {},
};

43
playground/tsconfig.json Normal file
View File

@ -0,0 +1,43 @@
{
"compilerOptions": {
"module": "CommonJS",
"moduleResolution": "Node",
"lib": ["ES2020"],
"target": "ES2019",
"strict": false,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"incremental": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"noEmitOnError": true,
"noImplicitThis": true,
"outDir": "dist",
"rootDir": ".",
},
"include": [
// Include root files
"./",
// Include all ts files
"./**/*.ts",
// Include all js files
"./**/*.js",
// Force the JSON files in the src folder to be included
"src/**/*.json"
],
"exclude": [
"node_modules/",
"build/",
"dist/",
".cache/",
".tmp/",
// Do not include admin files in the server compilation
"src/admin/",
// Do not include test files
"**/*.test.*",
// Do not include plugins in the server compilation
"src/plugins/**"
]
}

View File

@ -8,6 +8,7 @@ import inquirer from 'inquirer';
import isEmpty from 'lodash/isEmpty';
import { createStrapi, compileStrapi } from '@strapi/strapi';
import gitDiff from 'git-diff';
import tsUtils from '@strapi/typescript-utils';
import warnings from './warnings';
import packageJSON from '../package.json';
@ -17,7 +18,19 @@ const program = new Command();
const getStrapiApp = async () => {
process.env.CONFIG_SYNC_CLI = 'true';
const appContext = await compileStrapi();
const appDir = process.cwd();
const isTSProject = await tsUtils.isUsingTypeScript(appDir);
const outDir = await tsUtils.resolveOutDir(appDir);
const alreadyCompiled = await fs.existsSync(outDir);
let appContext;
if (!isTSProject || !alreadyCompiled) {
appContext = await compileStrapi();
} else {
const distDir = isTSProject ? outDir : appDir;
appContext = { appDir, distDir };
}
const app = await createStrapi(appContext).load();
return app;
};