Studio: theme editing

This commit is contained in:
Pieter Vander Vennet 2023-10-30 13:45:44 +01:00
parent 6e7eccf9de
commit 3aa9a21dea
34 changed files with 975 additions and 350 deletions

View file

@ -100,7 +100,7 @@ export default class ScriptUtils {
.filter((path) => path.indexOf("license_info.json") < 0)
}
public static getThemeFiles(): { parsed: LayoutConfigJson; path: string }[] {
public static getThemeFiles(): { parsed: LayoutConfigJson; path: string; raw: string }[] {
return this.getThemePaths().map((path) => {
try {
const contents = readFileSync(path, { encoding: "utf8" })
@ -108,7 +108,7 @@ export default class ScriptUtils {
throw "The file " + path + " is empty, did you properly save?"
}
const parsed = JSON.parse(contents)
return { parsed: parsed, path: path }
return { parsed: parsed, path: path, raw: contents }
} catch (e) {
console.error("Could not read file ", path, "due to ", e)
throw e

View file

@ -13,8 +13,8 @@ mkdir dist/assets 2> /dev/null
export NODE_OPTIONS="--max-old-space-size=8192"
# This script ends every line with '&&' to chain everything. A failure will thus stop the build
npm run generate:editor-layer-index &&
npm run generate &&
# npm run generate:editor-layer-index &&
# npm run generate &&
npm run generate:layouts
if [ $? -ne 0 ]; then
@ -24,7 +24,7 @@ fi
SRC_MAPS=""
SRC_MAPS="--sourcemap"
BRANCH=`git rev-parse --abbrev-ref HEAD`
echo "The branch name is $BRANCH"
if [ $BRANCH = "develop" ]
@ -46,6 +46,7 @@ else
fi
export NODE_OPTIONS=--max-old-space-size=7000
which vite
vite build $SRC_MAPS
# Copy the layer files, as these might contain assets (e.g. svgs)
cp -r assets/layers/ dist/assets/layers/

View file

@ -141,7 +141,8 @@ function extractHintsFrom(
description: string,
fieldnames: string[],
path: (string | number)[],
type: any
type: any,
schemepart: any
): Record<string, string> {
if (!description) {
return {}
@ -167,19 +168,28 @@ function extractHintsFrom(
}
if (hints["types"]) {
const notRequired = hints["ifunset"] !== undefined
const numberOfExpectedSubtypes = hints["types"].replaceAll("|", ";").split(";").length
if (!Array.isArray(type)) {
if (!Array.isArray(type) && !notRequired) {
throw (
"At " +
path.join(".") +
"Invalid hint in the documentation: `types` indicates that there are " +
numberOfExpectedSubtypes +
" subtypes, but object does not support subtypes. Did you mean `type` instead?\n\tTypes are: " +
hints["types"]
hints["types"] +
"\n: hints: " +
JSON.stringify(hints) +
" req:" +
JSON.stringify(schemepart)
)
}
const numberOfActualTypes = type.length
if (numberOfActualTypes !== numberOfExpectedSubtypes) {
if (
numberOfActualTypes !== numberOfExpectedSubtypes &&
notRequired &&
numberOfActualTypes + 1 !== numberOfExpectedSubtypes
) {
throw `At ${path.join(
"."
)}\nInvalid hint in the documentation: \`types\` indicates that there are ${numberOfExpectedSubtypes} subtypes, but there are ${numberOfActualTypes} subtypes
@ -213,10 +223,16 @@ function addMetafields(fieldnames: string[], fullSchema: JsonSchema): ConfigMeta
const type = schemePart.items?.anyOf ?? schemePart.type ?? schemePart.anyOf
let description = schemePart.description
let hints = extractHintsFrom(description, fieldnames, path, type)
let hints = extractHintsFrom(description, fieldnames, path, type, schemePart)
const childDescription = schemePart["child-description"]
if (childDescription) {
const childHints = extractHintsFrom(childDescription, fieldnames, path, type)
const childHints = extractHintsFrom(
childDescription,
fieldnames,
path,
type,
schemePart
)
hints = { ...childHints, ...hints }
description = description ?? childDescription
}
@ -299,9 +315,9 @@ function validateMeta(path: ConfigMeta): string | undefined {
}
if (path.hints.question === undefined && !Array.isArray(path.type)) {
/* return (
ctx +
" does not have a question set. As such, MapComplete-studio users will not be able to set this property"
) //*/
ctx +
" does not have a question set. As such, MapComplete-studio users will not be able to set this property"
) //*/
}
return undefined

View file

@ -7,6 +7,7 @@ import {
import Translations from "../src/UI/i18n/Translations"
import { Translation } from "../src/UI/i18n/Translation"
import { LayerConfigJson } from "../src/Models/ThemeConfig/Json/LayerConfigJson"
import { ConversionContext } from "../src/Models/ThemeConfig/Conversion/Conversion"
/*
* This script reads all theme and layer files and reformats them inplace
@ -68,7 +69,7 @@ for (const layerFile of layerFiles) {
const fixed = <LayerConfigJson>(
new UpdateLegacyLayer().convertStrict(
layerFile.parsed,
"While linting " + layerFile.path
ConversionContext.construct([layerFile.path.split("/").at(-1)], ["update legacy"])
)
)
addArticleToPresets(fixed)
@ -83,7 +84,7 @@ for (const themeFile of themeFiles) {
try {
const fixed = new FixLegacyTheme().convertStrict(
themeFile.parsed,
"While linting " + themeFile.path
ConversionContext.construct([themeFile.path.split("/").at(-1)], ["update legacy layer"])
)
for (const layer of fixed.layers) {
if (layer["presets"] !== undefined) {
@ -91,7 +92,11 @@ for (const themeFile of themeFiles) {
}
}
// extractInlineLayer(fixed)
writeFileSync(themeFile.path, JSON.stringify(fixed, null, " "))
const endsWithNewline = themeFile.raw.at(-1) === "\n"
writeFileSync(
themeFile.path,
JSON.stringify(fixed, null, " ") + (endsWithNewline ? "\n" : "")
)
} catch (e) {
console.error("COULD NOT LINT THEME" + themeFile.path + ":\n\t" + e)
}

View file

@ -2,6 +2,7 @@ import * as fs from "node:fs"
import * as http from "node:http"
import * as path from "node:path"
import ScriptUtils from "./ScriptUtils"
import * as meta from "../package.json"
const PORT = 1235
const CORS = "http://localhost:1234,https://mapcomplete.org,https://dev.mapcomplete.org"
@ -115,4 +116,8 @@ http.createServer(async (req, res) => {
}
}).listen(PORT)
console.log(`Server running at http://127.0.0.1:${PORT}/`)
console.log(
`Server started at http://127.0.0.1:${PORT}/, the time is ${new Date().toISOString()}, version from package.json is ${
meta.version
}`
)