hot-updater 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.mjs +1 -1
- package/dist/{fingerprint-D0Q1Sl5G.mjs → fingerprint-DyKBEn51.mjs} +339 -685
- package/dist/index.mjs +2 -2
- package/dist/infra-templates/aws/lambda/index.cjs +1 -1
- package/dist/infra-templates/aws/template.json +10 -10
- package/dist/infra-templates/azure/azure/function/index.mjs +1 -1
- package/dist/infra-templates/azure/template.json +11 -11
- package/dist/infra-templates/cloudflare/template.json +10 -10
- package/dist/infra-templates/cloudflare/worker/dist/README.md +1 -1
- package/dist/infra-templates/cloudflare/worker/dist/index.js +1 -1
- package/dist/infra-templates/cloudflare/worker/dist/index.js.map +1 -1
- package/dist/infra-templates/firebase/firebase/functions/index.cjs +1 -1
- package/dist/infra-templates/firebase/template.json +11 -11
- package/dist/infra-templates/supabase/supabase/functions/hot-updater-v1/_hot-updater/hot-updater-server/dist/package.cjs +1 -1
- package/dist/infra-templates/supabase/supabase/functions/hot-updater-v1/_hot-updater/hot-updater-server/dist/package.mjs +1 -1
- package/dist/infra-templates/supabase/template.json +10 -10
- package/dist/infra-templates/vercel/ENVIRONMENT.md +3 -5
- package/dist/infra-templates/vercel/SETUP.md +14 -11
- package/dist/infra-templates/vercel/app/hot-updater.config.bare.ts +1 -6
- package/dist/infra-templates/vercel/app/hot-updater.config.expo.ts +1 -6
- package/dist/infra-templates/vercel/app/hot-updater.config.rock.ts +1 -6
- package/dist/infra-templates/vercel/app/hotUpdater.ts +1 -6
- package/dist/infra-templates/vercel/template.json +12 -19
- package/dist/infra-templates/vercel/vercel/api/index.mjs +4 -10
- package/package.json +24 -26
|
@@ -67,12 +67,12 @@ const criticalProperties = [
|
|
|
67
67
|
];
|
|
68
68
|
//#endregion
|
|
69
69
|
//#region ../../node_modules/.pnpm/fast-xml-parser@5.7.2/node_modules/fast-xml-parser/src/validator.js
|
|
70
|
-
const defaultOptions$
|
|
70
|
+
const defaultOptions$1 = {
|
|
71
71
|
allowBooleanAttributes: false,
|
|
72
72
|
unpairedTags: []
|
|
73
73
|
};
|
|
74
74
|
function validate(xmlData, options) {
|
|
75
|
-
options = Object.assign({}, defaultOptions$
|
|
75
|
+
options = Object.assign({}, defaultOptions$1, options);
|
|
76
76
|
const tags = [];
|
|
77
77
|
let tagFound = false;
|
|
78
78
|
let reachedRoot = false;
|
|
@@ -1839,7 +1839,7 @@ const defaultOnDangerousProperty = (name) => {
|
|
|
1839
1839
|
if (DANGEROUS_PROPERTY_NAMES.includes(name)) return "__" + name;
|
|
1840
1840
|
return name;
|
|
1841
1841
|
};
|
|
1842
|
-
const defaultOptions
|
|
1842
|
+
const defaultOptions = {
|
|
1843
1843
|
preserveOrder: false,
|
|
1844
1844
|
attributeNamePrefix: "@_",
|
|
1845
1845
|
attributesGroupName: false,
|
|
@@ -1926,7 +1926,7 @@ function normalizeProcessEntities(value, htmlEntities) {
|
|
|
1926
1926
|
return normalizeProcessEntities(true);
|
|
1927
1927
|
}
|
|
1928
1928
|
const buildOptions = function(options) {
|
|
1929
|
-
const built = Object.assign({}, defaultOptions
|
|
1929
|
+
const built = Object.assign({}, defaultOptions, options);
|
|
1930
1930
|
const propertyNameOptions = [
|
|
1931
1931
|
{
|
|
1932
1932
|
value: built.attributeNamePrefix,
|
|
@@ -2509,7 +2509,7 @@ function handleInfinity(str, num, options) {
|
|
|
2509
2509
|
}
|
|
2510
2510
|
//#endregion
|
|
2511
2511
|
//#region ../../node_modules/.pnpm/fast-xml-parser@5.7.2/node_modules/fast-xml-parser/src/ignoreAttributes.js
|
|
2512
|
-
function getIgnoreAttributesFn
|
|
2512
|
+
function getIgnoreAttributesFn(ignoreAttributes) {
|
|
2513
2513
|
if (typeof ignoreAttributes === "function") return ignoreAttributes;
|
|
2514
2514
|
if (Array.isArray(ignoreAttributes)) return (attrName) => {
|
|
2515
2515
|
for (const pattern of ignoreAttributes) {
|
|
@@ -3321,11 +3321,11 @@ var OrderedObjParser = class {
|
|
|
3321
3321
|
this.resolveNameSpace = resolveNameSpace;
|
|
3322
3322
|
this.buildAttributesMap = buildAttributesMap;
|
|
3323
3323
|
this.isItStopNode = isItStopNode;
|
|
3324
|
-
this.replaceEntitiesValue = replaceEntitiesValue
|
|
3324
|
+
this.replaceEntitiesValue = replaceEntitiesValue;
|
|
3325
3325
|
this.readStopNodeData = readStopNodeData;
|
|
3326
3326
|
this.saveTextToParentTag = saveTextToParentTag;
|
|
3327
3327
|
this.addChild = addChild;
|
|
3328
|
-
this.ignoreAttributesFn = getIgnoreAttributesFn
|
|
3328
|
+
this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes);
|
|
3329
3329
|
this.entityExpansionCount = 0;
|
|
3330
3330
|
this.currentExpandedLength = 0;
|
|
3331
3331
|
let namedEntities = { ...XML };
|
|
@@ -3624,7 +3624,7 @@ function addChild(currentNode, childNode, matcher, startIndex) {
|
|
|
3624
3624
|
* @param {string} tagName - Tag name
|
|
3625
3625
|
* @param {string|Matcher} jPath - jPath string or Matcher instance based on options.jPath
|
|
3626
3626
|
*/
|
|
3627
|
-
function replaceEntitiesValue
|
|
3627
|
+
function replaceEntitiesValue(val, tagName, jPath) {
|
|
3628
3628
|
const entityConfig = this.options.processEntities;
|
|
3629
3629
|
if (!entityConfig || !entityConfig.enabled) return val;
|
|
3630
3630
|
if (entityConfig.allowedTags) {
|
|
@@ -3832,7 +3832,7 @@ function compress(arr, options, matcher, readonlyMatcher) {
|
|
|
3832
3832
|
const compressedObj = {};
|
|
3833
3833
|
for (let i = 0; i < arr.length; i++) {
|
|
3834
3834
|
const tagObj = arr[i];
|
|
3835
|
-
const property = propName
|
|
3835
|
+
const property = propName(tagObj);
|
|
3836
3836
|
if (property !== void 0 && property !== options.textNodeName) {
|
|
3837
3837
|
const rawAttrs = stripAttributePrefix(tagObj[":@"] || {}, options.attributeNamePrefix);
|
|
3838
3838
|
matcher.push(property, rawAttrs);
|
|
@@ -3867,7 +3867,7 @@ function compress(arr, options, matcher, readonlyMatcher) {
|
|
|
3867
3867
|
} else if (text !== void 0) compressedObj[options.textNodeName] = text;
|
|
3868
3868
|
return compressedObj;
|
|
3869
3869
|
}
|
|
3870
|
-
function propName
|
|
3870
|
+
function propName(obj) {
|
|
3871
3871
|
const keys = Object.keys(obj);
|
|
3872
3872
|
for (let i = 0; i < keys.length; i++) {
|
|
3873
3873
|
const key = keys[i];
|
|
@@ -3945,667 +3945,290 @@ var XMLParser = class {
|
|
|
3945
3945
|
}
|
|
3946
3946
|
};
|
|
3947
3947
|
//#endregion
|
|
3948
|
-
//#region
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
return
|
|
3954
|
-
}
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
}
|
|
3958
|
-
|
|
3959
|
-
//#region ../../node_modules/.pnpm/xml-naming@0.1.0/node_modules/xml-naming/src/index.js
|
|
3960
|
-
/**
|
|
3961
|
-
* xml-naming
|
|
3962
|
-
* Validates XML Name productions as defined in the XML 1.0 and 1.1 specifications.
|
|
3963
|
-
* Covers: Name, NCName, QName, NMToken, NMTokens
|
|
3964
|
-
*
|
|
3965
|
-
* XML 1.0 spec: https://www.w3.org/TR/xml/#NT-Name
|
|
3966
|
-
* XML 1.1 spec: https://www.w3.org/TR/xml11/#NT-NameStartChar
|
|
3967
|
-
* XML NS spec: https://www.w3.org/TR/xml-names/#NT-NCName
|
|
3968
|
-
*/
|
|
3969
|
-
const nameStartChar10 = ":A-Za-z_À-ÖØ-öø-˿Ͱ-ͽͿ-҆҈--⁰-Ⰰ-、-豈-﷏ﷰ-�";
|
|
3970
|
-
const nameChar10 = nameStartChar10 + "\\-\\.\\d" + "·" + "̀-ͯ" + "‿-⁀";
|
|
3971
|
-
const nameStartChar11 = ":A-Za-z_À-˿Ͱ-ͽͿ-҆҈--⁰-Ⰰ-、-豈-﷏ﷰ-�𐀀-";
|
|
3972
|
-
const nameChar11 = nameStartChar11 + "\\-\\.\\d" + "·" + "̀-ͯ" + "҇" + "‿-⁀";
|
|
3973
|
-
const buildRegexes = (startChar, char, flags = "") => {
|
|
3974
|
-
const ncNamePat = `[${startChar.replace(":", "")}][${char.replace(":", "")}]*`;
|
|
3975
|
-
return {
|
|
3976
|
-
name: new RegExp(`^[${startChar}][${char}]*$`, flags),
|
|
3977
|
-
ncName: new RegExp(`^${ncNamePat}$`, flags),
|
|
3978
|
-
qName: new RegExp(`^${ncNamePat}(?::${ncNamePat})?$`, flags),
|
|
3979
|
-
nmToken: new RegExp(`^[${char}]+$`, flags),
|
|
3980
|
-
nmTokens: new RegExp(`^[${char}]+(?:\\s+[${char}]+)*$`, flags)
|
|
3981
|
-
};
|
|
3948
|
+
//#region src/utils/configParser/androidManifestEdit.ts
|
|
3949
|
+
const NAME = /[^\s/>=]+/y;
|
|
3950
|
+
const WHITESPACE = /\s*/y;
|
|
3951
|
+
const matchAt = (pattern, text, index) => {
|
|
3952
|
+
pattern.lastIndex = index;
|
|
3953
|
+
return pattern.exec(text);
|
|
3954
|
+
};
|
|
3955
|
+
const skipTo = (xml, terminator, from) => {
|
|
3956
|
+
const index = xml.indexOf(terminator, from);
|
|
3957
|
+
if (index === -1) throw new Error(`unterminated markup, expected "${terminator}"`);
|
|
3958
|
+
return index + terminator.length;
|
|
3982
3959
|
};
|
|
3983
|
-
const regexes10 = buildRegexes(nameStartChar10, nameChar10);
|
|
3984
|
-
const regexes11 = buildRegexes(nameStartChar11, nameChar11, "u");
|
|
3985
|
-
const getRegexes = (xmlVersion = "1.0") => xmlVersion === "1.1" ? regexes11 : regexes10;
|
|
3986
|
-
/**
|
|
3987
|
-
* Returns true if the string is a valid QName (Qualified Name).
|
|
3988
|
-
* Allows exactly one colon as a prefix separator: prefix:localName.
|
|
3989
|
-
* Used for: element and attribute names in namespace-aware XML/SVG.
|
|
3990
|
-
*/
|
|
3991
|
-
const qName = (str, { xmlVersion = "1.0" } = {}) => getRegexes(xmlVersion).qName.test(str);
|
|
3992
|
-
//#endregion
|
|
3993
|
-
//#region ../../node_modules/.pnpm/fast-xml-builder@1.2.0/node_modules/fast-xml-builder/src/orderedJs2Xml.js
|
|
3994
|
-
const EOL = "\n";
|
|
3995
|
-
/**
|
|
3996
|
-
* Detect XML version from the first element of the ordered array input.
|
|
3997
|
-
* The first element must be a ?xml processing instruction with a version attribute.
|
|
3998
|
-
* Returns '1.0' if not found.
|
|
3999
|
-
*
|
|
4000
|
-
* @param {array} jArray
|
|
4001
|
-
* @param {object} options
|
|
4002
|
-
*/
|
|
4003
|
-
function detectXmlVersionFromArray(jArray, options) {
|
|
4004
|
-
if (!Array.isArray(jArray) || jArray.length === 0) return "1.0";
|
|
4005
|
-
const first = jArray[0];
|
|
4006
|
-
if (propName(first) === "?xml") {
|
|
4007
|
-
const attrs = first[":@"];
|
|
4008
|
-
if (attrs) {
|
|
4009
|
-
const versionKey = options.attributeNamePrefix + "version";
|
|
4010
|
-
if (attrs[versionKey]) return attrs[versionKey];
|
|
4011
|
-
}
|
|
4012
|
-
}
|
|
4013
|
-
return "1.0";
|
|
4014
|
-
}
|
|
4015
|
-
/**
|
|
4016
|
-
* Resolve a tag or attribute name through sanitizeName if configured.
|
|
4017
|
-
* Validation via xml-naming's qName is performed first; the sanitizeName
|
|
4018
|
-
* callback is invoked only when the name is invalid. If sanitizeName is
|
|
4019
|
-
* false (default), no validation occurs and the name is used as-is.
|
|
4020
|
-
*
|
|
4021
|
-
* @param {string} name - raw name from the JS object
|
|
4022
|
-
* @param {boolean} isAttribute - true when resolving an attribute name
|
|
4023
|
-
* @param {object} options
|
|
4024
|
-
* @param {Matcher} matcher - current matcher state (readonly from callback perspective)
|
|
4025
|
-
* @param {string} xmlVersion - '1.0' or '1.1', forwarded to xml-naming
|
|
4026
|
-
*/
|
|
4027
|
-
function resolveTagName$1(name, isAttribute, options, matcher, xmlVersion) {
|
|
4028
|
-
if (!options.sanitizeName) return name;
|
|
4029
|
-
if (qName(name, { xmlVersion })) return name;
|
|
4030
|
-
return options.sanitizeName(name, {
|
|
4031
|
-
isAttribute,
|
|
4032
|
-
matcher: matcher.readOnly()
|
|
4033
|
-
});
|
|
4034
|
-
}
|
|
4035
3960
|
/**
|
|
4036
|
-
*
|
|
4037
|
-
*
|
|
4038
|
-
*
|
|
3961
|
+
* Element tags of an XML document in document order. Comments, CDATA,
|
|
3962
|
+
* processing instructions and the doctype are skipped, so markup inside them
|
|
3963
|
+
* is never mistaken for an element.
|
|
4039
3964
|
*/
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
if (
|
|
4047
|
-
|
|
4048
|
-
}
|
|
4049
|
-
const xmlVersion = detectXmlVersionFromArray(jArray, options);
|
|
4050
|
-
const matcher = new Matcher();
|
|
4051
|
-
return arrToStr(jArray, options, indentation, matcher, stopNodeExpressions, xmlVersion);
|
|
4052
|
-
}
|
|
4053
|
-
function arrToStr(arr, options, indentation, matcher, stopNodeExpressions, xmlVersion) {
|
|
4054
|
-
let xmlStr = "";
|
|
4055
|
-
let isPreviousElementTag = false;
|
|
4056
|
-
if (options.maxNestedTags && matcher.getDepth() > options.maxNestedTags) throw new Error("Maximum nested tags exceeded");
|
|
4057
|
-
if (!Array.isArray(arr)) {
|
|
4058
|
-
if (arr !== void 0 && arr !== null) {
|
|
4059
|
-
let text = arr.toString();
|
|
4060
|
-
text = replaceEntitiesValue(text, options);
|
|
4061
|
-
return text;
|
|
4062
|
-
}
|
|
4063
|
-
return "";
|
|
4064
|
-
}
|
|
4065
|
-
for (let i = 0; i < arr.length; i++) {
|
|
4066
|
-
const tagObj = arr[i];
|
|
4067
|
-
const rawTagName = propName(tagObj);
|
|
4068
|
-
if (rawTagName === void 0) continue;
|
|
4069
|
-
const tagName = rawTagName === options.textNodeName || rawTagName === options.cdataPropName || rawTagName === options.commentPropName || rawTagName[0] === "?" ? rawTagName : resolveTagName$1(rawTagName, false, options, matcher, xmlVersion);
|
|
4070
|
-
const attrValues = extractAttributeValues(tagObj[":@"], options);
|
|
4071
|
-
matcher.push(tagName, attrValues);
|
|
4072
|
-
const isStopNode = checkStopNode(matcher, stopNodeExpressions);
|
|
4073
|
-
if (tagName === options.textNodeName) {
|
|
4074
|
-
let tagText = tagObj[rawTagName];
|
|
4075
|
-
if (!isStopNode) {
|
|
4076
|
-
tagText = options.tagValueProcessor(tagName, tagText);
|
|
4077
|
-
tagText = replaceEntitiesValue(tagText, options);
|
|
4078
|
-
}
|
|
4079
|
-
if (isPreviousElementTag) xmlStr += indentation;
|
|
4080
|
-
xmlStr += tagText;
|
|
4081
|
-
isPreviousElementTag = false;
|
|
4082
|
-
matcher.pop();
|
|
4083
|
-
continue;
|
|
4084
|
-
} else if (tagName === options.cdataPropName) {
|
|
4085
|
-
if (isPreviousElementTag) xmlStr += indentation;
|
|
4086
|
-
const val = tagObj[rawTagName][0][options.textNodeName];
|
|
4087
|
-
const safeVal = safeCdata(val);
|
|
4088
|
-
xmlStr += `<![CDATA[${safeVal}]]>`;
|
|
4089
|
-
isPreviousElementTag = false;
|
|
4090
|
-
matcher.pop();
|
|
3965
|
+
const scanTags = (xml) => {
|
|
3966
|
+
const tags = [];
|
|
3967
|
+
let index = 0;
|
|
3968
|
+
while (index < xml.length) {
|
|
3969
|
+
const start = xml.indexOf("<", index);
|
|
3970
|
+
if (start === -1) break;
|
|
3971
|
+
if (xml.startsWith("<!--", start)) {
|
|
3972
|
+
index = skipTo(xml, "-->", start + 4);
|
|
4091
3973
|
continue;
|
|
4092
|
-
}
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
xmlStr += indentation + `<!--${safeVal}-->`;
|
|
4096
|
-
isPreviousElementTag = true;
|
|
4097
|
-
matcher.pop();
|
|
3974
|
+
}
|
|
3975
|
+
if (xml.startsWith("<![CDATA[", start)) {
|
|
3976
|
+
index = skipTo(xml, "]]>", start + 9);
|
|
4098
3977
|
continue;
|
|
4099
|
-
}
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
isPreviousElementTag = true;
|
|
4103
|
-
matcher.pop();
|
|
3978
|
+
}
|
|
3979
|
+
if (xml.startsWith("<?", start)) {
|
|
3980
|
+
index = skipTo(xml, "?>", start + 2);
|
|
4104
3981
|
continue;
|
|
4105
3982
|
}
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
let tagValue;
|
|
4110
|
-
if (isStopNode) tagValue = getRawContent(tagObj[rawTagName], options);
|
|
4111
|
-
else tagValue = arrToStr(tagObj[rawTagName], options, newIdentation, matcher, stopNodeExpressions, xmlVersion);
|
|
4112
|
-
if (options.unpairedTags.indexOf(tagName) !== -1) {
|
|
4113
|
-
if (options.suppressUnpairedNode) xmlStr += tagStart + ">";
|
|
4114
|
-
else xmlStr += tagStart + "/>";
|
|
4115
|
-
} else if ((!tagValue || tagValue.length === 0) && options.suppressEmptyNode) xmlStr += tagStart + "/>";
|
|
4116
|
-
else if (tagValue && tagValue.endsWith(">")) xmlStr += tagStart + `>${tagValue}${indentation}</${tagName}>`;
|
|
4117
|
-
else {
|
|
4118
|
-
xmlStr += tagStart + ">";
|
|
4119
|
-
if (tagValue && indentation !== "" && (tagValue.includes("/>") || tagValue.includes("</"))) xmlStr += indentation + options.indentBy + tagValue + indentation;
|
|
4120
|
-
else xmlStr += tagValue;
|
|
4121
|
-
xmlStr += `</${tagName}>`;
|
|
3983
|
+
if (xml.startsWith("<!", start)) {
|
|
3984
|
+
index = skipTo(xml, ">", start + 2);
|
|
3985
|
+
continue;
|
|
4122
3986
|
}
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
}
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
const attStr = attr_to_str_raw(item[":@"], options);
|
|
4163
|
-
const nestedContent = getRawContent(item[tagName], options);
|
|
4164
|
-
if (!nestedContent || nestedContent.length === 0) content += `<${tagName}${attStr}/>`;
|
|
4165
|
-
else content += `<${tagName}${attStr}>${nestedContent}</${tagName}>`;
|
|
4166
|
-
}
|
|
4167
|
-
}
|
|
4168
|
-
return content;
|
|
4169
|
-
}
|
|
4170
|
-
/**
|
|
4171
|
-
* Build attribute string for stopNodes - NO entity replacement
|
|
4172
|
-
*/
|
|
4173
|
-
function attr_to_str_raw(attrMap, options) {
|
|
4174
|
-
let attrStr = "";
|
|
4175
|
-
if (attrMap && !options.ignoreAttributes) for (let attr in attrMap) {
|
|
4176
|
-
if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;
|
|
4177
|
-
let attrVal = attrMap[attr];
|
|
4178
|
-
if (attrVal === true && options.suppressBooleanAttributes) attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}`;
|
|
4179
|
-
else attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}="${escapeAttribute(attrVal)}"`;
|
|
4180
|
-
}
|
|
4181
|
-
return attrStr;
|
|
4182
|
-
}
|
|
4183
|
-
function propName(obj) {
|
|
4184
|
-
const keys = Object.keys(obj);
|
|
4185
|
-
for (let i = 0; i < keys.length; i++) {
|
|
4186
|
-
const key = keys[i];
|
|
4187
|
-
if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;
|
|
4188
|
-
if (key !== ":@") return key;
|
|
4189
|
-
}
|
|
4190
|
-
}
|
|
4191
|
-
/**
|
|
4192
|
-
* Build attribute string, resolving attribute names through sanitizeName when configured.
|
|
4193
|
-
* Accepts matcher so the callback has path context.
|
|
4194
|
-
*/
|
|
4195
|
-
function attr_to_str(attrMap, options, isStopNode, matcher, xmlVersion) {
|
|
4196
|
-
let attrStr = "";
|
|
4197
|
-
if (attrMap && !options.ignoreAttributes) for (let attr in attrMap) {
|
|
4198
|
-
if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;
|
|
4199
|
-
const cleanAttrName = attr.substr(options.attributeNamePrefix.length);
|
|
4200
|
-
const resolvedAttrName = isStopNode ? cleanAttrName : resolveTagName$1(cleanAttrName, true, options, matcher, xmlVersion);
|
|
4201
|
-
let attrVal;
|
|
4202
|
-
if (isStopNode) attrVal = attrMap[attr];
|
|
4203
|
-
else {
|
|
4204
|
-
attrVal = options.attributeValueProcessor(attr, attrMap[attr]);
|
|
4205
|
-
attrVal = replaceEntitiesValue(attrVal, options);
|
|
3987
|
+
let cursor = start + 1;
|
|
3988
|
+
const closing = xml[cursor] === "/";
|
|
3989
|
+
if (closing) cursor += 1;
|
|
3990
|
+
const name = matchAt(NAME, xml, cursor)?.[0];
|
|
3991
|
+
if (!name) throw new Error(`invalid tag at offset ${start}`);
|
|
3992
|
+
cursor += name.length;
|
|
3993
|
+
const attributes = [];
|
|
3994
|
+
let selfClosing = false;
|
|
3995
|
+
for (;;) {
|
|
3996
|
+
cursor += matchAt(WHITESPACE, xml, cursor)?.[0].length ?? 0;
|
|
3997
|
+
if (cursor >= xml.length) throw new Error(`unterminated tag <${name}> at offset ${start}`);
|
|
3998
|
+
if (xml.startsWith("/>", cursor)) {
|
|
3999
|
+
selfClosing = true;
|
|
4000
|
+
cursor += 2;
|
|
4001
|
+
break;
|
|
4002
|
+
}
|
|
4003
|
+
if (xml[cursor] === ">") {
|
|
4004
|
+
cursor += 1;
|
|
4005
|
+
break;
|
|
4006
|
+
}
|
|
4007
|
+
const attributeStart = cursor;
|
|
4008
|
+
const attributeName = matchAt(NAME, xml, cursor)?.[0];
|
|
4009
|
+
if (!attributeName) throw new Error(`invalid attribute in <${name}> at offset ${cursor}`);
|
|
4010
|
+
cursor += attributeName.length;
|
|
4011
|
+
cursor += matchAt(WHITESPACE, xml, cursor)?.[0].length ?? 0;
|
|
4012
|
+
if (xml[cursor] !== "=") throw new Error(`attribute ${attributeName} in <${name}> has no value`);
|
|
4013
|
+
cursor += 1;
|
|
4014
|
+
cursor += matchAt(WHITESPACE, xml, cursor)?.[0].length ?? 0;
|
|
4015
|
+
const quote = xml[cursor];
|
|
4016
|
+
if (quote !== "\"" && quote !== "'") throw new Error(`attribute ${attributeName} in <${name}> is not quoted`);
|
|
4017
|
+
const valueEnd = xml.indexOf(quote, cursor + 1);
|
|
4018
|
+
if (valueEnd === -1) throw new Error(`unterminated value of ${attributeName} in <${name}>`);
|
|
4019
|
+
attributes.push({
|
|
4020
|
+
name: attributeName,
|
|
4021
|
+
rawValue: xml.slice(cursor + 1, valueEnd),
|
|
4022
|
+
start: attributeStart,
|
|
4023
|
+
end: valueEnd + 1
|
|
4024
|
+
});
|
|
4025
|
+
cursor = valueEnd + 1;
|
|
4206
4026
|
}
|
|
4207
|
-
|
|
4208
|
-
|
|
4027
|
+
tags.push({
|
|
4028
|
+
name,
|
|
4029
|
+
start,
|
|
4030
|
+
end: cursor,
|
|
4031
|
+
closing,
|
|
4032
|
+
selfClosing,
|
|
4033
|
+
attributes
|
|
4034
|
+
});
|
|
4035
|
+
index = cursor;
|
|
4209
4036
|
}
|
|
4210
|
-
return
|
|
4211
|
-
}
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
textValue = textValue.replace(entity.regex, entity.val);
|
|
4037
|
+
return tags;
|
|
4038
|
+
};
|
|
4039
|
+
const decodeEntities = (value) => value.replace(/&(#x[0-9a-fA-F]+|#[0-9]+|amp|lt|gt|quot|apos);/g, (_, entity) => {
|
|
4040
|
+
switch (entity) {
|
|
4041
|
+
case "amp": return "&";
|
|
4042
|
+
case "lt": return "<";
|
|
4043
|
+
case "gt": return ">";
|
|
4044
|
+
case "quot": return "\"";
|
|
4045
|
+
case "apos": return "'";
|
|
4046
|
+
default: return String.fromCodePoint(entity.startsWith("#x") ? Number.parseInt(entity.slice(2), 16) : Number.parseInt(entity.slice(1), 10));
|
|
4221
4047
|
}
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4048
|
+
});
|
|
4049
|
+
const escapeAttribute = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """);
|
|
4050
|
+
const attributeValue = (tag, name) => {
|
|
4051
|
+
const attribute = tag.attributes.find((item) => item.name === name);
|
|
4052
|
+
return attribute === void 0 ? void 0 : decodeEntities(attribute.rawValue);
|
|
4053
|
+
};
|
|
4054
|
+
/** The first `<application>` directly under `<manifest>`, with its children. */
|
|
4055
|
+
const findApplication = (xml) => {
|
|
4056
|
+
const tags = scanTags(xml);
|
|
4057
|
+
const stack = [];
|
|
4058
|
+
for (let index = 0; index < tags.length; index += 1) {
|
|
4059
|
+
const tag = tags[index];
|
|
4060
|
+
if (tag.closing) {
|
|
4061
|
+
stack.pop();
|
|
4062
|
+
continue;
|
|
4232
4063
|
}
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
//#endregion
|
|
4237
|
-
//#region ../../node_modules/.pnpm/fast-xml-builder@1.2.0/node_modules/fast-xml-builder/src/fxb.js
|
|
4238
|
-
const defaultOptions = {
|
|
4239
|
-
attributeNamePrefix: "@_",
|
|
4240
|
-
attributesGroupName: false,
|
|
4241
|
-
textNodeName: "#text",
|
|
4242
|
-
ignoreAttributes: true,
|
|
4243
|
-
cdataPropName: false,
|
|
4244
|
-
format: false,
|
|
4245
|
-
indentBy: " ",
|
|
4246
|
-
suppressEmptyNode: false,
|
|
4247
|
-
suppressUnpairedNode: true,
|
|
4248
|
-
suppressBooleanAttributes: true,
|
|
4249
|
-
tagValueProcessor: function(key, a) {
|
|
4250
|
-
return a;
|
|
4251
|
-
},
|
|
4252
|
-
attributeValueProcessor: function(attrName, a) {
|
|
4253
|
-
return a;
|
|
4254
|
-
},
|
|
4255
|
-
preserveOrder: false,
|
|
4256
|
-
commentPropName: false,
|
|
4257
|
-
unpairedTags: [],
|
|
4258
|
-
entities: [
|
|
4259
|
-
{
|
|
4260
|
-
regex: /* @__PURE__ */ new RegExp("&", "g"),
|
|
4261
|
-
val: "&"
|
|
4262
|
-
},
|
|
4263
|
-
{
|
|
4264
|
-
regex: /* @__PURE__ */ new RegExp(">", "g"),
|
|
4265
|
-
val: ">"
|
|
4266
|
-
},
|
|
4267
|
-
{
|
|
4268
|
-
regex: /* @__PURE__ */ new RegExp("<", "g"),
|
|
4269
|
-
val: "<"
|
|
4270
|
-
},
|
|
4271
|
-
{
|
|
4272
|
-
regex: /* @__PURE__ */ new RegExp("'", "g"),
|
|
4273
|
-
val: "'"
|
|
4274
|
-
},
|
|
4275
|
-
{
|
|
4276
|
-
regex: /* @__PURE__ */ new RegExp("\"", "g"),
|
|
4277
|
-
val: """
|
|
4064
|
+
if (!(tag.name === "application" && stack.length === 1 && stack[0] === "manifest")) {
|
|
4065
|
+
if (!tag.selfClosing) stack.push(tag.name);
|
|
4066
|
+
continue;
|
|
4278
4067
|
}
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
maxNestedTags: 100,
|
|
4284
|
-
jPath: true,
|
|
4285
|
-
sanitizeName: false
|
|
4286
|
-
};
|
|
4287
|
-
function Builder(options) {
|
|
4288
|
-
this.options = Object.assign({}, defaultOptions, options);
|
|
4289
|
-
if (this.options.stopNodes && Array.isArray(this.options.stopNodes)) this.options.stopNodes = this.options.stopNodes.map((node) => {
|
|
4290
|
-
if (typeof node === "string" && node.startsWith("*.")) return ".." + node.substring(2);
|
|
4291
|
-
return node;
|
|
4292
|
-
});
|
|
4293
|
-
this.stopNodeExpressions = [];
|
|
4294
|
-
if (this.options.stopNodes && Array.isArray(this.options.stopNodes)) for (let i = 0; i < this.options.stopNodes.length; i++) {
|
|
4295
|
-
const node = this.options.stopNodes[i];
|
|
4296
|
-
if (typeof node === "string") this.stopNodeExpressions.push(new Expression(node));
|
|
4297
|
-
else if (node instanceof Expression) this.stopNodeExpressions.push(node);
|
|
4298
|
-
}
|
|
4299
|
-
if (this.options.ignoreAttributes === true || this.options.attributesGroupName) this.isAttribute = function() {
|
|
4300
|
-
return false;
|
|
4301
|
-
};
|
|
4302
|
-
else {
|
|
4303
|
-
this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes);
|
|
4304
|
-
this.attrPrefixLen = this.options.attributeNamePrefix.length;
|
|
4305
|
-
this.isAttribute = isAttribute;
|
|
4306
|
-
}
|
|
4307
|
-
this.processTextOrObjNode = processTextOrObjNode;
|
|
4308
|
-
if (this.options.format) {
|
|
4309
|
-
this.indentate = indentate;
|
|
4310
|
-
this.tagEndChar = ">\n";
|
|
4311
|
-
this.newLine = "\n";
|
|
4312
|
-
} else {
|
|
4313
|
-
this.indentate = function() {
|
|
4314
|
-
return "";
|
|
4068
|
+
if (tag.selfClosing) return {
|
|
4069
|
+
openTag: tag,
|
|
4070
|
+
closeTag: null,
|
|
4071
|
+
children: []
|
|
4315
4072
|
};
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4073
|
+
const children = [];
|
|
4074
|
+
let depth = 0;
|
|
4075
|
+
let open = null;
|
|
4076
|
+
for (let inner = index + 1; inner < tags.length; inner += 1) {
|
|
4077
|
+
const child = tags[inner];
|
|
4078
|
+
if (child.closing) {
|
|
4079
|
+
if (depth === 0) return {
|
|
4080
|
+
openTag: tag,
|
|
4081
|
+
closeTag: child,
|
|
4082
|
+
children
|
|
4083
|
+
};
|
|
4084
|
+
depth -= 1;
|
|
4085
|
+
if (depth === 0 && open) {
|
|
4086
|
+
children.push({
|
|
4087
|
+
openTag: open,
|
|
4088
|
+
start: open.start,
|
|
4089
|
+
end: child.end
|
|
4090
|
+
});
|
|
4091
|
+
open = null;
|
|
4092
|
+
}
|
|
4093
|
+
continue;
|
|
4094
|
+
}
|
|
4095
|
+
if (child.selfClosing) {
|
|
4096
|
+
if (depth === 0) children.push({
|
|
4097
|
+
openTag: child,
|
|
4098
|
+
start: child.start,
|
|
4099
|
+
end: child.end
|
|
4100
|
+
});
|
|
4101
|
+
continue;
|
|
4102
|
+
}
|
|
4103
|
+
if (depth === 0) open = child;
|
|
4104
|
+
depth += 1;
|
|
4331
4105
|
}
|
|
4332
|
-
|
|
4333
|
-
if (v) return v;
|
|
4334
|
-
}
|
|
4335
|
-
return "1.0";
|
|
4336
|
-
}
|
|
4337
|
-
/**
|
|
4338
|
-
* Resolve a tag or attribute name through sanitizeName if configured.
|
|
4339
|
-
* Validation via xml-naming's qName is performed first; the sanitizeName
|
|
4340
|
-
* callback is invoked only when the name is invalid. If sanitizeName is
|
|
4341
|
-
* false (default), no validation occurs and the name is used as-is.
|
|
4342
|
-
*
|
|
4343
|
-
* @param {string} name - raw name from the JS object
|
|
4344
|
-
* @param {boolean} isAttribute - true when resolving an attribute name
|
|
4345
|
-
* @param {object} options
|
|
4346
|
-
* @param {Matcher} matcher - current matcher state (readonly from callback perspective)
|
|
4347
|
-
* @param {string} xmlVersion - '1.0' or '1.1', forwarded to xml-naming
|
|
4348
|
-
*/
|
|
4349
|
-
function resolveTagName(name, isAttribute, options, matcher, xmlVersion) {
|
|
4350
|
-
if (!options.sanitizeName) return name;
|
|
4351
|
-
if (qName(name, { xmlVersion })) return name;
|
|
4352
|
-
return options.sanitizeName(name, {
|
|
4353
|
-
isAttribute,
|
|
4354
|
-
matcher: matcher.readOnly()
|
|
4355
|
-
});
|
|
4356
|
-
}
|
|
4357
|
-
Builder.prototype.build = function(jObj) {
|
|
4358
|
-
if (this.options.preserveOrder) return toXml(jObj, this.options);
|
|
4359
|
-
else {
|
|
4360
|
-
if (Array.isArray(jObj) && this.options.arrayNodeName && this.options.arrayNodeName.length > 1) jObj = { [this.options.arrayNodeName]: jObj };
|
|
4361
|
-
const matcher = new Matcher();
|
|
4362
|
-
const xmlVersion = detectXmlVersionFromObj(jObj, this.options);
|
|
4363
|
-
return this.j2x(jObj, 0, matcher, xmlVersion).val;
|
|
4364
|
-
}
|
|
4365
|
-
};
|
|
4366
|
-
Builder.prototype.j2x = function(jObj, level, matcher, xmlVersion) {
|
|
4367
|
-
let attrStr = "";
|
|
4368
|
-
let val = "";
|
|
4369
|
-
if (this.options.maxNestedTags && matcher.getDepth() >= this.options.maxNestedTags) throw new Error("Maximum nested tags exceeded");
|
|
4370
|
-
const jPath = this.options.jPath ? matcher.toString() : matcher;
|
|
4371
|
-
const isCurrentStopNode = this.checkStopNode(matcher);
|
|
4372
|
-
for (let key in jObj) {
|
|
4373
|
-
if (!Object.prototype.hasOwnProperty.call(jObj, key)) continue;
|
|
4374
|
-
const resolvedKey = key === this.options.textNodeName || key === this.options.cdataPropName || key === this.options.commentPropName || this.options.attributesGroupName && key === this.options.attributesGroupName || this.isAttribute(key) || key[0] === "?" ? key : resolveTagName(key, false, this.options, matcher, xmlVersion);
|
|
4375
|
-
if (typeof jObj[key] === "undefined") {
|
|
4376
|
-
if (this.isAttribute(key)) val += "";
|
|
4377
|
-
} else if (jObj[key] === null) {
|
|
4378
|
-
if (this.isAttribute(key)) val += "";
|
|
4379
|
-
else if (resolvedKey === this.options.cdataPropName || resolvedKey === this.options.commentPropName) val += "";
|
|
4380
|
-
else if (resolvedKey[0] === "?") val += this.indentate(level) + "<" + resolvedKey + "?" + this.tagEndChar;
|
|
4381
|
-
else val += this.indentate(level) + "<" + resolvedKey + "/" + this.tagEndChar;
|
|
4382
|
-
} else if (jObj[key] instanceof Date) val += this.buildTextValNode(jObj[key], resolvedKey, "", level, matcher);
|
|
4383
|
-
else if (typeof jObj[key] !== "object") {
|
|
4384
|
-
const attr = this.isAttribute(key);
|
|
4385
|
-
if (attr && !this.ignoreAttributesFn(attr, jPath)) {
|
|
4386
|
-
const resolvedAttr = resolveTagName(attr, true, this.options, matcher, xmlVersion);
|
|
4387
|
-
attrStr += this.buildAttrPairStr(resolvedAttr, "" + jObj[key], isCurrentStopNode);
|
|
4388
|
-
} else if (!attr) {
|
|
4389
|
-
if (key === this.options.textNodeName) {
|
|
4390
|
-
let newval = this.options.tagValueProcessor(key, "" + jObj[key]);
|
|
4391
|
-
val += this.replaceEntitiesValue(newval);
|
|
4392
|
-
} else {
|
|
4393
|
-
matcher.push(resolvedKey);
|
|
4394
|
-
const isStopNode = this.checkStopNode(matcher);
|
|
4395
|
-
matcher.pop();
|
|
4396
|
-
if (isStopNode) {
|
|
4397
|
-
const textValue = "" + jObj[key];
|
|
4398
|
-
if (textValue === "") val += this.indentate(level) + "<" + resolvedKey + this.closeTag(resolvedKey) + this.tagEndChar;
|
|
4399
|
-
else val += this.indentate(level) + "<" + resolvedKey + ">" + textValue + "</" + resolvedKey + this.tagEndChar;
|
|
4400
|
-
} else val += this.buildTextValNode(jObj[key], resolvedKey, "", level, matcher);
|
|
4401
|
-
}
|
|
4402
|
-
}
|
|
4403
|
-
} else if (Array.isArray(jObj[key])) {
|
|
4404
|
-
const arrLen = jObj[key].length;
|
|
4405
|
-
let listTagVal = "";
|
|
4406
|
-
let listTagAttr = "";
|
|
4407
|
-
for (let j = 0; j < arrLen; j++) {
|
|
4408
|
-
const item = jObj[key][j];
|
|
4409
|
-
if (typeof item === "undefined") {} else if (item === null) {
|
|
4410
|
-
if (resolvedKey[0] === "?") val += this.indentate(level) + "<" + resolvedKey + "?" + this.tagEndChar;
|
|
4411
|
-
else val += this.indentate(level) + "<" + resolvedKey + "/" + this.tagEndChar;
|
|
4412
|
-
} else if (typeof item === "object") {
|
|
4413
|
-
if (this.options.oneListGroup) {
|
|
4414
|
-
matcher.push(resolvedKey);
|
|
4415
|
-
const result = this.j2x(item, level + 1, matcher, xmlVersion);
|
|
4416
|
-
matcher.pop();
|
|
4417
|
-
listTagVal += result.val;
|
|
4418
|
-
if (this.options.attributesGroupName && item.hasOwnProperty(this.options.attributesGroupName)) listTagAttr += result.attrStr;
|
|
4419
|
-
} else listTagVal += this.processTextOrObjNode(item, resolvedKey, level, matcher, xmlVersion);
|
|
4420
|
-
} else if (this.options.oneListGroup) {
|
|
4421
|
-
let textValue = this.options.tagValueProcessor(resolvedKey, item);
|
|
4422
|
-
textValue = this.replaceEntitiesValue(textValue);
|
|
4423
|
-
listTagVal += textValue;
|
|
4424
|
-
} else {
|
|
4425
|
-
matcher.push(resolvedKey);
|
|
4426
|
-
const isStopNode = this.checkStopNode(matcher);
|
|
4427
|
-
matcher.pop();
|
|
4428
|
-
if (isStopNode) {
|
|
4429
|
-
const textValue = "" + item;
|
|
4430
|
-
if (textValue === "") listTagVal += this.indentate(level) + "<" + resolvedKey + this.closeTag(resolvedKey) + this.tagEndChar;
|
|
4431
|
-
else listTagVal += this.indentate(level) + "<" + resolvedKey + ">" + textValue + "</" + resolvedKey + this.tagEndChar;
|
|
4432
|
-
} else listTagVal += this.buildTextValNode(item, resolvedKey, "", level, matcher);
|
|
4433
|
-
}
|
|
4434
|
-
}
|
|
4435
|
-
if (this.options.oneListGroup) listTagVal = this.buildObjectNode(listTagVal, resolvedKey, listTagAttr, level);
|
|
4436
|
-
val += listTagVal;
|
|
4437
|
-
} else if (this.options.attributesGroupName && key === this.options.attributesGroupName) {
|
|
4438
|
-
const Ks = Object.keys(jObj[key]);
|
|
4439
|
-
const L = Ks.length;
|
|
4440
|
-
for (let j = 0; j < L; j++) {
|
|
4441
|
-
const resolvedAttr = resolveTagName(Ks[j], true, this.options, matcher, xmlVersion);
|
|
4442
|
-
attrStr += this.buildAttrPairStr(resolvedAttr, "" + jObj[key][Ks[j]], isCurrentStopNode);
|
|
4443
|
-
}
|
|
4444
|
-
} else val += this.processTextOrObjNode(jObj[key], resolvedKey, level, matcher, xmlVersion);
|
|
4106
|
+
throw new Error("<application> is not closed");
|
|
4445
4107
|
}
|
|
4446
|
-
return
|
|
4447
|
-
attrStr,
|
|
4448
|
-
val
|
|
4449
|
-
};
|
|
4108
|
+
return null;
|
|
4450
4109
|
};
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
if (this.options.suppressBooleanAttributes && val === "true") return " " + attrName;
|
|
4457
|
-
else return " " + attrName + "=\"" + escapeAttribute(val) + "\"";
|
|
4110
|
+
const metaDataElements = (application, key) => application.children.filter((child) => child.openTag.name === "meta-data" && attributeValue(child.openTag, "android:name") === key);
|
|
4111
|
+
/** Leading whitespace of the line that contains `offset`. */
|
|
4112
|
+
const lineIndent = (xml, offset) => {
|
|
4113
|
+
const lineStart = xml.lastIndexOf("\n", offset - 1) + 1;
|
|
4114
|
+
return /^[ \t]*/.exec(xml.slice(lineStart, offset))?.[0] ?? "";
|
|
4458
4115
|
};
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
const rawContent = this.buildRawContent(object);
|
|
4464
|
-
const attrStr = this.buildAttributesForStopNode(object);
|
|
4465
|
-
matcher.pop();
|
|
4466
|
-
return this.buildObjectNode(rawContent, key, attrStr, level);
|
|
4467
|
-
}
|
|
4468
|
-
const result = this.j2x(object, level + 1, matcher, xmlVersion);
|
|
4469
|
-
matcher.pop();
|
|
4470
|
-
if (key[0] === "?") return this.buildTextValNode("", key, result.attrStr, level, matcher);
|
|
4471
|
-
else if (object[this.options.textNodeName] !== void 0 && Object.keys(object).length === 1) return this.buildTextValNode(object[this.options.textNodeName], key, result.attrStr, level, matcher);
|
|
4472
|
-
else return this.buildObjectNode(result.val, key, result.attrStr, level);
|
|
4473
|
-
}
|
|
4474
|
-
Builder.prototype.extractAttributes = function(obj) {
|
|
4475
|
-
if (!obj || typeof obj !== "object") return null;
|
|
4476
|
-
const attrValues = {};
|
|
4477
|
-
let hasAttrs = false;
|
|
4478
|
-
if (this.options.attributesGroupName && obj[this.options.attributesGroupName]) {
|
|
4479
|
-
const attrGroup = obj[this.options.attributesGroupName];
|
|
4480
|
-
for (let attrKey in attrGroup) {
|
|
4481
|
-
if (!Object.prototype.hasOwnProperty.call(attrGroup, attrKey)) continue;
|
|
4482
|
-
const cleanKey = attrKey.startsWith(this.options.attributeNamePrefix) ? attrKey.substring(this.options.attributeNamePrefix.length) : attrKey;
|
|
4483
|
-
attrValues[cleanKey] = escapeAttribute(attrGroup[attrKey]);
|
|
4484
|
-
hasAttrs = true;
|
|
4485
|
-
}
|
|
4486
|
-
} else for (let key in obj) {
|
|
4487
|
-
if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;
|
|
4488
|
-
const attr = this.isAttribute(key);
|
|
4489
|
-
if (attr) {
|
|
4490
|
-
attrValues[attr] = escapeAttribute(obj[key]);
|
|
4491
|
-
hasAttrs = true;
|
|
4492
|
-
}
|
|
4493
|
-
}
|
|
4494
|
-
return hasAttrs ? attrValues : null;
|
|
4116
|
+
/** Whether only whitespace sits between the start of the line and `offset`. */
|
|
4117
|
+
const startsLine = (xml, offset) => {
|
|
4118
|
+
const lineStart = xml.lastIndexOf("\n", offset - 1) + 1;
|
|
4119
|
+
return /^[ \t]*$/.test(xml.slice(lineStart, offset));
|
|
4495
4120
|
};
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
let content = "";
|
|
4501
|
-
for (let key in obj) {
|
|
4502
|
-
if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;
|
|
4503
|
-
if (this.isAttribute(key)) continue;
|
|
4504
|
-
if (this.options.attributesGroupName && key === this.options.attributesGroupName) continue;
|
|
4505
|
-
const value = obj[key];
|
|
4506
|
-
if (key === this.options.textNodeName) content += value;
|
|
4507
|
-
else if (Array.isArray(value)) {
|
|
4508
|
-
for (let item of value) if (typeof item === "string" || typeof item === "number") content += `<${key}>${item}</${key}>`;
|
|
4509
|
-
else if (typeof item === "object" && item !== null) {
|
|
4510
|
-
const nestedContent = this.buildRawContent(item);
|
|
4511
|
-
const nestedAttrs = this.buildAttributesForStopNode(item);
|
|
4512
|
-
if (nestedContent === "") content += `<${key}${nestedAttrs}/>`;
|
|
4513
|
-
else content += `<${key}${nestedAttrs}>${nestedContent}</${key}>`;
|
|
4514
|
-
}
|
|
4515
|
-
} else if (typeof value === "object" && value !== null) {
|
|
4516
|
-
const nestedContent = this.buildRawContent(value);
|
|
4517
|
-
const nestedAttrs = this.buildAttributesForStopNode(value);
|
|
4518
|
-
if (nestedContent === "") content += `<${key}${nestedAttrs}/>`;
|
|
4519
|
-
else content += `<${key}${nestedAttrs}>${nestedContent}</${key}>`;
|
|
4520
|
-
} else content += `<${key}>${value}</${key}>`;
|
|
4521
|
-
}
|
|
4522
|
-
return content;
|
|
4121
|
+
const lineEnding = (xml) => xml.includes("\r\n") ? "\r\n" : "\n";
|
|
4122
|
+
/** `" />"` or `"/>"`, whichever the file already uses more. */
|
|
4123
|
+
const selfClosingStyle = (xml) => {
|
|
4124
|
+
return (xml.match(/\s\/>/g)?.length ?? 0) >= (xml.match(/[^\s]\/>/g)?.length ?? 0) ? " />" : "/>";
|
|
4523
4125
|
};
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
const cleanKey = attrKey.startsWith(this.options.attributeNamePrefix) ? attrKey.substring(this.options.attributeNamePrefix.length) : attrKey;
|
|
4532
|
-
const val = attrGroup[attrKey];
|
|
4533
|
-
if (val === true && this.options.suppressBooleanAttributes) attrStr += " " + cleanKey;
|
|
4534
|
-
else attrStr += " " + cleanKey + "=\"" + val + "\"";
|
|
4535
|
-
}
|
|
4536
|
-
} else for (let key in obj) {
|
|
4537
|
-
if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;
|
|
4538
|
-
const attr = this.isAttribute(key);
|
|
4539
|
-
if (attr) {
|
|
4540
|
-
const val = obj[key];
|
|
4541
|
-
if (val === true && this.options.suppressBooleanAttributes) attrStr += " " + attr;
|
|
4542
|
-
else attrStr += " " + attr + "=\"" + val + "\"";
|
|
4543
|
-
}
|
|
4544
|
-
}
|
|
4545
|
-
return attrStr;
|
|
4126
|
+
const indentUnit = (xml, application) => {
|
|
4127
|
+
const applicationIndent = lineIndent(xml, application.openTag.start);
|
|
4128
|
+
if (applicationIndent.includes(" ")) return " ";
|
|
4129
|
+
const manifest = /<manifest\b/.exec(xml);
|
|
4130
|
+
const manifestIndent = manifest ? lineIndent(xml, manifest.index) : "";
|
|
4131
|
+
const unit = applicationIndent.slice(manifestIndent.length);
|
|
4132
|
+
return unit.length > 0 ? unit : " ";
|
|
4546
4133
|
};
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4134
|
+
const applyEdits = (xml, edits) => [...edits].sort((a, b) => b.start - a.start).reduce((result, edit) => result.slice(0, edit.start) + edit.text + result.slice(edit.end), xml);
|
|
4135
|
+
/**
|
|
4136
|
+
* Sets `<meta-data android:name={key} android:value={value}>` under
|
|
4137
|
+
* `<application>`, changing nothing else in the file. An existing element
|
|
4138
|
+
* gets its `android:value` replaced in place; otherwise a new element is
|
|
4139
|
+
* added as the last child, indented like its siblings.
|
|
4140
|
+
*
|
|
4141
|
+
* @returns the edited manifest, or null when it has no `<application>`.
|
|
4142
|
+
*/
|
|
4143
|
+
const setManifestMetaData = (xml, key, value) => {
|
|
4144
|
+
const application = findApplication(xml);
|
|
4145
|
+
if (!application) return null;
|
|
4146
|
+
const valueAttribute = `android:value="${escapeAttribute(value)}"`;
|
|
4147
|
+
const existing = metaDataElements(application, key);
|
|
4148
|
+
if (existing.length > 0) return applyEdits(xml, existing.flatMap(({ openTag }) => {
|
|
4149
|
+
const attribute = (name) => openTag.attributes.find((item) => item.name === name);
|
|
4150
|
+
const current = attribute("android:value");
|
|
4151
|
+
const resource = attribute("android:resource");
|
|
4152
|
+
if (!current && resource) return [{
|
|
4153
|
+
start: resource.start,
|
|
4154
|
+
end: resource.end,
|
|
4155
|
+
text: valueAttribute
|
|
4156
|
+
}];
|
|
4157
|
+
const edits = current ? [{
|
|
4158
|
+
start: current.start,
|
|
4159
|
+
end: current.end,
|
|
4160
|
+
text: valueAttribute
|
|
4161
|
+
}] : [{
|
|
4162
|
+
start: attribute("android:name").end,
|
|
4163
|
+
end: attribute("android:name").end,
|
|
4164
|
+
text: ` ${valueAttribute}`
|
|
4165
|
+
}];
|
|
4166
|
+
if (resource) {
|
|
4167
|
+
let start = resource.start;
|
|
4168
|
+
while (start > openTag.start && /\s/.test(xml[start - 1])) start -= 1;
|
|
4169
|
+
edits.push({
|
|
4170
|
+
start,
|
|
4171
|
+
end: resource.end,
|
|
4172
|
+
text: ""
|
|
4173
|
+
});
|
|
4558
4174
|
}
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
}
|
|
4175
|
+
return edits;
|
|
4176
|
+
}));
|
|
4177
|
+
const eol = lineEnding(xml);
|
|
4178
|
+
const element = `<meta-data android:name="${escapeAttribute(key)}" ${valueAttribute}${selfClosingStyle(xml)}`;
|
|
4179
|
+
const applicationIndent = lineIndent(xml, application.openTag.start);
|
|
4180
|
+
const lastChild = application.children.at(-1);
|
|
4181
|
+
const childIndent = lastChild && startsLine(xml, lastChild.start) ? lineIndent(xml, lastChild.start) : applicationIndent + indentUnit(xml, application);
|
|
4182
|
+
if (application.closeTag === null) {
|
|
4183
|
+
const { openTag } = application;
|
|
4184
|
+
const head = xml.slice(openTag.start, openTag.end).replace(/\s*\/>$/, ">");
|
|
4185
|
+
return applyEdits(xml, [{
|
|
4186
|
+
start: openTag.start,
|
|
4187
|
+
end: openTag.end,
|
|
4188
|
+
text: `${head}${eol}${childIndent}${element}${eol}${applicationIndent}</application>`
|
|
4189
|
+
}]);
|
|
4190
|
+
}
|
|
4191
|
+
const closeStart = application.closeTag.start;
|
|
4192
|
+
if (startsLine(xml, closeStart)) {
|
|
4193
|
+
const lineStart = xml.lastIndexOf("\n", closeStart - 1) + 1;
|
|
4194
|
+
return applyEdits(xml, [{
|
|
4195
|
+
start: lineStart,
|
|
4196
|
+
end: lineStart,
|
|
4197
|
+
text: `${childIndent}${element}${eol}`
|
|
4198
|
+
}]);
|
|
4199
|
+
}
|
|
4200
|
+
return applyEdits(xml, [{
|
|
4201
|
+
start: closeStart,
|
|
4202
|
+
end: closeStart,
|
|
4203
|
+
text: element
|
|
4204
|
+
}]);
|
|
4563
4205
|
};
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
return
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
else return this.indentate(level) + "<" + key + attrStr + ">" + textValue + "</" + key + this.tagEndChar;
|
|
4590
|
-
}
|
|
4591
|
-
};
|
|
4592
|
-
Builder.prototype.replaceEntitiesValue = function(textValue) {
|
|
4593
|
-
if (textValue && textValue.length > 0 && this.options.processEntities) for (let i = 0; i < this.options.entities.length; i++) {
|
|
4594
|
-
const entity = this.options.entities[i];
|
|
4595
|
-
textValue = textValue.replace(entity.regex, entity.val);
|
|
4596
|
-
}
|
|
4597
|
-
return textValue;
|
|
4206
|
+
/**
|
|
4207
|
+
* Removes every `<meta-data android:name={key}>` under `<application>`. An
|
|
4208
|
+
* element alone on its line takes the line with it.
|
|
4209
|
+
*
|
|
4210
|
+
* @returns the edited manifest, or null when there was nothing to remove.
|
|
4211
|
+
*/
|
|
4212
|
+
const removeManifestMetaData = (xml, key) => {
|
|
4213
|
+
const application = findApplication(xml);
|
|
4214
|
+
if (!application) return null;
|
|
4215
|
+
const existing = metaDataElements(application, key);
|
|
4216
|
+
if (existing.length === 0) return null;
|
|
4217
|
+
return applyEdits(xml, existing.map(({ start, end }) => {
|
|
4218
|
+
const lineStart = xml.lastIndexOf("\n", start - 1) + 1;
|
|
4219
|
+
const newline = xml.indexOf("\n", end);
|
|
4220
|
+
const lineEnd = newline === -1 ? xml.length : newline + 1;
|
|
4221
|
+
return /^[ \t]*$/.test(xml.slice(lineStart, start)) && /^[ \t]*\r?\n?$/.test(xml.slice(end, lineEnd)) ? {
|
|
4222
|
+
start: lineStart,
|
|
4223
|
+
end: lineEnd,
|
|
4224
|
+
text: ""
|
|
4225
|
+
} : {
|
|
4226
|
+
start,
|
|
4227
|
+
end,
|
|
4228
|
+
text: ""
|
|
4229
|
+
};
|
|
4230
|
+
}));
|
|
4598
4231
|
};
|
|
4599
|
-
function indentate(level) {
|
|
4600
|
-
return this.options.indentBy.repeat(level);
|
|
4601
|
-
}
|
|
4602
|
-
function isAttribute(name) {
|
|
4603
|
-
if (name.startsWith(this.options.attributeNamePrefix) && name !== this.options.textNodeName) return name.substr(this.attrPrefixLen);
|
|
4604
|
-
else return false;
|
|
4605
|
-
}
|
|
4606
|
-
//#endregion
|
|
4607
|
-
//#region ../../node_modules/.pnpm/fast-xml-parser@5.7.2/node_modules/fast-xml-parser/src/xmlbuilder/json2xml.js
|
|
4608
|
-
var json2xml_default = Builder;
|
|
4609
4232
|
//#endregion
|
|
4610
4233
|
//#region src/utils/configParser/androidParser.ts
|
|
4611
4234
|
/** The AndroidManifest meta-data names the native SDK reads. */
|
|
@@ -4617,7 +4240,6 @@ const MANIFEST_KEYS = /* @__PURE__ */ new Set([
|
|
|
4617
4240
|
var AndroidConfigParser = class {
|
|
4618
4241
|
androidManifestPaths;
|
|
4619
4242
|
parser;
|
|
4620
|
-
builder;
|
|
4621
4243
|
constructor(androidManifestPaths) {
|
|
4622
4244
|
this.androidManifestPaths = (androidManifestPaths || []).map((p) => path.isAbsolute(p) ? p : path.join(getCwd(), p));
|
|
4623
4245
|
const options = {
|
|
@@ -4629,13 +4251,6 @@ var AndroidConfigParser = class {
|
|
|
4629
4251
|
suppressEmptyNode: true
|
|
4630
4252
|
};
|
|
4631
4253
|
this.parser = new XMLParser(options);
|
|
4632
|
-
this.builder = new json2xml_default({
|
|
4633
|
-
...options,
|
|
4634
|
-
format: true,
|
|
4635
|
-
indentBy: " ",
|
|
4636
|
-
suppressBooleanAttributes: false,
|
|
4637
|
-
processEntities: true
|
|
4638
|
-
});
|
|
4639
4254
|
}
|
|
4640
4255
|
async exists() {
|
|
4641
4256
|
return this.getExistingManifestPaths().length > 0;
|
|
@@ -4688,14 +4303,8 @@ var AndroidConfigParser = class {
|
|
|
4688
4303
|
const updatedPaths = [];
|
|
4689
4304
|
for (const androidManifestPath of existingManifestPaths) try {
|
|
4690
4305
|
const content = await fs.promises.readFile(androidManifestPath, "utf-8");
|
|
4691
|
-
const
|
|
4692
|
-
|
|
4693
|
-
if (!application?.["meta-data"]) continue;
|
|
4694
|
-
const metaData = Array.isArray(application["meta-data"]) ? application["meta-data"] : [application["meta-data"]];
|
|
4695
|
-
const filtered = metaData.filter((item) => item["@_android:name"] !== manifestKey);
|
|
4696
|
-
if (filtered.length === metaData.length) continue;
|
|
4697
|
-
application["meta-data"] = filtered.length === 0 ? void 0 : filtered.length === 1 ? filtered[0] : filtered;
|
|
4698
|
-
const newContent = this.builder.build(result);
|
|
4306
|
+
const newContent = removeManifestMetaData(content, manifestKey);
|
|
4307
|
+
if (newContent === null) continue;
|
|
4699
4308
|
await fs.promises.writeFile(androidManifestPath, newContent, "utf-8");
|
|
4700
4309
|
updatedPaths.push(path.relative(getCwd(), androidManifestPath));
|
|
4701
4310
|
} catch (error) {
|
|
@@ -4717,21 +4326,9 @@ var AndroidConfigParser = class {
|
|
|
4717
4326
|
const updatedPaths = [];
|
|
4718
4327
|
for (const androidManifestPath of existingPaths) try {
|
|
4719
4328
|
const content = await fs.promises.readFile(androidManifestPath, "utf-8");
|
|
4720
|
-
const
|
|
4721
|
-
|
|
4722
|
-
if (
|
|
4723
|
-
if (!application["meta-data"]) application["meta-data"] = [];
|
|
4724
|
-
const metaData = Array.isArray(application["meta-data"]) ? application["meta-data"] : [application["meta-data"]];
|
|
4725
|
-
const existingIndex = metaData.findIndex((item) => item["@_android:name"] === key);
|
|
4726
|
-
const metaDataElement = {
|
|
4727
|
-
"@_android:name": key,
|
|
4728
|
-
"@_android:value": value
|
|
4729
|
-
};
|
|
4730
|
-
if (existingIndex !== -1) metaData[existingIndex] = metaDataElement;
|
|
4731
|
-
else metaData.push(metaDataElement);
|
|
4732
|
-
application["meta-data"] = metaData.length === 1 ? metaData[0] : metaData;
|
|
4733
|
-
const newContent = this.builder.build(result);
|
|
4734
|
-
await fs.promises.writeFile(androidManifestPath, newContent, "utf-8");
|
|
4329
|
+
const newContent = setManifestMetaData(content, key, value);
|
|
4330
|
+
if (newContent === null) continue;
|
|
4331
|
+
if (newContent !== content) await fs.promises.writeFile(androidManifestPath, newContent, "utf-8");
|
|
4735
4332
|
updatedPaths.push(path.relative(getCwd(), androidManifestPath));
|
|
4736
4333
|
} catch (error) {
|
|
4737
4334
|
throw new Error(`Failed to parse or update AndroidManifest.xml: ${error}`);
|
|
@@ -15021,7 +14618,7 @@ var require_build = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
15021
14618
|
}
|
|
15022
14619
|
}));
|
|
15023
14620
|
//#endregion
|
|
15024
|
-
//#region src/utils/configParser/
|
|
14621
|
+
//#region src/utils/configParser/plistFormat.ts
|
|
15025
14622
|
var import_plist = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports) => {
|
|
15026
14623
|
/**
|
|
15027
14624
|
* Parser functions.
|
|
@@ -15038,6 +14635,61 @@ var import_plist = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((expo
|
|
|
15038
14635
|
exports[k] = builderFunctions[k];
|
|
15039
14636
|
});
|
|
15040
14637
|
})))(), 1);
|
|
14638
|
+
/** Elements whose text can span several lines in a pretty-printed plist. */
|
|
14639
|
+
const TEXT_ELEMENT = /<(key|string|data|date|integer|real)>/;
|
|
14640
|
+
const closingTag = (name) => `</${name}>`;
|
|
14641
|
+
/**
|
|
14642
|
+
* Lays out `plist.build` output the way Xcode writes an Info.plist, so that
|
|
14643
|
+
* writing one key does not shift every other line of the file.
|
|
14644
|
+
*
|
|
14645
|
+
* `plist.build` indents everything under `<plist>` one level, while Xcode
|
|
14646
|
+
* puts the root `<dict>` at column 0. When the previous file had its root at
|
|
14647
|
+
* column 0 (or there is no previous file), every element line under `<plist>`
|
|
14648
|
+
* loses one leading tab. A file whose root is already indented under
|
|
14649
|
+
* `<plist>` (the layout `plist.build` itself writes) is left indented. Text of a multi-line value is left as it is: a text line
|
|
14650
|
+
* never starts with a raw `<`, and lines between an opening and a closing text
|
|
14651
|
+
* tag are skipped. The file keeps the trailing newline it had.
|
|
14652
|
+
*/
|
|
14653
|
+
function formatPlistLikeXcode(built, previous) {
|
|
14654
|
+
const lines = built.split("\n");
|
|
14655
|
+
const formatted = [];
|
|
14656
|
+
let insidePlist = false;
|
|
14657
|
+
let openText = null;
|
|
14658
|
+
const dedent = previous === void 0 || rootIsAtColumnZero(previous);
|
|
14659
|
+
for (const line of lines) {
|
|
14660
|
+
if (openText !== null) {
|
|
14661
|
+
formatted.push(line);
|
|
14662
|
+
if (line.includes(closingTag(openText))) openText = null;
|
|
14663
|
+
continue;
|
|
14664
|
+
}
|
|
14665
|
+
if (line.startsWith("</plist>")) insidePlist = false;
|
|
14666
|
+
formatted.push(dedent && insidePlist && /^\t+</.test(line) ? line.slice(1) : line);
|
|
14667
|
+
if (/^<plist\b/.test(line)) insidePlist = true;
|
|
14668
|
+
const opened = TEXT_ELEMENT.exec(line);
|
|
14669
|
+
if (opened) {
|
|
14670
|
+
if (!line.slice(opened.index + opened[0].length).includes(closingTag(opened[1]))) openText = opened[1];
|
|
14671
|
+
}
|
|
14672
|
+
}
|
|
14673
|
+
let result = formatted.join("\n");
|
|
14674
|
+
if (previous?.endsWith("\n") && !result.endsWith("\n")) result += "\n";
|
|
14675
|
+
return result;
|
|
14676
|
+
}
|
|
14677
|
+
/**
|
|
14678
|
+
* Whether the root element under `<plist>` in `xml` starts at column 0.
|
|
14679
|
+
* Blank lines and XML comments before the root are skipped.
|
|
14680
|
+
*/
|
|
14681
|
+
function rootIsAtColumnZero(xml) {
|
|
14682
|
+
const open = /<plist\b[^>]*>/.exec(xml);
|
|
14683
|
+
if (!open) return true;
|
|
14684
|
+
const rest = xml.slice(open.index + open[0].length).replace(/<!--[\s\S]*?-->/g, (comment) => comment.replace(/[^\n]/g, " "));
|
|
14685
|
+
for (const line of rest.split("\n").slice(1)) {
|
|
14686
|
+
const indent = /^[^\S\n]*(?=<)/.exec(line);
|
|
14687
|
+
if (indent) return indent[0] === "";
|
|
14688
|
+
}
|
|
14689
|
+
return true;
|
|
14690
|
+
}
|
|
14691
|
+
//#endregion
|
|
14692
|
+
//#region src/utils/configParser/bplistParser.ts
|
|
15041
14693
|
const MAX_OBJECT_SIZE = 1e8;
|
|
15042
14694
|
const MAX_OBJECT_COUNT = 32768;
|
|
15043
14695
|
const EPOCH = 9783072e5;
|
|
@@ -15329,13 +14981,14 @@ var IosConfigParser = class {
|
|
|
15329
14981
|
for (const plistFile of plistPaths) {
|
|
15330
14982
|
const relativePath = path.relative(getCwd(), plistFile);
|
|
15331
14983
|
try {
|
|
15332
|
-
const
|
|
14984
|
+
const plistBuffer = await fs.promises.readFile(plistFile);
|
|
14985
|
+
const plistObject = parsePlist(plistBuffer);
|
|
15333
14986
|
if (!(key in plistObject)) continue;
|
|
15334
14987
|
delete plistObject[key];
|
|
15335
|
-
const newPlistXml = import_plist.default.build(plistObject, {
|
|
14988
|
+
const newPlistXml = formatPlistLikeXcode(import_plist.default.build(plistObject, {
|
|
15336
14989
|
indent: " ",
|
|
15337
14990
|
pretty: true
|
|
15338
|
-
});
|
|
14991
|
+
}), plistBuffer.toString("utf-8"));
|
|
15339
14992
|
await fs.promises.writeFile(plistFile, newPlistXml);
|
|
15340
14993
|
updatedPaths.push(relativePath);
|
|
15341
14994
|
} catch (error) {
|
|
@@ -15354,13 +15007,14 @@ var IosConfigParser = class {
|
|
|
15354
15007
|
for (const plistFile of plistPaths) {
|
|
15355
15008
|
const relativePath = path.relative(getCwd(), plistFile);
|
|
15356
15009
|
try {
|
|
15357
|
-
const
|
|
15010
|
+
const plistBuffer = await fs.promises.readFile(plistFile);
|
|
15011
|
+
const plistObject = parsePlist(plistBuffer);
|
|
15358
15012
|
if (plistObject[key] === value) continue;
|
|
15359
15013
|
plistObject[key] = value;
|
|
15360
|
-
const newPlistXml = import_plist.default.build(plistObject, {
|
|
15014
|
+
const newPlistXml = formatPlistLikeXcode(import_plist.default.build(plistObject, {
|
|
15361
15015
|
indent: " ",
|
|
15362
15016
|
pretty: true
|
|
15363
|
-
});
|
|
15017
|
+
}), plistBuffer.toString("utf-8"));
|
|
15364
15018
|
await fs.promises.writeFile(plistFile, newPlistXml);
|
|
15365
15019
|
updatedPaths.push(relativePath);
|
|
15366
15020
|
} catch (error) {
|