@windrun-huaiin/dev-scripts 6.8.1 → 6.9.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/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +137 -1410
- package/dist/cli.mjs +145 -432
- package/dist/commands/check-translations.d.ts +3 -0
- package/dist/commands/check-translations.d.ts.map +1 -0
- package/dist/commands/check-translations.js +132 -0
- package/dist/commands/check-translations.mjs +130 -0
- package/dist/commands/clean-translations.d.ts +3 -0
- package/dist/commands/clean-translations.d.ts.map +1 -0
- package/dist/commands/clean-translations.js +148 -0
- package/dist/commands/clean-translations.mjs +146 -0
- package/dist/commands/create-diaomao-app.d.ts +2 -0
- package/dist/commands/create-diaomao-app.d.ts.map +1 -0
- package/dist/commands/create-diaomao-app.js +151 -0
- package/dist/commands/create-diaomao-app.mjs +149 -0
- package/dist/commands/deep-clean.d.ts +3 -0
- package/dist/commands/deep-clean.d.ts.map +1 -0
- package/dist/commands/deep-clean.js +119 -0
- package/dist/commands/deep-clean.mjs +117 -0
- package/dist/commands/easy-changeset.d.ts +2 -0
- package/dist/commands/easy-changeset.d.ts.map +1 -0
- package/dist/commands/easy-changeset.js +39 -0
- package/dist/commands/easy-changeset.mjs +37 -0
- package/dist/commands/generate-blog-index.d.ts +3 -0
- package/dist/commands/generate-blog-index.d.ts.map +1 -0
- package/dist/commands/generate-blog-index.js +302 -0
- package/dist/commands/generate-blog-index.mjs +300 -0
- package/dist/commands/generate-nextjs-architecture.d.ts +3 -0
- package/dist/commands/generate-nextjs-architecture.d.ts.map +1 -0
- package/dist/commands/generate-nextjs-architecture.js +84 -0
- package/dist/commands/generate-nextjs-architecture.mjs +82 -0
- package/dist/config/index.d.ts +10 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +173 -0
- package/dist/config/index.mjs +170 -0
- package/dist/config/schema.d.ts +34 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +80 -0
- package/dist/config/schema.mjs +78 -0
- package/dist/index.d.ts +6 -49
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -996
- package/dist/index.mjs +4 -3
- package/dist/utils/file-scanner.d.ts +22 -0
- package/dist/utils/file-scanner.d.ts.map +1 -0
- package/dist/utils/file-scanner.js +70 -0
- package/dist/utils/file-scanner.mjs +65 -0
- package/dist/utils/logger.d.ts +24 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +63 -0
- package/dist/utils/logger.mjs +61 -0
- package/dist/utils/translation-parser.d.ts +29 -0
- package/dist/utils/translation-parser.d.ts.map +1 -0
- package/dist/utils/translation-parser.js +225 -0
- package/dist/utils/translation-parser.mjs +218 -0
- package/package.json +5 -5
- package/dist/chunk-GVR6HFHM.mjs +0 -989
- package/dist/chunk-GVR6HFHM.mjs.map +0 -1
- package/dist/cli.d.mts +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/cli.mjs.map +0 -1
- package/dist/index.d.mts +0 -49
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var schema = require('../config/schema.js');
|
|
4
|
+
var fileScanner = require('../utils/file-scanner.js');
|
|
5
|
+
var logger = require('../utils/logger.js');
|
|
6
|
+
var child_process = require('child_process');
|
|
7
|
+
var fs = require('fs');
|
|
8
|
+
var path = require('path');
|
|
9
|
+
|
|
10
|
+
function getCurrentDateString() {
|
|
11
|
+
const now = new Date();
|
|
12
|
+
const year = now.getFullYear();
|
|
13
|
+
const month = String(now.getMonth() + 1).padStart(2, '0');
|
|
14
|
+
const day = String(now.getDate()).padStart(2, '0');
|
|
15
|
+
return `${year}-${month}-${day}`;
|
|
16
|
+
}
|
|
17
|
+
async function generateNextjsArchitecture(config, cwd = typeof process !== 'undefined' ? process.cwd() : '.') {
|
|
18
|
+
const logger$1 = new logger.Logger(config);
|
|
19
|
+
try {
|
|
20
|
+
// get logs directory and blog directory
|
|
21
|
+
const logsDir = path.join(cwd, config.output?.logDir || 'logs');
|
|
22
|
+
const blogDir = path.join(cwd, config.blog?.mdxDir || 'src/mdx/blog');
|
|
23
|
+
if (!fs.existsSync(logsDir))
|
|
24
|
+
fs.mkdirSync(logsDir, { recursive: true });
|
|
25
|
+
if (!fs.existsSync(blogDir))
|
|
26
|
+
fs.mkdirSync(blogDir, { recursive: true });
|
|
27
|
+
// generate tree result to logs directory
|
|
28
|
+
const treeJsonPath = path.join(logsDir, 'project_tree.json');
|
|
29
|
+
logger$1.log(`Running tree command to generate ${treeJsonPath}`);
|
|
30
|
+
child_process.execSync(`tree -a -J -I '.next|node_modules|logs|dist|pnpm-lock.yaml|turbo|.turbo|public|.cursor|.DS_Store|.git' > ${treeJsonPath}`);
|
|
31
|
+
// read tree result
|
|
32
|
+
const tree = fileScanner.readJsonFile(treeJsonPath);
|
|
33
|
+
if (!tree) {
|
|
34
|
+
logger$1.error('Failed to read tree JSON result!');
|
|
35
|
+
return 1;
|
|
36
|
+
}
|
|
37
|
+
// Merge config and user first
|
|
38
|
+
const userConfig = config.architectureConfig || {};
|
|
39
|
+
const architectureConfig = { ...(schema.DEFAULT_CONFIG.architectureConfig || {}), ...userConfig };
|
|
40
|
+
function renderTree(nodes, depth = 0, parentPath = '') {
|
|
41
|
+
let mdx = '';
|
|
42
|
+
for (const node of nodes) {
|
|
43
|
+
const nodePath = parentPath ? `${parentPath}/${node.name}` : node.name;
|
|
44
|
+
const anotion = architectureConfig[node.name] || '';
|
|
45
|
+
// scan root directory name='ROOT'
|
|
46
|
+
const displayName = (depth === 0 && node.name === '.') ? 'ROOT' : node.name;
|
|
47
|
+
if (node.type === 'directory') {
|
|
48
|
+
if (!node.contents || node.contents.length === 0) {
|
|
49
|
+
// handle empty folder
|
|
50
|
+
mdx += `${' '.repeat(depth)}<ZiaFolder name="${displayName}" anotion="${anotion}" className="opacity-50" disabled/>\n`;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
// handle non-empty folder
|
|
54
|
+
mdx += `${' '.repeat(depth)}<ZiaFolder name="${displayName}" anotion="${anotion}" defaultOpen>\n`;
|
|
55
|
+
mdx += renderTree(node.contents, depth + 1, nodePath);
|
|
56
|
+
mdx += `${' '.repeat(depth)}</ZiaFolder>\n`;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else if (node.type === 'file') {
|
|
60
|
+
mdx += `${' '.repeat(depth)}<ZiaFile name="${node.name}" anotion="${anotion}" href="" />\n`;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return mdx;
|
|
64
|
+
}
|
|
65
|
+
// generate frontmatter
|
|
66
|
+
const frontmatter = `---\ntitle: About Project Structure\ndescription: Show all source code directories and files\nicon: Gift\ndate: ${getCurrentDateString()}\n---\n\n## Quick Started\n\n`;
|
|
67
|
+
// generate mdx content
|
|
68
|
+
const filesContent = renderTree(tree);
|
|
69
|
+
const indentedFilesContent = filesContent.split('\n').map(line => line ? ' ' + line : '').join('\n');
|
|
70
|
+
const mdx = frontmatter + '<Files>\n' + indentedFilesContent + '</Files>\n';
|
|
71
|
+
// output to blog directory
|
|
72
|
+
const outputMdxPath = path.join(blogDir, 'nextjs-architecture.mdx');
|
|
73
|
+
fs.writeFileSync(outputMdxPath, mdx);
|
|
74
|
+
logger$1.success(`Successfully generated ${outputMdxPath}`);
|
|
75
|
+
logger$1.saveToFile('generate-nextjs-architecture.log', cwd);
|
|
76
|
+
return 0;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
logger$1.error(`Error generating nextjs architecture mdx: ${error}`);
|
|
80
|
+
return 1;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
exports.generateNextjsArchitecture = generateNextjsArchitecture;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { DEFAULT_CONFIG } from '../config/schema.mjs';
|
|
2
|
+
import { readJsonFile } from '../utils/file-scanner.mjs';
|
|
3
|
+
import { Logger } from '../utils/logger.mjs';
|
|
4
|
+
import { execSync } from 'child_process';
|
|
5
|
+
import { existsSync, mkdirSync, writeFileSync } from 'fs';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
|
|
8
|
+
function getCurrentDateString() {
|
|
9
|
+
const now = new Date();
|
|
10
|
+
const year = now.getFullYear();
|
|
11
|
+
const month = String(now.getMonth() + 1).padStart(2, '0');
|
|
12
|
+
const day = String(now.getDate()).padStart(2, '0');
|
|
13
|
+
return `${year}-${month}-${day}`;
|
|
14
|
+
}
|
|
15
|
+
async function generateNextjsArchitecture(config, cwd = typeof process !== 'undefined' ? process.cwd() : '.') {
|
|
16
|
+
const logger = new Logger(config);
|
|
17
|
+
try {
|
|
18
|
+
// get logs directory and blog directory
|
|
19
|
+
const logsDir = join(cwd, config.output?.logDir || 'logs');
|
|
20
|
+
const blogDir = join(cwd, config.blog?.mdxDir || 'src/mdx/blog');
|
|
21
|
+
if (!existsSync(logsDir))
|
|
22
|
+
mkdirSync(logsDir, { recursive: true });
|
|
23
|
+
if (!existsSync(blogDir))
|
|
24
|
+
mkdirSync(blogDir, { recursive: true });
|
|
25
|
+
// generate tree result to logs directory
|
|
26
|
+
const treeJsonPath = join(logsDir, 'project_tree.json');
|
|
27
|
+
logger.log(`Running tree command to generate ${treeJsonPath}`);
|
|
28
|
+
execSync(`tree -a -J -I '.next|node_modules|logs|dist|pnpm-lock.yaml|turbo|.turbo|public|.cursor|.DS_Store|.git' > ${treeJsonPath}`);
|
|
29
|
+
// read tree result
|
|
30
|
+
const tree = readJsonFile(treeJsonPath);
|
|
31
|
+
if (!tree) {
|
|
32
|
+
logger.error('Failed to read tree JSON result!');
|
|
33
|
+
return 1;
|
|
34
|
+
}
|
|
35
|
+
// Merge config and user first
|
|
36
|
+
const userConfig = config.architectureConfig || {};
|
|
37
|
+
const architectureConfig = { ...(DEFAULT_CONFIG.architectureConfig || {}), ...userConfig };
|
|
38
|
+
function renderTree(nodes, depth = 0, parentPath = '') {
|
|
39
|
+
let mdx = '';
|
|
40
|
+
for (const node of nodes) {
|
|
41
|
+
const nodePath = parentPath ? `${parentPath}/${node.name}` : node.name;
|
|
42
|
+
const anotion = architectureConfig[node.name] || '';
|
|
43
|
+
// scan root directory name='ROOT'
|
|
44
|
+
const displayName = (depth === 0 && node.name === '.') ? 'ROOT' : node.name;
|
|
45
|
+
if (node.type === 'directory') {
|
|
46
|
+
if (!node.contents || node.contents.length === 0) {
|
|
47
|
+
// handle empty folder
|
|
48
|
+
mdx += `${' '.repeat(depth)}<ZiaFolder name="${displayName}" anotion="${anotion}" className="opacity-50" disabled/>\n`;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
// handle non-empty folder
|
|
52
|
+
mdx += `${' '.repeat(depth)}<ZiaFolder name="${displayName}" anotion="${anotion}" defaultOpen>\n`;
|
|
53
|
+
mdx += renderTree(node.contents, depth + 1, nodePath);
|
|
54
|
+
mdx += `${' '.repeat(depth)}</ZiaFolder>\n`;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else if (node.type === 'file') {
|
|
58
|
+
mdx += `${' '.repeat(depth)}<ZiaFile name="${node.name}" anotion="${anotion}" href="" />\n`;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return mdx;
|
|
62
|
+
}
|
|
63
|
+
// generate frontmatter
|
|
64
|
+
const frontmatter = `---\ntitle: About Project Structure\ndescription: Show all source code directories and files\nicon: Gift\ndate: ${getCurrentDateString()}\n---\n\n## Quick Started\n\n`;
|
|
65
|
+
// generate mdx content
|
|
66
|
+
const filesContent = renderTree(tree);
|
|
67
|
+
const indentedFilesContent = filesContent.split('\n').map(line => line ? ' ' + line : '').join('\n');
|
|
68
|
+
const mdx = frontmatter + '<Files>\n' + indentedFilesContent + '</Files>\n';
|
|
69
|
+
// output to blog directory
|
|
70
|
+
const outputMdxPath = join(blogDir, 'nextjs-architecture.mdx');
|
|
71
|
+
writeFileSync(outputMdxPath, mdx);
|
|
72
|
+
logger.success(`Successfully generated ${outputMdxPath}`);
|
|
73
|
+
logger.saveToFile('generate-nextjs-architecture.log', cwd);
|
|
74
|
+
return 0;
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
logger.error(`Error generating nextjs architecture mdx: ${error}`);
|
|
78
|
+
return 1;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export { generateNextjsArchitecture };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { DevScriptsConfig } from '@dev-scripts/config/schema';
|
|
2
|
+
/**
|
|
3
|
+
* load full config
|
|
4
|
+
*/
|
|
5
|
+
export declare function loadConfig(cwd?: string, override?: Partial<DevScriptsConfig>, verbose?: boolean): DevScriptsConfig;
|
|
6
|
+
/**
|
|
7
|
+
* validate config
|
|
8
|
+
*/
|
|
9
|
+
export declare function validateConfig(config: DevScriptsConfig): void;
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,gBAAgB,EAAyB,MAAM,4BAA4B,CAAA;AA6FpG;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAA6D,EAAE,QAAQ,GAAE,OAAO,CAAC,gBAAgB,CAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAkC5K;AA2CD;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAY7D"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var fs = require('fs');
|
|
4
|
+
var path = require('path');
|
|
5
|
+
var schema = require('./schema.js');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* load config from package.json
|
|
9
|
+
*/
|
|
10
|
+
function loadPackageJsonConfig(cwd) {
|
|
11
|
+
try {
|
|
12
|
+
const packageJsonPath = path.join(cwd, 'package.json');
|
|
13
|
+
if (!fs.existsSync(packageJsonPath))
|
|
14
|
+
return null;
|
|
15
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
16
|
+
const devScripts = packageJson.devScripts;
|
|
17
|
+
// only return config if devScripts field actually exists
|
|
18
|
+
if (!devScripts || Object.keys(devScripts).length === 0) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
// convert to standard config format
|
|
22
|
+
const config = {};
|
|
23
|
+
if (devScripts.locales || devScripts.defaultLocale || devScripts.messageRoot) {
|
|
24
|
+
config.i18n = {
|
|
25
|
+
locales: devScripts.locales || schema.DEFAULT_CONFIG.i18n.locales,
|
|
26
|
+
defaultLocale: devScripts.defaultLocale || schema.DEFAULT_CONFIG.i18n.defaultLocale,
|
|
27
|
+
messageRoot: devScripts.messageRoot || schema.DEFAULT_CONFIG.i18n.messageRoot
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
if (devScripts.scanDirs) {
|
|
31
|
+
config.scan = {
|
|
32
|
+
include: devScripts.scanDirs,
|
|
33
|
+
exclude: schema.DEFAULT_CONFIG.scan.exclude
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
if (devScripts.blogDir) {
|
|
37
|
+
config.blog = {
|
|
38
|
+
mdxDir: devScripts.blogDir,
|
|
39
|
+
...schema.DEFAULT_CONFIG.blog
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
if (devScripts.logDir) {
|
|
43
|
+
config.output = {
|
|
44
|
+
logDir: devScripts.logDir,
|
|
45
|
+
verbose: schema.DEFAULT_CONFIG.output.verbose
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
return Object.keys(config).length > 0 ? config : null;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
console.warn(`Warning: Failed to load package.json config: ${error}`);
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* load config from dev-scripts.config.json file
|
|
57
|
+
*/
|
|
58
|
+
function loadConfigFile(cwd) {
|
|
59
|
+
try {
|
|
60
|
+
const configPath = path.join(cwd, 'dev-scripts.config.json');
|
|
61
|
+
if (!fs.existsSync(configPath)) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
console.warn(`Warning: Failed to load dev-scripts.config.json: ${error}`);
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* deep merge config object
|
|
73
|
+
*/
|
|
74
|
+
function mergeConfig(base, override) {
|
|
75
|
+
const result = { ...base };
|
|
76
|
+
for (const [key, value] of Object.entries(override)) {
|
|
77
|
+
if (value !== undefined && value !== null) {
|
|
78
|
+
if (typeof value === 'object' && !Array.isArray(value) && typeof result[key] === 'object') {
|
|
79
|
+
result[key] = { ...result[key], ...value };
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
result[key] = value;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* load full config
|
|
90
|
+
*/
|
|
91
|
+
function loadConfig(cwd = typeof process !== 'undefined' ? process.cwd() : '.', override = {}, verbose) {
|
|
92
|
+
let config = { ...schema.DEFAULT_CONFIG };
|
|
93
|
+
const configSources = [];
|
|
94
|
+
// 1. load dev-scripts.config.json
|
|
95
|
+
const fileConfig = loadConfigFile(cwd);
|
|
96
|
+
if (fileConfig) {
|
|
97
|
+
config = mergeConfig(config, fileConfig);
|
|
98
|
+
configSources.push('dev-scripts.config.json');
|
|
99
|
+
}
|
|
100
|
+
// 2. load package.json config
|
|
101
|
+
const packageConfig = loadPackageJsonConfig(cwd);
|
|
102
|
+
if (packageConfig) {
|
|
103
|
+
config = mergeConfig(config, packageConfig);
|
|
104
|
+
configSources.push('package.json');
|
|
105
|
+
}
|
|
106
|
+
// 3. apply any override config
|
|
107
|
+
config = mergeConfig(config, override);
|
|
108
|
+
if (Object.keys(override).length > 0) {
|
|
109
|
+
configSources.push('runtime override');
|
|
110
|
+
}
|
|
111
|
+
// 4. print config info in verbose mode
|
|
112
|
+
const shouldPrintConfig = verbose !== undefined ? verbose : config.output.verbose;
|
|
113
|
+
if (shouldPrintConfig) {
|
|
114
|
+
// temporarily set verbose for printing
|
|
115
|
+
const configForPrint = { ...config };
|
|
116
|
+
configForPrint.output = { ...config.output, verbose: true };
|
|
117
|
+
printConfigInfo(configForPrint, configSources, cwd);
|
|
118
|
+
}
|
|
119
|
+
return config;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* print config information in verbose mode
|
|
123
|
+
*/
|
|
124
|
+
function printConfigInfo(config, sources, cwd) {
|
|
125
|
+
console.log('\n📋 Config Information:');
|
|
126
|
+
console.log(` working directory: ${cwd}`);
|
|
127
|
+
console.log(` config sources: ${sources.length > 0 ? sources.join(' + ') : 'default config'}`);
|
|
128
|
+
console.log('\n🌐 i18n:');
|
|
129
|
+
console.log(` locales: [${config.i18n.locales.join(', ')}]`);
|
|
130
|
+
console.log(` defaultLocale: ${config.i18n.defaultLocale}`);
|
|
131
|
+
console.log(` messageRoot: ${config.i18n.messageRoot}`);
|
|
132
|
+
console.log('\n🔍 scan:');
|
|
133
|
+
console.log(` include: [${config.scan.include.join(', ')}]`);
|
|
134
|
+
if (config.scan.exclude && config.scan.exclude.length > 0) {
|
|
135
|
+
console.log(` exclude: [${config.scan.exclude.join(', ')}]`);
|
|
136
|
+
}
|
|
137
|
+
if (config.scan.baseDir) {
|
|
138
|
+
console.log(` baseDir: ${config.scan.baseDir}`);
|
|
139
|
+
}
|
|
140
|
+
if (config.blog) {
|
|
141
|
+
console.log('\n📝 blog:');
|
|
142
|
+
console.log(` mdxDir: ${config.blog.mdxDir}`);
|
|
143
|
+
console.log(` outputFile: ${config.blog.outputFile || 'index.mdx (default)'}`);
|
|
144
|
+
console.log(` metaFile: ${config.blog.metaFile || 'meta.json (default)'}`);
|
|
145
|
+
if (config.blog.iocSlug) {
|
|
146
|
+
console.log(` iocSlug: ${config.blog.iocSlug}`);
|
|
147
|
+
}
|
|
148
|
+
if (config.blog.prefix) {
|
|
149
|
+
console.log(` prefix: ${config.blog.prefix}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
console.log('\n📤 output:');
|
|
153
|
+
console.log(` logDir: ${config.output.logDir}`);
|
|
154
|
+
console.log(` verbose: ${config.output.verbose}`);
|
|
155
|
+
console.log('');
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* validate config
|
|
159
|
+
*/
|
|
160
|
+
function validateConfig(config) {
|
|
161
|
+
if (!config.i18n.locales || config.i18n.locales.length === 0) {
|
|
162
|
+
throw new Error('at least one language is required');
|
|
163
|
+
}
|
|
164
|
+
if (!config.i18n.locales.includes(config.i18n.defaultLocale)) {
|
|
165
|
+
throw new Error('default language must be in the supported language list');
|
|
166
|
+
}
|
|
167
|
+
if (config.scan.include.length === 0) {
|
|
168
|
+
throw new Error('at least one scan path is required');
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
exports.loadConfig = loadConfig;
|
|
173
|
+
exports.validateConfig = validateConfig;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { DEFAULT_CONFIG } from './schema.mjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* load config from package.json
|
|
7
|
+
*/
|
|
8
|
+
function loadPackageJsonConfig(cwd) {
|
|
9
|
+
try {
|
|
10
|
+
const packageJsonPath = path.join(cwd, 'package.json');
|
|
11
|
+
if (!fs.existsSync(packageJsonPath))
|
|
12
|
+
return null;
|
|
13
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
14
|
+
const devScripts = packageJson.devScripts;
|
|
15
|
+
// only return config if devScripts field actually exists
|
|
16
|
+
if (!devScripts || Object.keys(devScripts).length === 0) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
// convert to standard config format
|
|
20
|
+
const config = {};
|
|
21
|
+
if (devScripts.locales || devScripts.defaultLocale || devScripts.messageRoot) {
|
|
22
|
+
config.i18n = {
|
|
23
|
+
locales: devScripts.locales || DEFAULT_CONFIG.i18n.locales,
|
|
24
|
+
defaultLocale: devScripts.defaultLocale || DEFAULT_CONFIG.i18n.defaultLocale,
|
|
25
|
+
messageRoot: devScripts.messageRoot || DEFAULT_CONFIG.i18n.messageRoot
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
if (devScripts.scanDirs) {
|
|
29
|
+
config.scan = {
|
|
30
|
+
include: devScripts.scanDirs,
|
|
31
|
+
exclude: DEFAULT_CONFIG.scan.exclude
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
if (devScripts.blogDir) {
|
|
35
|
+
config.blog = {
|
|
36
|
+
mdxDir: devScripts.blogDir,
|
|
37
|
+
...DEFAULT_CONFIG.blog
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
if (devScripts.logDir) {
|
|
41
|
+
config.output = {
|
|
42
|
+
logDir: devScripts.logDir,
|
|
43
|
+
verbose: DEFAULT_CONFIG.output.verbose
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return Object.keys(config).length > 0 ? config : null;
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
console.warn(`Warning: Failed to load package.json config: ${error}`);
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* load config from dev-scripts.config.json file
|
|
55
|
+
*/
|
|
56
|
+
function loadConfigFile(cwd) {
|
|
57
|
+
try {
|
|
58
|
+
const configPath = path.join(cwd, 'dev-scripts.config.json');
|
|
59
|
+
if (!fs.existsSync(configPath)) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
console.warn(`Warning: Failed to load dev-scripts.config.json: ${error}`);
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* deep merge config object
|
|
71
|
+
*/
|
|
72
|
+
function mergeConfig(base, override) {
|
|
73
|
+
const result = { ...base };
|
|
74
|
+
for (const [key, value] of Object.entries(override)) {
|
|
75
|
+
if (value !== undefined && value !== null) {
|
|
76
|
+
if (typeof value === 'object' && !Array.isArray(value) && typeof result[key] === 'object') {
|
|
77
|
+
result[key] = { ...result[key], ...value };
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
result[key] = value;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* load full config
|
|
88
|
+
*/
|
|
89
|
+
function loadConfig(cwd = typeof process !== 'undefined' ? process.cwd() : '.', override = {}, verbose) {
|
|
90
|
+
let config = { ...DEFAULT_CONFIG };
|
|
91
|
+
const configSources = [];
|
|
92
|
+
// 1. load dev-scripts.config.json
|
|
93
|
+
const fileConfig = loadConfigFile(cwd);
|
|
94
|
+
if (fileConfig) {
|
|
95
|
+
config = mergeConfig(config, fileConfig);
|
|
96
|
+
configSources.push('dev-scripts.config.json');
|
|
97
|
+
}
|
|
98
|
+
// 2. load package.json config
|
|
99
|
+
const packageConfig = loadPackageJsonConfig(cwd);
|
|
100
|
+
if (packageConfig) {
|
|
101
|
+
config = mergeConfig(config, packageConfig);
|
|
102
|
+
configSources.push('package.json');
|
|
103
|
+
}
|
|
104
|
+
// 3. apply any override config
|
|
105
|
+
config = mergeConfig(config, override);
|
|
106
|
+
if (Object.keys(override).length > 0) {
|
|
107
|
+
configSources.push('runtime override');
|
|
108
|
+
}
|
|
109
|
+
// 4. print config info in verbose mode
|
|
110
|
+
const shouldPrintConfig = verbose !== undefined ? verbose : config.output.verbose;
|
|
111
|
+
if (shouldPrintConfig) {
|
|
112
|
+
// temporarily set verbose for printing
|
|
113
|
+
const configForPrint = { ...config };
|
|
114
|
+
configForPrint.output = { ...config.output, verbose: true };
|
|
115
|
+
printConfigInfo(configForPrint, configSources, cwd);
|
|
116
|
+
}
|
|
117
|
+
return config;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* print config information in verbose mode
|
|
121
|
+
*/
|
|
122
|
+
function printConfigInfo(config, sources, cwd) {
|
|
123
|
+
console.log('\n📋 Config Information:');
|
|
124
|
+
console.log(` working directory: ${cwd}`);
|
|
125
|
+
console.log(` config sources: ${sources.length > 0 ? sources.join(' + ') : 'default config'}`);
|
|
126
|
+
console.log('\n🌐 i18n:');
|
|
127
|
+
console.log(` locales: [${config.i18n.locales.join(', ')}]`);
|
|
128
|
+
console.log(` defaultLocale: ${config.i18n.defaultLocale}`);
|
|
129
|
+
console.log(` messageRoot: ${config.i18n.messageRoot}`);
|
|
130
|
+
console.log('\n🔍 scan:');
|
|
131
|
+
console.log(` include: [${config.scan.include.join(', ')}]`);
|
|
132
|
+
if (config.scan.exclude && config.scan.exclude.length > 0) {
|
|
133
|
+
console.log(` exclude: [${config.scan.exclude.join(', ')}]`);
|
|
134
|
+
}
|
|
135
|
+
if (config.scan.baseDir) {
|
|
136
|
+
console.log(` baseDir: ${config.scan.baseDir}`);
|
|
137
|
+
}
|
|
138
|
+
if (config.blog) {
|
|
139
|
+
console.log('\n📝 blog:');
|
|
140
|
+
console.log(` mdxDir: ${config.blog.mdxDir}`);
|
|
141
|
+
console.log(` outputFile: ${config.blog.outputFile || 'index.mdx (default)'}`);
|
|
142
|
+
console.log(` metaFile: ${config.blog.metaFile || 'meta.json (default)'}`);
|
|
143
|
+
if (config.blog.iocSlug) {
|
|
144
|
+
console.log(` iocSlug: ${config.blog.iocSlug}`);
|
|
145
|
+
}
|
|
146
|
+
if (config.blog.prefix) {
|
|
147
|
+
console.log(` prefix: ${config.blog.prefix}`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
console.log('\n📤 output:');
|
|
151
|
+
console.log(` logDir: ${config.output.logDir}`);
|
|
152
|
+
console.log(` verbose: ${config.output.verbose}`);
|
|
153
|
+
console.log('');
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* validate config
|
|
157
|
+
*/
|
|
158
|
+
function validateConfig(config) {
|
|
159
|
+
if (!config.i18n.locales || config.i18n.locales.length === 0) {
|
|
160
|
+
throw new Error('at least one language is required');
|
|
161
|
+
}
|
|
162
|
+
if (!config.i18n.locales.includes(config.i18n.defaultLocale)) {
|
|
163
|
+
throw new Error('default language must be in the supported language list');
|
|
164
|
+
}
|
|
165
|
+
if (config.scan.include.length === 0) {
|
|
166
|
+
throw new Error('at least one scan path is required');
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export { loadConfig, validateConfig };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface DevScriptsConfig {
|
|
2
|
+
i18n: {
|
|
3
|
+
locales: string[];
|
|
4
|
+
defaultLocale: string;
|
|
5
|
+
messageRoot: string;
|
|
6
|
+
};
|
|
7
|
+
scan: {
|
|
8
|
+
include: string[];
|
|
9
|
+
exclude?: string[];
|
|
10
|
+
baseDir?: string;
|
|
11
|
+
};
|
|
12
|
+
blog?: {
|
|
13
|
+
mdxDir: string;
|
|
14
|
+
outputFile?: string;
|
|
15
|
+
metaFile?: string;
|
|
16
|
+
iocSlug?: string;
|
|
17
|
+
prefix?: string;
|
|
18
|
+
};
|
|
19
|
+
output: {
|
|
20
|
+
logDir: string;
|
|
21
|
+
verbose?: boolean;
|
|
22
|
+
};
|
|
23
|
+
architectureConfig?: Record<string, string>;
|
|
24
|
+
}
|
|
25
|
+
export interface PackageJsonDevScripts {
|
|
26
|
+
locales?: string[];
|
|
27
|
+
defaultLocale?: string;
|
|
28
|
+
messageRoot?: string;
|
|
29
|
+
scanDirs?: string[];
|
|
30
|
+
blogDir?: string;
|
|
31
|
+
logDir?: string;
|
|
32
|
+
}
|
|
33
|
+
export declare const DEFAULT_CONFIG: DevScriptsConfig;
|
|
34
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAE/B,IAAI,EAAE;QACJ,OAAO,EAAE,MAAM,EAAE,CAAA;QACjB,aAAa,EAAE,MAAM,CAAA;QACrB,WAAW,EAAE,MAAM,CAAA;KACpB,CAAA;IAGD,IAAI,EAAE;QACJ,OAAO,EAAE,MAAM,EAAE,CAAA;QACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;QAClB,OAAO,CAAC,EAAE,MAAM,CAAA;KACjB,CAAA;IAGD,IAAI,CAAC,EAAE;QACL,MAAM,EAAE,MAAM,CAAA;QACd,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;IAGD,MAAM,EAAE;QACN,MAAM,EAAE,MAAM,CAAA;QACd,OAAO,CAAC,EAAE,OAAO,CAAA;KAClB,CAAA;IAGD,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC5C;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,eAAO,MAAM,cAAc,EAAE,gBA2E5B,CAAA"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const DEFAULT_CONFIG = {
|
|
4
|
+
i18n: {
|
|
5
|
+
locales: ['en', 'zh'],
|
|
6
|
+
defaultLocale: 'en',
|
|
7
|
+
messageRoot: 'messages'
|
|
8
|
+
},
|
|
9
|
+
scan: {
|
|
10
|
+
include: ['src/**/*.{tsx,ts,jsx,js}'],
|
|
11
|
+
exclude: ['src/**/*.d.ts', 'src/**/*.test.ts', 'src/**/*.test.tsx', 'node_modules/**']
|
|
12
|
+
},
|
|
13
|
+
blog: {
|
|
14
|
+
mdxDir: 'src/mdx/blog',
|
|
15
|
+
outputFile: 'index.mdx',
|
|
16
|
+
metaFile: 'meta.json',
|
|
17
|
+
iocSlug: 'ioc',
|
|
18
|
+
prefix: 'blog'
|
|
19
|
+
},
|
|
20
|
+
output: {
|
|
21
|
+
logDir: 'logs',
|
|
22
|
+
verbose: false
|
|
23
|
+
},
|
|
24
|
+
architectureConfig: {
|
|
25
|
+
".": "项目根目录",
|
|
26
|
+
".env.local": "本地环境变量配置",
|
|
27
|
+
".eslintrc.json": "ESLint 代码规范配置",
|
|
28
|
+
".gitignore": "Git忽略文件配置",
|
|
29
|
+
".source": "Fuma数据源Build产物",
|
|
30
|
+
"CHANGELOG.md": "变更记录",
|
|
31
|
+
"components.json": "组件依赖清单",
|
|
32
|
+
"dev-scripts.config.json": "dev-scripts脚本工具配置",
|
|
33
|
+
"LICENSE": "开源许可证",
|
|
34
|
+
"messages": "翻译目录",
|
|
35
|
+
"next-env.d.ts": "Next.js环境类型声明",
|
|
36
|
+
"next.config.ts": "Next.js项目配置",
|
|
37
|
+
"package.json": "项目依赖与脚本",
|
|
38
|
+
"postcss.config.mjs": "PostCSS 配置",
|
|
39
|
+
"source.config.ts": "Fuma数据源扫描配置",
|
|
40
|
+
"src": "源码目录",
|
|
41
|
+
"tsconfig.json": "TypeScript配置",
|
|
42
|
+
"tsconfig.node.json": "Node.js相关TypeScript 配置",
|
|
43
|
+
"logs": "日志输出目录",
|
|
44
|
+
"apps": "Monorepo多应用目录",
|
|
45
|
+
"packages": "子工程组件库目录",
|
|
46
|
+
"README.md": "项目说明文档",
|
|
47
|
+
"app": "Next.js 应用主入口目录",
|
|
48
|
+
"components": "页面组件",
|
|
49
|
+
"lib": "工具包",
|
|
50
|
+
"mdx": "FumaMDX文档",
|
|
51
|
+
"middleware.ts": "中间件入口",
|
|
52
|
+
"i18n.ts": "多语言配置",
|
|
53
|
+
"globals.css": "全局样式",
|
|
54
|
+
"layout.config.tsx": "布局配置",
|
|
55
|
+
"layout.tsx": "布局",
|
|
56
|
+
"loading.tsx": "全局加载组件",
|
|
57
|
+
"hero.tsx": "首页大字组件",
|
|
58
|
+
"mdx-components.tsx": "FumaMDX组件库(自定义)",
|
|
59
|
+
"llm-content": "FumaMDX复制接口",
|
|
60
|
+
"[locale]": "Nextjs i18n路由目录",
|
|
61
|
+
"(clerk)": "Clerk认证",
|
|
62
|
+
"(home)": "首页",
|
|
63
|
+
"[...catchAll]": "全局404页面",
|
|
64
|
+
"blog": "博客",
|
|
65
|
+
"docs": "文档",
|
|
66
|
+
"legal": "法律",
|
|
67
|
+
"api": "API接口",
|
|
68
|
+
"robots.ts": "robots.txt生成脚本",
|
|
69
|
+
"sitemap.ts": "网站地图",
|
|
70
|
+
"appConfig.ts": "应用全局配置",
|
|
71
|
+
"site-config.ts": "网站图标配置",
|
|
72
|
+
"ioc.mdx": "月度/统计",
|
|
73
|
+
"meta.json": "FumaMDX元数据",
|
|
74
|
+
"nextjs-architecture.mdx": "Next.js项目结构",
|
|
75
|
+
".github": "GitHub 配置目录",
|
|
76
|
+
"workflows": "CI/CD 工作流配置"
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
|