diff --git a/README.md b/README.md index 66593b5ec41dc3eda4dcabe6e545dc0cb4985c8c..cb89a05ca57317be423e05415fdd6cd0589bbfc8 100644 --- a/README.md +++ b/README.md @@ -508,4 +508,4 @@ Run the following command after making any changes to the base code: ``` yarn run qjs ``` -This script needs to be run as compilation for quickjs requires several direct changes to the code. \ No newline at end of file +This script needs to be run because compilation for quickjs requires several direct changes to the code. \ No newline at end of file diff --git a/src/commands/1.0,1.1/index.ts b/src/commands/1.0,1.1/index.ts index bc09adfdc7ce0b2570020efa0ae7402cd9a9f7f5..ff8b4c56321a3362fc00224b01800f62466f9a1f 100644 --- a/src/commands/1.0,1.1/index.ts +++ b/src/commands/1.0,1.1/index.ts @@ -1,21 +1 @@ -import get from "./get"; -import set from "./set"; -import add from "./add"; -import del from "./del"; -import operate from "./operate"; -import supported from "./supported"; -import proto from "./proto"; -import instances from "./instances"; -import notify from "./notify"; - -export default { - GET: get, - ADD: add, - DELETE: del, - GET_INSTANCES: instances, - GET_SUPPORTED_DM: supported, - GET_SUPPORTED_PROTO: proto, - NOTIFY: notify, - OPERATE: operate, - SET: set, -}; +export default {}; diff --git a/src/commands/1.0,1.1/operate.ts b/src/commands/1.0,1.1/operate.ts deleted file mode 100644 index 1dbbbe7dd0e11ee5d3cd2df3fb7ac1744ba78756..0000000000000000000000000000000000000000 --- a/src/commands/1.0,1.1/operate.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from "../common/operate"; \ No newline at end of file diff --git a/src/commands/1.0,1.1/proto.ts b/src/commands/1.0,1.1/proto.ts deleted file mode 100644 index cc691e9264a7433d44094eb422307e23626851e6..0000000000000000000000000000000000000000 --- a/src/commands/1.0,1.1/proto.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { DecodeFn, EncodeFn } from "../../types"; -import * as util from "../util"; - -const decode: DecodeFn = (msg) => { - const results = util.search(msg, "agentSupportedProtocolVersions"); - return [results.split(",")]; -}; - -const encode: EncodeFn = ({ proto }) => ({ - lookup: "Msg", - header: { - msgId: util.uniq("GET_SUPPORTED_PROTO@"), - msgType: "GET_SUPPORTED_PROTO", - lookup: "Header", - }, - body: { - lookup: "Body", - request: { - lookup: "Request", - getSupportedProtocol: { - controllerSupportedProtocolVersions: proto || "", - }, - }, - }, -}); - -export default { - decode, - encode, -}; diff --git a/src/commands/1.0,1.1/set.ts b/src/commands/1.0,1.1/set.ts deleted file mode 100644 index 22d6ab3c1214e52682805875594624ba2226aa26..0000000000000000000000000000000000000000 --- a/src/commands/1.0,1.1/set.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { - DecodeFn, - EncodeFn, - SetLookupUpdateObject, - SetLookupUpdateParamSetting, -} from "../../types"; -import * as util from "../util"; -import { decode as commonDecode } from "../common/set"; - -const decode = commonDecode; - -const isObject = (v) => - typeof v === "object" && v.required !== undefined && v.value !== undefined; - -const makePairs = (path: string, value): [string, any, boolean][] => - path.endsWith(".") && typeof value === "object" && value !== null - ? Object.entries(value as any[]).map(([k, v]) => - isObject(v) - ? [k, v.value.toString(), "required" in v && Boolean(v.required)] - : [k, v.toString(), true] - ) - : [[path.split(".").pop() || "", (value || "").toString(), true]]; - -const encode: EncodeFn = ({ value, path: initialPath }) => { - const paths = Array.isArray(initialPath) ? initialPath : [initialPath]; - const values = value ? (Array.isArray(value) ? value : [value]) : []; - const allowPartial = - (values && values.some((it) => it.allowPartial)) || false; - - const updateObjs = paths.map((path, i) => ({ - lookup: "Set.UpdateObject" as SetLookupUpdateObject, - objPath: path.endsWith(".") - ? path - : path.slice(0, path.lastIndexOf(".") + 1), - paramSettings: makePairs(path, values[i]) - .filter(([k]) => k !== "allowPartial") - .map(([param, value, required]) => ({ - lookup: "Set.UpdateParamSetting" as SetLookupUpdateParamSetting, - param, - value, - required, - })), - })); - - return { - lookup: "Msg", - header: { - lookup: "Header", - msgId: util.uniq("SET@"), - msgType: "SET", - }, - body: { - lookup: "Body", - request: { - lookup: "Request", - set: { - allowPartial, - updateObjs, - }, - }, - }, - }; -}; - -export default { - decode, - encode, -}; diff --git a/src/commands/1.2/add.ts b/src/commands/1.2/add.ts deleted file mode 100644 index 96a18df49998e6b23c8eacbd169cddc91c10a58d..0000000000000000000000000000000000000000 --- a/src/commands/1.2/add.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { DecodeFn, EncodeFn } from "../../types"; -import * as util from "../util"; -import { AddLookupCreateObject, AddLookupCreateParamSetting } from "../../types"; - -const decode: DecodeFn = (msg) => { - const paths: string[] | undefined = util.searchAll(msg, "instantiatedPath"); - if (paths && paths.length === 1) return [paths[0]]; - return [paths]; -}; - -const isObj = (v) => - typeof v === "object" && v.required !== undefined && v.value !== undefined; - -const makePair = (value): [string, any, boolean][] => - value - ? Object.entries(value as any[]).map(([k, v]) => - isObj(v) - ? [k, v.value.toString(), "required" in v && Boolean(v.required)] - : [k, v.toString(), true] - ) - : []; - -const encode: EncodeFn = ({ value, path }) => { - const paths = Array.isArray(path) ? path : [path]; - const values = value ? (Array.isArray(value) ? value : [value]) : []; - const allowPartial = values && values.some((it) => it.allowPartial) || false; - - const createObjs = paths.map((path, i) => ({ - lookup: "Add.CreateObject" as AddLookupCreateObject, - objPath: path, - paramSettings: makePair(values[i]) - .filter(([k]) => k !== "allowPartial") - .map(([param, value, required]) => ({ - lookup: "Add.CreateParamSetting" as AddLookupCreateParamSetting, - param, - value, - required, - })), - })); - - return { - lookup: "Msg", - header: { - lookup: "Header", - msgId: util.uniq("ADD@"), - msgType: "ADD", - }, - body: { - lookup: "Body", - request: { - lookup: "Request", - add: { - allowPartial, - createObjs, - }, - }, - }, - }; -}; - -export default { - decode, - encode, -}; diff --git a/src/commands/1.2/del.ts b/src/commands/1.2/del.ts deleted file mode 100644 index 77bab504e95f5506da03363c8e4d42bde5aa3e6a..0000000000000000000000000000000000000000 --- a/src/commands/1.2/del.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { DecodeFn, EncodeFn } from "../../types"; -import { uniq, searchAll } from "../util"; - -const decode: DecodeFn = (msg) => { - const affectedPaths = searchAll(msg, "affectedPaths") || []; - return [affectedPaths]; -}; - -const encode: EncodeFn = ({ paths, allowPartial }) => ({ - lookup: "Msg", - header: { - msgId: uniq("DELETE@"), - msgType: "DELETE", - lookup: "Header", - }, - body: { - lookup: "Body", - request: { - lookup: "Request", - delete: { - objPaths: Array.isArray(paths) ? paths : [paths], - allowPartial: allowPartial || false - }, - }, - }, -}); - -export default { - decode, - encode -}; diff --git a/src/commands/1.2/get.ts b/src/commands/1.2/get.ts deleted file mode 100644 index 71e73225a179dd8a68df9ac872fc7dc616e03c29..0000000000000000000000000000000000000000 --- a/src/commands/1.2/get.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { DecodeFn, EncodeFn } from "../../types"; -import * as util from "../util"; - -const decode: DecodeFn = (msg, decodeOptions) => { - const reqPathResults = util.search(msg, "reqPathResults"); - if (decodeOptions?.raw) return [reqPathResults]; - if (reqPathResults) { - return [ - util.processGetResult(reqPathResults as util.PathResult[], decodeOptions), - ]; - } - return [null]; -}; - -const encode: EncodeFn = ({ paths, options }) => ({ - lookup: "Msg", - header: { - msgId: util.uniq("GET@"), - msgType: "GET", - lookup: "Header", - }, - body: { - lookup: "Body", - request: { - lookup: "Request", - get: { - paramPaths: Array.isArray(paths) ? paths : [paths], - maxDepth: options?.max_depth || 2, - }, - }, - }, -}); - -export default { - decode, - encode, -}; diff --git a/src/commands/1.2/index.ts b/src/commands/1.2/index.ts index bc09adfdc7ce0b2570020efa0ae7402cd9a9f7f5..ff8b4c56321a3362fc00224b01800f62466f9a1f 100644 --- a/src/commands/1.2/index.ts +++ b/src/commands/1.2/index.ts @@ -1,21 +1 @@ -import get from "./get"; -import set from "./set"; -import add from "./add"; -import del from "./del"; -import operate from "./operate"; -import supported from "./supported"; -import proto from "./proto"; -import instances from "./instances"; -import notify from "./notify"; - -export default { - GET: get, - ADD: add, - DELETE: del, - GET_INSTANCES: instances, - GET_SUPPORTED_DM: supported, - GET_SUPPORTED_PROTO: proto, - NOTIFY: notify, - OPERATE: operate, - SET: set, -}; +export default {}; diff --git a/src/commands/1.2/instances.ts b/src/commands/1.2/instances.ts deleted file mode 100644 index 11d274e4809b6034c9f188b5a93f95a6b99e30e6..0000000000000000000000000000000000000000 --- a/src/commands/1.2/instances.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { DecodeFn, EncodeFn } from "../../types"; -import * as util from "../util"; - -const decode: DecodeFn = (msg) => { - const results = util.search(msg, "reqPathResults"); - return [results]; -}; - -const encode: EncodeFn = ({ paths, opts = {} }) => ({ - lookup: "Msg", - header: { - msgId: util.uniq("GET_INSTANCES@"), - msgType: "GET_INSTANCES", - lookup: "Header", - }, - body: { - lookup: "Body", - request: { - lookup: "Request", - getInstances: { - objPaths: Array.isArray(paths) ? paths : [paths], - firstLevelOnly: opts.firstLevelOnly || false - }, - }, - }, -}); - -export default { - decode, - encode -}; diff --git a/src/commands/1.2/notify.ts b/src/commands/1.2/notify.ts deleted file mode 100644 index 25ac2f963cc6eb7d0422d59479771404d4980e5c..0000000000000000000000000000000000000000 --- a/src/commands/1.2/notify.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { DecodeFn, EncodeFn } from "../../types"; -import * as util from "../util"; - -const parseInfo = (key: string, data: Record<string, any>) => - util.unflatten( - util.search(data, key === "operComplete" ? "outputArgs" : key) || {} - ); - -const decode: DecodeFn = (msg) => { - const parent = util.searchParent(msg, "subscriptionId"); - if (parent) { - const id = parent.subscriptionId; - const relField = Object.keys(parent).find((k) => k !== "subscriptionId"); - return id && relField - ? [parseInfo(relField, msg), id, null] - : [null, id, null]; - } - return [null]; -}; - -const encode: EncodeFn = ({ paths }) => ({ - lookup: "Msg", - header: { - msgId: util.uniq("NOTIFY@"), - msgType: "GET", - lookup: "Header", - }, - body: { - lookup: "Body", - request: { - lookup: "Request", - get: { - paramPaths: Array.isArray(paths) ? paths : [paths], - }, - }, - }, -}); - -export default { - decode, - encode, -}; diff --git a/src/commands/1.2/operate.ts b/src/commands/1.2/operate.ts deleted file mode 100644 index 1dbbbe7dd0e11ee5d3cd2df3fb7ac1744ba78756..0000000000000000000000000000000000000000 --- a/src/commands/1.2/operate.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from "../common/operate"; \ No newline at end of file diff --git a/src/commands/1.2/set.ts b/src/commands/1.2/set.ts deleted file mode 100644 index 22d6ab3c1214e52682805875594624ba2226aa26..0000000000000000000000000000000000000000 --- a/src/commands/1.2/set.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { - DecodeFn, - EncodeFn, - SetLookupUpdateObject, - SetLookupUpdateParamSetting, -} from "../../types"; -import * as util from "../util"; -import { decode as commonDecode } from "../common/set"; - -const decode = commonDecode; - -const isObject = (v) => - typeof v === "object" && v.required !== undefined && v.value !== undefined; - -const makePairs = (path: string, value): [string, any, boolean][] => - path.endsWith(".") && typeof value === "object" && value !== null - ? Object.entries(value as any[]).map(([k, v]) => - isObject(v) - ? [k, v.value.toString(), "required" in v && Boolean(v.required)] - : [k, v.toString(), true] - ) - : [[path.split(".").pop() || "", (value || "").toString(), true]]; - -const encode: EncodeFn = ({ value, path: initialPath }) => { - const paths = Array.isArray(initialPath) ? initialPath : [initialPath]; - const values = value ? (Array.isArray(value) ? value : [value]) : []; - const allowPartial = - (values && values.some((it) => it.allowPartial)) || false; - - const updateObjs = paths.map((path, i) => ({ - lookup: "Set.UpdateObject" as SetLookupUpdateObject, - objPath: path.endsWith(".") - ? path - : path.slice(0, path.lastIndexOf(".") + 1), - paramSettings: makePairs(path, values[i]) - .filter(([k]) => k !== "allowPartial") - .map(([param, value, required]) => ({ - lookup: "Set.UpdateParamSetting" as SetLookupUpdateParamSetting, - param, - value, - required, - })), - })); - - return { - lookup: "Msg", - header: { - lookup: "Header", - msgId: util.uniq("SET@"), - msgType: "SET", - }, - body: { - lookup: "Body", - request: { - lookup: "Request", - set: { - allowPartial, - updateObjs, - }, - }, - }, - }; -}; - -export default { - decode, - encode, -}; diff --git a/src/commands/1.2/supported.ts b/src/commands/1.2/supported.ts deleted file mode 100644 index cd3d9ce38eb389f5b7c6dbcf73aa59d90dc91988..0000000000000000000000000000000000000000 --- a/src/commands/1.2/supported.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { DecodeFn, EncodeFn } from "../../types"; -import * as util from "../util"; - -const decode: DecodeFn = (msg) => { - const results = util.search(msg, "reqObjResults"); - return [results]; -}; - -const encode: EncodeFn = ({ paths, opts = {} }) => ({ - lookup: "Msg", - header: { - msgId: util.uniq("GET_SUPPORTED_DM@"), - msgType: "GET_SUPPORTED_DM", - lookup: "Header", - }, - body: { - lookup: "Body", - request: { - lookup: "Request", - getSupportedDm: { - objPaths: Array.isArray(paths) ? paths : [paths], - firstLevelOnly: opts.firstLevelOnly || false, - returnCommands: opts.returnCommands || false, - returnEvents: opts.returnEvents || false, - returnParams: opts.returnParams || false, - }, - }, - }, -}); - -export default { - decode, - encode -}; diff --git a/src/commands/1.0,1.1/add.ts b/src/commands/common/add.ts similarity index 100% rename from src/commands/1.0,1.1/add.ts rename to src/commands/common/add.ts diff --git a/src/commands/1.0,1.1/del.ts b/src/commands/common/del.ts similarity index 100% rename from src/commands/1.0,1.1/del.ts rename to src/commands/common/del.ts diff --git a/src/commands/1.0,1.1/get.ts b/src/commands/common/get.ts similarity index 100% rename from src/commands/1.0,1.1/get.ts rename to src/commands/common/get.ts diff --git a/src/commands/common/index.ts b/src/commands/common/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..2414d099c317411af58673444880165fbc39ccc7 --- /dev/null +++ b/src/commands/common/index.ts @@ -0,0 +1,21 @@ +import get from "./get"; +import set from "./set"; +import add from "./add"; +import del from "./del"; +import operate from "./operate"; +import supported from "./supported"; +import proto from "./proto"; +import instances from "./instances"; +import notify from "./notify"; + +export default { + GET: get, + GET_INSTANCES: instances, + GET_SUPPORTED_DM: supported, + GET_SUPPORTED_PROTO: proto, + NOTIFY: notify, + ADD: add, + DELETE: del, + OPERATE: operate, + SET: set, +}; diff --git a/src/commands/1.0,1.1/instances.ts b/src/commands/common/instances.ts similarity index 100% rename from src/commands/1.0,1.1/instances.ts rename to src/commands/common/instances.ts diff --git a/src/commands/1.0,1.1/notify.ts b/src/commands/common/notify.ts similarity index 100% rename from src/commands/1.0,1.1/notify.ts rename to src/commands/common/notify.ts diff --git a/src/commands/1.2/proto.ts b/src/commands/common/proto.ts similarity index 100% rename from src/commands/1.2/proto.ts rename to src/commands/common/proto.ts diff --git a/src/commands/common/set.ts b/src/commands/common/set.ts index 67ee6c4d3acb0cbefa0929df95d8896bb0a53689..31fede982d86b210395569ee840f6c7f53d3604f 100644 --- a/src/commands/common/set.ts +++ b/src/commands/common/set.ts @@ -1,8 +1,71 @@ import { DecodeFn } from "../../types"; import { searchAll } from "../util"; +import { + EncodeFn, + SetLookupUpdateObject, + SetLookupUpdateParamSetting, +} from "../../types"; +import * as util from "../util"; -export const decode: DecodeFn = (msg, decodeOptions) => { - if (decodeOptions?.raw) return [msg] +const decode: DecodeFn = (msg, decodeOptions) => { + if (decodeOptions?.raw) return [msg]; const affected = searchAll(msg, "updatedInstResults"); return [affected]; }; +const isObject = (v) => + typeof v === "object" && v.required !== undefined && v.value !== undefined; + +const makePairs = (path: string, value): [string, any, boolean][] => + path.endsWith(".") && typeof value === "object" && value !== null + ? Object.entries(value as any[]).map(([k, v]) => + isObject(v) + ? [k, v.value.toString(), "required" in v && Boolean(v.required)] + : [k, v.toString(), true] + ) + : [[path.split(".").pop() || "", (value || "").toString(), true]]; + +const encode: EncodeFn = ({ value, path: initialPath }) => { + const paths = Array.isArray(initialPath) ? initialPath : [initialPath]; + const values = value ? (Array.isArray(value) ? value : [value]) : []; + const allowPartial = + (values && values.some((it) => it.allowPartial)) || false; + + const updateObjs = paths.map((path, i) => ({ + lookup: "Set.UpdateObject" as SetLookupUpdateObject, + objPath: path.endsWith(".") + ? path + : path.slice(0, path.lastIndexOf(".") + 1), + paramSettings: makePairs(path, values[i]) + .filter(([k]) => k !== "allowPartial") + .map(([param, value, required]) => ({ + lookup: "Set.UpdateParamSetting" as SetLookupUpdateParamSetting, + param, + value, + required, + })), + })); + + return { + lookup: "Msg", + header: { + lookup: "Header", + msgId: util.uniq("SET@"), + msgType: "SET", + }, + body: { + lookup: "Body", + request: { + lookup: "Request", + set: { + allowPartial, + updateObjs, + }, + }, + }, + }; +}; + +export default { + decode, + encode, +}; diff --git a/src/commands/1.0,1.1/supported.ts b/src/commands/common/supported.ts similarity index 100% rename from src/commands/1.0,1.1/supported.ts rename to src/commands/common/supported.ts diff --git a/src/commands/index.ts b/src/commands/index.ts index d38dec5ed39fb70f6081645719540c630601643e..23101291be1668478450dfba52bf31de7daa2228 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -2,7 +2,6 @@ import { extractCommand, makeBuffer, search, searchParent } from "./util"; import { CommandType, CallFn, - CommandObject, PbRequestMessage, RecipeObject, OnFn, @@ -10,6 +9,7 @@ import { Proto, DecodeOptions, USPVersion, + CommandObject, } from "../types"; import resolve from "./recipes/resolve"; @@ -18,13 +18,22 @@ import subscribe from "./recipes/subscribe"; import v10 from "./1.0,1.1"; import v12 from "./1.2"; +import common from "./common"; + +// Note: version files are empty for now, they used to be necessary but were later made obsolete. I still keep them around in case version specific changes crop up again. -const commands: Record<USPVersion, Record<CommandType, CommandObject>> = { +const versionSpecificCommands = { "1.0": v10, "1.1": v10, "1.2": v12, }; +const getCommand = ( + version: USPVersion, + commandType: CommandType +): CommandObject | null => + versionSpecificCommands[version][commandType] || common[commandType] || null; + const recipes: RecipeObject[] = [resolve as any, operateRecipe, subscribe]; export const makeRecipes = (call: CallFn, on: OnFn): any => @@ -57,7 +66,7 @@ export const decode: DecodeFn = (parsedMsg, version: USPVersion) => { const err = searchParent(parsedMsg, "errMsg") || null; const command = extractCommand(parsedMsg); const foundId = search(parsedMsg, "msgId"); - + // if id is formatted by me (command@) then use, otherwise check for sub id const id = foundId.includes("@") ? foundId @@ -67,7 +76,7 @@ export const decode: DecodeFn = (parsedMsg, version: USPVersion) => { if (!command) return unkownErr(parsedMsg); if (err) return [id, null, err, command]; - const cmd: CommandObject | null = commands[version][command] || null; + const cmd: CommandObject | null = getCommand(version, command); if (!cmd) return unkownErr(parsedMsg); const [decodedData, decodedId, decodedErr] = cmd.decode(parsedMsg); @@ -87,8 +96,7 @@ export const decodeWithOptions: DecodeWithOptionsFn = ( options, version: USPVersion ) => { - const cmd: CommandObject | null = - commands[version][cmdType as CommandType] || null; + const cmd: CommandObject | null = getCommand(version, cmdType as CommandType); if (!cmd) return unkownErr(parsedMsg); if (options.raw) return parsedMsg; @@ -104,7 +112,7 @@ export const makeEncode = version: USPVersion, args: Record<string, any> ): [string, any, string | null] => { - const cmd = commands[version][command] || null; + const cmd = getCommand(version, command); if (!cmd) return ["error", null, `Uknown command: ${command}`]; return [...convert(proto, cmd.encode(args), options)]; };