@takuhon/core 0.22.0 → 0.23.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 CHANGED
@@ -4208,6 +4208,43 @@ interface GravatarOptions {
4208
4208
  */
4209
4209
  declare function gravatarUrl(email: string, options?: GravatarOptions): string;
4210
4210
 
4211
+ /**
4212
+ * Format an ISO date (`YYYY-MM` or `YYYY-MM-DD`) as human-facing text in the
4213
+ * given locale — e.g. `2024-11` renders as `Nov 2024` (en) / `2024年11月` (ja),
4214
+ * and `2025-12-22` as `Dec 22, 2025` (en) / `2025年12月22日` (ja).
4215
+ *
4216
+ * This is the single date-formatting transform shared by the static HTML and CV
4217
+ * renderers in `@takuhon/api` (via their `dateRange`/`timeTag` helpers). The
4218
+ * machine-readable ISO value is never altered: the caller keeps it verbatim in
4219
+ * the enclosing `<time datetime>` attribute. The machine-readable surfaces
4220
+ * (JSON-LD, `/api/profile`, `takuhon.json`, MCP) must NOT call this — they emit
4221
+ * raw ISO so consuming machines decide their own presentation.
4222
+ *
4223
+ * The date is built with `setUTCFullYear` — not `Date.UTC`, which coerces years
4224
+ * 0-99 into 1900-1999 — and formatted in UTC, so a month-precision value keeps
4225
+ * its century and never slips to the previous month west of UTC (`new
4226
+ * Date('2024-05')` parses as midnight UTC and would render as the prior month).
4227
+ *
4228
+ * Every failure path is fail-safe (this never throws):
4229
+ * - A value that is not a well-formed `YYYY-MM`/`YYYY-MM-DD` (wrong shape, an
4230
+ * out-of-range month/day digit, or a calendar-impossible date such as
4231
+ * `2024-02-30`) is returned unchanged, never a shifted or `Invalid Date`.
4232
+ * - An empty `locale` is replaced with `en` before the call, because
4233
+ * `Intl.DateTimeFormat('')` throws a `RangeError`. A structurally invalid
4234
+ * BCP-47 tag also throws and is caught, again falling back to `en`. A
4235
+ * well-formed but unregistered tag (e.g. `zz`) does not throw — `Intl`
4236
+ * negotiates it (typically to English) without entering the catch.
4237
+ */
4238
+ declare function formatDate(value: string, locale: LocaleTag): string;
4239
+
4240
+ /**
4241
+ * Resolve the "Present" timeline label for the given locale. Tries the exact
4242
+ * tag, then the base language subtag (so a resolved `ja-JP` still finds `ja`,
4243
+ * mirroring core's regional-subtag fallback), then English. Callers pass a
4244
+ * `LocalizedTakuhon.resolvedLocale`.
4245
+ */
4246
+ declare function getPresentLabel(locale: LocaleTag): string;
4247
+
4211
4248
  /**
4212
4249
  * MCP (Model Context Protocol) projection of a profile.
4213
4250
  *
@@ -4417,4 +4454,4 @@ declare function stripImageMetadata(bytes: Uint8Array, mime: AcceptedImageMime):
4417
4454
  */
4418
4455
  declare const SCHEMA_VERSION = "0.7.0";
4419
4456
 
4420
- export { ACCEPTED_IMAGE_MIME_TYPES, type AcceptedImageMime, type ActivitySettings, type ActivitySnapshot, type ActivityStorage, type Address, type AssetOptions, type AssetRecord, type Avatar, type Career, type Certification, type CodingTime, ConflictError, type Contact, type ContentLicense, type ContentLicenseAttribution, type ContributionCalendar, type ContributionDay, type Course, type CvDocument, type CvHeader, type CvSection, type CvSectionKind, DARK_PALETTE, type Education, type ExportOptions, type ExportedTakuhon, type GravatarOptions, type Honor, IMAGE_EXTENSIONS, type ImageInfo, ImportError, type Iso3166Alpha2, type IsoDateTime, LIGHT_PALETTE, type Language, type LanguageBreakdown, type LanguageProficiency, type Link, type LinkBuiltin, type LinkCustom, type LinkType, type LocaleTag, type LocalizedAddress, type LocalizedAvatar, type LocalizedBody, type LocalizedCareer, type LocalizedCertification, type LocalizedCourse, type LocalizedEducation, type LocalizedHonor, type LocalizedLanguage, type LocalizedLink, type LocalizedLinkBuiltin, type LocalizedLinkCustom, type LocalizedMembership, type LocalizedPatent, type LocalizedProfile, type LocalizedProject, type LocalizedPublication, type LocalizedRecommendation, type LocalizedRecommendationAuthor, type LocalizedTakuhon, type LocalizedTestScore, type LocalizedTitle, type LocalizedVolunteering, MAX_IMAGE_BYTES, MAX_IMAGE_DIMENSION, MAX_IMAGE_FRAMES, MCP_PROFILE_SECTIONS, MCP_RESOURCES, MCP_TOOLS, type McpInputSchema, type McpProfileSection, McpRequestError, type McpResourceDefinition, type McpResourceResult, type McpToolDefinition, type McpToolResult, type Membership, type Meta, type MetaPrivacy, type Migration, MigrationError, type NormalizedTakuhon, NotFoundError, type Palette, type Patent, type PatentStatus, type Profile, type Project, type PublicVisibility, type Publication, RANK_FULL_CODING_HOURS, RANK_FULL_CONTRIBUTIONS, RANK_TIER_THRESHOLDS, type RankInput, type RankTier, type RankTierLabel, type Recommendation, type RecommendationAuthor, type RenderActivitySvgOptions, SCHEMA_VERSION, SUPPORTED_SCHEMA_VERSIONS, type Schema, type Settings, type Skill, type Slug, StorageError, type Takuhon, type TakuhonAssetStorage, type TakuhonStorage, type TestScore, type ValidationError, type ValidationResult, type Volunteering, type YearMonth, applyPublicPrivacyFilter, computeLanguagePercentages, deriveCv, deriveRankTier, detectImageMime, executeMcpTool, exportTakuhon, formatCodingTime, generateJsonLd, generatePersonJsonLd, generateProfilePageJsonLd, gravatarUrl, importTakuhon, isActivitySnapshot, migrateTakuhon, migrations, normalize, readImageInfo, readMcpResource, renderActivitySvg, resolveLocale, schema, stripImageMetadata, validate };
4457
+ export { ACCEPTED_IMAGE_MIME_TYPES, type AcceptedImageMime, type ActivitySettings, type ActivitySnapshot, type ActivityStorage, type Address, type AssetOptions, type AssetRecord, type Avatar, type Career, type Certification, type CodingTime, ConflictError, type Contact, type ContentLicense, type ContentLicenseAttribution, type ContributionCalendar, type ContributionDay, type Course, type CvDocument, type CvHeader, type CvSection, type CvSectionKind, DARK_PALETTE, type Education, type ExportOptions, type ExportedTakuhon, type GravatarOptions, type Honor, IMAGE_EXTENSIONS, type ImageInfo, ImportError, type Iso3166Alpha2, type IsoDateTime, LIGHT_PALETTE, type Language, type LanguageBreakdown, type LanguageProficiency, type Link, type LinkBuiltin, type LinkCustom, type LinkType, type LocaleTag, type LocalizedAddress, type LocalizedAvatar, type LocalizedBody, type LocalizedCareer, type LocalizedCertification, type LocalizedCourse, type LocalizedEducation, type LocalizedHonor, type LocalizedLanguage, type LocalizedLink, type LocalizedLinkBuiltin, type LocalizedLinkCustom, type LocalizedMembership, type LocalizedPatent, type LocalizedProfile, type LocalizedProject, type LocalizedPublication, type LocalizedRecommendation, type LocalizedRecommendationAuthor, type LocalizedTakuhon, type LocalizedTestScore, type LocalizedTitle, type LocalizedVolunteering, MAX_IMAGE_BYTES, MAX_IMAGE_DIMENSION, MAX_IMAGE_FRAMES, MCP_PROFILE_SECTIONS, MCP_RESOURCES, MCP_TOOLS, type McpInputSchema, type McpProfileSection, McpRequestError, type McpResourceDefinition, type McpResourceResult, type McpToolDefinition, type McpToolResult, type Membership, type Meta, type MetaPrivacy, type Migration, MigrationError, type NormalizedTakuhon, NotFoundError, type Palette, type Patent, type PatentStatus, type Profile, type Project, type PublicVisibility, type Publication, RANK_FULL_CODING_HOURS, RANK_FULL_CONTRIBUTIONS, RANK_TIER_THRESHOLDS, type RankInput, type RankTier, type RankTierLabel, type Recommendation, type RecommendationAuthor, type RenderActivitySvgOptions, SCHEMA_VERSION, SUPPORTED_SCHEMA_VERSIONS, type Schema, type Settings, type Skill, type Slug, StorageError, type Takuhon, type TakuhonAssetStorage, type TakuhonStorage, type TestScore, type ValidationError, type ValidationResult, type Volunteering, type YearMonth, applyPublicPrivacyFilter, computeLanguagePercentages, deriveCv, deriveRankTier, detectImageMime, executeMcpTool, exportTakuhon, formatCodingTime, formatDate, generateJsonLd, generatePersonJsonLd, generateProfilePageJsonLd, getPresentLabel, gravatarUrl, importTakuhon, isActivitySnapshot, migrateTakuhon, migrations, normalize, readImageInfo, readMcpResource, renderActivitySvg, resolveLocale, schema, stripImageMetadata, validate };
package/dist/index.js CHANGED
@@ -12459,6 +12459,37 @@ function gravatarUrl(email, options) {
12459
12459
  return query ? `${GRAVATAR_AVATAR_BASE}${hash}?${query}` : `${GRAVATAR_AVATAR_BASE}${hash}`;
12460
12460
  }
12461
12461
 
12462
+ // src/date-format.ts
12463
+ var ISO_DATE = /^(\d{4})-(0[1-9]|1[0-2])(?:-(0[1-9]|[12]\d|3[01]))?$/;
12464
+ function formatDate(value, locale) {
12465
+ const match = ISO_DATE.exec(value);
12466
+ if (!match) return value;
12467
+ const year = Number(match[1]);
12468
+ const month = Number(match[2]);
12469
+ const day = match[3] !== void 0 ? Number(match[3]) : void 0;
12470
+ const date = /* @__PURE__ */ new Date(0);
12471
+ date.setUTCFullYear(year, month - 1, day ?? 1);
12472
+ if (date.getUTCFullYear() !== year || date.getUTCMonth() !== month - 1 || date.getUTCDate() !== (day ?? 1)) {
12473
+ return value;
12474
+ }
12475
+ const options = day !== void 0 ? { year: "numeric", month: "short", day: "numeric", timeZone: "UTC" } : { year: "numeric", month: "short", timeZone: "UTC" };
12476
+ try {
12477
+ return new Intl.DateTimeFormat(locale || "en", options).format(date);
12478
+ } catch {
12479
+ return new Intl.DateTimeFormat("en", options).format(date);
12480
+ }
12481
+ }
12482
+
12483
+ // src/ui-labels.ts
12484
+ var PRESENT_LABELS = {
12485
+ en: "Present",
12486
+ ja: "\u73FE\u5728"
12487
+ };
12488
+ function getPresentLabel(locale) {
12489
+ const base = locale.split("-")[0] ?? locale;
12490
+ return PRESENT_LABELS[locale] ?? PRESENT_LABELS[base] ?? "Present";
12491
+ }
12492
+
12462
12493
  // src/mcp.ts
12463
12494
  var MCP_PROFILE_SECTIONS = [
12464
12495
  "profile",
@@ -12976,9 +13007,11 @@ export {
12976
13007
  executeMcpTool,
12977
13008
  exportTakuhon,
12978
13009
  formatCodingTime,
13010
+ formatDate,
12979
13011
  generateJsonLd,
12980
13012
  generatePersonJsonLd,
12981
13013
  generateProfilePageJsonLd,
13014
+ getPresentLabel,
12982
13015
  gravatarUrl,
12983
13016
  importTakuhon,
12984
13017
  isActivitySnapshot,