astrotype 0.1.3 → 0.1.5
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/cli/commands/add-font.mjs +4 -3
- package/cli/commands/add.mjs +27 -5
- package/cli/lib/add-utils.mjs +63 -2
- package/package.json +1 -1
|
@@ -33,15 +33,16 @@ export async function addFontCommand(fontName, options = {}) {
|
|
|
33
33
|
const cssText = `${toCssRules(font)}`;
|
|
34
34
|
const cssPath = writeAstrotypeCss(targetDir, font.name, cssText);
|
|
35
35
|
const fontsSetup = ensureAstroFontsApiSetup(targetDir, [font]);
|
|
36
|
-
console.log(`Installed font "${font.name}"
|
|
36
|
+
console.log(`Installed font "${font.name}" -> ${path.relative(targetDir, cssPath)}`);
|
|
37
37
|
if (fontsSetup.configured) {
|
|
38
|
-
console.log("
|
|
38
|
+
console.log("Wired Astro Fonts API entries for this font.");
|
|
39
39
|
if (fontsSetup.manualMergeRequired) {
|
|
40
40
|
console.log(
|
|
41
|
-
`
|
|
41
|
+
`Heads up: existing fonts config found in ${path.relative(targetDir, fontsSetup.configPath)}. Merge astrotypeFonts there.`
|
|
42
42
|
);
|
|
43
43
|
}
|
|
44
44
|
} else {
|
|
45
45
|
console.log(`Skipped Astro Fonts API setup: ${fontsSetup.reason}`);
|
|
46
46
|
}
|
|
47
|
+
console.log(`Next step: map your app classes/tokens to ${font.font.variable || `--font-${font.name}`}.`);
|
|
47
48
|
}
|
package/cli/commands/add.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { getFontByName, getPairingByName } from "../lib/registry.mjs";
|
|
2
|
+
import { getAllPairings, getFontByName, getPairingByName } from "../lib/registry.mjs";
|
|
3
3
|
import {
|
|
4
|
+
activatePairingCssImport,
|
|
4
5
|
ensureAstroFontsApiSetup,
|
|
5
6
|
isAstroProject,
|
|
6
7
|
writeAstrotypeCss,
|
|
@@ -17,6 +18,20 @@ function toCssRules(ruleMap) {
|
|
|
17
18
|
.join("\n\n");
|
|
18
19
|
}
|
|
19
20
|
|
|
21
|
+
function toUtilityClassRules() {
|
|
22
|
+
return `.font-heading {
|
|
23
|
+
font-family: var(--font-heading);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.font-body {
|
|
27
|
+
font-family: var(--font-body);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.font-mono {
|
|
31
|
+
font-family: var(--font-mono);
|
|
32
|
+
}`;
|
|
33
|
+
}
|
|
34
|
+
|
|
20
35
|
export async function addPairingCommand(pairingName, options = {}) {
|
|
21
36
|
const targetDir = path.resolve(options.cwd || process.cwd());
|
|
22
37
|
if (!isAstroProject(targetDir)) {
|
|
@@ -41,21 +56,28 @@ export async function addPairingCommand(pairingName, options = {}) {
|
|
|
41
56
|
}
|
|
42
57
|
|
|
43
58
|
const cssText = `${toCssRules(pairing.css)}
|
|
59
|
+
|
|
60
|
+
${toUtilityClassRules()}
|
|
44
61
|
`;
|
|
45
62
|
const pairingCssPath = writeAstrotypeCss(targetDir, pairing.name, cssText);
|
|
63
|
+
const pairingSlugs = getAllPairings().map((item) => item.name).filter(Boolean);
|
|
64
|
+
const importUpdate = activatePairingCssImport(targetDir, pairing.name, pairingSlugs);
|
|
46
65
|
const fontsSetup = ensureAstroFontsApiSetup(targetDir, fonts);
|
|
47
66
|
|
|
48
|
-
console.log(`Installed pairing "${pairing.name}"
|
|
67
|
+
console.log(`Installed pairing "${pairing.name}" -> ${path.relative(targetDir, pairingCssPath)}`);
|
|
68
|
+
if (importUpdate.removed.length > 0) {
|
|
69
|
+
console.log(`Switched active pairing import (removed: ${importUpdate.removed.join(", ")}).`);
|
|
70
|
+
}
|
|
49
71
|
if (fontsSetup.configured) {
|
|
50
|
-
console.log("
|
|
72
|
+
console.log("Wired Astro Fonts API entries for this pairing.");
|
|
51
73
|
if (fontsSetup.manualMergeRequired) {
|
|
52
74
|
console.log(
|
|
53
|
-
`
|
|
75
|
+
`Heads up: existing fonts config found in ${path.relative(targetDir, fontsSetup.configPath)}. Merge astrotypeFonts there.`
|
|
54
76
|
);
|
|
55
77
|
}
|
|
56
78
|
} else {
|
|
57
79
|
console.log(`Skipped Astro Fonts API setup: ${fontsSetup.reason}`);
|
|
58
80
|
}
|
|
59
|
-
console.log("
|
|
81
|
+
console.log("Next step: map your app classes/tokens to --font-heading, --font-body, and --font-mono.");
|
|
60
82
|
}
|
|
61
83
|
|
package/cli/lib/add-utils.mjs
CHANGED
|
@@ -150,18 +150,29 @@ ${lines}
|
|
|
150
150
|
configText = ensureAstroConfigHasAstrotypeImport(configText);
|
|
151
151
|
const result = ensureAstroConfigHasFontsProperty(configText);
|
|
152
152
|
fs.writeFileSync(astroConfigPath, result.text);
|
|
153
|
+
const isAlreadyWired = /\bfonts\s*:\s*astrotypeFonts\b/.test(result.text);
|
|
153
154
|
|
|
154
155
|
return {
|
|
155
156
|
configured: true,
|
|
156
157
|
configPath: astroConfigPath,
|
|
157
|
-
manualMergeRequired: !result.injected && /\bfonts\s*:/.test(configText),
|
|
158
|
+
manualMergeRequired: !result.injected && !isAlreadyWired && /\bfonts\s*:/.test(configText),
|
|
158
159
|
};
|
|
159
160
|
}
|
|
160
161
|
|
|
161
162
|
export function ensureImport(globalCssPath, importLine) {
|
|
162
163
|
const css = fs.existsSync(globalCssPath) ? fs.readFileSync(globalCssPath, "utf-8") : "";
|
|
163
164
|
if (css.includes(importLine)) return;
|
|
164
|
-
|
|
165
|
+
const lines = css.split(/\r?\n/);
|
|
166
|
+
let lastImportIndex = -1;
|
|
167
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
168
|
+
if (/^\s*@import\s+/.test(lines[index])) lastImportIndex = index;
|
|
169
|
+
}
|
|
170
|
+
if (lastImportIndex === -1) {
|
|
171
|
+
fs.writeFileSync(globalCssPath, `${importLine}\n${css}`);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
lines.splice(lastImportIndex + 1, 0, importLine);
|
|
175
|
+
fs.writeFileSync(globalCssPath, `${lines.join("\n")}\n`);
|
|
165
176
|
}
|
|
166
177
|
|
|
167
178
|
export function writeAstrotypeCss(targetDir, slug, cssText) {
|
|
@@ -175,3 +186,53 @@ export function writeAstrotypeCss(targetDir, slug, cssText) {
|
|
|
175
186
|
ensureImport(globalCssPath, `@import "./astrotypes/${slug}.css";`);
|
|
176
187
|
return cssPath;
|
|
177
188
|
}
|
|
189
|
+
|
|
190
|
+
export function activatePairingCssImport(targetDir, activePairingSlug, pairingSlugs) {
|
|
191
|
+
const globalCssPath = path.join(targetDir, "src", "styles", "global.css");
|
|
192
|
+
ensureDir(path.dirname(globalCssPath));
|
|
193
|
+
const importLine = `@import "./astrotypes/${activePairingSlug}.css";`;
|
|
194
|
+
const knownPairings = new Set(pairingSlugs || []);
|
|
195
|
+
|
|
196
|
+
if (!fs.existsSync(globalCssPath)) {
|
|
197
|
+
fs.writeFileSync(globalCssPath, `${importLine}\n`);
|
|
198
|
+
return { removed: [], added: true };
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const css = fs.readFileSync(globalCssPath, "utf-8");
|
|
202
|
+
const lines = css.split(/\r?\n/);
|
|
203
|
+
const keptLines = [];
|
|
204
|
+
const removed = [];
|
|
205
|
+
let hasActive = false;
|
|
206
|
+
|
|
207
|
+
for (const line of lines) {
|
|
208
|
+
const match = line.match(
|
|
209
|
+
/^\s*@import\s+["']\.\/astrotypes\/([a-z0-9-]+)\.css["'];\s*$/
|
|
210
|
+
);
|
|
211
|
+
if (!match) {
|
|
212
|
+
keptLines.push(line);
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
const slug = match[1];
|
|
216
|
+
if (slug === activePairingSlug) {
|
|
217
|
+
hasActive = true;
|
|
218
|
+
keptLines.push(importLine);
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
if (knownPairings.has(slug)) {
|
|
222
|
+
removed.push(slug);
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
keptLines.push(line);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (!hasActive) {
|
|
229
|
+
let lastImportIndex = -1;
|
|
230
|
+
for (let index = 0; index < keptLines.length; index += 1) {
|
|
231
|
+
if (/^\s*@import\s+/.test(keptLines[index])) lastImportIndex = index;
|
|
232
|
+
}
|
|
233
|
+
if (lastImportIndex === -1) keptLines.unshift(importLine);
|
|
234
|
+
else keptLines.splice(lastImportIndex + 1, 0, importLine);
|
|
235
|
+
}
|
|
236
|
+
fs.writeFileSync(globalCssPath, `${keptLines.join("\n")}\n`);
|
|
237
|
+
return { removed, added: !hasActive };
|
|
238
|
+
}
|