astrotype 0.1.4 → 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.
@@ -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,11 +56,18 @@ 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
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
72
  console.log("Wired Astro Fonts API entries for this pairing.");
51
73
  if (fontsSetup.manualMergeRequired) {
@@ -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
- fs.writeFileSync(globalCssPath, `${importLine}\n${css}`);
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
+ }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "astrotype",
3
3
  "description": "Astro-first font registry and CLI for installing pairings or single fonts.",
4
4
  "type": "module",
5
- "version": "0.1.4",
5
+ "version": "0.1.5",
6
6
  "private": false,
7
7
  "keywords": [
8
8
  "astro",