Spaces:
Build error
Build error
/* eslint-disable no-undef */ | |
const formatMessage = require('format-message'); | |
const BlockType = require('../../extension-support/block-type'); | |
const ArgumentType = require('../../extension-support/argument-type'); | |
const Cast = require('../../util/cast'); | |
const { | |
validateJSON, | |
validateArray, | |
stringToEqivalint, | |
valueToString, | |
validateRegex | |
} = require('../../util/json-block-utilities'); | |
// const Cast = require('../../util/cast'); | |
/** | |
* Class for JSON blocks | |
* @constructor | |
*/ | |
class JgJSONBlocks { | |
constructor (runtime) { | |
/** | |
* The runtime instantiating this block package. | |
* @type {Runtime} | |
*/ | |
this.runtime = runtime; | |
} | |
/** | |
* @returns {object} metadata for this extension and its blocks. | |
*/ | |
getInfo () { | |
return { | |
id: 'jgJSON', | |
name: 'JSON', | |
color1: '#0FBD8C', | |
color2: '#0EAF82', | |
blocks: [ | |
{ | |
opcode: 'json_validate', | |
blockType: BlockType.BOOLEAN, | |
arguments: { | |
json: { | |
type: ArgumentType.STRING, | |
defaultValue: "{}" | |
} | |
}, | |
text: 'is json [json] valid?' | |
}, | |
"---", | |
{ | |
opcode: 'getValueFromJSON', | |
text: formatMessage({ | |
id: 'jgJSON.blocks.getValueFromJSON', | |
default: 'get [VALUE] from [JSON]', | |
description: 'Gets a value from a JSON object.' | |
}), | |
disableMonitor: true, | |
blockType: BlockType.REPORTER, | |
arguments: { | |
VALUE: { | |
type: ArgumentType.STRING, | |
defaultValue: formatMessage({ | |
id: 'jgJSON.getValueFromJSON_value', | |
default: 'key', | |
description: 'The name of the item you want to get from the JSON.' | |
}) | |
}, | |
JSON: { | |
type: ArgumentType.STRING, | |
defaultValue: '{"key": "value"}' | |
} | |
} | |
}, | |
{ | |
opcode: 'getTreeValueFromJSON', | |
text: 'get path [VALUE] from [JSON]', | |
disableMonitor: true, | |
blockType: BlockType.REPORTER, | |
arguments: { | |
VALUE: { | |
type: ArgumentType.STRING, | |
defaultValue: 'first/second' | |
}, | |
JSON: { | |
type: ArgumentType.STRING, | |
defaultValue: '{"first": {"second": 2, "third": 3}}' | |
} | |
} | |
}, | |
{ | |
opcode: 'setValueToKeyInJSON', | |
text: formatMessage({ | |
id: 'jgJSON.blocks.setValueToKeyInJSON', | |
default: 'set [KEY] to [VALUE] in [JSON]', | |
description: 'Returns the JSON with the key set to the value.' | |
}), | |
disableMonitor: true, | |
blockType: BlockType.REPORTER, | |
arguments: { | |
VALUE: { | |
type: ArgumentType.STRING, | |
defaultValue: formatMessage({ | |
id: 'jgJSON.setValueToKeyInJSON_value', | |
default: 'value', | |
description: 'The value of the key you are setting.' | |
}) | |
}, | |
KEY: { | |
type: ArgumentType.STRING, | |
defaultValue: formatMessage({ | |
id: 'jgJSON.setValueToKeyInJSON_key', | |
default: 'key', | |
description: 'The key you are setting in the JSON.' | |
}) | |
}, | |
JSON: { | |
type: ArgumentType.STRING, | |
defaultValue: "{}" | |
} | |
} | |
}, | |
{ | |
opcode: 'json_delete', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
json: { | |
type: ArgumentType.STRING, | |
defaultValue: "{}" | |
}, | |
key: { | |
type: ArgumentType.STRING, | |
defaultValue: formatMessage({ | |
id: 'jgJSON.setValueToKeyInJSON_key', | |
default: 'key', | |
description: 'The key you are setting in the JSON.' | |
}) | |
} | |
}, | |
text: 'in json [json] delete key [key]' | |
}, | |
{ | |
opcode: 'json_values', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
json: { | |
type: ArgumentType.STRING, | |
defaultValue: "{}" | |
} | |
}, | |
text: 'get all values from json [json]' | |
}, | |
{ | |
opcode: 'json_keys', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
json: { | |
type: ArgumentType.STRING, | |
defaultValue: "{}" | |
} | |
}, | |
text: 'get all keys from json [json]' | |
}, | |
{ | |
opcode: 'json_has', | |
blockType: BlockType.BOOLEAN, | |
arguments: { | |
json: { | |
type: ArgumentType.STRING, | |
defaultValue: "{}" | |
}, | |
key: { | |
type: ArgumentType.STRING, | |
defaultValue: formatMessage({ | |
id: 'jgJSON.setValueToKeyInJSON_key', | |
default: 'key', | |
description: 'The key you are setting in the JSON.' | |
}) | |
} | |
}, | |
text: 'json [json] has key [key] ?' | |
}, | |
{ | |
opcode: 'json_combine', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
one: { | |
type: ArgumentType.STRING, | |
defaultValue: "{}" | |
}, | |
two: { | |
type: ArgumentType.STRING, | |
defaultValue: "{}" | |
} | |
}, | |
text: 'combine json [one] and json [two]' | |
}, | |
{ | |
blockType: BlockType.LABEL, | |
text: "Arrays" | |
}, | |
{ | |
opcode: 'json_array_validate', | |
blockType: BlockType.BOOLEAN, | |
arguments: { | |
array: { | |
type: ArgumentType.STRING, | |
defaultValue: "[]" | |
} | |
}, | |
text: 'is array [array] valid?' | |
}, | |
{ | |
opcode: 'json_array_split', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
text: { | |
type: ArgumentType.STRING, | |
defaultValue: "A, B, C" | |
}, | |
delimeter: { | |
type: ArgumentType.STRING, | |
defaultValue: ', ' | |
} | |
}, | |
text: 'create an array from text [text] with delimeter [delimeter]' | |
}, | |
{ | |
opcode: 'json_array_join', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
array: { | |
type: ArgumentType.STRING, | |
defaultValue: "[\"A\", \"B\", \"C\"]" | |
}, | |
delimeter: { | |
type: ArgumentType.STRING, | |
defaultValue: ', ' | |
} | |
}, | |
text: 'create text from array [array] with delimeter [delimeter]' | |
}, | |
"---", | |
{ | |
opcode: 'json_array_push', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
array: { | |
type: ArgumentType.STRING, | |
defaultValue: "[\"A\", \"B\", \"C\"]" | |
}, | |
item: { | |
type: ArgumentType.STRING, | |
defaultValue: formatMessage({ | |
id: 'jgJSON.setValueToKeyInJSON_value', | |
default: 'value', | |
description: 'The value of the key you are setting.' | |
}) | |
} | |
}, | |
text: 'in array [array] add [item]' | |
}, | |
"---", | |
{ | |
opcode: 'json_array_concatLayer1', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
array1: { | |
type: ArgumentType.STRING, | |
defaultValue: "[\"A\", \"B\", \"C\"]" | |
}, | |
array2: { | |
type: ArgumentType.STRING, | |
defaultValue: "[\"D\", \"E\", \"F\"]" | |
} | |
}, | |
text: 'add items from array [array2] to array [array1]' | |
}, | |
{ | |
opcode: 'json_array_concatLayer2', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
array1: { | |
type: ArgumentType.STRING, | |
defaultValue: "[\"A\", \"B\", \"C\"]" | |
}, | |
array2: { | |
type: ArgumentType.STRING, | |
defaultValue: "[\"D\", \"E\", \"F\"]" | |
}, | |
array3: { | |
type: ArgumentType.STRING, | |
defaultValue: "[\"G\", \"H\", \"I\"]" | |
} | |
}, | |
text: 'add items from array [array2] and array [array3] to array [array1]' | |
}, | |
"---", | |
{ | |
opcode: 'json_array_delete', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
array: { | |
type: ArgumentType.STRING, | |
defaultValue: "[\"A\", \"B\", \"C\"]" | |
}, | |
index: { | |
type: ArgumentType.NUMBER, | |
defaultValue: 2 | |
} | |
}, | |
text: 'in array [array] delete [index]' | |
}, | |
{ | |
opcode: 'json_array_reverse', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
array: { | |
type: ArgumentType.STRING, | |
defaultValue: "[\"A\", \"B\", \"C\"]" | |
} | |
}, | |
text: 'reverse array [array]' | |
}, | |
{ | |
opcode: 'json_array_insert', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
array: { | |
type: ArgumentType.STRING, | |
defaultValue: "[\"A\", \"B\", \"C\"]" | |
}, | |
index: { | |
type: ArgumentType.NUMBER, | |
defaultValue: 2 | |
}, | |
value: { | |
type: ArgumentType.STRING, | |
defaultValue: formatMessage({ | |
id: 'jgJSON.setValueToKeyInJSON_value', | |
default: 'value', | |
description: 'The value of the key you are setting.' | |
}) | |
} | |
}, | |
text: 'in array [array] insert [value] at [index]' | |
}, | |
{ | |
opcode: 'json_array_set', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
array: { | |
type: ArgumentType.STRING, | |
defaultValue: "[\"A\", \"B\", \"C\"]" | |
}, | |
index: { | |
type: ArgumentType.NUMBER, | |
defaultValue: 2 | |
}, | |
value: { | |
type: ArgumentType.STRING, | |
defaultValue: formatMessage({ | |
id: 'jgJSON.setValueToKeyInJSON_value', | |
default: 'value', | |
description: 'The value of the key you are setting.' | |
}) | |
} | |
}, | |
text: 'in array [array] set [index] to [value]' | |
}, | |
"---", | |
{ | |
opcode: 'json_array_get', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
array: { | |
type: ArgumentType.STRING, | |
defaultValue: "[\"A\", \"B\", \"C\"]" | |
}, | |
index: { | |
type: ArgumentType.NUMBER, | |
defaultValue: 2 | |
} | |
}, | |
text: 'in array [array] get [index]' | |
}, | |
{ | |
opcode: 'json_array_indexofNostart', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
array: { | |
type: ArgumentType.STRING, | |
defaultValue: "[\"A\", \"B\", \"C\"]" | |
}, | |
value: { | |
type: ArgumentType.STRING, | |
defaultValue: "value" | |
} | |
}, | |
text: 'in array [array] get index of [value]' | |
}, | |
{ | |
opcode: 'json_array_indexof', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
array: { | |
type: ArgumentType.STRING, | |
defaultValue: "[\"A\", \"B\", \"C\"]" | |
}, | |
number: { | |
type: ArgumentType.NUMBER, | |
defaultValue: 2 | |
}, | |
value: { | |
type: ArgumentType.STRING, | |
defaultValue: formatMessage({ | |
id: 'jgJSON.setValueToKeyInJSON_value', | |
default: 'value', | |
description: 'The value of the key you are setting.' | |
}) | |
} | |
}, | |
text: 'in array [array] from [number] get index of [value]' | |
}, | |
{ | |
opcode: 'json_array_length', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
array: { | |
type: ArgumentType.STRING, | |
defaultValue: "[\"A\", \"B\", \"C\"]" | |
} | |
}, | |
text: 'length of array [array]' | |
}, | |
{ | |
opcode: 'json_array_contains', | |
blockType: BlockType.BOOLEAN, | |
arguments: { | |
array: { | |
type: ArgumentType.STRING, | |
defaultValue: "[\"A\", \"B\", \"C\"]" | |
}, | |
value: { | |
type: ArgumentType.STRING, | |
defaultValue: formatMessage({ | |
id: 'jgJSON.setValueToKeyInJSON_value', | |
default: 'value', | |
description: 'The value of the key you are setting.' | |
}) | |
} | |
}, | |
text: 'array [array] contains [value] ?' | |
}, | |
"---", | |
{ | |
opcode: 'json_array_flat', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
array: { | |
type: ArgumentType.STRING, | |
defaultValue: "[[\"A\", \"B\"], [\"C\", \"D\"]]" | |
}, | |
layer: { | |
type: ArgumentType.NUMBER, | |
defaultValue: 1 | |
} | |
}, | |
text: 'flatten nested array [array] by [layer] layers' | |
}, | |
"---", | |
{ | |
opcode: 'json_array_getrange', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
array: { | |
type: ArgumentType.STRING, | |
defaultValue: "[\"A\", \"B\", \"C\"]" | |
}, | |
index1: { | |
type: ArgumentType.NUMBER, | |
defaultValue: 2 | |
}, | |
index2: { | |
type: ArgumentType.NUMBER, | |
defaultValue: 2 | |
} | |
}, | |
text: 'in array [array] get all items from [index1] to [index2]' | |
}, | |
"---", | |
{ | |
opcode: 'json_array_isempty', | |
blockType: BlockType.BOOLEAN, | |
arguments: { | |
array: { | |
type: ArgumentType.STRING, | |
defaultValue: "[\"A\", \"B\", \"C\"]" | |
} | |
}, | |
text: 'is array [array] empty?' | |
}, | |
"---", | |
{ | |
opcode: 'json_array_listtoarray', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
list: { | |
type: ArgumentType.STRING, | |
defaultValue: 'select a list', | |
menu: 'lists' | |
} | |
}, | |
hideFromPalette: true, | |
text: 'get contents of list [list] as array' | |
}, | |
{ | |
opcode: 'json_array_tolist', | |
blockType: BlockType.COMMAND, | |
arguments: { | |
list: { | |
type: ArgumentType.STRING, | |
defaultValue: 'select a list', | |
menu: 'lists' | |
}, | |
array: { | |
type: ArgumentType.STRING, | |
defaultValue: "[\"A\", \"B\", \"C\"]" | |
} | |
}, | |
hideFromPalette: true, | |
text: 'set contents of list [list] to contents of array [array]' | |
} | |
], | |
menus: { | |
lists: 'getAllLists' | |
} | |
}; | |
} | |
getAllLists () { | |
const variables = [].concat( | |
Object.values(vm.runtime.getTargetForStage().variables), | |
Object.values(vm.editingTarget.variables) | |
); | |
const lists = variables.filter(i => i.type === 'list'); | |
if (lists.length === 0) { | |
return [ | |
{ | |
text: 'select a list', | |
value: 'select a list' | |
} | |
]; | |
} | |
return lists.map(i => ({ | |
text: i.name, | |
value: JSON.stringify({ | |
id: i.id, | |
name: i.name | |
}) | |
})); | |
} | |
getValueFromJSON (args) { | |
const key = args.VALUE; | |
const json = validateJSON(args.JSON).object; | |
return valueToString(json[key]); | |
} | |
getTreeValueFromJSON (args) { | |
const tree = Cast.toString(args.VALUE); | |
let _json; | |
if (Cast.toString(args.JSON).startsWith('[')) { | |
_json = validateArray(args.JSON).array; | |
} else { | |
_json = validateJSON(args.JSON).object; | |
} | |
const json = _json; | |
if (!tree.includes('/')) { | |
// if we dont have a slash, treat it like | |
// the get value block | |
if (Array.isArray(json)) { | |
return this.json_array_get({ | |
array: Cast.toString(args.JSON), | |
index: Cast.toNumber(args.VALUE) | |
}); | |
} | |
return this.getValueFromJSON(args); | |
} | |
let value = ''; | |
let currentObject = json; | |
const treeSplit = tree.split('/'); | |
for (const key of treeSplit) { | |
value = ''; | |
// check for array so we can do "object/array/3/value" | |
if (Array.isArray(currentObject)) { | |
currentObject = currentObject[Cast.toNumber(key)]; | |
value = currentObject; | |
continue; | |
} | |
if (typeof currentObject === 'object') { | |
currentObject = currentObject[key]; | |
value = currentObject; | |
} else { | |
value = currentObject; | |
} | |
} | |
if (typeof value === "undefined") return ''; | |
return valueToString(value); | |
} | |
setValueToKeyInJSON (args) { | |
const json = validateJSON(args.JSON).object; | |
const key = args.KEY; | |
const value = args.VALUE; | |
json[key] = stringToEqivalint(value); | |
return JSON.stringify(json); | |
} | |
json_has (args) { | |
const json = validateJSON(args.json).object; | |
const key = args.key; | |
return json.hasOwnProperty(key); | |
} | |
json_delete (args) { | |
const json = validateJSON(args.json).object; | |
const key = args.key; | |
if (!json.hasOwnProperty(key)) return JSON.stringify(json); | |
delete json[key]; | |
return JSON.stringify(json); | |
} | |
json_values (args) { | |
const json = validateJSON(args.json).object; | |
return JSON.stringify(Object.values(json)); | |
} | |
json_keys (args) { | |
const json = validateJSON(args.json).object; | |
return JSON.stringify(Object.keys(json)); | |
} | |
json_array_length (args) { | |
const array = validateArray(args.array).array; | |
return array.length; | |
} | |
json_array_isempty (args) { | |
const array = validateArray(args.array).array; | |
return !array.length; | |
} | |
json_array_contains (args) { | |
const array = validateArray(args.array).array; | |
const value = args.value; | |
return array.includes(stringToEqivalint(value)); | |
} | |
json_array_reverse (args) { | |
const array = validateArray(args.array).array; | |
return JSON.stringify(array.reverse()); | |
} | |
json_array_indexof (args) { | |
const array = validateArray(args.array).array; | |
const number = args.number; | |
const value = args.value; | |
return array.indexOf(stringToEqivalint(value), number); | |
} | |
json_array_indexofNostart (args) { | |
const array = validateArray(args.array).array; | |
const value = args.value; | |
return array.indexOf(stringToEqivalint(value)); | |
} | |
json_array_set (args) { | |
const array = validateArray(args.array).array; | |
const index = args.index; | |
const value = args.value; | |
array[index] = stringToEqivalint(value); | |
return JSON.stringify(array); | |
} | |
json_array_insert (args) { | |
const array = validateArray(args.array).array; | |
const index = args.index; | |
const value = args.value; | |
array.splice(index, 0, stringToEqivalint(value)); | |
return JSON.stringify(array); | |
} | |
json_array_get (args) { | |
const array = validateArray(args.array).array; | |
const index = args.index; | |
return valueToString(array[index]); | |
} | |
json_array_getrange (args) { | |
const array = validateArray(args.array).array; | |
const index1 = args.index1; | |
const index2 = args.index2; | |
return JSON.stringify(array.slice(index1, index2)); | |
} | |
json_array_push (args) { | |
const array = validateArray(args.array).array; | |
const value = args.item; | |
array.push(stringToEqivalint(value)); | |
return JSON.stringify(array); | |
} | |
json_array_concatLayer1 (args) { | |
const array1 = validateArray(args.array1).array; | |
const array2 = validateArray(args.array2).array; | |
const array = array1.concat(array2); | |
return JSON.stringify(array); | |
} | |
json_array_concatLayer2 (args) { | |
const array1 = validateArray(args.array1).array; | |
const array2 = validateArray(args.array2).array; | |
const array3 = validateArray(args.array3).array; | |
const array = array1.concat(array2, array3); | |
return JSON.stringify(array); | |
} | |
json_array_flat (args) { | |
const array = validateArray(args.array).array; | |
const depth = Cast.toNumber(args.layer); | |
const flattened = array.flat(depth); | |
return JSON.stringify(flattened); | |
} | |
json_array_tolist (args, util) { | |
let list; | |
try { | |
list = JSON.parse(args.list); | |
} catch { | |
return; | |
} | |
const array = validateArray(args.array).array; | |
const content = util.target.lookupOrCreateList(list.id, list.name); | |
content.value = array.map(x => valueToString(x)); | |
} | |
json_array_listtoarray (args, util) { | |
let list; | |
try { | |
list = JSON.parse(args.list); | |
} catch { | |
return; | |
} | |
const content = util.target.lookupOrCreateList(list.id, list.name).value; | |
return JSON.stringify(content.map(x => stringToEqivalint(x))); | |
} | |
json_array_delete (args) { | |
const array = validateArray(args.array).array; | |
const index = args.index; | |
array.splice(index, 1); | |
return JSON.stringify(array); | |
} | |
json_array_split (args) { | |
return JSON.stringify(args.text.split(args.delimeter)); | |
} | |
json_array_join (args) { | |
return validateArray(args.array).array.join(args.delimeter); | |
} | |
json_validate (args) { | |
return validateJSON(args.json).isValid; | |
} | |
json_array_validate (args) { | |
return validateArray(args.array).isValid; | |
} | |
json_combine (args) { | |
const one = validateJSON(args.one).object; | |
const two = validateJSON(args.two).object; | |
return JSON.stringify(Object.assign(one, two)); | |
} | |
} | |
module.exports = JgJSONBlocks; | |