Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFE: option to be explicit about !!timestamp tags #475

Open
isaacs opened this issue May 25, 2023 · 1 comment
Open

RFE: option to be explicit about !!timestamp tags #475

isaacs opened this issue May 25, 2023 · 1 comment
Labels
enhancement New feature or request

Comments

@isaacs
Copy link
Contributor

isaacs commented May 25, 2023

Is your feature request related to a problem? Please describe.

Even though it seems (if I'm reading it correctly?) to be in line with the spec, there's an ambiguity when dealing with date strings.

If you have an object with an actual date, and an object with a string representation of the same date, then they yaml.stringify to the same value, because !!timestamp is a default, so it isn't tagged in the yaml.

> yaml.stringify({ x: new Date('2023') })
'x: 2023-01-01T00:00:00.000Z\n'
> yaml.stringify({ x: new Date('2023').toISOString() })
'x: 2023-01-01T00:00:00.000Z\n'

This makes it impossible to know what you actually got in the value, and a string and a Date are quite different things!

What's worse, when parsing yaml, you get the same value in both cases, making rehydration impossible to do faithfully:

> yaml.parse(yaml.stringify({ x: new Date('2023') }))
{ x: '2023-01-01T00:00:00.000Z' } // <-- string, expected Date
> yaml.parse(yaml.stringify({ x: new Date('2023').toISOString() }))
{ x: '2023-01-01T00:00:00.000Z' } // <-- string, as expected

Of course, you can explicitly say "treat valid date strings as dates":

> yaml.parse(yaml.stringify({ x: new Date('2023') }), { customTags: ['timestamp'] })
{ x: 2023-01-01T00:00:00.000Z } // <-- Date, as expected

But then that swings too far in the other direction:

> yaml.parse(yaml.stringify({ x: new Date('2023').toISOString() }), { customTags: ['timestamp'] })
{ x: 2023-01-01T00:00:00.000Z } // <-- Date! expected string

If a !!timestamp were present in the stringified value, then this would work as expected:

> yaml.parse('x: 2023-01-01T00:00:00.000Z\n')
{ x: '2023-01-01T00:00:00.000Z' }  // <-- string, as expected
> yaml.parse('x: !!timestamp 2023-01-01T00:00:00.000Z\n')
{ x: 2023-01-01T00:00:00.000Z }  // <-- date, as expected

Describe the solution you'd like

It would be nice if there was an option to yaml.stringify to explicitly declare that we want to get a !!timestamp tag added to any Date objects.

As far as I can see, what yaml is doing today isn't wrong according to the spec, but neither would it be if !!timestamp were added in these cases by default (or even, always).

> yaml.stringify({ x: new Date('2023') }, { explicitTimestamp: true })
'x: !!timestamp 2023-01-01T00:00:00.000Z\n'

Describe alternatives you've considered

My alternative at the moment (which I'm not thrilled about) is to define !!timestamp in my own code as a custom tag, so that it isn't default: true. But I'd much prefer to just use the one that ships with yaml already.

@isaacs isaacs added the enhancement New feature or request label May 25, 2023
@eemeli
Copy link
Owner

eemeli commented May 25, 2023

Atm, the internal !!timestamp tag can be accessed via

import { Schema } from 'yaml'
const schema = new Schema({ resolveKnownTags: true })
const timestamp = schema.knownTags['tag:yaml.org,2002:timestamp']
timestamp.default = false // toggles this for all users, not just this schema instance

But that's pretty hacky and undocumented. It seems to me like it might make sense to add an explicit API for accessing YAML 1.1 tags to yaml-types, which would then take the burden of digging them out of the yaml package.

isaacs added a commit to tapjs/tap-yaml that referenced this issue May 25, 2023
Little bit hacky, but at least don't have to manage a copy of it.

See: eemeli/yaml#475
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants