astrotype 0.1.2 → 0.1.3
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 +13 -5
- package/cli/commands/add.mjs +13 -5
- package/cli/lib/add-utils.mjs +132 -20
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { getFontByName } from "../lib/registry.mjs";
|
|
3
3
|
import {
|
|
4
|
-
|
|
4
|
+
ensureAstroFontsApiSetup,
|
|
5
5
|
isAstroProject,
|
|
6
6
|
writeAstrotypeCss,
|
|
7
7
|
} from "../lib/add-utils.mjs";
|
|
@@ -30,10 +30,18 @@ export async function addFontCommand(fontName, options = {}) {
|
|
|
30
30
|
process.exit(1);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
const
|
|
34
|
-
const cssText = `${fontImports}
|
|
35
|
-
|
|
36
|
-
${toCssRules(font)}`;
|
|
33
|
+
const cssText = `${toCssRules(font)}`;
|
|
37
34
|
const cssPath = writeAstrotypeCss(targetDir, font.name, cssText);
|
|
35
|
+
const fontsSetup = ensureAstroFontsApiSetup(targetDir, [font]);
|
|
38
36
|
console.log(`Installed font "${font.name}" into ${path.relative(targetDir, cssPath)}.`);
|
|
37
|
+
if (fontsSetup.configured) {
|
|
38
|
+
console.log("Configured Astro Fonts API entries for this font.");
|
|
39
|
+
if (fontsSetup.manualMergeRequired) {
|
|
40
|
+
console.log(
|
|
41
|
+
`Detected an existing fonts config in ${path.relative(targetDir, fontsSetup.configPath)}; merge astrotypeFonts manually there.`
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
} else {
|
|
45
|
+
console.log(`Skipped Astro Fonts API setup: ${fontsSetup.reason}`);
|
|
46
|
+
}
|
|
39
47
|
}
|
package/cli/commands/add.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { getFontByName, getPairingByName } from "../lib/registry.mjs";
|
|
3
3
|
import {
|
|
4
|
-
|
|
4
|
+
ensureAstroFontsApiSetup,
|
|
5
5
|
isAstroProject,
|
|
6
6
|
writeAstrotypeCss,
|
|
7
7
|
} from "../lib/add-utils.mjs";
|
|
@@ -40,14 +40,22 @@ export async function addPairingCommand(pairingName, options = {}) {
|
|
|
40
40
|
process.exit(1);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
const
|
|
44
|
-
const cssText = `${fontImports}
|
|
45
|
-
|
|
46
|
-
${toCssRules(pairing.css)}
|
|
43
|
+
const cssText = `${toCssRules(pairing.css)}
|
|
47
44
|
`;
|
|
48
45
|
const pairingCssPath = writeAstrotypeCss(targetDir, pairing.name, cssText);
|
|
46
|
+
const fontsSetup = ensureAstroFontsApiSetup(targetDir, fonts);
|
|
49
47
|
|
|
50
48
|
console.log(`Installed pairing "${pairing.name}" into ${path.relative(targetDir, pairingCssPath)}.`);
|
|
49
|
+
if (fontsSetup.configured) {
|
|
50
|
+
console.log("Configured Astro Fonts API entries for this pairing.");
|
|
51
|
+
if (fontsSetup.manualMergeRequired) {
|
|
52
|
+
console.log(
|
|
53
|
+
`Detected an existing fonts config in ${path.relative(targetDir, fontsSetup.configPath)}; merge astrotypeFonts manually there.`
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
console.log(`Skipped Astro Fonts API setup: ${fontsSetup.reason}`);
|
|
58
|
+
}
|
|
51
59
|
console.log("No Tailwind color utilities are required; styles are CSS-token driven.");
|
|
52
60
|
}
|
|
53
61
|
|
package/cli/lib/add-utils.mjs
CHANGED
|
@@ -22,28 +22,140 @@ export function isAstroProject(targetDir) {
|
|
|
22
22
|
);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
);
|
|
25
|
+
function toAstroFontDescriptor(font) {
|
|
26
|
+
if (!font?.font?.provider) return null;
|
|
27
|
+
const provider = String(font.font.provider).toLowerCase();
|
|
28
|
+
const cssVariable = font.font.variable || `--font-${font.name}`;
|
|
29
|
+
if (provider === "google") {
|
|
30
|
+
return {
|
|
31
|
+
name: font.name,
|
|
32
|
+
familyName: font.title,
|
|
33
|
+
cssVariable,
|
|
34
|
+
provider: "google",
|
|
35
|
+
options: null,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (provider === "npm") {
|
|
39
|
+
const npmPackage = font.font.npmPackage || font.font.package;
|
|
40
|
+
if (!npmPackage) return null;
|
|
41
|
+
let file = null;
|
|
42
|
+
if (npmPackage === "geist") {
|
|
43
|
+
if (font.name === "geist") file = "font/sans.css";
|
|
44
|
+
if (font.name === "geist-mono") file = "font/mono.css";
|
|
44
45
|
}
|
|
46
|
+
return {
|
|
47
|
+
name: font.name,
|
|
48
|
+
familyName: font.title,
|
|
49
|
+
cssVariable,
|
|
50
|
+
provider: "npm",
|
|
51
|
+
options: {
|
|
52
|
+
package: npmPackage,
|
|
53
|
+
...(file ? { file } : {}),
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function serializeAstroFontDescriptor(descriptor) {
|
|
61
|
+
const optionsLine = descriptor.options
|
|
62
|
+
? `,\n options: ${JSON.stringify(descriptor.options)}`
|
|
63
|
+
: "";
|
|
64
|
+
return ` {
|
|
65
|
+
provider: fontProviders.${descriptor.provider}(),
|
|
66
|
+
name: ${JSON.stringify(descriptor.familyName)},
|
|
67
|
+
cssVariable: ${JSON.stringify(descriptor.cssVariable)}${optionsLine}
|
|
68
|
+
}`;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function getAstroConfigPath(targetDir) {
|
|
72
|
+
const astroConfigCandidates = [
|
|
73
|
+
"astro.config.mjs",
|
|
74
|
+
"astro.config.js",
|
|
75
|
+
"astro.config.ts",
|
|
76
|
+
"astro.config.cjs",
|
|
77
|
+
];
|
|
78
|
+
for (const file of astroConfigCandidates) {
|
|
79
|
+
const filePath = path.join(targetDir, file);
|
|
80
|
+
if (fs.existsSync(filePath)) return filePath;
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function ensureAstroConfigHasAstrotypeImport(configText) {
|
|
86
|
+
const importLine = 'import { astrotypeFonts } from "./src/astrotypes/fonts.mjs";';
|
|
87
|
+
if (configText.includes(importLine)) return configText;
|
|
88
|
+
const defineConfigImportRegex = /import\s*\{[^}]*defineConfig[^}]*\}\s*from\s*["']astro\/config["'];?\n?/;
|
|
89
|
+
const match = configText.match(defineConfigImportRegex);
|
|
90
|
+
if (!match) return configText;
|
|
91
|
+
return configText.replace(match[0], `${match[0]}${importLine}\n`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function ensureAstroConfigHasFontsProperty(configText) {
|
|
95
|
+
if (/\bfonts\s*:/.test(configText)) return { text: configText, injected: false };
|
|
96
|
+
let next = configText.replace(
|
|
97
|
+
/defineConfig\(\s*\{/,
|
|
98
|
+
"defineConfig({\n fonts: astrotypeFonts,"
|
|
99
|
+
);
|
|
100
|
+
next = next.replace(/fonts: astrotypeFonts,\s*\}\);/m, "fonts: astrotypeFonts,\n});");
|
|
101
|
+
return { text: next, injected: next !== configText };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function ensureAstroFontsApiSetup(targetDir, fontEntries) {
|
|
105
|
+
const descriptors = fontEntries.map(toAstroFontDescriptor).filter(Boolean);
|
|
106
|
+
if (descriptors.length === 0) {
|
|
107
|
+
return {
|
|
108
|
+
configured: false,
|
|
109
|
+
reason: "No compatible providers found for Astro Fonts API.",
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const astrotypeDir = path.join(targetDir, "src", "astrotypes");
|
|
114
|
+
ensureDir(astrotypeDir);
|
|
115
|
+
const statePath = path.join(astrotypeDir, "fonts.state.json");
|
|
116
|
+
const prior = fs.existsSync(statePath)
|
|
117
|
+
? JSON.parse(fs.readFileSync(statePath, "utf-8"))
|
|
118
|
+
: [];
|
|
119
|
+
const byVariable = new Map();
|
|
120
|
+
for (const entry of prior) {
|
|
121
|
+
if (entry?.cssVariable) byVariable.set(entry.cssVariable, entry);
|
|
45
122
|
}
|
|
46
|
-
|
|
123
|
+
for (const descriptor of descriptors) {
|
|
124
|
+
byVariable.set(descriptor.cssVariable, descriptor);
|
|
125
|
+
}
|
|
126
|
+
const merged = [...byVariable.values()].sort((a, b) =>
|
|
127
|
+
a.cssVariable.localeCompare(b.cssVariable)
|
|
128
|
+
);
|
|
129
|
+
fs.writeFileSync(statePath, `${JSON.stringify(merged, null, 2)}\n`);
|
|
130
|
+
|
|
131
|
+
const modulePath = path.join(astrotypeDir, "fonts.mjs");
|
|
132
|
+
const lines = merged.map((entry) => serializeAstroFontDescriptor(entry)).join(",\n");
|
|
133
|
+
const moduleText = `import { fontProviders } from "astro/config";
|
|
134
|
+
|
|
135
|
+
export const astrotypeFonts = [
|
|
136
|
+
${lines}
|
|
137
|
+
];
|
|
138
|
+
`;
|
|
139
|
+
fs.writeFileSync(modulePath, moduleText);
|
|
140
|
+
|
|
141
|
+
const astroConfigPath = getAstroConfigPath(targetDir);
|
|
142
|
+
if (!astroConfigPath) {
|
|
143
|
+
return {
|
|
144
|
+
configured: false,
|
|
145
|
+
reason: "No astro.config.* file found.",
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
let configText = fs.readFileSync(astroConfigPath, "utf-8");
|
|
150
|
+
configText = ensureAstroConfigHasAstrotypeImport(configText);
|
|
151
|
+
const result = ensureAstroConfigHasFontsProperty(configText);
|
|
152
|
+
fs.writeFileSync(astroConfigPath, result.text);
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
configured: true,
|
|
156
|
+
configPath: astroConfigPath,
|
|
157
|
+
manualMergeRequired: !result.injected && /\bfonts\s*:/.test(configText),
|
|
158
|
+
};
|
|
47
159
|
}
|
|
48
160
|
|
|
49
161
|
export function ensureImport(globalCssPath, importLine) {
|