@vettvangur/design-system 0.0.2 → 0.0.4

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.
@@ -0,0 +1,536 @@
1
+ #!/usr/bin/env node
2
+ import { promises } from 'node:fs';
3
+ import path from 'node:path';
4
+ import process from 'node:process';
5
+ import { p as parseColors, a as parseTypography, i as inputsSpec } from './inputs-BBITK9zz.js';
6
+ import 'node:url';
7
+
8
+ const CWD = process.cwd();
9
+
10
+ // Generated components
11
+ const OUT_DIR = path.resolve(CWD, 'src/astrobook/components');
12
+ const OUT_PREVIEW = path.join(OUT_DIR, 'Preview.astro'); // <-- new
13
+ const OUT_COLORS = path.join(OUT_DIR, 'Colors.astro');
14
+ const OUT_BODIES = path.join(OUT_DIR, 'Bodies.astro');
15
+ const OUT_HEADLINES = path.join(OUT_DIR, 'Headlines.astro');
16
+ const OUT_BUTTONS = path.join(OUT_DIR, 'Buttons.astro');
17
+ const OUT_INPUTS = path.join(OUT_DIR, 'Inputs.astro');
18
+ const OUT_RICHTEXT = path.join(OUT_DIR, 'Richtext.astro');
19
+ const OUT_TABLES = path.join(OUT_DIR, 'Tables.astro'); // <-- added
20
+
21
+ // Story folders
22
+ const ASTROBOOK_DIR = path.resolve(CWD, 'src/astrobook');
23
+ const OUT_DIR_TYPOGRAPHY = path.join(ASTROBOOK_DIR, 'Typography');
24
+ const OUT_DIR_UI = path.join(ASTROBOOK_DIR, 'UI');
25
+ const OUT_DIR_COLORS = path.join(ASTROBOOK_DIR, 'Colors');
26
+ async function generateAstro() {
27
+ // ensure dirs
28
+ await promises.mkdir(OUT_DIR, {
29
+ recursive: true
30
+ });
31
+ await promises.mkdir(ASTROBOOK_DIR, {
32
+ recursive: true
33
+ });
34
+ await promises.mkdir(OUT_DIR_TYPOGRAPHY, {
35
+ recursive: true
36
+ });
37
+ await promises.mkdir(OUT_DIR_UI, {
38
+ recursive: true
39
+ });
40
+ await promises.mkdir(OUT_DIR_COLORS, {
41
+ recursive: true
42
+ });
43
+
44
+ // write Preview.astro (to a FILE, not the folder)
45
+ await promises.writeFile(OUT_PREVIEW, generatePreview(), 'utf8');
46
+ console.log(`✓ Wrote ${rel(OUT_PREVIEW)} (Preview)`);
47
+
48
+ // write story files
49
+ await renderStoriesAstro();
50
+ const [colors, typography, buttons] = await Promise.all([parseColors(), parseTypography()
51
+ //parseButtons(),
52
+ ]);
53
+
54
+ // Colors -> Colors.astro
55
+ if (colors?.length) {
56
+ await promises.writeFile(OUT_COLORS, renderColorsAstro(colors), 'utf8');
57
+ console.log(`✓ Wrote ${rel(OUT_COLORS)} (${colors.length} swatches)`);
58
+ } else {
59
+ console.warn('• No colors parsed — Colors.astro not written');
60
+ }
61
+
62
+ // Bodies -> Bodies.astro
63
+ if (typography?.bodies?.length) {
64
+ await promises.writeFile(OUT_BODIES, renderBodiesAstro(typography.bodies), 'utf8');
65
+ console.log(`✓ Wrote ${rel(OUT_BODIES)} (${typography.bodies.length} bodies)`);
66
+ } else {
67
+ console.warn('• No bodies parsed — Bodies.astro not written');
68
+ }
69
+
70
+ // Headlines -> Headlines.astro
71
+ if (typography?.headlines?.length) {
72
+ await promises.writeFile(OUT_HEADLINES, renderHeadlinesAstro(typography.headlines), 'utf8');
73
+ console.log(`✓ Wrote ${rel(OUT_HEADLINES)} (${typography.headlines.length} headlines)`);
74
+ } else {
75
+ console.warn('• No headlines parsed — Headlines.astro not written');
76
+ }
77
+
78
+ // Buttons -> Buttons.astro
79
+ if (buttons?.length) {
80
+ await promises.writeFile(OUT_BUTTONS, renderButtonsAstro(buttons), 'utf8');
81
+ console.log(`✓ Wrote ${rel(OUT_BUTTONS)} (${buttons.length} buttons)`);
82
+ } else {
83
+ console.warn('• No buttons parsed — Buttons.astro not written');
84
+ }
85
+
86
+ // Inputs -> Inputs.astro
87
+ const hasAnyInputs = Object.values(inputsSpec).some(arr => Array.isArray(arr) && arr.length);
88
+ if (hasAnyInputs) {
89
+ await promises.writeFile(OUT_INPUTS, renderInputsAstro(inputsSpec), 'utf8');
90
+ console.log(`✓ Wrote ${rel(OUT_INPUTS)} (inputs:${inputsSpec.inputs?.length ?? 0} selects:${inputsSpec.selects?.length ?? 0} ` + `checkboxes:${inputsSpec.checkboxes?.length ?? 0} radios:${inputsSpec.radios?.length ?? 0} textareas:${inputsSpec.textareas?.length ?? 0})`);
91
+ } else {
92
+ console.warn('• No input spec items — Inputs.astro not written');
93
+ }
94
+
95
+ // Richtext -> Richtext.astro (static specimen)
96
+ await promises.writeFile(OUT_RICHTEXT, renderRichtextAstro(), 'utf8');
97
+ console.log(`✓ Wrote ${rel(OUT_RICHTEXT)} (Richtext)`);
98
+
99
+ // Tables -> Tables.astro (static specimen)
100
+ await promises.writeFile(OUT_TABLES, renderTablesAstro(), 'utf8');
101
+ console.log(`✓ Wrote ${rel(OUT_TABLES)} (Tables)`);
102
+ }
103
+
104
+ /* ---------- story writers ---------- */
105
+
106
+ async function renderStoriesAstro() {
107
+ const storyBody = generateStoryBody();
108
+ const storyColors = generateStoryColors();
109
+ const storyHeadline = generateStoryHeadline();
110
+ const storyButton = generateStoryButtons();
111
+ const storyInputs = generateStoryInputs();
112
+ const storyRichtext = generateStoryRichtext();
113
+ const storyTables = generateStoryTables(); // <-- added
114
+
115
+ const FILE_BODY = path.join(OUT_DIR_TYPOGRAPHY, 'Body.stories.ts');
116
+ const FILE_HEADLINES = path.join(OUT_DIR_TYPOGRAPHY, 'Headlines.stories.ts');
117
+ const FILE_RICHTEXT = path.join(OUT_DIR_TYPOGRAPHY, 'Richtext.stories.ts');
118
+ const FILE_BUTTONS = path.join(OUT_DIR_UI, 'Buttons.stories.ts');
119
+ const FILE_INPUTS = path.join(OUT_DIR_UI, 'Inputs.stories.ts');
120
+ const FILE_TABLES = path.join(OUT_DIR_UI, 'Tables.stories.ts'); // <-- added
121
+ const FILE_COLORS = path.join(OUT_DIR_COLORS, 'Colors.stories.ts');
122
+ await promises.writeFile(FILE_BODY, storyBody, 'utf8');
123
+ await promises.writeFile(FILE_HEADLINES, storyHeadline, 'utf8');
124
+ await promises.writeFile(FILE_RICHTEXT, storyRichtext, 'utf8');
125
+ await promises.writeFile(FILE_BUTTONS, storyButton, 'utf8');
126
+ await promises.writeFile(FILE_INPUTS, storyInputs, 'utf8');
127
+ await promises.writeFile(FILE_TABLES, storyTables, 'utf8'); // <-- added
128
+ await promises.writeFile(FILE_COLORS, storyColors, 'utf8');
129
+ console.log('✓ Wrote story files:');
130
+ console.log(` - ${rel(FILE_BODY)}`);
131
+ console.log(` - ${rel(FILE_HEADLINES)}`);
132
+ console.log(` - ${rel(FILE_RICHTEXT)}`);
133
+ console.log(` - ${rel(FILE_BUTTONS)}`);
134
+ console.log(` - ${rel(FILE_INPUTS)}`);
135
+ console.log(` - ${rel(FILE_TABLES)}`);
136
+ console.log(` - ${rel(FILE_COLORS)}`);
137
+ }
138
+
139
+ /* ---------- code gens ---------- */
140
+
141
+ function generatePreview() {
142
+ return `
143
+ ---
144
+ /** Auto-generated - do not edit by hand */
145
+ import '@/styles/main.css'
146
+ import Fonts from '@/components/core/utility/Fonts.astro'
147
+ ---
148
+ <Fonts />
149
+ <div class="astrobook-preview bg-background">
150
+ <slot />
151
+ </div>
152
+ `.trimStart();
153
+ }
154
+ function generateStoryBody() {
155
+ return `
156
+ // Auto-generated — do not edit by hand
157
+ import Preview from '@/astrobook/components/Preview.astro'
158
+ import Bodies from '@/astrobook/components/Bodies.astro'
159
+
160
+ export default {
161
+ title: 'Typography/Body',
162
+ component: Bodies,
163
+ }
164
+
165
+ export const Overview = {
166
+ render: () => Preview({ slots: { default: Bodies({}) } }),
167
+ }
168
+ `.trimStart();
169
+ }
170
+ function generateStoryColors() {
171
+ return `
172
+ // Auto-generated — do not edit by hand
173
+ import Preview from '@/astrobook/components/Preview.astro'
174
+ import Colors from '@/astrobook/components/Colors.astro'
175
+
176
+ export default {
177
+ title: 'Colors',
178
+ component: Colors,
179
+ }
180
+
181
+ export const Overview = {
182
+ render: () => Preview({ slots: { default: Colors({}) } }),
183
+ }
184
+ `.trimStart();
185
+ }
186
+ function generateStoryHeadline() {
187
+ return `
188
+ // Auto-generated — do not edit by hand
189
+ import Preview from '@/astrobook/components/Preview.astro'
190
+ import Headlines from '@/astrobook/components/Headlines.astro'
191
+
192
+ export default {
193
+ title: 'Typography/Headlines',
194
+ component: Headlines,
195
+ }
196
+
197
+ export const Overview = {
198
+ render: () => Preview({ slots: { default: Headlines({}) } }),
199
+ }
200
+ `.trimStart();
201
+ }
202
+ function generateStoryButtons() {
203
+ return `
204
+ // Auto-generated — do not edit by hand
205
+ import Preview from '@/astrobook/components/Preview.astro'
206
+ import Buttons from '@/astrobook/components/Buttons.astro'
207
+
208
+ export default {
209
+ title: 'UI/Buttons',
210
+ component: Buttons,
211
+ }
212
+
213
+ export const Overview = {
214
+ render: () => Preview({ slots: { default: Buttons({}) } }),
215
+ }
216
+ `.trimStart();
217
+ }
218
+ function generateStoryInputs() {
219
+ return `
220
+ // Auto-generated — do not edit by hand
221
+ import Preview from '@/astrobook/components/Preview.astro'
222
+ import Inputs from '@/astrobook/components/Inputs.astro'
223
+
224
+ export default {
225
+ title: 'UI/Inputs',
226
+ component: Inputs,
227
+ }
228
+
229
+ export const Overview = {
230
+ render: () => Preview({ slots: { default: Inputs({}) } }),
231
+ }
232
+ `.trimStart();
233
+ }
234
+ function generateStoryRichtext() {
235
+ return `
236
+ // Auto-generated — do not edit by hand
237
+ import Preview from '@/astrobook/components/Preview.astro'
238
+ import Richtext from '@/astrobook/components/Richtext.astro'
239
+
240
+ export default {
241
+ title: 'Typography/Richtext',
242
+ component: Richtext,
243
+ }
244
+
245
+ export const Overview = {
246
+ render: () => Preview({ slots: { default: Richtext({}) } }),
247
+ }
248
+ `.trimStart();
249
+ }
250
+ function generateStoryTables() {
251
+ return `
252
+ // Auto-generated — do not edit by hand
253
+ import Preview from '@/astrobook/components/Preview.astro'
254
+ import Tables from '@/astrobook/components/Tables.astro'
255
+
256
+ export default {
257
+ title: 'UI/Tables',
258
+ component: Tables,
259
+ }
260
+
261
+ export const Overview = {
262
+ render: () => Preview({ slots: { default: Tables({}) } }),
263
+ }
264
+ `.trimStart();
265
+ }
266
+
267
+ /* ---------- renderers ---------- */
268
+
269
+ function renderColorsAstro(colors) {
270
+ const items = colors.map(({
271
+ title,
272
+ color,
273
+ class: klass
274
+ }) => {
275
+ const style = `background:${color};`;
276
+ return `
277
+ <div class="flex items-center gap-4 p-3 rounded border border-black/10 bg-white/5">
278
+ <div class="size-10 rounded shadow-inner ring-1 ring-black/10" style="${style}"></div>
279
+ <div class="flex flex-col text-sm">
280
+ <span class="font-medium">${e(title)}</span>
281
+ <span class="opacity-70">token: <code>--color-${e(klass.replace(/^x-/, ''))}</code></span>
282
+ <span class="opacity-70">class: <code>${e(klass)}</code></span>
283
+ <span class="opacity-70">value: <code>${e(color)}</code></span>
284
+ </div>
285
+ </div>`.trim();
286
+ });
287
+ return `---
288
+ /* Auto-generated — do not edit by hand */
289
+ ---
290
+ <div class="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
291
+ ${items.join('\n')}
292
+ </div>
293
+ `;
294
+ }
295
+ function renderBodiesAstro(bodies) {
296
+ const items = bodies.map(b => {
297
+ const meta = metaText(b.size, b.lineheight, b.config);
298
+ return ` <p class="${a(b.class)}">${e(b.title)} ${meta}</p>`;
299
+ });
300
+ return `---
301
+ /* Auto-generated — do not edit by hand */
302
+ ---
303
+ <div class="space-y-4">
304
+ ${items.join('\n')}
305
+ </div>
306
+ `;
307
+ }
308
+ function renderHeadlinesAstro(headlines) {
309
+ const lines = headlines.map(h => {
310
+ const meta = metaText(h.size, h.lineheight, h.config);
311
+ return ` <div class="flex items-baseline gap-2">
312
+ <Headline size="2" text="${a(h.title)}" class="${a(h.class)}" />
313
+ ${meta}
314
+ </div>`;
315
+ });
316
+ return `---
317
+ /* Auto-generated — do not edit by hand */
318
+ import Headline from '@/components/core/Headline.astro'
319
+ ---
320
+ <div class="space-y-4">
321
+ ${lines.join('\n')}
322
+ </div>
323
+ `;
324
+ }
325
+ function renderButtonsAstro(buttons) {
326
+ const lines = buttons.map(b => {
327
+ const klass = b.class.trim(); // variants already @apply button; don't prepend "button"
328
+ return ` <div class="flex items-center gap-3">
329
+ <Button text="${a(b.text)}" modifier="${a(klass)}" />
330
+ <span class="text-sm opacity-70">${e(b.title)} — <code>${e(klass)}</code></span>
331
+ </div>`;
332
+ });
333
+ return `---
334
+ /* Auto-generated — do not edit by hand */
335
+ import Button from '@/components/core/button/Button.astro' /* adjust if path differs */
336
+ ---
337
+ <div class="space-y-3">
338
+ ${lines.join('\n')}
339
+ </div>
340
+ `;
341
+ }
342
+ function renderInputsAstro(spec) {
343
+ const {
344
+ inputs = [],
345
+ selects = [],
346
+ checkboxes = [],
347
+ radios = [],
348
+ textareas = []
349
+ } = spec;
350
+ const renderGroup = (title, componentTag, items) => {
351
+ if (!items?.length) {
352
+ return '';
353
+ }
354
+ const rows = items.map(obj => ` <${componentTag} ${attrs(obj)} />`).join('\n');
355
+ return `
356
+ <section>
357
+ <h3 class="text-sm opacity-70 mb-2">${e(title)}</h3>
358
+ ${rows}
359
+ </section>`;
360
+ };
361
+ return `---
362
+ /* Auto-generated — do not edit by hand */
363
+ import Input from '@/components/core/inputs/Input.astro'
364
+ import Select from '@/components/core/inputs/Select.astro'
365
+ import Selection from '@/components/core/inputs/Selection.astro'
366
+ ---
367
+ <div class="space-y-8">
368
+ ${renderGroup('Inputs', 'Input', inputs)}
369
+ ${renderGroup('Selects', 'Select', selects)}
370
+ ${renderGroup('Checkboxes', 'Selection', checkboxes)}
371
+ ${renderGroup('Radios', 'Selection', radios)}
372
+ ${renderGroup('Textareas', 'Select', textareas)}
373
+ </div>
374
+ `;
375
+ }
376
+ function renderRichtextAstro() {
377
+ return `---
378
+ /* Auto-generated — do not edit by hand */
379
+ import Headline from '@/components/core/Headline.astro'
380
+ ---
381
+ <section class="w-full">
382
+ <Headline
383
+ text="Richtext"
384
+ size="1"
385
+ class="headline-1 mb-[60px]"
386
+ />
387
+
388
+ <div class="richtext">
389
+ <h1>h1</h1>
390
+ <h2>h2</h2>
391
+ <h3>h3</h3>
392
+ <h4>h4</h4>
393
+ <h5>h5</h5>
394
+ <p>
395
+ Ófróðlegt þorviðar <a href="https://www.vettvangur.is/" target="_blank">látist kærðu</a>, allfeginn því að kaupmanni, <strong>hraðasta</strong> ættleri <em>farminum</em> þuríði brústeinunum konungsþræll grænar. Hólmganga hrísflekkur, lifum skalla-grímur tíkr. Meiðinn hatast oddleifsdóttir, dólglegast dyflini, torfafóstri torfunni rak jarðarmenið stirðir. Býsn hvé ölseljunni gerði, jafnvitur lög vaskligr, sám hvortveggja ófrelsi trúfasti hallkelsdóttur sneri mund guðmundarsonum. Sekum meginmerkurinnar, arfsali allmikilli sjaldgæf. Uggasyni sættu konungsþræll gæs, alþýðuskap orðtækið stokkar, orkar mund ormláðs skrumaði hriflusonar virðak. Biðjum meiðinn keppa, taliðr uggasyni, skerðan manngjarnlega hofgyðja vilk allmikilli. Ógott hirðum samdóma, heimamaðr endilangt, erlingur kaldur gjósa seimþollr hallkell landkaupi. Torfunni tungu-oddur þorviðar gufárós, ævifús sekur tröllskessa, umbanda rétttrúaður bráðan svörfuði nýt íþrótt dalalönd halli. Flyðruness haldnar aðsóknar skerðan, auðhnykkjanda mannvandur smálöndum sauðarhöfðinu ferjunni.
396
+ </p>
397
+ <ul>
398
+ <li>List item</li>
399
+ <li>List item</li>
400
+ <li>
401
+ List item
402
+ <ul>
403
+ <li>Nested item</li>
404
+ <li>Nested item</li>
405
+ <li>
406
+ Nested item
407
+ <ul>
408
+ <li>Nested even more item</li>
409
+ <li>Nested even more item</li>
410
+ <li>Nested even more item</li>
411
+ </ul>
412
+ </li>
413
+ </ul>
414
+ </li>
415
+ <li>List item</li>
416
+ </ul>
417
+ <ol>
418
+ <li>List item</li>
419
+ <li>
420
+ List item
421
+ <ol>
422
+ <li>Nested item</li>
423
+ <li>Nested item</li>
424
+ <li>Nested item</li>
425
+ </ol>
426
+ </li>
427
+ <li>List item</li>
428
+ <li>List item</li>
429
+ </ol>
430
+ <p>
431
+ Ófróðlegt þorviðar <a href="https://www.vettvangur.is/" target="_blank">látist kærðu</a>, allfeginn því að kaupmanni, hraðasta ættleri farminum þuríði brústeinunum konungsþræll grænar. Hólmganga hrísflekkur, lifum skalla-grímur tíkr. Meiðinn hatast oddleifsdóttir, dólglegast dyflini, torfafóstri torfunni rak jarðarmenið stirðir. Býsn hvé ölseljunni gerði, jafnvitur lög vaskligr, sám hvortveggja ófrelsi trúfasti hallkelsdóttur sneri mund guðmundarsonum. Sekum meginmerkurinnar, arfsali allmikilli sjaldgæf. Uggasyni sættu konungsþræll gæs, alþýðuskap orðtækið stokkar, orkar mund ormláðs skrumaði hriflusonar virðak. Biðjum meiðinn keppa, taliðr uggasyni, skerðan manngjarnlega hofgyðja vilk allmikilli. Ógott hirðum samdóma, heimamaðr endilangt, erlingur kaldur gjósa seimþollr hallkell landkaupi. Torfunni tungu-oddur þorviðar gufárós, ævifús sekur tröllskessa, umbanda rétttrúaður bráðan svörfuði nýt íþrótt dalalönd halli. Flyðruness haldnar aðsóknar skerðan, auðhnykkjanda mannvandur smálöndum sauðarhöfðinu ferjunni.
432
+ </p>
433
+ </div>
434
+ </section>
435
+ `.trimStart();
436
+ }
437
+ function renderTablesAstro() {
438
+ return `---
439
+ /* Auto-generated — do not edit by hand */
440
+ import Headline from '@/components/core/Headline.astro'
441
+ ---
442
+ <section class="w-full">
443
+ <Headline
444
+ text="Tables"
445
+ size="1"
446
+ class="headline-1 mb-20"
447
+ />
448
+
449
+ <div class="table">
450
+ <table class="table__element">
451
+ <thead>
452
+ <tr>
453
+ <th>Head</th>
454
+ <th>Head</th>
455
+ <th>Head</th>
456
+ <th>Head</th>
457
+ <th>Head</th>
458
+ </tr>
459
+ </thead>
460
+ <tbody>
461
+ <tr>
462
+ <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td>
463
+ </tr>
464
+ <tr>
465
+ <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td>
466
+ </tr>
467
+ <tr>
468
+ <td>1</td><td>2</td><td>3</td><td>4</td><td>5</td>
469
+ </tr>
470
+ </tbody>
471
+ </table>
472
+ </div>
473
+ </section>
474
+ `.trimStart();
475
+ }
476
+
477
+ /* ---------- helpers ---------- */
478
+
479
+ function attrs(obj = {}) {
480
+ const parts = [];
481
+ for (const [key, val] of Object.entries(obj)) {
482
+ if (val === '' || val === null || val === undefined || val === false) {
483
+ continue;
484
+ }
485
+ if (typeof val === 'string') {
486
+ parts.push(`${key}="${a(val)}"`);
487
+ } else if (typeof val === 'number') {
488
+ parts.push(`${key}={${val}}`);
489
+ } else if (typeof val === 'boolean') {
490
+ parts.push(`${key}={true}`);
491
+ } else {
492
+ parts.push(`${key}={${JSON.stringify(val)}}`);
493
+ }
494
+ }
495
+ return parts.join(' ');
496
+ }
497
+ function metaText(size, lineheight, config) {
498
+ const basePair = pair({
499
+ size,
500
+ lineHeight: lineheight
501
+ });
502
+ const parts = [];
503
+ if (config?.desktop && (config.desktop.size || config.desktop.lineHeight)) {
504
+ parts.push(`D: ${pair(config.desktop)}`);
505
+ }
506
+ if (config?.mobile && (config.mobile.size || config.mobile.lineHeight)) {
507
+ parts.push(`M: ${pair(config.mobile)}`);
508
+ }
509
+ const label = parts.length ? parts.join(' • ') : basePair;
510
+ if (!label) {
511
+ return '';
512
+ }
513
+ return `<span class="opacity-60 text-sm">${e(label)}</span>`;
514
+ }
515
+ function pair({
516
+ size,
517
+ lineHeight
518
+ } = {}) {
519
+ const s = size ?? null;
520
+ const l = lineHeight ?? null;
521
+ if (!s && !l) {
522
+ return '';
523
+ }
524
+ return `${s ?? '-'} / ${l ?? '-'}`;
525
+ }
526
+ function e(s = '') {
527
+ return String(s).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;');
528
+ }
529
+ function a(s = '') {
530
+ return String(s).replaceAll('"', '&quot;');
531
+ }
532
+ function rel(p) {
533
+ return path.relative(process.cwd(), p);
534
+ }
535
+
536
+ export { generateAstro as default };