core-maugli 1.2.50 → 1.2.52

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/.gitignore CHANGED
@@ -23,13 +23,32 @@ pnpm-debug.log*
23
23
  # Кеш типографа
24
24
  .typograf-cache.json
25
25
 
26
- # Игнорировать все автогенерируемые изображения
27
- # Адаптивные ресайзы
26
+ # Игнорируем автогенерируемые изображения разных размеров (все форматы)
28
27
  public/**/*-400.webp
29
- public/**/*-800.webp
28
+ public/**/*-800.webp
30
29
  public/**/*-1200.webp
31
-
32
- # Оптимизированные версии (с суффиксом _optimized)
30
+ public/**/*-400.png
31
+ public/**/*-800.png
32
+ public/**/*-1200.png
33
+ public/**/*-400.jpg
34
+ public/**/*-800.jpg
35
+ public/**/*-1200.jpg
36
+ public/**/*-400.jpeg
37
+ public/**/*-800.jpeg
38
+ public/**/*-1200.jpeg
39
+ # Игнорируем дубликаты (если вдруг появятся)
40
+ public/**/*-400-*.webp
41
+ public/**/*-800-*.webp
42
+ public/**/*-1200-*.webp
43
+ public/**/*-400-*.png
44
+ public/**/*-800-*.png
45
+ public/**/*-1200-*.png
46
+ public/**/*-400-*.jpg
47
+ public/**/*-800-*.jpg
48
+ public/**/*-1200-*.jpg
49
+ public/**/*-400-*.jpeg
50
+ public/**/*-800-*.jpeg
51
+ public/**/*-1200-*.jpeg# Оптимизированные версии (с суффиксом _optimized)
33
52
  public/**/*_optimized.webp
34
53
 
35
54
  # Вынесенные из подпапок изображения с префиксами
package/bin/init.js CHANGED
@@ -93,6 +93,16 @@ function updateConfig(targetDir, lang, repoUrl) {
93
93
  if (repoUrl) {
94
94
  console.log(`Configured repository URL to ${repoUrl}`);
95
95
  }
96
+
97
+ // Create netlify.toml for new blog
98
+ try {
99
+ execSync('npm run init-netlify', {
100
+ cwd: targetDir,
101
+ stdio: 'pipe'
102
+ });
103
+ } catch (error) {
104
+ console.log('Note: netlify.toml will be created on npm install');
105
+ }
96
106
  }
97
107
 
98
108
  export default async function init(targetName, langOption, repoOption) {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "core-maugli",
3
3
  "description": "Astro & Tailwind CSS blog theme for Maugli.",
4
4
  "type": "module",
5
- "version": "1.2.50",
5
+ "version": "1.2.52",
6
6
  "license": "GPL-3.0-or-later OR Commercial",
7
7
  "repository": {
8
8
  "type": "git",
@@ -40,9 +40,9 @@
40
40
  "check-version": "node scripts/check-version.js",
41
41
  "auto-update": "node scripts/auto-update.js",
42
42
  "build:ci": "SKIP_VERSION_CHECK=true npm run build",
43
- "generate-netlify": "node scripts/copy-netlify-config.js",
43
+ "init-netlify": "node scripts/copy-netlify-config.js",
44
44
  "set-force-update": "node scripts/set-force-update.js",
45
- "postinstall": "node scripts/upgrade-config.js && node scripts/setup-user-images.js && node scripts/copy-netlify-config.js",
45
+ "postinstall": "node scripts/upgrade-config.js && node scripts/setup-user-images.js",
46
46
  "generate-previews": "node scripts/generate-previews.js"
47
47
  },
48
48
  "dependencies": {
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Очищает ресайзеные изображения из git
5
+ * Удаляет уже закоммиченные файлы с суффиксами -400, -800, -1200
6
+ */
7
+
8
+ import { execSync } from 'child_process';
9
+
10
+ function main() {
11
+ try {
12
+ console.log('🧹 Cleaning resized images from git...');
13
+
14
+ // Ищем все ресайзеные изображения в git
15
+ let resizedFiles;
16
+ try {
17
+ resizedFiles = execSync('git ls-files | grep -E ".*-(400|800|1200)\\.webp$"', { encoding: 'utf8' });
18
+ } catch (error) {
19
+ console.log('✅ No resized images found in git - nothing to clean');
20
+ return;
21
+ }
22
+
23
+ if (!resizedFiles.trim()) {
24
+ console.log('✅ No resized images found in git - nothing to clean');
25
+ return;
26
+ }
27
+
28
+ const files = resizedFiles.trim().split('\n');
29
+ console.log(`📋 Found ${files.length} resized images in git:`);
30
+ files.forEach(file => console.log(` 🗑️ ${file}`));
31
+
32
+ // Удаляем файлы из git индекса (но оставляем на диске)
33
+ const filesString = files.join(' ');
34
+ execSync(`git rm --cached ${filesString}`, { encoding: 'utf8' });
35
+
36
+ console.log(`✅ Removed ${files.length} resized images from git`);
37
+ console.log('💡 Files remain on disk but will be ignored by git');
38
+ console.log('');
39
+ console.log('📝 Next steps:');
40
+ console.log(' 1. git add .gitignore');
41
+ console.log(' 2. git commit -m "chore: remove resized images from git"');
42
+ console.log('');
43
+ console.log('🔄 Resized images will be regenerated automatically during build');
44
+
45
+ } catch (error) {
46
+ console.error('❌ Error cleaning resized images:', error.message);
47
+ console.log('💡 You can manually run: git rm --cached public/**/*-{400,800,1200}.webp');
48
+ }
49
+ }
50
+
51
+ main();
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Простое копирование netlify.toml из пакета core-maugli
5
+ */
6
+
7
+ import fs from 'fs';
8
+ import path from 'path';
9
+ import { fileURLToPath } from 'url';
10
+
11
+ const __filename = fileURLToPath(import.meta.url);
12
+ const __dirname = path.dirname(__filename);
13
+
14
+ function main() {
15
+ try {
16
+ const targetPath = path.join(process.cwd(), 'netlify.toml');
17
+
18
+ // Проверяем, есть ли уже netlify.toml с маркером "CUSTOMIZED"
19
+ if (fs.existsSync(targetPath)) {
20
+ const existingContent = fs.readFileSync(targetPath, 'utf8');
21
+
22
+ if (existingContent.includes('# CUSTOMIZED')) {
23
+ console.log('📋 Found "# CUSTOMIZED" marker - preserving entire file');
24
+ return;
25
+ }
26
+
27
+ // Создаем бэкап
28
+ fs.copyFileSync(targetPath, targetPath + '.backup');
29
+ console.log('📦 Created backup: netlify.toml.backup');
30
+ }
31
+
32
+ // Ищем исходный файл в пакете
33
+ let sourcePath;
34
+ const nodeModulesPath = path.join(process.cwd(), 'node_modules', 'core-maugli', 'netlify.toml');
35
+ if (fs.existsSync(nodeModulesPath)) {
36
+ sourcePath = nodeModulesPath;
37
+ } else {
38
+ sourcePath = path.join(__dirname, '..', 'netlify.toml');
39
+ }
40
+
41
+ if (!fs.existsSync(sourcePath)) {
42
+ console.log('⚠️ netlify.toml template not found');
43
+ return;
44
+ }
45
+
46
+ // Просто копируем файл
47
+ fs.copyFileSync(sourcePath, targetPath);
48
+ console.log('✅ netlify.toml copied successfully');
49
+
50
+ console.log('');
51
+ console.log('💡 Add "# CUSTOMIZED" comment to prevent auto-updates');
52
+
53
+ } catch (error) {
54
+ console.error('❌ Error copying netlify.toml:', error.message);
55
+ }
56
+ }
57
+
58
+ main();
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * Умно обновляет netlify.toml, мерджит плагины и сохраняет пользовательские настройки
4
+ * Копирует netlify.toml только при инициализации нового блога
5
+ * НЕ ТРОГАЕТ существующие netlify.toml файлы!
5
6
  */
6
7
 
7
8
  import fs from 'fs';
@@ -11,208 +12,18 @@ import { fileURLToPath } from 'url';
11
12
  const __filename = fileURLToPath(import.meta.url);
12
13
  const __dirname = path.dirname(__filename);
13
14
 
14
- // Базовые плагины из core-maugli (будут обновляться)
15
- const BASE_PLUGINS = [
16
- 'netlify-plugin-astro',
17
- '@netlify/plugin-lighthouse',
18
- 'netlify-plugin-image-optim',
19
- 'netlify-plugin-minify-html',
20
- 'netlify-plugin-submit-sitemap',
21
- 'netlify-plugin-checklinks',
22
- 'netlify-plugin-inline-critical-css',
23
- 'netlify-plugin-hashfiles'
24
- ];
25
-
26
- // Опциональные плагины (требуют ручной настройки)
27
- const OPTIONAL_PLUGINS = [
28
- 'netlify-plugin-bluesky',
29
- '@supabase/netlify-integration',
30
- 'netlify-plugin-bluesky-custom-domain'
31
- ];
32
-
33
- /**
34
- * Парсит TOML файл и извлекает плагины
35
- */
36
- function parseNetlifyToml(content) {
37
- const plugins = [];
38
- const lines = content.split('\n');
39
- let currentPlugin = null;
40
-
41
- for (let i = 0; i < lines.length; i++) {
42
- const line = lines[i].trim();
43
-
44
- // Проверяем начало секции плагина
45
- if (line === '[[plugins]]') {
46
- currentPlugin = {};
47
- }
48
- // Извлекаем package
49
- else if (currentPlugin && line.match(/package\s*=\s*["']([^"']+)["']/)) {
50
- const match = line.match(/package\s*=\s*["']([^"']+)["']/);
51
- currentPlugin.package = match[1];
52
- plugins.push(currentPlugin);
53
- currentPlugin = null;
54
- }
55
- }
56
-
57
- return plugins;
58
- }
59
-
60
- /**
61
- * Получает плагины из maugli.config.ts
62
- */
63
- async function getMaugliConfigPlugins() {
64
- try {
65
- const configPath = path.join(process.cwd(), 'src', 'config', 'maugli.config.ts');
66
- if (!fs.existsSync(configPath)) {
67
- console.log('📝 maugli.config.ts not found, using default plugins');
68
- return BASE_PLUGINS;
69
- }
70
-
71
- const configContent = fs.readFileSync(configPath, 'utf8');
72
-
73
- // Ищем секцию netlify.plugins
74
- const netlifyMatch = configContent.match(/netlify:\s*{[\s\S]*?plugins:\s*\[([\s\S]*?)\]/);
75
-
76
- if (netlifyMatch) {
77
- const pluginsString = netlifyMatch[1];
78
- const plugins = [];
79
-
80
- // Разбираем построчно, чтобы правильно обработать комментарии
81
- const lines = pluginsString.split('\n');
82
- for (const line of lines) {
83
- const trimmed = line.trim();
84
- // Пропускаем пустые строки и комментарии
85
- if (!trimmed || trimmed.startsWith('//')) continue;
86
-
87
- // Извлекаем строку плагина
88
- const match = trimmed.match(/['"]([^'"]+)['"]/);
89
- if (match) {
90
- const pluginName = match[1].trim();
91
- if (pluginName && !pluginName.includes('//')) {
92
- plugins.push(pluginName);
93
- }
94
- }
95
- }
96
-
97
- console.log(`📋 Found ${plugins.length} plugins in maugli.config.ts`);
98
- return plugins;
99
- }
100
-
101
- console.log('📝 No plugins found in maugli.config.ts, using defaults');
102
- return BASE_PLUGINS;
103
- } catch (error) {
104
- console.log(`⚠️ Error reading maugli.config.ts: ${error.message}`);
105
- return BASE_PLUGINS;
106
- }
107
- }
108
-
109
- /**
110
- * Мерджит плагины: базовые + из конфига + пользовательские
111
- */
112
- function mergePlugins(existingPlugins, configPlugins) {
113
- const merged = new Set();
114
- const userPlugins = [];
115
-
116
- // Добавляем все плагины из конфига
117
- configPlugins.forEach(plugin => merged.add(plugin));
118
-
119
- // Добавляем пользовательские плагины (не из базового списка)
120
- existingPlugins.forEach(plugin => {
121
- const packageName = plugin.package;
122
- if (!BASE_PLUGINS.includes(packageName) && !configPlugins.includes(packageName)) {
123
- userPlugins.push(packageName);
124
- merged.add(packageName);
125
- }
126
- });
127
-
128
- return {
129
- all: Array.from(merged),
130
- user: userPlugins,
131
- config: configPlugins
132
- };
133
- }
134
-
135
- /**
136
- * Генерирует TOML секцию плагинов
137
- */
138
- function generatePluginsToml(plugins, userPlugins, optionalActive) {
139
- let toml = '\n# Плагины (автоматически управляемые)\n';
140
-
141
- plugins.forEach(plugin => {
142
- const isOptional = OPTIONAL_PLUGINS.includes(plugin);
143
- const isActive = optionalActive.includes(plugin);
144
- const isUser = userPlugins.includes(plugin);
145
-
146
- if (isOptional && !isActive) {
147
- // Опциональный плагин, неактивный - комментируем
148
- toml += `# [[plugins]]\n# package = "${plugin}"\n`;
149
- } else {
150
- // Активный плагин
151
- toml += `[[plugins]]\n package = "${plugin}"`;
152
- if (isUser) {
153
- toml += ' # user-added';
154
- }
155
- toml += '\n';
156
- }
157
- toml += '\n';
158
- });
159
-
160
- return toml;
161
- }
162
-
163
- async function main() {
15
+ function main() {
164
16
  try {
165
17
  const targetPath = path.join(process.cwd(), 'netlify.toml');
166
18
 
167
- // Получаем плагины из конфига
168
- const configPlugins = await getMaugliConfigPlugins();
169
-
170
- let existingPlugins = [];
171
- let existingContent = '';
172
- let activeOptionalPlugins = [];
173
- let shouldPreserve = false;
174
-
175
- // Анализируем существующий файл
19
+ // Если netlify.toml уже существует - НЕ ТРОГАЕМ!
176
20
  if (fs.existsSync(targetPath)) {
177
- existingContent = fs.readFileSync(targetPath, 'utf8');
178
- existingPlugins = parseNetlifyToml(existingContent);
179
-
180
- // Определяем активные опциональные плагины
181
- activeOptionalPlugins = existingPlugins
182
- .map(p => p.package)
183
- .filter(pkg => OPTIONAL_PLUGINS.includes(pkg));
184
-
185
- // Проверяем, нужно ли сохранить файл
186
- const hasCustomComment = existingContent.includes('# CUSTOMIZED') &&
187
- !existingContent.includes('Add "# CUSTOMIZED" comment'); // Исключаем инструкцию
188
- const hasUserModifications = !existingContent.includes('# Auto-copied from core-maugli package');
189
-
190
- if (hasCustomComment) {
191
- console.log('📋 Found "# CUSTOMIZED" marker - preserving entire file');
192
- return;
193
- }
194
-
195
- if (activeOptionalPlugins.length > 0) {
196
- console.log('📋 Found active integrations:');
197
- activeOptionalPlugins.forEach(plugin => {
198
- console.log(` � ${plugin}`);
199
- });
200
- shouldPreserve = true;
201
- }
202
- }
203
-
204
- // Мерджим плагины
205
- const mergedPlugins = mergePlugins(existingPlugins, configPlugins);
206
-
207
- if (mergedPlugins.user.length > 0) {
208
- console.log('📦 Found user plugins:');
209
- mergedPlugins.user.forEach(plugin => {
210
- console.log(` ✨ ${plugin}`);
211
- });
212
- shouldPreserve = true;
21
+ console.log('📋 netlify.toml already exists - leaving unchanged');
22
+ console.log('� Configure Netlify plugins manually via Netlify UI');
23
+ return;
213
24
  }
214
25
 
215
- // Читаем базовый шаблон
26
+ // Ищем исходный файл в пакете
216
27
  let sourcePath;
217
28
  const nodeModulesPath = path.join(process.cwd(), 'node_modules', 'core-maugli', 'netlify.toml');
218
29
  if (fs.existsSync(nodeModulesPath)) {
@@ -226,53 +37,18 @@ async function main() {
226
37
  return;
227
38
  }
228
39
 
229
- let templateContent = fs.readFileSync(sourcePath, 'utf8');
230
-
231
- // Заменяем секцию плагинов
232
- const pluginsToml = generatePluginsToml(
233
- mergedPlugins.all,
234
- mergedPlugins.user,
235
- activeOptionalPlugins
236
- );
237
-
238
- // Удаляем старую секцию плагинов и вставляем новую
239
- const beforePlugins = templateContent.split('# Обязательные плагины')[0];
240
- const afterPlugins = templateContent.split('# Redirects')[1] || templateContent.split('[[redirects]]')[0];
241
-
242
- const updatedContent = beforePlugins.trim() + '\n' + pluginsToml + '\n# Redirects' + (afterPlugins || '');
243
-
244
- // Создаем бэкап если файл существует
245
- if (fs.existsSync(targetPath) && shouldPreserve) {
246
- fs.copyFileSync(targetPath, targetPath + '.backup');
247
- console.log('📦 Created backup: netlify.toml.backup');
248
- }
249
-
250
- // Записываем обновленный файл
251
- fs.writeFileSync(targetPath, updatedContent);
252
-
253
- console.log('✅ netlify.toml updated successfully');
254
- console.log(`📋 Total plugins: ${mergedPlugins.all.length}`);
255
- console.log(` � From config: ${mergedPlugins.config.length}`);
256
- console.log(` ✨ User added: ${mergedPlugins.user.length}`);
257
- console.log(` 🔵 Active integrations: ${activeOptionalPlugins.length}`);
258
-
259
- if (OPTIONAL_PLUGINS.some(p => !activeOptionalPlugins.includes(p))) {
260
- console.log('\n📝 Available integrations (currently disabled):');
261
- OPTIONAL_PLUGINS.forEach(plugin => {
262
- if (!activeOptionalPlugins.includes(plugin)) {
263
- const setupUrl = plugin.includes('bluesky')
264
- ? 'https://app.netlify.com/extensions/bluesky-custom-domain'
265
- : plugin.includes('supabase')
266
- ? 'https://app.netlify.com/extensions/supabase'
267
- : 'Netlify Extensions';
268
- console.log(` � ${plugin}: ${setupUrl}`);
269
- }
270
- });
271
- }
40
+ // Копируем файл только для нового блога
41
+ fs.copyFileSync(sourcePath, targetPath);
42
+ console.log('✅ netlify.toml created for new blog');
43
+ console.log('');
44
+ console.log('📝 Next steps:');
45
+ console.log(' 1. Deploy to Netlify');
46
+ console.log(' 2. Configure plugins via Netlify UI');
47
+ console.log(' 3. Add "# CUSTOMIZED" comment to prevent overwrites');
272
48
 
273
49
  } catch (error) {
274
- console.error('❌ Error updating netlify.toml:', error.message);
50
+ console.error('❌ Error copying netlify.toml:', error.message);
275
51
  }
276
52
  }
277
53
 
278
- main().catch(console.error);
54
+ main();
@@ -56,10 +56,8 @@ const REQUIRED_SCRIPTS = [
56
56
  'scripts/update-with-backup.js',
57
57
  'scripts/check-version.js',
58
58
  'scripts/auto-update.js',
59
- 'scripts/copy-netlify-config.js',
60
59
  'scripts/set-force-update.js',
61
- '.gitignore',
62
- 'netlify.toml'
60
+ '.gitignore'
63
61
  ];
64
62
 
65
63
  function log(message, type = 'info') {
@@ -155,23 +153,7 @@ function updateBlogProject(projectPath) {
155
153
  process.chdir(absolutePath);
156
154
  execSync('npm update core-maugli', { stdio: 'pipe' });
157
155
 
158
- // 8. Копируем netlify.toml
159
- log('Copying netlify.toml configuration...', 'info');
160
- const copyNetlifyScript = path.join(process.cwd(), 'scripts/copy-netlify-config.js');
161
- if (fs.existsSync(copyNetlifyScript)) {
162
- try {
163
- const { execSync } = require('child_process');
164
- execSync(`node "${copyNetlifyScript}"`, {
165
- stdio: 'pipe',
166
- cwd: absolutePath
167
- });
168
- log(' ✅ netlify.toml copied', 'success');
169
- } catch (error) {
170
- log(` ⚠️ netlify.toml copy failed: ${error.message}`, 'warn');
171
- }
172
- }
173
-
174
- // 9. Результат
156
+ // 8. Результат
175
157
  log(`Project updated successfully!`, 'success');
176
158
  log(` Version: ${oldVersion} → ${CURRENT_VERSION}`, 'info');
177
159
  log(` Scripts updated: ${scriptsUpdated ? 'Yes' : 'No'}`, 'info');