Skip to content

Commit 39966f2

Browse files
authored
Update packages and refactor to comply with afv07 (#113)
* Update packages and refactor to comply with afv07 * Support windows
1 parent d124b4e commit 39966f2

File tree

17 files changed

+3433
-3532
lines changed

17 files changed

+3433
-3532
lines changed

package-lock.json

Lines changed: 2902 additions & 3379 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,12 @@
2929
"tests/plugins/*"
3030
],
3131
"devDependencies": {
32-
"@types/cross-spawn": "6.0.6",
33-
"@types/jest": "^29.5.2",
34-
"@types/lodash": "^4.14.195",
35-
"del-cli": "^5.0.0",
32+
"@types/jest": "^29.5.14",
33+
"del-cli": "^6.0.0",
3634
"jest": "29.7.0",
37-
"lerna": "^7.0.2",
38-
"prettier": "^3.0.3",
39-
"typescript": "^5.1.3"
35+
"lerna": "^8.2.2",
36+
"prettier": "^3.5.3",
37+
"typescript": "^5.8.3"
4038
},
4139
"theme-json": {
4240
"src": "./tests/data/theme-json",

packages/create/package.json

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,19 @@
2929
"theme-json": "./dist/bin/theme-json.mjs"
3030
},
3131
"dependencies": {
32-
"chokidar": "^3.5.3",
33-
"cosmiconfig": "^8.1.3",
34-
"cross-spawn": "^7.0.3",
32+
"chokidar": "^4.0.3",
33+
"cosmiconfig": "^9.0.0",
34+
"cross-spawn": "^7.0.6",
3535
"deepmerge": "^4.3.1",
36-
"fast-glob": "^3.2.7",
37-
"lodash": "^4.17.21",
38-
"picocolors": "^1.0.0",
36+
"fast-glob": "^3.3.3",
37+
"picocolors": "^1.1.1",
3938
"slash": "^5.1.0"
4039
},
4140
"publishConfig": {
4241
"access": "public"
42+
},
43+
"devDependencies": {
44+
"@types/chokidar": "^1.7.5",
45+
"@types/cross-spawn": "^6.0.6"
4346
}
4447
}

packages/create/src/bin/theme-json.mts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
/**
44
* Internal dependencies
55
*/
6-
import { getNodeArgsFromCLI, spawnScript } from '../utils/index.mjs';
6+
import { getNodeArgsFromCLI, spawnScript } from '../utils/cli.mjs';
77

88
const { scriptName, scriptArgs, nodeArgs } = getNodeArgsFromCLI();
99

packages/create/src/lib/build.mts

Lines changed: 121 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -3,122 +3,157 @@
33
*/
44
import { readFileSync, writeFileSync } from 'node:fs';
55
import fastGlob from 'fast-glob';
6-
import _ from 'lodash';
7-
import pc from 'picocolors';
86
import deepMerge from 'deepmerge';
7+
import { pathToFileURL } from 'node:url';
98

109
/**
1110
* Internal dependencies
1211
*/
13-
import { getConfig, getPlugins, importFresh } from '../utils/index.mjs';
12+
import { getConfig, getPlugins, Config } from '../utils/config.mjs';
13+
import { logInfo, logError, logSuccess } from '../utils/logger.mjs';
14+
import {
15+
camelCase,
16+
setNestedValue,
17+
isEmpty,
18+
} from '../utils/object-helpers.mjs';
1419

1520
async function build() {
16-
const configs = await getConfig();
21+
try {
22+
const configs: Array<Config> = await getConfig();
1723

18-
for (const config of configs) {
19-
const { src, version } = config;
24+
// Assign default names if not provided
25+
configs.forEach((config, index) => {
26+
config.name = config.name || `config-${index}`;
27+
});
28+
29+
for (const config of configs) {
30+
logInfo(`Building theme.json for config: ${config.name}`);
31+
const themeJson = await generateThemeJson({
32+
...config,
33+
});
34+
writeFileSync(
35+
config.dest,
36+
JSON.stringify(themeJson, null, config.pretty ? '\t' : ''),
37+
);
38+
logSuccess(`theme.json created at ${config.dest}`);
39+
}
40+
} catch (error) {
41+
logError(
42+
'Error during build process',
43+
error instanceof Error ? error : undefined,
44+
);
45+
}
46+
}
47+
48+
async function generateThemeJson(config: Config) {
49+
try {
50+
const { src, version, addSchema, wpVersion } = config;
2051
const plugins = await getPlugins(config);
2152

22-
let initialThemeJson: any = {
23-
version,
24-
};
53+
let themeJson: { version: number; $schema?: string } = { version };
2554

26-
if (config.addSchema) {
55+
if (addSchema) {
2756
const schemaVersion =
28-
config.wpVersion === 'trunk'
29-
? 'trunk'
30-
: `wp/${config.wpVersion}`;
31-
initialThemeJson.$schema = `https://schemas.wp.org/${schemaVersion}/theme.json`;
57+
wpVersion === 'trunk' ? 'trunk' : `wp/${wpVersion}`;
58+
themeJson.$schema = `https://schemas.wp.org/${schemaVersion}/theme.json`;
3259
}
3360

34-
if (!!plugins.before.length) {
61+
if (plugins.before.length) {
3562
for (const plugin of plugins.before) {
36-
initialThemeJson = await plugin(initialThemeJson, config);
63+
themeJson = await plugin(themeJson, config);
3764
}
3865
}
3966

40-
const files = fastGlob.sync(src + '**/*', {
41-
ignore: [src + '**/*.temp-fresh-import.{mjs,cjs}'],
67+
const files = fastGlob.sync(`${src}**/*`, {
68+
ignore: [`${src}**/*.temp-fresh-import.{mjs,cjs}`],
4269
});
4370

44-
let themeJson = await files.reduce(async (previousValue, file) => {
45-
let nextValue = await previousValue;
46-
47-
try {
48-
let fileConfig;
49-
50-
if (file.endsWith('.cjs') || file.endsWith('.mjs')) {
51-
const importedFile = await importFresh(file);
52-
53-
fileConfig = importedFile.default;
54-
55-
if (typeof fileConfig === 'function') {
56-
fileConfig = fileConfig();
57-
}
58-
} else if (file.endsWith('.json')) {
59-
const content = readFileSync(file, {
60-
encoding: 'utf-8',
61-
});
62-
63-
fileConfig = JSON.parse(content);
64-
} else {
65-
console.log(
66-
pc.red(
67-
`${file.replace(
68-
src,
69-
'',
70-
)}: File not supported. Supported extensions are: json, cjs and mjs.\n`,
71-
),
72-
);
73-
process.exit(1);
74-
}
75-
76-
if (!_.isEmpty(fileConfig)) {
77-
const destination = file
78-
.replace(src, '')
79-
.replace(/\.[^/.]+$/, '');
80-
81-
const splittedDestination = destination.split('/blocks/');
82-
83-
if (splittedDestination[0]) {
84-
let dest = splittedDestination[0].split('/');
85-
dest = dest.map(_.camelCase);
86-
87-
if (splittedDestination[1]) {
88-
const [blockNamespace, blockName, ...blockDest] =
89-
splittedDestination[1].split('/');
90-
dest = [
91-
...dest,
92-
'blocks',
93-
`${blockNamespace}/${blockName}`,
94-
...blockDest,
95-
];
96-
}
97-
98-
const newNextValue = _.set({}, dest, fileConfig);
99-
nextValue = deepMerge(nextValue, newNextValue);
100-
}
101-
}
102-
} catch (err) {
103-
console.log(file, err);
71+
for (const file of files) {
72+
logInfo(`Processing file: ${file}`);
73+
const fileConfig = await processFile(file, src);
74+
if (fileConfig) {
75+
themeJson = {
76+
...deepMerge(themeJson, fileConfig),
77+
version: themeJson.version,
78+
};
10479
}
80+
}
10581

106-
return nextValue;
107-
}, Promise.resolve(initialThemeJson));
108-
109-
if (!!plugins.after.length) {
82+
if (plugins.after.length) {
11083
for (const plugin of plugins.after) {
11184
themeJson = await plugin(themeJson, config);
11285
}
11386
}
11487

115-
writeFileSync(
116-
config.dest,
117-
JSON.stringify(themeJson, null, config.pretty ? '\t' : ''),
88+
return themeJson;
89+
} catch (error) {
90+
logError(
91+
'Error generating theme.json',
92+
error instanceof Error ? error : undefined,
11893
);
94+
95+
throw error;
11996
}
97+
}
12098

121-
console.log(pc.green('🎉 theme.json created'));
99+
interface FileConfig {
100+
[key: string]: any;
101+
}
102+
103+
async function processFile(
104+
file: string,
105+
src: string,
106+
): Promise<FileConfig | undefined> {
107+
try {
108+
let fileConfig: FileConfig | undefined;
109+
110+
if (file.endsWith('.cjs') || file.endsWith('.mjs')) {
111+
// Convert the file path to a file:// URL
112+
const fileUrl = pathToFileURL(file);
113+
const importedFile = await import(fileUrl.href); // Use the file:// URL for dynamic import
114+
fileConfig = importedFile.default;
115+
116+
if (typeof fileConfig === 'function') {
117+
fileConfig = fileConfig();
118+
}
119+
} else if (file.endsWith('.json')) {
120+
const content = readFileSync(file, { encoding: 'utf-8' });
121+
fileConfig = JSON.parse(content) as FileConfig;
122+
} else {
123+
throw new Error(`Unsupported file type: ${file}`);
124+
}
125+
126+
if (fileConfig && !isEmpty(fileConfig)) {
127+
const destination = file.replace(src, '').replace(/\.[^/.]+$/, '');
128+
const splittedDestination = destination.split('/blocks/');
129+
130+
let dest: string[] = (splittedDestination[0] ?? '')
131+
.split('/')
132+
.map(camelCase);
133+
134+
if (splittedDestination[1]) {
135+
const [blockNamespace, blockName, ...blockDest] =
136+
splittedDestination[1].split('/');
137+
dest = [
138+
...dest,
139+
'blocks',
140+
`${blockNamespace}/${blockName}`,
141+
...blockDest,
142+
];
143+
}
144+
145+
return setNestedValue({}, dest, fileConfig);
146+
}
147+
148+
return undefined; // Explicitly return undefined if no fileConfig is found
149+
} catch (error) {
150+
logError(
151+
`Error processing file: ${file}`,
152+
error instanceof Error ? error : undefined,
153+
);
154+
155+
throw error;
156+
}
122157
}
123158

124159
export default build;

packages/create/src/scripts/build.mts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,22 @@
22
* Internal dependencies
33
*/
44
import build from '../lib/build.mjs';
5+
import { logInfo, logError, logSuccess } from '../utils/logger.mjs';
56

6-
build();
7+
/**
8+
* Executes the build process.
9+
*/
10+
async function executeBuild() {
11+
try {
12+
logInfo('Starting build process...');
13+
await build();
14+
logSuccess('Build process completed successfully.');
15+
} catch (error) {
16+
logError(
17+
'Error during build process',
18+
error instanceof Error ? error : undefined,
19+
);
20+
}
21+
}
22+
23+
executeBuild();

0 commit comments

Comments
 (0)