From 314e0e76f8c0132be14a2257e591a1adb060b1cb Mon Sep 17 00:00:00 2001 From: Minhyeok Park Date: Mon, 28 Oct 2024 21:33:41 +0900 Subject: [PATCH] feat: add datetime transforms --- package.json | 2 + pnpm-lock.yaml | 16 ++++++++ src/Editor/index.tsx | 2 +- src/TransformGridItem/index.tsx | 47 ++++++++++++++++++++--- src/TransformGridItem/style.module.scss | 2 +- src/Transforms/DatetimeTransforms.ts | 50 +++++++++++++++++++++++++ src/Transforms/Transform.ts | 29 ++++++++------ src/vite-env.d.ts | 4 ++ 8 files changed, 132 insertions(+), 20 deletions(-) create mode 100644 src/Transforms/DatetimeTransforms.ts diff --git a/package.json b/package.json index 825f6db..7c92140 100644 --- a/package.json +++ b/package.json @@ -15,10 +15,12 @@ "clsx": "^2.1.1", "framer-motion": "^11.11.10", "json5": "^2.2.3", + "moment": "^2.30.1", "normalize.css": "^8.0.1", "react": "^18.3.1", "react-dom": "^18.3.1", "recoil": "^0.7.7", + "strtime": "^1.1.2", "styled-components": "^6.1.13", "yaml": "^2.6.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 574b88f..8716ebc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: json5: specifier: ^2.2.3 version: 2.2.3 + moment: + specifier: ^2.30.1 + version: 2.30.1 normalize.css: specifier: ^8.0.1 version: 8.0.1 @@ -35,6 +38,9 @@ importers: recoil: specifier: ^0.7.7 version: 0.7.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + strtime: + specifier: ^1.1.2 + version: 1.1.2 styled-components: specifier: ^6.1.13 version: 6.1.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -994,6 +1000,9 @@ packages: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} + moment@2.30.1: + resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + monaco-editor@0.52.0: resolution: {integrity: sha512-OeWhNpABLCeTqubfqLMXGsqf6OmPU6pHM85kF3dhy6kq5hnhuVS1p3VrEW/XhWHc71P2tHyS5JFySD8mgs1crw==} @@ -1269,6 +1278,9 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + strtime@1.1.2: + resolution: {integrity: sha512-FI4KG8T6kTckaD17M8MJrde8p/OVrVbfbXZV1Q5CUsBBuxkxtS3LZmWnGKC38lIZHKFJ7L6RU+fZ9GPuQgZEzQ==} + styled-components@6.1.13: resolution: {integrity: sha512-M0+N2xSnAtwcVAQeFEsGWFFxXDftHUD7XrKla06QbpUMmbmtFBMMTcKWvFXtWxuD5qQkB8iU5gk6QASlx2ZRMw==} engines: {node: '>= 16'} @@ -2169,6 +2181,8 @@ snapshots: dependencies: brace-expansion: 2.0.1 + moment@2.30.1: {} + monaco-editor@0.52.0: {} ms@2.1.3: {} @@ -2422,6 +2436,8 @@ snapshots: strip-json-comments@3.1.1: {} + strtime@1.1.2: {} + styled-components@6.1.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@emotion/is-prop-valid': 1.2.2 diff --git a/src/Editor/index.tsx b/src/Editor/index.tsx index 04c642e..e47ed8b 100644 --- a/src/Editor/index.tsx +++ b/src/Editor/index.tsx @@ -16,7 +16,7 @@ export const Editor: FC = () => { loading={<>} value={value} language="yaml" - onChange={(v) => setValue(v?.trim() ?? '')} + onChange={(v) => setValue(v ?? '')} options={{ automaticLayout: true, lineNumbersMinChars: 3, diff --git a/src/TransformGridItem/index.tsx b/src/TransformGridItem/index.tsx index 9eb01f5..358b6d2 100644 --- a/src/TransformGridItem/index.tsx +++ b/src/TransformGridItem/index.tsx @@ -7,11 +7,9 @@ import clsx from "clsx"; import { useRecoilState } from "recoil"; import { EditorValueState } from "../GlobalStates/EditorValueState"; import { - isTransformCheckboxOption, - isTransformIntboxOption, - isTransformTextboxOption, TransformCheckboxOption, TransformIntboxOption, + TransformRadioOption, TransformTextboxOption, WrappedTransform, WrappedTransformResult @@ -71,6 +69,18 @@ export const TransformGridItem: FC = ({ transform }) => { setOptions(new Map(options)) } + + const onRadioOptionChanged = + (option: TransformRadioOption) => + (event: ChangeEvent) => { + + options.set(option.key, { + ...option, + value: event.target.value + }) + + setOptions(new Map(options)) + } const onForwardButtonPressed = () => { if (result.error) @@ -90,7 +100,7 @@ export const TransformGridItem: FC = ({ transform }) => {
{[...options.values()] - ?.filter(isTransformCheckboxOption) + ?.filter((v) => v.type === 'CHECKBOX') .map((option, i) => ( ))} {[...options.values()] - ?.filter(isTransformTextboxOption) + ?.filter((v) => v.type === 'TEXTBOX') .map((option, i) => (
diff --git a/src/TransformGridItem/style.module.scss b/src/TransformGridItem/style.module.scss index 433ce2d..19fbecb 100644 --- a/src/TransformGridItem/style.module.scss +++ b/src/TransformGridItem/style.module.scss @@ -30,7 +30,7 @@ scrollbar-color: gray #323232; align-items: center; - .optionItem { + * { display: flex; gap: 6px; } diff --git a/src/Transforms/DatetimeTransforms.ts b/src/Transforms/DatetimeTransforms.ts new file mode 100644 index 0000000..8317cf4 --- /dev/null +++ b/src/Transforms/DatetimeTransforms.ts @@ -0,0 +1,50 @@ +import { Transform } from "./Transform"; +import { strptime } from 'strtime' +import moment from "moment"; + +export const DatetimeTransform: Transform = { + name: 'datetime', + + fn: async (v, o) => { + const [expression, samples] = v.split('\n\n') + const format = o.get('f')?.value + + const parsedSamples = samples + .split('\n') + .map((sample) => { + if (format === 'c') + return strptime(sample, expression.replace(/'/g, '')) + + if (format === 'java') + return moment(sample, expression.replace(/'/g, '')).toDate() + + throw new Error('Unknown Format') + }) + .map((date) => JSON.stringify({ + year: date.getFullYear(), + month: date.getMonth() + 1, + date: date.getDate(), + hour: date.getHours(), + minute: date.getMinutes(), + second: date.getSeconds(), + milli: date.getMilliseconds() + })) + .join('\n') + + return [ + expression, + samples, + parsedSamples + ].join('\n\n') + }, + + options: [{ + type: 'RADIO', + key: 'f', + value: 'c', + radios: [ + { value: 'c' }, + { value: 'java' } + ] + }] +} diff --git a/src/Transforms/Transform.ts b/src/Transforms/Transform.ts index 704e399..cb43cb0 100644 --- a/src/Transforms/Transform.ts +++ b/src/Transforms/Transform.ts @@ -1,4 +1,5 @@ import { Base64DecodeTransform, Base64EncodeTransform } from "./Base64Transforms" +import { DatetimeTransform } from "./DatetimeTransforms" import { GzipDecompressTransform } from "./GzipTransform" import { JSONBeautifyTransform, JSONEscapeTransform, JSONSimplifyTransform, JSONUnescapeTransform } from "./JSONTransforms" import { RegexpTransform } from "./RegexpTransform" @@ -27,17 +28,20 @@ export interface TransformIntboxOption { value?: number } +export interface TransformRadioOption { + type: 'RADIO', + key: string, + label?: string, + value?: string, + radios: { + label?: string + value: string + }[] +} + export type TransformOption = - TransformCheckboxOption | TransformTextboxOption | TransformIntboxOption - -export const isTransformCheckboxOption = (object: any): object is TransformCheckboxOption => - object.type === 'CHECKBOX' - -export const isTransformTextboxOption = (object: any): object is TransformTextboxOption => - object.type === 'TEXTBOX' - -export const isTransformIntboxOption = (object: any): object is TransformIntboxOption => - object.type === 'INTBOX' + TransformCheckboxOption | TransformTextboxOption | + TransformIntboxOption | TransformRadioOption export interface Transform { name: string @@ -77,7 +81,7 @@ export const wrapTransform = (transform: Transform): WrappedTransform => ({ export const transforms: Transform[] = [ RegexpTransform, - GzipDecompressTransform, + DatetimeTransform, Base64DecodeTransform, Base64EncodeTransform, URIDecodeTransform, @@ -87,5 +91,6 @@ export const transforms: Transform[] = [ JSONEscapeTransform, JSONUnescapeTransform, JSON2YAMLTransform, - YAML2JSONTransform + YAML2JSONTransform, + GzipDecompressTransform ] diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index 11f02fe..05e6e12 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -1 +1,5 @@ /// + +module 'strtime' { + function strptime (string, string): Date +}