From 94174ebcce8a5adcd769373b531110813e0aa533 Mon Sep 17 00:00:00 2001 From: Aarnav Tale Date: Wed, 17 Apr 2024 17:20:35 -0400 Subject: [PATCH] feat: add dumb yaml detection --- app/routes/_data.acls._index/editor.tsx | 12 +++++++----- app/routes/_data.acls._index/route.tsx | 7 ++++--- app/utils/config.ts | 15 ++++++++++++--- package.json | 1 + pnpm-lock.yaml | 24 ++++++++++++++++++++++++ 5 files changed, 48 insertions(+), 11 deletions(-) diff --git a/app/routes/_data.acls._index/editor.tsx b/app/routes/_data.acls._index/editor.tsx index f310cf1..bc779c5 100644 --- a/app/routes/_data.acls._index/editor.tsx +++ b/app/routes/_data.acls._index/editor.tsx @@ -1,9 +1,10 @@ import { json } from '@codemirror/lang-json' +import { yaml } from '@codemirror/lang-yaml' import { useFetcher } from '@remix-run/react' import { githubDark, githubLight } from '@uiw/codemirror-theme-github' import CodeMirror from '@uiw/react-codemirror' import clsx from 'clsx' -import { useEffect, useState } from 'react' +import { useEffect, useMemo, useState } from 'react' import CodeMirrorMerge from 'react-codemirror-merge' import { toast } from 'react-hot-toast/headless' @@ -18,12 +19,14 @@ type EditorProperties = { readonly data: { hasAclWrite: boolean; currentAcl: string; + aclType: string; }; } export default function Editor({ data, acl, setAcl, mode }: EditorProperties) { const [light, setLight] = useState(false) const fetcher = useFetcher() + const aclType = useMemo(() => data.aclType === 'json' ? json() : yaml(), [data.aclType]) useEffect(() => { const theme = window.matchMedia('(prefers-color-scheme: light)') @@ -35,7 +38,6 @@ export default function Editor({ data, acl, setAcl, mode }: EditorProperties) { }, []) return ( - <>
{ setAcl(value) @@ -65,12 +67,12 @@ export default function Editor({ data, acl, setAcl, mode }: EditorProperties) {
diff --git a/app/routes/_data.acls._index/route.tsx b/app/routes/_data.acls._index/route.tsx index b0826ff..26cc6e4 100644 --- a/app/routes/_data.acls._index/route.tsx +++ b/app/routes/_data.acls._index/route.tsx @@ -20,10 +20,11 @@ export async function loader() { throw new Error('No ACL configuration is available') } - const acl = await getAcl() + const { data, type } = await getAcl() return { hasAclWrite: context.hasAclWrite, - currentAcl: acl + currentAcl: data, + aclType: type } } @@ -85,7 +86,7 @@ export default function Page() { diff --git a/app/utils/config.ts b/app/utils/config.ts index 02c972c..5630951 100644 --- a/app/utils/config.ts +++ b/app/utils/config.ts @@ -2,7 +2,7 @@ import { type FSWatcher, watch } from 'node:fs' import { access, constants, readFile, writeFile } from 'node:fs/promises' import { resolve } from 'node:path' -import { type Document, parseDocument } from 'yaml' +import { type Document, parse, parseDocument } from 'yaml' type Duration = `${string}s` | `${string}h` | `${string}m` | `${string}d` | `${string}y` @@ -141,11 +141,19 @@ export async function getAcl() { } if (!path) { - return '' + return { data: '', type: 'json' } } const data = await readFile(path, 'utf8') - return data + + // Naive check for YAML over JSON + // This is because JSON.parse doesn't support comments + try { + parse(data) + return { data, type: 'yaml' } + } catch { + return { data, type: 'json' } + } } // This is so obscenely dangerous, please have a check around it @@ -339,3 +347,4 @@ async function hasAclW() { return false } + diff --git a/package.json b/package.json index 67f7b33..b738ace 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ }, "dependencies": { "@codemirror/lang-json": "^6.0.1", + "@codemirror/lang-yaml": "^6.1.1", "@dnd-kit/core": "^6.1.0", "@dnd-kit/modifiers": "^7.0.0", "@dnd-kit/sortable": "^8.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 537dec5..f73bc60 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ dependencies: '@codemirror/lang-json': specifier: ^6.0.1 version: 6.0.1 + '@codemirror/lang-yaml': + specifier: ^6.1.1 + version: 6.1.1(@codemirror/view@6.26.3) '@dnd-kit/core': specifier: ^6.1.0 version: 6.1.0(react-dom@18.2.0)(react@18.2.0) @@ -490,6 +493,19 @@ packages: '@lezer/json': 1.0.2 dev: false + /@codemirror/lang-yaml@6.1.1(@codemirror/view@6.26.3): + resolution: {integrity: sha512-HV2NzbK9bbVnjWxwObuZh5FuPCowx51mEfoFT9y3y+M37fA3+pbxx4I7uePuygFzDsAmCTwQSc/kXh/flab4uw==} + dependencies: + '@codemirror/autocomplete': 6.16.0(@codemirror/language@6.10.1)(@codemirror/state@6.4.1)(@codemirror/view@6.26.3)(@lezer/common@1.2.1) + '@codemirror/language': 6.10.1 + '@codemirror/state': 6.4.1 + '@lezer/common': 1.2.1 + '@lezer/highlight': 1.2.0 + '@lezer/yaml': 1.0.2 + transitivePeerDependencies: + - '@codemirror/view' + dev: false + /@codemirror/language@6.10.1: resolution: {integrity: sha512-5GrXzrhq6k+gL5fjkAwt90nYDmjlzTIJV8THnxNFtNKWotMIlzzN+CpqxqwXOECnUdOndmSeWntVrVcv5axWRQ==} dependencies: @@ -1160,6 +1176,14 @@ packages: '@lezer/common': 1.2.1 dev: false + /@lezer/yaml@1.0.2: + resolution: {integrity: sha512-XCkwuxe+eumJ28nA9e1S6XKsXz9W7V/AG+WBiWOtiIuUpKcZ/bHuvN8bLxSDREIcybSRpEd/jvphh4vgm6Ed2g==} + dependencies: + '@lezer/common': 1.2.1 + '@lezer/highlight': 1.2.0 + '@lezer/lr': 1.4.0 + dev: false + /@mdx-js/mdx@2.3.0: resolution: {integrity: sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA==} dependencies: