core-maugli 1.2.81 → 1.2.82
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/package.json +5 -4
- package/scripts/auto-update.js +21 -18
- package/scripts/cleanup-duplicates.js +31 -0
- package/scripts/postinstall.js +47 -0
- package/scripts/update-components.js +12 -3
- package/scripts/upgrade-config.js +0 -19
- package/scripts/verify-pack.js +29 -1
- package/src/components/BaseHead.astro +1 -1
- package/src/content/products/maugli-freeblog.md +2 -2
- package/src/pages/sw.js.ts +6 -0
- package/src/styles/global.css +45 -1
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.
|
|
5
|
+
"version": "1.2.82",
|
|
6
6
|
"license": "GPL-3.0-or-later OR Commercial",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -42,12 +42,13 @@
|
|
|
42
42
|
"build:ci": "SKIP_VERSION_CHECK=true npm run build",
|
|
43
43
|
"init-netlify": "node scripts/copy-netlify-config.js",
|
|
44
44
|
"set-force-update": "node scripts/set-force-update.js",
|
|
45
|
-
"postinstall": "node scripts/
|
|
45
|
+
"postinstall": "node scripts/postinstall.js",
|
|
46
46
|
"generate-previews": "node scripts/generate-previews.js",
|
|
47
47
|
"generate-netlify": "node scripts/generate-netlify-config.js",
|
|
48
|
-
"verify-pack": "node scripts/verify-pack.js"
|
|
48
|
+
"verify-pack": "node scripts/verify-pack.js",
|
|
49
|
+
"clean:duplicates": "node scripts/cleanup-duplicates.js"
|
|
49
50
|
},
|
|
50
|
-
"prepublishOnly": "npm run verify-pack",
|
|
51
|
+
"prepublishOnly": "npm run clean:duplicates && npm run verify-pack",
|
|
51
52
|
"dependencies": {
|
|
52
53
|
"@astrojs/mdx": "^4.3.0",
|
|
53
54
|
"@astrojs/rss": "^4.0.11",
|
package/scripts/auto-update.js
CHANGED
|
@@ -46,20 +46,20 @@ async function getLatestVersion() {
|
|
|
46
46
|
|
|
47
47
|
function compareVersions(current, latest) {
|
|
48
48
|
if (!current || !latest) return false;
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
current = current.replace(/^[\^~]/, '');
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
const currentParts = current.split('.').map(Number);
|
|
53
53
|
const latestParts = latest.split('.').map(Number);
|
|
54
|
-
|
|
54
|
+
|
|
55
55
|
for (let i = 0; i < Math.max(currentParts.length, latestParts.length); i++) {
|
|
56
56
|
const currentPart = currentParts[i] || 0;
|
|
57
57
|
const latestPart = latestParts[i] || 0;
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
if (latestPart > currentPart) return true;
|
|
60
60
|
if (latestPart < currentPart) return false;
|
|
61
61
|
}
|
|
62
|
-
|
|
62
|
+
|
|
63
63
|
return false;
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -80,7 +80,7 @@ async function syncHelperFiles() {
|
|
|
80
80
|
'scripts/check-version.js',
|
|
81
81
|
'scripts/auto-update.js',
|
|
82
82
|
'scripts/set-force-update.js',
|
|
83
|
-
'.gitignore'
|
|
83
|
+
'.gitignore'
|
|
84
84
|
];
|
|
85
85
|
|
|
86
86
|
async function sha256(p) {
|
|
@@ -117,28 +117,31 @@ async function syncHelperFiles() {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
async function cleanupDuplicates() {
|
|
120
|
+
let removed = 0;
|
|
120
121
|
async function walk(dir) {
|
|
121
122
|
const ents = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
122
123
|
for (const e of ents) {
|
|
123
124
|
const p = path.join(dir, e.name);
|
|
124
125
|
if (e.isDirectory()) await walk(p);
|
|
125
|
-
else if (/\
|
|
126
|
+
else if (/\s\d+(\.[^.]+)?$/i.test(e.name) || /\s?\(\d+\)(\.[^.]+)?$/i.test(e.name)) {
|
|
126
127
|
await fs.promises.unlink(p).catch(() => {});
|
|
128
|
+
removed++;
|
|
127
129
|
console.log(`✖ removed duplicate: ${path.relative(root, p)}`);
|
|
128
130
|
}
|
|
129
131
|
}
|
|
130
132
|
}
|
|
131
133
|
await walk(root);
|
|
134
|
+
console.log(`✖ total duplicates removed: ${removed}`);
|
|
132
135
|
}
|
|
133
136
|
|
|
134
137
|
await copyItems();
|
|
135
|
-
await cleanupDuplicates().catch(e => console.warn('cleanup warning:', e.message));
|
|
138
|
+
await cleanupDuplicates().catch((e) => console.warn('cleanup warning:', e.message));
|
|
136
139
|
}
|
|
137
140
|
|
|
138
141
|
async function performAutoUpdate() {
|
|
139
142
|
console.log(colorize('🤖 CI/CD Auto-update mode activated', 'cyan'));
|
|
140
143
|
console.log(colorize('🔄 Updating core-maugli automatically...', 'blue'));
|
|
141
|
-
|
|
144
|
+
|
|
142
145
|
try {
|
|
143
146
|
// Check if update script exists
|
|
144
147
|
const updateScriptPath = path.join(process.cwd(), 'scripts', 'update-all-blogs.js');
|
|
@@ -151,7 +154,7 @@ async function performAutoUpdate() {
|
|
|
151
154
|
execSync('npm update core-maugli', { stdio: 'inherit' });
|
|
152
155
|
await syncHelperFiles();
|
|
153
156
|
}
|
|
154
|
-
|
|
157
|
+
|
|
155
158
|
console.log(colorize('✅ Auto-update completed successfully!', 'green'));
|
|
156
159
|
return true;
|
|
157
160
|
} catch (error) {
|
|
@@ -162,36 +165,36 @@ async function performAutoUpdate() {
|
|
|
162
165
|
|
|
163
166
|
async function main() {
|
|
164
167
|
console.log(colorize('🔍 Checking for core-maugli updates...', 'cyan'));
|
|
165
|
-
|
|
168
|
+
|
|
166
169
|
const currentVersion = await getCurrentVersion();
|
|
167
170
|
const latestVersion = await getLatestVersion();
|
|
168
|
-
|
|
171
|
+
|
|
169
172
|
if (!currentVersion || !latestVersion) {
|
|
170
173
|
console.log(colorize('⚠️ Could not check version. Proceeding...', 'yellow'));
|
|
171
174
|
return;
|
|
172
175
|
}
|
|
173
|
-
|
|
176
|
+
|
|
174
177
|
console.log(colorize(`📦 Current version: ${currentVersion}`, 'white'));
|
|
175
178
|
console.log(colorize(`📦 Latest version: ${latestVersion}`, 'white'));
|
|
176
|
-
|
|
179
|
+
|
|
177
180
|
if (!compareVersions(currentVersion, latestVersion)) {
|
|
178
181
|
console.log(colorize('✅ Already using the latest version!', 'green'));
|
|
179
182
|
return;
|
|
180
183
|
}
|
|
181
|
-
|
|
184
|
+
|
|
182
185
|
// Auto-update without prompts
|
|
183
186
|
console.log(colorize(`🚀 New version ${latestVersion} available! Auto-updating...`, 'magenta'));
|
|
184
|
-
|
|
187
|
+
|
|
185
188
|
const success = await performAutoUpdate();
|
|
186
189
|
if (!success) {
|
|
187
190
|
console.error(colorize('❌ Auto-update failed. Build may fail or produce unexpected results.', 'red'));
|
|
188
191
|
process.exit(1);
|
|
189
192
|
}
|
|
190
|
-
|
|
193
|
+
|
|
191
194
|
console.log(colorize('✅ Ready to proceed with updated version!', 'green'));
|
|
192
195
|
}
|
|
193
196
|
|
|
194
|
-
main().catch(error => {
|
|
197
|
+
main().catch((error) => {
|
|
195
198
|
console.error(colorize('❌ Auto-update check failed:', 'red'), error.message);
|
|
196
199
|
process.exit(1);
|
|
197
200
|
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { promises as fs } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
|
|
5
|
+
const dirs = ['src/components', 'src/utils', 'public/flags'];
|
|
6
|
+
const patterns = [/\(\d+\)$/i, /\s\d+$/i, /- copy$/i, /_copy$/i];
|
|
7
|
+
|
|
8
|
+
async function scan(dir) {
|
|
9
|
+
let entries;
|
|
10
|
+
try {
|
|
11
|
+
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
12
|
+
} catch {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
for (const entry of entries) {
|
|
16
|
+
const fullPath = path.join(dir, entry.name);
|
|
17
|
+
if (entry.isDirectory()) {
|
|
18
|
+
await scan(fullPath);
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const base = path.basename(entry.name, path.extname(entry.name));
|
|
22
|
+
if (patterns.some((p) => p.test(base))) {
|
|
23
|
+
await fs.unlink(fullPath);
|
|
24
|
+
console.log(`Removed duplicate: ${fullPath}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
for (const dir of dirs) {
|
|
30
|
+
await scan(dir);
|
|
31
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from 'fs/promises';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { fileURLToPath, pathToFileURL } from 'url';
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
|
|
10
|
+
async function runUpgrade() {
|
|
11
|
+
const upgradePath = path.join(__dirname, 'upgrade-config.js');
|
|
12
|
+
await import(pathToFileURL(upgradePath).href);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function runSetupImages() {
|
|
16
|
+
const { setupUserImages } = await import('./setup-user-images.js');
|
|
17
|
+
await setupUserImages();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function main() {
|
|
21
|
+
const pkgPath = path.join(__dirname, '..', 'package.json');
|
|
22
|
+
const pkg = JSON.parse(await fs.readFile(pkgPath, 'utf8'));
|
|
23
|
+
const currentVersion = pkg.version;
|
|
24
|
+
|
|
25
|
+
const userRoot = process.env.INIT_CWD || process.cwd();
|
|
26
|
+
const versionFile = path.join(userRoot, '.core-maugli-version');
|
|
27
|
+
|
|
28
|
+
let previousVersion = null;
|
|
29
|
+
try {
|
|
30
|
+
previousVersion = (await fs.readFile(versionFile, 'utf8')).trim();
|
|
31
|
+
} catch {}
|
|
32
|
+
|
|
33
|
+
if (previousVersion !== currentVersion) {
|
|
34
|
+
console.log(`Detected core-maugli version change (${previousVersion || 'none'} -> ${currentVersion}).`);
|
|
35
|
+
await runUpgrade();
|
|
36
|
+
await fs.writeFile(versionFile, currentVersion, 'utf8');
|
|
37
|
+
} else {
|
|
38
|
+
console.log(`core-maugli version ${currentVersion} unchanged, skipping upgrade.`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
await runSetupImages();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
main().catch((err) => {
|
|
45
|
+
console.error('Postinstall failed:', err);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
});
|
|
@@ -63,7 +63,12 @@ const PRESERVE_PATHS = [
|
|
|
63
63
|
];
|
|
64
64
|
|
|
65
65
|
// Дополнительные паттерны для мусорных файлов
|
|
66
|
-
const EXTRA_STALE_PATTERNS = [
|
|
66
|
+
const EXTRA_STALE_PATTERNS = [
|
|
67
|
+
/\s[0-9]+\.(astro|jsx?|tsx?|mjs|cjs|css|json)$/i, // "file 1.js"
|
|
68
|
+
/\(\d+\)\.(astro|tsx?|jsx?|mjs|cjs|css|json)$/i, // "file(1).js"
|
|
69
|
+
/(?:[\s_-](?:копия|copy))\.(astro|tsx?|jsx?|mjs|cjs|css|json)$/i, // "file - копия.js" или "file_copy.js"
|
|
70
|
+
/~$/i
|
|
71
|
+
];
|
|
67
72
|
|
|
68
73
|
// Рекурсивный обход проекта
|
|
69
74
|
async function walk(dir, visitor) {
|
|
@@ -103,12 +108,16 @@ async function cleanup() {
|
|
|
103
108
|
|
|
104
109
|
// Удаляем дубликаты и временные файлы внутри FORCE_UPDATE_PATHS
|
|
105
110
|
await walk(userRoot, async (p, dir) => {
|
|
111
|
+
const base = path.basename(p);
|
|
106
112
|
if (dir) {
|
|
107
|
-
if (
|
|
113
|
+
if (
|
|
114
|
+
isInsideForcePaths(p) &&
|
|
115
|
+
(/\s[0-9]+$/.test(base) || /\(\d+\)$/.test(base) || /(?:[\s_-](?:копия|copy))$/i.test(base))
|
|
116
|
+
) {
|
|
108
117
|
await fs.rm(p, { recursive: true, force: true });
|
|
109
118
|
removed.push(path.relative(userRoot, p));
|
|
110
119
|
}
|
|
111
|
-
} else if (isInsideForcePaths(p) && EXTRA_STALE_PATTERNS.some((rx) => rx.test(
|
|
120
|
+
} else if (isInsideForcePaths(p) && EXTRA_STALE_PATTERNS.some((rx) => rx.test(base))) {
|
|
112
121
|
await fs.rm(p, { force: true });
|
|
113
122
|
removed.push(path.relative(userRoot, p));
|
|
114
123
|
}
|
|
@@ -9,17 +9,6 @@ import { fileURLToPath, pathToFileURL } from 'url';
|
|
|
9
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
10
10
|
const __dirname = path.dirname(__filename);
|
|
11
11
|
|
|
12
|
-
// Импортируем функцию обновления компонентов
|
|
13
|
-
async function importUpdateComponents() {
|
|
14
|
-
try {
|
|
15
|
-
const { updateComponents } = await import('./update-components.js');
|
|
16
|
-
return updateComponents;
|
|
17
|
-
} catch (error) {
|
|
18
|
-
console.warn('Could not load update-components.js:', error.message);
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
12
|
const defaultConfigPath = path.join(__dirname, '../src/config/maugli.config.ts');
|
|
24
13
|
const userRoot = process.env.INIT_CWD || process.cwd();
|
|
25
14
|
const userConfigPath = path.join(userRoot, 'src/config/maugli.config.ts');
|
|
@@ -55,14 +44,6 @@ function mergeMissing(target, source) {
|
|
|
55
44
|
|
|
56
45
|
async function main() {
|
|
57
46
|
console.log('🔄 Starting Maugli upgrade process...');
|
|
58
|
-
|
|
59
|
-
// Сначала обновляем компоненты
|
|
60
|
-
const updateComponents = await importUpdateComponents();
|
|
61
|
-
if (updateComponents) {
|
|
62
|
-
await updateComponents();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Затем обновляем конфиг
|
|
66
47
|
const pkg = await loadTsModule(defaultConfigPath);
|
|
67
48
|
const defCfg = pkg.maugliConfig;
|
|
68
49
|
const newVersion = pkg.MAUGLI_CONFIG_VERSION || defCfg.configVersion;
|
package/scripts/verify-pack.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { execSync } from 'node:child_process';
|
|
3
|
-
import { readFileSync, statSync } from 'node:fs';
|
|
3
|
+
import { readFileSync, statSync, readdirSync } from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
4
5
|
|
|
5
6
|
// Run `npm pack --dry-run` and capture JSON output describing package contents
|
|
6
7
|
const env = { ...process.env, npm_config_loglevel: 'error' };
|
|
@@ -44,4 +45,31 @@ if (missing.length > 0) {
|
|
|
44
45
|
process.exit(1);
|
|
45
46
|
}
|
|
46
47
|
|
|
48
|
+
const duplicatePatterns = [/\(\d+\)$/i, /\s\d+$/i, /- copy$/i, /_copy$/i];
|
|
49
|
+
const duplicateDirs = ['src/components', 'src/utils', 'public/flags'];
|
|
50
|
+
|
|
51
|
+
function findDuplicates(dir, results = []) {
|
|
52
|
+
let entries;
|
|
53
|
+
try {
|
|
54
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
55
|
+
} catch {
|
|
56
|
+
return results;
|
|
57
|
+
}
|
|
58
|
+
for (const entry of entries) {
|
|
59
|
+
const full = path.join(dir, entry.name);
|
|
60
|
+
if (entry.isDirectory()) {
|
|
61
|
+
findDuplicates(full, results);
|
|
62
|
+
} else {
|
|
63
|
+
const base = path.basename(entry.name, path.extname(entry.name));
|
|
64
|
+
if (duplicatePatterns.some((p) => p.test(base))) results.push(full);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return results;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const duplicates = duplicateDirs.flatMap((d) => findDuplicates(d));
|
|
71
|
+
if (duplicates.length > 0) {
|
|
72
|
+
console.warn('Warning: duplicate files detected:', duplicates.join(', '));
|
|
73
|
+
}
|
|
74
|
+
|
|
47
75
|
console.log('All required package files are present.');
|
|
@@ -175,7 +175,7 @@ let defaultAuthorName = defaultAuthor.data.name;
|
|
|
175
175
|
if ('serviceWorker' in navigator) {
|
|
176
176
|
window.addEventListener('load', async () => {
|
|
177
177
|
try {
|
|
178
|
-
const registration = await navigator.serviceWorker.register(
|
|
178
|
+
const registration = await navigator.serviceWorker.register(`${import.meta.env.BASE_URL}sw.js`);
|
|
179
179
|
console.log('SW registered: ', registration);
|
|
180
180
|
} catch (registrationError) {
|
|
181
181
|
console.log('SW registration failed: ', registrationError);
|
|
@@ -56,7 +56,7 @@ jsonld:
|
|
|
56
56
|
'@type': 'Offer'
|
|
57
57
|
'priceCurrency': 'USD'
|
|
58
58
|
'price': '0'
|
|
59
|
-
'url': 'https://
|
|
59
|
+
'url': 'https://www.npmjs.com/package/core-maugli'
|
|
60
60
|
|
|
61
61
|
isExample: true
|
|
62
62
|
---
|
|
@@ -157,6 +157,6 @@ Maugli Free Blog спроектирован для лёгкой развертк
|
|
|
157
157
|
|
|
158
158
|
## **Где взять?**
|
|
159
159
|
|
|
160
|
-
- **
|
|
160
|
+
- **NPM:** [core-maugli](https://www.npmjs.com/package/core-maugli)
|
|
161
161
|
|
|
162
162
|
**Maugli Free Blog — это платформа, созданная для автоматизации, SEO и AI-интеграций.**
|
package/src/styles/global.css
CHANGED
|
@@ -157,7 +157,13 @@
|
|
|
157
157
|
--tw-prose-captions: var(--text-muted);
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
.prose p
|
|
160
|
+
.prose p {
|
|
161
|
+
font-size: 1em;
|
|
162
|
+
margin: 0 0 0.9em;
|
|
163
|
+
color: var(--text-main) 85%;
|
|
164
|
+
line-height: 1.65 !important;
|
|
165
|
+
}
|
|
166
|
+
|
|
161
167
|
.prose li {
|
|
162
168
|
line-height: 1.65 !important;
|
|
163
169
|
}
|
|
@@ -188,6 +194,44 @@
|
|
|
188
194
|
}
|
|
189
195
|
|
|
190
196
|
/* Ссылки — читаемые и неядрёные */
|
|
197
|
+
|
|
198
|
+
/* Таблицы — перегородки (границы) в цвет мутед-бэкграунда */
|
|
199
|
+
.prose table {
|
|
200
|
+
border-collapse: collapse;
|
|
201
|
+
margin-top: 16px;
|
|
202
|
+
}
|
|
203
|
+
.prose th,
|
|
204
|
+
.prose td {
|
|
205
|
+
border-top: 1px solid var(--bg-muted);
|
|
206
|
+
border-bottom: 1px solid var(--bg-muted);
|
|
207
|
+
border-left: none;
|
|
208
|
+
border-right: none;
|
|
209
|
+
}
|
|
210
|
+
.prose thead th {
|
|
211
|
+
background: none !important;
|
|
212
|
+
font-size: 1em;
|
|
213
|
+
color: var(--text-heading);
|
|
214
|
+
border-top: none !important;
|
|
215
|
+
font-weight: 700;
|
|
216
|
+
}
|
|
217
|
+
.prose th,
|
|
218
|
+
.prose td {
|
|
219
|
+
font-size: 1em;
|
|
220
|
+
color: color-mix(in srgb, var(--text-main) 80%, transparent);
|
|
221
|
+
}
|
|
222
|
+
html.dark .prose thead th {
|
|
223
|
+
background: none;
|
|
224
|
+
}
|
|
225
|
+
html.dark .prose th,
|
|
226
|
+
html.dark .prose td {
|
|
227
|
+
border-top-color: none;
|
|
228
|
+
border-bottom-color: var(--bg-muted);
|
|
229
|
+
border-left: none;
|
|
230
|
+
border-right: none;
|
|
231
|
+
}
|
|
232
|
+
html.dark .prose thead th {
|
|
233
|
+
background: none !important;
|
|
234
|
+
}
|
|
191
235
|
.prose a {
|
|
192
236
|
color: color-mix(in srgb, var(--color-brand) 80%, var(--text-main));
|
|
193
237
|
text-decoration: underline;
|