From c52bd93256a4124e7399204ff67a9c0145d5f578 Mon Sep 17 00:00:00 2001 From: Jonathan Delgado Date: Wed, 12 Oct 2022 02:31:31 -0300 Subject: [PATCH] feat: initial commit --- README.md | 23 +++++++++++ ndate.ts | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 README.md create mode 100644 ndate.ts diff --git a/README.md b/README.md new file mode 100644 index 0000000..15b20db --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# ndate script + +Date format to console. + +```shell +Usage: ndate [-] [--zero] [--date-style ] [--time-style ] + [--local ] [--json] [--date ] [--help] [-j] [-d ] + [-l ] [-z] [-h] +``` + +Please install with deno: + +```shell +deno install ndate.ts +``` + +Samples use: + +```shell +ndate # Tuesday, October 11, 2022 at 5:59:37 PM Chile Summer Time +ndate --local es-CL # martes, 11 de octubre de 2022, 17:59:14 hora de verano de Chile +ndate --local en-CL # Tuesday, October 11, 2022 at 5:59:37 PM Chile Summer Time +``` diff --git a/ndate.ts b/ndate.ts new file mode 100644 index 0000000..981830d --- /dev/null +++ b/ndate.ts @@ -0,0 +1,116 @@ +const dateStyles = ["full", "long", "medium", "short"] as const; +const timeStyles = ["full", "long", "medium", "short"] as const; +type DateStyle = (typeof dateStyles)[number]; +type TimeStyle = (typeof dateStyles)[number]; +const toDateStyle = (v: unknown): DateStyle | undefined => typeof v === "string" ? dateStyles.find(dateStyle => dateStyle.startsWith(v)) : undefined; +const toTimeStyle = (v: unknown): DateStyle | undefined => typeof v === "string" ? timeStyles.find(timeStyle => timeStyle.startsWith(v)) : undefined; +const dateParse = (val: string): Date => { + const d = new Date(val); + if (Number.isNaN(Number(d))) { + throw new Error(`the ${Deno.inspect(val)} time stamp no valid`); + } + return d; +} + +let dateStyle: DateStyle = 'full'; +let timeStyle: TimeStyle = 'full'; +let newLine = true; +let local: string | undefined; +let date = new Date(); +let json = false; +let stdinRedeable = false; +let showHelp = false; + +const transformOptions: Record string | undefined) => void> = { + '-': () => { stdinRedeable = true }, + '--zero': () => { newLine = false; }, + '--date-style': (next) => { dateStyle = toDateStyle(next()) ?? 'full' }, + '--time-style': (next) => { timeStyle = toTimeStyle(next()) ?? 'full' }, + '--local': (next) => { local = next() }, + '--json': () => { json = true }, + '--date': (next) => { + const v = next(); + if (v) { + date = dateParse(v); + } + }, + '--help': () => { showHelp = true }, + get "-j"() { return this['--json'] }, + get "-d"() { return this["--date"] }, + get "-l"() { return this["--local"] }, + get "-z"() { return this["--zero"] }, + get "-h"() { return this["--help"] }, +}; + +const optionsLabels: Record = { + '--date-style': { label: `<${dateStyles.join('|')}>` }, + '--time-style': { label: `<${timeStyles.join('|')}>` }, + '--local': { label: `` }, + '--date': { label: `` }, + get "-j"() { return this['--json'] }, + get "-d"() { return this["--date"] }, + get "-l"() { return this["--local"] }, + get "-z"() { return this["--zero"] }, + get "-h"() { return this["--help"] }, +}; + +for ( + let argsCursor = Deno.args[Symbol.iterator](), + { value: arg, done } = argsCursor.next(); + !done; + { value: arg, done } = argsCursor.next() +) { + const next = (): string | undefined => argsCursor.next().value; + if (typeof arg === "string" && arg in transformOptions) { transformOptions[arg](next); } +} + +const run = async () => { + if (showHelp) { + const items = Object.keys(transformOptions) + .map(item => { + const label = optionsLabels[item]?.label; + return label ? `[${item} ${label}]` : `[${item}]`; + }); + + const textUsage = `Usage: ndate`; + + const lines: string[] = []; + let currentLine: string | undefined; + for (const item of items) { + if (!currentLine) { + currentLine = lines.length ? `${' '.repeat(textUsage.length)}` : `${textUsage}`; + } + + currentLine = `${currentLine} ${item}`; + if (currentLine.length > 80) { + lines.push(currentLine); + currentLine = undefined; + } + } + + if (currentLine) lines.push(currentLine); + + for (const line of lines) { + console.log(line); + } + + return; + } + + if (stdinRedeable) { + const buff = new Uint8Array(256); + await Deno.stdin.read(buff); + const text = new TextDecoder().decode(buff.subarray(0, buff.findIndex(p => p === 0))).trim(); + date = dateParse(text); + } + + const dateStr = json ? date.toJSON() : date.toLocaleString(local, { dateStyle, timeStyle }); + + Deno.stdout.write(new TextEncoder().encode(dateStr)) + + if (newLine) Deno.stdout.write( + new TextEncoder().encode(`\n`) + ) +} + +await run();