@anja.codes/vitakit 0.1.0
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/LICENSE +21 -0
- package/README.md +159 -0
- package/dist/check.d.mts +22 -0
- package/dist/check.mjs +196 -0
- package/dist/cli.d.mts +45 -0
- package/dist/cli.mjs +225 -0
- package/dist/index.d.mts +398 -0
- package/dist/index.mjs +21 -0
- package/dist/nuxt.d.mts +15 -0
- package/dist/nuxt.mjs +98 -0
- package/dist/runtime/components/VitaDate.vue +20 -0
- package/dist/runtime/components/VitaEntry.vue +24 -0
- package/dist/runtime/components/VitaIssues.vue +25 -0
- package/dist/runtime/components/VitaLinks.vue +19 -0
- package/dist/runtime/components/VitaMarkdown.vue +14 -0
- package/dist/runtime/components/VitaPublication.vue +30 -0
- package/dist/runtime/components/VitaPublications.vue +39 -0
- package/dist/runtime/components/VitaSection.vue +60 -0
- package/dist/runtime/composables/useVitakit.ts +47 -0
- package/dist/schemas/education.ts +21 -0
- package/dist/schemas/employment.ts +21 -0
- package/dist/schemas/publications.ts +48 -0
- package/dist/schemas/supervision.ts +20 -0
- package/dist/schemas/talks.ts +19 -0
- package/dist/schemas/teaching.ts +19 -0
- package/dist/shared/index.d.mts +68 -0
- package/dist/shared/index.mjs +57 -0
- package/dist/shared/vitakit.BRhjqpAt.mjs +250 -0
- package/dist/shared/vitakit.BlU-p01e.mjs +14 -0
- package/dist/shared/vitakit.BxcnlFGP.mjs +325 -0
- package/dist/shared/vitakit.CypCF-4Q.mjs +503 -0
- package/dist/shared/vitakit.D8WRg_Xx.d.mts +153 -0
- package/dist/styles/vitakit-math.csl +314 -0
- package/dist/tex/templates/_generic.eta +6 -0
- package/dist/tex/templates/education.eta +9 -0
- package/dist/tex/templates/employment.eta +9 -0
- package/dist/tex/templates/publications.eta +7 -0
- package/dist/tex/templates/supervision.eta +4 -0
- package/dist/tex/templates/talks.eta +3 -0
- package/dist/tex/templates/teaching.eta +6 -0
- package/dist/tex/vitakit-cv.cls +119 -0
- package/dist/tex.d.mts +93 -0
- package/dist/tex.mjs +129 -0
- package/package.json +121 -0
- package/src/bin/vitakit-build-cv.mjs +50 -0
- package/src/bin/vitakit-check.mjs +57 -0
- package/src/bin/vitakit.mjs +158 -0
- package/styles/vitakit-math.csl +314 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
import * as zod from 'zod';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export { z } from 'zod';
|
|
4
|
+
import { D as DateRange, V as Visibility, a as VitakitContent } from './shared/vitakit.D8WRg_Xx.mjs';
|
|
5
|
+
import { RichTextMarker } from './shared/index.mjs';
|
|
6
|
+
export { C as ContentIssue, b as DatePoint, E as Entry, c as EntryBase, I as Institution, L as Link, P as Page, d as Profile, e as Publication, f as PublicationBadge, g as PublicationGroup, h as RichText } from './shared/vitakit.D8WRg_Xx.mjs';
|
|
7
|
+
import { BadgeConfig } from '@behackl/citation-js-extras';
|
|
8
|
+
export { BadgeConfig, badgePresets } from '@behackl/citation-js-extras';
|
|
9
|
+
import * as zod_v4_core from 'zod/v4/core';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Paths on the website where a URL is expected: `slides: /slides/talk.pdf`,
|
|
13
|
+
* a file in `public/`.
|
|
14
|
+
*
|
|
15
|
+
* Validation cannot know where the site is served, so the `url` primitive
|
|
16
|
+
* only marks such a path, as `richText` marks its fields, and `loadContent`
|
|
17
|
+
* resolves every mark: for the website against the deployment base path, for
|
|
18
|
+
* the PDF against `profile.url`, the site's public address. The marker is
|
|
19
|
+
* internal and never appears in `VitakitContent`.
|
|
20
|
+
*/
|
|
21
|
+
/** The single property that identifies an unresolved site path. */
|
|
22
|
+
declare const PATH_KEY = "__vitakitPath";
|
|
23
|
+
interface SitePathMarker {
|
|
24
|
+
[PATH_KEY]: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Zod building blocks shared by the built-in schemas and available to users
|
|
29
|
+
* writing their own `schemas/*.ts`.
|
|
30
|
+
*
|
|
31
|
+
* Two rules keep user-written schemas consistent with built-in ones:
|
|
32
|
+
* - dates go through `dateRange`, so sorting and formatting behave the same
|
|
33
|
+
* - entries are strict objects, so a typo is an error rather than a silent
|
|
34
|
+
* missing field
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
declare const text: z.ZodString;
|
|
38
|
+
/**
|
|
39
|
+
* A field that may contain Markdown and mathematics, e.g. a talk or thesis
|
|
40
|
+
* title containing `$k$`.
|
|
41
|
+
*
|
|
42
|
+
* Validation cannot render it (the renderer needs the deployment base URL and
|
|
43
|
+
* can fail), so parsing only marks the value; `loadSection` renders every
|
|
44
|
+
* marker afterwards, turning it into `{ text, html }`.
|
|
45
|
+
*/
|
|
46
|
+
declare const richText: z.ZodPipe<z.ZodString, z.ZodTransform<RichTextMarker, string>>;
|
|
47
|
+
/**
|
|
48
|
+
* A link: an `http(s)` or `mailto` URL, or a path on the site such as
|
|
49
|
+
* `/slides/talk.pdf` (a file in `public/`). A path is marked here and resolved
|
|
50
|
+
* by `loadContent`, for the website against the deployment base path, for the
|
|
51
|
+
* PDF against `profile.url`.
|
|
52
|
+
*/
|
|
53
|
+
declare const url: z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>;
|
|
54
|
+
/**
|
|
55
|
+
* A single date or a span. Accepts, in order of how people actually write CVs:
|
|
56
|
+
*
|
|
57
|
+
* ```yaml
|
|
58
|
+
* date: 2024-03-15 # a point
|
|
59
|
+
* date: { from: 2019, to: 2023 }
|
|
60
|
+
* date: { from: 2023, to: present }
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
declare const dateRange: z.ZodPipe<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodObject<{
|
|
64
|
+
from: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
|
|
65
|
+
to: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodLiteral<"present">]>>;
|
|
66
|
+
}, z.core.$strict>]>, z.ZodTransform<DateRange, string | {
|
|
67
|
+
from: string;
|
|
68
|
+
to?: string | undefined;
|
|
69
|
+
}>>;
|
|
70
|
+
declare const institution: z.ZodUnion<readonly [z.ZodPipe<z.ZodString, z.ZodTransform<{
|
|
71
|
+
name: string;
|
|
72
|
+
}, string>>, z.ZodObject<{
|
|
73
|
+
name: z.ZodString;
|
|
74
|
+
url: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>>;
|
|
75
|
+
}, z.core.$strict>]>;
|
|
76
|
+
declare const link: z.ZodUnion<readonly [z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>, z.ZodTransform<{
|
|
77
|
+
label: string;
|
|
78
|
+
url: string | SitePathMarker;
|
|
79
|
+
}, string | SitePathMarker>>, z.ZodObject<{
|
|
80
|
+
label: z.ZodString;
|
|
81
|
+
url: z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>;
|
|
82
|
+
}, z.core.$strict>]>;
|
|
83
|
+
declare const visibility: z.ZodDefault<z.ZodEnum<Record<Visibility, Visibility>>>;
|
|
84
|
+
/**
|
|
85
|
+
* Wrap an entry shape so that every section entry supports `visibility`.
|
|
86
|
+
* Built-in and user schemas both go through this.
|
|
87
|
+
*/
|
|
88
|
+
declare function entry<Shape extends z.ZodRawShape>(shape: Shape): z.ZodObject<{
|
|
89
|
+
visibility: z.ZodDefault<z.ZodEnum<Record<Visibility, Visibility>>>;
|
|
90
|
+
} & Shape extends infer T ? { -readonly [P in keyof T]: T[P]; } : never, z.core.$strict>;
|
|
91
|
+
/** A list of entries: what a `content/<name>.yml` file must contain. */
|
|
92
|
+
declare function section<Shape extends z.ZodRawShape>(shape: Shape): z.ZodArray<z.ZodObject<{
|
|
93
|
+
visibility: z.ZodDefault<z.ZodEnum<Record<Visibility, Visibility>>>;
|
|
94
|
+
} & Shape extends infer T ? { -readonly [P in keyof T]: T[P]; } : never, z.core.$strict>>;
|
|
95
|
+
|
|
96
|
+
declare const _default$4: z.ZodArray<z.ZodObject<{
|
|
97
|
+
visibility: z.ZodDefault<z.ZodEnum<Record<Visibility, Visibility>>>;
|
|
98
|
+
date: z.ZodPipe<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodObject<{
|
|
99
|
+
from: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
|
|
100
|
+
to: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodLiteral<"present">]>>;
|
|
101
|
+
}, z.core.$strict>]>, z.ZodTransform<DateRange, string | {
|
|
102
|
+
from: string;
|
|
103
|
+
to?: string | undefined;
|
|
104
|
+
}>>;
|
|
105
|
+
degree: z.ZodString;
|
|
106
|
+
institution: z.ZodUnion<readonly [z.ZodPipe<z.ZodString, z.ZodTransform<{
|
|
107
|
+
name: string;
|
|
108
|
+
}, string>>, z.ZodObject<{
|
|
109
|
+
name: z.ZodString;
|
|
110
|
+
url: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>>;
|
|
111
|
+
}, z.core.$strict>]>;
|
|
112
|
+
thesis: z.ZodOptional<z.ZodObject<{
|
|
113
|
+
title: z.ZodPipe<z.ZodString, z.ZodTransform<RichTextMarker, string>>;
|
|
114
|
+
type: z.ZodOptional<z.ZodString>;
|
|
115
|
+
supervisor: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodUnion<readonly [z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>, z.ZodTransform<{
|
|
116
|
+
label: string;
|
|
117
|
+
url: string | SitePathMarker;
|
|
118
|
+
}, string | SitePathMarker>>, z.ZodObject<{
|
|
119
|
+
label: z.ZodString;
|
|
120
|
+
url: z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>;
|
|
121
|
+
}, z.core.$strict>]>]>>;
|
|
122
|
+
url: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>>;
|
|
123
|
+
}, z.core.$strict>>;
|
|
124
|
+
note: z.ZodOptional<z.ZodString>;
|
|
125
|
+
}, z.core.$strict>>;
|
|
126
|
+
|
|
127
|
+
declare const _default$3: z.ZodArray<z.ZodObject<{
|
|
128
|
+
visibility: z.ZodDefault<z.ZodEnum<Record<Visibility, Visibility>>>;
|
|
129
|
+
date: z.ZodPipe<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodObject<{
|
|
130
|
+
from: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
|
|
131
|
+
to: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodLiteral<"present">]>>;
|
|
132
|
+
}, z.core.$strict>]>, z.ZodTransform<DateRange, string | {
|
|
133
|
+
from: string;
|
|
134
|
+
to?: string | undefined;
|
|
135
|
+
}>>;
|
|
136
|
+
position: z.ZodString;
|
|
137
|
+
institution: z.ZodUnion<readonly [z.ZodPipe<z.ZodString, z.ZodTransform<{
|
|
138
|
+
name: string;
|
|
139
|
+
}, string>>, z.ZodObject<{
|
|
140
|
+
name: z.ZodString;
|
|
141
|
+
url: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>>;
|
|
142
|
+
}, z.core.$strict>]>;
|
|
143
|
+
project: z.ZodOptional<z.ZodObject<{
|
|
144
|
+
title: z.ZodPipe<z.ZodString, z.ZodTransform<RichTextMarker, string>>;
|
|
145
|
+
funder: z.ZodOptional<z.ZodString>;
|
|
146
|
+
grant: z.ZodOptional<z.ZodString>;
|
|
147
|
+
url: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>>;
|
|
148
|
+
}, z.core.$strict>>;
|
|
149
|
+
note: z.ZodOptional<z.ZodString>;
|
|
150
|
+
}, z.core.$strict>>;
|
|
151
|
+
|
|
152
|
+
declare const _default$2: zod.ZodArray<zod.ZodObject<{
|
|
153
|
+
visibility: zod.ZodDefault<zod.ZodEnum<Record<Visibility, Visibility>>>;
|
|
154
|
+
date: zod.ZodPipe<zod.ZodUnion<readonly [zod.ZodPipe<zod.ZodUnion<readonly [zod.ZodString, zod.ZodNumber]>, zod.ZodTransform<string, string | number>>, zod.ZodObject<{
|
|
155
|
+
from: zod.ZodPipe<zod.ZodUnion<readonly [zod.ZodString, zod.ZodNumber]>, zod.ZodTransform<string, string | number>>;
|
|
156
|
+
to: zod.ZodOptional<zod.ZodUnion<readonly [zod.ZodPipe<zod.ZodUnion<readonly [zod.ZodString, zod.ZodNumber]>, zod.ZodTransform<string, string | number>>, zod.ZodLiteral<"present">]>>;
|
|
157
|
+
}, zod_v4_core.$strict>]>, zod.ZodTransform<DateRange, string | {
|
|
158
|
+
from: string;
|
|
159
|
+
to?: string | undefined;
|
|
160
|
+
}>>;
|
|
161
|
+
title: zod.ZodPipe<zod.ZodString, zod.ZodTransform<RichTextMarker, string>>;
|
|
162
|
+
role: zod.ZodOptional<zod.ZodString>;
|
|
163
|
+
institution: zod.ZodOptional<zod.ZodUnion<readonly [zod.ZodPipe<zod.ZodString, zod.ZodTransform<{
|
|
164
|
+
name: string;
|
|
165
|
+
}, string>>, zod.ZodObject<{
|
|
166
|
+
name: zod.ZodString;
|
|
167
|
+
url: zod.ZodOptional<zod.ZodPipe<zod.ZodString, zod.ZodTransform<string | SitePathMarker, string>>>;
|
|
168
|
+
}, zod_v4_core.$strict>]>>;
|
|
169
|
+
term: zod.ZodOptional<zod.ZodString>;
|
|
170
|
+
url: zod.ZodOptional<zod.ZodPipe<zod.ZodString, zod.ZodTransform<string | SitePathMarker, string>>>;
|
|
171
|
+
note: zod.ZodOptional<zod.ZodString>;
|
|
172
|
+
}, zod_v4_core.$strict>>;
|
|
173
|
+
|
|
174
|
+
declare const _default$1: z.ZodArray<z.ZodObject<{
|
|
175
|
+
visibility: z.ZodDefault<z.ZodEnum<Record<Visibility, Visibility>>>;
|
|
176
|
+
date: z.ZodPipe<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodObject<{
|
|
177
|
+
from: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
|
|
178
|
+
to: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodLiteral<"present">]>>;
|
|
179
|
+
}, z.core.$strict>]>, z.ZodTransform<DateRange, string | {
|
|
180
|
+
from: string;
|
|
181
|
+
to?: string | undefined;
|
|
182
|
+
}>>;
|
|
183
|
+
title: z.ZodPipe<z.ZodString, z.ZodTransform<RichTextMarker, string>>;
|
|
184
|
+
event: z.ZodOptional<z.ZodString>;
|
|
185
|
+
location: z.ZodOptional<z.ZodString>;
|
|
186
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
187
|
+
invited: "invited";
|
|
188
|
+
contributed: "contributed";
|
|
189
|
+
seminar: "seminar";
|
|
190
|
+
poster: "poster";
|
|
191
|
+
outreach: "outreach";
|
|
192
|
+
}>>;
|
|
193
|
+
url: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>>;
|
|
194
|
+
slides: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>>;
|
|
195
|
+
}, z.core.$strict>>;
|
|
196
|
+
|
|
197
|
+
declare const _default: z.ZodArray<z.ZodObject<{
|
|
198
|
+
visibility: z.ZodDefault<z.ZodEnum<Record<Visibility, Visibility>>>;
|
|
199
|
+
date: z.ZodPipe<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodObject<{
|
|
200
|
+
from: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
|
|
201
|
+
to: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodLiteral<"present">]>>;
|
|
202
|
+
}, z.core.$strict>]>, z.ZodTransform<DateRange, string | {
|
|
203
|
+
from: string;
|
|
204
|
+
to?: string | undefined;
|
|
205
|
+
}>>;
|
|
206
|
+
student: z.ZodString;
|
|
207
|
+
ongoing: z.ZodDefault<z.ZodBoolean>;
|
|
208
|
+
title: z.ZodPipe<z.ZodString, z.ZodTransform<RichTextMarker, string>>;
|
|
209
|
+
degree: z.ZodOptional<z.ZodString>;
|
|
210
|
+
institution: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodString, z.ZodTransform<{
|
|
211
|
+
name: string;
|
|
212
|
+
}, string>>, z.ZodObject<{
|
|
213
|
+
name: z.ZodString;
|
|
214
|
+
url: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>>;
|
|
215
|
+
}, z.core.$strict>]>>;
|
|
216
|
+
coSupervisor: z.ZodOptional<z.ZodString>;
|
|
217
|
+
}, z.core.$strict>>;
|
|
218
|
+
|
|
219
|
+
/** Every built-in section, keyed by its `content/<name>.yml` file name. */
|
|
220
|
+
declare const schemas: {
|
|
221
|
+
readonly education: z.ZodArray<z.ZodObject<{
|
|
222
|
+
visibility: z.ZodDefault<z.ZodEnum<Record<Visibility, Visibility>>>;
|
|
223
|
+
date: z.ZodPipe<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodObject<{
|
|
224
|
+
from: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
|
|
225
|
+
to: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodLiteral<"present">]>>;
|
|
226
|
+
}, z.core.$strict>]>, z.ZodTransform<DateRange, string | {
|
|
227
|
+
from: string;
|
|
228
|
+
to?: string | undefined;
|
|
229
|
+
}>>;
|
|
230
|
+
degree: z.ZodString;
|
|
231
|
+
institution: z.ZodUnion<readonly [z.ZodPipe<z.ZodString, z.ZodTransform<{
|
|
232
|
+
name: string;
|
|
233
|
+
}, string>>, z.ZodObject<{
|
|
234
|
+
name: z.ZodString;
|
|
235
|
+
url: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>>;
|
|
236
|
+
}, z.core.$strict>]>;
|
|
237
|
+
thesis: z.ZodOptional<z.ZodObject<{
|
|
238
|
+
title: z.ZodPipe<z.ZodString, z.ZodTransform<RichTextMarker, string>>;
|
|
239
|
+
type: z.ZodOptional<z.ZodString>;
|
|
240
|
+
supervisor: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodUnion<readonly [z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>, z.ZodTransform<{
|
|
241
|
+
label: string;
|
|
242
|
+
url: string | SitePathMarker;
|
|
243
|
+
}, string | SitePathMarker>>, z.ZodObject<{
|
|
244
|
+
label: z.ZodString;
|
|
245
|
+
url: z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>;
|
|
246
|
+
}, z.core.$strict>]>]>>;
|
|
247
|
+
url: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>>;
|
|
248
|
+
}, z.core.$strict>>;
|
|
249
|
+
note: z.ZodOptional<z.ZodString>;
|
|
250
|
+
}, z.core.$strict>>;
|
|
251
|
+
readonly employment: z.ZodArray<z.ZodObject<{
|
|
252
|
+
visibility: z.ZodDefault<z.ZodEnum<Record<Visibility, Visibility>>>;
|
|
253
|
+
date: z.ZodPipe<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodObject<{
|
|
254
|
+
from: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
|
|
255
|
+
to: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodLiteral<"present">]>>;
|
|
256
|
+
}, z.core.$strict>]>, z.ZodTransform<DateRange, string | {
|
|
257
|
+
from: string;
|
|
258
|
+
to?: string | undefined;
|
|
259
|
+
}>>;
|
|
260
|
+
position: z.ZodString;
|
|
261
|
+
institution: z.ZodUnion<readonly [z.ZodPipe<z.ZodString, z.ZodTransform<{
|
|
262
|
+
name: string;
|
|
263
|
+
}, string>>, z.ZodObject<{
|
|
264
|
+
name: z.ZodString;
|
|
265
|
+
url: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>>;
|
|
266
|
+
}, z.core.$strict>]>;
|
|
267
|
+
project: z.ZodOptional<z.ZodObject<{
|
|
268
|
+
title: z.ZodPipe<z.ZodString, z.ZodTransform<RichTextMarker, string>>;
|
|
269
|
+
funder: z.ZodOptional<z.ZodString>;
|
|
270
|
+
grant: z.ZodOptional<z.ZodString>;
|
|
271
|
+
url: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>>;
|
|
272
|
+
}, z.core.$strict>>;
|
|
273
|
+
note: z.ZodOptional<z.ZodString>;
|
|
274
|
+
}, z.core.$strict>>;
|
|
275
|
+
readonly teaching: z.ZodArray<z.ZodObject<{
|
|
276
|
+
visibility: z.ZodDefault<z.ZodEnum<Record<Visibility, Visibility>>>;
|
|
277
|
+
date: z.ZodPipe<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodObject<{
|
|
278
|
+
from: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
|
|
279
|
+
to: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodLiteral<"present">]>>;
|
|
280
|
+
}, z.core.$strict>]>, z.ZodTransform<DateRange, string | {
|
|
281
|
+
from: string;
|
|
282
|
+
to?: string | undefined;
|
|
283
|
+
}>>;
|
|
284
|
+
title: z.ZodPipe<z.ZodString, z.ZodTransform<RichTextMarker, string>>;
|
|
285
|
+
role: z.ZodOptional<z.ZodString>;
|
|
286
|
+
institution: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodString, z.ZodTransform<{
|
|
287
|
+
name: string;
|
|
288
|
+
}, string>>, z.ZodObject<{
|
|
289
|
+
name: z.ZodString;
|
|
290
|
+
url: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>>;
|
|
291
|
+
}, z.core.$strict>]>>;
|
|
292
|
+
term: z.ZodOptional<z.ZodString>;
|
|
293
|
+
url: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>>;
|
|
294
|
+
note: z.ZodOptional<z.ZodString>;
|
|
295
|
+
}, z.core.$strict>>;
|
|
296
|
+
readonly talks: z.ZodArray<z.ZodObject<{
|
|
297
|
+
visibility: z.ZodDefault<z.ZodEnum<Record<Visibility, Visibility>>>;
|
|
298
|
+
date: z.ZodPipe<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodObject<{
|
|
299
|
+
from: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
|
|
300
|
+
to: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodLiteral<"present">]>>;
|
|
301
|
+
}, z.core.$strict>]>, z.ZodTransform<DateRange, string | {
|
|
302
|
+
from: string;
|
|
303
|
+
to?: string | undefined;
|
|
304
|
+
}>>;
|
|
305
|
+
title: z.ZodPipe<z.ZodString, z.ZodTransform<RichTextMarker, string>>;
|
|
306
|
+
event: z.ZodOptional<z.ZodString>;
|
|
307
|
+
location: z.ZodOptional<z.ZodString>;
|
|
308
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
309
|
+
invited: "invited";
|
|
310
|
+
contributed: "contributed";
|
|
311
|
+
seminar: "seminar";
|
|
312
|
+
poster: "poster";
|
|
313
|
+
outreach: "outreach";
|
|
314
|
+
}>>;
|
|
315
|
+
url: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>>;
|
|
316
|
+
slides: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>>;
|
|
317
|
+
}, z.core.$strict>>;
|
|
318
|
+
readonly supervision: z.ZodArray<z.ZodObject<{
|
|
319
|
+
visibility: z.ZodDefault<z.ZodEnum<Record<Visibility, Visibility>>>;
|
|
320
|
+
date: z.ZodPipe<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodObject<{
|
|
321
|
+
from: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
|
|
322
|
+
to: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodLiteral<"present">]>>;
|
|
323
|
+
}, z.core.$strict>]>, z.ZodTransform<DateRange, string | {
|
|
324
|
+
from: string;
|
|
325
|
+
to?: string | undefined;
|
|
326
|
+
}>>;
|
|
327
|
+
student: z.ZodString;
|
|
328
|
+
ongoing: z.ZodDefault<z.ZodBoolean>;
|
|
329
|
+
title: z.ZodPipe<z.ZodString, z.ZodTransform<RichTextMarker, string>>;
|
|
330
|
+
degree: z.ZodOptional<z.ZodString>;
|
|
331
|
+
institution: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodString, z.ZodTransform<{
|
|
332
|
+
name: string;
|
|
333
|
+
}, string>>, z.ZodObject<{
|
|
334
|
+
name: z.ZodString;
|
|
335
|
+
url: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string | SitePathMarker, string>>>;
|
|
336
|
+
}, z.core.$strict>]>>;
|
|
337
|
+
coSupervisor: z.ZodOptional<z.ZodString>;
|
|
338
|
+
}, z.core.$strict>>;
|
|
339
|
+
};
|
|
340
|
+
type BuiltinSection = keyof typeof schemas;
|
|
341
|
+
/**
|
|
342
|
+
* Extend a built-in section's *entry* shape, keeping the array wrapper.
|
|
343
|
+
*
|
|
344
|
+
* ```ts
|
|
345
|
+
* export default extendSection(schemas.teaching, { evaluationScore: z.number().optional() })
|
|
346
|
+
* ```
|
|
347
|
+
*/
|
|
348
|
+
declare function extendSection<Shape extends z.ZodRawShape>(base: z.ZodArray<z.ZodObject<z.ZodRawShape>>, shape: Shape): z.ZodArray<z.ZodObject<((string | number) & keyof Shape extends never ? Readonly<{
|
|
349
|
+
[k: string]: z.core.$ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
|
|
350
|
+
}> & { -readonly [P in keyof Shape]: Shape[P]; } : (Readonly<{
|
|
351
|
+
[k: string]: z.core.$ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
|
|
352
|
+
}> extends infer T_1 extends z.core.util.SomeObject ? { [K in keyof T_1 as K extends keyof Shape ? never : K]: T_1[K]; } : never) & { [K_1 in keyof { -readonly [P in keyof Shape]: Shape[P]; }]: { -readonly [P in keyof Shape]: Shape[P]; }[K_1]; }) extends infer T ? { [k in keyof T]: T[k]; } : never, z.core.$strip>>;
|
|
353
|
+
|
|
354
|
+
interface LoadContentOptions {
|
|
355
|
+
/** Throw on the first problem (builds) or collect them (dev). */
|
|
356
|
+
strict?: boolean;
|
|
357
|
+
/** Deployment base URL, used to rewrite root-relative asset paths. */
|
|
358
|
+
baseURL?: string;
|
|
359
|
+
/** Highest visibility to include; the website must never exceed `public`. */
|
|
360
|
+
maxVisibility?: Visibility;
|
|
361
|
+
/**
|
|
362
|
+
* Who links to paths on the site (`/slides/talk.pdf`): the website, which
|
|
363
|
+
* prefixes the base URL, or the PDF, which needs `profile.url` in front.
|
|
364
|
+
*/
|
|
365
|
+
target?: 'website' | 'pdf';
|
|
366
|
+
}
|
|
367
|
+
declare function loadContent(rootDir: string, options?: LoadContentOptions): Promise<VitakitContent>;
|
|
368
|
+
|
|
369
|
+
interface PublicationGroupConfig {
|
|
370
|
+
/** A value of the `status` field; lowercase, e.g. `preprint` or `talk-slides`. */
|
|
371
|
+
id: string;
|
|
372
|
+
/** Heading on the website and in the PDF. */
|
|
373
|
+
label: string;
|
|
374
|
+
}
|
|
375
|
+
/** What `schemas/publications.ts` may set; everything is optional. */
|
|
376
|
+
interface PublicationsInput {
|
|
377
|
+
/** The values of `status`, in the order the groups appear. */
|
|
378
|
+
groups?: PublicationGroupConfig[];
|
|
379
|
+
/** The group of an entry without `status`. Defaults to the first group. */
|
|
380
|
+
defaultGroup?: string;
|
|
381
|
+
/** BibTeX fields that become links after a reference, on the website. */
|
|
382
|
+
badges?: BadgeConfig[];
|
|
383
|
+
/** Further BibTeX fields to hand to the website, as `entry.fields`. */
|
|
384
|
+
fields?: string[];
|
|
385
|
+
/**
|
|
386
|
+
* A built-in CSL style (`apa`, `vancouver`, ...) or a path relative to the
|
|
387
|
+
* project. Not needed for `content/publications.csl`, which is found anyway.
|
|
388
|
+
*/
|
|
389
|
+
cslStyle?: string;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Typing for `schemas/publications.ts`; the file is validated when it is
|
|
393
|
+
* loaded, so that problems are reported with its name.
|
|
394
|
+
*/
|
|
395
|
+
declare function publications(input: PublicationsInput): PublicationsInput;
|
|
396
|
+
|
|
397
|
+
export { DateRange, Visibility, VitakitContent, dateRange, _default$4 as education, _default$3 as employment, entry, extendSection, institution, link, loadContent, publications, richText, schemas, section, _default as supervision, _default$1 as talks, _default$2 as teaching, text, url, visibility };
|
|
398
|
+
export type { BuiltinSection, LoadContentOptions, PublicationGroupConfig, PublicationsInput };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export { d as dateRange, e as education, a as employment, b as entry, c as extendSection, i as institution, l as link, r as richText, s as schemas, f as section, g as supervision, t as talks, h as teaching, j as text, u as url, v as visibility } from './shared/vitakit.BxcnlFGP.mjs';
|
|
2
|
+
export { l as loadContent, p as publications } from './shared/vitakit.CypCF-4Q.mjs';
|
|
3
|
+
export { badgePresets } from '@behackl/citation-js-extras';
|
|
4
|
+
export { z } from 'zod';
|
|
5
|
+
import 'node:fs';
|
|
6
|
+
import 'node:path';
|
|
7
|
+
import 'node:url';
|
|
8
|
+
import 'node:fs/promises';
|
|
9
|
+
import 'gray-matter';
|
|
10
|
+
import 'yaml';
|
|
11
|
+
import 'unified';
|
|
12
|
+
import 'remark-parse';
|
|
13
|
+
import 'remark-gfm';
|
|
14
|
+
import 'remark-math';
|
|
15
|
+
import 'remark-rehype';
|
|
16
|
+
import 'rehype-katex';
|
|
17
|
+
import 'rehype-raw';
|
|
18
|
+
import 'rehype-stringify';
|
|
19
|
+
import 'unist-util-visit';
|
|
20
|
+
import 'rehype-parse';
|
|
21
|
+
import 'rehype-sanitize';
|
package/dist/nuxt.d.mts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { NuxtModule } from '@nuxt/schema';
|
|
2
|
+
|
|
3
|
+
interface ModuleOptions {
|
|
4
|
+
/** Where `content/` and `schemas/` live. Defaults to the Nuxt root. */
|
|
5
|
+
rootDir?: string;
|
|
6
|
+
/**
|
|
7
|
+
* Add KaTeX's stylesheet to every page. On by default; turn it off only to
|
|
8
|
+
* load the stylesheet yourself, and then from the same KaTeX version.
|
|
9
|
+
*/
|
|
10
|
+
katexCss?: boolean;
|
|
11
|
+
}
|
|
12
|
+
declare const module$1: NuxtModule<ModuleOptions>;
|
|
13
|
+
|
|
14
|
+
export { module$1 as default };
|
|
15
|
+
export type { ModuleOptions };
|
package/dist/nuxt.mjs
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { defineNuxtModule, createResolver, addTemplate, addTypeTemplate, addImportsDir, addComponentsDir, addPrerenderRoutes, updateTemplates } from '@nuxt/kit';
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { l as loadContent } from './shared/vitakit.CypCF-4Q.mjs';
|
|
4
|
+
import 'node:fs/promises';
|
|
5
|
+
import 'node:path';
|
|
6
|
+
import 'gray-matter';
|
|
7
|
+
import 'yaml';
|
|
8
|
+
import 'unified';
|
|
9
|
+
import 'remark-parse';
|
|
10
|
+
import 'remark-gfm';
|
|
11
|
+
import 'remark-math';
|
|
12
|
+
import 'remark-rehype';
|
|
13
|
+
import 'rehype-katex';
|
|
14
|
+
import 'rehype-raw';
|
|
15
|
+
import 'rehype-stringify';
|
|
16
|
+
import 'unist-util-visit';
|
|
17
|
+
import './shared/vitakit.BxcnlFGP.mjs';
|
|
18
|
+
import 'node:fs';
|
|
19
|
+
import 'node:url';
|
|
20
|
+
import 'zod';
|
|
21
|
+
import '@behackl/citation-js-extras';
|
|
22
|
+
import 'rehype-parse';
|
|
23
|
+
import 'rehype-sanitize';
|
|
24
|
+
|
|
25
|
+
function katexStylesheet() {
|
|
26
|
+
const renderer = createRequire(createRequire(import.meta.url).resolve("rehype-katex"));
|
|
27
|
+
return renderer.resolve("katex/dist/katex.min.css");
|
|
28
|
+
}
|
|
29
|
+
const TEMPLATE = "vitakit/content.mjs";
|
|
30
|
+
const TYPES = "vitakit/content.d.ts";
|
|
31
|
+
function report(content) {
|
|
32
|
+
if (!content.issues.length) return;
|
|
33
|
+
const lines = content.issues.map((issue) => ` ${issue.where}: ${issue.message.replace(/\n/g, "\n ")}`);
|
|
34
|
+
console.error(`
|
|
35
|
+
[vitakit] ${content.issues.length} content problem(s):
|
|
36
|
+
${lines.join("\n")}
|
|
37
|
+
`);
|
|
38
|
+
}
|
|
39
|
+
const module$1 = defineNuxtModule({
|
|
40
|
+
meta: {
|
|
41
|
+
name: "vitakit",
|
|
42
|
+
configKey: "vitakit",
|
|
43
|
+
compatibility: { nuxt: ">=4.0.0" }
|
|
44
|
+
},
|
|
45
|
+
async setup(options, nuxt) {
|
|
46
|
+
const resolver = createResolver(import.meta.url);
|
|
47
|
+
const rootDir = options.rootDir ?? nuxt.options.rootDir;
|
|
48
|
+
const load = (strict) => loadContent(rootDir, {
|
|
49
|
+
strict,
|
|
50
|
+
baseURL: nuxt.options.app.baseURL,
|
|
51
|
+
// The website never sees anything but public entries; `cv` and `private`
|
|
52
|
+
// exist for the LaTeX side and must not reach the browser bundle.
|
|
53
|
+
maxVisibility: "public"
|
|
54
|
+
});
|
|
55
|
+
let content = await load(!nuxt.options.dev);
|
|
56
|
+
report(content);
|
|
57
|
+
nuxt.options.alias["#vitakit/content"] = `${nuxt.options.buildDir}/${TEMPLATE}`;
|
|
58
|
+
addTemplate({
|
|
59
|
+
filename: TEMPLATE,
|
|
60
|
+
write: true,
|
|
61
|
+
getContents: () => `export default ${JSON.stringify(content)}
|
|
62
|
+
`
|
|
63
|
+
});
|
|
64
|
+
addTypeTemplate({
|
|
65
|
+
filename: TYPES,
|
|
66
|
+
getContents: () => [
|
|
67
|
+
`import type { VitakitContent } from '@anja.codes/vitakit'`,
|
|
68
|
+
`declare module '#vitakit/content' {`,
|
|
69
|
+
` const content: VitakitContent`,
|
|
70
|
+
` export default content`,
|
|
71
|
+
`}`,
|
|
72
|
+
""
|
|
73
|
+
].join("\n")
|
|
74
|
+
});
|
|
75
|
+
if (options.katexCss !== false) nuxt.options.css.push(katexStylesheet());
|
|
76
|
+
nuxt.options.build.transpile.push(resolver.resolve("./runtime"));
|
|
77
|
+
addImportsDir(resolver.resolve("./runtime/composables"));
|
|
78
|
+
await addComponentsDir({ path: resolver.resolve("./runtime/components"), prefix: "Vita", pathPrefix: false });
|
|
79
|
+
addPrerenderRoutes(content.pages.map((page) => page.route));
|
|
80
|
+
if (!nuxt.options.dev) return;
|
|
81
|
+
nuxt.options.watch.push("../content", "../schemas");
|
|
82
|
+
nuxt.hook("builder:watch", async (_event, path) => {
|
|
83
|
+
if (!/[/\\](content|schemas)[/\\]/.test(path)) return;
|
|
84
|
+
try {
|
|
85
|
+
content = await load(false);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.error(`
|
|
88
|
+
[vitakit] ${error instanceof Error ? error.message : String(error)}
|
|
89
|
+
`);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
report(content);
|
|
93
|
+
await updateTemplates({ filter: (item) => item.filename === TEMPLATE });
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
export { module$1 as default };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/** A date or span, formatted identically on the website and in the PDF. */
|
|
3
|
+
import { computed } from 'vue'
|
|
4
|
+
import { formatDateRange, type DateRange } from '@anja.codes/vitakit/shared'
|
|
5
|
+
|
|
6
|
+
const props = defineProps<{
|
|
7
|
+
value?: DateRange
|
|
8
|
+
locale?: string
|
|
9
|
+
presentLabel?: string
|
|
10
|
+
}>()
|
|
11
|
+
|
|
12
|
+
const label = computed(() => formatDateRange(props.value, {
|
|
13
|
+
locale: props.locale,
|
|
14
|
+
presentLabel: props.presentLabel,
|
|
15
|
+
}))
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<template>
|
|
19
|
+
<time v-if="label" class="vita-date" :datetime="value?.from.raw">{{ label }}</time>
|
|
20
|
+
</template>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* One row of a section: a date column and free content.
|
|
4
|
+
*
|
|
5
|
+
* This is the shape every built-in section component uses, so ejecting one and
|
|
6
|
+
* restyling it does not require reproducing the layout primitives.
|
|
7
|
+
*/
|
|
8
|
+
import type { DateRange } from '@anja.codes/vitakit/shared'
|
|
9
|
+
|
|
10
|
+
defineProps<{ date?: DateRange }>()
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<li class="vita-entry">
|
|
15
|
+
<div class="vita-entry__date">
|
|
16
|
+
<slot name="date">
|
|
17
|
+
<VitaDate :value="date" />
|
|
18
|
+
</slot>
|
|
19
|
+
</div>
|
|
20
|
+
<div class="vita-entry__body">
|
|
21
|
+
<slot />
|
|
22
|
+
</div>
|
|
23
|
+
</li>
|
|
24
|
+
</template>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Development-only banner listing content problems.
|
|
4
|
+
*
|
|
5
|
+
* A build fails on any of these, so `issues` is always empty in production and
|
|
6
|
+
* this component renders nothing there.
|
|
7
|
+
*/
|
|
8
|
+
import { useVitakit } from '#imports'
|
|
9
|
+
|
|
10
|
+
const { issues } = useVitakit()
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<aside v-if="issues.length" class="vita-issues">
|
|
15
|
+
<p class="vita-issues__title">
|
|
16
|
+
{{ issues.length }} content problem{{ issues.length > 1 ? 's' : '' }} — the build would fail.
|
|
17
|
+
</p>
|
|
18
|
+
<ul>
|
|
19
|
+
<li v-for="issue in issues" :key="issue.where + issue.message">
|
|
20
|
+
<code>{{ issue.where }}</code>
|
|
21
|
+
<pre>{{ issue.message }}</pre>
|
|
22
|
+
</li>
|
|
23
|
+
</ul>
|
|
24
|
+
</aside>
|
|
25
|
+
</template>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/** A row of links; external ones get the usual safety attributes. */
|
|
3
|
+
import type { Link } from '@anja.codes/vitakit/shared'
|
|
4
|
+
|
|
5
|
+
defineProps<{ links?: Link[] }>()
|
|
6
|
+
|
|
7
|
+
const isExternal = (url: string) => /^https?:\/\//.test(url)
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<ul v-if="links?.length" class="vita-links">
|
|
12
|
+
<li v-for="item in links" :key="item.url">
|
|
13
|
+
<a
|
|
14
|
+
:href="item.url"
|
|
15
|
+
v-bind="isExternal(item.url) ? { target: '_blank', rel: 'noopener noreferrer' } : {}"
|
|
16
|
+
>{{ item.label }}</a>
|
|
17
|
+
</li>
|
|
18
|
+
</ul>
|
|
19
|
+
</template>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Renders build-time Markdown output.
|
|
4
|
+
*
|
|
5
|
+
* The HTML is produced by the vitakit build and is trusted, which is why
|
|
6
|
+
* `v-html` is acceptable here and would not be for user input.
|
|
7
|
+
*/
|
|
8
|
+
defineProps<{ html?: string }>()
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<!-- eslint-disable-next-line vue/no-v-html -- build-time rendered Markdown -->
|
|
13
|
+
<div v-if="html" class="vita-prose" v-html="html" />
|
|
14
|
+
</template>
|