Skip to content

Commit a385d18

Browse files
committed
feat: Implement JS Object to JSON Converter (CorentinTh#849)
1 parent d3b32cc commit a385d18

File tree

9 files changed

+148
-1
lines changed

9 files changed

+148
-1
lines changed

components.d.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,26 +89,39 @@ declare module '@vue/runtime-core' {
8989
HttpStatusCodes: typeof import('./src/tools/http-status-codes/http-status-codes.vue')['default']
9090
IbanValidatorAndParser: typeof import('./src/tools/iban-validator-and-parser/iban-validator-and-parser.vue')['default']
9191
'IconMdi:brushVariant': typeof import('~icons/mdi/brush-variant')['default']
92+
'IconMdi:contentCopy': typeof import('~icons/mdi/content-copy')['default']
9293
'IconMdi:kettleSteamOutline': typeof import('~icons/mdi/kettle-steam-outline')['default']
94+
IconMdiArrowDown: typeof import('~icons/mdi/arrow-down')['default']
95+
IconMdiArrowRightBottom: typeof import('~icons/mdi/arrow-right-bottom')['default']
96+
IconMdiCamera: typeof import('~icons/mdi/camera')['default']
9397
IconMdiChevronDown: typeof import('~icons/mdi/chevron-down')['default']
9498
IconMdiChevronRight: typeof import('~icons/mdi/chevron-right')['default']
9599
IconMdiClose: typeof import('~icons/mdi/close')['default']
96100
IconMdiContentCopy: typeof import('~icons/mdi/content-copy')['default']
101+
IconMdiDeleteOutline: typeof import('~icons/mdi/delete-outline')['default']
102+
IconMdiDownload: typeof import('~icons/mdi/download')['default']
97103
IconMdiEye: typeof import('~icons/mdi/eye')['default']
98104
IconMdiEyeOff: typeof import('~icons/mdi/eye-off')['default']
99105
IconMdiHeart: typeof import('~icons/mdi/heart')['default']
106+
IconMdiPause: typeof import('~icons/mdi/pause')['default']
107+
IconMdiPlay: typeof import('~icons/mdi/play')['default']
108+
IconMdiRecord: typeof import('~icons/mdi/record')['default']
109+
IconMdiRefresh: typeof import('~icons/mdi/refresh')['default']
100110
IconMdiSearch: typeof import('~icons/mdi/search')['default']
101111
IconMdiTranslate: typeof import('~icons/mdi/translate')['default']
102112
IconMdiTriangleDown: typeof import('~icons/mdi/triangle-down')['default']
113+
IconMdiVideo: typeof import('~icons/mdi/video')['default']
103114
InputCopyable: typeof import('./src/components/InputCopyable.vue')['default']
104115
IntegerBaseConverter: typeof import('./src/tools/integer-base-converter/integer-base-converter.vue')['default']
105116
Ipv4AddressConverter: typeof import('./src/tools/ipv4-address-converter/ipv4-address-converter.vue')['default']
106117
Ipv4RangeExpander: typeof import('./src/tools/ipv4-range-expander/ipv4-range-expander.vue')['default']
107118
Ipv4SubnetCalculator: typeof import('./src/tools/ipv4-subnet-calculator/ipv4-subnet-calculator.vue')['default']
108119
Ipv6UlaGenerator: typeof import('./src/tools/ipv6-ula-generator/ipv6-ula-generator.vue')['default']
120+
JavascriptToJson: typeof import('./src/tools/javascript-to-json/javascript-to-json.vue')['default']
109121
JsonDiff: typeof import('./src/tools/json-diff/json-diff.vue')['default']
110122
JsonMinify: typeof import('./src/tools/json-minify/json-minify.vue')['default']
111123
JsonToCsv: typeof import('./src/tools/json-to-csv/json-to-csv.vue')['default']
124+
JsonToJavascript: typeof import('./src/tools/json-to-javascript/json-to-javascript.vue')['default']
112125
JsonToToml: typeof import('./src/tools/json-to-toml/json-to-toml.vue')['default']
113126
JsonToYaml: typeof import('./src/tools/json-to-yaml-converter/json-to-yaml.vue')['default']
114127
JsonViewer: typeof import('./src/tools/json-viewer/json-viewer.vue')['default']
@@ -126,25 +139,40 @@ declare module '@vue/runtime-core' {
126139
MenuLayout: typeof import('./src/components/MenuLayout.vue')['default']
127140
MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default']
128141
MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default']
142+
NAlert: typeof import('naive-ui')['NAlert']
129143
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
144+
NCheckbox: typeof import('naive-ui')['NCheckbox']
130145
NCode: typeof import('naive-ui')['NCode']
131146
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
147+
NColorPicker: typeof import('naive-ui')['NColorPicker']
132148
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
149+
NDatePicker: typeof import('naive-ui')['NDatePicker']
133150
NDivider: typeof import('naive-ui')['NDivider']
151+
NDynamicInput: typeof import('naive-ui')['NDynamicInput']
134152
NEllipsis: typeof import('naive-ui')['NEllipsis']
153+
NForm: typeof import('naive-ui')['NForm']
135154
NFormItem: typeof import('naive-ui')['NFormItem']
136155
NGi: typeof import('naive-ui')['NGi']
137156
NGrid: typeof import('naive-ui')['NGrid']
138157
NH1: typeof import('naive-ui')['NH1']
158+
NH2: typeof import('naive-ui')['NH2']
139159
NH3: typeof import('naive-ui')['NH3']
140160
NIcon: typeof import('naive-ui')['NIcon']
161+
NImage: typeof import('naive-ui')['NImage']
162+
NInputGroup: typeof import('naive-ui')['NInputGroup']
163+
NInputGroupLabel: typeof import('naive-ui')['NInputGroupLabel']
141164
NInputNumber: typeof import('naive-ui')['NInputNumber']
142-
NLabel: typeof import('naive-ui')['NLabel']
143165
NLayout: typeof import('naive-ui')['NLayout']
144166
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
145167
NMenu: typeof import('naive-ui')['NMenu']
168+
NProgress: typeof import('naive-ui')['NProgress']
146169
NScrollbar: typeof import('naive-ui')['NScrollbar']
170+
NSlider: typeof import('naive-ui')['NSlider']
147171
NSpin: typeof import('naive-ui')['NSpin']
172+
NStatistic: typeof import('naive-ui')['NStatistic']
173+
NSwitch: typeof import('naive-ui')['NSwitch']
174+
NTable: typeof import('naive-ui')['NTable']
175+
NTag: typeof import('naive-ui')['NTag']
148176
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
149177
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
150178
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
@@ -159,6 +187,7 @@ declare module '@vue/runtime-core' {
159187
RouterLink: typeof import('vue-router')['RouterLink']
160188
RouterView: typeof import('vue-router')['RouterView']
161189
RsaKeyPairGenerator: typeof import('./src/tools/rsa-key-pair-generator/rsa-key-pair-generator.vue')['default']
190+
SafelinkDecoder: typeof import('./src/tools/safelink-decoder/safelink-decoder.vue')['default']
162191
SlugifyString: typeof import('./src/tools/slugify-string/slugify-string.vue')['default']
163192
SpanCopyable: typeof import('./src/components/SpanCopyable.vue')['default']
164193
SqlPrettify: typeof import('./src/tools/sql-prettify/sql-prettify.vue')['default']

locales/en.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,14 @@ tools:
199199
json-to-yaml-converter:
200200
title: JSON to YAML converter
201201
description: Simply convert JSON to YAML with this live online converter.
202+
203+
json-to-javascript:
204+
title: JSON to JS converter
205+
description: Simply convert JSON to Javascript object with this live online converter.
206+
207+
javascript-to-json:
208+
title: JS to JSON converter
209+
description: Simply convert Javascript object to JSON with this live online converter.
202210

203211
url-parser:
204212
title: Url parser

locales/zh.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,14 @@ tools:
197197
title: JSON到YAML转换器
198198
description: 在线转换将JSON转换为YAML。
199199

200+
json-to-javascript:
201+
title: JSON 到 JS 转换器
202+
description: 使用此在线转换器将 JSON 转换为 Javascript 对象。
203+
204+
javascript-to-json:
205+
title: JS 到 JSON 转换器
206+
description: 使用此在线转换器将 Javascript 对象转换为 JSON。
207+
200208
url-parser:
201209
title: Url分析器
202210
description: 解析url字符串以获取所有不同的部分(协议、来源、参数、端口、用户名密码…)

src/components/TextareaCopyable.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { Copy } from '@vicons/tabler';
33
import { useElementSize } from '@vueuse/core';
44
import hljs from 'highlight.js/lib/core';
5+
import javascriptHljs from 'highlight.js/lib/languages/javascript';
56
import jsonHljs from 'highlight.js/lib/languages/json';
67
import sqlHljs from 'highlight.js/lib/languages/sql';
78
import xmlHljs from 'highlight.js/lib/languages/xml';
@@ -24,6 +25,7 @@ const props = withDefaults(
2425
copyMessage: 'Copy to clipboard',
2526
},
2627
);
28+
hljs.registerLanguage('javascript', javascriptHljs);
2729
hljs.registerLanguage('sql', sqlHljs);
2830
hljs.registerLanguage('json', jsonHljs);
2931
hljs.registerLanguage('html', xmlHljs);

src/tools/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import { tool as jsonDiff } from './json-diff';
2828
import { tool as ipv4RangeExpander } from './ipv4-range-expander';
2929
import { tool as httpStatusCodes } from './http-status-codes';
3030
import { tool as yamlToJson } from './yaml-to-json-converter';
31+
import { tool as javascriptToJson } from './javascript-to-json';
32+
import { tool as jsonToJavascript } from './json-to-javascript';
3133
import { tool as jsonToYaml } from './json-to-yaml-converter';
3234
import { tool as ipv6UlaGenerator } from './ipv6-ula-generator';
3335
import { tool as ipv4AddressConverter } from './ipv4-address-converter';
@@ -102,6 +104,8 @@ export const toolsByCategory: ToolCategory[] = [
102104
textToUnicode,
103105
yamlToJson,
104106
yamlToToml,
107+
javascriptToJson,
108+
jsonToJavascript,
105109
jsonToYaml,
106110
jsonToToml,
107111
listConverter,

src/tools/javascript-to-json/index.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Braces } from '@vicons/tabler';
2+
import { defineTool } from '../tool';
3+
import { translate } from '@/plugins/i18n.plugin';
4+
5+
export const tool = defineTool({
6+
name: translate('tools.javascript-to-json.title'),
7+
path: '/javascript-to-json',
8+
description: translate('tools.javascript-to-json.description'),
9+
keywords: ['javascript', 'to', 'json'],
10+
component: () => import('./javascript-to-json.vue'),
11+
icon: Braces,
12+
createdAt: new Date('2024-03-29'),
13+
});
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<script setup lang="ts">
2+
import JSON5 from 'json5';
3+
import type { UseValidationRule } from '@/composable/validation';
4+
import { isNotThrowing } from '@/utils/boolean';
5+
import { withDefaultOnError } from '@/utils/defaults';
6+
7+
const indentSize = useStorage('json-prettify:indent-size', 3);
8+
const transformer = (value: string) => withDefaultOnError(() => JSON.stringify(JSON5.parse(value), null, indentSize.value), '');
9+
10+
const rules: UseValidationRule<string>[] = [
11+
{
12+
validator: (value: string) => value === '' || isNotThrowing(() => JSON.stringify(JSON5.parse(value))),
13+
message: 'Provided JS Object is not valid.',
14+
},
15+
];
16+
</script>
17+
18+
<template>
19+
<div style="flex: 0 0 100%">
20+
<div style="margin: 0 auto; max-width: 600px" flex justify-center gap-3>
21+
<n-form-item label="Indent size :" label-placement="left" label-width="100" :show-feedback="false">
22+
<n-input-number v-model:value="indentSize" min="0" max="10" style="width: 100px" />
23+
</n-form-item>
24+
</div>
25+
</div>
26+
27+
<format-transformer
28+
input-label="Your JavaScript Object"
29+
input-placeholder="Paste your JS Object here..."
30+
output-label="JSON from your JavaScript Object"
31+
output-language="json"
32+
:input-validation-rules="rules"
33+
:transformer="transformer"
34+
/>
35+
</template>

src/tools/json-to-javascript/index.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Braces } from '@vicons/tabler';
2+
import { defineTool } from '../tool';
3+
import { translate } from '@/plugins/i18n.plugin';
4+
5+
export const tool = defineTool({
6+
name: translate('tools.json-to-javascript.title'),
7+
path: '/json-to-javascript',
8+
description: translate('tools.json-to-javascript.description'),
9+
keywords: ['json', 'to', 'javascript'],
10+
component: () => import('./json-to-javascript.vue'),
11+
icon: Braces,
12+
createdAt: new Date('2024-03-29'),
13+
});
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<script setup lang="ts">
2+
import JSON5 from 'json5';
3+
import type { UseValidationRule } from '@/composable/validation';
4+
import { isNotThrowing } from '@/utils/boolean';
5+
import { withDefaultOnError } from '@/utils/defaults';
6+
7+
const indentSize = useStorage('json-prettify:indent-size', 3);
8+
const transformer = (value: string) => withDefaultOnError(() => JSON5.stringify(JSON.parse(value), null, indentSize.value), '');
9+
10+
const rules: UseValidationRule<string>[] = [
11+
{
12+
validator: (value: string) => value === '' || isNotThrowing(() => JSON5.stringify(JSON.parse(value))),
13+
message: 'Provided JSON is not valid.',
14+
},
15+
];
16+
</script>
17+
18+
<template>
19+
<div style="flex: 0 0 100%">
20+
<div style="margin: 0 auto; max-width: 600px" flex justify-center gap-3>
21+
<n-form-item label="Indent size :" label-placement="left" label-width="100" :show-feedback="false">
22+
<n-input-number v-model:value="indentSize" min="0" max="10" style="width: 100px" />
23+
</n-form-item>
24+
</div>
25+
</div>
26+
27+
<format-transformer
28+
input-label="Your JSON"
29+
input-placeholder="Paste your JSON here..."
30+
output-label="JavaScript Object from your JSON"
31+
output-language="javascript"
32+
:input-validation-rules="rules"
33+
:transformer="transformer"
34+
/>
35+
</template>

0 commit comments

Comments
 (0)