Skip to content

Commit

Permalink
feat: use branded IsoDate
Browse files Browse the repository at this point in the history
  • Loading branch information
kirillgroshkov committed Nov 9, 2024
1 parent 68bf943 commit 5990a9a
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 30 deletions.
4 changes: 2 additions & 2 deletions scripts/dateStringTodayBench.script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ yarn tsn dateStringTodayBench
*/

import { runBenchScript } from '@naturalcycles/bench-lib'
import { localDate } from '@naturalcycles/js-lib'
import { IsoDate, localDate } from '@naturalcycles/js-lib'
import { isValid, objectSchema, stringSchema } from '../src'

const entries = localDate
Expand All @@ -15,7 +15,7 @@ const entries = localDate
}))

const entrySchema1 = objectSchema({
date: stringSchema.dateString('2000-01-01', 'today'),
date: stringSchema.dateString('2000-01-01' as IsoDate, 'today'),
})

const entrySchema2 = objectSchema({
Expand Down
12 changes: 9 additions & 3 deletions src/validation/ajv/ajv.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { JsonSchema } from '@naturalcycles/js-lib'
import type { IsoDate, JsonSchema } from '@naturalcycles/js-lib'
import { _deepFreeze, _try, jsonSchema, localTime } from '@naturalcycles/js-lib'
import { _inspect } from '../../index'
import { testDir } from '../../test/paths.cnst'
Expand Down Expand Up @@ -187,9 +187,15 @@ test.each([
[{ type: 'string', format: 'countryCode' }, ['se', 'sve']],
[{ type: 'string', format: 'currency' }, ['sek', 'us']],
[{ type: 'number', format: 'unixTimestamp' }, [1232342342000, -1]],
[{ type: 'number', format: 'unixTimestamp2000' }, [1232342342000, localTime('1999-01-01').unix]],
[
{ type: 'number', format: 'unixTimestamp2000' },
[1232342342000, localTime('1999-01-01' as IsoDate).unix],
],
[{ type: 'number', format: 'unixTimestampMillis' }, [-1]],
[{ type: 'number', format: 'unixTimestampMillis2000' }, [-1, localTime('1999-01-01').unixMillis]],
[
{ type: 'number', format: 'unixTimestampMillis2000' },
[-1, localTime('1999-01-01' as IsoDate).unixMillis],
],
[{ type: 'number', format: 'utcOffset' }, [-15 * 60]],
[{ type: 'number', format: 'utcOffsetHours' }, [-15, 15]],
] as [JsonSchema, any[]][])('%s should be invalid', (schema, objects: any[]) => {
Expand Down
6 changes: 3 additions & 3 deletions src/validation/joi/joi.shared.schemas.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expectTypeOf } from '@naturalcycles/dev-lib/dist/testing'
import { BaseDBEntity, localTime } from '@naturalcycles/js-lib'
import { BaseDBEntity, IsoDateTime, localTime } from '@naturalcycles/js-lib'
import { testValidation } from '../../test/validation.test.util'
import {
baseDBEntitySchema,
Expand Down Expand Up @@ -226,7 +226,7 @@ describe('dateTimeStringSchema', () => {
'2024-09-30T00:55:12',
'2024-09-30T00:55:12+02:00',
'2024-09-30T00:55:12Z',
]
] as IsoDateTime[]

test.each(validDateTimes)('valid dateTime: %s', s => {
expect(isValid(s, dateTimeStringSchema)).toBe(true)
Expand All @@ -249,7 +249,7 @@ describe('dateTimeStringSchema', () => {
'extra2024-07-25T00:55Z', // Extra characters before a valid datetime
'Some random string', // Random string
'2024 was a good year', // Year with some text
]
] as IsoDateTime[]

test.each(invalidDateTimes)('invalid dateTime: %s', s => {
expect(isValid(s, dateTimeStringSchema)).toBe(false)
Expand Down
6 changes: 4 additions & 2 deletions src/validation/joi/joi.shared.schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
_stringEnumKeys,
_stringEnumValues,
BaseDBEntity,
IsoDate,
IsoDateTime,
NumberEnum,
StringEnum,
UnixTimestamp,
Expand All @@ -22,7 +24,7 @@ export const numberSchema = Joi.number()
export const numberSchemaTyped = <T>(): NumberSchema<T> => Joi.number<T>()
export const integerSchema = Joi.number().integer()
export const percentageSchema = Joi.number().integer().min(0).max(100)
export const dateStringSchema = stringSchema.dateString()
export const dateStringSchema = stringSchema.dateString() as StringSchema<IsoDate>
export const binarySchema = Joi.binary()
export const dateObjectSchema = Joi.object().instance(Date)

Expand All @@ -36,7 +38,7 @@ export const DATE_TIME_STRING_REGEX =

export const dateTimeStringSchema = stringSchema.regex(DATE_TIME_STRING_REGEX).messages({
'string.pattern.base': `must be a DateTime string`,
})
}) as StringSchema<IsoDateTime>

/**
* Allows all values of a String Enum.
Expand Down
4 changes: 2 additions & 2 deletions src/validation/joi/string.extensions.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { localTime } from '@naturalcycles/js-lib'
import { IsoDate, localTime } from '@naturalcycles/js-lib'
import { testValidation } from '../../test/validation.test.util'
import { stringSchema } from './joi.shared.schemas'

Expand All @@ -13,7 +13,7 @@ test('dateString', () => {
})

test('dateString min/max', async () => {
const schema = stringSchema.dateString('2017-06-21', '2017-06-23')
const schema = stringSchema.dateString('2017-06-21' as IsoDate, '2017-06-23' as IsoDate)

testValidation(
schema,
Expand Down
18 changes: 9 additions & 9 deletions src/validation/joi/string.extensions.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { localTime } from '@naturalcycles/js-lib'
import { IsoDate, localTime } from '@naturalcycles/js-lib'
import type Joi from 'joi'
import { Extension, StringSchema as JoiStringSchema } from 'joi'

export interface StringSchema<TSchema = string> extends JoiStringSchema<TSchema> {
dateString: (min?: string, max?: string) => this
dateString: (min?: IsoDate | 'today', max?: IsoDate | 'today') => this
}

export interface JoiDateStringOptions {
min?: string
max?: string
min?: IsoDate | 'today'
max?: IsoDate | 'today'
}

export function stringExtensions(joi: typeof Joi): Extension {
Expand All @@ -24,7 +24,7 @@ export function stringExtensions(joi: typeof Joi): Extension {
},
rules: {
dateString: {
method(min?: string, max?: string) {
method(min?: IsoDate, max?: IsoDate) {
return this.$_addRule({
name: 'dateString',
args: { min, max } satisfies JoiDateStringOptions,
Expand Down Expand Up @@ -101,11 +101,11 @@ function isLeapYear(year: number): boolean {
}

let lastCheckedPlus = 0
let todayStrPlusCached: string
let todayStrPlusCached: IsoDate
let lastCheckedMinus = 0
let todayStrMinusCached: string
let todayStrMinusCached: IsoDate

function getTodayStrPlus15(): string {
function getTodayStrPlus15(): IsoDate {
const now = Date.now()
if (now - lastCheckedPlus < 3_600_000) {
// cached for 1 hour
Expand All @@ -116,7 +116,7 @@ function getTodayStrPlus15(): string {
return (todayStrPlusCached = localTime.now().plus(15, 'hour').toISODate())
}

function getTodayStrMinus15(): string {
function getTodayStrMinus15(): IsoDate {
const now = Date.now()
if (now - lastCheckedMinus < 3_600_000) {
// cached for 1 hour
Expand Down
18 changes: 9 additions & 9 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1009,9 +1009,9 @@
typescript "^5.0.2"

"@naturalcycles/dev-lib@^15.0.3":
version "15.27.1"
resolved "https://registry.yarnpkg.com/@naturalcycles/dev-lib/-/dev-lib-15.27.1.tgz#8620e279e92f6b76bf01446094bfba1fa4482aa9"
integrity sha512-3mov6Hfd7BXpjXhuLi5MZC2bBiLfXNLDkbVsYAvYorx587w9sQMLtI7PvlnI+R370joO+/kAxjJFXIb3RaINCg==
version "15.27.2"
resolved "https://registry.yarnpkg.com/@naturalcycles/dev-lib/-/dev-lib-15.27.2.tgz#b69473f2cbf191b44dfb219b1dc728a858876eff"
integrity sha512-54o9VExhppDsQ7NxiX+7soxpvg++5grsVgL1pyYGDypeH/xIhaAipLj9z3GALCyRk3ohAa8RkQ0I+FrW59ZVsg==
dependencies:
"@biomejs/biome" "^1.8.3"
"@commitlint/cli" "^19.0.0"
Expand Down Expand Up @@ -1047,17 +1047,17 @@
yargs "^17.0.0"

"@naturalcycles/js-lib@^14.0.0", "@naturalcycles/js-lib@^14.244.0":
version "14.260.0"
resolved "https://registry.yarnpkg.com/@naturalcycles/js-lib/-/js-lib-14.260.0.tgz#1086a684ff4ccd028be053d9fa701d9cd5358dbf"
integrity sha512-GfkmD+xAP8GODx2kh++5MErmDMu50S/QAslbtoaKtpWrmFlfaMEtNpYLXLDYGjcj4NJRilbE9hwiM8Rizs5V2g==
version "14.261.0"
resolved "https://registry.yarnpkg.com/@naturalcycles/js-lib/-/js-lib-14.261.0.tgz#e85aaa6c68b5efeada4e4cfdcb5c00e5e30a8d3a"
integrity sha512-7+jI98zjNcifAkQu8q4UHhXzeclJVIDfoE8GHpwdqjbaT6a9p2KOikvBjMd1SdCH1OTR6ijBPNvax1VS9Jb2qw==
dependencies:
tslib "^2.0.0"
zod "^3.20.2"

"@naturalcycles/nodejs-lib@^13.0.1", "@naturalcycles/nodejs-lib@^13.0.2":
version "13.35.0"
resolved "https://registry.yarnpkg.com/@naturalcycles/nodejs-lib/-/nodejs-lib-13.35.0.tgz#473f7ddfb3432e5a91d803950868c070fcba0e59"
integrity sha512-Dwil0k3oDjDBHKeEw6qxEiHUidoFHYlaxiLtUaADeTSa8FwgHKw6PIyax3pYcaITkJ0EQftpDTosTKhOr2UVRw==
version "13.36.0"
resolved "https://registry.yarnpkg.com/@naturalcycles/nodejs-lib/-/nodejs-lib-13.36.0.tgz#cea71bd4e88ba37d28cb4af9a12fd5e0678d4fd0"
integrity sha512-v6t2P2HGFhaCFN9iM5Fgvg7qnf7FAK76SatCLGoQtdozyUX7xnPj8xUe35ft2YGvmu1TaWU4UWqRKTJEWGwByA==
dependencies:
"@naturalcycles/js-lib" "^14.244.0"
"@types/js-yaml" "^4.0.9"
Expand Down

0 comments on commit 5990a9a

Please sign in to comment.