Skip to content

feat: Add temporal support#230

Draft
DecimalTurn wants to merge 23 commits into
latestfrom
dev-temporal
Draft

feat: Add temporal support#230
DecimalTurn wants to merge 23 commits into
latestfrom
dev-temporal

Conversation

@DecimalTurn

Copy link
Copy Markdown
Owner

This pull request introduces support for the (new) JavaScript Temporal API.

The implementation is opt-in via a new temporal option.

Temporal API Integration:

  • Added a new temporal: boolean option to ParseOptions, allowing TOML date/time values to be parsed as Temporal objects when enabled.
  • Implemented duck-typed detection of Temporal objects in utility functions, ensuring robust handling across different JS realms.
  • Updated parsing and serialization logic to convert between TOML date/time types and their corresponding Temporal types, both when reading TOML and when stringifying JS objects.

@DecimalTurn DecimalTurn changed the title feat: Add temporal support and related tests feat: Add temporal support Jun 20, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds opt-in support for parsing TOML date/time values into JavaScript Temporal objects, and extends stringify/patch logic to accept Temporal inputs while keeping existing Date-subclass behavior as the default for backward compatibility.

Changes:

  • Introduces ParseOptions.temporal and threads it through parse() / TomlDocument / toJS() so TOML date/time nodes can return Temporal objects.
  • Adds Temporal duck-typing utilities plus Temporal-aware diffing/patching/stringification paths.
  • Adds Temporal-focused documentation and a new Jest test suite (with polyfill).

Reviewed changes

Copilot reviewed 15 out of 17 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/utils.ts Adds Temporal detection + Temporal-aware equality/stable stringification helpers.
src/toml-document.ts Stores and applies the new temporal parse option when producing JS objects.
src/to-js.ts Threads temporal option and converts TOML custom Date subclasses into Temporal values when enabled.
src/temporal-global.d.ts Adds a minimal Temporal typing shim (currently as a global declaration).
src/patch.ts Auto-detects Temporal in updated, threads temporal mode through toJS, and preserves Temporal date/time serialization.
src/parse-options.ts Documents and adds the new temporal?: boolean option.
src/parse-js.ts Detects Temporal inputs during stringify and routes them through Temporal-aware CST generation.
src/index.ts Documents and forwards options.temporal through parse().
src/generate.ts Adds generateTemporalDateTime() to serialize Temporal objects to TOML date/time nodes.
src/__tests__/temporal.test.ts Adds Temporal integration tests using @js-temporal/polyfill.
README.md Documents default Date-subclass behavior vs opt-in Temporal behavior + examples.
package.json / pnpm-lock.yaml Adds @js-temporal/polyfill dev dependency for tests.
CHANGELOG.md Notes Temporal support additions.
PLAN-temporal.md Adds implementation plan/notes for Temporal support.
.github/workflows/test-and-build.yml Expands CI Node matrix to include Node 26.x.
.github/workflows/node-engine-check.yml Updates engine check job to Node 26.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/utils.ts
Comment thread src/utils.ts
Comment thread src/patch.ts
Comment thread src/utils.ts
Comment thread src/__tests__/temporal.test.ts
Comment thread src/generate.ts Outdated
Comment thread src/generate.ts Outdated
Comment thread src/generate.ts Outdated
@socket-security

socket-security Bot commented Jun 21, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​js-temporal/​polyfill@​0.5.11001009783100

View full report

@js-temporal/polyfill does not provide getISOFields; only native Temporal
implementations do. Keep the equals check which exists on both.
ZonedDateTime.toString() includes IANA annotations that TOML strips,
causing spurious diffs. Use temporalToTomlString for consistency.
TOML only supports offset timezones. ZonedDateTime with IANA annotations
now throws a clear error. Offset timezones are still accepted.
Fixed dateValueToTemporal to use +00:00 instead of UTC.
temporalToTomlString always emits T, but the existing TOML may use
a space separator. Re-apply the separator from existing.raw.
…ralDateTime

Centralizes TOML validation (bracket rejection, Z normalization) through
temporalToTomlString instead of raw toString().
Temporarily remove globalThis.Temporal to verify the runtime guard
throws a clear error.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 18 changed files in this pull request and generated 10 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

Comment thread src/to-js.ts
Comment on lines +83 to +85
if (value instanceof LocalDateTime) {
return T.PlainDateTime.from(value.toISOString());
}
Comment thread src/to-js.ts
Comment on lines +87 to +98
if (value instanceof OffsetDateTime) {
const iso = value.toISOString();
// Extract offset: e.g. "2024-01-15T10:30:00+05:30" or "2024-01-15T10:30:00Z"
const offsetMatch = iso.match(/([+-]\d{2}:\d{2}|Z)$/);
const offset = offsetMatch ? offsetMatch[1] : 'Z';
// Strip offset suffix to get the plain datetime
const plainIso = iso.replace(/([+-]\d{2}:\d{2}|Z)$/, '');
// ZonedDateTime.from requires a timezone. Use the offset itself so the
// resulting object has an offset timezone (not IANA), which TOML can represent.
const tz = offset === 'Z' ? '+00:00' : offset;
return T.ZonedDateTime.from(`${plainIso}${offset}[${tz}]`);
}
Comment thread src/generate.ts
Comment on lines +441 to +444
if (truncateZeroTimeInDates) {
const T = (globalThis as any).Temporal;
const plainDate = T.PlainDate.from(value.toString().split('T')[0]);
if (plainDate.toString() + 'T00:00:00' === value.toString().slice(0, 19)) {
Comment thread src/utils.ts Outdated
Comment on lines +86 to +88
// Normalize +00:00 to Z
return full.replace(/\[.*\]$/, '').replace('+00:00', 'Z');
}
Comment thread src/utils.ts
Comment on lines +89 to +91

return value.toString();
}
Comment thread docs/Dates.md
Comment on lines +59 to +73
stringify({
start: Temporal.PlainDate.from('2024-01-15'),
due: Temporal.ZonedDateTime.from('2024-12-31T23:59:59Z[UTC]')
});
// start = 2024-01-15
// due = 2024-12-31T23:59:59Z

patch('d = 2024-01-15\n', {
d: Temporal.PlainDateTime.from('2025-06-01T12:00:00')
});
// d = 2025-06-01T12:00:00
```

> **Note:** TOML only supports timezone offsets (`+05:30`, `Z`), not IANA timezone names. When a `Temporal.ZonedDateTime` with an IANA annotation (e.g. `[Asia/Kolkata]`) is serialized, only the offset portion is kept.

Comment thread CHANGELOG.md
### Added

- Parsing: New `temporal` option in `ParseOptions`. When `true`, TOML date/time values are returned as [Temporal](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Temporal) objects (`Temporal.PlainDate`, `Temporal.PlainTime`, `Temporal.PlainDateTime`, `Temporal.ZonedDateTime`) instead of custom `Date` subclasses.
- Stringify: Auto-detect Temporal objects in the input JS and serialize them to the correct TOML date/time type. `ZonedDateTime` IANA annotations are stripped (TOML only supports offsets).
Comment thread src/parse-options.ts
Comment on lines +16 to +18
* The Temporal API must be available in the runtime (it is Stage 4
* and shipping in modern browsers and Node.js).
*
Comment thread PLAN-temporal.md
1. **`temporal` is opt-in (default `false`).** This avoids a breaking change. In a future major version it could become opt-out or the default once Temporal reaches Baseline.
2. **Temporal detection in serialize path is automatic.** If a user has a Temporal object in their JS, we want it to serialize correctly without extra configuration.
3. **Duck-typing for Temporal detection** rather than `instanceof` checks, because Temporal objects may come from different realms (e.g., iframes, vm contexts).
4. **For `ZonedDateTime` with IANA timezone**, we strip the IANA annotation and keep only the offset in TOML output. TOML does not support IANA timezone names.
Comment on lines +4 to +7
* Uses @js-temporal/polyfill because Node.js 24 does not yet ship
* Temporal natively (Stage 4 spec, expected in a future release).
* The polyfill is set on globalThis so the library code can access it
* the same way it would access the native Temporal global.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants