@takuhon/core 1.0.0 → 1.3.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/dist/index.d.ts +371 -7
- package/dist/index.js +975 -23
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/takuhon.schema.json +116 -2
package/dist/index.js
CHANGED
|
@@ -305,7 +305,7 @@ var require_takuhon_validator = __commonJS({
|
|
|
305
305
|
"use strict";
|
|
306
306
|
module.exports = validate20;
|
|
307
307
|
module.exports.default = validate20;
|
|
308
|
-
var schema31 = { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://takuhon.example/schemas/1.0.0/takuhon.schema.json", "title": "Takuhon Profile", "description": "Portable profile data format consumed by @takuhon/core. The canonical contract for profile content authored as takuhon.json.", "type": "object", "additionalProperties": false, "required": ["schemaVersion", "profile", "contact", "settings", "meta"], "properties": { "schemaVersion": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(-[a-zA-Z0-9.-]+)?$", "description": "Semantic version of the takuhon schema this document conforms to." }, "profile": { "$ref": "#/$defs/Profile" }, "links": { "type": "array", "maxItems": 100, "items": { "$ref": "#/$defs/Link" } }, "careers": { "type": "array", "maxItems": 50, "items": { "$ref": "#/$defs/Career" } }, "projects": { "type": "array", "maxItems": 100, "items": { "$ref": "#/$defs/Project" } }, "skills": { "type": "array", "maxItems": 200, "items": { "$ref": "#/$defs/Skill" } }, "certifications": { "type": "array", "maxItems": 50, "items": { "$ref": "#/$defs/Certification" } }, "memberships": { "type": "array", "maxItems": 50, "items": { "$ref": "#/$defs/Membership" } }, "volunteering": { "type": "array", "maxItems": 50, "items": { "$ref": "#/$defs/Volunteering" } }, "honors": { "type": "array", "maxItems": 50, "items": { "$ref": "#/$defs/Honor" } }, "education": { "type": "array", "maxItems": 30, "items": { "$ref": "#/$defs/Education" } }, "publications": { "type": "array", "maxItems": 100, "items": { "$ref": "#/$defs/Publication" } }, "languages": { "type": "array", "maxItems": 30, "items": { "$ref": "#/$defs/Language" } }, "courses": { "type": "array", "maxItems": 100, "items": { "$ref": "#/$defs/Course" } }, "patents": { "type": "array", "maxItems": 50, "items": { "$ref": "#/$defs/Patent" } }, "testScores": { "type": "array", "maxItems": 30, "items": { "$ref": "#/$defs/TestScore" } }, "recommendations": { "type": "array", "maxItems": 50, "items": { "$ref": "#/$defs/Recommendation" } }, "contact": { "$ref": "#/$defs/Contact" }, "settings": { "$ref": "#/$defs/Settings" }, "meta": { "$ref": "#/$defs/Meta" } }, "$defs": { "LocaleTag": { "type": "string", "minLength": 2, "maxLength": 35, "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})*$", "description": "BCP-47 language tag (e.g., 'en', 'ja', 'zh-Hant', 'pt-BR')." }, "Iso3166Alpha2": { "type": "string", "pattern": "^[A-Z]{2}$", "description": "ISO 3166-1 alpha-2 country code (uppercase, two letters)." }, "YearMonth": { "type": "string", "pattern": "^[0-9]{4}-(0[1-9]|1[0-2])$", "description": "Year-month in 'YYYY-MM' format (Gregorian calendar)." }, "IsoDateTime": { "type": "string", "format": "date-time", "description": "ISO 8601 date-time (e.g., 2026-05-11T12:34:56Z)." }, "Url": { "type": "string", "format": "uri", "maxLength": 2048 }, "Email": { "type": "string", "format": "email", "maxLength": 254 }, "Slug": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z0-9][a-z0-9-]*$", "description": "URL-safe identifier (lowercase alphanumerics and hyphens, must start with alphanumeric)." }, "Visibility": { "type": "string", "enum": ["public", "private"], "description": "Per-item public visibility (added in 0.7.0). 'private' removes the item from every public surface via applyPublicPrivacyFilter; an absent value or 'public' keeps the item public." }, "LocalizedTitle": { "type": "object", "minProperties": 1, "propertyNames": { "type": "string", "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})*$" }, "additionalProperties": { "type": "string", "minLength": 1, "maxLength": 200, "pattern": "\\S" }, "description": "Map of BCP-47 locale tag to short title-like string (max 200 chars per value). Each value must contain at least one non-whitespace character." }, "LocalizedBody": { "type": "object", "minProperties": 1, "propertyNames": { "type": "string", "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})*$" }, "additionalProperties": { "type": "string", "minLength": 1, "maxLength": 5e3, "pattern": "\\S" }, "description": "Map of BCP-47 locale tag to body-length string (max 5000 chars per value). Each value must contain at least one non-whitespace character." }, "LinkType": { "type": "string", "enum": ["website", "blog", "github", "gitlab", "linkedin", "x", "mastodon", "bluesky", "instagram", "youtube", "threads", "facebook", "email", "rss", "custom"], "description": "Identifies the kind of link. 'custom' requires iconUrl." }, "Profile": { "type": "object", "additionalProperties": false, "required": ["displayName"], "properties": { "displayName": { "$ref": "#/$defs/LocalizedTitle" }, "tagline": { "$ref": "#/$defs/LocalizedTitle" }, "bio": { "$ref": "#/$defs/LocalizedBody" }, "avatar": { "$ref": "#/$defs/Avatar" }, "location": { "$ref": "#/$defs/Address" } } }, "Avatar": { "type": "object", "additionalProperties": false, "required": ["url"], "properties": { "url": { "type": "string", "format": "uri-reference", "maxLength": 2048, "description": "URL or path to the avatar image." }, "alt": { "$ref": "#/$defs/LocalizedTitle" } } }, "Address": { "type": "object", "additionalProperties": false, "properties": { "country": { "$ref": "#/$defs/Iso3166Alpha2" }, "region": { "type": "string", "maxLength": 100 }, "locality": { "$ref": "#/$defs/LocalizedTitle" }, "display": { "$ref": "#/$defs/LocalizedTitle" } } }, "Link": { "type": "object", "additionalProperties": false, "required": ["id", "type", "url"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "type": { "$ref": "#/$defs/LinkType" }, "label": { "$ref": "#/$defs/LocalizedTitle" }, "url": { "$ref": "#/$defs/Url" }, "featured": { "type": "boolean" }, "order": { "type": "integer", "minimum": 0 }, "iconUrl": { "$ref": "#/$defs/Url" } }, "allOf": [{ "if": { "properties": { "type": { "const": "custom" } }, "required": ["type"] }, "then": { "properties": { "iconUrl": { "$ref": "#/$defs/Url" } }, "required": ["iconUrl"] } }] }, "Career": { "type": "object", "additionalProperties": false, "required": ["id", "organization", "role", "startDate"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "organization": { "$ref": "#/$defs/LocalizedTitle" }, "role": { "$ref": "#/$defs/LocalizedTitle" }, "description": { "$ref": "#/$defs/LocalizedBody" }, "startDate": { "$ref": "#/$defs/YearMonth" }, "endDate": { "anyOf": [{ "$ref": "#/$defs/YearMonth" }, { "type": "null" }] }, "isCurrent": { "type": "boolean" }, "url": { "$ref": "#/$defs/Url" }, "location": { "$ref": "#/$defs/Address" }, "order": { "type": "integer", "minimum": 0 } } }, "Project": { "type": "object", "additionalProperties": false, "required": ["id", "title"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "title": { "$ref": "#/$defs/LocalizedTitle" }, "description": { "$ref": "#/$defs/LocalizedBody" }, "url": { "$ref": "#/$defs/Url" }, "tags": { "type": "array", "maxItems": 30, "items": { "type": "string", "minLength": 1, "maxLength": 50 } }, "relatedCareerId": { "$ref": "#/$defs/Slug" }, "startDate": { "$ref": "#/$defs/YearMonth" }, "endDate": { "anyOf": [{ "$ref": "#/$defs/YearMonth" }, { "type": "null" }] }, "highlighted": { "type": "boolean" }, "order": { "type": "integer", "minimum": 0 } } }, "Skill": { "type": "object", "additionalProperties": false, "required": ["id", "label"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "label": { "type": "string", "minLength": 1, "maxLength": 100 }, "category": { "type": "string", "minLength": 1, "maxLength": 64, "description": "Recommended values (extensible): programming, design, business, communication, language, music, art, sports, other." }, "order": { "type": "integer", "minimum": 0 } } }, "Contact": { "type": "object", "additionalProperties": false, "properties": { "email": { "$ref": "#/$defs/Email" }, "showEmail": { "type": "boolean", "default": false }, "formUrl": { "$ref": "#/$defs/Url" } } }, "Settings": { "type": "object", "additionalProperties": false, "required": ["defaultLocale", "availableLocales"], "properties": { "defaultLocale": { "$ref": "#/$defs/LocaleTag" }, "fallbackLocale": { "$ref": "#/$defs/LocaleTag" }, "availableLocales": { "type": "array", "minItems": 1, "maxItems": 50, "uniqueItems": true, "items": { "$ref": "#/$defs/LocaleTag" } }, "theme": { "type": "string", "minLength": 1, "maxLength": 64, "description": "UI theme identifier. 'default' is the built-in theme; adapters may add more." }, "showPoweredBy": { "type": "boolean", "default": true, "description": "Display the 'Powered by takuhon' attribution in the rendered profile." }, "enableJsonLd": { "type": "boolean", "default": true, "description": "Emit Schema.org JSON-LD on the rendered profile page." }, "enableApi": { "type": "boolean", "default": true, "description": "Expose the public read API endpoints (GET /api/profile, /api/jsonld, /api/schema, /takuhon.json)." }, "enableAnalytics": { "type": "boolean", "default": false, "description": "Opt-in flag for first-party analytics. Default is false to keep takuhon privacy-respecting by default." }, "activity": { "$ref": "#/$defs/ActivitySettings" }, "publicVisibility": { "$ref": "#/$defs/PublicVisibility" } } }, "PublicVisibility": { "type": "object", "additionalProperties": false, "description": "Per-section public visibility (added in 0.6.0). Each key is a content section; setting it to false hides that whole section from every public surface (GET /, /api/profile, /api/jsonld, /takuhon.json, MCP, and the derived CV) via the shared applyPublicPrivacyFilter. An absent key \u2014 or an absent object \u2014 means the section is public, so the default is all-visible and omitting this block is fully backwards-compatible. The profile identity (profile.displayName, \u2026) is always public and is intentionally not a key here. Field-level controls (contact.showEmail, meta.privacy.*) still apply within a visible section: visibility is the AND of the feature toggle, this section flag, and the field flag.", "properties": { "links": { "type": "boolean", "description": "Default true. When false, links[] is emitted empty on public surfaces." }, "careers": { "type": "boolean", "description": "Default true. When false, careers[] is emitted empty on public surfaces." }, "projects": { "type": "boolean", "description": "Default true. When false, projects[] is emitted empty on public surfaces." }, "skills": { "type": "boolean", "description": "Default true. When false, skills[] is emitted empty on public surfaces." }, "certifications": { "type": "boolean", "description": "Default true. When false, certifications[] is emitted empty on public surfaces." }, "memberships": { "type": "boolean", "description": "Default true. When false, memberships[] is emitted empty on public surfaces." }, "volunteering": { "type": "boolean", "description": "Default true. When false, volunteering[] is emitted empty on public surfaces." }, "honors": { "type": "boolean", "description": "Default true. When false, honors[] is emitted empty on public surfaces." }, "education": { "type": "boolean", "description": "Default true. When false, education[] is emitted empty on public surfaces." }, "publications": { "type": "boolean", "description": "Default true. When false, publications[] is emitted empty on public surfaces." }, "languages": { "type": "boolean", "description": "Default true. When false, languages[] is emitted empty on public surfaces." }, "courses": { "type": "boolean", "description": "Default true. When false, courses[] is emitted empty on public surfaces." }, "patents": { "type": "boolean", "description": "Default true. When false, patents[] is emitted empty on public surfaces." }, "testScores": { "type": "boolean", "description": "Default true. When false, testScores[] is emitted empty on public surfaces." }, "recommendations": { "type": "boolean", "description": "Default true. When false, recommendations[] is emitted empty on public surfaces." }, "contact": { "type": "boolean", "description": "Default true. When false, the contact section (email, formUrl) is emitted empty on public surfaces." } } }, "ActivitySettings": { "type": "object", "additionalProperties": false, "description": "Opt-in developer-activity dashboard configuration (GitHub / WakaTime). Only the owner-curated settings live here; secrets are provisioned out of band and the synced metrics are stored in a separate document, never in takuhon.json.", "properties": { "enabled": { "type": "boolean", "default": false, "description": "Master switch. When false (the default), the activity section is not rendered even if a snapshot exists." }, "github": { "type": "object", "additionalProperties": false, "required": ["username"], "properties": { "username": { "type": "string", "minLength": 1, "maxLength": 39, "description": "GitHub login whose public activity is summarized." }, "showLanguages": { "type": "boolean", "default": true }, "showContributions": { "type": "boolean", "default": true } } }, "wakatime": { "type": "object", "additionalProperties": false, "required": ["username"], "properties": { "username": { "type": "string", "minLength": 1, "maxLength": 255, "description": "WakaTime username whose coding-time stats are summarized." }, "showCodingTime": { "type": "boolean", "default": true } } }, "showRank": { "type": "boolean", "default": true, "description": "Display the derived activity rank / badge." }, "refreshHintHours": { "type": "integer", "minimum": 1, "maximum": 168, "description": "Advisory refresh cadence in hours. The real cadence is how often the sync step (CLI command or scheduled job) runs." } } }, "Meta": { "type": "object", "additionalProperties": false, "required": ["contentLicense"], "properties": { "createdAt": { "$ref": "#/$defs/IsoDateTime" }, "updatedAt": { "$ref": "#/$defs/IsoDateTime" }, "generator": { "type": "string", "minLength": 1, "maxLength": 100, "description": "Tool that produced this document (e.g. 'Takuhon', 'create-takuhon@0.1.0')." }, "contentLicense": { "$ref": "#/$defs/ContentLicense" }, "privacy": { "$ref": "#/$defs/MetaPrivacy" } } }, "ContentLicense": { "type": "object", "additionalProperties": false, "required": ["spdxId"], "properties": { "spdxId": { "type": "string", "minLength": 1, "maxLength": 64, "description": "SPDX identifier (e.g., 'CC-BY-4.0', 'CC0-1.0') or 'Proprietary'. No default; the profile owner must choose explicitly." }, "url": { "$ref": "#/$defs/Url" }, "attribution": { "type": "object", "additionalProperties": false, "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200 }, "url": { "$ref": "#/$defs/Url" } } }, "rights": { "type": "string", "minLength": 1, "maxLength": 1e3, "description": "Free-form rights statement (used when spdxId='Proprietary' or for additional notices)." } } }, "MetaPrivacy": { "type": "object", "additionalProperties": false, "description": "Opt-out flags that strip personally identifying fields from public API output (GET /api/profile, /api/jsonld, /takuhon.json). Admin endpoints (PUT /api/admin/*, GET /api/admin/export) ignore these flags. Privacy-by-default: omitting the object or individual flags is equivalent to true.", "properties": { "hideCredentialIds": { "type": "boolean", "default": true, "description": "When true (default), strip certifications[*].credentialId from public responses." }, "hideEducationGrades": { "type": "boolean", "default": true, "description": "When true (default), strip education[*].grade from public responses." } } }, "Certification": { "type": "object", "additionalProperties": false, "required": ["id", "title", "issuingOrganization", "issueDate"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "title": { "$ref": "#/$defs/LocalizedTitle" }, "issuingOrganization": { "$ref": "#/$defs/LocalizedTitle" }, "issueDate": { "$ref": "#/$defs/YearMonth" }, "expirationDate": { "anyOf": [{ "$ref": "#/$defs/YearMonth" }, { "type": "null" }], "description": "null = explicitly 'no expiration'. Omit if unknown/unstated." }, "credentialId": { "type": "string", "minLength": 1, "maxLength": 100, "description": "License or certificate number. Public exposure controlled by meta.privacy.hideCredentialIds." }, "url": { "$ref": "#/$defs/Url" }, "order": { "type": "integer", "minimum": 0 } } }, "Membership": { "type": "object", "additionalProperties": false, "required": ["id", "organization", "startDate"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "organization": { "$ref": "#/$defs/LocalizedTitle" }, "role": { "$ref": "#/$defs/LocalizedTitle" }, "description": { "$ref": "#/$defs/LocalizedBody" }, "startDate": { "$ref": "#/$defs/YearMonth" }, "endDate": { "anyOf": [{ "$ref": "#/$defs/YearMonth" }, { "type": "null" }], "description": "null = ongoing. Omit if unknown." }, "isCurrent": { "type": "boolean" }, "url": { "$ref": "#/$defs/Url" }, "order": { "type": "integer", "minimum": 0 } } }, "Volunteering": { "type": "object", "additionalProperties": false, "required": ["id", "organization", "role", "startDate"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "organization": { "$ref": "#/$defs/LocalizedTitle" }, "role": { "$ref": "#/$defs/LocalizedTitle" }, "cause": { "$ref": "#/$defs/LocalizedTitle" }, "description": { "$ref": "#/$defs/LocalizedBody" }, "startDate": { "$ref": "#/$defs/YearMonth" }, "endDate": { "anyOf": [{ "$ref": "#/$defs/YearMonth" }, { "type": "null" }] }, "isCurrent": { "type": "boolean" }, "url": { "$ref": "#/$defs/Url" }, "order": { "type": "integer", "minimum": 0 } } }, "Honor": { "type": "object", "additionalProperties": false, "required": ["id", "title", "issuer", "date"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "title": { "$ref": "#/$defs/LocalizedTitle" }, "issuer": { "$ref": "#/$defs/LocalizedTitle" }, "description": { "$ref": "#/$defs/LocalizedBody" }, "date": { "$ref": "#/$defs/YearMonth" }, "url": { "$ref": "#/$defs/Url" }, "order": { "type": "integer", "minimum": 0 } } }, "Education": { "type": "object", "additionalProperties": false, "required": ["id", "institution", "startDate"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "institution": { "$ref": "#/$defs/LocalizedTitle" }, "degree": { "$ref": "#/$defs/LocalizedTitle" }, "fieldOfStudy": { "$ref": "#/$defs/LocalizedTitle" }, "description": { "$ref": "#/$defs/LocalizedBody" }, "grade": { "type": "string", "minLength": 1, "maxLength": 50, "description": "Free-form grade / class / GPA. Public exposure controlled by meta.privacy.hideEducationGrades." }, "startDate": { "$ref": "#/$defs/YearMonth" }, "endDate": { "anyOf": [{ "$ref": "#/$defs/YearMonth" }, { "type": "null" }], "description": "null = currently enrolled." }, "isCurrent": { "type": "boolean" }, "url": { "$ref": "#/$defs/Url" }, "order": { "type": "integer", "minimum": 0 } } }, "Publication": { "type": "object", "additionalProperties": false, "required": ["id", "title", "date"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "title": { "$ref": "#/$defs/LocalizedTitle" }, "publisher": { "$ref": "#/$defs/LocalizedTitle" }, "description": { "$ref": "#/$defs/LocalizedBody" }, "date": { "$ref": "#/$defs/YearMonth" }, "url": { "$ref": "#/$defs/Url" }, "doi": { "type": "string", "minLength": 1, "maxLength": 200, "description": "DOI identifier (e.g. '10.1145/3548643.3548644'). The full URL goes in 'url'." }, "coAuthors": { "type": "array", "maxItems": 50, "items": { "type": "string", "minLength": 1, "maxLength": 100 }, "description": "Co-author names in original script. Excludes the profile owner." }, "order": { "type": "integer", "minimum": 0 } } }, "Language": { "type": "object", "additionalProperties": false, "required": ["id", "language", "proficiency"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "language": { "$ref": "#/$defs/LocaleTag" }, "displayName": { "$ref": "#/$defs/LocalizedTitle" }, "proficiency": { "type": "string", "enum": ["native", "fluent", "professional", "intermediate", "basic"], "description": "LinkedIn-compatible 5-level proficiency." }, "order": { "type": "integer", "minimum": 0 } } }, "Course": { "type": "object", "additionalProperties": false, "required": ["id", "title"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "title": { "$ref": "#/$defs/LocalizedTitle" }, "provider": { "$ref": "#/$defs/LocalizedTitle" }, "courseNumber": { "type": "string", "minLength": 1, "maxLength": 50 }, "description": { "$ref": "#/$defs/LocalizedBody" }, "completionDate": { "$ref": "#/$defs/YearMonth" }, "certificateUrl": { "$ref": "#/$defs/Url" }, "relatedEducationId": { "$ref": "#/$defs/Slug", "description": "Optional reference to an education[].id (e.g. for university coursework)." }, "order": { "type": "integer", "minimum": 0 } } }, "Patent": { "type": "object", "additionalProperties": false, "required": ["id", "title", "patentNumber", "status"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "title": { "$ref": "#/$defs/LocalizedTitle" }, "patentNumber": { "type": "string", "minLength": 1, "maxLength": 100 }, "office": { "type": "string", "maxLength": 100, "description": "Patent office name (e.g. 'USPTO', 'JPO', 'EPO')." }, "status": { "type": "string", "enum": ["pending", "issued", "expired", "abandoned"] }, "description": { "$ref": "#/$defs/LocalizedBody" }, "filingDate": { "$ref": "#/$defs/YearMonth" }, "grantDate": { "$ref": "#/$defs/YearMonth" }, "url": { "$ref": "#/$defs/Url" }, "coInventors": { "type": "array", "maxItems": 20, "items": { "type": "string", "minLength": 1, "maxLength": 100 } }, "order": { "type": "integer", "minimum": 0 } } }, "TestScore": { "type": "object", "additionalProperties": false, "required": ["id", "title", "score", "date"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "title": { "$ref": "#/$defs/LocalizedTitle" }, "score": { "type": "string", "minLength": 1, "maxLength": 50, "description": "Free-form score string (e.g. '112 / 120', '330', 'N1 Pass', or a percentile). The validator does not interpret its contents." }, "date": { "$ref": "#/$defs/YearMonth" }, "relatedEducationId": { "$ref": "#/$defs/Slug", "description": "Optional reference to an education[].id (e.g. for a university course exam)." }, "description": { "$ref": "#/$defs/LocalizedBody" }, "url": { "$ref": "#/$defs/Url" }, "order": { "type": "integer", "minimum": 0 } } }, "Recommendation": { "type": "object", "additionalProperties": false, "required": ["id", "body", "author"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "body": { "$ref": "#/$defs/LocalizedBody" }, "author": { "$ref": "#/$defs/RecommendationAuthor" }, "relationship": { "$ref": "#/$defs/LocalizedTitle", "description": "How the recommender relates to the profile owner (e.g. 'managed directly', 'worked together')." }, "date": { "$ref": "#/$defs/YearMonth" }, "relatedCareerId": { "$ref": "#/$defs/Slug", "description": "Optional reference to a careers[].id (the position the recommendation pertains to)." }, "relatedEducationId": { "$ref": "#/$defs/Slug", "description": "Optional reference to an education[].id (e.g. a recommendation from a professor)." }, "order": { "type": "integer", "minimum": 0 } } }, "RecommendationAuthor": { "type": "object", "additionalProperties": false, "required": ["name"], "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 100, "description": "Recommender's name, in its original script. Owner-curated; takuhon does not verify it." }, "headline": { "$ref": "#/$defs/LocalizedTitle", "description": "Recommender's title / role / organization at the time of the recommendation." }, "url": { "$ref": "#/$defs/Url", "description": "Link to the recommender's profile, for external verification by the reader." } } } } };
|
|
308
|
+
var schema31 = { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://takuhon.example/schemas/1.3.0/takuhon.schema.json", "title": "Takuhon Profile", "description": "Portable profile data format consumed by @takuhon/core. The canonical contract for profile content authored as takuhon.json.", "type": "object", "additionalProperties": false, "required": ["schemaVersion", "profile", "contact", "settings", "meta"], "properties": { "schemaVersion": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(-[a-zA-Z0-9.-]+)?$", "description": "Semantic version of the takuhon schema this document conforms to." }, "profile": { "$ref": "#/$defs/Profile" }, "links": { "type": "array", "maxItems": 100, "items": { "$ref": "#/$defs/Link" } }, "careers": { "type": "array", "maxItems": 50, "items": { "$ref": "#/$defs/Career" } }, "projects": { "type": "array", "maxItems": 100, "items": { "$ref": "#/$defs/Project" } }, "skills": { "type": "array", "maxItems": 200, "items": { "$ref": "#/$defs/Skill" } }, "certifications": { "type": "array", "maxItems": 50, "items": { "$ref": "#/$defs/Certification" } }, "memberships": { "type": "array", "maxItems": 50, "items": { "$ref": "#/$defs/Membership" } }, "volunteering": { "type": "array", "maxItems": 50, "items": { "$ref": "#/$defs/Volunteering" } }, "honors": { "type": "array", "maxItems": 50, "items": { "$ref": "#/$defs/Honor" } }, "education": { "type": "array", "maxItems": 30, "items": { "$ref": "#/$defs/Education" } }, "publications": { "type": "array", "maxItems": 100, "items": { "$ref": "#/$defs/Publication" } }, "languages": { "type": "array", "maxItems": 30, "items": { "$ref": "#/$defs/Language" } }, "courses": { "type": "array", "maxItems": 100, "items": { "$ref": "#/$defs/Course" } }, "patents": { "type": "array", "maxItems": 50, "items": { "$ref": "#/$defs/Patent" } }, "testScores": { "type": "array", "maxItems": 30, "items": { "$ref": "#/$defs/TestScore" } }, "recommendations": { "type": "array", "maxItems": 50, "items": { "$ref": "#/$defs/Recommendation" } }, "contact": { "$ref": "#/$defs/Contact" }, "settings": { "$ref": "#/$defs/Settings" }, "meta": { "$ref": "#/$defs/Meta" } }, "$defs": { "LocaleTag": { "type": "string", "minLength": 2, "maxLength": 35, "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})*$", "description": "BCP-47 language tag (e.g., 'en', 'ja', 'zh-Hant', 'pt-BR')." }, "Iso3166Alpha2": { "type": "string", "pattern": "^[A-Z]{2}$", "description": "ISO 3166-1 alpha-2 country code (uppercase, two letters)." }, "YearMonth": { "type": "string", "pattern": "^[0-9]{4}-(0[1-9]|1[0-2])$", "description": "Year-month in 'YYYY-MM' format (Gregorian calendar)." }, "IsoDateTime": { "type": "string", "format": "date-time", "description": "ISO 8601 date-time (e.g., 2026-05-11T12:34:56Z)." }, "Url": { "type": "string", "format": "uri", "maxLength": 2048 }, "Email": { "type": "string", "format": "email", "maxLength": 254 }, "Slug": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z0-9][a-z0-9-]*$", "description": "URL-safe identifier (lowercase alphanumerics and hyphens, must start with alphanumeric)." }, "Visibility": { "type": "string", "enum": ["public", "private"], "description": "Per-item public visibility (added in 0.7.0). 'private' removes the item from every public surface via applyPublicPrivacyFilter; an absent value or 'public' keeps the item public." }, "LocalizedTitle": { "type": "object", "minProperties": 1, "propertyNames": { "type": "string", "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})*$" }, "additionalProperties": { "type": "string", "minLength": 1, "maxLength": 200, "pattern": "\\S" }, "description": "Map of BCP-47 locale tag to short title-like string (max 200 chars per value). Each value must contain at least one non-whitespace character." }, "LocalizedBody": { "type": "object", "minProperties": 1, "propertyNames": { "type": "string", "pattern": "^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})*$" }, "additionalProperties": { "type": "string", "minLength": 1, "maxLength": 5e3, "pattern": "\\S" }, "description": "Map of BCP-47 locale tag to body-length string (max 5000 chars per value). Each value must contain at least one non-whitespace character." }, "LinkType": { "type": "string", "enum": ["website", "blog", "github", "gitlab", "linkedin", "x", "mastodon", "bluesky", "instagram", "youtube", "threads", "facebook", "email", "rss", "custom"], "description": "Identifies the kind of link. 'custom' requires iconUrl." }, "Profile": { "type": "object", "additionalProperties": false, "required": ["displayName"], "properties": { "displayName": { "$ref": "#/$defs/LocalizedTitle" }, "tagline": { "$ref": "#/$defs/LocalizedTitle" }, "bio": { "$ref": "#/$defs/LocalizedBody" }, "avatar": { "$ref": "#/$defs/Avatar" }, "location": { "$ref": "#/$defs/Address" } } }, "Avatar": { "type": "object", "additionalProperties": false, "required": ["url"], "properties": { "url": { "type": "string", "format": "uri-reference", "maxLength": 2048, "description": "URL or path to the avatar image." }, "alt": { "$ref": "#/$defs/LocalizedTitle" } } }, "Address": { "type": "object", "additionalProperties": false, "properties": { "country": { "$ref": "#/$defs/Iso3166Alpha2" }, "region": { "type": "string", "maxLength": 100 }, "locality": { "$ref": "#/$defs/LocalizedTitle" }, "display": { "$ref": "#/$defs/LocalizedTitle" } } }, "Link": { "type": "object", "additionalProperties": false, "required": ["id", "type", "url"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "type": { "$ref": "#/$defs/LinkType" }, "label": { "$ref": "#/$defs/LocalizedTitle" }, "url": { "$ref": "#/$defs/Url" }, "featured": { "type": "boolean" }, "order": { "type": "integer", "minimum": 0 }, "iconUrl": { "$ref": "#/$defs/Url" } }, "allOf": [{ "if": { "properties": { "type": { "const": "custom" } }, "required": ["type"] }, "then": { "properties": { "iconUrl": { "$ref": "#/$defs/Url" } }, "required": ["iconUrl"] } }] }, "Career": { "type": "object", "additionalProperties": false, "required": ["id", "organization", "role", "startDate"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "organization": { "$ref": "#/$defs/LocalizedTitle" }, "role": { "$ref": "#/$defs/LocalizedTitle" }, "description": { "$ref": "#/$defs/LocalizedBody" }, "startDate": { "$ref": "#/$defs/YearMonth" }, "endDate": { "anyOf": [{ "$ref": "#/$defs/YearMonth" }, { "type": "null" }] }, "isCurrent": { "type": "boolean" }, "url": { "$ref": "#/$defs/Url" }, "location": { "$ref": "#/$defs/Address" }, "order": { "type": "integer", "minimum": 0 } } }, "Project": { "type": "object", "additionalProperties": false, "required": ["id", "title"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "title": { "$ref": "#/$defs/LocalizedTitle" }, "description": { "$ref": "#/$defs/LocalizedBody" }, "url": { "$ref": "#/$defs/Url" }, "tags": { "type": "array", "maxItems": 30, "items": { "type": "string", "minLength": 1, "maxLength": 50 } }, "relatedCareerId": { "$ref": "#/$defs/Slug" }, "startDate": { "$ref": "#/$defs/YearMonth" }, "endDate": { "anyOf": [{ "$ref": "#/$defs/YearMonth" }, { "type": "null" }] }, "highlighted": { "type": "boolean" }, "order": { "type": "integer", "minimum": 0 } } }, "Skill": { "type": "object", "additionalProperties": false, "required": ["id", "label"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "label": { "type": "string", "minLength": 1, "maxLength": 100 }, "category": { "type": "string", "minLength": 1, "maxLength": 64, "description": "Recommended values (extensible): programming, design, business, communication, language, music, art, sports, other." }, "order": { "type": "integer", "minimum": 0 } } }, "SkillCategory": { "type": "object", "additionalProperties": false, "required": ["id", "label"], "properties": { "id": { "type": "string", "minLength": 1, "maxLength": 64, "description": "Matches the `category` value on the skills that belong to this group." }, "label": { "$ref": "#/$defs/LocalizedTitle", "description": "Localized display heading for the group." } } }, "Contact": { "type": "object", "additionalProperties": false, "properties": { "email": { "$ref": "#/$defs/Email" }, "showEmail": { "type": "boolean", "default": false }, "formUrl": { "$ref": "#/$defs/Url" } } }, "Settings": { "type": "object", "additionalProperties": false, "required": ["defaultLocale", "availableLocales"], "properties": { "defaultLocale": { "$ref": "#/$defs/LocaleTag" }, "fallbackLocale": { "$ref": "#/$defs/LocaleTag" }, "availableLocales": { "type": "array", "minItems": 1, "maxItems": 50, "uniqueItems": true, "items": { "$ref": "#/$defs/LocaleTag" } }, "theme": { "type": "string", "minLength": 1, "maxLength": 64, "description": "UI theme identifier. 'default' is the built-in theme; adapters may add more." }, "showPoweredBy": { "type": "boolean", "default": true, "description": "Display the 'Powered by takuhon' attribution in the rendered profile." }, "enableJsonLd": { "type": "boolean", "default": true, "description": "Emit Schema.org JSON-LD on the rendered profile page." }, "enableApi": { "type": "boolean", "default": true, "description": "Expose the public read API endpoints (GET /api/profile, /api/jsonld, /api/schema, /takuhon.json)." }, "enableAnalytics": { "type": "boolean", "default": false, "description": "Opt-in flag for first-party analytics. Default is false to keep takuhon privacy-respecting by default." }, "activity": { "$ref": "#/$defs/ActivitySettings" }, "publicVisibility": { "$ref": "#/$defs/PublicVisibility" }, "contact": { "$ref": "#/$defs/ContactSettings" }, "appearance": { "$ref": "#/$defs/AppearanceSettings" }, "skillCategories": { "type": "array", "maxItems": 50, "items": { "$ref": "#/$defs/SkillCategory" }, "description": "Ordered skill-category display groups (added in 1.3.0). When present, the rendered profile groups skills by their `category` under these localized headings, in array order; absent = the flat skill list. A skill whose `category` is not listed here (or which has none) renders in a trailing group so nothing is dropped." } } }, "AppearanceSettings": { "type": "object", "additionalProperties": false, "description": "Opt-in design tokens for the rendered profile (added in 1.2.0). A declarative re-skin seam: owners override the standard renderer's built-in color and font defaults. This is a token map only, not arbitrary CSS \u2014 every value is length- and pattern-constrained so it cannot break out of the inline <style>. Overriding tokens re-skins the page but cannot re-layout it (spacing/radius/type-scale are intentionally not exposed). Absent = the built-in defaults are used unchanged.", "properties": { "fontFamily": { "type": "string", "minLength": 1, "maxLength": 256, "pattern": `^[A-Za-z0-9\\s,'"._-]+$`, "description": 'CSS font-family stack for the page body, e.g. "Inter, system-ui, sans-serif". Quotes and commas are allowed; CSS-structural characters (; { } < >) are not.' }, "colors": { "$ref": "#/$defs/AppearanceColors", "description": "Light-mode (:root) color overrides." }, "colorsDark": { "$ref": "#/$defs/AppearanceColors", "description": "Dark-mode (prefers-color-scheme: dark) color overrides. Note: until the standard renderer ships a default dark palette, only the keys set here change in dark mode." } } }, "AppearanceColors": { "type": "object", "additionalProperties": false, "description": `A set of overridable color tokens. Each value is a CSS color (hex, rgb()/rgba(), hsl()/hsla(), or a named color); CSS-structural characters (; { } < > " ' \\) are disallowed so a value cannot escape the inline <style>.`, "properties": { "bg": { "$ref": "#/$defs/CssColor", "description": "Page background." }, "surface": { "$ref": "#/$defs/CssColor", "description": "Raised surfaces such as skill/tag chips." }, "text": { "$ref": "#/$defs/CssColor", "description": "Primary body text." }, "textMuted": { "$ref": "#/$defs/CssColor", "description": "Secondary/muted text (taglines, meta, captions)." }, "border": { "$ref": "#/$defs/CssColor", "description": "Hairline borders and rules." }, "accent": { "$ref": "#/$defs/CssColor", "description": "Accent color for emphasis and focus affordances." }, "primary": { "$ref": "#/$defs/CssColor", "description": "Primary interactive color, e.g. links." }, "primaryContrast": { "$ref": "#/$defs/CssColor", "description": "Foreground color used on top of the primary color." } } }, "CssColor": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^(?:#[0-9A-Fa-f]{3,8}|[A-Za-z]+|(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\\([A-Za-z0-9.,%/\\s-]*\\))$", "description": "A CSS color value, restricted to a safe allowlist: a hex color (#rgb/#rgba/#rrggbb/#rrggbbaa), a bare keyword (named colors, currentColor, transparent), or a color function (rgb/rgba/hsl/hsla/hwb/lab/lch/oklab/oklch/color). url(), image-set(), var(), and other fetch- or reference-bearing functions are intentionally excluded so a value can never trigger an external request or escape the inline <style>." }, "ContactSettings": { "type": "object", "additionalProperties": false, "description": "Opt-in contact form configuration (added in 1.1.0). Only public values live here; the Turnstile site key is safe to embed in the page. The Turnstile secret, the recipient address, and the From label are provisioned out of band as environment configuration and are never stored in takuhon.json. Adapters that support the form mount the widget and a POST endpoint when 'enabled' is true.", "properties": { "enabled": { "type": "boolean", "default": false, "description": "Master switch. When false (the default), no contact form is mounted even if a site key is present." }, "turnstileSiteKey": { "type": "string", "minLength": 1, "maxLength": 128, "description": "Public Cloudflare Turnstile site key, safe to embed in the page. Without it the widget is not mounted." }, "endpoint": { "type": "string", "minLength": 1, "maxLength": 2048, "description": "Override the POST endpoint the widget submits to. Defaults to /api/contact on the same origin." }, "subjectPrefix": { "type": "string", "minLength": 1, "maxLength": 128, "description": "Subject prefix for the delivered email, e.g. '[example.com contact]'." } } }, "PublicVisibility": { "type": "object", "additionalProperties": false, "description": "Per-section public visibility (added in 0.6.0). Each key is a content section; setting it to false hides that whole section from every public surface (GET /, /api/profile, /api/jsonld, /takuhon.json, MCP, and the derived CV) via the shared applyPublicPrivacyFilter. An absent key \u2014 or an absent object \u2014 means the section is public, so the default is all-visible and omitting this block is fully backwards-compatible. The profile identity (profile.displayName, \u2026) is always public and is intentionally not a key here. Field-level controls (contact.showEmail, meta.privacy.*) still apply within a visible section: visibility is the AND of the feature toggle, this section flag, and the field flag.", "properties": { "links": { "type": "boolean", "description": "Default true. When false, links[] is emitted empty on public surfaces." }, "careers": { "type": "boolean", "description": "Default true. When false, careers[] is emitted empty on public surfaces." }, "projects": { "type": "boolean", "description": "Default true. When false, projects[] is emitted empty on public surfaces." }, "skills": { "type": "boolean", "description": "Default true. When false, skills[] is emitted empty on public surfaces." }, "certifications": { "type": "boolean", "description": "Default true. When false, certifications[] is emitted empty on public surfaces." }, "memberships": { "type": "boolean", "description": "Default true. When false, memberships[] is emitted empty on public surfaces." }, "volunteering": { "type": "boolean", "description": "Default true. When false, volunteering[] is emitted empty on public surfaces." }, "honors": { "type": "boolean", "description": "Default true. When false, honors[] is emitted empty on public surfaces." }, "education": { "type": "boolean", "description": "Default true. When false, education[] is emitted empty on public surfaces." }, "publications": { "type": "boolean", "description": "Default true. When false, publications[] is emitted empty on public surfaces." }, "languages": { "type": "boolean", "description": "Default true. When false, languages[] is emitted empty on public surfaces." }, "courses": { "type": "boolean", "description": "Default true. When false, courses[] is emitted empty on public surfaces." }, "patents": { "type": "boolean", "description": "Default true. When false, patents[] is emitted empty on public surfaces." }, "testScores": { "type": "boolean", "description": "Default true. When false, testScores[] is emitted empty on public surfaces." }, "recommendations": { "type": "boolean", "description": "Default true. When false, recommendations[] is emitted empty on public surfaces." }, "contact": { "type": "boolean", "description": "Default true. When false, the contact section (email, formUrl) is emitted empty on public surfaces." } } }, "ActivitySettings": { "type": "object", "additionalProperties": false, "description": "Opt-in developer-activity dashboard configuration (GitHub / WakaTime). Only the owner-curated settings live here; secrets are provisioned out of band and the synced metrics are stored in a separate document, never in takuhon.json.", "properties": { "enabled": { "type": "boolean", "default": false, "description": "Master switch. When false (the default), the activity section is not rendered even if a snapshot exists." }, "github": { "type": "object", "additionalProperties": false, "required": ["username"], "properties": { "username": { "type": "string", "minLength": 1, "maxLength": 39, "description": "GitHub login whose public activity is summarized." }, "showLanguages": { "type": "boolean", "default": true }, "showContributions": { "type": "boolean", "default": true } } }, "wakatime": { "type": "object", "additionalProperties": false, "required": ["username"], "properties": { "username": { "type": "string", "minLength": 1, "maxLength": 255, "description": "WakaTime username whose coding-time stats are summarized." }, "showCodingTime": { "type": "boolean", "default": true } } }, "showRank": { "type": "boolean", "default": true, "description": "Display the derived activity rank / badge." }, "refreshHintHours": { "type": "integer", "minimum": 1, "maximum": 168, "description": "Advisory refresh cadence in hours. The real cadence is how often the sync step (CLI command or scheduled job) runs." } } }, "Meta": { "type": "object", "additionalProperties": false, "required": ["contentLicense"], "properties": { "createdAt": { "$ref": "#/$defs/IsoDateTime" }, "updatedAt": { "$ref": "#/$defs/IsoDateTime" }, "generator": { "type": "string", "minLength": 1, "maxLength": 100, "description": "Tool that produced this document (e.g. 'Takuhon', 'create-takuhon@0.1.0')." }, "contentLicense": { "$ref": "#/$defs/ContentLicense" }, "privacy": { "$ref": "#/$defs/MetaPrivacy" } } }, "ContentLicense": { "type": "object", "additionalProperties": false, "required": ["spdxId"], "properties": { "spdxId": { "type": "string", "minLength": 1, "maxLength": 64, "description": "SPDX identifier (e.g., 'CC-BY-4.0', 'CC0-1.0') or 'Proprietary'. No default; the profile owner must choose explicitly." }, "url": { "$ref": "#/$defs/Url" }, "attribution": { "type": "object", "additionalProperties": false, "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200 }, "url": { "$ref": "#/$defs/Url" } } }, "rights": { "type": "string", "minLength": 1, "maxLength": 1e3, "description": "Free-form rights statement (used when spdxId='Proprietary' or for additional notices)." } } }, "MetaPrivacy": { "type": "object", "additionalProperties": false, "description": "Opt-out flags that strip personally identifying fields from public API output (GET /api/profile, /api/jsonld, /takuhon.json). Admin endpoints (PUT /api/admin/*, GET /api/admin/export) ignore these flags. Privacy-by-default: omitting the object or individual flags is equivalent to true.", "properties": { "hideCredentialIds": { "type": "boolean", "default": true, "description": "When true (default), strip certifications[*].credentialId from public responses." }, "hideEducationGrades": { "type": "boolean", "default": true, "description": "When true (default), strip education[*].grade from public responses." } } }, "Certification": { "type": "object", "additionalProperties": false, "required": ["id", "title", "issuingOrganization", "issueDate"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "title": { "$ref": "#/$defs/LocalizedTitle" }, "issuingOrganization": { "$ref": "#/$defs/LocalizedTitle" }, "issueDate": { "$ref": "#/$defs/YearMonth" }, "expirationDate": { "anyOf": [{ "$ref": "#/$defs/YearMonth" }, { "type": "null" }], "description": "null = explicitly 'no expiration'. Omit if unknown/unstated." }, "credentialId": { "type": "string", "minLength": 1, "maxLength": 100, "description": "License or certificate number. Public exposure controlled by meta.privacy.hideCredentialIds." }, "url": { "$ref": "#/$defs/Url" }, "order": { "type": "integer", "minimum": 0 } } }, "Membership": { "type": "object", "additionalProperties": false, "required": ["id", "organization", "startDate"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "organization": { "$ref": "#/$defs/LocalizedTitle" }, "role": { "$ref": "#/$defs/LocalizedTitle" }, "description": { "$ref": "#/$defs/LocalizedBody" }, "startDate": { "$ref": "#/$defs/YearMonth" }, "endDate": { "anyOf": [{ "$ref": "#/$defs/YearMonth" }, { "type": "null" }], "description": "null = ongoing. Omit if unknown." }, "isCurrent": { "type": "boolean" }, "url": { "$ref": "#/$defs/Url" }, "order": { "type": "integer", "minimum": 0 } } }, "Volunteering": { "type": "object", "additionalProperties": false, "required": ["id", "organization", "role", "startDate"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "organization": { "$ref": "#/$defs/LocalizedTitle" }, "role": { "$ref": "#/$defs/LocalizedTitle" }, "cause": { "$ref": "#/$defs/LocalizedTitle" }, "description": { "$ref": "#/$defs/LocalizedBody" }, "startDate": { "$ref": "#/$defs/YearMonth" }, "endDate": { "anyOf": [{ "$ref": "#/$defs/YearMonth" }, { "type": "null" }] }, "isCurrent": { "type": "boolean" }, "url": { "$ref": "#/$defs/Url" }, "order": { "type": "integer", "minimum": 0 } } }, "Honor": { "type": "object", "additionalProperties": false, "required": ["id", "title", "issuer", "date"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "title": { "$ref": "#/$defs/LocalizedTitle" }, "issuer": { "$ref": "#/$defs/LocalizedTitle" }, "description": { "$ref": "#/$defs/LocalizedBody" }, "date": { "$ref": "#/$defs/YearMonth" }, "url": { "$ref": "#/$defs/Url" }, "order": { "type": "integer", "minimum": 0 } } }, "Education": { "type": "object", "additionalProperties": false, "required": ["id", "institution", "startDate"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "institution": { "$ref": "#/$defs/LocalizedTitle" }, "degree": { "$ref": "#/$defs/LocalizedTitle" }, "fieldOfStudy": { "$ref": "#/$defs/LocalizedTitle" }, "description": { "$ref": "#/$defs/LocalizedBody" }, "grade": { "type": "string", "minLength": 1, "maxLength": 50, "description": "Free-form grade / class / GPA. Public exposure controlled by meta.privacy.hideEducationGrades." }, "startDate": { "$ref": "#/$defs/YearMonth" }, "endDate": { "anyOf": [{ "$ref": "#/$defs/YearMonth" }, { "type": "null" }], "description": "null = currently enrolled." }, "isCurrent": { "type": "boolean" }, "url": { "$ref": "#/$defs/Url" }, "order": { "type": "integer", "minimum": 0 } } }, "Publication": { "type": "object", "additionalProperties": false, "required": ["id", "title", "date"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "title": { "$ref": "#/$defs/LocalizedTitle" }, "publisher": { "$ref": "#/$defs/LocalizedTitle" }, "description": { "$ref": "#/$defs/LocalizedBody" }, "date": { "$ref": "#/$defs/YearMonth" }, "url": { "$ref": "#/$defs/Url" }, "doi": { "type": "string", "minLength": 1, "maxLength": 200, "description": "DOI identifier (e.g. '10.1145/3548643.3548644'). The full URL goes in 'url'." }, "coAuthors": { "type": "array", "maxItems": 50, "items": { "type": "string", "minLength": 1, "maxLength": 100 }, "description": "Co-author names in original script. Excludes the profile owner." }, "order": { "type": "integer", "minimum": 0 } } }, "Language": { "type": "object", "additionalProperties": false, "required": ["id", "language", "proficiency"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "language": { "$ref": "#/$defs/LocaleTag" }, "displayName": { "$ref": "#/$defs/LocalizedTitle" }, "proficiency": { "type": "string", "enum": ["native", "fluent", "professional", "intermediate", "basic"], "description": "LinkedIn-compatible 5-level proficiency." }, "order": { "type": "integer", "minimum": 0 } } }, "Course": { "type": "object", "additionalProperties": false, "required": ["id", "title"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "title": { "$ref": "#/$defs/LocalizedTitle" }, "provider": { "$ref": "#/$defs/LocalizedTitle" }, "courseNumber": { "type": "string", "minLength": 1, "maxLength": 50 }, "description": { "$ref": "#/$defs/LocalizedBody" }, "completionDate": { "$ref": "#/$defs/YearMonth" }, "certificateUrl": { "$ref": "#/$defs/Url" }, "relatedEducationId": { "$ref": "#/$defs/Slug", "description": "Optional reference to an education[].id (e.g. for university coursework)." }, "order": { "type": "integer", "minimum": 0 } } }, "Patent": { "type": "object", "additionalProperties": false, "required": ["id", "title", "patentNumber", "status"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "title": { "$ref": "#/$defs/LocalizedTitle" }, "patentNumber": { "type": "string", "minLength": 1, "maxLength": 100 }, "office": { "type": "string", "maxLength": 100, "description": "Patent office name (e.g. 'USPTO', 'JPO', 'EPO')." }, "status": { "type": "string", "enum": ["pending", "issued", "expired", "abandoned"] }, "description": { "$ref": "#/$defs/LocalizedBody" }, "filingDate": { "$ref": "#/$defs/YearMonth" }, "grantDate": { "$ref": "#/$defs/YearMonth" }, "url": { "$ref": "#/$defs/Url" }, "coInventors": { "type": "array", "maxItems": 20, "items": { "type": "string", "minLength": 1, "maxLength": 100 } }, "order": { "type": "integer", "minimum": 0 } } }, "TestScore": { "type": "object", "additionalProperties": false, "required": ["id", "title", "score", "date"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "title": { "$ref": "#/$defs/LocalizedTitle" }, "score": { "type": "string", "minLength": 1, "maxLength": 50, "description": "Free-form score string (e.g. '112 / 120', '330', 'N1 Pass', or a percentile). The validator does not interpret its contents." }, "date": { "$ref": "#/$defs/YearMonth" }, "relatedEducationId": { "$ref": "#/$defs/Slug", "description": "Optional reference to an education[].id (e.g. for a university course exam)." }, "description": { "$ref": "#/$defs/LocalizedBody" }, "url": { "$ref": "#/$defs/Url" }, "order": { "type": "integer", "minimum": 0 } } }, "Recommendation": { "type": "object", "additionalProperties": false, "required": ["id", "body", "author"], "properties": { "id": { "$ref": "#/$defs/Slug" }, "visibility": { "$ref": "#/$defs/Visibility" }, "body": { "$ref": "#/$defs/LocalizedBody" }, "author": { "$ref": "#/$defs/RecommendationAuthor" }, "relationship": { "$ref": "#/$defs/LocalizedTitle", "description": "How the recommender relates to the profile owner (e.g. 'managed directly', 'worked together')." }, "date": { "$ref": "#/$defs/YearMonth" }, "relatedCareerId": { "$ref": "#/$defs/Slug", "description": "Optional reference to a careers[].id (the position the recommendation pertains to)." }, "relatedEducationId": { "$ref": "#/$defs/Slug", "description": "Optional reference to an education[].id (e.g. a recommendation from a professor)." }, "order": { "type": "integer", "minimum": 0 } } }, "RecommendationAuthor": { "type": "object", "additionalProperties": false, "required": ["name"], "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 100, "description": "Recommender's name, in its original script. Owner-curated; takuhon does not verify it." }, "headline": { "$ref": "#/$defs/LocalizedTitle", "description": "Recommender's title / role / organization at the time of the recommendation." }, "url": { "$ref": "#/$defs/Url", "description": "Link to the recommender's profile, for external verification by the reader." } } } } };
|
|
309
309
|
var func1 = Object.prototype.hasOwnProperty;
|
|
310
310
|
var pattern4 = new RegExp("^[0-9]+\\.[0-9]+\\.[0-9]+(-[a-zA-Z0-9.-]+)?$", "u");
|
|
311
311
|
var pattern5 = new RegExp("^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})*$", "u");
|
|
@@ -8861,9 +8861,631 @@ var require_takuhon_validator = __commonJS({
|
|
|
8861
8861
|
return errors === 0;
|
|
8862
8862
|
}
|
|
8863
8863
|
validate60.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
8864
|
-
var schema168 = { "type": "object", "additionalProperties": false, "required": ["defaultLocale", "availableLocales"], "properties": { "defaultLocale": { "$ref": "#/$defs/LocaleTag" }, "fallbackLocale": { "$ref": "#/$defs/LocaleTag" }, "availableLocales": { "type": "array", "minItems": 1, "maxItems": 50, "uniqueItems": true, "items": { "$ref": "#/$defs/LocaleTag" } }, "theme": { "type": "string", "minLength": 1, "maxLength": 64, "description": "UI theme identifier. 'default' is the built-in theme; adapters may add more." }, "showPoweredBy": { "type": "boolean", "default": true, "description": "Display the 'Powered by takuhon' attribution in the rendered profile." }, "enableJsonLd": { "type": "boolean", "default": true, "description": "Emit Schema.org JSON-LD on the rendered profile page." }, "enableApi": { "type": "boolean", "default": true, "description": "Expose the public read API endpoints (GET /api/profile, /api/jsonld, /api/schema, /takuhon.json)." }, "enableAnalytics": { "type": "boolean", "default": false, "description": "Opt-in flag for first-party analytics. Default is false to keep takuhon privacy-respecting by default." }, "activity": { "$ref": "#/$defs/ActivitySettings" }, "publicVisibility": { "$ref": "#/$defs/PublicVisibility" } } };
|
|
8864
|
+
var schema168 = { "type": "object", "additionalProperties": false, "required": ["defaultLocale", "availableLocales"], "properties": { "defaultLocale": { "$ref": "#/$defs/LocaleTag" }, "fallbackLocale": { "$ref": "#/$defs/LocaleTag" }, "availableLocales": { "type": "array", "minItems": 1, "maxItems": 50, "uniqueItems": true, "items": { "$ref": "#/$defs/LocaleTag" } }, "theme": { "type": "string", "minLength": 1, "maxLength": 64, "description": "UI theme identifier. 'default' is the built-in theme; adapters may add more." }, "showPoweredBy": { "type": "boolean", "default": true, "description": "Display the 'Powered by takuhon' attribution in the rendered profile." }, "enableJsonLd": { "type": "boolean", "default": true, "description": "Emit Schema.org JSON-LD on the rendered profile page." }, "enableApi": { "type": "boolean", "default": true, "description": "Expose the public read API endpoints (GET /api/profile, /api/jsonld, /api/schema, /takuhon.json)." }, "enableAnalytics": { "type": "boolean", "default": false, "description": "Opt-in flag for first-party analytics. Default is false to keep takuhon privacy-respecting by default." }, "activity": { "$ref": "#/$defs/ActivitySettings" }, "publicVisibility": { "$ref": "#/$defs/PublicVisibility" }, "contact": { "$ref": "#/$defs/ContactSettings" }, "appearance": { "$ref": "#/$defs/AppearanceSettings" }, "skillCategories": { "type": "array", "maxItems": 50, "items": { "$ref": "#/$defs/SkillCategory" }, "description": "Ordered skill-category display groups (added in 1.3.0). When present, the rendered profile groups skills by their `category` under these localized headings, in array order; absent = the flat skill list. A skill whose `category` is not listed here (or which has none) renders in a trailing group so nothing is dropped." } } };
|
|
8865
8865
|
var schema173 = { "type": "object", "additionalProperties": false, "description": "Per-section public visibility (added in 0.6.0). Each key is a content section; setting it to false hides that whole section from every public surface (GET /, /api/profile, /api/jsonld, /takuhon.json, MCP, and the derived CV) via the shared applyPublicPrivacyFilter. An absent key \u2014 or an absent object \u2014 means the section is public, so the default is all-visible and omitting this block is fully backwards-compatible. The profile identity (profile.displayName, \u2026) is always public and is intentionally not a key here. Field-level controls (contact.showEmail, meta.privacy.*) still apply within a visible section: visibility is the AND of the feature toggle, this section flag, and the field flag.", "properties": { "links": { "type": "boolean", "description": "Default true. When false, links[] is emitted empty on public surfaces." }, "careers": { "type": "boolean", "description": "Default true. When false, careers[] is emitted empty on public surfaces." }, "projects": { "type": "boolean", "description": "Default true. When false, projects[] is emitted empty on public surfaces." }, "skills": { "type": "boolean", "description": "Default true. When false, skills[] is emitted empty on public surfaces." }, "certifications": { "type": "boolean", "description": "Default true. When false, certifications[] is emitted empty on public surfaces." }, "memberships": { "type": "boolean", "description": "Default true. When false, memberships[] is emitted empty on public surfaces." }, "volunteering": { "type": "boolean", "description": "Default true. When false, volunteering[] is emitted empty on public surfaces." }, "honors": { "type": "boolean", "description": "Default true. When false, honors[] is emitted empty on public surfaces." }, "education": { "type": "boolean", "description": "Default true. When false, education[] is emitted empty on public surfaces." }, "publications": { "type": "boolean", "description": "Default true. When false, publications[] is emitted empty on public surfaces." }, "languages": { "type": "boolean", "description": "Default true. When false, languages[] is emitted empty on public surfaces." }, "courses": { "type": "boolean", "description": "Default true. When false, courses[] is emitted empty on public surfaces." }, "patents": { "type": "boolean", "description": "Default true. When false, patents[] is emitted empty on public surfaces." }, "testScores": { "type": "boolean", "description": "Default true. When false, testScores[] is emitted empty on public surfaces." }, "recommendations": { "type": "boolean", "description": "Default true. When false, recommendations[] is emitted empty on public surfaces." }, "contact": { "type": "boolean", "description": "Default true. When false, the contact section (email, formUrl) is emitted empty on public surfaces." } } };
|
|
8866
8866
|
var func0 = require_equal().default;
|
|
8867
|
+
var pattern133 = new RegExp(`^[A-Za-z0-9\\s,'"._-]+$`, "u");
|
|
8868
|
+
var pattern134 = new RegExp("^(?:#[0-9A-Fa-f]{3,8}|[A-Za-z]+|(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\\([A-Za-z0-9.,%/\\s-]*\\))$", "u");
|
|
8869
|
+
function validate64(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
8870
|
+
let vErrors = null;
|
|
8871
|
+
let errors = 0;
|
|
8872
|
+
const evaluated0 = validate64.evaluated;
|
|
8873
|
+
if (evaluated0.dynamicProps) {
|
|
8874
|
+
evaluated0.props = void 0;
|
|
8875
|
+
}
|
|
8876
|
+
if (evaluated0.dynamicItems) {
|
|
8877
|
+
evaluated0.items = void 0;
|
|
8878
|
+
}
|
|
8879
|
+
if (data && typeof data == "object" && !Array.isArray(data)) {
|
|
8880
|
+
for (const key0 in data) {
|
|
8881
|
+
if (!(key0 === "bg" || key0 === "surface" || key0 === "text" || key0 === "textMuted" || key0 === "border" || key0 === "accent" || key0 === "primary" || key0 === "primaryContrast")) {
|
|
8882
|
+
const err0 = { instancePath, schemaPath: "#/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key0 }, message: "must NOT have additional properties" };
|
|
8883
|
+
if (vErrors === null) {
|
|
8884
|
+
vErrors = [err0];
|
|
8885
|
+
} else {
|
|
8886
|
+
vErrors.push(err0);
|
|
8887
|
+
}
|
|
8888
|
+
errors++;
|
|
8889
|
+
}
|
|
8890
|
+
}
|
|
8891
|
+
if (data.bg !== void 0) {
|
|
8892
|
+
let data0 = data.bg;
|
|
8893
|
+
if (typeof data0 === "string") {
|
|
8894
|
+
if (func2(data0) > 64) {
|
|
8895
|
+
const err1 = { instancePath: instancePath + "/bg", schemaPath: "#/$defs/CssColor/maxLength", keyword: "maxLength", params: { limit: 64 }, message: "must NOT have more than 64 characters" };
|
|
8896
|
+
if (vErrors === null) {
|
|
8897
|
+
vErrors = [err1];
|
|
8898
|
+
} else {
|
|
8899
|
+
vErrors.push(err1);
|
|
8900
|
+
}
|
|
8901
|
+
errors++;
|
|
8902
|
+
}
|
|
8903
|
+
if (func2(data0) < 1) {
|
|
8904
|
+
const err2 = { instancePath: instancePath + "/bg", schemaPath: "#/$defs/CssColor/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
|
|
8905
|
+
if (vErrors === null) {
|
|
8906
|
+
vErrors = [err2];
|
|
8907
|
+
} else {
|
|
8908
|
+
vErrors.push(err2);
|
|
8909
|
+
}
|
|
8910
|
+
errors++;
|
|
8911
|
+
}
|
|
8912
|
+
if (!pattern134.test(data0)) {
|
|
8913
|
+
const err3 = { instancePath: instancePath + "/bg", schemaPath: "#/$defs/CssColor/pattern", keyword: "pattern", params: { pattern: "^(?:#[0-9A-Fa-f]{3,8}|[A-Za-z]+|(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\\([A-Za-z0-9.,%/\\s-]*\\))$" }, message: 'must match pattern "^(?:#[0-9A-Fa-f]{3,8}|[A-Za-z]+|(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\\([A-Za-z0-9.,%/\\s-]*\\))$"' };
|
|
8914
|
+
if (vErrors === null) {
|
|
8915
|
+
vErrors = [err3];
|
|
8916
|
+
} else {
|
|
8917
|
+
vErrors.push(err3);
|
|
8918
|
+
}
|
|
8919
|
+
errors++;
|
|
8920
|
+
}
|
|
8921
|
+
} else {
|
|
8922
|
+
const err4 = { instancePath: instancePath + "/bg", schemaPath: "#/$defs/CssColor/type", keyword: "type", params: { type: "string" }, message: "must be string" };
|
|
8923
|
+
if (vErrors === null) {
|
|
8924
|
+
vErrors = [err4];
|
|
8925
|
+
} else {
|
|
8926
|
+
vErrors.push(err4);
|
|
8927
|
+
}
|
|
8928
|
+
errors++;
|
|
8929
|
+
}
|
|
8930
|
+
}
|
|
8931
|
+
if (data.surface !== void 0) {
|
|
8932
|
+
let data1 = data.surface;
|
|
8933
|
+
if (typeof data1 === "string") {
|
|
8934
|
+
if (func2(data1) > 64) {
|
|
8935
|
+
const err5 = { instancePath: instancePath + "/surface", schemaPath: "#/$defs/CssColor/maxLength", keyword: "maxLength", params: { limit: 64 }, message: "must NOT have more than 64 characters" };
|
|
8936
|
+
if (vErrors === null) {
|
|
8937
|
+
vErrors = [err5];
|
|
8938
|
+
} else {
|
|
8939
|
+
vErrors.push(err5);
|
|
8940
|
+
}
|
|
8941
|
+
errors++;
|
|
8942
|
+
}
|
|
8943
|
+
if (func2(data1) < 1) {
|
|
8944
|
+
const err6 = { instancePath: instancePath + "/surface", schemaPath: "#/$defs/CssColor/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
|
|
8945
|
+
if (vErrors === null) {
|
|
8946
|
+
vErrors = [err6];
|
|
8947
|
+
} else {
|
|
8948
|
+
vErrors.push(err6);
|
|
8949
|
+
}
|
|
8950
|
+
errors++;
|
|
8951
|
+
}
|
|
8952
|
+
if (!pattern134.test(data1)) {
|
|
8953
|
+
const err7 = { instancePath: instancePath + "/surface", schemaPath: "#/$defs/CssColor/pattern", keyword: "pattern", params: { pattern: "^(?:#[0-9A-Fa-f]{3,8}|[A-Za-z]+|(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\\([A-Za-z0-9.,%/\\s-]*\\))$" }, message: 'must match pattern "^(?:#[0-9A-Fa-f]{3,8}|[A-Za-z]+|(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\\([A-Za-z0-9.,%/\\s-]*\\))$"' };
|
|
8954
|
+
if (vErrors === null) {
|
|
8955
|
+
vErrors = [err7];
|
|
8956
|
+
} else {
|
|
8957
|
+
vErrors.push(err7);
|
|
8958
|
+
}
|
|
8959
|
+
errors++;
|
|
8960
|
+
}
|
|
8961
|
+
} else {
|
|
8962
|
+
const err8 = { instancePath: instancePath + "/surface", schemaPath: "#/$defs/CssColor/type", keyword: "type", params: { type: "string" }, message: "must be string" };
|
|
8963
|
+
if (vErrors === null) {
|
|
8964
|
+
vErrors = [err8];
|
|
8965
|
+
} else {
|
|
8966
|
+
vErrors.push(err8);
|
|
8967
|
+
}
|
|
8968
|
+
errors++;
|
|
8969
|
+
}
|
|
8970
|
+
}
|
|
8971
|
+
if (data.text !== void 0) {
|
|
8972
|
+
let data2 = data.text;
|
|
8973
|
+
if (typeof data2 === "string") {
|
|
8974
|
+
if (func2(data2) > 64) {
|
|
8975
|
+
const err9 = { instancePath: instancePath + "/text", schemaPath: "#/$defs/CssColor/maxLength", keyword: "maxLength", params: { limit: 64 }, message: "must NOT have more than 64 characters" };
|
|
8976
|
+
if (vErrors === null) {
|
|
8977
|
+
vErrors = [err9];
|
|
8978
|
+
} else {
|
|
8979
|
+
vErrors.push(err9);
|
|
8980
|
+
}
|
|
8981
|
+
errors++;
|
|
8982
|
+
}
|
|
8983
|
+
if (func2(data2) < 1) {
|
|
8984
|
+
const err10 = { instancePath: instancePath + "/text", schemaPath: "#/$defs/CssColor/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
|
|
8985
|
+
if (vErrors === null) {
|
|
8986
|
+
vErrors = [err10];
|
|
8987
|
+
} else {
|
|
8988
|
+
vErrors.push(err10);
|
|
8989
|
+
}
|
|
8990
|
+
errors++;
|
|
8991
|
+
}
|
|
8992
|
+
if (!pattern134.test(data2)) {
|
|
8993
|
+
const err11 = { instancePath: instancePath + "/text", schemaPath: "#/$defs/CssColor/pattern", keyword: "pattern", params: { pattern: "^(?:#[0-9A-Fa-f]{3,8}|[A-Za-z]+|(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\\([A-Za-z0-9.,%/\\s-]*\\))$" }, message: 'must match pattern "^(?:#[0-9A-Fa-f]{3,8}|[A-Za-z]+|(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\\([A-Za-z0-9.,%/\\s-]*\\))$"' };
|
|
8994
|
+
if (vErrors === null) {
|
|
8995
|
+
vErrors = [err11];
|
|
8996
|
+
} else {
|
|
8997
|
+
vErrors.push(err11);
|
|
8998
|
+
}
|
|
8999
|
+
errors++;
|
|
9000
|
+
}
|
|
9001
|
+
} else {
|
|
9002
|
+
const err12 = { instancePath: instancePath + "/text", schemaPath: "#/$defs/CssColor/type", keyword: "type", params: { type: "string" }, message: "must be string" };
|
|
9003
|
+
if (vErrors === null) {
|
|
9004
|
+
vErrors = [err12];
|
|
9005
|
+
} else {
|
|
9006
|
+
vErrors.push(err12);
|
|
9007
|
+
}
|
|
9008
|
+
errors++;
|
|
9009
|
+
}
|
|
9010
|
+
}
|
|
9011
|
+
if (data.textMuted !== void 0) {
|
|
9012
|
+
let data3 = data.textMuted;
|
|
9013
|
+
if (typeof data3 === "string") {
|
|
9014
|
+
if (func2(data3) > 64) {
|
|
9015
|
+
const err13 = { instancePath: instancePath + "/textMuted", schemaPath: "#/$defs/CssColor/maxLength", keyword: "maxLength", params: { limit: 64 }, message: "must NOT have more than 64 characters" };
|
|
9016
|
+
if (vErrors === null) {
|
|
9017
|
+
vErrors = [err13];
|
|
9018
|
+
} else {
|
|
9019
|
+
vErrors.push(err13);
|
|
9020
|
+
}
|
|
9021
|
+
errors++;
|
|
9022
|
+
}
|
|
9023
|
+
if (func2(data3) < 1) {
|
|
9024
|
+
const err14 = { instancePath: instancePath + "/textMuted", schemaPath: "#/$defs/CssColor/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
|
|
9025
|
+
if (vErrors === null) {
|
|
9026
|
+
vErrors = [err14];
|
|
9027
|
+
} else {
|
|
9028
|
+
vErrors.push(err14);
|
|
9029
|
+
}
|
|
9030
|
+
errors++;
|
|
9031
|
+
}
|
|
9032
|
+
if (!pattern134.test(data3)) {
|
|
9033
|
+
const err15 = { instancePath: instancePath + "/textMuted", schemaPath: "#/$defs/CssColor/pattern", keyword: "pattern", params: { pattern: "^(?:#[0-9A-Fa-f]{3,8}|[A-Za-z]+|(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\\([A-Za-z0-9.,%/\\s-]*\\))$" }, message: 'must match pattern "^(?:#[0-9A-Fa-f]{3,8}|[A-Za-z]+|(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\\([A-Za-z0-9.,%/\\s-]*\\))$"' };
|
|
9034
|
+
if (vErrors === null) {
|
|
9035
|
+
vErrors = [err15];
|
|
9036
|
+
} else {
|
|
9037
|
+
vErrors.push(err15);
|
|
9038
|
+
}
|
|
9039
|
+
errors++;
|
|
9040
|
+
}
|
|
9041
|
+
} else {
|
|
9042
|
+
const err16 = { instancePath: instancePath + "/textMuted", schemaPath: "#/$defs/CssColor/type", keyword: "type", params: { type: "string" }, message: "must be string" };
|
|
9043
|
+
if (vErrors === null) {
|
|
9044
|
+
vErrors = [err16];
|
|
9045
|
+
} else {
|
|
9046
|
+
vErrors.push(err16);
|
|
9047
|
+
}
|
|
9048
|
+
errors++;
|
|
9049
|
+
}
|
|
9050
|
+
}
|
|
9051
|
+
if (data.border !== void 0) {
|
|
9052
|
+
let data4 = data.border;
|
|
9053
|
+
if (typeof data4 === "string") {
|
|
9054
|
+
if (func2(data4) > 64) {
|
|
9055
|
+
const err17 = { instancePath: instancePath + "/border", schemaPath: "#/$defs/CssColor/maxLength", keyword: "maxLength", params: { limit: 64 }, message: "must NOT have more than 64 characters" };
|
|
9056
|
+
if (vErrors === null) {
|
|
9057
|
+
vErrors = [err17];
|
|
9058
|
+
} else {
|
|
9059
|
+
vErrors.push(err17);
|
|
9060
|
+
}
|
|
9061
|
+
errors++;
|
|
9062
|
+
}
|
|
9063
|
+
if (func2(data4) < 1) {
|
|
9064
|
+
const err18 = { instancePath: instancePath + "/border", schemaPath: "#/$defs/CssColor/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
|
|
9065
|
+
if (vErrors === null) {
|
|
9066
|
+
vErrors = [err18];
|
|
9067
|
+
} else {
|
|
9068
|
+
vErrors.push(err18);
|
|
9069
|
+
}
|
|
9070
|
+
errors++;
|
|
9071
|
+
}
|
|
9072
|
+
if (!pattern134.test(data4)) {
|
|
9073
|
+
const err19 = { instancePath: instancePath + "/border", schemaPath: "#/$defs/CssColor/pattern", keyword: "pattern", params: { pattern: "^(?:#[0-9A-Fa-f]{3,8}|[A-Za-z]+|(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\\([A-Za-z0-9.,%/\\s-]*\\))$" }, message: 'must match pattern "^(?:#[0-9A-Fa-f]{3,8}|[A-Za-z]+|(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\\([A-Za-z0-9.,%/\\s-]*\\))$"' };
|
|
9074
|
+
if (vErrors === null) {
|
|
9075
|
+
vErrors = [err19];
|
|
9076
|
+
} else {
|
|
9077
|
+
vErrors.push(err19);
|
|
9078
|
+
}
|
|
9079
|
+
errors++;
|
|
9080
|
+
}
|
|
9081
|
+
} else {
|
|
9082
|
+
const err20 = { instancePath: instancePath + "/border", schemaPath: "#/$defs/CssColor/type", keyword: "type", params: { type: "string" }, message: "must be string" };
|
|
9083
|
+
if (vErrors === null) {
|
|
9084
|
+
vErrors = [err20];
|
|
9085
|
+
} else {
|
|
9086
|
+
vErrors.push(err20);
|
|
9087
|
+
}
|
|
9088
|
+
errors++;
|
|
9089
|
+
}
|
|
9090
|
+
}
|
|
9091
|
+
if (data.accent !== void 0) {
|
|
9092
|
+
let data5 = data.accent;
|
|
9093
|
+
if (typeof data5 === "string") {
|
|
9094
|
+
if (func2(data5) > 64) {
|
|
9095
|
+
const err21 = { instancePath: instancePath + "/accent", schemaPath: "#/$defs/CssColor/maxLength", keyword: "maxLength", params: { limit: 64 }, message: "must NOT have more than 64 characters" };
|
|
9096
|
+
if (vErrors === null) {
|
|
9097
|
+
vErrors = [err21];
|
|
9098
|
+
} else {
|
|
9099
|
+
vErrors.push(err21);
|
|
9100
|
+
}
|
|
9101
|
+
errors++;
|
|
9102
|
+
}
|
|
9103
|
+
if (func2(data5) < 1) {
|
|
9104
|
+
const err22 = { instancePath: instancePath + "/accent", schemaPath: "#/$defs/CssColor/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
|
|
9105
|
+
if (vErrors === null) {
|
|
9106
|
+
vErrors = [err22];
|
|
9107
|
+
} else {
|
|
9108
|
+
vErrors.push(err22);
|
|
9109
|
+
}
|
|
9110
|
+
errors++;
|
|
9111
|
+
}
|
|
9112
|
+
if (!pattern134.test(data5)) {
|
|
9113
|
+
const err23 = { instancePath: instancePath + "/accent", schemaPath: "#/$defs/CssColor/pattern", keyword: "pattern", params: { pattern: "^(?:#[0-9A-Fa-f]{3,8}|[A-Za-z]+|(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\\([A-Za-z0-9.,%/\\s-]*\\))$" }, message: 'must match pattern "^(?:#[0-9A-Fa-f]{3,8}|[A-Za-z]+|(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\\([A-Za-z0-9.,%/\\s-]*\\))$"' };
|
|
9114
|
+
if (vErrors === null) {
|
|
9115
|
+
vErrors = [err23];
|
|
9116
|
+
} else {
|
|
9117
|
+
vErrors.push(err23);
|
|
9118
|
+
}
|
|
9119
|
+
errors++;
|
|
9120
|
+
}
|
|
9121
|
+
} else {
|
|
9122
|
+
const err24 = { instancePath: instancePath + "/accent", schemaPath: "#/$defs/CssColor/type", keyword: "type", params: { type: "string" }, message: "must be string" };
|
|
9123
|
+
if (vErrors === null) {
|
|
9124
|
+
vErrors = [err24];
|
|
9125
|
+
} else {
|
|
9126
|
+
vErrors.push(err24);
|
|
9127
|
+
}
|
|
9128
|
+
errors++;
|
|
9129
|
+
}
|
|
9130
|
+
}
|
|
9131
|
+
if (data.primary !== void 0) {
|
|
9132
|
+
let data6 = data.primary;
|
|
9133
|
+
if (typeof data6 === "string") {
|
|
9134
|
+
if (func2(data6) > 64) {
|
|
9135
|
+
const err25 = { instancePath: instancePath + "/primary", schemaPath: "#/$defs/CssColor/maxLength", keyword: "maxLength", params: { limit: 64 }, message: "must NOT have more than 64 characters" };
|
|
9136
|
+
if (vErrors === null) {
|
|
9137
|
+
vErrors = [err25];
|
|
9138
|
+
} else {
|
|
9139
|
+
vErrors.push(err25);
|
|
9140
|
+
}
|
|
9141
|
+
errors++;
|
|
9142
|
+
}
|
|
9143
|
+
if (func2(data6) < 1) {
|
|
9144
|
+
const err26 = { instancePath: instancePath + "/primary", schemaPath: "#/$defs/CssColor/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
|
|
9145
|
+
if (vErrors === null) {
|
|
9146
|
+
vErrors = [err26];
|
|
9147
|
+
} else {
|
|
9148
|
+
vErrors.push(err26);
|
|
9149
|
+
}
|
|
9150
|
+
errors++;
|
|
9151
|
+
}
|
|
9152
|
+
if (!pattern134.test(data6)) {
|
|
9153
|
+
const err27 = { instancePath: instancePath + "/primary", schemaPath: "#/$defs/CssColor/pattern", keyword: "pattern", params: { pattern: "^(?:#[0-9A-Fa-f]{3,8}|[A-Za-z]+|(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\\([A-Za-z0-9.,%/\\s-]*\\))$" }, message: 'must match pattern "^(?:#[0-9A-Fa-f]{3,8}|[A-Za-z]+|(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\\([A-Za-z0-9.,%/\\s-]*\\))$"' };
|
|
9154
|
+
if (vErrors === null) {
|
|
9155
|
+
vErrors = [err27];
|
|
9156
|
+
} else {
|
|
9157
|
+
vErrors.push(err27);
|
|
9158
|
+
}
|
|
9159
|
+
errors++;
|
|
9160
|
+
}
|
|
9161
|
+
} else {
|
|
9162
|
+
const err28 = { instancePath: instancePath + "/primary", schemaPath: "#/$defs/CssColor/type", keyword: "type", params: { type: "string" }, message: "must be string" };
|
|
9163
|
+
if (vErrors === null) {
|
|
9164
|
+
vErrors = [err28];
|
|
9165
|
+
} else {
|
|
9166
|
+
vErrors.push(err28);
|
|
9167
|
+
}
|
|
9168
|
+
errors++;
|
|
9169
|
+
}
|
|
9170
|
+
}
|
|
9171
|
+
if (data.primaryContrast !== void 0) {
|
|
9172
|
+
let data7 = data.primaryContrast;
|
|
9173
|
+
if (typeof data7 === "string") {
|
|
9174
|
+
if (func2(data7) > 64) {
|
|
9175
|
+
const err29 = { instancePath: instancePath + "/primaryContrast", schemaPath: "#/$defs/CssColor/maxLength", keyword: "maxLength", params: { limit: 64 }, message: "must NOT have more than 64 characters" };
|
|
9176
|
+
if (vErrors === null) {
|
|
9177
|
+
vErrors = [err29];
|
|
9178
|
+
} else {
|
|
9179
|
+
vErrors.push(err29);
|
|
9180
|
+
}
|
|
9181
|
+
errors++;
|
|
9182
|
+
}
|
|
9183
|
+
if (func2(data7) < 1) {
|
|
9184
|
+
const err30 = { instancePath: instancePath + "/primaryContrast", schemaPath: "#/$defs/CssColor/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
|
|
9185
|
+
if (vErrors === null) {
|
|
9186
|
+
vErrors = [err30];
|
|
9187
|
+
} else {
|
|
9188
|
+
vErrors.push(err30);
|
|
9189
|
+
}
|
|
9190
|
+
errors++;
|
|
9191
|
+
}
|
|
9192
|
+
if (!pattern134.test(data7)) {
|
|
9193
|
+
const err31 = { instancePath: instancePath + "/primaryContrast", schemaPath: "#/$defs/CssColor/pattern", keyword: "pattern", params: { pattern: "^(?:#[0-9A-Fa-f]{3,8}|[A-Za-z]+|(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\\([A-Za-z0-9.,%/\\s-]*\\))$" }, message: 'must match pattern "^(?:#[0-9A-Fa-f]{3,8}|[A-Za-z]+|(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\\([A-Za-z0-9.,%/\\s-]*\\))$"' };
|
|
9194
|
+
if (vErrors === null) {
|
|
9195
|
+
vErrors = [err31];
|
|
9196
|
+
} else {
|
|
9197
|
+
vErrors.push(err31);
|
|
9198
|
+
}
|
|
9199
|
+
errors++;
|
|
9200
|
+
}
|
|
9201
|
+
} else {
|
|
9202
|
+
const err32 = { instancePath: instancePath + "/primaryContrast", schemaPath: "#/$defs/CssColor/type", keyword: "type", params: { type: "string" }, message: "must be string" };
|
|
9203
|
+
if (vErrors === null) {
|
|
9204
|
+
vErrors = [err32];
|
|
9205
|
+
} else {
|
|
9206
|
+
vErrors.push(err32);
|
|
9207
|
+
}
|
|
9208
|
+
errors++;
|
|
9209
|
+
}
|
|
9210
|
+
}
|
|
9211
|
+
} else {
|
|
9212
|
+
const err33 = { instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" };
|
|
9213
|
+
if (vErrors === null) {
|
|
9214
|
+
vErrors = [err33];
|
|
9215
|
+
} else {
|
|
9216
|
+
vErrors.push(err33);
|
|
9217
|
+
}
|
|
9218
|
+
errors++;
|
|
9219
|
+
}
|
|
9220
|
+
validate64.errors = vErrors;
|
|
9221
|
+
return errors === 0;
|
|
9222
|
+
}
|
|
9223
|
+
validate64.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
9224
|
+
function validate63(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
9225
|
+
let vErrors = null;
|
|
9226
|
+
let errors = 0;
|
|
9227
|
+
const evaluated0 = validate63.evaluated;
|
|
9228
|
+
if (evaluated0.dynamicProps) {
|
|
9229
|
+
evaluated0.props = void 0;
|
|
9230
|
+
}
|
|
9231
|
+
if (evaluated0.dynamicItems) {
|
|
9232
|
+
evaluated0.items = void 0;
|
|
9233
|
+
}
|
|
9234
|
+
if (data && typeof data == "object" && !Array.isArray(data)) {
|
|
9235
|
+
for (const key0 in data) {
|
|
9236
|
+
if (!(key0 === "fontFamily" || key0 === "colors" || key0 === "colorsDark")) {
|
|
9237
|
+
const err0 = { instancePath, schemaPath: "#/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key0 }, message: "must NOT have additional properties" };
|
|
9238
|
+
if (vErrors === null) {
|
|
9239
|
+
vErrors = [err0];
|
|
9240
|
+
} else {
|
|
9241
|
+
vErrors.push(err0);
|
|
9242
|
+
}
|
|
9243
|
+
errors++;
|
|
9244
|
+
}
|
|
9245
|
+
}
|
|
9246
|
+
if (data.fontFamily !== void 0) {
|
|
9247
|
+
let data0 = data.fontFamily;
|
|
9248
|
+
if (typeof data0 === "string") {
|
|
9249
|
+
if (func2(data0) > 256) {
|
|
9250
|
+
const err1 = { instancePath: instancePath + "/fontFamily", schemaPath: "#/properties/fontFamily/maxLength", keyword: "maxLength", params: { limit: 256 }, message: "must NOT have more than 256 characters" };
|
|
9251
|
+
if (vErrors === null) {
|
|
9252
|
+
vErrors = [err1];
|
|
9253
|
+
} else {
|
|
9254
|
+
vErrors.push(err1);
|
|
9255
|
+
}
|
|
9256
|
+
errors++;
|
|
9257
|
+
}
|
|
9258
|
+
if (func2(data0) < 1) {
|
|
9259
|
+
const err2 = { instancePath: instancePath + "/fontFamily", schemaPath: "#/properties/fontFamily/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
|
|
9260
|
+
if (vErrors === null) {
|
|
9261
|
+
vErrors = [err2];
|
|
9262
|
+
} else {
|
|
9263
|
+
vErrors.push(err2);
|
|
9264
|
+
}
|
|
9265
|
+
errors++;
|
|
9266
|
+
}
|
|
9267
|
+
if (!pattern133.test(data0)) {
|
|
9268
|
+
const err3 = { instancePath: instancePath + "/fontFamily", schemaPath: "#/properties/fontFamily/pattern", keyword: "pattern", params: { pattern: `^[A-Za-z0-9\\s,'"._-]+$` }, message: `must match pattern "^[A-Za-z0-9\\s,'"._-]+$"` };
|
|
9269
|
+
if (vErrors === null) {
|
|
9270
|
+
vErrors = [err3];
|
|
9271
|
+
} else {
|
|
9272
|
+
vErrors.push(err3);
|
|
9273
|
+
}
|
|
9274
|
+
errors++;
|
|
9275
|
+
}
|
|
9276
|
+
} else {
|
|
9277
|
+
const err4 = { instancePath: instancePath + "/fontFamily", schemaPath: "#/properties/fontFamily/type", keyword: "type", params: { type: "string" }, message: "must be string" };
|
|
9278
|
+
if (vErrors === null) {
|
|
9279
|
+
vErrors = [err4];
|
|
9280
|
+
} else {
|
|
9281
|
+
vErrors.push(err4);
|
|
9282
|
+
}
|
|
9283
|
+
errors++;
|
|
9284
|
+
}
|
|
9285
|
+
}
|
|
9286
|
+
if (data.colors !== void 0) {
|
|
9287
|
+
if (!validate64(data.colors, { instancePath: instancePath + "/colors", parentData: data, parentDataProperty: "colors", rootData, dynamicAnchors })) {
|
|
9288
|
+
vErrors = vErrors === null ? validate64.errors : vErrors.concat(validate64.errors);
|
|
9289
|
+
errors = vErrors.length;
|
|
9290
|
+
}
|
|
9291
|
+
}
|
|
9292
|
+
if (data.colorsDark !== void 0) {
|
|
9293
|
+
if (!validate64(data.colorsDark, { instancePath: instancePath + "/colorsDark", parentData: data, parentDataProperty: "colorsDark", rootData, dynamicAnchors })) {
|
|
9294
|
+
vErrors = vErrors === null ? validate64.errors : vErrors.concat(validate64.errors);
|
|
9295
|
+
errors = vErrors.length;
|
|
9296
|
+
}
|
|
9297
|
+
}
|
|
9298
|
+
} else {
|
|
9299
|
+
const err5 = { instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" };
|
|
9300
|
+
if (vErrors === null) {
|
|
9301
|
+
vErrors = [err5];
|
|
9302
|
+
} else {
|
|
9303
|
+
vErrors.push(err5);
|
|
9304
|
+
}
|
|
9305
|
+
errors++;
|
|
9306
|
+
}
|
|
9307
|
+
validate63.errors = vErrors;
|
|
9308
|
+
return errors === 0;
|
|
9309
|
+
}
|
|
9310
|
+
validate63.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
9311
|
+
function validate68(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
9312
|
+
let vErrors = null;
|
|
9313
|
+
let errors = 0;
|
|
9314
|
+
const evaluated0 = validate68.evaluated;
|
|
9315
|
+
if (evaluated0.dynamicProps) {
|
|
9316
|
+
evaluated0.props = void 0;
|
|
9317
|
+
}
|
|
9318
|
+
if (evaluated0.dynamicItems) {
|
|
9319
|
+
evaluated0.items = void 0;
|
|
9320
|
+
}
|
|
9321
|
+
if (data && typeof data == "object" && !Array.isArray(data)) {
|
|
9322
|
+
if (data.id === void 0) {
|
|
9323
|
+
const err0 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "id" }, message: "must have required property 'id'" };
|
|
9324
|
+
if (vErrors === null) {
|
|
9325
|
+
vErrors = [err0];
|
|
9326
|
+
} else {
|
|
9327
|
+
vErrors.push(err0);
|
|
9328
|
+
}
|
|
9329
|
+
errors++;
|
|
9330
|
+
}
|
|
9331
|
+
if (data.label === void 0) {
|
|
9332
|
+
const err1 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "label" }, message: "must have required property 'label'" };
|
|
9333
|
+
if (vErrors === null) {
|
|
9334
|
+
vErrors = [err1];
|
|
9335
|
+
} else {
|
|
9336
|
+
vErrors.push(err1);
|
|
9337
|
+
}
|
|
9338
|
+
errors++;
|
|
9339
|
+
}
|
|
9340
|
+
for (const key0 in data) {
|
|
9341
|
+
if (!(key0 === "id" || key0 === "label")) {
|
|
9342
|
+
const err2 = { instancePath, schemaPath: "#/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key0 }, message: "must NOT have additional properties" };
|
|
9343
|
+
if (vErrors === null) {
|
|
9344
|
+
vErrors = [err2];
|
|
9345
|
+
} else {
|
|
9346
|
+
vErrors.push(err2);
|
|
9347
|
+
}
|
|
9348
|
+
errors++;
|
|
9349
|
+
}
|
|
9350
|
+
}
|
|
9351
|
+
if (data.id !== void 0) {
|
|
9352
|
+
let data0 = data.id;
|
|
9353
|
+
if (typeof data0 === "string") {
|
|
9354
|
+
if (func2(data0) > 64) {
|
|
9355
|
+
const err3 = { instancePath: instancePath + "/id", schemaPath: "#/properties/id/maxLength", keyword: "maxLength", params: { limit: 64 }, message: "must NOT have more than 64 characters" };
|
|
9356
|
+
if (vErrors === null) {
|
|
9357
|
+
vErrors = [err3];
|
|
9358
|
+
} else {
|
|
9359
|
+
vErrors.push(err3);
|
|
9360
|
+
}
|
|
9361
|
+
errors++;
|
|
9362
|
+
}
|
|
9363
|
+
if (func2(data0) < 1) {
|
|
9364
|
+
const err4 = { instancePath: instancePath + "/id", schemaPath: "#/properties/id/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
|
|
9365
|
+
if (vErrors === null) {
|
|
9366
|
+
vErrors = [err4];
|
|
9367
|
+
} else {
|
|
9368
|
+
vErrors.push(err4);
|
|
9369
|
+
}
|
|
9370
|
+
errors++;
|
|
9371
|
+
}
|
|
9372
|
+
} else {
|
|
9373
|
+
const err5 = { instancePath: instancePath + "/id", schemaPath: "#/properties/id/type", keyword: "type", params: { type: "string" }, message: "must be string" };
|
|
9374
|
+
if (vErrors === null) {
|
|
9375
|
+
vErrors = [err5];
|
|
9376
|
+
} else {
|
|
9377
|
+
vErrors.push(err5);
|
|
9378
|
+
}
|
|
9379
|
+
errors++;
|
|
9380
|
+
}
|
|
9381
|
+
}
|
|
9382
|
+
if (data.label !== void 0) {
|
|
9383
|
+
let data1 = data.label;
|
|
9384
|
+
if (data1 && typeof data1 == "object" && !Array.isArray(data1)) {
|
|
9385
|
+
if (Object.keys(data1).length < 1) {
|
|
9386
|
+
const err6 = { instancePath: instancePath + "/label", schemaPath: "#/$defs/LocalizedTitle/minProperties", keyword: "minProperties", params: { limit: 1 }, message: "must NOT have fewer than 1 properties" };
|
|
9387
|
+
if (vErrors === null) {
|
|
9388
|
+
vErrors = [err6];
|
|
9389
|
+
} else {
|
|
9390
|
+
vErrors.push(err6);
|
|
9391
|
+
}
|
|
9392
|
+
errors++;
|
|
9393
|
+
}
|
|
9394
|
+
for (const key1 in data1) {
|
|
9395
|
+
const _errs7 = errors;
|
|
9396
|
+
if (typeof key1 === "string") {
|
|
9397
|
+
if (!pattern5.test(key1)) {
|
|
9398
|
+
const err7 = { instancePath: instancePath + "/label", schemaPath: "#/$defs/LocalizedTitle/propertyNames/pattern", keyword: "pattern", params: { pattern: "^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})*$" }, message: 'must match pattern "^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})*$"', propertyName: key1 };
|
|
9399
|
+
if (vErrors === null) {
|
|
9400
|
+
vErrors = [err7];
|
|
9401
|
+
} else {
|
|
9402
|
+
vErrors.push(err7);
|
|
9403
|
+
}
|
|
9404
|
+
errors++;
|
|
9405
|
+
}
|
|
9406
|
+
} else {
|
|
9407
|
+
const err8 = { instancePath: instancePath + "/label", schemaPath: "#/$defs/LocalizedTitle/propertyNames/type", keyword: "type", params: { type: "string" }, message: "must be string", propertyName: key1 };
|
|
9408
|
+
if (vErrors === null) {
|
|
9409
|
+
vErrors = [err8];
|
|
9410
|
+
} else {
|
|
9411
|
+
vErrors.push(err8);
|
|
9412
|
+
}
|
|
9413
|
+
errors++;
|
|
9414
|
+
}
|
|
9415
|
+
var valid2 = _errs7 === errors;
|
|
9416
|
+
if (!valid2) {
|
|
9417
|
+
const err9 = { instancePath: instancePath + "/label", schemaPath: "#/$defs/LocalizedTitle/propertyNames", keyword: "propertyNames", params: { propertyName: key1 }, message: "property name must be valid" };
|
|
9418
|
+
if (vErrors === null) {
|
|
9419
|
+
vErrors = [err9];
|
|
9420
|
+
} else {
|
|
9421
|
+
vErrors.push(err9);
|
|
9422
|
+
}
|
|
9423
|
+
errors++;
|
|
9424
|
+
}
|
|
9425
|
+
}
|
|
9426
|
+
for (const key2 in data1) {
|
|
9427
|
+
let data2 = data1[key2];
|
|
9428
|
+
if (typeof data2 === "string") {
|
|
9429
|
+
if (func2(data2) > 200) {
|
|
9430
|
+
const err10 = { instancePath: instancePath + "/label/" + key2.replace(/~/g, "~0").replace(/\//g, "~1"), schemaPath: "#/$defs/LocalizedTitle/additionalProperties/maxLength", keyword: "maxLength", params: { limit: 200 }, message: "must NOT have more than 200 characters" };
|
|
9431
|
+
if (vErrors === null) {
|
|
9432
|
+
vErrors = [err10];
|
|
9433
|
+
} else {
|
|
9434
|
+
vErrors.push(err10);
|
|
9435
|
+
}
|
|
9436
|
+
errors++;
|
|
9437
|
+
}
|
|
9438
|
+
if (func2(data2) < 1) {
|
|
9439
|
+
const err11 = { instancePath: instancePath + "/label/" + key2.replace(/~/g, "~0").replace(/\//g, "~1"), schemaPath: "#/$defs/LocalizedTitle/additionalProperties/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
|
|
9440
|
+
if (vErrors === null) {
|
|
9441
|
+
vErrors = [err11];
|
|
9442
|
+
} else {
|
|
9443
|
+
vErrors.push(err11);
|
|
9444
|
+
}
|
|
9445
|
+
errors++;
|
|
9446
|
+
}
|
|
9447
|
+
if (!pattern6.test(data2)) {
|
|
9448
|
+
const err12 = { instancePath: instancePath + "/label/" + key2.replace(/~/g, "~0").replace(/\//g, "~1"), schemaPath: "#/$defs/LocalizedTitle/additionalProperties/pattern", keyword: "pattern", params: { pattern: "\\S" }, message: 'must match pattern "\\S"' };
|
|
9449
|
+
if (vErrors === null) {
|
|
9450
|
+
vErrors = [err12];
|
|
9451
|
+
} else {
|
|
9452
|
+
vErrors.push(err12);
|
|
9453
|
+
}
|
|
9454
|
+
errors++;
|
|
9455
|
+
}
|
|
9456
|
+
} else {
|
|
9457
|
+
const err13 = { instancePath: instancePath + "/label/" + key2.replace(/~/g, "~0").replace(/\//g, "~1"), schemaPath: "#/$defs/LocalizedTitle/additionalProperties/type", keyword: "type", params: { type: "string" }, message: "must be string" };
|
|
9458
|
+
if (vErrors === null) {
|
|
9459
|
+
vErrors = [err13];
|
|
9460
|
+
} else {
|
|
9461
|
+
vErrors.push(err13);
|
|
9462
|
+
}
|
|
9463
|
+
errors++;
|
|
9464
|
+
}
|
|
9465
|
+
}
|
|
9466
|
+
} else {
|
|
9467
|
+
const err14 = { instancePath: instancePath + "/label", schemaPath: "#/$defs/LocalizedTitle/type", keyword: "type", params: { type: "object" }, message: "must be object" };
|
|
9468
|
+
if (vErrors === null) {
|
|
9469
|
+
vErrors = [err14];
|
|
9470
|
+
} else {
|
|
9471
|
+
vErrors.push(err14);
|
|
9472
|
+
}
|
|
9473
|
+
errors++;
|
|
9474
|
+
}
|
|
9475
|
+
}
|
|
9476
|
+
} else {
|
|
9477
|
+
const err15 = { instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" };
|
|
9478
|
+
if (vErrors === null) {
|
|
9479
|
+
vErrors = [err15];
|
|
9480
|
+
} else {
|
|
9481
|
+
vErrors.push(err15);
|
|
9482
|
+
}
|
|
9483
|
+
errors++;
|
|
9484
|
+
}
|
|
9485
|
+
validate68.errors = vErrors;
|
|
9486
|
+
return errors === 0;
|
|
9487
|
+
}
|
|
9488
|
+
validate68.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
8867
9489
|
function validate62(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
8868
9490
|
let vErrors = null;
|
|
8869
9491
|
let errors = 0;
|
|
@@ -9588,12 +10210,175 @@ var require_takuhon_validator = __commonJS({
|
|
|
9588
10210
|
errors++;
|
|
9589
10211
|
}
|
|
9590
10212
|
}
|
|
10213
|
+
if (data.contact !== void 0) {
|
|
10214
|
+
let data37 = data.contact;
|
|
10215
|
+
if (data37 && typeof data37 == "object" && !Array.isArray(data37)) {
|
|
10216
|
+
for (const key5 in data37) {
|
|
10217
|
+
if (!(key5 === "enabled" || key5 === "turnstileSiteKey" || key5 === "endpoint" || key5 === "subjectPrefix")) {
|
|
10218
|
+
const err66 = { instancePath: instancePath + "/contact", schemaPath: "#/$defs/ContactSettings/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key5 }, message: "must NOT have additional properties" };
|
|
10219
|
+
if (vErrors === null) {
|
|
10220
|
+
vErrors = [err66];
|
|
10221
|
+
} else {
|
|
10222
|
+
vErrors.push(err66);
|
|
10223
|
+
}
|
|
10224
|
+
errors++;
|
|
10225
|
+
}
|
|
10226
|
+
}
|
|
10227
|
+
if (data37.enabled !== void 0) {
|
|
10228
|
+
if (typeof data37.enabled !== "boolean") {
|
|
10229
|
+
const err67 = { instancePath: instancePath + "/contact/enabled", schemaPath: "#/$defs/ContactSettings/properties/enabled/type", keyword: "type", params: { type: "boolean" }, message: "must be boolean" };
|
|
10230
|
+
if (vErrors === null) {
|
|
10231
|
+
vErrors = [err67];
|
|
10232
|
+
} else {
|
|
10233
|
+
vErrors.push(err67);
|
|
10234
|
+
}
|
|
10235
|
+
errors++;
|
|
10236
|
+
}
|
|
10237
|
+
}
|
|
10238
|
+
if (data37.turnstileSiteKey !== void 0) {
|
|
10239
|
+
let data39 = data37.turnstileSiteKey;
|
|
10240
|
+
if (typeof data39 === "string") {
|
|
10241
|
+
if (func2(data39) > 128) {
|
|
10242
|
+
const err68 = { instancePath: instancePath + "/contact/turnstileSiteKey", schemaPath: "#/$defs/ContactSettings/properties/turnstileSiteKey/maxLength", keyword: "maxLength", params: { limit: 128 }, message: "must NOT have more than 128 characters" };
|
|
10243
|
+
if (vErrors === null) {
|
|
10244
|
+
vErrors = [err68];
|
|
10245
|
+
} else {
|
|
10246
|
+
vErrors.push(err68);
|
|
10247
|
+
}
|
|
10248
|
+
errors++;
|
|
10249
|
+
}
|
|
10250
|
+
if (func2(data39) < 1) {
|
|
10251
|
+
const err69 = { instancePath: instancePath + "/contact/turnstileSiteKey", schemaPath: "#/$defs/ContactSettings/properties/turnstileSiteKey/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
|
|
10252
|
+
if (vErrors === null) {
|
|
10253
|
+
vErrors = [err69];
|
|
10254
|
+
} else {
|
|
10255
|
+
vErrors.push(err69);
|
|
10256
|
+
}
|
|
10257
|
+
errors++;
|
|
10258
|
+
}
|
|
10259
|
+
} else {
|
|
10260
|
+
const err70 = { instancePath: instancePath + "/contact/turnstileSiteKey", schemaPath: "#/$defs/ContactSettings/properties/turnstileSiteKey/type", keyword: "type", params: { type: "string" }, message: "must be string" };
|
|
10261
|
+
if (vErrors === null) {
|
|
10262
|
+
vErrors = [err70];
|
|
10263
|
+
} else {
|
|
10264
|
+
vErrors.push(err70);
|
|
10265
|
+
}
|
|
10266
|
+
errors++;
|
|
10267
|
+
}
|
|
10268
|
+
}
|
|
10269
|
+
if (data37.endpoint !== void 0) {
|
|
10270
|
+
let data40 = data37.endpoint;
|
|
10271
|
+
if (typeof data40 === "string") {
|
|
10272
|
+
if (func2(data40) > 2048) {
|
|
10273
|
+
const err71 = { instancePath: instancePath + "/contact/endpoint", schemaPath: "#/$defs/ContactSettings/properties/endpoint/maxLength", keyword: "maxLength", params: { limit: 2048 }, message: "must NOT have more than 2048 characters" };
|
|
10274
|
+
if (vErrors === null) {
|
|
10275
|
+
vErrors = [err71];
|
|
10276
|
+
} else {
|
|
10277
|
+
vErrors.push(err71);
|
|
10278
|
+
}
|
|
10279
|
+
errors++;
|
|
10280
|
+
}
|
|
10281
|
+
if (func2(data40) < 1) {
|
|
10282
|
+
const err72 = { instancePath: instancePath + "/contact/endpoint", schemaPath: "#/$defs/ContactSettings/properties/endpoint/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
|
|
10283
|
+
if (vErrors === null) {
|
|
10284
|
+
vErrors = [err72];
|
|
10285
|
+
} else {
|
|
10286
|
+
vErrors.push(err72);
|
|
10287
|
+
}
|
|
10288
|
+
errors++;
|
|
10289
|
+
}
|
|
10290
|
+
} else {
|
|
10291
|
+
const err73 = { instancePath: instancePath + "/contact/endpoint", schemaPath: "#/$defs/ContactSettings/properties/endpoint/type", keyword: "type", params: { type: "string" }, message: "must be string" };
|
|
10292
|
+
if (vErrors === null) {
|
|
10293
|
+
vErrors = [err73];
|
|
10294
|
+
} else {
|
|
10295
|
+
vErrors.push(err73);
|
|
10296
|
+
}
|
|
10297
|
+
errors++;
|
|
10298
|
+
}
|
|
10299
|
+
}
|
|
10300
|
+
if (data37.subjectPrefix !== void 0) {
|
|
10301
|
+
let data41 = data37.subjectPrefix;
|
|
10302
|
+
if (typeof data41 === "string") {
|
|
10303
|
+
if (func2(data41) > 128) {
|
|
10304
|
+
const err74 = { instancePath: instancePath + "/contact/subjectPrefix", schemaPath: "#/$defs/ContactSettings/properties/subjectPrefix/maxLength", keyword: "maxLength", params: { limit: 128 }, message: "must NOT have more than 128 characters" };
|
|
10305
|
+
if (vErrors === null) {
|
|
10306
|
+
vErrors = [err74];
|
|
10307
|
+
} else {
|
|
10308
|
+
vErrors.push(err74);
|
|
10309
|
+
}
|
|
10310
|
+
errors++;
|
|
10311
|
+
}
|
|
10312
|
+
if (func2(data41) < 1) {
|
|
10313
|
+
const err75 = { instancePath: instancePath + "/contact/subjectPrefix", schemaPath: "#/$defs/ContactSettings/properties/subjectPrefix/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
|
|
10314
|
+
if (vErrors === null) {
|
|
10315
|
+
vErrors = [err75];
|
|
10316
|
+
} else {
|
|
10317
|
+
vErrors.push(err75);
|
|
10318
|
+
}
|
|
10319
|
+
errors++;
|
|
10320
|
+
}
|
|
10321
|
+
} else {
|
|
10322
|
+
const err76 = { instancePath: instancePath + "/contact/subjectPrefix", schemaPath: "#/$defs/ContactSettings/properties/subjectPrefix/type", keyword: "type", params: { type: "string" }, message: "must be string" };
|
|
10323
|
+
if (vErrors === null) {
|
|
10324
|
+
vErrors = [err76];
|
|
10325
|
+
} else {
|
|
10326
|
+
vErrors.push(err76);
|
|
10327
|
+
}
|
|
10328
|
+
errors++;
|
|
10329
|
+
}
|
|
10330
|
+
}
|
|
10331
|
+
} else {
|
|
10332
|
+
const err77 = { instancePath: instancePath + "/contact", schemaPath: "#/$defs/ContactSettings/type", keyword: "type", params: { type: "object" }, message: "must be object" };
|
|
10333
|
+
if (vErrors === null) {
|
|
10334
|
+
vErrors = [err77];
|
|
10335
|
+
} else {
|
|
10336
|
+
vErrors.push(err77);
|
|
10337
|
+
}
|
|
10338
|
+
errors++;
|
|
10339
|
+
}
|
|
10340
|
+
}
|
|
10341
|
+
if (data.appearance !== void 0) {
|
|
10342
|
+
if (!validate63(data.appearance, { instancePath: instancePath + "/appearance", parentData: data, parentDataProperty: "appearance", rootData, dynamicAnchors })) {
|
|
10343
|
+
vErrors = vErrors === null ? validate63.errors : vErrors.concat(validate63.errors);
|
|
10344
|
+
errors = vErrors.length;
|
|
10345
|
+
}
|
|
10346
|
+
}
|
|
10347
|
+
if (data.skillCategories !== void 0) {
|
|
10348
|
+
let data43 = data.skillCategories;
|
|
10349
|
+
if (Array.isArray(data43)) {
|
|
10350
|
+
if (data43.length > 50) {
|
|
10351
|
+
const err78 = { instancePath: instancePath + "/skillCategories", schemaPath: "#/properties/skillCategories/maxItems", keyword: "maxItems", params: { limit: 50 }, message: "must NOT have more than 50 items" };
|
|
10352
|
+
if (vErrors === null) {
|
|
10353
|
+
vErrors = [err78];
|
|
10354
|
+
} else {
|
|
10355
|
+
vErrors.push(err78);
|
|
10356
|
+
}
|
|
10357
|
+
errors++;
|
|
10358
|
+
}
|
|
10359
|
+
const len1 = data43.length;
|
|
10360
|
+
for (let i2 = 0; i2 < len1; i2++) {
|
|
10361
|
+
if (!validate68(data43[i2], { instancePath: instancePath + "/skillCategories/" + i2, parentData: data43, parentDataProperty: i2, rootData, dynamicAnchors })) {
|
|
10362
|
+
vErrors = vErrors === null ? validate68.errors : vErrors.concat(validate68.errors);
|
|
10363
|
+
errors = vErrors.length;
|
|
10364
|
+
}
|
|
10365
|
+
}
|
|
10366
|
+
} else {
|
|
10367
|
+
const err79 = { instancePath: instancePath + "/skillCategories", schemaPath: "#/properties/skillCategories/type", keyword: "type", params: { type: "array" }, message: "must be array" };
|
|
10368
|
+
if (vErrors === null) {
|
|
10369
|
+
vErrors = [err79];
|
|
10370
|
+
} else {
|
|
10371
|
+
vErrors.push(err79);
|
|
10372
|
+
}
|
|
10373
|
+
errors++;
|
|
10374
|
+
}
|
|
10375
|
+
}
|
|
9591
10376
|
} else {
|
|
9592
|
-
const
|
|
10377
|
+
const err80 = { instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" };
|
|
9593
10378
|
if (vErrors === null) {
|
|
9594
|
-
vErrors = [
|
|
10379
|
+
vErrors = [err80];
|
|
9595
10380
|
} else {
|
|
9596
|
-
vErrors.push(
|
|
10381
|
+
vErrors.push(err80);
|
|
9597
10382
|
}
|
|
9598
10383
|
errors++;
|
|
9599
10384
|
}
|
|
@@ -9602,10 +10387,10 @@ var require_takuhon_validator = __commonJS({
|
|
|
9602
10387
|
}
|
|
9603
10388
|
validate62.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
9604
10389
|
var formats36 = require_formats().fullFormats["date-time"];
|
|
9605
|
-
function
|
|
10390
|
+
function validate72(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
9606
10391
|
let vErrors = null;
|
|
9607
10392
|
let errors = 0;
|
|
9608
|
-
const evaluated0 =
|
|
10393
|
+
const evaluated0 = validate72.evaluated;
|
|
9609
10394
|
if (evaluated0.dynamicProps) {
|
|
9610
10395
|
evaluated0.props = void 0;
|
|
9611
10396
|
}
|
|
@@ -9821,14 +10606,14 @@ var require_takuhon_validator = __commonJS({
|
|
|
9821
10606
|
}
|
|
9822
10607
|
errors++;
|
|
9823
10608
|
}
|
|
9824
|
-
|
|
10609
|
+
validate72.errors = vErrors;
|
|
9825
10610
|
return errors === 0;
|
|
9826
10611
|
}
|
|
9827
|
-
|
|
9828
|
-
function
|
|
10612
|
+
validate72.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
10613
|
+
function validate71(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
9829
10614
|
let vErrors = null;
|
|
9830
10615
|
let errors = 0;
|
|
9831
|
-
const evaluated0 =
|
|
10616
|
+
const evaluated0 = validate71.evaluated;
|
|
9832
10617
|
if (evaluated0.dynamicProps) {
|
|
9833
10618
|
evaluated0.props = void 0;
|
|
9834
10619
|
}
|
|
@@ -9932,8 +10717,8 @@ var require_takuhon_validator = __commonJS({
|
|
|
9932
10717
|
}
|
|
9933
10718
|
}
|
|
9934
10719
|
if (data.contentLicense !== void 0) {
|
|
9935
|
-
if (!
|
|
9936
|
-
vErrors = vErrors === null ?
|
|
10720
|
+
if (!validate72(data.contentLicense, { instancePath: instancePath + "/contentLicense", parentData: data, parentDataProperty: "contentLicense", rootData, dynamicAnchors })) {
|
|
10721
|
+
vErrors = vErrors === null ? validate72.errors : vErrors.concat(validate72.errors);
|
|
9937
10722
|
errors = vErrors.length;
|
|
9938
10723
|
}
|
|
9939
10724
|
}
|
|
@@ -9992,10 +10777,10 @@ var require_takuhon_validator = __commonJS({
|
|
|
9992
10777
|
}
|
|
9993
10778
|
errors++;
|
|
9994
10779
|
}
|
|
9995
|
-
|
|
10780
|
+
validate71.errors = vErrors;
|
|
9996
10781
|
return errors === 0;
|
|
9997
10782
|
}
|
|
9998
|
-
|
|
10783
|
+
validate71.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
9999
10784
|
function validate20(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
|
|
10000
10785
|
;
|
|
10001
10786
|
let vErrors = null;
|
|
@@ -10540,8 +11325,8 @@ var require_takuhon_validator = __commonJS({
|
|
|
10540
11325
|
}
|
|
10541
11326
|
}
|
|
10542
11327
|
if (data.meta !== void 0) {
|
|
10543
|
-
if (!
|
|
10544
|
-
vErrors = vErrors === null ?
|
|
11328
|
+
if (!validate71(data.meta, { instancePath: instancePath + "/meta", parentData: data, parentDataProperty: "meta", rootData, dynamicAnchors })) {
|
|
11329
|
+
vErrors = vErrors === null ? validate71.errors : vErrors.concat(validate71.errors);
|
|
10545
11330
|
errors = vErrors.length;
|
|
10546
11331
|
}
|
|
10547
11332
|
}
|
|
@@ -10564,7 +11349,7 @@ var require_takuhon_validator = __commonJS({
|
|
|
10564
11349
|
// takuhon.schema.json
|
|
10565
11350
|
var takuhon_schema_default = {
|
|
10566
11351
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
10567
|
-
$id: "https://takuhon.example/schemas/1.
|
|
11352
|
+
$id: "https://takuhon.example/schemas/1.3.0/takuhon.schema.json",
|
|
10568
11353
|
title: "Takuhon Profile",
|
|
10569
11354
|
description: "Portable profile data format consumed by @takuhon/core. The canonical contract for profile content authored as takuhon.json.",
|
|
10570
11355
|
type: "object",
|
|
@@ -10876,6 +11661,23 @@ var takuhon_schema_default = {
|
|
|
10876
11661
|
order: { type: "integer", minimum: 0 }
|
|
10877
11662
|
}
|
|
10878
11663
|
},
|
|
11664
|
+
SkillCategory: {
|
|
11665
|
+
type: "object",
|
|
11666
|
+
additionalProperties: false,
|
|
11667
|
+
required: ["id", "label"],
|
|
11668
|
+
properties: {
|
|
11669
|
+
id: {
|
|
11670
|
+
type: "string",
|
|
11671
|
+
minLength: 1,
|
|
11672
|
+
maxLength: 64,
|
|
11673
|
+
description: "Matches the `category` value on the skills that belong to this group."
|
|
11674
|
+
},
|
|
11675
|
+
label: {
|
|
11676
|
+
$ref: "#/$defs/LocalizedTitle",
|
|
11677
|
+
description: "Localized display heading for the group."
|
|
11678
|
+
}
|
|
11679
|
+
}
|
|
11680
|
+
},
|
|
10879
11681
|
Contact: {
|
|
10880
11682
|
type: "object",
|
|
10881
11683
|
additionalProperties: false,
|
|
@@ -10926,7 +11728,104 @@ var takuhon_schema_default = {
|
|
|
10926
11728
|
description: "Opt-in flag for first-party analytics. Default is false to keep takuhon privacy-respecting by default."
|
|
10927
11729
|
},
|
|
10928
11730
|
activity: { $ref: "#/$defs/ActivitySettings" },
|
|
10929
|
-
publicVisibility: { $ref: "#/$defs/PublicVisibility" }
|
|
11731
|
+
publicVisibility: { $ref: "#/$defs/PublicVisibility" },
|
|
11732
|
+
contact: { $ref: "#/$defs/ContactSettings" },
|
|
11733
|
+
appearance: { $ref: "#/$defs/AppearanceSettings" },
|
|
11734
|
+
skillCategories: {
|
|
11735
|
+
type: "array",
|
|
11736
|
+
maxItems: 50,
|
|
11737
|
+
items: { $ref: "#/$defs/SkillCategory" },
|
|
11738
|
+
description: "Ordered skill-category display groups (added in 1.3.0). When present, the rendered profile groups skills by their `category` under these localized headings, in array order; absent = the flat skill list. A skill whose `category` is not listed here (or which has none) renders in a trailing group so nothing is dropped."
|
|
11739
|
+
}
|
|
11740
|
+
}
|
|
11741
|
+
},
|
|
11742
|
+
AppearanceSettings: {
|
|
11743
|
+
type: "object",
|
|
11744
|
+
additionalProperties: false,
|
|
11745
|
+
description: "Opt-in design tokens for the rendered profile (added in 1.2.0). A declarative re-skin seam: owners override the standard renderer's built-in color and font defaults. This is a token map only, not arbitrary CSS \u2014 every value is length- and pattern-constrained so it cannot break out of the inline <style>. Overriding tokens re-skins the page but cannot re-layout it (spacing/radius/type-scale are intentionally not exposed). Absent = the built-in defaults are used unchanged.",
|
|
11746
|
+
properties: {
|
|
11747
|
+
fontFamily: {
|
|
11748
|
+
type: "string",
|
|
11749
|
+
minLength: 1,
|
|
11750
|
+
maxLength: 256,
|
|
11751
|
+
pattern: `^[A-Za-z0-9\\s,'"._-]+$`,
|
|
11752
|
+
description: 'CSS font-family stack for the page body, e.g. "Inter, system-ui, sans-serif". Quotes and commas are allowed; CSS-structural characters (; { } < >) are not.'
|
|
11753
|
+
},
|
|
11754
|
+
colors: {
|
|
11755
|
+
$ref: "#/$defs/AppearanceColors",
|
|
11756
|
+
description: "Light-mode (:root) color overrides."
|
|
11757
|
+
},
|
|
11758
|
+
colorsDark: {
|
|
11759
|
+
$ref: "#/$defs/AppearanceColors",
|
|
11760
|
+
description: "Dark-mode (prefers-color-scheme: dark) color overrides. Note: until the standard renderer ships a default dark palette, only the keys set here change in dark mode."
|
|
11761
|
+
}
|
|
11762
|
+
}
|
|
11763
|
+
},
|
|
11764
|
+
AppearanceColors: {
|
|
11765
|
+
type: "object",
|
|
11766
|
+
additionalProperties: false,
|
|
11767
|
+
description: `A set of overridable color tokens. Each value is a CSS color (hex, rgb()/rgba(), hsl()/hsla(), or a named color); CSS-structural characters (; { } < > " ' \\) are disallowed so a value cannot escape the inline <style>.`,
|
|
11768
|
+
properties: {
|
|
11769
|
+
bg: { $ref: "#/$defs/CssColor", description: "Page background." },
|
|
11770
|
+
surface: {
|
|
11771
|
+
$ref: "#/$defs/CssColor",
|
|
11772
|
+
description: "Raised surfaces such as skill/tag chips."
|
|
11773
|
+
},
|
|
11774
|
+
text: { $ref: "#/$defs/CssColor", description: "Primary body text." },
|
|
11775
|
+
textMuted: {
|
|
11776
|
+
$ref: "#/$defs/CssColor",
|
|
11777
|
+
description: "Secondary/muted text (taglines, meta, captions)."
|
|
11778
|
+
},
|
|
11779
|
+
border: { $ref: "#/$defs/CssColor", description: "Hairline borders and rules." },
|
|
11780
|
+
accent: {
|
|
11781
|
+
$ref: "#/$defs/CssColor",
|
|
11782
|
+
description: "Accent color for emphasis and focus affordances."
|
|
11783
|
+
},
|
|
11784
|
+
primary: {
|
|
11785
|
+
$ref: "#/$defs/CssColor",
|
|
11786
|
+
description: "Primary interactive color, e.g. links."
|
|
11787
|
+
},
|
|
11788
|
+
primaryContrast: {
|
|
11789
|
+
$ref: "#/$defs/CssColor",
|
|
11790
|
+
description: "Foreground color used on top of the primary color."
|
|
11791
|
+
}
|
|
11792
|
+
}
|
|
11793
|
+
},
|
|
11794
|
+
CssColor: {
|
|
11795
|
+
type: "string",
|
|
11796
|
+
minLength: 1,
|
|
11797
|
+
maxLength: 64,
|
|
11798
|
+
pattern: "^(?:#[0-9A-Fa-f]{3,8}|[A-Za-z]+|(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\\([A-Za-z0-9.,%/\\s-]*\\))$",
|
|
11799
|
+
description: "A CSS color value, restricted to a safe allowlist: a hex color (#rgb/#rgba/#rrggbb/#rrggbbaa), a bare keyword (named colors, currentColor, transparent), or a color function (rgb/rgba/hsl/hsla/hwb/lab/lch/oklab/oklch/color). url(), image-set(), var(), and other fetch- or reference-bearing functions are intentionally excluded so a value can never trigger an external request or escape the inline <style>."
|
|
11800
|
+
},
|
|
11801
|
+
ContactSettings: {
|
|
11802
|
+
type: "object",
|
|
11803
|
+
additionalProperties: false,
|
|
11804
|
+
description: "Opt-in contact form configuration (added in 1.1.0). Only public values live here; the Turnstile site key is safe to embed in the page. The Turnstile secret, the recipient address, and the From label are provisioned out of band as environment configuration and are never stored in takuhon.json. Adapters that support the form mount the widget and a POST endpoint when 'enabled' is true.",
|
|
11805
|
+
properties: {
|
|
11806
|
+
enabled: {
|
|
11807
|
+
type: "boolean",
|
|
11808
|
+
default: false,
|
|
11809
|
+
description: "Master switch. When false (the default), no contact form is mounted even if a site key is present."
|
|
11810
|
+
},
|
|
11811
|
+
turnstileSiteKey: {
|
|
11812
|
+
type: "string",
|
|
11813
|
+
minLength: 1,
|
|
11814
|
+
maxLength: 128,
|
|
11815
|
+
description: "Public Cloudflare Turnstile site key, safe to embed in the page. Without it the widget is not mounted."
|
|
11816
|
+
},
|
|
11817
|
+
endpoint: {
|
|
11818
|
+
type: "string",
|
|
11819
|
+
minLength: 1,
|
|
11820
|
+
maxLength: 2048,
|
|
11821
|
+
description: "Override the POST endpoint the widget submits to. Defaults to /api/contact on the same origin."
|
|
11822
|
+
},
|
|
11823
|
+
subjectPrefix: {
|
|
11824
|
+
type: "string",
|
|
11825
|
+
minLength: 1,
|
|
11826
|
+
maxLength: 128,
|
|
11827
|
+
description: "Subject prefix for the delivered email, e.g. '[example.com contact]'."
|
|
11828
|
+
}
|
|
10930
11829
|
}
|
|
10931
11830
|
},
|
|
10932
11831
|
PublicVisibility: {
|
|
@@ -11400,7 +12299,10 @@ var SUPPORTED_SCHEMA_VERSIONS = [
|
|
|
11400
12299
|
"0.5.0",
|
|
11401
12300
|
"0.6.0",
|
|
11402
12301
|
"0.7.0",
|
|
11403
|
-
"1.0.0"
|
|
12302
|
+
"1.0.0",
|
|
12303
|
+
"1.1.0",
|
|
12304
|
+
"1.2.0",
|
|
12305
|
+
"1.3.0"
|
|
11404
12306
|
];
|
|
11405
12307
|
function validate(data) {
|
|
11406
12308
|
if (typeof data !== "object" || data === null || Array.isArray(data)) {
|
|
@@ -11759,7 +12661,7 @@ function resolveLocale(data, locale, fallbackLocale) {
|
|
|
11759
12661
|
testScores: data.testScores.map((t) => resolveTestScore(t, candidates)),
|
|
11760
12662
|
recommendations: data.recommendations.map((r) => resolveRecommendation(r, candidates)),
|
|
11761
12663
|
contact: data.contact,
|
|
11762
|
-
settings: data.settings,
|
|
12664
|
+
settings: resolveSettings(data.settings, candidates),
|
|
11763
12665
|
meta: data.meta,
|
|
11764
12666
|
resolvedLocale: displayPick?.tag ?? candidates[0] ?? ""
|
|
11765
12667
|
};
|
|
@@ -11802,6 +12704,17 @@ function pickLocalizedWithTag(field, candidates) {
|
|
|
11802
12704
|
function pickLocalized(field, candidates) {
|
|
11803
12705
|
return pickLocalizedWithTag(field, candidates)?.value;
|
|
11804
12706
|
}
|
|
12707
|
+
function resolveSettings(settings, candidates) {
|
|
12708
|
+
const { skillCategories, ...rest } = settings;
|
|
12709
|
+
if (!skillCategories) return rest;
|
|
12710
|
+
return {
|
|
12711
|
+
...rest,
|
|
12712
|
+
skillCategories: skillCategories.map((c) => ({
|
|
12713
|
+
id: c.id,
|
|
12714
|
+
label: pickLocalized(c.label, candidates) ?? c.id
|
|
12715
|
+
}))
|
|
12716
|
+
};
|
|
12717
|
+
}
|
|
11805
12718
|
function resolveProfile(profile, candidates, displayName) {
|
|
11806
12719
|
const out = { displayName };
|
|
11807
12720
|
const tagline = pickLocalized(profile.tagline, candidates);
|
|
@@ -12634,6 +13547,42 @@ var v0_7_0_to_v1_0_0 = {
|
|
|
12634
13547
|
}
|
|
12635
13548
|
};
|
|
12636
13549
|
|
|
13550
|
+
// src/migrations/v1.0.0-to-v1.1.0.ts
|
|
13551
|
+
var v1_0_0_to_v1_1_0 = {
|
|
13552
|
+
from: "1.0.0",
|
|
13553
|
+
to: "1.1.0",
|
|
13554
|
+
migrate(data) {
|
|
13555
|
+
return {
|
|
13556
|
+
...data,
|
|
13557
|
+
schemaVersion: "1.1.0"
|
|
13558
|
+
};
|
|
13559
|
+
}
|
|
13560
|
+
};
|
|
13561
|
+
|
|
13562
|
+
// src/migrations/v1.1.0-to-v1.2.0.ts
|
|
13563
|
+
var v1_1_0_to_v1_2_0 = {
|
|
13564
|
+
from: "1.1.0",
|
|
13565
|
+
to: "1.2.0",
|
|
13566
|
+
migrate(data) {
|
|
13567
|
+
return {
|
|
13568
|
+
...data,
|
|
13569
|
+
schemaVersion: "1.2.0"
|
|
13570
|
+
};
|
|
13571
|
+
}
|
|
13572
|
+
};
|
|
13573
|
+
|
|
13574
|
+
// src/migrations/v1.2.0-to-v1.3.0.ts
|
|
13575
|
+
var v1_2_0_to_v1_3_0 = {
|
|
13576
|
+
from: "1.2.0",
|
|
13577
|
+
to: "1.3.0",
|
|
13578
|
+
migrate(data) {
|
|
13579
|
+
return {
|
|
13580
|
+
...data,
|
|
13581
|
+
schemaVersion: "1.3.0"
|
|
13582
|
+
};
|
|
13583
|
+
}
|
|
13584
|
+
};
|
|
13585
|
+
|
|
12637
13586
|
// src/migrations/index.ts
|
|
12638
13587
|
var migrations = [
|
|
12639
13588
|
v0_1_0_to_v0_2_0,
|
|
@@ -12642,7 +13591,10 @@ var migrations = [
|
|
|
12642
13591
|
v0_4_0_to_v0_5_0,
|
|
12643
13592
|
v0_5_0_to_v0_6_0,
|
|
12644
13593
|
v0_6_0_to_v0_7_0,
|
|
12645
|
-
v0_7_0_to_v1_0_0
|
|
13594
|
+
v0_7_0_to_v1_0_0,
|
|
13595
|
+
v1_0_0_to_v1_1_0,
|
|
13596
|
+
v1_1_0_to_v1_2_0,
|
|
13597
|
+
v1_2_0_to_v1_3_0
|
|
12646
13598
|
];
|
|
12647
13599
|
|
|
12648
13600
|
// src/migrate.ts
|
|
@@ -13632,7 +14584,7 @@ function stripImageMetadata(bytes, mime) {
|
|
|
13632
14584
|
}
|
|
13633
14585
|
|
|
13634
14586
|
// src/index.ts
|
|
13635
|
-
var SCHEMA_VERSION = "1.
|
|
14587
|
+
var SCHEMA_VERSION = "1.3.0";
|
|
13636
14588
|
export {
|
|
13637
14589
|
ACCEPTED_IMAGE_MIME_TYPES,
|
|
13638
14590
|
ConflictError,
|