mirror of
https://github.com/misode/misode.github.io.git
synced 2026-05-01 21:23:12 +00:00
Wrap all JSON.parse calls with try-catch
This commit is contained in:
+8
-5
@@ -4,6 +4,7 @@ import type { Project } from './contexts/index.js'
|
||||
import { DRAFT_PROJECT } from './contexts/index.js'
|
||||
import type { VersionId } from './services/index.js'
|
||||
import { DEFAULT_VERSION, VersionIds } from './services/index.js'
|
||||
import { safeJsonParse } from './Utils.js'
|
||||
|
||||
export namespace Store {
|
||||
export const ID_LANGUAGE = 'language'
|
||||
@@ -65,7 +66,7 @@ export namespace Store {
|
||||
export function getProjects(): Project[] {
|
||||
const projects = localStorage.getItem(ID_PROJECTS)
|
||||
if (projects) {
|
||||
return JSON.parse(projects) as Project[]
|
||||
return safeJsonParse(projects) ?? []
|
||||
}
|
||||
return [DRAFT_PROJECT]
|
||||
}
|
||||
@@ -73,13 +74,13 @@ export namespace Store {
|
||||
export function getPreviewPanelOpen(): boolean | undefined {
|
||||
const open = localStorage.getItem(ID_PREVIEW_PANEL_OPEN)
|
||||
if (open === null) return undefined
|
||||
return JSON.parse(open)
|
||||
return safeJsonParse(open)
|
||||
}
|
||||
|
||||
export function getProjectPanelOpen(): boolean | undefined {
|
||||
const open = localStorage.getItem(ID_PROJECT_PANEL_OPEN)
|
||||
if (open === null) return undefined
|
||||
return JSON.parse(open)
|
||||
return safeJsonParse(open)
|
||||
}
|
||||
|
||||
export function getOpenProject() {
|
||||
@@ -99,7 +100,8 @@ export namespace Store {
|
||||
}
|
||||
|
||||
export function getGeneratorHistory(): string[] {
|
||||
return JSON.parse(localStorage.getItem(ID_GENERATOR_HISTORY) ?? '[]')
|
||||
const value = localStorage.getItem(ID_GENERATOR_HISTORY) ?? '[]'
|
||||
return safeJsonParse(value) ?? []
|
||||
}
|
||||
|
||||
export function setLanguage(language: string | undefined) {
|
||||
@@ -173,7 +175,8 @@ export namespace Store {
|
||||
}
|
||||
|
||||
export function getWhatsNewSeen(): { id: string, time: string }[] {
|
||||
return JSON.parse(localStorage.getItem(ID_WHATS_NEW_SEEN) ?? '[]')
|
||||
const value = localStorage.getItem(ID_WHATS_NEW_SEEN) ?? '[]'
|
||||
return safeJsonParse(value) ?? []
|
||||
}
|
||||
|
||||
export function seeWhatsNew(ids: string[]) {
|
||||
|
||||
@@ -623,3 +623,11 @@ export function makeDescriptionId(prefix: string, id: Identifier | undefined) {
|
||||
}
|
||||
return `${prefix}.${id.namespace}.${id.path.replaceAll('/', '.')}`
|
||||
}
|
||||
|
||||
export function safeJsonParse(text: string): any {
|
||||
try {
|
||||
return JSON.parse(text)
|
||||
} catch (e) {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { DocAndNode } from '@spyglassmc/core'
|
||||
import { useState } from 'preact/hooks'
|
||||
import { Analytics } from '../../Analytics.js'
|
||||
import { useLocale, useProject } from '../../contexts/index.js'
|
||||
import { safeJsonParse } from '../../Utils.js'
|
||||
import { Btn } from '../Btn.js'
|
||||
import { TextInput } from '../forms/index.js'
|
||||
import { Modal } from '../Modal.js'
|
||||
@@ -29,8 +30,11 @@ export function FileCreation({ docAndNode, id, method, onClose }: Props) {
|
||||
return
|
||||
}
|
||||
Analytics.saveProjectFile(id, projects.length, project.files.length, method as any)
|
||||
const data = JSON.parse(docAndNode.doc.getText())
|
||||
updateFile(id, undefined, { type: id, id: fileId, data })
|
||||
const text = docAndNode.doc.getText()
|
||||
const data = safeJsonParse(text)
|
||||
if (data !== undefined) {
|
||||
updateFile(id, undefined, { type: id, id: fileId, data })
|
||||
}
|
||||
onClose()
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { DocAndNode } from '@spyglassmc/core'
|
||||
import { useDocAndNode } from '../../contexts/Spyglass.jsx'
|
||||
import { useVersion } from '../../contexts/Version.jsx'
|
||||
import { checkVersion } from '../../services/index.js'
|
||||
import { safeJsonParse } from '../../Utils.js'
|
||||
import { BiomeSourcePreview, BlockStatePreview, DecoratorPreview, DensityFunctionPreview, LootTablePreview, ModelPreview, NoisePreview, NoiseSettingsPreview, RecipePreview, StructureSetPreview } from '../previews/index.js'
|
||||
|
||||
export const HasPreview = ['loot_table', 'recipe', 'dimension', 'worldgen/density_function', 'worldgen/noise', 'worldgen/noise_settings', 'worldgen/configured_feature', 'worldgen/placed_feature', 'worldgen/structure_set', 'block_definition', 'docAndNode']
|
||||
@@ -27,7 +28,7 @@ export function PreviewPanel({ docAndNode: original, id, shown }: PreviewPanelPr
|
||||
return <RecipePreview {...{ docAndNode, shown }} />
|
||||
}
|
||||
|
||||
if (id === 'dimension' && JSON.parse(docAndNode.doc.getText()).generator?.type?.endsWith('noise')) {
|
||||
if (id === 'dimension' && safeJsonParse(docAndNode.doc.getText())?.generator?.type?.endsWith('noise')) {
|
||||
return <BiomeSourcePreview {...{ docAndNode, shown }} />
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { AsyncCancel, useActiveTimeout, useAsync, useSearchParam } from '../../h
|
||||
import type { VersionId } from '../../services/index.js'
|
||||
import { checkVersion, fetchPreset, fetchRegistries, getSnippet, shareSnippet } from '../../services/index.js'
|
||||
import { Store } from '../../Store.js'
|
||||
import { cleanUrl, genPath } from '../../Utils.js'
|
||||
import { cleanUrl, genPath, safeJsonParse } from '../../Utils.js'
|
||||
import { Ad, Btn, BtnMenu, ErrorPanel, FileCreation, FileRenaming, Footer, HasPreview, Octicon, PreviewPanel, ProjectCreation, ProjectDeletion, ProjectPanel, SearchList, SourcePanel, TextInput, Tree, VersionSwitcher } from '../index.js'
|
||||
|
||||
export const SHARE_KEY = 'share'
|
||||
@@ -102,8 +102,10 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
|
||||
setSharedSnippetId(undefined, true)
|
||||
}
|
||||
if (file) {
|
||||
const data = JSON.parse(doc.getText())
|
||||
updateFile(gen.id, file.id, { id: file.id, data })
|
||||
const data = safeJsonParse(doc.getText())
|
||||
if (data !== undefined) {
|
||||
updateFile(gen.id, file.id, { id: file.id, data })
|
||||
}
|
||||
}
|
||||
ignoreChange.current = false
|
||||
setError(null)
|
||||
@@ -211,7 +213,7 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
|
||||
setShareShown(true)
|
||||
} else if (doc) {
|
||||
setShareLoading(true)
|
||||
shareSnippet(gen.id, version, JSON.parse(doc.getText()), previewShown)
|
||||
shareSnippet(gen.id, version, doc.getText(), previewShown)
|
||||
.then(({ id, length, compressed, rate }) => {
|
||||
Analytics.createSnippet(gen.id, id, version, length, compressed, rate)
|
||||
const url = `${location.origin}/${gen.url}/?${SHARE_KEY}=${id}`
|
||||
|
||||
@@ -5,7 +5,7 @@ import { getProjectData, useLocale, useProject, useStore, useVersion } from '../
|
||||
import { useAsync } from '../../hooks/index.js'
|
||||
import { checkVersion } from '../../services/Versions.js'
|
||||
import { Store } from '../../Store.js'
|
||||
import { iterateWorld2D, randomSeed, stringToColor } from '../../Utils.js'
|
||||
import { iterateWorld2D, randomSeed, safeJsonParse, stringToColor } from '../../Utils.js'
|
||||
import { Btn, BtnMenu, NumberInput } from '../index.js'
|
||||
import type { ColormapType } from './Colormap.js'
|
||||
import { getColormap } from './Colormap.js'
|
||||
@@ -32,7 +32,7 @@ export const BiomeSourcePreview = ({ docAndNode, shown }: PreviewProps) => {
|
||||
const [focused2, setFocused2] = useState<string[]>([])
|
||||
|
||||
const text = docAndNode.doc.getText()
|
||||
const data = JSON.parse(text)
|
||||
const data = safeJsonParse(text) ?? {}
|
||||
const type: string = data?.generator?.biome_source?.type?.replace(/^minecraft:/, '') ?? ''
|
||||
const hasRandomness = type === 'multi_noise' || type === 'the_end'
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useVersion } from '../../contexts/index.js'
|
||||
import { useAsync } from '../../hooks/useAsync.js'
|
||||
import { AsyncCancel } from '../../hooks/useAsyncFn.js'
|
||||
import { getResources, ResourceWrapper } from '../../services/Resources.js'
|
||||
import { safeJsonParse } from '../../Utils.js'
|
||||
import type { PreviewProps } from './index.js'
|
||||
import { InteractiveCanvas3D } from './InteractiveCanvas3D.jsx'
|
||||
|
||||
@@ -18,7 +19,7 @@ export const BlockStatePreview = ({ docAndNode, shown }: PreviewProps) => {
|
||||
const { value: resources } = useAsync(async () => {
|
||||
if (!shown) return AsyncCancel
|
||||
const resources = await getResources(version)
|
||||
const definition = BlockDefinition.fromJson(JSON.parse(text))
|
||||
const definition = BlockDefinition.fromJson(safeJsonParse(text) ?? {})
|
||||
const wrapper = new ResourceWrapper(resources, {
|
||||
getBlockDefinition(id) {
|
||||
if (id.equals(PREVIEW_ID)) return definition
|
||||
|
||||
@@ -2,7 +2,7 @@ import { BlockPos, ChunkPos, LegacyRandom, PerlinNoise } from 'deepslate'
|
||||
import type { mat3 } from 'gl-matrix'
|
||||
import { useCallback, useMemo, useRef, useState } from 'preact/hooks'
|
||||
import { useLocale, useVersion } from '../../contexts/index.js'
|
||||
import { computeIfAbsent, iterateWorld2D, randomSeed } from '../../Utils.js'
|
||||
import { computeIfAbsent, iterateWorld2D, randomSeed, safeJsonParse } from '../../Utils.js'
|
||||
import { Btn } from '../index.js'
|
||||
import type { PlacedFeature, PlacementContext } from './Decorator.js'
|
||||
import { decorateChunk } from './Decorator.js'
|
||||
@@ -50,7 +50,7 @@ export const DecoratorPreview = ({ docAndNode, shown }: PreviewProps) => {
|
||||
}, [])
|
||||
const onDraw = useCallback(function onDraw(transform: mat3) {
|
||||
if (!ctx.current || !imageData.current || !shown) return
|
||||
const data = JSON.parse(text)
|
||||
const data = safeJsonParse(text) ?? {}
|
||||
iterateWorld2D(imageData.current, transform, (x, y) => {
|
||||
const pos = ChunkPos.create(Math.floor(x / 16), Math.floor(-y / 16))
|
||||
const features = computeIfAbsent(chunkFeatures, `${pos[0]} ${pos[1]}`, () => decorateChunk(pos, data, context))
|
||||
|
||||
@@ -6,7 +6,7 @@ import { getProjectData, useLocale, useProject, useVersion } from '../../context
|
||||
import { useAsync } from '../../hooks/useAsync.js'
|
||||
import { useLocalStorage } from '../../hooks/useLocalStorage.js'
|
||||
import { Store } from '../../Store.js'
|
||||
import { iterateWorld2D, randomSeed } from '../../Utils.js'
|
||||
import { iterateWorld2D, randomSeed, safeJsonParse } from '../../Utils.js'
|
||||
import { Btn, BtnMenu, NumberInput } from '../index.js'
|
||||
import type { ColormapType } from './Colormap.js'
|
||||
import { getColormap } from './Colormap.js'
|
||||
@@ -33,7 +33,7 @@ export const DensityFunctionPreview = ({ docAndNode, shown }: PreviewProps) => {
|
||||
|
||||
const { value: df } = useAsync(async () => {
|
||||
await DEEPSLATE.loadVersion(version, getProjectData(project))
|
||||
const df = DEEPSLATE.loadDensityFunction(JSON.parse(text), minY, height, seed)
|
||||
const df = DEEPSLATE.loadDensityFunction(safeJsonParse(text) ?? {}, minY, height, seed)
|
||||
return df
|
||||
}, [version, project, minY, height, seed, text])
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useMemo, useRef, useState } from 'preact/hooks'
|
||||
import { useLocale, useVersion } from '../../contexts/index.js'
|
||||
import { useAsync } from '../../hooks/useAsync.js'
|
||||
import { checkVersion, fetchAllPresets, fetchItemComponents } from '../../services/index.js'
|
||||
import { clamp, jsonToNbt, randomSeed } from '../../Utils.js'
|
||||
import { clamp, jsonToNbt, randomSeed, safeJsonParse } from '../../Utils.js'
|
||||
import { Btn, BtnMenu, NumberInput } from '../index.js'
|
||||
import { ItemDisplay } from '../ItemDisplay.jsx'
|
||||
import { ItemDisplay1204 } from '../ItemDisplay1204.jsx'
|
||||
@@ -40,10 +40,7 @@ export const LootTablePreview = ({ docAndNode }: PreviewProps) => {
|
||||
return []
|
||||
}
|
||||
const [itemTags, lootTables, itemComponents, enchantments, enchantmentTags] = dependencies
|
||||
let table = {}
|
||||
try {
|
||||
table = JSON.parse(text)
|
||||
} catch (e) {}
|
||||
const table = safeJsonParse(text) ?? {}
|
||||
if (use1204) {
|
||||
return generateLootTable1204(table, {
|
||||
version, seed, luck, daytime, weather,
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useVersion } from '../../contexts/index.js'
|
||||
import { useAsync } from '../../hooks/useAsync.js'
|
||||
import { AsyncCancel } from '../../hooks/useAsyncFn.js'
|
||||
import { getResources, ResourceWrapper } from '../../services/Resources.js'
|
||||
import { safeJsonParse } from '../../Utils.js'
|
||||
import type { PreviewProps } from './index.js'
|
||||
import { InteractiveCanvas3D } from './InteractiveCanvas3D.jsx'
|
||||
|
||||
@@ -19,7 +20,7 @@ export const ModelPreview = ({ docAndNode, shown }: PreviewProps) => {
|
||||
const { value: resources } = useAsync(async () => {
|
||||
if (!shown) return AsyncCancel
|
||||
const resources = await getResources(version)
|
||||
const blockModel = BlockModel.fromJson(JSON.parse(text))
|
||||
const blockModel = BlockModel.fromJson(safeJsonParse(text) ?? {})
|
||||
blockModel.flatten(resources)
|
||||
const wrapper = new ResourceWrapper(resources, {
|
||||
getBlockDefinition(id) {
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { mat3 } from 'gl-matrix'
|
||||
import { useCallback, useMemo, useRef, useState } from 'preact/hooks'
|
||||
import { useLocale } from '../../contexts/index.js'
|
||||
import { Store } from '../../Store.js'
|
||||
import { iterateWorld2D, randomSeed } from '../../Utils.js'
|
||||
import { iterateWorld2D, randomSeed, safeJsonParse } from '../../Utils.js'
|
||||
import { Btn } from '../index.js'
|
||||
import type { ColormapType } from './Colormap.js'
|
||||
import { getColormap } from './Colormap.js'
|
||||
@@ -19,7 +19,7 @@ export const NoisePreview = ({ docAndNode, shown }: PreviewProps) => {
|
||||
|
||||
const noise = useMemo(() => {
|
||||
const random = XoroshiroRandom.create(seed)
|
||||
const params = NoiseParameters.fromJson(JSON.parse(text))
|
||||
const params = NoiseParameters.fromJson(safeJsonParse(text) ?? {})
|
||||
return new NormalNoise(random, params)
|
||||
}, [text, seed])
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import { getProjectData, useLocale, useProject, useVersion } from '../../context
|
||||
import { useAsync } from '../../hooks/index.js'
|
||||
import { fetchRegistries } from '../../services/index.js'
|
||||
import { Store } from '../../Store.js'
|
||||
import { iterateWorld2D, randomSeed } from '../../Utils.js'
|
||||
import { iterateWorld2D, randomSeed, safeJsonParse } from '../../Utils.js'
|
||||
import { Btn, BtnInput, BtnMenu, ErrorPanel } from '../index.js'
|
||||
import type { ColormapType } from './Colormap.js'
|
||||
import { getColormap } from './Colormap.js'
|
||||
@@ -26,7 +26,7 @@ export const NoiseSettingsPreview = ({ docAndNode, shown }: PreviewProps) => {
|
||||
const text = docAndNode.doc.getText()
|
||||
|
||||
const { value, error } = useAsync(async () => {
|
||||
const data = JSON.parse(text)
|
||||
const data = safeJsonParse(text) ?? {}
|
||||
await DEEPSLATE.loadVersion(version, getProjectData(project))
|
||||
const biomeSource = { type: 'fixed', biome }
|
||||
await DEEPSLATE.loadChunkGenerator(data, biomeSource, seed)
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useLocale, useVersion } from '../../contexts/index.js'
|
||||
import { useAsync } from '../../hooks/useAsync.js'
|
||||
import type { VersionId } from '../../services/index.js'
|
||||
import { checkVersion, fetchAllPresets } from '../../services/index.js'
|
||||
import { jsonToNbt } from '../../Utils.js'
|
||||
import { jsonToNbt, safeJsonParse } from '../../Utils.js'
|
||||
import { Btn, BtnMenu } from '../index.js'
|
||||
import { ItemDisplay } from '../ItemDisplay.jsx'
|
||||
import type { PreviewProps } from './index.js'
|
||||
@@ -30,13 +30,13 @@ export const RecipePreview = ({ docAndNode }: PreviewProps) => {
|
||||
}, [])
|
||||
|
||||
const text = docAndNode.doc.getText()
|
||||
const recipe = JSON.parse(text)
|
||||
const recipe = safeJsonParse(text) ?? {}
|
||||
const items = useMemo<Map<Slot, ItemStack>>(() => {
|
||||
return placeItems(version, recipe, animation, itemTags ?? new Map())
|
||||
}, [text, animation, itemTags])
|
||||
|
||||
const gui = useMemo(() => {
|
||||
const type = recipe.type?.replace(/^minecraft:/, '')
|
||||
const type = recipe?.type?.replace(/^minecraft:/, '')
|
||||
if (type === 'smelting' || type === 'blasting' || type === 'smoking' || type === 'campfire_cooking') {
|
||||
return '/images/furnace.png'
|
||||
} else if (type === 'stonecutting') {
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useCallback, useMemo, useRef, useState } from 'preact/hooks'
|
||||
import { useLocale, useVersion } from '../../contexts/index.js'
|
||||
import { useAsync } from '../../hooks/useAsync.js'
|
||||
import type { Color } from '../../Utils.js'
|
||||
import { computeIfAbsent, iterateWorld2D, randomSeed, stringToColor } from '../../Utils.js'
|
||||
import { computeIfAbsent, iterateWorld2D, randomSeed, safeJsonParse, stringToColor } from '../../Utils.js'
|
||||
import { Btn } from '../index.js'
|
||||
import { featureColors } from './Decorator.js'
|
||||
import { DEEPSLATE } from './Deepslate.js'
|
||||
@@ -21,7 +21,7 @@ export const StructureSetPreview = ({ docAndNode, shown }: PreviewProps) => {
|
||||
|
||||
const { value: structureSet } = useAsync(async () => {
|
||||
await DEEPSLATE.loadVersion(version)
|
||||
const structureSet = DEEPSLATE.loadStructureSet(JSON.parse(text), seed)
|
||||
const structureSet = DEEPSLATE.loadStructureSet(safeJsonParse(text) ?? {}, seed)
|
||||
return structureSet
|
||||
}, [text, version, seed])
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { createContext } from 'preact'
|
||||
import { useCallback, useContext } from 'preact/hooks'
|
||||
import { useLocalStorage } from '../hooks/index.js'
|
||||
import type { Color } from '../Utils.js'
|
||||
import { safeJsonParse } from '../Utils.js'
|
||||
|
||||
interface Store {
|
||||
biomeColors: Record<string, [number, number, number]>
|
||||
@@ -19,7 +20,7 @@ export function useStore() {
|
||||
}
|
||||
|
||||
export function StoreProvider({ children }: { children: ComponentChildren }) {
|
||||
const [biomeColors, setBiomeColors] = useLocalStorage<Record<string, Color>>('misode_biome_colors', {}, JSON.parse, JSON.stringify)
|
||||
const [biomeColors, setBiomeColors] = useLocalStorage<Record<string, Color>>('misode_biome_colors', {}, s => safeJsonParse(s) ?? {}, JSON.stringify)
|
||||
|
||||
const setBiomeColor = useCallback((biome: string, color: Color) => {
|
||||
setBiomeColors({...biomeColors, [biome]: color })
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { NbtTag } from 'deepslate'
|
||||
import { Identifier, ItemStack } from 'deepslate'
|
||||
import { safeJsonParse } from '../Utils.js'
|
||||
|
||||
export class ResolvedItem extends ItemStack {
|
||||
|
||||
@@ -108,11 +109,7 @@ export class ResolvedItem extends ItemStack {
|
||||
public getLore() {
|
||||
return this.get('lore', tag => {
|
||||
return tag.isList() ? tag.map(e => {
|
||||
try {
|
||||
return JSON.parse(e.getAsString())
|
||||
} catch (e) {
|
||||
return { text: '(invalid lore line)' }
|
||||
}
|
||||
return safeJsonParse(e.getAsString()) ?? { text: '(invalid lore line)' }
|
||||
}) : []
|
||||
}) ?? []
|
||||
}
|
||||
@@ -153,11 +150,7 @@ export class ResolvedItem extends ItemStack {
|
||||
public getHoverName() {
|
||||
const customName = this.get('custom_name', tag => tag.isString() ? tag.getAsString() : undefined)
|
||||
if (customName) {
|
||||
try {
|
||||
return JSON.parse(customName)
|
||||
} catch (e) {
|
||||
return '(invalid custom name)'
|
||||
}
|
||||
return safeJsonParse(customName) ?? '(invalid custom name)'
|
||||
}
|
||||
|
||||
const bookTitle = this.get('written_book_content', tag => tag.isCompound() ? (tag.hasCompound('title') ? tag.getCompound('title').getString('raw') : tag.getString('title')) : undefined)
|
||||
@@ -167,11 +160,7 @@ export class ResolvedItem extends ItemStack {
|
||||
|
||||
const itemName = this.get('item_name', tag => tag.isString() ? tag.getAsString() : undefined)
|
||||
if (itemName) {
|
||||
try {
|
||||
return JSON.parse(itemName)
|
||||
} catch (e) {
|
||||
return { text: '(invalid item name)' }
|
||||
}
|
||||
return safeJsonParse(itemName) ?? { text: '(invalid item name)' }
|
||||
}
|
||||
|
||||
const guess = this.id.path
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import lz from 'lz-string'
|
||||
import { safeJsonParse } from '../Utils.js'
|
||||
import type { VersionId } from './Versions.js'
|
||||
|
||||
const API_PREFIX = 'https://snippets.misode.workers.dev'
|
||||
|
||||
const ShareCache = new Map<string, string>()
|
||||
|
||||
export async function shareSnippet(type: string, version: VersionId, jsonData: any, show_preview: boolean) {
|
||||
export async function shareSnippet(type: string, version: VersionId, text: string, show_preview: boolean) {
|
||||
try {
|
||||
const raw = JSON.stringify(jsonData)
|
||||
const data = lz.compressToBase64(raw)
|
||||
const data = lz.compressToBase64(text)
|
||||
const body = JSON.stringify({ data, type, version, show_preview })
|
||||
let id = ShareCache.get(body)
|
||||
if (!id) {
|
||||
@@ -16,7 +16,7 @@ export async function shareSnippet(type: string, version: VersionId, jsonData: a
|
||||
ShareCache.set(body, snippet.id)
|
||||
id = snippet.id as string
|
||||
}
|
||||
return { id, length: raw.length, compressed: data.length, rate: raw.length / data.length }
|
||||
return { id, length: text.length, compressed: data.length, rate: text.length / data.length }
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
e.message = `Error creating share link: ${e.message}`
|
||||
@@ -30,7 +30,7 @@ export async function getSnippet(id: string) {
|
||||
const snippet = await fetchApi(`/${id}`)
|
||||
return {
|
||||
...snippet,
|
||||
data: JSON.parse(lz.decompressFromBase64(snippet.data) ?? '{}'),
|
||||
data: safeJsonParse(lz.decompressFromBase64(snippet.data) ?? '{}') ?? {},
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { NbtTag } from 'deepslate'
|
||||
import yaml from 'js-yaml'
|
||||
import { Store } from '../Store.js'
|
||||
import { jsonToNbt } from '../Utils.js'
|
||||
import { jsonToNbt, safeJsonParse } from '../Utils.js'
|
||||
|
||||
const INDENTS: Record<string, number | string | undefined> = {
|
||||
'2_spaces': 2,
|
||||
@@ -21,7 +21,7 @@ const FORMATS: Record<string, {
|
||||
snbt: {
|
||||
parse: (s) => JSON.stringify(NbtTag.fromString(s).toSimplifiedJson(), null, 2),
|
||||
stringify: (s, i) => {
|
||||
const tag = jsonToNbt(JSON.parse(s))
|
||||
const tag = jsonToNbt(safeJsonParse(s) ?? {})
|
||||
if (i === undefined) {
|
||||
return tag.toString()
|
||||
}
|
||||
@@ -30,7 +30,7 @@ const FORMATS: Record<string, {
|
||||
},
|
||||
yaml: {
|
||||
parse: (s) => JSON.stringify(yaml.load(s), null, 2),
|
||||
stringify: (s, i) => yaml.dump(JSON.parse(s), {
|
||||
stringify: (s, i) => yaml.dump(safeJsonParse(s) ?? {}, {
|
||||
flowLevel: i === undefined ? 0 : -1,
|
||||
indent: typeof i === 'string' ? 4 : i,
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user