@absolutejs/absolute 0.20.0-beta.22 → 0.20.0-beta.24
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/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/cli/index.js +411 -80
- package/dist/mobile/index.js +210 -16
- package/dist/mobile/index.js.map +4 -4
- package/dist/src/mobile/androidTestReport.d.ts +14 -0
- package/dist/src/mobile/deviceCapabilities.d.ts +7 -1
- package/dist/src/mobile/iosTestReport.d.ts +7 -41
- package/dist/src/mobile/nativeTestReport.d.ts +72 -0
- package/package.json +6 -3
package/dist/mobile/index.js
CHANGED
|
@@ -5077,6 +5077,12 @@ var IOS_USAGE_DESCRIPTIONS = new Set([
|
|
|
5077
5077
|
"photo-library",
|
|
5078
5078
|
"photo-library-add"
|
|
5079
5079
|
]);
|
|
5080
|
+
var IOS_PRIVACY_ACCESSED_API_REASONS = {
|
|
5081
|
+
NSPrivacyAccessedAPICategoryFileTimestamp: new Set(["C617.1"])
|
|
5082
|
+
};
|
|
5083
|
+
var IOS_PRIVACY_ACCESSED_APIS = [
|
|
5084
|
+
"NSPrivacyAccessedAPICategoryFileTimestamp"
|
|
5085
|
+
];
|
|
5080
5086
|
var object2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5081
5087
|
var readJson = (path) => {
|
|
5082
5088
|
const value = JSON.parse(readFileSync4(path, "utf8"));
|
|
@@ -5099,15 +5105,38 @@ var androidPermissions = (value, field) => {
|
|
|
5099
5105
|
throw new TypeError(`${field}.permissions must contain Android permission names.`);
|
|
5100
5106
|
return [...permissions];
|
|
5101
5107
|
};
|
|
5102
|
-
var
|
|
5108
|
+
var iosPrivacyAccessedApis = (value, field) => {
|
|
5109
|
+
if (value === undefined)
|
|
5110
|
+
return;
|
|
5111
|
+
if (!object2(value))
|
|
5112
|
+
throw new TypeError(`${field} must be an object.`);
|
|
5113
|
+
const privacy = {};
|
|
5114
|
+
for (const api of IOS_PRIVACY_ACCESSED_APIS) {
|
|
5115
|
+
const reasons = value[api];
|
|
5116
|
+
if (reasons === undefined)
|
|
5117
|
+
continue;
|
|
5118
|
+
const supported = IOS_PRIVACY_ACCESSED_API_REASONS[api];
|
|
5119
|
+
if (!Array.isArray(reasons) || reasons.length === 0 || !reasons.every((reason) => typeof reason === "string" && supported.has(reason)))
|
|
5120
|
+
throw new TypeError(`${field} contains an unsupported API or reason.`);
|
|
5121
|
+
privacy[api] = [...reasons];
|
|
5122
|
+
}
|
|
5123
|
+
if (Object.keys(value).some((api) => !IOS_PRIVACY_ACCESSED_APIS.some((known) => known === api)))
|
|
5124
|
+
throw new TypeError(`${field} contains an unsupported API or reason.`);
|
|
5125
|
+
return privacy;
|
|
5126
|
+
};
|
|
5127
|
+
var iosNativeRequirements = (value, field) => {
|
|
5103
5128
|
if (value === undefined)
|
|
5104
5129
|
return;
|
|
5105
5130
|
if (!object2(value))
|
|
5106
5131
|
throw new TypeError(`${field} must be an object.`);
|
|
5107
|
-
const { usageDescriptions } = value;
|
|
5108
|
-
if (!Array.isArray(usageDescriptions) || !usageDescriptions.every((purpose) => typeof purpose === "string" && IOS_USAGE_DESCRIPTIONS.has(purpose)))
|
|
5132
|
+
const { privacyAccessedApis, usageDescriptions } = value;
|
|
5133
|
+
if (usageDescriptions !== undefined && (!Array.isArray(usageDescriptions) || !usageDescriptions.every((purpose) => typeof purpose === "string" && IOS_USAGE_DESCRIPTIONS.has(purpose))))
|
|
5109
5134
|
throw new TypeError(`${field}.usageDescriptions contains an unsupported purpose.`);
|
|
5110
|
-
|
|
5135
|
+
const privacy = iosPrivacyAccessedApis(privacyAccessedApis, `${field}.privacyAccessedApis`);
|
|
5136
|
+
return {
|
|
5137
|
+
...privacy === undefined ? {} : { privacyAccessedApis: privacy },
|
|
5138
|
+
...usageDescriptions === undefined ? {} : { usageDescriptions: [...usageDescriptions] }
|
|
5139
|
+
};
|
|
5111
5140
|
};
|
|
5112
5141
|
var parseProvider = (name, value) => {
|
|
5113
5142
|
if (!IDENTIFIER_PATTERN.test(name))
|
|
@@ -5129,10 +5158,10 @@ var parseProvider = (name, value) => {
|
|
|
5129
5158
|
throw new TypeError(`${name}.native must be an object.`);
|
|
5130
5159
|
const { android, ios } = nativeMetadata;
|
|
5131
5160
|
const permissions = androidPermissions(android, `${name}.native.android`);
|
|
5132
|
-
const
|
|
5161
|
+
const iosRequirements = iosNativeRequirements(ios, `${name}.native.ios`);
|
|
5133
5162
|
native = {
|
|
5134
5163
|
...permissions === undefined ? {} : { android: { permissions } },
|
|
5135
|
-
...
|
|
5164
|
+
...iosRequirements === undefined ? {} : { ios: iosRequirements }
|
|
5136
5165
|
};
|
|
5137
5166
|
}
|
|
5138
5167
|
return {
|
|
@@ -5142,14 +5171,32 @@ var parseProvider = (name, value) => {
|
|
|
5142
5171
|
packages: [...value.packages]
|
|
5143
5172
|
};
|
|
5144
5173
|
};
|
|
5145
|
-
var absoluteDeviceNativeRequirements = (plan) =>
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
|
|
5174
|
+
var absoluteDeviceNativeRequirements = (plan) => {
|
|
5175
|
+
const privacy = plan.capabilities.reduce((requirements, name) => {
|
|
5176
|
+
for (const api of IOS_PRIVACY_ACCESSED_APIS) {
|
|
5177
|
+
const reasons = plan.providers[name]?.native?.ios?.privacyAccessedApis?.[api] ?? [];
|
|
5178
|
+
if (reasons.length === 0)
|
|
5179
|
+
continue;
|
|
5180
|
+
const current = requirements[api] ?? new Set;
|
|
5181
|
+
for (const reason of reasons)
|
|
5182
|
+
current.add(reason);
|
|
5183
|
+
requirements[api] = current;
|
|
5184
|
+
}
|
|
5185
|
+
return requirements;
|
|
5186
|
+
}, {});
|
|
5187
|
+
return {
|
|
5188
|
+
androidPermissions: [
|
|
5189
|
+
...new Set(plan.capabilities.flatMap((name) => plan.providers[name]?.native?.android?.permissions ?? []))
|
|
5190
|
+
].sort(),
|
|
5191
|
+
iosPrivacyAccessedApis: IOS_PRIVACY_ACCESSED_APIS.flatMap((api) => {
|
|
5192
|
+
const reasons = privacy[api];
|
|
5193
|
+
return reasons ? [{ api, reasons: [...reasons].sort() }] : [];
|
|
5194
|
+
}),
|
|
5195
|
+
iosUsageDescriptions: [
|
|
5196
|
+
...new Set(plan.capabilities.flatMap((name) => plan.providers[name]?.native?.ios?.usageDescriptions ?? []))
|
|
5197
|
+
].sort()
|
|
5198
|
+
};
|
|
5199
|
+
};
|
|
5153
5200
|
var loadAbsoluteDeviceCapabilityProviders = (projectRoot) => {
|
|
5154
5201
|
const path = join13(resolve11(projectRoot), "node_modules", CAPACITOR_ADAPTER, "package.json");
|
|
5155
5202
|
const manifest = readJson(path);
|
|
@@ -5780,6 +5827,8 @@ import { join as join16 } from "path";
|
|
|
5780
5827
|
var START_MARKER2 = "<!-- absolutejs:device-capabilities:start -->";
|
|
5781
5828
|
var END_MARKER2 = "<!-- absolutejs:device-capabilities:end -->";
|
|
5782
5829
|
var NOT_FOUND2 = -1;
|
|
5830
|
+
var IOS_PRIVACY_FILE_REFERENCE = "A85D0C000000000000000001";
|
|
5831
|
+
var IOS_PRIVACY_BUILD_FILE = "A85D0C000000000000000002";
|
|
5783
5832
|
var escapeXml2 = (value) => value.replaceAll("&", "&").replaceAll('"', """).replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">");
|
|
5784
5833
|
var writeChangedFile2 = async (path, source) => {
|
|
5785
5834
|
const current = await readFile15(path, "utf8");
|
|
@@ -5790,6 +5839,15 @@ var writeChangedFile2 = async (path, source) => {
|
|
|
5790
5839
|
await rename12(temporary, path);
|
|
5791
5840
|
return true;
|
|
5792
5841
|
};
|
|
5842
|
+
var optionalSource = async (path) => {
|
|
5843
|
+
try {
|
|
5844
|
+
return await readFile15(path, "utf8");
|
|
5845
|
+
} catch (error) {
|
|
5846
|
+
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
5847
|
+
return null;
|
|
5848
|
+
throw error;
|
|
5849
|
+
}
|
|
5850
|
+
};
|
|
5793
5851
|
var managed = (source, region, insertion) => {
|
|
5794
5852
|
const start = source.indexOf(START_MARKER2);
|
|
5795
5853
|
const end = source.indexOf(END_MARKER2);
|
|
@@ -5827,6 +5885,134 @@ var iosDescription = (appName, purpose) => {
|
|
|
5827
5885
|
return `${appName} does not track location in the background; this description supports the foreground location provider required by the native runtime.`;
|
|
5828
5886
|
return `${appName} adds to your photo library only for photo actions you choose.`;
|
|
5829
5887
|
};
|
|
5888
|
+
var privacyEntries = (requirements) => requirements.iosPrivacyAccessedApis.map(({ api, reasons }) => ` <dict>
|
|
5889
|
+
<key>NSPrivacyAccessedAPIType</key>
|
|
5890
|
+
<string>${escapeXml2(api)}</string>
|
|
5891
|
+
<key>NSPrivacyAccessedAPITypeReasons</key>
|
|
5892
|
+
<array>
|
|
5893
|
+
${reasons.map((reason) => ` <string>${escapeXml2(reason)}</string>`).join(`
|
|
5894
|
+
`)}
|
|
5895
|
+
</array>
|
|
5896
|
+
</dict>`).join(`
|
|
5897
|
+
`);
|
|
5898
|
+
var privacyManifestSource = (source, requirements) => {
|
|
5899
|
+
const entries = privacyEntries(requirements);
|
|
5900
|
+
const wholeRegion = entries ? ` ${START_MARKER2}
|
|
5901
|
+
<key>NSPrivacyAccessedAPITypes</key>
|
|
5902
|
+
<array>
|
|
5903
|
+
${entries}
|
|
5904
|
+
</array>
|
|
5905
|
+
${END_MARKER2}
|
|
5906
|
+
` : "";
|
|
5907
|
+
if (source === null)
|
|
5908
|
+
return entries ? `<?xml version="1.0" encoding="UTF-8"?>
|
|
5909
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
5910
|
+
<plist version="1.0">
|
|
5911
|
+
<dict>
|
|
5912
|
+
${wholeRegion} <key>NSPrivacyCollectedDataTypes</key>
|
|
5913
|
+
<array/>
|
|
5914
|
+
<key>NSPrivacyTracking</key>
|
|
5915
|
+
<false/>
|
|
5916
|
+
</dict>
|
|
5917
|
+
</plist>
|
|
5918
|
+
` : null;
|
|
5919
|
+
const start = source.indexOf(START_MARKER2);
|
|
5920
|
+
if (start !== NOT_FOUND2) {
|
|
5921
|
+
const end = source.indexOf(END_MARKER2);
|
|
5922
|
+
if (end === NOT_FOUND2)
|
|
5923
|
+
throw new TypeError("AbsoluteJS device-capability ownership markers are malformed.");
|
|
5924
|
+
const owned = source.slice(start, end);
|
|
5925
|
+
const ownsWholeKey = owned.includes("NSPrivacyAccessedAPITypes");
|
|
5926
|
+
let region = "";
|
|
5927
|
+
if (ownsWholeKey)
|
|
5928
|
+
region = wholeRegion;
|
|
5929
|
+
else if (entries)
|
|
5930
|
+
region = ` ${START_MARKER2}
|
|
5931
|
+
${entries}
|
|
5932
|
+
${END_MARKER2}
|
|
5933
|
+
`;
|
|
5934
|
+
return managed(source, region, source.lastIndexOf("</dict>"));
|
|
5935
|
+
}
|
|
5936
|
+
const key = source.indexOf("<key>NSPrivacyAccessedAPITypes</key>");
|
|
5937
|
+
if (key === NOT_FOUND2)
|
|
5938
|
+
return managed(source, wholeRegion, source.lastIndexOf("</dict>"));
|
|
5939
|
+
if (!entries)
|
|
5940
|
+
return source;
|
|
5941
|
+
const array = source.indexOf("<array>", key);
|
|
5942
|
+
if (array === NOT_FOUND2)
|
|
5943
|
+
throw new TypeError("iOS PrivacyInfo.xcprivacy has a malformed NSPrivacyAccessedAPITypes value.");
|
|
5944
|
+
const insertion = source.indexOf(`
|
|
5945
|
+
`, array);
|
|
5946
|
+
if (insertion === NOT_FOUND2)
|
|
5947
|
+
throw new TypeError("iOS PrivacyInfo.xcprivacy array is malformed.");
|
|
5948
|
+
return managed(source, ` ${START_MARKER2}
|
|
5949
|
+
${entries}
|
|
5950
|
+
${END_MARKER2}
|
|
5951
|
+
`, insertion + 1);
|
|
5952
|
+
};
|
|
5953
|
+
var writeIosPrivacyManifest = async (path, current, source) => {
|
|
5954
|
+
if (source === null)
|
|
5955
|
+
return false;
|
|
5956
|
+
if (current !== null)
|
|
5957
|
+
return writeChangedFile2(path, source);
|
|
5958
|
+
await writeFile13(path, source, { flag: "wx" });
|
|
5959
|
+
return true;
|
|
5960
|
+
};
|
|
5961
|
+
var configureIosPrivacyProject = async (config, requirements) => {
|
|
5962
|
+
if (requirements.iosPrivacyAccessedApis.length === 0)
|
|
5963
|
+
return false;
|
|
5964
|
+
const projectPath = join16(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
|
|
5965
|
+
const project = await readFile15(projectPath, "utf8");
|
|
5966
|
+
return writeChangedFile2(projectPath, addIosPrivacyProjectReference(project));
|
|
5967
|
+
};
|
|
5968
|
+
var addIosPrivacyProjectReference = (source) => {
|
|
5969
|
+
const fileMatch = source.match(/([A-F0-9]{24}) \/\* PrivacyInfo\.xcprivacy \*\/ = \{isa = PBXFileReference;/u);
|
|
5970
|
+
const fileReference = fileMatch?.[1] ?? IOS_PRIVACY_FILE_REFERENCE;
|
|
5971
|
+
const buildMatch = source.match(/([A-F0-9]{24}) \/\* PrivacyInfo\.xcprivacy in Resources \*\/ = \{isa = PBXBuildFile;/u);
|
|
5972
|
+
const buildFile = buildMatch?.[1] ?? IOS_PRIVACY_BUILD_FILE;
|
|
5973
|
+
if (!fileMatch && source.includes(fileReference) || !buildMatch && source.includes(buildFile))
|
|
5974
|
+
throw new TypeError("AbsoluteJS iOS privacy-manifest identifiers collide.");
|
|
5975
|
+
let next = source;
|
|
5976
|
+
if (!buildMatch) {
|
|
5977
|
+
const marker = "/* End PBXBuildFile section */";
|
|
5978
|
+
const index = next.indexOf(marker);
|
|
5979
|
+
if (index === NOT_FOUND2)
|
|
5980
|
+
throw new TypeError("Could not find the iOS PBXBuildFile section.");
|
|
5981
|
+
next = `${next.slice(0, index)} ${buildFile} /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = ${fileReference} /* PrivacyInfo.xcprivacy */; };
|
|
5982
|
+
${next.slice(index)}`;
|
|
5983
|
+
}
|
|
5984
|
+
if (!fileMatch) {
|
|
5985
|
+
const marker = "/* End PBXFileReference section */";
|
|
5986
|
+
const index = next.indexOf(marker);
|
|
5987
|
+
if (index === NOT_FOUND2)
|
|
5988
|
+
throw new TypeError("Could not find the iOS PBXFileReference section.");
|
|
5989
|
+
next = `${next.slice(0, index)} ${fileReference} /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
|
5990
|
+
${next.slice(index)}`;
|
|
5991
|
+
}
|
|
5992
|
+
const groupsStart = next.indexOf("/* Begin PBXGroup section */");
|
|
5993
|
+
const groupsEnd = next.indexOf("/* End PBXGroup section */");
|
|
5994
|
+
const groups = next.slice(groupsStart, groupsEnd);
|
|
5995
|
+
if (!groups.includes(`${fileReference} /* PrivacyInfo.xcprivacy */`)) {
|
|
5996
|
+
const appGroup = groups.match(/[A-F0-9]{24} \/\* App \*\/ = \{\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = \(\n/u);
|
|
5997
|
+
if (!appGroup || appGroup.index === undefined)
|
|
5998
|
+
throw new TypeError("Could not find the iOS App PBXGroup.");
|
|
5999
|
+
const index = groupsStart + appGroup.index + appGroup[0].length;
|
|
6000
|
+
next = `${next.slice(0, index)} ${fileReference} /* PrivacyInfo.xcprivacy */,
|
|
6001
|
+
${next.slice(index)}`;
|
|
6002
|
+
}
|
|
6003
|
+
const resourcesStart = next.indexOf("/* Begin PBXResourcesBuildPhase section */");
|
|
6004
|
+
const resourcesEnd = next.indexOf("/* End PBXResourcesBuildPhase section */");
|
|
6005
|
+
const resources = next.slice(resourcesStart, resourcesEnd);
|
|
6006
|
+
if (!resources.includes(`${buildFile} /* PrivacyInfo.xcprivacy in Resources */`)) {
|
|
6007
|
+
const files = resources.match(/isa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = \d+;\n\t\t\tfiles = \(\n/u);
|
|
6008
|
+
if (!files || files.index === undefined)
|
|
6009
|
+
throw new TypeError("Could not find the iOS Resources build phase.");
|
|
6010
|
+
const index = resourcesStart + files.index + files[0].length;
|
|
6011
|
+
next = `${next.slice(0, index)} ${buildFile} /* PrivacyInfo.xcprivacy in Resources */,
|
|
6012
|
+
${next.slice(index)}`;
|
|
6013
|
+
}
|
|
6014
|
+
return next;
|
|
6015
|
+
};
|
|
5830
6016
|
var configureIos2 = async (config, plan) => {
|
|
5831
6017
|
const path = join16(config.nativeProjectDirectory, "ios/App/App/Info.plist");
|
|
5832
6018
|
const source = await readFile15(path, "utf8");
|
|
@@ -5838,7 +6024,15 @@ var configureIos2 = async (config, plan) => {
|
|
|
5838
6024
|
${content}
|
|
5839
6025
|
${END_MARKER2}
|
|
5840
6026
|
` : "";
|
|
5841
|
-
|
|
6027
|
+
const infoChanged = await writeChangedFile2(path, managed(source, region, source.lastIndexOf("</dict>")));
|
|
6028
|
+
const privacyPath = join16(config.nativeProjectDirectory, "ios/App/App/PrivacyInfo.xcprivacy");
|
|
6029
|
+
const privacyCurrent = await optionalSource(privacyPath);
|
|
6030
|
+
const privacySource = privacyManifestSource(privacyCurrent, requirements);
|
|
6031
|
+
const [privacyChanged, projectChanged] = await Promise.all([
|
|
6032
|
+
writeIosPrivacyManifest(privacyPath, privacyCurrent, privacySource),
|
|
6033
|
+
configureIosPrivacyProject(config, requirements)
|
|
6034
|
+
]);
|
|
6035
|
+
return infoChanged || privacyChanged || projectChanged;
|
|
5842
6036
|
};
|
|
5843
6037
|
var configureAndroid2 = async (config, plan) => {
|
|
5844
6038
|
const path = join16(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
|
|
@@ -6614,5 +6808,5 @@ export {
|
|
|
6614
6808
|
ABSOLUTE_ANDROID_RELEASE_FORMAT
|
|
6615
6809
|
};
|
|
6616
6810
|
|
|
6617
|
-
//# debugId=
|
|
6811
|
+
//# debugId=443011A81611F30D64756E2164756E21
|
|
6618
6812
|
//# sourceMappingURL=index.js.map
|