@d-zero/beholder 2.1.6 → 3.0.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.
@@ -0,0 +1,568 @@
1
+ /**
2
+ * Lookup tables mapping `<meta name>`, `<meta property>`, `<meta http-equiv>`,
3
+ * `<meta itemprop>`, and `<link rel>` to their dot-path in `Meta`.
4
+ *
5
+ * Each key has a single canonical lowercase form. Cross-reference keys
6
+ * (e.g., `format-detection` writes to both `formatDetection.*` and
7
+ * `apple.formatDetectionTelephone`) use `paths` with more than one entry.
8
+ *
9
+ * Values referenced from `frontmatter-keys.md` in `../../frontend-env/`.
10
+ * @module
11
+ */
12
+
13
+ export type KeyTransform =
14
+ | 'string'
15
+ | 'number'
16
+ | 'boolean-yes'
17
+ | 'boolean-on'
18
+ | 'boolean-true';
19
+
20
+ export type KeyDef = {
21
+ /** One or more dot-paths under `Meta` to write the value into. */
22
+ readonly paths: readonly string[];
23
+ /** When `true`, repeated occurrences accumulate into an array at the path. */
24
+ readonly multi?: boolean;
25
+ /** Value normalization to apply. Defaults to `'string'`. */
26
+ readonly transform?: KeyTransform;
27
+ };
28
+
29
+ /** Defines how a `<link rel>` is stored under `Meta.link`. */
30
+ export type LinkRelDef = {
31
+ /** Dot-path under `Meta.link` (e.g., `'canonical'`, `'preload'`). */
32
+ readonly path: string;
33
+ /**
34
+ * `'single'` keeps the first; `'href-only'` stores the href string only;
35
+ * `'array'` accumulates `LinkEntry[]`; `'icon-sized'` accumulates only when
36
+ * `sizes` is set.
37
+ */
38
+ readonly cardinality: 'single' | 'href-only' | 'array' | 'icon-sized';
39
+ };
40
+
41
+ /** `<meta name="X">` → dot-path in `Meta`. */
42
+ export const META_NAME_MAP: Record<string, KeyDef> = {
43
+ 'application-name': { paths: ['applicationName'] },
44
+ author: { paths: ['author'] },
45
+ description: { paths: ['description'] },
46
+ generator: { paths: ['generator'] },
47
+ keywords: { paths: ['keywords'] },
48
+ creator: { paths: ['creator'] },
49
+ publisher: { paths: ['publisher'] },
50
+ 'theme-color': { paths: ['themeColor'] },
51
+ 'color-scheme': { paths: ['colorScheme'] },
52
+ 'supported-color-schemes': { paths: ['supportedColorSchemes'] },
53
+ googlebot: { paths: ['googlebot'] },
54
+ 'googlebot-news': { paths: ['googlebotNews'] },
55
+ 'googlebot-image': { paths: ['googlebotImage'] },
56
+ 'googlebot-video': { paths: ['googlebotVideo'] },
57
+ bingbot: { paths: ['bingbot'] },
58
+ slurp: { paths: ['slurp'] },
59
+ duckduckbot: { paths: ['duckduckbot'] },
60
+ yandex: { paths: ['yandex'] },
61
+ baiduspider: { paths: ['baiduspider'] },
62
+ ia_archiver: { paths: ['iaArchiver'] },
63
+ 'revisit-after': { paths: ['revisitAfter'] },
64
+ rating: { paths: ['rating'] },
65
+ distribution: { paths: ['distribution'] },
66
+ classification: { paths: ['classification'] },
67
+ category: { paths: ['category'] },
68
+ subject: { paths: ['subject'] },
69
+ topic: { paths: ['topic'] },
70
+ summary: { paths: ['summary'] },
71
+ abstract: { paths: ['abstract'] },
72
+ audience: { paths: ['audience'] },
73
+ target: { paths: ['target'] },
74
+ copyright: { paths: ['copyright'] },
75
+ designer: { paths: ['designer'] },
76
+ owner: { paths: ['owner'] },
77
+ 'reply-to': { paths: ['replyTo'] },
78
+ contact: { paths: ['contact'] },
79
+ 'identifier-url': { paths: ['identifierUrl'] },
80
+ language: { paths: ['language'] },
81
+ revision: { paths: ['revision'] },
82
+ build: { paths: ['build'] },
83
+ version: { paths: ['version'] },
84
+ handheldfriendly: {
85
+ paths: ['handheldFriendly', 'mobile.handheldFriendly', 'legacy.handheldFriendly'],
86
+ },
87
+ mobileoptimized: {
88
+ paths: ['mobileOptimized', 'mobile.mobileOptimized', 'legacy.mobileOptimized'],
89
+ },
90
+ 'mobile-web-app-capable': { paths: ['mobileWebAppCapable'] },
91
+ 'application-url': { paths: ['applicationUrl'] },
92
+ theme: { paths: ['theme'] },
93
+
94
+ // Apple iOS
95
+ 'apple-mobile-web-app-capable': {
96
+ paths: ['apple.mobileWebAppCapable'],
97
+ transform: 'boolean-yes',
98
+ },
99
+ 'apple-mobile-web-app-status-bar-style': {
100
+ paths: ['apple.mobileWebAppStatusBarStyle'],
101
+ },
102
+ 'apple-mobile-web-app-title': { paths: ['apple.mobileWebAppTitle'] },
103
+ 'apple-touch-fullscreen': {
104
+ paths: ['apple.touchFullscreen'],
105
+ transform: 'boolean-yes',
106
+ },
107
+ 'apple-itunes-app': { paths: ['apple.itunesApp'] },
108
+ 'apple-mobile-web-app-orientations': { paths: ['apple.mobileWebAppOrientations'] },
109
+ 'apple-touch-icon-title': { paths: ['apple.touchIconTitle'] },
110
+ 'apple-touch-startup-image': { paths: ['apple.touchStartupImage'] },
111
+
112
+ // Microsoft
113
+ 'msapplication-tilecolor': { paths: ['msapplication.tileColor'] },
114
+ 'msapplication-tileimage': { paths: ['msapplication.tileImage'] },
115
+ 'msapplication-config': { paths: ['msapplication.config', 'msapplication.configFile'] },
116
+ 'msapplication-navbutton-color': { paths: ['msapplication.navbuttonColor'] },
117
+ 'msapplication-square70x70logo': { paths: ['msapplication.square70x70logo'] },
118
+ 'msapplication-square150x150logo': { paths: ['msapplication.square150x150logo'] },
119
+ 'msapplication-square310x310logo': { paths: ['msapplication.square310x310logo'] },
120
+ 'msapplication-wide310x150logo': { paths: ['msapplication.wide310x150logo'] },
121
+ 'msapplication-starturl': { paths: ['msapplication.starturl'] },
122
+ 'msapplication-window': { paths: ['msapplication.window'] },
123
+ 'msapplication-task': { paths: ['msapplication.task'], multi: true },
124
+ 'msapplication-task-separator': { paths: ['msapplication.taskSeparator'] },
125
+ 'msapplication-tooltip': { paths: ['msapplication.tooltip'] },
126
+ 'msapplication-notification': { paths: ['msapplication.notification'] },
127
+ 'msapplication-badge': { paths: ['msapplication.badge'] },
128
+ 'msapplication-tap-highlight': { paths: ['msapplication.tapHighlight'] },
129
+ 'msapplication-allowdomainapicalls': { paths: ['msapplication.allowDomainApiCalls'] },
130
+ 'msapplication-allowdomainmetatags': { paths: ['msapplication.allowDomainMetaTags'] },
131
+ mssmarttagspreventparsing: {
132
+ paths: ['msapplication.smartTagsPreventParsing', 'legacy.msSmartTagsPreventParsing'],
133
+ },
134
+ ie_rm_off: { paths: ['msapplication.ieRmOff'] },
135
+
136
+ // Verification
137
+ 'google-site-verification': { paths: ['verification.google'] },
138
+ 'msvalidate.01': { paths: ['verification.bing'] },
139
+ 'yandex-verification': { paths: ['verification.yandex'] },
140
+ 'baidu-site-verification': { paths: ['verification.baidu'] },
141
+ 'naver-site-verification': { paths: ['verification.naver'] },
142
+ 'p:domain_verify': { paths: ['verification.pinterest'] },
143
+ 'facebook-domain-verification': { paths: ['verification.facebook'] },
144
+ alexaverifyid: { paths: ['verification.alexa'] },
145
+ 'norton-safeweb-site-verification': { paths: ['verification.norton'] },
146
+ 'ahrefs-site-verification': { paths: ['verification.ahrefs'] },
147
+ 'detectify-verification': { paths: ['verification.detectify'] },
148
+ 'zoho-verification': { paths: ['verification.zoho'] },
149
+ 'wot-verification': { paths: ['verification.wot'] },
150
+ 'seznam-wmt': { paths: ['verification.seznam'] },
151
+ 'shopify-checkout-api-token': { paths: ['verification.shopify'] },
152
+ 'brave-rewards-verification': { paths: ['verification.brave'] },
153
+
154
+ // Google-specific
155
+ 'google-translate-customization': { paths: ['google.translateCustomization'] },
156
+ 'google-adsense-account': { paths: ['google.adsenseAccount'] },
157
+ 'google-play-app': { paths: ['google.playApp'] },
158
+
159
+ // Dublin Core
160
+ 'dc.title': { paths: ['dc.title'] },
161
+ 'dc.creator': { paths: ['dc.creator'] },
162
+ 'dc.subject': { paths: ['dc.subject'] },
163
+ 'dc.description': { paths: ['dc.description'] },
164
+ 'dc.publisher': { paths: ['dc.publisher'] },
165
+ 'dc.contributor': { paths: ['dc.contributor'] },
166
+ 'dc.date': { paths: ['dc.date'] },
167
+ 'dc.type': { paths: ['dc.type'] },
168
+ 'dc.format': { paths: ['dc.format'] },
169
+ 'dc.identifier': { paths: ['dc.identifier'] },
170
+ 'dc.source': { paths: ['dc.source'] },
171
+ 'dc.language': { paths: ['dc.language'] },
172
+ 'dc.relation': { paths: ['dc.relation'] },
173
+ 'dc.coverage': { paths: ['dc.coverage'] },
174
+ 'dc.rights': { paths: ['dc.rights'] },
175
+
176
+ // DC Terms
177
+ 'dcterms.abstract': { paths: ['dcterms.abstract'] },
178
+ 'dcterms.accessrights': { paths: ['dcterms.accessRights'] },
179
+ 'dcterms.accrualmethod': { paths: ['dcterms.accrualMethod'] },
180
+ 'dcterms.accrualperiodicity': { paths: ['dcterms.accrualPeriodicity'] },
181
+ 'dcterms.accrualpolicy': { paths: ['dcterms.accrualPolicy'] },
182
+ 'dcterms.alternative': { paths: ['dcterms.alternative'] },
183
+ 'dcterms.audience': { paths: ['dcterms.audience'] },
184
+ 'dcterms.available': { paths: ['dcterms.available'] },
185
+ 'dcterms.bibliographiccitation': { paths: ['dcterms.bibliographicCitation'] },
186
+ 'dcterms.conformsto': { paths: ['dcterms.conformsTo'] },
187
+ 'dcterms.created': { paths: ['dcterms.created'] },
188
+ 'dcterms.dateaccepted': { paths: ['dcterms.dateAccepted'] },
189
+ 'dcterms.datecopyrighted': { paths: ['dcterms.dateCopyrighted'] },
190
+ 'dcterms.datesubmitted': { paths: ['dcterms.dateSubmitted'] },
191
+ 'dcterms.educationlevel': { paths: ['dcterms.educationLevel'] },
192
+ 'dcterms.extent': { paths: ['dcterms.extent'] },
193
+ 'dcterms.hasformat': { paths: ['dcterms.hasFormat'] },
194
+ 'dcterms.haspart': { paths: ['dcterms.hasPart'] },
195
+ 'dcterms.hasversion': { paths: ['dcterms.hasVersion'] },
196
+ 'dcterms.instructionalmethod': { paths: ['dcterms.instructionalMethod'] },
197
+ 'dcterms.isformatof': { paths: ['dcterms.isFormatOf'] },
198
+ 'dcterms.ispartof': { paths: ['dcterms.isPartOf'] },
199
+ 'dcterms.isreferencedby': { paths: ['dcterms.isReferencedBy'] },
200
+ 'dcterms.isreplacedby': { paths: ['dcterms.isReplacedBy'] },
201
+ 'dcterms.isrequiredby': { paths: ['dcterms.isRequiredBy'] },
202
+ 'dcterms.issued': { paths: ['dcterms.issued'] },
203
+ 'dcterms.isversionof': { paths: ['dcterms.isVersionOf'] },
204
+ 'dcterms.license': { paths: ['dcterms.license'] },
205
+ 'dcterms.mediator': { paths: ['dcterms.mediator'] },
206
+ 'dcterms.medium': { paths: ['dcterms.medium'] },
207
+ 'dcterms.modified': { paths: ['dcterms.modified'] },
208
+ 'dcterms.provenance': { paths: ['dcterms.provenance'] },
209
+ 'dcterms.references': { paths: ['dcterms.references'] },
210
+ 'dcterms.replaces': { paths: ['dcterms.replaces'] },
211
+ 'dcterms.requires': { paths: ['dcterms.requires'] },
212
+ 'dcterms.rightsholder': { paths: ['dcterms.rightsHolder'] },
213
+ 'dcterms.spatial': { paths: ['dcterms.spatial'] },
214
+ 'dcterms.tableofcontents': { paths: ['dcterms.tableOfContents'] },
215
+ 'dcterms.temporal': { paths: ['dcterms.temporal'] },
216
+ 'dcterms.valid': { paths: ['dcterms.valid'] },
217
+
218
+ // Geo
219
+ 'geo.region': { paths: ['geo.region'] },
220
+ 'geo.placename': { paths: ['geo.placename'] },
221
+ 'geo.position': { paths: ['geo.position'] },
222
+ 'geo.country': { paths: ['geo.country'] },
223
+ 'geo.a1': { paths: ['geo.a1'] },
224
+ 'geo.a2': { paths: ['geo.a2'] },
225
+ 'geo.a3': { paths: ['geo.a3'] },
226
+ 'geo.lmk': { paths: ['geo.lmk'] },
227
+ icbm: { paths: ['icbm'] },
228
+
229
+ // Citation
230
+ citation_title: { paths: ['citation.title'] },
231
+ citation_author: { paths: ['citation.author'], multi: true },
232
+ citation_author_email: { paths: ['citation.authorEmail'], multi: true },
233
+ citation_author_institution: { paths: ['citation.authorInstitution'], multi: true },
234
+ citation_publication_date: { paths: ['citation.publicationDate'] },
235
+ citation_date: { paths: ['citation.date'] },
236
+ citation_journal_title: { paths: ['citation.journalTitle'] },
237
+ citation_journal_abbrev: { paths: ['citation.journalAbbrev'] },
238
+ citation_conference_title: { paths: ['citation.conferenceTitle'] },
239
+ citation_publisher: { paths: ['citation.publisher'] },
240
+ citation_volume: { paths: ['citation.volume'] },
241
+ citation_issue: { paths: ['citation.issue'] },
242
+ citation_firstpage: { paths: ['citation.firstpage'] },
243
+ citation_lastpage: { paths: ['citation.lastpage'] },
244
+ citation_doi: { paths: ['citation.doi'] },
245
+ citation_isbn: { paths: ['citation.isbn'] },
246
+ citation_issn: { paths: ['citation.issn'] },
247
+ citation_language: { paths: ['citation.language'] },
248
+ citation_keywords: { paths: ['citation.keywords'] },
249
+ citation_pdf_url: { paths: ['citation.pdfUrl'] },
250
+ citation_fulltext_html_url: { paths: ['citation.fulltextHtmlUrl'] },
251
+ citation_dissertation_institution: { paths: ['citation.dissertationInstitution'] },
252
+ citation_technical_report_institution: {
253
+ paths: ['citation.technicalReportInstitution'],
254
+ },
255
+ citation_technical_report_number: { paths: ['citation.technicalReportNumber'] },
256
+
257
+ // CSRF
258
+ 'csrf-param': { paths: ['csrfParam'] },
259
+ 'csrf-token': { paths: ['csrfToken'] },
260
+
261
+ // Misc
262
+ 'go-import': { paths: ['goImport'] },
263
+ bitcoin: { paths: ['bitcoin'] },
264
+ 'origin-trial': { paths: ['originTrial'], multi: true },
265
+ monetization: { paths: ['monetization'] },
266
+ 'payment-pointer': { paths: ['paymentPointer'] },
267
+ 'amp-experiments-opt-in': { paths: ['ampExperimentsOptIn', 'amp.experimentsOptIn'] },
268
+ 'amp-google-client-id-api': { paths: ['ampGoogleClientIdApi'] },
269
+
270
+ // Pinterest
271
+ 'pinterest-rich-pin': { paths: ['pinterest.richPin'], transform: 'boolean-true' },
272
+ pinterest: { paths: ['pinterest.nopin'], transform: 'boolean-true' },
273
+
274
+ // Legacy
275
+ imagetoolbar: { paths: ['legacy.imagetoolbar'] },
276
+ 'page-version': { paths: ['legacy.pageVersion'] },
277
+ 'resource-type': { paths: ['legacy.resourceType'] },
278
+ 'doc-class': { paths: ['legacy.docClass'] },
279
+ 'doc-rights': { paths: ['legacy.docRights'] },
280
+ 'doc-type': { paths: ['legacy.docType'] },
281
+
282
+ // Mobile-specific
283
+ 'mobile-agent': { paths: ['mobile.mobileAgent'] },
284
+ 'full-screen': { paths: ['mobile.fullScreen'] },
285
+ browsermode: { paths: ['mobile.browsermode'] },
286
+ 'x5-orientation': { paths: ['mobile.x5Orientation'] },
287
+ 'x5-fullscreen': { paths: ['mobile.x5Fullscreen'] },
288
+ 'x5-page-mode': { paths: ['mobile.x5PageMode'] },
289
+ 'screen-orientation': { paths: ['mobile.screenOrientation'] },
290
+ layoutmode: { paths: ['mobile.layoutmode'] },
291
+ imagemode: { paths: ['mobile.imagemode'] },
292
+
293
+ // Twitter Cards (treated as name in HTML even though logically property-like)
294
+ 'twitter:card': { paths: ['twitter.card'] },
295
+ 'twitter:site': { paths: ['twitter.site'] },
296
+ 'twitter:site:id': { paths: ['twitter.siteId'] },
297
+ 'twitter:creator': { paths: ['twitter.creator'] },
298
+ 'twitter:creator:id': { paths: ['twitter.creatorId'] },
299
+ 'twitter:title': { paths: ['twitter.title'] },
300
+ 'twitter:description': { paths: ['twitter.description'] },
301
+ 'twitter:image': { paths: ['twitter.image'] },
302
+ 'twitter:image:src': { paths: ['twitter.imageSrc'] },
303
+ 'twitter:image:alt': { paths: ['twitter.imageAlt'] },
304
+ 'twitter:image:width': { paths: ['twitter.imageWidth'] },
305
+ 'twitter:image:height': { paths: ['twitter.imageHeight'] },
306
+ 'twitter:url': { paths: ['twitter.url'] },
307
+ 'twitter:domain': { paths: ['twitter.domain'] },
308
+ 'twitter:player': { paths: ['twitter.player'] },
309
+ 'twitter:player:width': { paths: ['twitter.playerWidth'] },
310
+ 'twitter:player:height': { paths: ['twitter.playerHeight'] },
311
+ 'twitter:player:stream': { paths: ['twitter.playerStream'] },
312
+ 'twitter:player:stream:content_type': { paths: ['twitter.playerStreamContentType'] },
313
+ 'twitter:app:name:iphone': { paths: ['twitter.appNameIphone'] },
314
+ 'twitter:app:id:iphone': { paths: ['twitter.appIdIphone'] },
315
+ 'twitter:app:url:iphone': { paths: ['twitter.appUrlIphone'] },
316
+ 'twitter:app:name:ipad': { paths: ['twitter.appNameIpad'] },
317
+ 'twitter:app:id:ipad': { paths: ['twitter.appIdIpad'] },
318
+ 'twitter:app:url:ipad': { paths: ['twitter.appUrlIpad'] },
319
+ 'twitter:app:name:googleplay': { paths: ['twitter.appNameGoogleplay'] },
320
+ 'twitter:app:id:googleplay': { paths: ['twitter.appIdGoogleplay'] },
321
+ 'twitter:app:url:googleplay': { paths: ['twitter.appUrlGoogleplay'] },
322
+ 'twitter:app:country': { paths: ['twitter.appCountry'] },
323
+ 'twitter:label1': { paths: ['twitter.label1'] },
324
+ 'twitter:data1': { paths: ['twitter.data1'] },
325
+ 'twitter:label2': { paths: ['twitter.label2'] },
326
+ 'twitter:data2': { paths: ['twitter.data2'] },
327
+ 'twitter:widgets:csp': { paths: ['twitter.widgetsCsp'] },
328
+ 'twitter:widgets:new-embed-design': { paths: ['twitter.widgetsNewEmbedDesign'] },
329
+ 'twitter:dnt': { paths: ['twitter.dnt'] },
330
+
331
+ // Experimental / vendor
332
+ 'darkreader-lock': {
333
+ paths: ['experimental.darkreaderLock'],
334
+ transform: 'boolean-true',
335
+ },
336
+ 'turbo-cache-control': { paths: ['experimental.turboCacheControl'] },
337
+ 'turbo-visit-control': { paths: ['experimental.turboVisitControl'] },
338
+ 'view-transition': { paths: ['experimental.viewTransition'] },
339
+
340
+ // Wiki
341
+ resourceloaderdynamicstyles: { paths: ['wiki.resourceLoaderDynamicStyles'] },
342
+ };
343
+
344
+ /** `<meta property="X">` → dot-path in `Meta`. */
345
+ export const META_PROPERTY_MAP: Record<string, KeyDef> = {
346
+ 'og:title': { paths: ['og.title'] },
347
+ 'og:type': { paths: ['og.type'] },
348
+ 'og:url': { paths: ['og.url'] },
349
+ 'og:site_name': { paths: ['og.siteName'] },
350
+ 'og:description': { paths: ['og.description'] },
351
+ 'og:determiner': { paths: ['og.determiner'] },
352
+ 'og:locale': { paths: ['og.locale'] },
353
+ 'og:locale:alternate': { paths: ['og.localeAlternate'], multi: true },
354
+
355
+ 'og:image': { paths: ['og.image'], multi: true },
356
+ 'og:image:url': { paths: ['og.imageUrl'] },
357
+ 'og:image:secure_url': { paths: ['og.imageSecureUrl'] },
358
+ 'og:image:type': { paths: ['og.imageType'] },
359
+ 'og:image:width': { paths: ['og.imageWidth'] },
360
+ 'og:image:height': { paths: ['og.imageHeight'] },
361
+ 'og:image:alt': { paths: ['og.imageAlt'] },
362
+
363
+ 'og:video': { paths: ['og.video'], multi: true },
364
+ 'og:video:url': { paths: ['og.videoUrl'] },
365
+ 'og:video:secure_url': { paths: ['og.videoSecureUrl'] },
366
+ 'og:video:type': { paths: ['og.videoType'] },
367
+ 'og:video:width': { paths: ['og.videoWidth'] },
368
+ 'og:video:height': { paths: ['og.videoHeight'] },
369
+ 'og:video:alt': { paths: ['og.videoAlt'] },
370
+
371
+ 'og:audio': { paths: ['og.audio'], multi: true },
372
+ 'og:audio:url': { paths: ['og.audioUrl'] },
373
+ 'og:audio:secure_url': { paths: ['og.audioSecureUrl'] },
374
+ 'og:audio:type': { paths: ['og.audioType'] },
375
+
376
+ 'article:published_time': { paths: ['og.article.publishedTime'] },
377
+ 'article:modified_time': { paths: ['og.article.modifiedTime'] },
378
+ 'article:expiration_time': { paths: ['og.article.expirationTime'] },
379
+ 'article:author': { paths: ['og.article.author'], multi: true },
380
+ 'article:section': { paths: ['og.article.section'] },
381
+ 'article:tag': { paths: ['og.article.tag'], multi: true },
382
+ 'article:publisher': { paths: ['og.article.publisher'] },
383
+
384
+ 'book:author': { paths: ['og.book.author'], multi: true },
385
+ 'book:isbn': { paths: ['og.book.isbn'] },
386
+ 'book:release_date': { paths: ['og.book.releaseDate'] },
387
+ 'book:tag': { paths: ['og.book.tag'], multi: true },
388
+
389
+ 'profile:first_name': { paths: ['og.profile.firstName'] },
390
+ 'profile:last_name': { paths: ['og.profile.lastName'] },
391
+ 'profile:username': { paths: ['og.profile.username'] },
392
+ 'profile:gender': { paths: ['og.profile.gender'] },
393
+
394
+ 'music:duration': { paths: ['og.music.duration'] },
395
+ 'music:album': { paths: ['og.music.album'], multi: true },
396
+ 'music:album:disc': { paths: ['og.music.albumDisc'] },
397
+ 'music:album:track': { paths: ['og.music.albumTrack'] },
398
+ 'music:musician': { paths: ['og.music.musician'], multi: true },
399
+ 'music:song': { paths: ['og.music.song'], multi: true },
400
+ 'music:song:disc': { paths: ['og.music.songDisc'] },
401
+ 'music:song:track': { paths: ['og.music.songTrack'] },
402
+ 'music:release_date': { paths: ['og.music.releaseDate'] },
403
+ 'music:creator': { paths: ['og.music.creator'], multi: true },
404
+
405
+ 'video:actor': { paths: ['og.videoNs.actor'], multi: true },
406
+ 'video:actor:role': { paths: ['og.videoNs.actorRole'] },
407
+ 'video:director': { paths: ['og.videoNs.director'], multi: true },
408
+ 'video:writer': { paths: ['og.videoNs.writer'], multi: true },
409
+ 'video:duration': { paths: ['og.videoNs.duration'] },
410
+ 'video:release_date': { paths: ['og.videoNs.releaseDate'] },
411
+ 'video:tag': { paths: ['og.videoNs.tag'], multi: true },
412
+ 'video:series': { paths: ['og.videoNs.series'] },
413
+
414
+ 'fb:app_id': { paths: ['fb.appId'] },
415
+ 'fb:admins': { paths: ['fb.admins'], multi: true },
416
+ 'fb:pages': { paths: ['fb.pages'], multi: true },
417
+
418
+ 'fediverse:creator': { paths: ['fediverse.creator'] },
419
+ };
420
+
421
+ /** `<meta http-equiv="X">` → dot-path in `Meta.httpEquiv`. */
422
+ export const HTTP_EQUIV_MAP: Record<string, KeyDef> = {
423
+ 'content-type': { paths: ['httpEquiv.contentType'] },
424
+ 'content-language': { paths: ['httpEquiv.contentLanguage'] },
425
+ 'default-style': { paths: ['httpEquiv.defaultStyle'] },
426
+ refresh: { paths: ['httpEquiv.refresh'] },
427
+ 'x-ua-compatible': { paths: ['httpEquiv.xUaCompatible'] },
428
+ 'content-security-policy': { paths: ['httpEquiv.contentSecurityPolicy'] },
429
+ 'content-security-policy-report-only': {
430
+ paths: ['httpEquiv.contentSecurityPolicyReportOnly'],
431
+ },
432
+ 'set-cookie': { paths: ['httpEquiv.setCookie'] },
433
+ pragma: { paths: ['httpEquiv.pragma'] },
434
+ 'cache-control': { paths: ['httpEquiv.cacheControl'] },
435
+ expires: { paths: ['httpEquiv.expires'] },
436
+ 'accept-ch': { paths: ['httpEquiv.acceptCh'] },
437
+ 'delegate-ch': { paths: ['httpEquiv.delegateCh'] },
438
+ 'permissions-policy': {
439
+ paths: ['httpEquiv.permissionsPolicy', 'httpEquiv.permissionsPolicyValue'],
440
+ },
441
+ 'origin-trial': {
442
+ paths: ['httpEquiv.originTrial', 'httpEquiv.originTrialToken'],
443
+ multi: true,
444
+ },
445
+ 'x-dns-prefetch-control': { paths: ['httpEquiv.xDnsPrefetchControl'] },
446
+ 'window-target': { paths: ['httpEquiv.windowTarget'] },
447
+ imagetoolbar: { paths: ['httpEquiv.imagetoolbar'] },
448
+ cleartype: { paths: ['httpEquiv.cleartype', 'msapplication.cleartype'] },
449
+ };
450
+
451
+ /** `<meta itemprop="X">` → dot-path in `Meta.itemprop`. */
452
+ export const ITEMPROP_MAP: Record<string, KeyDef> = {
453
+ name: { paths: ['itemprop.name'] },
454
+ description: { paths: ['itemprop.description'] },
455
+ image: { paths: ['itemprop.image'] },
456
+ };
457
+
458
+ /** `<link rel="X">` → dot-path in `Meta.link`. */
459
+ export const LINK_REL_MAP: Record<string, LinkRelDef> = {
460
+ canonical: { path: 'canonical', cardinality: 'href-only' },
461
+ alternate: { path: 'alternateHreflang', cardinality: 'array' },
462
+ amphtml: { path: 'amphtml', cardinality: 'href-only' },
463
+ author: { path: 'author', cardinality: 'href-only' },
464
+ bookmark: { path: 'bookmark', cardinality: 'href-only' },
465
+ help: { path: 'help', cardinality: 'href-only' },
466
+ license: { path: 'license', cardinality: 'href-only' },
467
+ next: { path: 'next', cardinality: 'href-only' },
468
+ prev: { path: 'prev', cardinality: 'href-only' },
469
+ previous: { path: 'previous', cardinality: 'href-only' },
470
+ first: { path: 'first', cardinality: 'href-only' },
471
+ last: { path: 'last', cardinality: 'href-only' },
472
+ up: { path: 'up', cardinality: 'href-only' },
473
+ index: { path: 'index', cardinality: 'href-only' },
474
+ contents: { path: 'contents', cardinality: 'href-only' },
475
+ start: { path: 'start', cardinality: 'href-only' },
476
+ search: { path: 'search', cardinality: 'single' },
477
+ tag: { path: 'tag', cardinality: 'array' },
478
+ archives: { path: 'archives', cardinality: 'array' },
479
+ publisher: { path: 'publisher', cardinality: 'href-only' },
480
+ 'privacy-policy': { path: 'privacyPolicy', cardinality: 'href-only' },
481
+ 'terms-of-service': { path: 'termsOfService', cardinality: 'href-only' },
482
+ copyright: { path: 'copyright', cardinality: 'href-only' },
483
+ appendix: { path: 'appendix', cardinality: 'array' },
484
+ chapter: { path: 'chapter', cardinality: 'array' },
485
+ section: { path: 'section', cardinality: 'array' },
486
+ subsection: { path: 'subsection', cardinality: 'array' },
487
+ glossary: { path: 'glossary', cardinality: 'href-only' },
488
+ profile: { path: 'profile', cardinality: 'array' },
489
+ edituri: { path: 'editUri', cardinality: 'href-only' },
490
+ pingback: { path: 'pingback', cardinality: 'href-only' },
491
+ webmention: { path: 'webmention', cardinality: 'href-only' },
492
+ micropub: { path: 'micropub', cardinality: 'href-only' },
493
+ microsub: { path: 'microsub', cardinality: 'href-only' },
494
+ me: { path: 'me', cardinality: 'array' },
495
+ authorization_endpoint: { path: 'authorizationEndpoint', cardinality: 'href-only' },
496
+ token_endpoint: { path: 'tokenEndpoint', cardinality: 'href-only' },
497
+ 'indieauth-metadata': { path: 'indieauthMetadata', cardinality: 'href-only' },
498
+ 'openid.server': { path: 'openidServer', cardinality: 'href-only' },
499
+ 'openid.delegate': { path: 'openidDelegate', cardinality: 'href-only' },
500
+ 'openid2.provider': { path: 'openid2Provider', cardinality: 'href-only' },
501
+ 'openid2.local_id': { path: 'openid2LocalId', cardinality: 'href-only' },
502
+ hub: { path: 'hub', cardinality: 'href-only' },
503
+ self: { path: 'self', cardinality: 'href-only' },
504
+ payment: { path: 'payment', cardinality: 'href-only' },
505
+ enclosure: { path: 'enclosure', cardinality: 'array' },
506
+ external: { path: 'external', cardinality: 'array' },
507
+ nofollow: { path: 'nofollow', cardinality: 'array' },
508
+ sponsored: { path: 'sponsored', cardinality: 'array' },
509
+ ugc: { path: 'ugc', cardinality: 'array' },
510
+ noopener: { path: 'noopener', cardinality: 'array' },
511
+ noreferrer: { path: 'noreferrer', cardinality: 'array' },
512
+ opener: { path: 'opener', cardinality: 'array' },
513
+ image_src: { path: 'imageSrc', cardinality: 'href-only' },
514
+ shortlink: { path: 'shortlink', cardinality: 'href-only' },
515
+ 'dns-prefetch': { path: 'dnsPrefetch', cardinality: 'array' },
516
+ preconnect: { path: 'preconnect', cardinality: 'array' },
517
+ prefetch: { path: 'prefetch', cardinality: 'array' },
518
+ prerender: { path: 'prerender', cardinality: 'array' },
519
+ preload: { path: 'preload', cardinality: 'array' },
520
+ modulepreload: { path: 'modulepreload', cardinality: 'array' },
521
+ expect: { path: 'expect', cardinality: 'array' },
522
+ stylesheet: { path: 'stylesheet', cardinality: 'array' },
523
+ manifest: { path: 'manifest', cardinality: 'href-only' },
524
+ serviceworker: { path: 'serviceworker', cardinality: 'href-only' },
525
+ dpp: { path: 'dpp', cardinality: 'href-only' },
526
+ gbfs: { path: 'gbfs', cardinality: 'href-only' },
527
+ syndication: { path: 'syndication', cardinality: 'array' },
528
+ 'api-catalog': { path: 'apiCatalog', cardinality: 'href-only' },
529
+ memento: { path: 'memento', cardinality: 'href-only' },
530
+ timegate: { path: 'timegate', cardinality: 'href-only' },
531
+ timemap: { path: 'timemap', cardinality: 'href-only' },
532
+ 'version-history': { path: 'versionHistory', cardinality: 'href-only' },
533
+ 'latest-version': { path: 'latestVersion', cardinality: 'href-only' },
534
+ 'predecessor-version': { path: 'predecessorVersion', cardinality: 'href-only' },
535
+ 'successor-version': { path: 'successorVersion', cardinality: 'href-only' },
536
+ 'working-copy': { path: 'workingCopy', cardinality: 'href-only' },
537
+ 'working-copy-of': { path: 'workingCopyOf', cardinality: 'href-only' },
538
+ describedby: { path: 'describedby', cardinality: 'href-only' },
539
+ describes: { path: 'describes', cardinality: 'href-only' },
540
+ via: { path: 'via', cardinality: 'href-only' },
541
+ related: { path: 'related', cardinality: 'array' },
542
+ 'cite-as': { path: 'citeAs', cardinality: 'href-only' },
543
+ disclosure: { path: 'disclosure', cardinality: 'href-only' },
544
+ status: { path: 'status', cardinality: 'href-only' },
545
+ sunset: { path: 'sunset', cardinality: 'href-only' },
546
+ deprecation: { path: 'deprecation', cardinality: 'href-only' },
547
+ lrdd: { path: 'lrdd', cardinality: 'href-only' },
548
+ hosts: { path: 'hosts', cardinality: 'href-only' },
549
+ service: { path: 'service', cardinality: 'href-only' },
550
+ 'service-desc': { path: 'serviceDesc', cardinality: 'href-only' },
551
+ 'service-doc': { path: 'serviceDoc', cardinality: 'href-only' },
552
+ 'service-meta': { path: 'serviceMeta', cardinality: 'href-only' },
553
+ 'c2pa-manifest': { path: 'c2paManifest', cardinality: 'href-only' },
554
+ 'compression-dictionary': { path: 'compressionDictionary', cardinality: 'href-only' },
555
+
556
+ icon: { path: 'icon', cardinality: 'single' },
557
+ 'shortcut icon': { path: 'shortcutIcon', cardinality: 'href-only' },
558
+ 'apple-touch-icon': { path: 'appleTouchIcon', cardinality: 'single' },
559
+ 'apple-touch-icon-precomposed': {
560
+ path: 'appleTouchIconPrecomposed',
561
+ cardinality: 'array',
562
+ },
563
+ 'apple-touch-startup-image': { path: 'appleTouchStartupImage', cardinality: 'array' },
564
+ 'mask-icon': { path: 'maskIcon', cardinality: 'single' },
565
+ 'fluid-icon': { path: 'fluidIcon', cardinality: 'single' },
566
+
567
+ 'security.txt': { path: 'securityTxt', cardinality: 'href-only' },
568
+ };