-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 0425b26
Showing
13 changed files
with
4,346 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
node_modules/ | ||
old |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"eslint.format.enable": true, | ||
"eslint.quiet": true, | ||
"editor.codeActionsOnSave": { | ||
"source.fixAll.eslint": "explicit" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { defineBuildConfig } from 'unbuild' | ||
|
||
export default defineBuildConfig({ | ||
externals: ['vue', 'luxon', 'defu'], | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import antfu from '@antfu/eslint-config' | ||
|
||
export default antfu( | ||
{ | ||
rules: { | ||
curly: ['error', 'all'], | ||
}, | ||
}, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
{ | ||
"name": "vue-luxon-next", | ||
"type": "module", | ||
"version": "1.0.0", | ||
"private": false, | ||
"description": "Easy DateTime formatting & parsing in Vue using Luxon", | ||
"author": "Donald Shtjefni <[email protected]>", | ||
"license": "MIT", | ||
"repository": "[email protected]:dnldsht/v-luxon.git", | ||
"keywords": [ | ||
"vue", | ||
"vuejs", | ||
"luxon", | ||
"date", | ||
"datetime", | ||
"time", | ||
"format", | ||
"parse" | ||
], | ||
"exports": { | ||
".": { | ||
"types": "./dist/index.d.ts", | ||
"import": "./dist/index.mjs", | ||
"require": "./dist/index.cjs" | ||
} | ||
}, | ||
"main": "./dist/index.cjs", | ||
"module": "./dist/index.mjs", | ||
"types": "./dist/index.d.ts", | ||
"files": [ | ||
"dist" | ||
], | ||
"scripts": { | ||
"build": "unbuild", | ||
"test": "vitest", | ||
"lint": "eslint .", | ||
"lint:fix": "eslint . --fix" | ||
}, | ||
"dependencies": { | ||
"defu": "^6.1.2", | ||
"luxon": "^3.3.0" | ||
}, | ||
"devDependencies": { | ||
"@antfu/eslint-config": "^3.6.0", | ||
"@types/luxon": "^3.3.0", | ||
"@vitest/ui": "^2.1.0", | ||
"eslint": "^9.10.0", | ||
"ts-loader": "^9.4.4", | ||
"typescript": "^5.1.3", | ||
"unbuild": "^1.2.1", | ||
"vitest": "^2.1.0", | ||
"vue": "^3.3.4" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import type { LuxonOptions } from './types' | ||
import { DateTime } from 'luxon' | ||
|
||
const localeFormats = { | ||
full: { format: DateTime.DATETIME_FULL }, | ||
fulls: { format: DateTime.DATETIME_FULL_WITH_SECONDS }, | ||
huge: { format: DateTime.DATETIME_HUGE }, | ||
huges: { format: DateTime.DATETIME_HUGE_WITH_SECONDS }, | ||
med: { format: DateTime.DATETIME_MED }, | ||
meds: { format: DateTime.DATETIME_MED_WITH_SECONDS }, | ||
short: { format: DateTime.DATETIME_SHORT }, | ||
shorts: { format: DateTime.DATETIME_SHORT_WITH_SECONDS }, | ||
date_full: { format: DateTime.DATE_FULL }, | ||
date_huge: { format: DateTime.DATE_HUGE }, | ||
date_med: { format: DateTime.DATE_MED }, | ||
date_medd: { format: DateTime.DATE_MED_WITH_WEEKDAY }, | ||
date_short: { format: DateTime.DATE_SHORT }, | ||
time24: { format: DateTime.TIME_24_SIMPLE }, | ||
time24longoffset: { format: DateTime.TIME_24_WITH_LONG_OFFSET }, | ||
time24s: { format: DateTime.TIME_24_WITH_SECONDS }, | ||
time: { format: DateTime.TIME_SIMPLE }, | ||
times: { format: DateTime.TIME_WITH_SECONDS }, | ||
} | ||
|
||
export const DEFAULT_SETTINGS: LuxonOptions = { | ||
input: { | ||
zone: 'utc', | ||
format: 'iso', | ||
}, | ||
output: { | ||
format: 'short', | ||
}, | ||
templates: { | ||
server: { | ||
zone: 'utc', | ||
format: 'iso', | ||
}, | ||
client: { | ||
zone: 'local', | ||
format: 'med', | ||
}, | ||
inputdate: { | ||
zone: 'client', | ||
format: 'yyyy-MM-dd', | ||
}, | ||
...localeFormats, | ||
}, | ||
} as const |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import type { DateTime } from 'luxon' | ||
import type { OutputOptions } from './types' | ||
|
||
export default function format(dt: DateTime, options: OutputOptions) { | ||
dt = dt.setZone(options.zone) | ||
if (options.locale) { | ||
dt = dt.setLocale(options.locale) | ||
} | ||
|
||
if (typeof options.format === 'object') { | ||
return dt.toLocaleString(options.format) | ||
} | ||
|
||
switch (options.format) { | ||
case 'relative': | ||
return dt.toRelative(options.relative) | ||
case 'sql': | ||
return dt.toSQL(options.sql) | ||
case 'iso': | ||
return dt.toISO(options.iso) | ||
case 'http': | ||
return dt.toHTTP() | ||
case 'jsdate': | ||
return dt.toJSDate() | ||
case 'rfc': | ||
case 'rfc2822': | ||
return dt.toRFC2822() | ||
case 'millis': | ||
return dt.toMillis() | ||
case 'unix': | ||
case 'seconds': | ||
return dt.toSeconds() | ||
default: | ||
if (typeof options.format !== 'string') { | ||
throw new TypeError(`Invalid format argument: ${options.format} must be a string`) | ||
} | ||
return dt.toFormat(options.format) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import type { App } from 'vue' | ||
|
||
import type { ParseOptions } from './parse' | ||
import type { InputOptions, LuxonOptions, OutputOptions } from './types' | ||
import { defu } from 'defu' | ||
import { DEFAULT_SETTINGS } from './constants' | ||
import formatDt from './format' | ||
import parse from './parse' | ||
|
||
type ParseInput = string | number | Date | ||
type FormatInputOptions = string | Partial<InputOptions> | ||
type FormatOutputOptions = string | Partial<OutputOptions> | ||
|
||
export default { | ||
install: (app: App, options: LuxonOptions = {}) => { | ||
const luxonOptions = defu(options, DEFAULT_SETTINGS) as Required<LuxonOptions> | ||
|
||
function extendInput(value: ParseInput, format?: FormatInputOptions): ParseOptions { | ||
let options = typeof format === 'string' ? { format } : format | ||
if (options === undefined) { | ||
options = {} | ||
} | ||
|
||
let template: Partial<InputOptions> | undefined | ||
|
||
if (typeof options.format === 'string' && options.format in luxonOptions.templates) { | ||
const { format: templateFormat, ...rest } = luxonOptions.templates[options.format as keyof typeof luxonOptions.templates] | ||
template = { | ||
...rest, | ||
...(templateFormat && typeof templateFormat === 'string' && { format: templateFormat }), | ||
} | ||
} | ||
|
||
if (!options.format) { | ||
if (value instanceof Date) { | ||
options.format = 'jsdate' | ||
} | ||
else if (typeof value === 'number') { | ||
options.format = 'millis' | ||
} | ||
else { | ||
options.format = template?.format || luxonOptions.input.format | ||
} | ||
} | ||
|
||
options.zone = options.zone || template?.zone || luxonOptions.input.zone | ||
return { value, ...options } as ParseOptions | ||
} | ||
|
||
function extendOutput(format?: FormatOutputOptions): OutputOptions { | ||
if (!format) { | ||
format = luxonOptions.output | ||
} | ||
const base = typeof format === 'string' ? { format } : format | ||
|
||
let template: Partial<OutputOptions> | undefined | ||
|
||
if (typeof base.format === 'string' && base.format in luxonOptions.templates) { | ||
template = luxonOptions.templates[base.format as keyof typeof luxonOptions.templates] as Partial<OutputOptions> | ||
} | ||
|
||
const m = defu(template, base, luxonOptions.output) | ||
return m as OutputOptions | ||
} | ||
|
||
function luxonParse(value: ParseInput, format?: FormatInputOptions) { | ||
return parse(extendInput(value, format)) | ||
} | ||
|
||
function luxonFormat(value: ParseInput, format?: FormatOutputOptions, inputFormat?: FormatInputOptions) { | ||
const dt = luxonParse(value, inputFormat) | ||
return formatDt(dt, extendOutput(format)) | ||
} | ||
|
||
app.config.globalProperties.$lp = luxonParse | ||
app.config.globalProperties.$lf = luxonFormat | ||
app.config.globalProperties.$luxon = luxonFormat | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import type { Zone } from 'luxon' | ||
import { DateTime } from 'luxon' | ||
|
||
interface JsDateParseOptions { | ||
value: Date | ||
format: 'jsdate' | ||
zone?: string | Zone | ||
} | ||
|
||
interface NumberParseOptions { | ||
value: number | ||
format: 'millis' | 'seconds' | 'unix' | ||
zone?: string | Zone | ||
} | ||
|
||
interface StringParseOptions { | ||
value: string | ||
format: 'sql' | 'iso' | 'http' | 'rfc2822' | string | ||
zone?: string | Zone | ||
} | ||
|
||
export type ParseOptions = StringParseOptions | NumberParseOptions | JsDateParseOptions | ||
|
||
export default function parse(options: ParseOptions): DateTime { | ||
const { value, format, zone } = options | ||
|
||
switch (format) { | ||
case 'sql': | ||
return DateTime.fromSQL(value, { zone }) | ||
case 'iso': | ||
return DateTime.fromISO(value, { zone }) | ||
case 'http': | ||
return DateTime.fromHTTP(value, { zone }) | ||
case 'jsdate': | ||
if (!(value instanceof Date)) { | ||
throw new TypeError(`Value must be an instance of Date, received ${value === null ? 'null' : typeof value}`) | ||
} | ||
return DateTime.fromJSDate(value, { zone }) | ||
case 'rfc2822': | ||
return DateTime.fromRFC2822(value, { zone }) | ||
case 'millis': | ||
if (typeof value !== 'number') { | ||
throw new TypeError(`Value must be an integer, received ${value === null ? 'null' : typeof value}`) | ||
} | ||
return DateTime.fromMillis(value, { zone }) | ||
case 'seconds': | ||
case 'unix': | ||
if (typeof value !== 'number') { | ||
throw new TypeError(`Value must be an integer, received ${value === null ? 'null' : typeof value}`) | ||
} | ||
return DateTime.fromSeconds(value, { zone }) | ||
default: | ||
if (typeof format !== 'string') { | ||
throw new TypeError(`Invalid format argument: ${format} must be a string`) | ||
} | ||
if (typeof value !== 'string') { | ||
throw new TypeError(`Value must be a string, received ${value === null ? 'null' : typeof value}`) | ||
} | ||
return DateTime.fromFormat(value, format, { zone }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import type { DateTimeFormatOptions, ToISOTimeOptions, ToRelativeOptions, ToSQLOptions, Zone } from 'luxon' | ||
|
||
export interface InputOptions { | ||
zone?: string | Zone | ||
format: string | ||
} | ||
|
||
export interface OutputOptions { | ||
zone?: string | Zone | ||
locale?: string | ||
format?: string | DateTimeFormatOptions | Intl.DateTimeFormatOptions | ||
relative?: ToRelativeOptions | ||
sql?: ToSQLOptions | ||
iso?: ToISOTimeOptions | ||
|
||
} | ||
|
||
export interface LuxonOptions { | ||
templates?: Record<string, OutputOptions> | ||
input?: InputOptions | ||
output?: OutputOptions | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "ESNext", | ||
"module": "ESNext", | ||
"moduleResolution": "Node", | ||
"strict": true, | ||
"esModuleInterop": true | ||
}, | ||
"include": ["src", "vitest.config.ts"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { defineConfig } from 'vitest/config' | ||
|
||
export default defineConfig({ | ||
test: { | ||
globals: true, | ||
environment: 'jsdom', | ||
}, | ||
}) |
Oops, something went wrong.