chisel-scripts 2.1.4 → 2.2.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/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  <!-- INSERT-NEW-ENTRIES-HERE -->
4
4
 
5
+ ## 2.2.0 (2026-02-09)
6
+
7
+ - chisel update scripts and husky precommit hooks ([31c1019](https://github.com/xfiveco/generator-chisel/commit/31c1019))
8
+ - Webpack config chnages: client ovarlay, nvmrc update, composer packages version update ([a07c16c](https://github.com/xfiveco/generator-chisel/commit/a07c16c))
9
+
10
+ ## <small>2.1.5 (2026-01-02)</small>
11
+
12
+ - wp-config-updates, wp/scripts lt, icons module define in functions.php ([3c97c63](https://github.com/xfiveco/generator-chisel/commit/3c97c63))
13
+
5
14
  ## <small>2.1.4 (2025-12-17)</small>
6
15
 
7
16
  - fix no experimental dev mode runtime chunk ([84817eb](https://github.com/xfiveco/generator-chisel/commit/84817eb))
package/composer.phar CHANGED
Binary file
package/index.js CHANGED
@@ -60,6 +60,15 @@ function adjustWebpackConfig(baseConfig, directory) {
60
60
  })();
61
61
 
62
62
  const preparedConfig = (config, index = null) => {
63
+ const devSeverClient = config.devServer ? {
64
+ ...config.devServer.client,
65
+ overlay: {
66
+ errors: true,
67
+ warnings: false,
68
+ runtimeErrors: false,
69
+ },
70
+ } : {}
71
+
63
72
  return {
64
73
  ...config,
65
74
  output: {
@@ -80,17 +89,15 @@ function adjustWebpackConfig(baseConfig, directory) {
80
89
  },
81
90
  devServer: config.devServer && {
82
91
  ...config.devServer,
92
+ client: {
93
+ ...devSeverClient,
94
+ },
83
95
  allowedHosts: [new URL(getUrl()).host],
84
96
  ...(process.env.CHISEL_PORT && {
85
97
  host: '0.0.0.0',
86
98
  port: Number(process.env.CHISEL_PORT) + 1,
87
99
  client: {
88
- ...config.devServer.client,
89
- overlay: {
90
- errors: true,
91
- warnings: false,
92
- runtimeErrors: false,
93
- },
100
+ ...devSeverClient,
94
101
  webSocketURL: new URL(getUrl())
95
102
  .toString()
96
103
  .replace(process.env.CHISEL_PORT, Number(process.env.CHISEL_PORT) + 1),
package/lib/Service.js CHANGED
@@ -27,6 +27,8 @@ module.exports = class Service {
27
27
 
28
28
  const builtInPlugins = [
29
29
  'wp-scripts.mjs', // start, build
30
+ 'chisel-update.mjs', // check-chisel-update, chisel-update
31
+ 'husky-init.mjs', // husky-init
30
32
  'composer',
31
33
  'wp',
32
34
  'wp-config',
@@ -0,0 +1,282 @@
1
+ import https from 'https';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+
5
+ // GitHub repository configuration
6
+ const REPO = 'xfiveco/generator-chisel';
7
+ const REF = 'v2';
8
+ const THEME_PATH =
9
+ 'packages/generator-chisel/lib/commands/create/creators/app/chisel-starter-theme';
10
+
11
+ // URLs
12
+ const STYLE_REMOTE_PATH = `${THEME_PATH}/style.chisel-tpl.css`;
13
+ const STYLE_URL = `https://raw.githubusercontent.com/${REPO}/${REF}/${STYLE_REMOTE_PATH}`;
14
+
15
+ /**
16
+ * List of paths to update from the Chisel repository.
17
+ * Can be folders or files.
18
+ */
19
+ const PATHS_TO_UPDATE = [
20
+ 'core',
21
+ // Add more folders/files here in the future
22
+ ];
23
+
24
+ // Map of remote names to local names if they differ
25
+ const NAME_MAPPING = {
26
+ 'style.chisel-tpl.css': 'style.css',
27
+ };
28
+
29
+ const DEFAULT_OPTIONS = {
30
+ headers: {
31
+ 'User-Agent': 'Chisel-Update-Script',
32
+ },
33
+ };
34
+
35
+ const VERSION_REGEX = /(Version:\s*)([0-9]+\.[0-9]+\.[0-9]+)/i;
36
+
37
+ // ============================================================================
38
+ // HTTP Utilities
39
+ // ============================================================================
40
+
41
+ function request(url, options = {}) {
42
+ return new Promise((resolve, reject) => {
43
+ const req = https.get(url, { ...DEFAULT_OPTIONS, ...options }, (res) => {
44
+ if (res.statusCode === 301 || res.statusCode === 302) {
45
+ return resolve(request(res.headers.location, options));
46
+ }
47
+ if (res.statusCode < 200 || res.statusCode >= 300) {
48
+ return reject(new Error(`Status Code: ${res.statusCode} for ${url}`));
49
+ }
50
+ const data = [];
51
+ res.on('data', (chunk) => data.push(chunk));
52
+ res.on('end', () => resolve(Buffer.concat(data)));
53
+ });
54
+ req.on('error', reject);
55
+ });
56
+ }
57
+
58
+ async function fetchText(url) {
59
+ const buffer = await request(url);
60
+ return buffer.toString();
61
+ }
62
+
63
+ async function fetchJson(url) {
64
+ const buffer = await request(url);
65
+ return JSON.parse(buffer.toString());
66
+ }
67
+
68
+ // ============================================================================
69
+ // Version Utilities
70
+ // ============================================================================
71
+
72
+ function extractVersion(css) {
73
+ const match = css.match(VERSION_REGEX);
74
+ return match ? match[2] : null;
75
+ }
76
+
77
+ function readLocalVersion(filePath) {
78
+ if (!fs.existsSync(filePath)) return null;
79
+ return extractVersion(fs.readFileSync(filePath, 'utf8'));
80
+ }
81
+
82
+ function updateLocalVersion(filePath, newVersion) {
83
+ if (!fs.existsSync(filePath)) {
84
+ console.error(`File not found: ${filePath}`);
85
+ return false;
86
+ }
87
+
88
+ const content = fs.readFileSync(filePath, 'utf8');
89
+ if (!VERSION_REGEX.test(content)) {
90
+ console.error(`Version pattern not found in: ${filePath}`);
91
+ return false;
92
+ }
93
+
94
+ const updatedContent = content.replace(VERSION_REGEX, `$1${newVersion}`);
95
+ fs.writeFileSync(filePath, updatedContent);
96
+ return true;
97
+ }
98
+
99
+ function compareVersions(a, b) {
100
+ const pa = a.split('.').map(Number);
101
+ const pb = b.split('.').map(Number);
102
+
103
+ for (let i = 0; i < 3; i++) {
104
+ if ((pa[i] || 0) > (pb[i] || 0)) return 1;
105
+ if ((pa[i] || 0) < (pb[i] || 0)) return -1;
106
+ }
107
+
108
+ return 0;
109
+ }
110
+
111
+ // ============================================================================
112
+ // Update Functions
113
+ // ============================================================================
114
+
115
+ async function downloadFile(url, destPath) {
116
+ const buffer = await request(url);
117
+ fs.mkdirSync(path.dirname(destPath), { recursive: true });
118
+ fs.writeFileSync(destPath, buffer);
119
+ }
120
+
121
+ async function updateFolder(remoteFolderPath, localFolderPath) {
122
+ console.log(`📂 Updating folder: ${path.basename(remoteFolderPath)}`);
123
+
124
+ const apiUrl = `https://api.github.com/repos/${REPO}/contents/${remoteFolderPath}?ref=${REF}`;
125
+ let items;
126
+
127
+ try {
128
+ items = await fetchJson(apiUrl);
129
+ } catch (err) {
130
+ if (err.message.includes('404')) {
131
+ console.warn(`⚠️ Remote folder not found: ${remoteFolderPath}`);
132
+ return;
133
+ }
134
+ throw err;
135
+ }
136
+
137
+ if (!Array.isArray(items)) {
138
+ if (items.type === 'file') {
139
+ await downloadFile(items.download_url, localFolderPath);
140
+ return;
141
+ }
142
+ throw new Error(
143
+ `Expected array of items from GitHub API, got: ${typeof items}`,
144
+ );
145
+ }
146
+
147
+ for (const item of items) {
148
+ const localItemPath = path.join(localFolderPath, item.name);
149
+
150
+ if (item.type === 'file') {
151
+ console.log(` 📄 ${item.name}`);
152
+ await downloadFile(item.download_url, localItemPath);
153
+ } else if (item.type === 'dir') {
154
+ await updateFolder(item.path, localItemPath);
155
+ }
156
+ }
157
+ }
158
+
159
+ async function updateFile(remotePath, localPath) {
160
+ console.log(` 📄 Updating file: ${path.basename(remotePath)}`);
161
+ const downloadUrl = `https://raw.githubusercontent.com/${REPO}/${REF}/${remotePath}`;
162
+ await downloadFile(downloadUrl, localPath);
163
+ }
164
+
165
+ async function syncStyleVersion(localStylePath) {
166
+ console.log('\n📋 Syncing style.css version...');
167
+
168
+ const localVersion = readLocalVersion(localStylePath);
169
+ const remoteCss = await fetchText(STYLE_URL);
170
+ const remoteVersion = extractVersion(remoteCss);
171
+
172
+ if (!remoteVersion) {
173
+ console.warn('⚠️ Could not fetch remote version.');
174
+ return;
175
+ }
176
+
177
+ if (!localVersion) {
178
+ console.warn('⚠️ Local version not found in style.css.');
179
+ return;
180
+ }
181
+
182
+ if (compareVersions(remoteVersion, localVersion) > 0) {
183
+ if (updateLocalVersion(localStylePath, remoteVersion)) {
184
+ console.log(` ✔ Version updated: ${localVersion} → ${remoteVersion}`);
185
+ }
186
+ } else {
187
+ console.log(` ✔ Version is already up to date (${localVersion})`);
188
+ }
189
+ }
190
+
191
+ // ============================================================================
192
+ // Command Registration
193
+ // ============================================================================
194
+
195
+ export default function chiselUpdate(api) {
196
+ api.registerCommand(
197
+ 'check-chisel-update',
198
+ (command) =>
199
+ command.description('check if a new Chisel version is available'),
200
+ async () => {
201
+ const localStylePath = api.resolve('style.css');
202
+
203
+ try {
204
+ const localVersion = readLocalVersion(localStylePath);
205
+
206
+ if (!localVersion) {
207
+ console.log(
208
+ '⚠️ Local version not found. Consider running `chisel-scripts update`.',
209
+ );
210
+ return;
211
+ }
212
+
213
+ console.log(`Local version: ${localVersion}`);
214
+
215
+ const remoteCss = await fetchText(STYLE_URL);
216
+ const remoteVersion = extractVersion(remoteCss);
217
+
218
+ if (!remoteVersion) {
219
+ console.log('⚠️ Could not fetch remote version.');
220
+ return;
221
+ }
222
+
223
+ if (compareVersions(remoteVersion, localVersion) > 0) {
224
+ console.log(
225
+ `\n⬆️ Update available: ${localVersion} → ${remoteVersion}`,
226
+ );
227
+ console.log(`Run 'chisel-scripts update' to update.`);
228
+ } else {
229
+ console.log(`✔ Chisel is up to date (${localVersion})`);
230
+ }
231
+ } catch (err) {
232
+ console.error('❌ Version check failed:', err.message);
233
+ process.exit(1);
234
+ }
235
+ },
236
+ );
237
+
238
+ api.registerCommand(
239
+ 'chisel-update',
240
+ (command) =>
241
+ command
242
+ .description('update Chisel core files from the repository')
243
+ .option('--skip-version-sync', 'skip syncing version in style.css'),
244
+ async (options) => {
245
+ const localBasePath = api.resolve();
246
+ const localStylePath = api.resolve('style.css');
247
+
248
+ console.log('🚀 Starting Chisel update...\n');
249
+
250
+ try {
251
+ // Update configured paths
252
+ for (const item of PATHS_TO_UPDATE) {
253
+ const remotePath = `${THEME_PATH}/${item}`;
254
+ const localName = NAME_MAPPING[item] || item;
255
+ const localPath = path.join(localBasePath, localName);
256
+
257
+ if (item.includes('.')) {
258
+ await updateFile(remotePath, localPath);
259
+ } else {
260
+ await updateFolder(remotePath, localPath);
261
+ }
262
+ }
263
+
264
+ // Sync version in style.css
265
+ if (!options.skipVersionSync) {
266
+ await syncStyleVersion(localStylePath);
267
+ }
268
+
269
+ console.log('\n✅ Update completed successfully!');
270
+ console.log(
271
+ 'Note: Local files that do not exist in the repository (e.g., custom files) were preserved.',
272
+ );
273
+ } catch (err) {
274
+ console.error('\n❌ Update failed:', err.message);
275
+ if (err.message.includes('403')) {
276
+ console.error('Note: This might be due to GitHub API rate limits.');
277
+ }
278
+ process.exit(1);
279
+ }
280
+ },
281
+ );
282
+ }
@@ -15,7 +15,7 @@ module.exports = (api) => {
15
15
 
16
16
  const targetDir = api.resolve(
17
17
  'src',
18
- template === 'acf' ? 'acf-blocks' : 'blocks',
18
+ template === 'acf' ? 'blocks-acf' : 'blocks',
19
19
  );
20
20
 
21
21
  const maybeTemplatePath =
@@ -0,0 +1,123 @@
1
+ import { execSync } from 'child_process';
2
+ import path from 'path';
3
+ import fs from 'fs';
4
+
5
+ /**
6
+ * Get the git root directory
7
+ * @param {string} cwd - Current working directory
8
+ * @returns {string|null} - Git root path or null if not in a git repo
9
+ */
10
+ function getGitRoot(cwd) {
11
+ try {
12
+ const result = execSync('git rev-parse --show-toplevel', {
13
+ cwd,
14
+ encoding: 'utf8',
15
+ stdio: ['pipe', 'pipe', 'pipe'],
16
+ });
17
+ return result.trim().replace(/\\/g, '/');
18
+ } catch {
19
+ return null;
20
+ }
21
+ }
22
+
23
+ /**
24
+ * Get relative path from git root to a target directory
25
+ * @param {string} gitRoot - Git root directory
26
+ * @param {string} targetDir - Target directory
27
+ * @returns {string} - Relative path
28
+ */
29
+ function getRelativePath(gitRoot, targetDir) {
30
+ // Normalize paths
31
+ const normalizedGitRoot = path.resolve(gitRoot).replace(/\\/g, '/');
32
+ const normalizedTarget = path.resolve(targetDir).replace(/\\/g, '/');
33
+
34
+ // Get relative path
35
+ return path.relative(normalizedGitRoot, normalizedTarget).replace(/\\/g, '/');
36
+ }
37
+
38
+ export default function huskyInit(api) {
39
+ api.registerCommand(
40
+ 'husky-init',
41
+ (command) =>
42
+ command
43
+ .description('initialize Husky git hooks for this theme')
44
+ .option('--force', 'force initialization even if already configured'),
45
+ async (options) => {
46
+ const themeDir = api.resolve();
47
+ const huskyDir = api.resolve('.husky');
48
+
49
+ // Check if .husky directory exists
50
+ if (!fs.existsSync(huskyDir)) {
51
+ console.error('❌ .husky directory not found in theme folder.');
52
+ console.error(' Make sure the theme was properly generated.');
53
+ process.exit(1);
54
+ }
55
+
56
+ // Find git root
57
+ const gitRoot = getGitRoot(themeDir);
58
+
59
+ if (!gitRoot) {
60
+ console.error('❌ Not inside a git repository.');
61
+ console.error(' Please run "git init" first at your project root.');
62
+ process.exit(1);
63
+ }
64
+
65
+ console.log(`📂 Git root: ${gitRoot}`);
66
+ console.log(`📁 Theme dir: ${themeDir}`);
67
+
68
+ // Calculate relative path from git root to .husky
69
+ const relativePath = getRelativePath(gitRoot, huskyDir);
70
+ console.log(`🔗 Husky path (relative to git root): ${relativePath}`);
71
+
72
+ // Check if husky is already configured
73
+ try {
74
+ const currentHooksPath = execSync('git config core.hooksPath', {
75
+ cwd: themeDir,
76
+ encoding: 'utf8',
77
+ stdio: ['pipe', 'pipe', 'pipe'],
78
+ }).trim();
79
+
80
+ if (currentHooksPath && !options.force) {
81
+ console.log(`\n✔ Husky is already configured.`);
82
+ console.log(` Current hooks path: ${currentHooksPath}`);
83
+ console.log(` Use --force to reconfigure.`);
84
+ return;
85
+ }
86
+ } catch {
87
+ // Not configured yet, continue
88
+ }
89
+
90
+ // Run husky from git root with the relative path
91
+ console.log('\n🚀 Initializing Husky...');
92
+
93
+ // Run husky with the relative path
94
+ try {
95
+ execSync(`npx husky ${relativePath}`, {
96
+ cwd: gitRoot,
97
+ stdio: 'inherit',
98
+ });
99
+ } catch (error) {
100
+ console.error('\n❌ Husky initialization failed.');
101
+ process.exit(1);
102
+ }
103
+
104
+
105
+ // Verify configuration
106
+ try {
107
+ const hooksPath = execSync('git config core.hooksPath', {
108
+ cwd: themeDir,
109
+ encoding: 'utf8',
110
+ stdio: ['pipe', 'pipe', 'pipe'],
111
+ }).trim();
112
+
113
+ console.log(`\n✅ Husky initialized successfully!`);
114
+ console.log(` Git hooks path: ${hooksPath}`);
115
+ console.log(
116
+ `\n Pre-commit hook will now protect core/ folder modifications.`,
117
+ );
118
+ } catch {
119
+ console.log(`\n✅ Husky initialized.`);
120
+ }
121
+ },
122
+ );
123
+ }
@@ -1 +1 @@
1
- 20.12.2
1
+ 24.11.1
@@ -0,0 +1,117 @@
1
+ <?php
2
+ /**
3
+ * The base configuration for WordPress
4
+ *
5
+ * The wp-config.php creation script uses this file during the
6
+ * installation. You don't have to use the web site, you can
7
+ * copy this file to "wp-config.php" and fill in the values.
8
+ *
9
+ * This file contains the following configurations:
10
+ *
11
+ * * MySQL settings
12
+ * * Secret keys
13
+ * * Database table prefix
14
+ * * ABSPATH
15
+ *
16
+ * @link https://codex.wordpress.org/Editing_wp-config.php
17
+ *
18
+ * @package WordPress
19
+ */
20
+
21
+ if ( file_exists( dirname( __FILE__ ) . '/wp-config-local.php' ) ) {
22
+
23
+ /**
24
+ * Settings for local environment loaded if available from wp-config-local.php
25
+ */
26
+
27
+ include dirname( __FILE__ ) . '/wp-config-local.php';
28
+
29
+ } else {
30
+
31
+ /**
32
+ * Settings for non-local environments, used when wp-config-local.php not available
33
+ */
34
+
35
+ /** MySQL settings - You can get this info from your web host */
36
+
37
+ /** The name of the database for WordPress */
38
+ define( 'DB_NAME', $_SERVER['DB_NAME'] );
39
+
40
+ /** MySQL database username */
41
+ define( 'DB_USER', $_SERVER['DB_USER'] );
42
+
43
+ /** MySQL database password */
44
+ define( 'DB_PASSWORD', $_SERVER['DB_PASSWORD'] );
45
+
46
+ /** MySQL hostname */
47
+ define( 'DB_HOST', $_SERVER['DB_HOST'] );
48
+
49
+ /**
50
+ * WordPress Database Table prefix.
51
+ *
52
+ * You can have multiple installations in one database if you give each
53
+ * a unique prefix. Only numbers, letters, and underscores please!
54
+ */
55
+ $table_prefix = '<%= tablePrefix %>';
56
+
57
+ /**
58
+ * For developers: WordPress debugging mode.
59
+ *
60
+ * Change this to true to enable the display of notices during development.
61
+ * It is strongly recommended that plugin and theme developers use WP_DEBUG
62
+ * in their development environments.
63
+ *
64
+ * For information on other constants that can be used for debugging,
65
+ * visit the Codex.
66
+ *
67
+ * @link https://codex.wordpress.org/Debugging_in_WordPress
68
+ */
69
+ define( 'WP_DEBUG', false );
70
+
71
+ /** The Database Collate type. Don't change this if in doubt. */
72
+ define( 'DB_COLLATE', '' );
73
+
74
+ /** Disable the Plugin and Theme Editor */
75
+ define( 'DISALLOW_FILE_EDIT', true );
76
+ }
77
+
78
+ /**
79
+ * Configuration for all available environments
80
+ */
81
+
82
+ /** Database Charset to use in creating database tables. */
83
+ define( 'DB_CHARSET', 'utf8' );
84
+
85
+ /**#@+
86
+ * Authentication Unique Keys and Salts.
87
+ *
88
+ * Change these to different unique phrases!
89
+ * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
90
+ * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
91
+ *
92
+ * @since 2.6.0
93
+ */
94
+ define('AUTH_KEY', 'put your unique phrase here');
95
+ define('SECURE_AUTH_KEY', 'put your unique phrase here');
96
+ define('LOGGED_IN_KEY', 'put your unique phrase here');
97
+ define('NONCE_KEY', 'put your unique phrase here');
98
+ define('AUTH_SALT', 'put your unique phrase here');
99
+ define('SECURE_AUTH_SALT', 'put your unique phrase here');
100
+ define('LOGGED_IN_SALT', 'put your unique phrase here');
101
+ define('NONCE_SALT', 'put your unique phrase here');
102
+
103
+ /**#@-*/
104
+
105
+ /* That's all, stop editing! Happy blogging. */
106
+
107
+ /** Hide PHP errors */
108
+ if ( !WP_DEBUG ) {
109
+ ini_set( 'display_errors', 0 );
110
+ }
111
+
112
+ /** Absolute path to the WordPress directory. */
113
+ if ( !defined('ABSPATH') )
114
+ define( 'ABSPATH', dirname(__FILE__) . '/' );
115
+
116
+ /** Sets up WordPress vars and included files. */
117
+ require_once( ABSPATH . 'wp-settings.php' );
@@ -57,8 +57,5 @@ define( 'WP_DEBUG_DISPLAY', false );
57
57
  define( 'SCRIPT_DEBUG', true );
58
58
  define( 'WP_ENVIRONMENT_TYPE', 'development' );
59
59
 
60
- // Icons module. Also requires packacke.json and scss configuration.
61
- define( 'CHISEL_USE_ICONS_MODULE', false );
62
-
63
60
  /** The Database Collate type. Don't change this if in doubt. */
64
61
  define( 'DB_COLLATE', '' );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chisel-scripts",
3
- "version": "2.1.4",
3
+ "version": "2.2.0",
4
4
  "description": "Chisel scripts",
5
5
  "bin": {
6
6
  "chisel-scripts": "bin/chisel-scripts.js"
@@ -37,7 +37,7 @@
37
37
  "svgo": "^3.3.2"
38
38
  },
39
39
  "peerDependencies": {
40
- "@wordpress/scripts": "^27.9.0 || ^31.0.0 || ^31.1.0"
40
+ "@wordpress/scripts": "^27.9.0 || ^31.0.0 || ^31.1.0 || ^31.2.0"
41
41
  },
42
- "gitHead": "0e9815944ac4188917808f5f4ea981b853294708"
42
+ "gitHead": "259173a22a8cb7a7380936bfc01baf4b87f6afa3"
43
43
  }