{"version":3,"sources":["util.ts"],"names":["PathType","entities","_rcedit","sax","decodeXML","default","encodeXML","defaultValue","value","undefined","defaultNull","defaultFalse","defaultTrue","entryIsEmptyResourceFork","entry","type","RESOURCE_FORK","size","pathRelativeBase","path","start","nocase","p","toLowerCase","s","startsWith","substr","length","pathRelativeBaseMatch","trimExtension","ext","e","endsWith","xmlEntitiesEncode","xmlEntitiesDecode","plistStringTagEncode","plistStringTagDecode","xml","end","contents","substring","infoPlistFind","key","replaceTagStart","replaceTagEnd","parser","tagPath","tags","tag","push","map","o","name","dictTag","keyTag","nextTag","onerror","err","ontext","text","onopentag","node","startTagPosition","onclosetag","position","write","close","infoPlistReplace","found","before","after","infoPlistRead","rcedit","options","opts","iconPath","icon","fileVersion","productVersion","versionStrings"],"mappings":"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","sourcesContent":["import {\n\tEntry,\n\tPathType\n} from '@shockpkg/archive-files';\nimport * as entities from 'entities';\n// @ts-ignore\nimport _rcedit from 'rcedit';\nimport sax from 'sax';\n\n// Handle module loader differences between CJS and ESM.\nconst decodeXML = entities.decodeXML || (entities as any).default.decodeXML;\nconst encodeXML = entities.encodeXML || (entities as any).default.encodeXML;\n\nexport interface IRceditOptionsVersionStrings {\n\t[key: string]: string;\n}\n\nexport interface IRceditOptions {\n\n\t/**\n\t * Icon path.\n\t *\n\t * @default null\n\t */\n\ticonPath?: string | null;\n\n\t/**\n\t * File version.\n\t *\n\t * @default null\n\t */\n\tfileVersion?: string | null;\n\n\t/**\n\t * Product version.\n\t *\n\t * @default null\n\t */\n\tproductVersion?: string | null;\n\n\t/**\n\t * Version strings.\n\t *\n\t * @default null\n\t */\n\tversionStrings?: IRceditOptionsVersionStrings | null;\n}\n\n/**\n * Default value if value is undefined.\n *\n * @param value Value.\n * @param defaultValue Default value.\n * @returns Value or the default value if undefined.\n */\nexport function defaultValue<T, U>(\n\tvalue: T,\n\tdefaultValue: U\n): Exclude<T | U, undefined> {\n\t// eslint-disable-next-line no-undefined\n\treturn value === undefined ? defaultValue : (value as any);\n}\n\n/**\n * Default null if value is undefined.\n *\n * @param value Value.\n * @returns Value or null if undefined.\n */\nexport function defaultNull<T>(value: T) {\n\treturn defaultValue(value, null);\n}\n\n/**\n * Default false if value is undefined.\n *\n * @param value Value.\n * @returns Value or false if undefined.\n */\nexport function defaultFalse<T>(value: T) {\n\treturn defaultValue(value, false);\n}\n\n/**\n * Default true if value is undefined.\n *\n * @param value Value.\n * @returns Value or true if undefined.\n */\nexport function defaultTrue<T>(value: T) {\n\treturn defaultValue(value, true);\n}\n\n/**\n * Check if Archive Entry is empty resource fork.\n *\n * @param entry Archive Entry.\n * @returns Is empty resource fork.\n */\nexport function entryIsEmptyResourceFork(entry: Entry) {\n\treturn entry.type === PathType.RESOURCE_FORK && !entry.size;\n}\n\n/**\n * Find path relative from base, if base matches.\n *\n * @param path Path to match against.\n * @param start Search start.\n * @param nocase Match case-insensitive.\n * @returns Returns path, or null.\n */\nexport function pathRelativeBase(\n\tpath: string,\n\tstart: string,\n\tnocase = false\n) {\n\tconst p = nocase ? path.toLowerCase() : path;\n\tconst s = nocase ? start.toLowerCase() : start;\n\tif (p === s) {\n\t\treturn '';\n\t}\n\tif (p.startsWith(`${s}/`)) {\n\t\treturn path.substr(s.length + 1);\n\t}\n\treturn null;\n}\n\n/**\n * Same as pathRelativeBase, but retuns true on a match, else false.\n *\n * @param path Path to match against.\n * @param start Search start.\n * @param nocase Match case-insensitive.\n * @returns Returns true on match, else false.\n */\nexport function pathRelativeBaseMatch(\n\tpath: string,\n\tstart: string,\n\tnocase = false\n) {\n\tconst p = nocase ? path.toLowerCase() : path;\n\tconst s = nocase ? start.toLowerCase() : start;\n\tif (p === s) {\n\t\treturn true;\n\t}\n\tif (p.startsWith(`${s}/`)) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n/**\n * Trim a file extenion.\n *\n * @param path File path.\n * @param ext File extension.\n * @param nocase Match case-insensitive.\n * @returns Path without file extension.\n */\nexport function trimExtension(\n\tpath: string,\n\text: string,\n\tnocase = false\n) {\n\tconst p = nocase ? path.toLowerCase() : path;\n\tconst e = nocase ? ext.toLowerCase() : ext;\n\treturn p.endsWith(e) ? path.substr(0, p.length - e.length) : path;\n}\n\n/**\n * Encode string for XML.\n *\n * @param value String value.\n * @returns Escaped string.\n */\nexport function xmlEntitiesEncode(value: string) {\n\treturn encodeXML(value);\n}\n\n/**\n * Decode string for XML.\n *\n * @param value Encoded value.\n * @returns Decoded string.\n */\nexport function xmlEntitiesDecode(value: string) {\n\treturn decodeXML(value);\n}\n\n/**\n * Encode string into plist string tag.\n *\n * @param value String value.\n * @returns Plist string.\n */\nexport function plistStringTagEncode(value: string) {\n\treturn `<string>${xmlEntitiesEncode(value)}</string>`;\n}\n\n/**\n * Decode string from plist string tag.\n *\n * @param xml XML tag.\n * @returns Plain string, or null.\n */\nexport function plistStringTagDecode(xml: string) {\n\tconst start = '<string>';\n\tconst end = '</string>';\n\tif (!xml.startsWith(start) || !xml.endsWith(end)) {\n\t\treturn null;\n\t}\n\tconst contents = xml.substring(start.length, xml.length - end.length);\n\treturn xmlEntitiesDecode(contents);\n}\n\n/**\n * A small helper function for finding Info.plist values.\n *\n * @param xml XML string.\n * @param key Plist dict key.\n * @returns Found indexes or null.\n */\nfunction infoPlistFind(\n\txml: string,\n\tkey: string\n) {\n\tlet replaceTagStart = -1;\n\tlet replaceTagEnd = -1;\n\n\tconst parser = sax.parser(true, {});\n\n\t// Get the tag path in a consistent way.\n\tconst tagPath = () => {\n\t\tconst tags = [...(parser as any).tags];\n\t\tconst {tag} = (parser as any);\n\t\tif (tag && tags[tags.length - 1] !== tag) {\n\t\t\ttags.push(tag);\n\t\t}\n\t\treturn tags.map(o => o.name as string);\n\t};\n\n\tconst dictTag = () => {\n\t\tconst path = tagPath();\n\t\tif (\n\t\t\tpath.length !== 3 ||\n\t\t\tpath[0] !== 'plist' ||\n\t\t\tpath[1] !== 'dict'\n\t\t) {\n\t\t\treturn null;\n\t\t}\n\t\treturn path[2];\n\t};\n\n\tlet keyTag = false;\n\tlet nextTag = false;\n\n\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\tparser.onerror = err => {\n\t\tthrow err;\n\t};\n\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\tparser.ontext = text => {\n\t\tif (keyTag && text === key) {\n\t\t\tnextTag = true;\n\t\t}\n\t};\n\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\tparser.onopentag = node => {\n\t\tconst tag = dictTag();\n\t\tif (!tag) {\n\t\t\treturn;\n\t\t}\n\t\tif (tag === 'key') {\n\t\t\tkeyTag = true;\n\t\t\treturn;\n\t\t}\n\t\tif (!nextTag) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (replaceTagStart < 0) {\n\t\t\treplaceTagStart = parser.startTagPosition - 1;\n\t\t}\n\t};\n\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\tparser.onclosetag = node => {\n\t\tconst tag = dictTag();\n\t\tif (!tag) {\n\t\t\treturn;\n\t\t}\n\t\tif (tag === 'key') {\n\t\t\tkeyTag = false;\n\t\t\treturn;\n\t\t}\n\t\tif (!nextTag) {\n\t\t\treturn;\n\t\t}\n\t\tnextTag = false;\n\n\t\tif (replaceTagEnd < 0) {\n\t\t\treplaceTagEnd = parser.position;\n\t\t}\n\t};\n\n\tparser.write(xml).close();\n\n\treturn (replaceTagStart < 0 || replaceTagEnd < 0) ?\n\t\tnull :\n\t\t[replaceTagStart, replaceTagEnd];\n}\n\n/**\n * A small utility function for replacing Info.plist values.\n *\n * @param xml XML string.\n * @param key Plist dict key.\n * @param value Plist dict value, XML tag.\n * @returns Updated document.\n */\nexport function infoPlistReplace(\n\txml: string,\n\tkey: string,\n\tvalue: string\n) {\n\tconst found = infoPlistFind(xml, key);\n\tif (!found) {\n\t\treturn xml;\n\t}\n\t// Splice in new value.\n\tconst before = xml.substr(0, found[0]);\n\tconst after = xml.substr(found[1]);\n\treturn `${before}${value}${after}`;\n}\n\n/**\n * A small utility function for reading Info.plist values.\n *\n * @param xml XML string.\n * @param key Plist dict key.\n * @returns XML tag.\n */\nexport function infoPlistRead(\n\txml: string,\n\tkey: string\n) {\n\tconst found = infoPlistFind(xml, key);\n\treturn found ? xml.substring(found[0], found[1]) : null;\n}\n\n/**\n * Uses rcedit to edit the resources of a Windows EXE.\n * Requires either Windows or wine in the path.\n *\n * @param path File path.\n * @param options Options object.\n */\nexport async function rcedit(\n\tpath: string,\n\toptions: IRceditOptions\n) {\n\tconst opts: {[key: string]: any} = {};\n\tif (options.iconPath) {\n\t\topts.icon = options.iconPath;\n\t}\n\tif (typeof options.fileVersion === 'string') {\n\t\topts['file-version'] = options.fileVersion;\n\t}\n\tif (typeof options.productVersion === 'string') {\n\t\topts['product-version'] = options.productVersion;\n\t}\n\tif (options.versionStrings) {\n\t\topts['version-string'] = options.versionStrings;\n\t}\n\tawait _rcedit(path, opts);\n}\n"],"file":"util.mjs","sourceRoot":"../src"}