@fecommunity/reactpress 2.0.0-beta-4-beta.1 → 2.0.0-beta.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/{scripts → bin}/reactpress.js +0 -0
- package/package.json +38 -34
- package/scripts/build-packages.js +271 -0
- package/scripts/deploy.sh +25 -0
- package/scripts/{reactpress-publish.js → publish-packages.js} +47 -237
- package/scripts/reactpress-server-old.js +130 -0
- package/scripts/reactpress-server.js +666 -0
- package/scripts/reactpress-cli.js +0 -90
- package/scripts/reactpress-deploy.sh +0 -47
- /package/scripts/{reactpress-dev.js → dev.js} +0 -0
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fecommunity/reactpress",
|
|
3
3
|
"author": "fecommunity",
|
|
4
|
-
"version": "2.0.0-beta
|
|
4
|
+
"version": "2.0.0-beta.0",
|
|
5
5
|
"description": "ReactPress - A full-stack CMS built with React, Next.js, and NestJS",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"reactpress",
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
"typescript"
|
|
14
14
|
],
|
|
15
15
|
"bin": {
|
|
16
|
-
"reactpress": "./
|
|
17
|
-
"reactpress-server": "./
|
|
16
|
+
"reactpress": "./bin/reactpress.js",
|
|
17
|
+
"reactpress-server": "./scripts/reactpress-server.js",
|
|
18
18
|
"reactpress-client": "./client/bin/reactpress-client.js"
|
|
19
19
|
},
|
|
20
20
|
"files": [
|
|
@@ -24,6 +24,40 @@
|
|
|
24
24
|
"server/bin/**/*",
|
|
25
25
|
"CONTRIBUTING.md"
|
|
26
26
|
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"clean": "pnpm clean:node_modules && pnpm clean:dist",
|
|
29
|
+
"clean:node_modules": "npx rimraf ./node_modules ./**/node_modules",
|
|
30
|
+
"clean:dist": "npx rimraf ./dist ./**/dist",
|
|
31
|
+
"dev": "node ./scripts/dev.js",
|
|
32
|
+
"dev:server": "pnpm run --dir ./server dev",
|
|
33
|
+
"dev:client": "pnpm run --dir ./client dev",
|
|
34
|
+
"dev:docs": "pnpm run --dir ./docs dev",
|
|
35
|
+
"build": "pnpm build:toolkit && pnpm build:server && pnpm build:client",
|
|
36
|
+
"build:packages": "node scripts/build-packages.js",
|
|
37
|
+
"build:toolkit": "pnpm run --dir ./toolkit build",
|
|
38
|
+
"build:server": "pnpm run --dir ./server build",
|
|
39
|
+
"build:client": "pnpm run --dir ./client build",
|
|
40
|
+
"build:docs": "pnpm run --dir ./docs build",
|
|
41
|
+
"deploy:docs": "pnpm run --dir ./docs deploy:surge",
|
|
42
|
+
"deploy": "sh scripts/deploy.sh",
|
|
43
|
+
"start": "concurrently 'pnpm:start:*'",
|
|
44
|
+
"start:server": "pnpm run --dir ./server start",
|
|
45
|
+
"start:client": "pnpm run --dir ./client start",
|
|
46
|
+
"pm2": "pnpm run pm2:server && pnpm run pm2:client",
|
|
47
|
+
"pm2:server": "pnpm run --dir ./server pm2",
|
|
48
|
+
"pm2:client": "pnpm run --dir ./client pm2",
|
|
49
|
+
"lint": "concurrently 'pnpm:lint:*'",
|
|
50
|
+
"lint:client": "eslint --fix './client/**/*.{ts,tsx,js,jsx}'",
|
|
51
|
+
"lint:server": "eslint --fix './server/./**/*.{ts,js}'",
|
|
52
|
+
"format": "concurrently 'pnpm:format:*'",
|
|
53
|
+
"format:js": "prettier --write --parser typescript './**/*.{ts,tsx,js,jsx}'",
|
|
54
|
+
"prepare": "husky",
|
|
55
|
+
"precommit": "lint-staged",
|
|
56
|
+
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0",
|
|
57
|
+
"publish": "node scripts/publish-packages.js",
|
|
58
|
+
"release": "node scripts/build-packages.js --publish",
|
|
59
|
+
"generate:api-types": "node scripts/generate-api-types.js"
|
|
60
|
+
},
|
|
27
61
|
"dependencies": {
|
|
28
62
|
"chalk": "^4.1.2",
|
|
29
63
|
"commander": "^9.4.1",
|
|
@@ -58,35 +92,5 @@
|
|
|
58
92
|
"eslint --fix"
|
|
59
93
|
]
|
|
60
94
|
},
|
|
61
|
-
"
|
|
62
|
-
"clean": "pnpm clean:node_modules && pnpm clean:dist",
|
|
63
|
-
"clean:node_modules": "npx rimraf ./node_modules ./**/node_modules",
|
|
64
|
-
"clean:dist": "npx rimraf ./dist ./**/dist",
|
|
65
|
-
"dev": "node ./scripts/reactpress-dev.js",
|
|
66
|
-
"dev:server": "pnpm run --dir ./server dev",
|
|
67
|
-
"dev:client": "pnpm run --dir ./client dev",
|
|
68
|
-
"dev:docs": "pnpm run --dir ./docs dev",
|
|
69
|
-
"build": "pnpm build:toolkit && pnpm build:server && pnpm build:client",
|
|
70
|
-
"build:packages": "node scripts/reactpress-cli.js --build",
|
|
71
|
-
"build:toolkit": "pnpm run --dir ./toolkit build",
|
|
72
|
-
"build:server": "pnpm run --dir ./server build",
|
|
73
|
-
"build:client": "pnpm run --dir ./client build",
|
|
74
|
-
"build:docs": "pnpm run --dir ./docs build",
|
|
75
|
-
"deploy:docs": "pnpm run --dir ./docs deploy:surge",
|
|
76
|
-
"deploy": "sh scripts/deploy.sh",
|
|
77
|
-
"start": "concurrently 'pnpm:start:*'",
|
|
78
|
-
"start:server": "pnpm run --dir ./server start",
|
|
79
|
-
"start:client": "pnpm run --dir ./client start",
|
|
80
|
-
"pm2": "pnpm run pm2:server && pnpm run pm2:client",
|
|
81
|
-
"pm2:server": "pnpm run --dir ./server pm2",
|
|
82
|
-
"pm2:client": "pnpm run --dir ./client pm2",
|
|
83
|
-
"lint": "concurrently 'pnpm:lint:*'",
|
|
84
|
-
"lint:client": "eslint --fix './client/**/*.{ts,tsx,js,jsx}'",
|
|
85
|
-
"lint:server": "eslint --fix './server/./**/*.{ts,js}'",
|
|
86
|
-
"format": "concurrently 'pnpm:format:*'",
|
|
87
|
-
"format:js": "prettier --write --parser typescript './**/*.{ts,tsx,js,jsx}'",
|
|
88
|
-
"precommit": "lint-staged",
|
|
89
|
-
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0",
|
|
90
|
-
"release": "node scripts/reactpress-publish.js --publish"
|
|
91
|
-
}
|
|
95
|
+
"packageManager": "pnpm@10.12.1+sha512.f0dda8580f0ee9481c5c79a1d927b9164f2c478e90992ad268bbb2465a736984391d6333d2c327913578b2804af33474ca554ba29c04a8b13060a717675ae3ac"
|
|
92
96
|
}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { execSync } = require('child_process');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const chalk = require('chalk');
|
|
7
|
+
const crypto = require('crypto');
|
|
8
|
+
|
|
9
|
+
// Package build order (dependencies first)
|
|
10
|
+
const packages = [
|
|
11
|
+
{
|
|
12
|
+
name: '@fecommunity/reactpress-config',
|
|
13
|
+
path: 'config',
|
|
14
|
+
description: 'Configuration management package'
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: '@fecommunity/reactpress-server',
|
|
18
|
+
path: 'server',
|
|
19
|
+
description: 'Backend API server package'
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: '@fecommunity/reactpress-client',
|
|
23
|
+
path: 'client',
|
|
24
|
+
description: 'Frontend application package'
|
|
25
|
+
}
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
// Generate a hash for a file or directory
|
|
29
|
+
function generateHash(filePath) {
|
|
30
|
+
try {
|
|
31
|
+
if (fs.statSync(filePath).isDirectory()) {
|
|
32
|
+
const files = fs.readdirSync(filePath);
|
|
33
|
+
const hashes = files
|
|
34
|
+
.filter(file => !file.startsWith('.') && file !== 'node_modules' && file !== 'dist' && file !== '.next') // Ignore hidden files and build directories
|
|
35
|
+
.map(file => generateHash(path.join(filePath, file)))
|
|
36
|
+
.sort();
|
|
37
|
+
return crypto.createHash('md5').update(hashes.join('')).digest('hex');
|
|
38
|
+
} else {
|
|
39
|
+
const content = fs.readFileSync(filePath);
|
|
40
|
+
return crypto.createHash('md5').update(content).digest('hex');
|
|
41
|
+
}
|
|
42
|
+
} catch (error) {
|
|
43
|
+
return '';
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Get package content hash
|
|
48
|
+
function getPackageHash(packagePath) {
|
|
49
|
+
const fullPath = path.join(process.cwd(), packagePath);
|
|
50
|
+
return generateHash(fullPath);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Check if package has meaningful changes
|
|
54
|
+
function hasMeaningfulChanges(packagePath, packageName) {
|
|
55
|
+
try {
|
|
56
|
+
// Create a hash file path to store previous hash in node_modules
|
|
57
|
+
const hashFilePath = path.join(process.cwd(), 'node_modules', '.build-cache', `${packageName.replace('/', '_')}.hash`);
|
|
58
|
+
|
|
59
|
+
// Generate current hash
|
|
60
|
+
const currentHash = getPackageHash(packagePath);
|
|
61
|
+
|
|
62
|
+
// Check if we have a previous hash
|
|
63
|
+
if (fs.existsSync(hashFilePath)) {
|
|
64
|
+
const previousHash = fs.readFileSync(hashFilePath, 'utf8').trim();
|
|
65
|
+
return currentHash !== previousHash;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// If no previous hash, consider it as having changes
|
|
69
|
+
return true;
|
|
70
|
+
} catch (error) {
|
|
71
|
+
console.log(chalk.yellow(`⚠️ Could not check changes for ${packageName}, assuming changes exist`));
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Save package hash
|
|
77
|
+
function savePackageHash(packagePath, packageName) {
|
|
78
|
+
try {
|
|
79
|
+
const hashFilePath = path.join(process.cwd(), 'node_modules', '.build-cache', `${packageName.replace('/', '_')}.hash`);
|
|
80
|
+
|
|
81
|
+
// Ensure cache directory exists
|
|
82
|
+
const cacheDir = path.dirname(hashFilePath);
|
|
83
|
+
if (!fs.existsSync(cacheDir)) {
|
|
84
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Generate and save current hash
|
|
88
|
+
const currentHash = getPackageHash(packagePath);
|
|
89
|
+
fs.writeFileSync(hashFilePath, currentHash);
|
|
90
|
+
} catch (error) {
|
|
91
|
+
console.log(chalk.yellow(`⚠️ Could not save hash for ${packageName}`));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Get current versions
|
|
96
|
+
function getCurrentVersion(packagePath) {
|
|
97
|
+
try {
|
|
98
|
+
const pkgPath = path.join(process.cwd(), packagePath, 'package.json');
|
|
99
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
100
|
+
return pkg.version;
|
|
101
|
+
} catch (error) {
|
|
102
|
+
return 'unknown';
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Fix workspace dependencies for build
|
|
107
|
+
function fixWorkspaceDependenciesForBuild(packagePath) {
|
|
108
|
+
console.log(chalk.blue(`🔧 Fixing workspace dependencies for build: ${packagePath}...`));
|
|
109
|
+
|
|
110
|
+
const pkgPath = path.join(process.cwd(), packagePath, 'package.json');
|
|
111
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
112
|
+
|
|
113
|
+
// Fix dependencies
|
|
114
|
+
const depTypes = ['dependencies', 'devDependencies', 'peerDependencies'];
|
|
115
|
+
|
|
116
|
+
depTypes.forEach(depType => {
|
|
117
|
+
if (pkg[depType]) {
|
|
118
|
+
Object.keys(pkg[depType]).forEach(depName => {
|
|
119
|
+
// Check if it's a workspace dependency
|
|
120
|
+
if (pkg[depType][depName] === 'workspace:*' || pkg[depType][depName].startsWith('workspace:')) {
|
|
121
|
+
// For build purposes, we'll use the file: protocol to reference local packages
|
|
122
|
+
const depPackage = packages.find(p => p.name === depName);
|
|
123
|
+
if (depPackage) {
|
|
124
|
+
console.log(chalk.gray(` Replacing ${depName} workspace dependency with file reference`));
|
|
125
|
+
pkg[depType][depName] = `file:../${depPackage.path}`;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// Write the updated package.json
|
|
133
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
134
|
+
console.log(chalk.green(`✅ Workspace dependencies fixed for build: ${packagePath}`));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Restore workspace dependencies after build
|
|
138
|
+
function restoreWorkspaceDependenciesAfterBuild(packagePath) {
|
|
139
|
+
console.log(chalk.blue(`🔄 Restoring workspace dependencies after build: ${packagePath}...`));
|
|
140
|
+
|
|
141
|
+
const pkgPath = path.join(process.cwd(), packagePath, 'package.json');
|
|
142
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
143
|
+
|
|
144
|
+
// Restore dependencies
|
|
145
|
+
const depTypes = ['dependencies', 'devDependencies', 'peerDependencies'];
|
|
146
|
+
|
|
147
|
+
depTypes.forEach(depType => {
|
|
148
|
+
if (pkg[depType]) {
|
|
149
|
+
Object.keys(pkg[depType]).forEach(depName => {
|
|
150
|
+
// Check if this is one of our internal packages referenced with file:
|
|
151
|
+
const depPackage = packages.find(p => p.name === depName);
|
|
152
|
+
if (depPackage && pkg[depType][depName].startsWith('file:')) {
|
|
153
|
+
console.log(chalk.gray(` Restoring ${depName} to workspace dependency`));
|
|
154
|
+
pkg[depType][depName] = 'workspace:*';
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// Write the updated package.json
|
|
161
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
162
|
+
console.log(chalk.green(`✅ Workspace dependencies restored after build: ${packagePath}`));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Build package
|
|
166
|
+
function buildPackage(pkg) {
|
|
167
|
+
console.log(chalk.blue(`\n🔨 Building ${pkg.name} (${pkg.description})...`));
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
// Fix workspace dependencies for build
|
|
171
|
+
fixWorkspaceDependenciesForBuild(pkg.path);
|
|
172
|
+
|
|
173
|
+
try {
|
|
174
|
+
if (pkg.path === 'config') {
|
|
175
|
+
execSync('pnpm run build', { cwd: path.join(process.cwd(), pkg.path), stdio: 'inherit' });
|
|
176
|
+
} else if (pkg.path === 'server') {
|
|
177
|
+
execSync('pnpm run prebuild && pnpm run build', { cwd: path.join(process.cwd(), pkg.path), stdio: 'inherit' });
|
|
178
|
+
} else if (pkg.path === 'client') {
|
|
179
|
+
execSync('pnpm run prebuild && pnpm run build', { cwd: path.join(process.cwd(), pkg.path), stdio: 'inherit' });
|
|
180
|
+
}
|
|
181
|
+
console.log(chalk.green(`✅ ${pkg.name} built successfully`));
|
|
182
|
+
} finally {
|
|
183
|
+
// Always restore workspace dependencies
|
|
184
|
+
restoreWorkspaceDependenciesAfterBuild(pkg.path);
|
|
185
|
+
}
|
|
186
|
+
} catch (error) {
|
|
187
|
+
console.log(chalk.red(`❌ Failed to build ${pkg.name}`));
|
|
188
|
+
throw error;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Main function
|
|
193
|
+
async function main() {
|
|
194
|
+
console.log(chalk.blue('🏗️ ReactPress Package Builder\n'));
|
|
195
|
+
|
|
196
|
+
// Show current versions
|
|
197
|
+
console.log(chalk.cyan('📋 Current package versions:'));
|
|
198
|
+
packages.forEach(pkg => {
|
|
199
|
+
const version = getCurrentVersion(pkg.path);
|
|
200
|
+
console.log(chalk.gray(` ${pkg.name}: ${version}`));
|
|
201
|
+
});
|
|
202
|
+
console.log();
|
|
203
|
+
|
|
204
|
+
try {
|
|
205
|
+
// Track which packages actually need to be built
|
|
206
|
+
const packagesToBuild = [];
|
|
207
|
+
|
|
208
|
+
// Check for meaningful changes in each package
|
|
209
|
+
for (const pkg of packages) {
|
|
210
|
+
if (fs.existsSync(path.join(process.cwd(), pkg.path))) {
|
|
211
|
+
if (hasMeaningfulChanges(pkg.path, pkg.name)) {
|
|
212
|
+
packagesToBuild.push(pkg);
|
|
213
|
+
console.log(chalk.blue(`\n📦 ${pkg.name} has changes, will be built`));
|
|
214
|
+
} else {
|
|
215
|
+
console.log(chalk.gray(`\n⏭️ ${pkg.name} has no meaningful changes, skipping...`));
|
|
216
|
+
}
|
|
217
|
+
} else {
|
|
218
|
+
console.log(chalk.yellow(`⚠️ Package ${pkg.name} directory not found, skipping...`));
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (packagesToBuild.length === 0) {
|
|
223
|
+
console.log(chalk.green('\n✅ No packages have meaningful changes. Nothing to build!'));
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Build packages that have changes
|
|
228
|
+
for (const pkg of packagesToBuild) {
|
|
229
|
+
await buildPackage(pkg);
|
|
230
|
+
// Save the hash after successful build
|
|
231
|
+
savePackageHash(pkg.path, pkg.name);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
console.log(chalk.green(`\n🎉 ${packagesToBuild.length} package(s) built successfully!`));
|
|
235
|
+
} catch (error) {
|
|
236
|
+
console.error(chalk.red('❌ Build failed:'), error);
|
|
237
|
+
process.exit(1);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Check if called with --publish flag
|
|
242
|
+
if (process.argv.includes('--publish')) {
|
|
243
|
+
// When called with --publish, we only show the header and versions but don't build
|
|
244
|
+
// The publish script will handle building as needed
|
|
245
|
+
console.log(chalk.blue('🏗️ ReactPress Package Builder\n'));
|
|
246
|
+
|
|
247
|
+
// Show current versions
|
|
248
|
+
console.log(chalk.cyan('📋 Current package versions:'));
|
|
249
|
+
packages.forEach(pkg => {
|
|
250
|
+
const version = getCurrentVersion(pkg.path);
|
|
251
|
+
console.log(chalk.gray(` ${pkg.name}: ${version}`));
|
|
252
|
+
});
|
|
253
|
+
console.log();
|
|
254
|
+
|
|
255
|
+
// Don't build packages here, just start the publish process
|
|
256
|
+
console.log(chalk.blue('\n🚀 Starting publish process...'));
|
|
257
|
+
// Execute publish script
|
|
258
|
+
const { spawn } = require('child_process');
|
|
259
|
+
const publishProcess = spawn('node', ['scripts/publish-packages.js', '--release'], { stdio: 'inherit' });
|
|
260
|
+
|
|
261
|
+
publishProcess.on('close', (code) => {
|
|
262
|
+
if (code === 0) {
|
|
263
|
+
console.log(chalk.green('\n✅ Build and publish completed successfully!'));
|
|
264
|
+
} else {
|
|
265
|
+
console.log(chalk.red('\n❌ Publish process failed!'));
|
|
266
|
+
process.exit(code);
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
} else {
|
|
270
|
+
main();
|
|
271
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# 更新代码
|
|
2
|
+
git checkout master
|
|
3
|
+
git pull
|
|
4
|
+
|
|
5
|
+
# 安装依赖&构建
|
|
6
|
+
pnpm install
|
|
7
|
+
|
|
8
|
+
# 构建本地配置
|
|
9
|
+
pnpm run build:config
|
|
10
|
+
|
|
11
|
+
# 构建服务器
|
|
12
|
+
pnpm run build:server
|
|
13
|
+
|
|
14
|
+
# 结束进程
|
|
15
|
+
pm2 kill
|
|
16
|
+
|
|
17
|
+
# 构建本地client
|
|
18
|
+
pnpm run build:client
|
|
19
|
+
|
|
20
|
+
# 启动
|
|
21
|
+
pnpm run pm2
|
|
22
|
+
|
|
23
|
+
# 开机启动
|
|
24
|
+
pm2 startup
|
|
25
|
+
pm2 save
|