diff --git a/src/datetime/localDate.ts b/src/datetime/localDate.ts index 50bf78b6..d6c2c146 100644 --- a/src/datetime/localDate.ts +++ b/src/datetime/localDate.ts @@ -57,9 +57,11 @@ export class LocalDate { setYear(v: number): LocalDate { return this.set('year', v) } + setMonth(v: number): LocalDate { return this.set('month', v) } + setDay(v: number): LocalDate { return this.set('day', v) } @@ -143,15 +145,19 @@ export class LocalDate { isToday(): boolean { return this.isSame(localDate.today()) } + isAfterToday(): boolean { return this.isAfter(localDate.today()) } + isSameOrAfterToday(): boolean { return this.isSameOrAfter(localDate.today()) } + isBeforeToday(): boolean { return this.isBefore(localDate.today()) } + isSameOrBeforeToday(): boolean { return this.isSameOrBefore(localDate.today()) } @@ -159,12 +165,15 @@ export class LocalDate { getAgeInYears(today?: LocalDateInput): number { return this.getAgeIn('year', today) } + getAgeInMonths(today?: LocalDateInput): number { return this.getAgeIn('month', today) } + getAgeInDays(today?: LocalDateInput): number { return this.getAgeIn('day', today) } + getAgeIn(unit: LocalDateUnit, today?: LocalDateInput): number { return localDate.fromInput(today || new Date()).diff(this, unit) } @@ -264,24 +273,31 @@ export class LocalDate { plusDays(num: number): LocalDate { return this.plus(num, 'day') } + plusWeeks(num: number): LocalDate { return this.plus(num, 'week') } + plusMonths(num: number): LocalDate { return this.plus(num, 'month') } + plusYears(num: number): LocalDate { return this.plus(num, 'year') } + minusDays(num: number): LocalDate { return this.plus(-num, 'day') } + minusWeeks(num: number): LocalDate { return this.plus(-num, 'week') } + minusMonths(num: number): LocalDate { return this.plus(-num, 'month') } + minusYears(num: number): LocalDate { return this.plus(-num, 'year') } diff --git a/src/datetime/localTime.ts b/src/datetime/localTime.ts index 0ba4191b..5e38404f 100644 --- a/src/datetime/localTime.ts +++ b/src/datetime/localTime.ts @@ -212,42 +212,55 @@ export class LocalTime { get year(): number { return this.$date.getFullYear() } + setYear(v: number): LocalTime { return this.set('year', v) } + get month(): number { return this.$date.getMonth() + 1 } + setMonth(v: number): LocalTime { return this.set('month', v) } + get week(): number { return getWeek(this.$date) } + setWeek(v: number): LocalTime { return this.set('week', v) } + get day(): number { return this.$date.getDate() } + setDay(v: number): LocalTime { return this.set('day', v) } + get hour(): number { return this.$date.getHours() } + setHour(v: number): LocalTime { return this.set('hour', v) } + get minute(): number { return this.$date.getMinutes() } + setMinute(v: number): LocalTime { return this.set('minute', v) } + get second(): number { return this.$date.getSeconds() } + setSecond(v: number): LocalTime { return this.set('second', v) } @@ -258,6 +271,7 @@ export class LocalTime { get dayOfWeek(): ISODayOfWeek { return (this.$date.getDay() || 7) as ISODayOfWeek } + setDayOfWeek(v: ISODayOfWeek): LocalTime { _assert(VALID_DAYS_OF_WEEK.has(v), `Invalid dayOfWeek: ${v}`) const dow = this.$date.getDay() || 7 @@ -292,42 +306,55 @@ export class LocalTime { plusSeconds(num: number): LocalTime { return this.plus(num, 'second') } + plusMinutes(num: number): LocalTime { return this.plus(num, 'minute') } + plusHours(num: number): LocalTime { return this.plus(num, 'hour') } + plusDays(num: number): LocalTime { return this.plus(num, 'day') } + plusWeeks(num: number): LocalTime { return this.plus(num, 'week') } + plusMonths(num: number): LocalTime { return this.plus(num, 'month') } + plusYears(num: number): LocalTime { return this.plus(num, 'year') } + minusSeconds(num: number): LocalTime { return this.plus(-num, 'second') } + minusMinutes(num: number): LocalTime { return this.plus(-num, 'minute') } + minusHours(num: number): LocalTime { return this.plus(-num, 'hour') } + minusDays(num: number): LocalTime { return this.plus(-num, 'day') } + minusWeeks(num: number): LocalTime { return this.plus(-num, 'week') } + minusMonths(num: number): LocalTime { return this.plus(-num, 'month') } + minusYears(num: number): LocalTime { return this.plus(-num, 'year') } @@ -452,20 +479,25 @@ export class LocalTime { isSame(d: LocalTimeInput): boolean { return this.compare(d) === 0 } + isBefore(d: LocalTimeInput, inclusive = false): boolean { const r = this.compare(d) return r === -1 || (r === 0 && inclusive) } + isSameOrBefore(d: LocalTimeInput): boolean { return this.compare(d) <= 0 } + isAfter(d: LocalTimeInput, inclusive = false): boolean { const r = this.compare(d) return r === 1 || (r === 0 && inclusive) } + isSameOrAfter(d: LocalTimeInput): boolean { return this.compare(d) >= 0 } + isBetween(min: LocalTimeInput, max: LocalTimeInput, incl: Inclusiveness = '[)'): boolean { let r = this.compare(min) // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with @@ -518,21 +550,27 @@ export class LocalTime { getAgeInYears(now?: LocalTimeInput): number { return this.getAgeIn('year', now) } + getAgeInMonths(now?: LocalTimeInput): number { return this.getAgeIn('month', now) } + getAgeInDays(now?: LocalTimeInput): number { return this.getAgeIn('day', now) } + getAgeInHours(now?: LocalTimeInput): number { return this.getAgeIn('hour', now) } + getAgeInMinutes(now?: LocalTimeInput): number { return this.getAgeIn('minute', now) } + getAgeInSeconds(now?: LocalTimeInput): number { return this.getAgeIn('second', now) } + getAgeIn(unit: LocalTimeUnit, now?: LocalTimeInput): number { return localTime.fromInput(now ?? new Date()).diff(this, unit) } @@ -540,6 +578,7 @@ export class LocalTime { isAfterNow(): boolean { return this.$date.valueOf() > Date.now() } + isBeforeNow(): boolean { return this.$date.valueOf() < Date.now() } diff --git a/src/json-schema/jsonSchemaBuilder.ts b/src/json-schema/jsonSchemaBuilder.ts index 3fccdfcd..6c597aca 100644 --- a/src/json-schema/jsonSchemaBuilder.ts +++ b/src/json-schema/jsonSchemaBuilder.ts @@ -131,38 +131,47 @@ export class JsonSchemaAnyBuilder Object.assign(this.schema, { $schema }) return this } + $schemaDraft7(): this { this.$schema('http://json-schema.org/draft-07/schema#') return this } + $id($id: string): this { Object.assign(this.schema, { $id }) return this } + title(title: string): this { Object.assign(this.schema, { title }) return this } + description(description: string): this { Object.assign(this.schema, { description }) return this } + deprecated(deprecated = true): this { Object.assign(this.schema, { deprecated }) return this } + type(type: string): this { Object.assign(this.schema, { type }) return this } + default(v: any): this { Object.assign(this.schema, { default: v }) return this } + oneOf(schemas: JsonSchema[]): this { Object.assign(this.schema, { oneOf: schemas }) return this } + allOf(schemas: JsonSchema[]): this { Object.assign(this.schema, { allOf: schemas }) return this @@ -211,18 +220,22 @@ export class JsonSchemaNumberBuilder extends JsonSchemaAnyBuilder extends JsonSchemaAnyB Object.assign(this.schema, { minProperties }) return this } + maxProps(maxProperties: number): this { Object.assign(this.schema, { maxProperties }) return this } + additionalProps(additionalProperties: boolean): this { Object.assign(this.schema, { additionalProperties }) return this @@ -400,10 +418,12 @@ export class JsonSchemaArrayBuilder extends JsonSchemaAnyBuilder< Object.assign(this.schema, { minItems }) return this } + max(maxItems: number): this { Object.assign(this.schema, { maxItems }) return this } + unique(uniqueItems: number): this { Object.assign(this.schema, { uniqueItems }) return this diff --git a/src/semver.ts b/src/semver.ts index 59b090e8..eaa7d7e8 100644 --- a/src/semver.ts +++ b/src/semver.ts @@ -28,9 +28,11 @@ export class Semver { get major(): number { return this.tokens[0] } + get minor(): number { return this.tokens[1] } + get patch(): number { return this.tokens[2] } diff --git a/yarn.lock b/yarn.lock index 1d04ebd1..58b2cecc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1307,9 +1307,9 @@ typescript "^5.0.2" "@naturalcycles/dev-lib@^15.0.3": - version "15.24.0" - resolved "https://registry.yarnpkg.com/@naturalcycles/dev-lib/-/dev-lib-15.24.0.tgz#0f07805ffe25abc3f7f2ce6cfc64f8761825360e" - integrity sha512-g5Pw8WuazJbOBU8t/yQSMlsLQjFo0jMUVN3wMPpDYFFznqSipBNnSfC1rFDDSZ36YO/b4cfsRA4I/z0P7MNaLA== + version "15.25.0" + resolved "https://registry.yarnpkg.com/@naturalcycles/dev-lib/-/dev-lib-15.25.0.tgz#dfc8270ca2f695399b8101242d740da253df5acd" + integrity sha512-UUSw+XwuzktCQ4gJdV+eG4OJPcCnX7XvIL7kC0InCkCnd9VFOPMMZ+QdB4E7AxBLnJ/fO8mRmj2KFSFymbK3cg== dependencies: "@biomejs/biome" "^1.8.3" "@commitlint/cli" "^19.0.0"