Skip to content

Commit aa9b882

Browse files
lovesinatraCorentinTh
authored andcommitted
feat(new-tool): yaml formater (CorentinTh#779)
* validating if yaml is correct and collecting format options * Formatting yaml, sorting keys and changing indent size. * Removed unused format options * Fixed lint errors * Installed types for js-yaml * Removed legacy routing and added tool creation date Co-authored-by: Corentin THOMASSET <[email protected]> * Using existing yaml package instead of js-yaml * Update src/tools/yaml-viewer/index.ts --------- Co-authored-by: Isaiah <[email protected]> Co-authored-by: Corentin THOMASSET <[email protected]>
1 parent eaf979b commit aa9b882

File tree

5 files changed

+111
-3
lines changed

5 files changed

+111
-3
lines changed

components.d.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ declare module '@vue/runtime-core' {
9292
'IconMdi:contentCopy': typeof import('~icons/mdi/content-copy')['default']
9393
'IconMdi:kettleSteamOutline': typeof import('~icons/mdi/kettle-steam-outline')['default']
9494
IconMdiArrowDown: typeof import('~icons/mdi/arrow-down')['default']
95-
IconMdiArrowRight: typeof import('~icons/mdi/arrow-right')['default']
9695
IconMdiArrowRightBottom: typeof import('~icons/mdi/arrow-right-bottom')['default']
9796
IconMdiCamera: typeof import('~icons/mdi/camera')['default']
9897
IconMdiChevronDown: typeof import('~icons/mdi/chevron-down')['default']
@@ -172,8 +171,6 @@ declare module '@vue/runtime-core' {
172171
NTable: typeof import('naive-ui')['NTable']
173172
NTag: typeof import('naive-ui')['NTag']
174173
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
175-
NUpload: typeof import('naive-ui')['NUpload']
176-
NUploadDragger: typeof import('naive-ui')['NUploadDragger']
177174
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
178175
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
179176
PdfSignatureChecker: typeof import('./src/tools/pdf-signature-checker/pdf-signature-checker.vue')['default']
@@ -215,5 +212,6 @@ declare module '@vue/runtime-core' {
215212
XmlFormatter: typeof import('./src/tools/xml-formatter/xml-formatter.vue')['default']
216213
YamlToJson: typeof import('./src/tools/yaml-to-json-converter/yaml-to-json.vue')['default']
217214
YamlToToml: typeof import('./src/tools/yaml-to-toml/yaml-to-toml.vue')['default']
215+
YamlViewer: typeof import('./src/tools/yaml-viewer/yaml-viewer.vue')['default']
218216
}
219217
}

src/tools/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ import { tool as urlParser } from './url-parser';
7676
import { tool as uuidGenerator } from './uuid-generator';
7777
import { tool as macAddressLookup } from './mac-address-lookup';
7878
import { tool as xmlFormatter } from './xml-formatter';
79+
import { tool as yamlViewer } from './yaml-viewer';
7980

8081
export const toolsByCategory: ToolCategory[] = [
8182
{
@@ -141,6 +142,7 @@ export const toolsByCategory: ToolCategory[] = [
141142
chmodCalculator,
142143
dockerRunToDockerComposeConverter,
143144
xmlFormatter,
145+
yamlViewer,
144146
],
145147
},
146148
{

src/tools/yaml-viewer/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { AlignJustified } from '@vicons/tabler';
2+
import { defineTool } from '../tool';
3+
4+
export const tool = defineTool({
5+
name: 'YAML prettify and format',
6+
path: '/yaml-prettify',
7+
description: 'Prettify your YAML string to a human friendly readable format.',
8+
keywords: ['yaml', 'viewer', 'prettify', 'format'],
9+
component: () => import('./yaml-viewer.vue'),
10+
icon: AlignJustified,
11+
createdAt: new Date('2024-01-31'),
12+
});

src/tools/yaml-viewer/yaml-models.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { type MaybeRef, get } from '@vueuse/core';
2+
3+
import yaml from 'yaml';
4+
5+
export { formatYaml };
6+
7+
function formatYaml({
8+
rawYaml,
9+
sortKeys = false,
10+
indentSize = 2,
11+
}: {
12+
rawYaml: MaybeRef<string>
13+
sortKeys?: MaybeRef<boolean>
14+
indentSize?: MaybeRef<number>
15+
}) {
16+
const parsedYaml = yaml.parse(get(rawYaml));
17+
18+
const formattedYAML = yaml.stringify(parsedYaml, {
19+
sortMapEntries: get(sortKeys),
20+
indent: get(indentSize),
21+
});
22+
23+
return formattedYAML;
24+
}

src/tools/yaml-viewer/yaml-viewer.vue

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<script setup lang="ts">
2+
import yaml from 'yaml';
3+
import { useStorage } from '@vueuse/core';
4+
import { formatYaml } from './yaml-models';
5+
import { withDefaultOnError } from '@/utils/defaults';
6+
import { useValidation } from '@/composable/validation';
7+
import TextareaCopyable from '@/components/TextareaCopyable.vue';
8+
9+
const inputElement = ref<HTMLElement>();
10+
11+
const rawYaml = useStorage('yaml-prettify:raw-yaml', '');
12+
const indentSize = useStorage('yaml-prettify:indent-size', 2);
13+
const sortKeys = useStorage('yaml-prettify:sort-keys', false);
14+
15+
const cleanYaml = computed(() => withDefaultOnError(() => formatYaml({ rawYaml, indentSize, sortKeys }), ''));
16+
17+
const rawYamlValidation = useValidation({
18+
source: rawYaml,
19+
rules: [
20+
{
21+
validator: v => v === '' || yaml.parse(v),
22+
message: 'Provided YAML is not valid.',
23+
},
24+
],
25+
});
26+
</script>
27+
28+
<template>
29+
<div style="flex: 0 0 100%">
30+
<div style="margin: 0 auto; max-width: 600px" flex justify-center gap-3>
31+
<n-form-item label="Sort keys :" label-placement="left" label-width="100">
32+
<n-switch v-model:value="sortKeys" />
33+
</n-form-item>
34+
<n-form-item label="Indent size :" label-placement="left" label-width="100" :show-feedback="false">
35+
<n-input-number v-model:value="indentSize" min="1" max="10" style="width: 100px" />
36+
</n-form-item>
37+
</div>
38+
</div>
39+
40+
<n-form-item
41+
label="Your raw YAML"
42+
:feedback="rawYamlValidation.message"
43+
:validation-status="rawYamlValidation.status"
44+
>
45+
<c-input-text
46+
ref="inputElement"
47+
v-model:value="rawYaml"
48+
placeholder="Paste your raw YAML here..."
49+
rows="20"
50+
multiline
51+
autocomplete="off"
52+
autocorrect="off"
53+
autocapitalize="off"
54+
spellcheck="false"
55+
monospace
56+
/>
57+
</n-form-item>
58+
<n-form-item label="Prettified version of your YAML">
59+
<TextareaCopyable :value="cleanYaml" language="yaml" :follow-height-of="inputElement" />
60+
</n-form-item>
61+
</template>
62+
63+
<style lang="less" scoped>
64+
.result-card {
65+
position: relative;
66+
.copy-button {
67+
position: absolute;
68+
top: 10px;
69+
right: 10px;
70+
}
71+
}
72+
</style>

0 commit comments

Comments
 (0)