disable vite plugin, delete more dead files
This commit is contained in:
parent
a5a8a078d5
commit
3c9df96d01
13 changed files with 3 additions and 718 deletions
|
|
@ -1,110 +0,0 @@
|
|||
import { glob } from 'glob'
|
||||
import { compact, keyBy, keys, map, omitBy, sortBy, without } from 'lodash-es'
|
||||
|
||||
import { toBlockJSON } from './block_processor/index.js'
|
||||
|
||||
|
||||
// server-side
|
||||
// gathers all block definition files in /app/blocks
|
||||
// passes each definition and its path through block processor
|
||||
// returns a collection of the resulting json
|
||||
|
||||
// files
|
||||
const
|
||||
PROJECT_ROOT = process.cwd(),
|
||||
BLOCK_LOCATION = `app/blocks/`,
|
||||
NON_BLOCK_FILES = [
|
||||
'**/*extension*.js',
|
||||
'**/*mixin*.js',
|
||||
'**/*mutator*.js',
|
||||
'**/*shadow*.js',
|
||||
'**/*example*.js',
|
||||
],
|
||||
|
||||
gatherBlockFiles = async () => {
|
||||
const
|
||||
jsfiles = await glob(`./${BLOCK_LOCATION}**/*.js`, { ignore: NON_BLOCK_FILES }),
|
||||
random = Math.random()*100000000 // break the import cache
|
||||
|
||||
return Promise.all(
|
||||
jsfiles.map(
|
||||
async filePath => ({
|
||||
definition: (await import(`${PROJECT_ROOT}/${filePath}?key=${random}`)).default,
|
||||
path: filePath.slice(BLOCK_LOCATION.length)
|
||||
})
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// definitions
|
||||
const
|
||||
BLOCK_KEYS = [
|
||||
"type",
|
||||
"name",
|
||||
"primaryCategory",
|
||||
"color",
|
||||
"bytecodeKey",
|
||||
"inputs",
|
||||
"fields",
|
||||
"template",
|
||||
"description",
|
||||
"docBlocks",
|
||||
"disabled",
|
||||
"generators",
|
||||
"regenerators",
|
||||
"toolbox",
|
||||
"visualization",
|
||||
"mixins",
|
||||
"extensions",
|
||||
"mutator",
|
||||
"connections",
|
||||
"lines"
|
||||
],
|
||||
|
||||
processBlock = ({ definition, path }) => {
|
||||
if(!definition) {
|
||||
throw new Error(`No Block definition found at path: ${BLOCK_LOCATION}${path}`)
|
||||
}
|
||||
|
||||
// ensure only supported keys are present
|
||||
const extraKeys = without(keys(definition), ...BLOCK_KEYS)
|
||||
|
||||
if(extraKeys.length) {
|
||||
throw new Error(`Custom Block definition has unrecognized keys: "${extraKeys.join('", "')}"\nBlock: ${definition.type} @ ${path}`)
|
||||
}
|
||||
|
||||
if(definition.disabled) { return }
|
||||
|
||||
// TODO: mechanism for Definition JSON defaults
|
||||
if(definition.connections?.mode === 'value') {
|
||||
// default input values with no output to 'expression'
|
||||
definition.connections.output = definition.connections.output || 'expression'
|
||||
}
|
||||
|
||||
// TODO: mechanism for Blockly JSON defaults
|
||||
const blockDefaults = {
|
||||
inputsInline: false
|
||||
}
|
||||
|
||||
return {
|
||||
...blockDefaults,
|
||||
...toBlockJSON(definition)
|
||||
}
|
||||
}
|
||||
|
||||
export const
|
||||
importBlockDefinitions = async () =>
|
||||
omitBy(keyBy(map(await gatherBlockFiles(), "definition"), "type"), def => def.disabled),
|
||||
|
||||
importBlockJson = async () =>
|
||||
sortBy(compact(map(await gatherBlockFiles(), processBlock)), "type"),
|
||||
|
||||
// defs and paths
|
||||
allBlockDefinitionsAndPaths = await gatherBlockFiles(),
|
||||
// just the definitions
|
||||
allBlockDefinitions = keyBy(compact(map(allBlockDefinitionsAndPaths, "definition")), "type"),
|
||||
// without disabled definitions
|
||||
blockDefinitions = omitBy(allBlockDefinitions, def => def.disabled),
|
||||
blockJson = compact(map(allBlockDefinitionsAndPaths, processBlock))
|
||||
|
||||
export default blockJson
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
import fs from 'fs'
|
||||
|
||||
import { importToolboxJs } from './toolbox_importer.js'
|
||||
import importMixinsJs from './mixin_importer.js'
|
||||
import importExtensionsJs from './extension_importer.js'
|
||||
import importMutatorsJs from './mutator_importer.js'
|
||||
import importGeneratorsJs from './generator_importer.js'
|
||||
import importRegeneratorsJs from './regenerator_importer.js'
|
||||
|
||||
|
||||
const section = (title, contents) => `
|
||||
///////////
|
||||
// ${title}
|
||||
///////////
|
||||
${contents}
|
||||
`
|
||||
|
||||
export default async () => (
|
||||
[
|
||||
"import Blockly from 'blockly'\n\n",
|
||||
section("Toolbox", importToolboxJs()),
|
||||
section("Mixins", await importMixinsJs()),
|
||||
section("Extensions", await importExtensionsJs()),
|
||||
section("Mutators", await importMutatorsJs()),
|
||||
section("Generators", await importGeneratorsJs()),
|
||||
section("Regenerators", await importRegeneratorsJs()),
|
||||
section("Blockly API Wrapper", fs.readFileSync(`./src/importer/blockly_api.js`))
|
||||
].join("")
|
||||
)
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
import { glob } from 'glob'
|
||||
import { assign, camelCase, fromPairs, isArray } from 'lodash-es'
|
||||
|
||||
import { importBlockDefinitions } from './block_importer.js'
|
||||
import renderTemplate from './template_renderer.js'
|
||||
import renderObject from './object_renderer.js'
|
||||
|
||||
|
||||
const
|
||||
PROJECT_ROOT = process.cwd(),
|
||||
EXTENSION_LOCATION = `app/extensions/`,
|
||||
|
||||
gatherExtensionFiles = async () => {
|
||||
const
|
||||
jsfiles = await glob(`./${EXTENSION_LOCATION}**/*.js`, { ignore: [ '**/*example*.js' ] }),
|
||||
random = Math.random()*100000000 // break the import cache
|
||||
|
||||
// loads app/extensions/extension_name.js into object like:
|
||||
// { extensionName: Function }
|
||||
return fromPairs(await Promise.all(
|
||||
jsfiles.map( async filePath => ([
|
||||
camelCase(filePath.split('/').at(-1).slice(0, -3)),
|
||||
(await import(`${PROJECT_ROOT}/${filePath}?key=${random}`)).default
|
||||
]))
|
||||
))
|
||||
}
|
||||
|
||||
export default async () => {
|
||||
const
|
||||
fileExtensions = await gatherExtensionFiles(),
|
||||
allExtensions = Object.values(await importBlockDefinitions())
|
||||
.map(def => def.extensions)
|
||||
.filter(ext => ext && !isArray(ext))
|
||||
.reduce(assign, fileExtensions)
|
||||
|
||||
|
||||
const renderedExtensions = `const allExtensions = ${ renderObject(allExtensions) }`
|
||||
|
||||
// render the extensions template and return the output
|
||||
return renderTemplate(renderedExtensions, './src/importer/extensions.template.js')
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
import { mapValues } from 'lodash-es'
|
||||
|
||||
import { importBlockDefinitions } from './block_importer.js'
|
||||
import renderTemplate from './template_renderer.js'
|
||||
import renderObject from './object_renderer.js'
|
||||
|
||||
|
||||
export default async () => {
|
||||
const
|
||||
blockGenerators = mapValues(await importBlockDefinitions(), "generators"),
|
||||
renderedGenerators = `const blockGenerators = ${ renderObject(blockGenerators) }`
|
||||
|
||||
// render the generators template and return the output
|
||||
return renderTemplate(renderedGenerators, './src/importer/generators.template.js')
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
import { glob } from 'glob'
|
||||
import { assign, camelCase, fromPairs, isArray, isString } from 'lodash-es'
|
||||
|
||||
import { importBlockDefinitions } from './block_importer.js'
|
||||
import renderTemplate from './template_renderer.js'
|
||||
import renderObject from './object_renderer.js'
|
||||
|
||||
|
||||
const
|
||||
PROJECT_ROOT = process.cwd(),
|
||||
MIXIN_LOCATION = `app/mixins/`,
|
||||
|
||||
gatherMixinFiles = async () => {
|
||||
const
|
||||
jsfiles = await glob(`./${MIXIN_LOCATION}**/*.js`, { ignore: [ '**/*example*.js' ] }),
|
||||
random = Math.random()*100000000 // break the import cache
|
||||
|
||||
// loads app/mixins/mixin_name.js into object like:
|
||||
// { mixinName: Function }
|
||||
return fromPairs(await Promise.all(
|
||||
jsfiles.map( async filePath => ([
|
||||
camelCase(filePath.split('/').at(-1).slice(0, -3)),
|
||||
(await import(`${PROJECT_ROOT}/${filePath}?key=${random}`)).default
|
||||
]))
|
||||
))
|
||||
}
|
||||
|
||||
export default async () => {
|
||||
const
|
||||
allMixins = await gatherMixinFiles(),
|
||||
blockDefMixins = Object.values(await importBlockDefinitions())
|
||||
.map(def => def.mixins)
|
||||
.filter(mix => mix)
|
||||
|
||||
// merge top-level objects and objects nested under arrays
|
||||
blockDefMixins.forEach(mixinDef => {
|
||||
if(isArray(mixinDef)) {
|
||||
mixinDef.forEach( item => {
|
||||
// ignore strings
|
||||
if(!isString(item)) {
|
||||
// assign all the keys of a nested object
|
||||
assign(allMixins, item)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// assign all the keys of a top-level object
|
||||
assign(allMixins, mixinDef)
|
||||
}
|
||||
})
|
||||
|
||||
const renderedMixins = `const allMixins = ${renderObject(allMixins)}`
|
||||
|
||||
// render the mixins template and return the output
|
||||
return renderTemplate(renderedMixins, './src/importer/mixins.template.js')
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
import { mapValues, pickBy } from 'lodash-es'
|
||||
|
||||
import { importBlockDefinitions } from './block_importer.js'
|
||||
import renderTemplate from './template_renderer.js'
|
||||
import renderObject from './object_renderer.js'
|
||||
|
||||
|
||||
export default async () => {
|
||||
// grab the value at the "mutator" key from all block defs, removing nulls
|
||||
const mutators = pickBy(mapValues(await importBlockDefinitions(), "mutator"))
|
||||
// write the javascript into a string
|
||||
const renderedMutators = `const allBlockMutators = ${ renderObject(mutators) }`
|
||||
// render the mutators template and return the output
|
||||
return renderTemplate(renderedMutators, './src/importer/mutators.template.js')
|
||||
}
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
import { compact, forOwn, keys, isString, isFunction, isArray, isNumber, isNull, isObject, isUndefined, map, isRegExp, sortBy } from 'lodash-es'
|
||||
|
||||
|
||||
const
|
||||
TAB = " ",
|
||||
STARTS_WITH_NUM = /^[0-9]/,
|
||||
CONTAINS_NON_ALPHANUM = /[^a-zA-Z0-9_]+/,
|
||||
CONTAINS_UNESCAPED_QUOTE = /(^|[^\\])(\")/g
|
||||
|
||||
const quotedKey = key =>
|
||||
STARTS_WITH_NUM.test(key) || CONTAINS_NON_ALPHANUM.test(key)
|
||||
? `"${key}"`
|
||||
: key
|
||||
|
||||
const renderValue = (value, tab=TAB) => {
|
||||
if (isString(value)) {
|
||||
return renderString(value)
|
||||
|
||||
} else if (isRegExp(value) || isNull(value) || isNumber(value) || isUndefined(value) || value === false) {
|
||||
return value
|
||||
|
||||
} else if (isFunction(value)) {
|
||||
return renderFunction(value, tab)
|
||||
|
||||
} else if (isArray(value)) {
|
||||
return `[ ${value.map(i => renderValue(i, tab+TAB)).join(", ")} ]`
|
||||
|
||||
} else if (isObject(value)) {
|
||||
const lines = []
|
||||
forOwn(value, (val, key) => {
|
||||
lines.push(`${tab}${quotedKey(key)}: ${renderValue(val, tab+TAB)}`)
|
||||
})
|
||||
return `{\n${lines.join(",\n\n")}\n${tab.slice(0, -TAB.length)}}`
|
||||
|
||||
} else {
|
||||
// TODO: what to really do here? maybe caller passes a strategy for missing values
|
||||
// return '{}'
|
||||
throw new Error(`Unexpected value type: ${value}`)
|
||||
}
|
||||
}
|
||||
|
||||
const renderString = stringValue => {
|
||||
// ensure double-quotes are escaped
|
||||
if(CONTAINS_UNESCAPED_QUOTE.test(stringValue)) {
|
||||
stringValue = stringValue.replaceAll(CONTAINS_UNESCAPED_QUOTE, "$1\\$2")
|
||||
}
|
||||
|
||||
return `"${stringValue}"`
|
||||
}
|
||||
|
||||
const renderFunction = (func, indentation=TAB) => {
|
||||
const
|
||||
functionString = func.toString(),
|
||||
// capture whitespace after first newline
|
||||
match = /\n\s*/.exec(functionString)?.[0].slice(1)
|
||||
|
||||
// early out if no newlines in function
|
||||
if(!match) { return functionString }
|
||||
|
||||
const reIndentedFunction = functionString
|
||||
// regex replace \n[measured whitespace] \n[indentation]
|
||||
.replaceAll(`\n${match}`, `\n${indentation}`)
|
||||
// replace last line with 2 less indentation and a closing bracket
|
||||
.replace(/\n.*$/, `\n${indentation.slice(0, -2)}}`)
|
||||
|
||||
return reIndentedFunction
|
||||
}
|
||||
|
||||
const renderObject = object => {
|
||||
const
|
||||
sortedKeys = sortBy(keys(object)),
|
||||
sortedKeyValues = compact(map(sortedKeys, rawKey => {
|
||||
const
|
||||
key = quotedKey(rawKey),
|
||||
value = object[rawKey]
|
||||
|
||||
return isUndefined(value)
|
||||
? null
|
||||
: `${key}: ${renderValue(value, TAB + TAB)}`
|
||||
}))
|
||||
|
||||
return [
|
||||
'{',
|
||||
`${TAB}${sortedKeyValues.join(`,\n\n${TAB}`)}`,
|
||||
'}'
|
||||
].join("\n")
|
||||
}
|
||||
|
||||
export default renderObject
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
import { mapValues } from 'lodash-es'
|
||||
import { importBlockDefinitions } from './block_importer.js'
|
||||
import renderTemplate from './template_renderer.js'
|
||||
import renderObject from './object_renderer.js'
|
||||
|
||||
|
||||
export default async () => {
|
||||
const
|
||||
blockRegenerators = mapValues(await importBlockDefinitions(), "regenerators"),
|
||||
renderedRegenerators = `const blockRegenerators = ${ renderObject(blockRegenerators) }`
|
||||
|
||||
return renderTemplate(renderedRegenerators, './src/importer/regenerators.template.js')
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
import fs from 'fs'
|
||||
|
||||
|
||||
export const renderTemplate = (renderedContent, sourceFilename) => {
|
||||
// read in file contents
|
||||
const existingFileContent = fs.readFileSync(sourceFilename).toString()
|
||||
// return transformed contents
|
||||
return existingFileContent.replace(/\/\* LOCAL->>[\s\S]*?<<-LOCAL \*\//, renderedContent)
|
||||
}
|
||||
|
||||
export default renderTemplate
|
||||
|
|
@ -1,272 +0,0 @@
|
|||
import { compact, forEach, identity, isEmpty, isString, keyBy, keys, map, mapValues, filter, flatMap, pickBy, reduce, without } from 'lodash-es'
|
||||
|
||||
import toolboxConfig from '../../app/toolbox/index.js'
|
||||
import { importBlockDefinitions } from './block_importer.js'
|
||||
import renderTemplate from './template_renderer.js'
|
||||
import renderObject from './object_renderer.js'
|
||||
|
||||
|
||||
const
|
||||
DEBUG = false,
|
||||
WARN = true,
|
||||
log = (...messages) => DEBUG && console.log(...messages),
|
||||
warn = (...messages) => (DEBUG || WARN) && console.warn(...messages),
|
||||
error = (...messages) => DEBUG && console.error(...messages)
|
||||
|
||||
|
||||
export const exportToolboxJSON = toolboxDef => {
|
||||
return {
|
||||
kind: 'categoryToolbox',
|
||||
contents: generateToolboxContents(toolboxDef.contents)
|
||||
}
|
||||
}
|
||||
|
||||
let
|
||||
blockDefinitionsByType = {},
|
||||
blockDefinitionsByCategory = {}
|
||||
|
||||
const
|
||||
importToolbox = async () => {
|
||||
blockDefinitionsByType = await importBlockDefinitions()
|
||||
blockDefinitionsByCategory = reduce(filter(blockDefinitionsByType, "toolbox"), (collection, definition) => {
|
||||
const category = definition.toolbox.category
|
||||
|
||||
if(!collection[category]) {
|
||||
collection[category] = []
|
||||
}
|
||||
|
||||
collection[category].push(definition)
|
||||
|
||||
return collection
|
||||
}, {})
|
||||
|
||||
log(`Processing Toolbox (DEBUG=true)`)
|
||||
|
||||
return buildToolbox()
|
||||
},
|
||||
|
||||
buildToolbox = () => ({
|
||||
kind: 'categoryToolbox',
|
||||
contents: generateToolboxContents(toolboxConfig)
|
||||
}),
|
||||
|
||||
generateToolboxContents = toolboxContents => map(toolboxContents, category => {
|
||||
if(category.name) {
|
||||
return generateCategoryFromDefinition(category)
|
||||
}
|
||||
|
||||
return category
|
||||
}),
|
||||
|
||||
generateCategoryFromDefinition = category => {
|
||||
log(`- "${category.name}"`)
|
||||
|
||||
validateCategoryDefinition(category)
|
||||
|
||||
const
|
||||
contents = generateCategoryContents(category),
|
||||
contentKinds = map(contents, "kind"),
|
||||
blockCount = filter(contentKinds, kind => kind == "block").length,
|
||||
labelCount = filter(contentKinds, kind => kind == "label").length
|
||||
|
||||
log(` - ${blockCount} blocks added`)
|
||||
if(labelCount) {
|
||||
log(` - ${labelCount} labels added`)
|
||||
}
|
||||
|
||||
if(!contents.length && !category.callback) {
|
||||
warn(` - Warning: no blocks generated for category without callback "${category.name}"!`)
|
||||
}
|
||||
|
||||
// inject other kinds of toolbox objects here
|
||||
return {
|
||||
kind: 'category',
|
||||
name: category.name,
|
||||
colour: (category.colour === 0) ? "0" : category.colour,
|
||||
...{
|
||||
custom: category.callback ? category.name : undefined
|
||||
},
|
||||
contents
|
||||
}
|
||||
},
|
||||
|
||||
EXPECTED_TOOLBOX_KEYS = [ "name", "colour", "label", "contents", "callback", "usesBlocks" ],
|
||||
|
||||
validateCategoryDefinition = definition => {
|
||||
const
|
||||
categoryKeys = keys(definition),
|
||||
unexpectedKeys = without(categoryKeys, ...EXPECTED_TOOLBOX_KEYS)
|
||||
|
||||
if(unexpectedKeys.length) {
|
||||
warn(` - Warning: Unexpected toolbox definition keys: "${unexpectedKeys.join(", ")}"`)
|
||||
}
|
||||
|
||||
// callback precludes contents and label
|
||||
if(categoryKeys.includes("callback")) {
|
||||
if(categoryKeys.includes("contents")) {
|
||||
warn(` - Warning: "contents" defined (${definition.contents}) on toolbox category ("${definition.name}") with a "callback" defined.`)
|
||||
}
|
||||
if(categoryKeys.includes("label")) {
|
||||
warn(` - Warning: "contents" defined on toolbox category ("${definition.name}") with a "label" defined.`)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
generateCategoryContents = ({ name, label, contents }) => {
|
||||
const toolboxContents = []
|
||||
|
||||
// prepend category label(s)
|
||||
if(label) {
|
||||
const labelArray = isString(label) ? [label] : label
|
||||
toolboxContents.push(...map(labelArray, makeLabel))
|
||||
}
|
||||
|
||||
// if a category has a contents array, use that
|
||||
if(contents) {
|
||||
log(` - using toolbox def`)
|
||||
|
||||
const definitionContents = typeof contents[0] === "string"
|
||||
? map(contents, findBlockByType)
|
||||
: contents
|
||||
// const blockDefinitions = map(contents, findBlockByType)
|
||||
|
||||
toolboxContents.push(...flatMap(definitionContents, blockDefinition => blockToLabelAndBlock(blockDefinition)))
|
||||
|
||||
warnOnExtraBlocksSpecifyCategory(name, definitionContents)
|
||||
|
||||
// otherwise add blocks by their toolbox.category
|
||||
} else {
|
||||
log(` - using block def`)
|
||||
toolboxContents.push(...flatMap(blockDefinitionsByCategory[name] || [], blockToLabelAndBlock))
|
||||
}
|
||||
|
||||
return toolboxContents
|
||||
},
|
||||
|
||||
warnOnExtraBlocksSpecifyCategory = (categoryName, usedBlocks) => {
|
||||
const blocksToWarn = without(blockDefinitionsByCategory[categoryName], ...usedBlocks)
|
||||
|
||||
if(blocksToWarn.length) {
|
||||
warn(` - Warning: toolbox specifications ignored for blocks: "${map(blocksToWarn, 'type').join('", "')}"`)
|
||||
}
|
||||
},
|
||||
|
||||
findBlockByType = type => {
|
||||
const blockDefinition = blockDefinitionsByType[type]
|
||||
|
||||
if(!blockDefinition) {
|
||||
throw new Error(`No block found with type "${type}".`)
|
||||
}
|
||||
|
||||
return blockDefinition
|
||||
},
|
||||
|
||||
blockToLabelAndBlock = block => compact([
|
||||
{
|
||||
kind: 'block',
|
||||
type: block.type,
|
||||
inputs: blockToInputs(block),
|
||||
fields: blockToFields(block)
|
||||
}, block.toolbox?.label
|
||||
? makeLabel(block.toolbox.label)
|
||||
: null
|
||||
]),
|
||||
|
||||
makeLabel = text => ({ kind: 'label', text }),
|
||||
|
||||
blockToInputs = ({ lines, inputs }) => {
|
||||
if(lines) {
|
||||
const inputValues =
|
||||
mapValues(
|
||||
keyBy(
|
||||
filter(
|
||||
map(lines, '[1]'),
|
||||
"inputValue"),
|
||||
"inputValue"),
|
||||
definitionPropsToInputs)
|
||||
|
||||
return isEmpty(inputValues) ? undefined : inputValues
|
||||
}
|
||||
|
||||
if(inputs) {
|
||||
const inputValues = mapValues(inputs, definitionPropsToInputs)
|
||||
|
||||
return isEmpty(inputValues) ? undefined : inputValues
|
||||
}
|
||||
},
|
||||
|
||||
// produces:
|
||||
// {
|
||||
// FIELD_NAME: field_value,
|
||||
// ...
|
||||
// }
|
||||
blockToFields = ({ lines, fields }) => {
|
||||
if(lines) {
|
||||
// get every field that contains a "value" property
|
||||
const defaultFields =
|
||||
reduce(
|
||||
map(
|
||||
filter(
|
||||
map(lines, '[1]'),
|
||||
"fields"),
|
||||
"fields"),
|
||||
(acc, fields) => {
|
||||
forEach(fields, (field, fieldKey) => {
|
||||
if(field.value){
|
||||
acc[fieldKey] = field.value
|
||||
}
|
||||
})
|
||||
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
return isEmpty(defaultFields) ? undefined : defaultFields
|
||||
}
|
||||
|
||||
if(fields) {
|
||||
const defaultFields = pickBy(mapValues(fields, "value"), identity)
|
||||
|
||||
return isEmpty(defaultFields) ? undefined : defaultFields
|
||||
}
|
||||
},
|
||||
|
||||
definitionPropsToInputs = ({ inputValue, block, shadow }) => {
|
||||
if(!block && !shadow) {
|
||||
console.warn("Warning: no block or shadow specified for", inputValue)
|
||||
return
|
||||
}
|
||||
|
||||
if(block) {
|
||||
const
|
||||
blockJson = blockToInput(block),
|
||||
shadowJson = shadowToInput(shadow || block)
|
||||
|
||||
return {
|
||||
...blockJson,
|
||||
...shadowJson
|
||||
}
|
||||
|
||||
} else if(shadow) {
|
||||
return shadowToInput(shadow)
|
||||
}
|
||||
},
|
||||
|
||||
blockToInput = block => isString(block) // is shorthand?
|
||||
? { block: { type: block }} // expand to full object
|
||||
: { block }, // set as shadow value
|
||||
|
||||
shadowToInput = shadow => isString(shadow) // is shorthand?
|
||||
? { shadow: { type: shadow }} // expand to full object
|
||||
: { shadow } // set as shadow value
|
||||
|
||||
export default importToolbox
|
||||
|
||||
export const importToolboxJs = () => {
|
||||
const
|
||||
categoriesWithCallbacks = filter(toolboxConfig, "callback"),
|
||||
// { "Category Name": () -> { /* category callback */ }}
|
||||
categoriesObject = mapValues(keyBy(categoriesWithCallbacks, "name"), "callback"),
|
||||
renderedCategoryCallbacks = `const categoryCallbacks = ${ renderObject(categoriesObject) }`
|
||||
|
||||
return renderTemplate(renderedCategoryCallbacks, './src/importer/toolbox.template.js')
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
import { find, keys, map } from 'lodash-es'
|
||||
|
||||
import { importBlockJson } from './block_importer.js'
|
||||
import importToolboxJson from './toolbox_importer.js'
|
||||
import importWorkspaceJson from './workspace_importer.js'
|
||||
|
||||
import importBlocklyJs from './blockly_importer.js'
|
||||
|
||||
|
||||
const PROCESSORS = {
|
||||
"/blocks.json": async () => JSON.stringify(await importBlockJson(), null, 2),
|
||||
"/toolbox.json": async () => JSON.stringify(await importToolboxJson(), null, 2),
|
||||
"/workspace.json": async () => JSON.stringify(await importWorkspaceJson(), null, 2),
|
||||
"/blockly_app.js": importBlocklyJs,
|
||||
}
|
||||
const PROCESSED_FILES = keys(PROCESSORS)
|
||||
|
||||
const findAnyProcessor = id => find(PROCESSORS, (_, fileEnding) => id.endsWith(fileEnding))
|
||||
|
||||
const prependVirtual = id => findAnyProcessor(id) && `\0${id}`
|
||||
|
||||
export default function ImportUserAppPlugin() {
|
||||
return {
|
||||
name: 'import-app-files',
|
||||
|
||||
resolveId(id) { return prependVirtual(id) },
|
||||
|
||||
load(id) {
|
||||
const processor = findAnyProcessor(id)
|
||||
|
||||
if(!processor) { return }
|
||||
|
||||
return processor()
|
||||
},
|
||||
|
||||
handleHotUpdate(ctx) {
|
||||
if(ctx.file.includes("/test/")) { return }
|
||||
|
||||
if(!ctx.file.includes('/app/') && !ctx.file.includes('/blockly_api.js')) {
|
||||
return
|
||||
}
|
||||
|
||||
const mods = map(PROCESSED_FILES, file =>
|
||||
ctx.server.moduleGraph.getModuleById(`\0.${file}`))
|
||||
|
||||
return ctx.modules.concat(mods)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
import fs from 'fs'
|
||||
|
||||
|
||||
export default () => {
|
||||
return JSON.parse(fs.readFileSync('./app/workspace/workspace.json'))
|
||||
}
|
||||
|
|
@ -1,16 +1,6 @@
|
|||
import { defineConfig, loadEnv } from 'vite'
|
||||
|
||||
import ImportUserAppPlugin from './src/importer/vite_plugin.js'
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
|
||||
export default defineConfig(({ mode }) => {
|
||||
const
|
||||
env = loadEnv(mode, process.cwd(), ''),
|
||||
plugins = env.NODE_ENV == 'development'
|
||||
? [ ImportUserAppPlugin() ]
|
||||
: []
|
||||
|
||||
return {
|
||||
plugins
|
||||
}
|
||||
export default defineConfig(() => {
|
||||
return {}
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue