voltra 2.2.0 → 2.3.1
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/build/cjs/apply/index.js +6 -1
- package/build/cjs/apply/index.js.map +1 -1
- package/build/cjs/config/normalize.js +150 -31
- package/build/cjs/config/normalize.js.map +1 -1
- package/build/cjs/config/perConfiguration.js +29 -0
- package/build/cjs/config/perConfiguration.js.map +1 -0
- package/build/cjs/config/serverUpdate.js +119 -0
- package/build/cjs/config/serverUpdate.js.map +1 -0
- package/build/cjs/config/widgetKind.js +25 -0
- package/build/cjs/config/widgetKind.js.map +1 -0
- package/build/cjs/dependencies/platformPackages.js +9 -0
- package/build/cjs/dependencies/platformPackages.js.map +1 -1
- package/build/cjs/discovery/ios.js +50 -31
- package/build/cjs/discovery/ios.js.map +1 -1
- package/build/cjs/discovery/metro.js +52 -0
- package/build/cjs/discovery/metro.js.map +1 -0
- package/build/cjs/index.js +6 -2
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/platforms/android/generated.js +98 -40
- package/build/cjs/platforms/android/generated.js.map +1 -1
- package/build/cjs/platforms/android/widgetSizing.js +89 -0
- package/build/cjs/platforms/android/widgetSizing.js.map +1 -0
- package/build/cjs/platforms/ios/apply.js +21 -11
- package/build/cjs/platforms/ios/apply.js.map +1 -1
- package/build/cjs/platforms/ios/buildConfigurationValues.js +73 -0
- package/build/cjs/platforms/ios/buildConfigurationValues.js.map +1 -0
- package/build/cjs/platforms/ios/entitlements.js +34 -19
- package/build/cjs/platforms/ios/entitlements.js.map +1 -1
- package/build/cjs/platforms/ios/generated.js +79 -32
- package/build/cjs/platforms/ios/generated.js.map +1 -1
- package/build/cjs/platforms/ios/plist.js +22 -4
- package/build/cjs/platforms/ios/plist.js.map +1 -1
- package/build/cjs/platforms/ios/targetName.js.map +1 -1
- package/build/cjs/platforms/ios/xcodeTarget.js +166 -23
- package/build/cjs/platforms/ios/xcodeTarget.js.map +1 -1
- package/build/cjs/platforms/shared/widgetModule.js +18 -145
- package/build/cjs/platforms/shared/widgetModule.js.map +1 -1
- package/build/esm/apply/index.js +6 -1
- package/build/esm/apply/index.js.map +1 -1
- package/build/esm/config/normalize.js +150 -31
- package/build/esm/config/normalize.js.map +1 -1
- package/build/esm/config/perConfiguration.js +25 -0
- package/build/esm/config/perConfiguration.js.map +1 -0
- package/build/esm/config/serverUpdate.js +112 -0
- package/build/esm/config/serverUpdate.js.map +1 -0
- package/build/esm/config/widgetKind.js +20 -0
- package/build/esm/config/widgetKind.js.map +1 -0
- package/build/esm/dependencies/platformPackages.js +8 -0
- package/build/esm/dependencies/platformPackages.js.map +1 -1
- package/build/esm/discovery/ios.js +50 -31
- package/build/esm/discovery/ios.js.map +1 -1
- package/build/esm/discovery/metro.js +46 -0
- package/build/esm/discovery/metro.js.map +1 -0
- package/build/esm/index.js +1 -0
- package/build/esm/index.js.map +1 -1
- package/build/esm/platforms/android/generated.js +100 -42
- package/build/esm/platforms/android/generated.js.map +1 -1
- package/build/esm/platforms/android/widgetSizing.js +85 -0
- package/build/esm/platforms/android/widgetSizing.js.map +1 -0
- package/build/esm/platforms/ios/apply.js +21 -11
- package/build/esm/platforms/ios/apply.js.map +1 -1
- package/build/esm/platforms/ios/buildConfigurationValues.js +68 -0
- package/build/esm/platforms/ios/buildConfigurationValues.js.map +1 -0
- package/build/esm/platforms/ios/entitlements.js +34 -19
- package/build/esm/platforms/ios/entitlements.js.map +1 -1
- package/build/esm/platforms/ios/generated.js +80 -33
- package/build/esm/platforms/ios/generated.js.map +1 -1
- package/build/esm/platforms/ios/plist.js +22 -4
- package/build/esm/platforms/ios/plist.js.map +1 -1
- package/build/esm/platforms/ios/targetName.js.map +1 -1
- package/build/esm/platforms/ios/xcodeTarget.js +166 -23
- package/build/esm/platforms/ios/xcodeTarget.js.map +1 -1
- package/build/esm/platforms/shared/widgetModule.js +16 -107
- package/build/esm/platforms/shared/widgetModule.js.map +1 -1
- package/build/types/apply/index.d.ts.map +1 -1
- package/build/types/config/normalize.d.ts.map +1 -1
- package/build/types/config/perConfiguration.d.ts +18 -0
- package/build/types/config/perConfiguration.d.ts.map +1 -0
- package/build/types/config/serverUpdate.d.ts +80 -0
- package/build/types/config/serverUpdate.d.ts.map +1 -0
- package/build/types/config/types.d.ts +91 -30
- package/build/types/config/types.d.ts.map +1 -1
- package/build/types/config/widgetKind.d.ts +11 -0
- package/build/types/config/widgetKind.d.ts.map +1 -0
- package/build/types/dependencies/platformPackages.d.ts +1 -0
- package/build/types/dependencies/platformPackages.d.ts.map +1 -1
- package/build/types/discovery/ios.d.ts +10 -0
- package/build/types/discovery/ios.d.ts.map +1 -1
- package/build/types/discovery/metro.d.ts +21 -0
- package/build/types/discovery/metro.d.ts.map +1 -0
- package/build/types/index.d.ts +3 -1
- package/build/types/index.d.ts.map +1 -1
- package/build/types/platforms/android/generated.d.ts.map +1 -1
- package/build/types/platforms/android/widgetSizing.d.ts +50 -0
- package/build/types/platforms/android/widgetSizing.d.ts.map +1 -0
- package/build/types/platforms/ios/apply.d.ts.map +1 -1
- package/build/types/platforms/ios/buildConfigurationValues.d.ts +33 -0
- package/build/types/platforms/ios/buildConfigurationValues.d.ts.map +1 -0
- package/build/types/platforms/ios/entitlements.d.ts +4 -4
- package/build/types/platforms/ios/entitlements.d.ts.map +1 -1
- package/build/types/platforms/ios/generated.d.ts +14 -2
- package/build/types/platforms/ios/generated.d.ts.map +1 -1
- package/build/types/platforms/ios/plist.d.ts +3 -3
- package/build/types/platforms/ios/plist.d.ts.map +1 -1
- package/build/types/platforms/ios/podfile.d.ts +2 -2
- package/build/types/platforms/ios/podfile.d.ts.map +1 -1
- package/build/types/platforms/ios/targetName.d.ts +2 -2
- package/build/types/platforms/ios/targetName.d.ts.map +1 -1
- package/build/types/platforms/ios/xcodeTarget.d.ts +4 -2
- package/build/types/platforms/ios/xcodeTarget.d.ts.map +1 -1
- package/build/types/platforms/shared/widgetModule.d.ts +12 -3
- package/build/types/platforms/shared/widgetModule.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/apply/index.ts +6 -1
- package/src/config/normalize.node.test.ts +105 -0
- package/src/config/normalize.ts +217 -45
- package/src/config/perConfiguration.ts +49 -0
- package/src/config/serverUpdate.ts +160 -0
- package/src/config/types.ts +97 -30
- package/src/config/widgetKind.node.test.ts +27 -0
- package/src/config/widgetKind.ts +27 -0
- package/src/dependencies/platformPackages.ts +11 -0
- package/src/discovery/ios.ts +104 -60
- package/src/discovery/metro.node.test.ts +91 -0
- package/src/discovery/metro.ts +54 -0
- package/src/index.ts +8 -0
- package/src/platforms/android/generated.ts +144 -47
- package/src/platforms/android/widgetSizing.ts +112 -0
- package/src/platforms/ios/apply.ts +21 -11
- package/src/platforms/ios/buildConfigurationValues.ts +105 -0
- package/src/platforms/ios/entitlements.ts +55 -31
- package/src/platforms/ios/generated.node.test.ts +61 -0
- package/src/platforms/ios/generated.ts +137 -38
- package/src/platforms/ios/plist.ts +36 -7
- package/src/platforms/ios/podfile.ts +2 -2
- package/src/platforms/ios/targetName.ts +2 -2
- package/src/platforms/ios/xcodeTarget.ts +248 -43
- package/src/platforms/shared/widgetModule.ts +22 -140
|
@@ -5,6 +5,7 @@ exports.applyIOSPlatform = applyIOSPlatform;
|
|
|
5
5
|
const ios_1 = require("../../discovery/ios");
|
|
6
6
|
const platformPackages_1 = require("../../dependencies/platformPackages");
|
|
7
7
|
const summary_1 = require("../../reporting/summary");
|
|
8
|
+
const buildConfigurationValues_1 = require("./buildConfigurationValues");
|
|
8
9
|
const entitlements_1 = require("./entitlements");
|
|
9
10
|
const generated_1 = require("./generated");
|
|
10
11
|
const plist_1 = require("./plist");
|
|
@@ -41,32 +42,36 @@ async function applyIOSPlatform(context) {
|
|
|
41
42
|
throw new summary_1.VoltraCliError('iOS config is missing.');
|
|
42
43
|
}
|
|
43
44
|
const discovery = getIOSDiscovery(context.preflight);
|
|
45
|
+
// Values given per build configuration are collapsed once, so every mutator below sees a plain
|
|
46
|
+
// string and the project carries the per-configuration values.
|
|
47
|
+
const { ios, buildSettings } = (0, buildConfigurationValues_1.resolveIOSBuildConfigurationValues)(iosConfig, discovery);
|
|
44
48
|
const generatedResult = await (0, generated_1.generateIOSFiles)({
|
|
45
49
|
projectRoot: context.config.projectRoot,
|
|
46
|
-
ios
|
|
50
|
+
ios,
|
|
47
51
|
discovery,
|
|
48
52
|
});
|
|
49
53
|
const entitlementsResult = await (0, entitlements_1.ensureEntitlements)({
|
|
50
54
|
projectRoot: context.config.projectRoot,
|
|
51
|
-
ios
|
|
55
|
+
ios,
|
|
52
56
|
discovery,
|
|
53
57
|
});
|
|
54
58
|
const infoPlistResult = await (0, plist_1.ensureInfoPlist)({
|
|
55
59
|
projectRoot: context.config.projectRoot,
|
|
56
|
-
ios
|
|
60
|
+
ios,
|
|
57
61
|
discovery,
|
|
58
62
|
});
|
|
59
63
|
const podfileResult = await (0, podfile_1.ensurePodfileBlock)({
|
|
60
64
|
projectRoot: context.config.projectRoot,
|
|
61
|
-
ios
|
|
65
|
+
ios,
|
|
62
66
|
discovery,
|
|
63
67
|
});
|
|
64
68
|
const xcodeTargetResult = await (0, xcodeTarget_1.ensureIOSWidgetTarget)({
|
|
65
69
|
projectRoot: context.config.projectRoot,
|
|
66
|
-
ios
|
|
70
|
+
ios,
|
|
67
71
|
discovery,
|
|
68
72
|
generatedFiles: generatedResult.files,
|
|
69
73
|
previousGeneratedFiles: context.previousState?.files,
|
|
74
|
+
buildSettings,
|
|
70
75
|
});
|
|
71
76
|
if (generatedResult.targetName !== xcodeTargetResult.targetName) {
|
|
72
77
|
throw new summary_1.VoltraCliError(`iOS generated files and Xcode target mutation resolved different widget target names: ${generatedResult.targetName} vs ${xcodeTargetResult.targetName}.`);
|
|
@@ -75,11 +80,10 @@ async function applyIOSPlatform(context) {
|
|
|
75
80
|
throw new summary_1.VoltraCliError(`iOS generated files and Podfile block resolved different widget target names: ${generatedResult.targetName} vs ${podfileResult.targetName}.`);
|
|
76
81
|
}
|
|
77
82
|
const changes = [
|
|
78
|
-
infoPlistResult.
|
|
79
|
-
entitlementsResult.
|
|
80
|
-
podfileResult.change,
|
|
81
|
-
|
|
82
|
-
].filter(isDefined);
|
|
83
|
+
...infoPlistResult.changes,
|
|
84
|
+
...entitlementsResult.changes,
|
|
85
|
+
...[podfileResult.change, xcodeTargetResult.change].filter(isDefined),
|
|
86
|
+
];
|
|
83
87
|
return {
|
|
84
88
|
platform: 'ios',
|
|
85
89
|
changes: [...changes, ...generatedResult.changes],
|
|
@@ -105,7 +109,13 @@ function isIOSProjectDiscovery(value) {
|
|
|
105
109
|
candidate.podfilePath,
|
|
106
110
|
candidate.mainTargetName,
|
|
107
111
|
candidate.infoPlistPath,
|
|
108
|
-
].every((entry) => typeof entry === 'string' && entry.length > 0) &&
|
|
112
|
+
].every((entry) => typeof entry === 'string' && entry.length > 0) &&
|
|
113
|
+
[
|
|
114
|
+
candidate.mainTargetCandidates,
|
|
115
|
+
candidate.buildConfigurationNames,
|
|
116
|
+
candidate.infoPlistPaths,
|
|
117
|
+
candidate.entitlementsPaths,
|
|
118
|
+
].every((entry) => Array.isArray(entry)));
|
|
109
119
|
}
|
|
110
120
|
function isDefined(value) {
|
|
111
121
|
return value !== undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../../../src/platforms/ios/apply.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../../../src/platforms/ios/apply.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IOSBuildConfigurationValueError = exports.VOLTRA_OWNED_BUILD_SETTINGS = exports.VOLTRA_BUILD_SETTING_PREFIX = void 0;
|
|
4
|
+
exports.resolveIOSBuildConfigurationValues = resolveIOSBuildConfigurationValues;
|
|
5
|
+
const perConfiguration_1 = require("../../config/perConfiguration");
|
|
6
|
+
const summary_1 = require("../../reporting/summary");
|
|
7
|
+
/**
|
|
8
|
+
* Prefix of the user-defined build settings Voltra writes. Settings under it are Voltra's to add
|
|
9
|
+
* and remove, so a value that stops being per build configuration leaves nothing behind.
|
|
10
|
+
*/
|
|
11
|
+
exports.VOLTRA_BUILD_SETTING_PREFIX = 'VOLTRA_';
|
|
12
|
+
const APP_GROUP_IDENTIFIER_SETTING = `${exports.VOLTRA_BUILD_SETTING_PREFIX}APP_GROUP_IDENTIFIER`;
|
|
13
|
+
const KEYCHAIN_GROUP_SETTING = `${exports.VOLTRA_BUILD_SETTING_PREFIX}KEYCHAIN_GROUP`;
|
|
14
|
+
/**
|
|
15
|
+
* The settings Voltra writes and is therefore allowed to remove. Anything else a project happens to
|
|
16
|
+
* name `VOLTRA_*` belongs to the user and is left alone.
|
|
17
|
+
*/
|
|
18
|
+
exports.VOLTRA_OWNED_BUILD_SETTINGS = [APP_GROUP_IDENTIFIER_SETTING, KEYCHAIN_GROUP_SETTING];
|
|
19
|
+
class IOSBuildConfigurationValueError extends summary_1.VoltraCliError {
|
|
20
|
+
constructor(message) {
|
|
21
|
+
super(message, 'VOLTRA_IOS_BUILD_CONFIGURATION_VALUE_FAILED');
|
|
22
|
+
this.name = 'IOSBuildConfigurationValueError';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.IOSBuildConfigurationValueError = IOSBuildConfigurationValueError;
|
|
26
|
+
/**
|
|
27
|
+
* Collapses per-build-configuration values into the single strings the platform mutators consume.
|
|
28
|
+
*
|
|
29
|
+
* A plain string resolves to itself and writes no build settings. A value given per build
|
|
30
|
+
* configuration becomes a user-defined build setting holding one value per configuration, and
|
|
31
|
+
* resolves to a reference to that setting, which Xcode expands per build into the entitlements and
|
|
32
|
+
* Info.plist files. The app and the generated widget extension both read the value that way, so
|
|
33
|
+
* nothing downstream has to know which environment is being built.
|
|
34
|
+
*/
|
|
35
|
+
function resolveIOSBuildConfigurationValues(ios, discovery) {
|
|
36
|
+
const buildSettings = new Map();
|
|
37
|
+
const resolve = (settingName, value, context) => {
|
|
38
|
+
if (!(0, perConfiguration_1.isPerConfigurationMap)(value)) {
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
const valuesByBuildConfiguration = (0, perConfiguration_1.getValuesByBuildConfiguration)(value, discovery.buildConfigurationNames, context, (message) => new IOSBuildConfigurationValueError(message));
|
|
42
|
+
for (const [buildConfigurationName, configurationValue] of valuesByBuildConfiguration) {
|
|
43
|
+
const configurationSettings = buildSettings.get(buildConfigurationName) ?? {};
|
|
44
|
+
configurationSettings[settingName] = configurationValue;
|
|
45
|
+
buildSettings.set(buildConfigurationName, configurationSettings);
|
|
46
|
+
}
|
|
47
|
+
return `$(${settingName})`;
|
|
48
|
+
};
|
|
49
|
+
return {
|
|
50
|
+
ios: {
|
|
51
|
+
...ios,
|
|
52
|
+
groupIdentifier: resolve(APP_GROUP_IDENTIFIER_SETTING, ios.groupIdentifier, 'ios.groupIdentifier'),
|
|
53
|
+
keychainGroup: resolve(KEYCHAIN_GROUP_SETTING, ios.keychainGroup, 'ios.keychainGroup'),
|
|
54
|
+
project: {
|
|
55
|
+
...ios.project,
|
|
56
|
+
entitlementsPath: resolveEntitlementsPath(ios.project.entitlementsPath, discovery),
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
buildSettings,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The entitlements file of the default build configuration. Unlike a value written into a file, a
|
|
64
|
+
* per-configuration entitlements path is a build setting of its own, so it is applied to the Xcode
|
|
65
|
+
* project directly rather than through a reference.
|
|
66
|
+
*/
|
|
67
|
+
function resolveEntitlementsPath(entitlementsPath, discovery) {
|
|
68
|
+
if (!(0, perConfiguration_1.isPerConfigurationMap)(entitlementsPath)) {
|
|
69
|
+
return entitlementsPath;
|
|
70
|
+
}
|
|
71
|
+
return discovery.entitlementsPathByConfiguration?.get(discovery.buildConfigurationNames[0]);
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=buildConfigurationValues.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildConfigurationValues.js","sourceRoot":"","sources":["../../../../src/platforms/ios/buildConfigurationValues.ts"],"names":[],"mappings":";;;AA6CA,gFA2CC;AAxFD,oEAAoG;AACpG,qDAAwD;AAMxD;;;GAGG;AACU,QAAA,2BAA2B,GAAG,SAAS,CAAA;AAEpD,MAAM,4BAA4B,GAAG,GAAG,mCAA2B,sBAAsB,CAAA;AACzF,MAAM,sBAAsB,GAAG,GAAG,mCAA2B,gBAAgB,CAAA;AAE7E;;;GAGG;AACU,QAAA,2BAA2B,GAAsB,CAAC,4BAA4B,EAAE,sBAAsB,CAAC,CAAA;AASpH,MAAa,+BAAgC,SAAQ,wBAAc;IACjE,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,6CAA6C,CAAC,CAAA;QAC7D,IAAI,CAAC,IAAI,GAAG,iCAAiC,CAAA;IAC/C,CAAC;CACF;AALD,0EAKC;AAED;;;;;;;;GAQG;AACH,SAAgB,kCAAkC,CAChD,GAA8B,EAC9B,SAA8B;IAE9B,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkC,CAAA;IAE/D,MAAM,OAAO,GAAG,CACd,WAAmB,EACnB,KAA2C,EAC3C,OAAe,EACK,EAAE;QACtB,IAAI,CAAC,IAAA,wCAAqB,EAAC,KAAK,CAAC,EAAE,CAAC;YAClC,OAAO,KAAK,CAAA;QACd,CAAC;QAED,MAAM,0BAA0B,GAAG,IAAA,gDAA6B,EAC9D,KAAK,EACL,SAAS,CAAC,uBAAuB,EACjC,OAAO,EACP,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,+BAA+B,CAAC,OAAO,CAAC,CAC1D,CAAA;QAED,KAAK,MAAM,CAAC,sBAAsB,EAAE,kBAAkB,CAAC,IAAI,0BAA0B,EAAE,CAAC;YACtF,MAAM,qBAAqB,GAAG,aAAa,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,EAAE,CAAA;YAC7E,qBAAqB,CAAC,WAAW,CAAC,GAAG,kBAAkB,CAAA;YACvD,aAAa,CAAC,GAAG,CAAC,sBAAsB,EAAE,qBAAqB,CAAC,CAAA;QAClE,CAAC;QAED,OAAO,KAAK,WAAW,GAAG,CAAA;IAC5B,CAAC,CAAA;IAED,OAAO;QACL,GAAG,EAAE;YACH,GAAG,GAAG;YACN,eAAe,EAAE,OAAO,CAAC,4BAA4B,EAAE,GAAG,CAAC,eAAe,EAAE,qBAAqB,CAAC;YAClG,aAAa,EAAE,OAAO,CAAC,sBAAsB,EAAE,GAAG,CAAC,aAAa,EAAE,mBAAmB,CAAC;YACtF,OAAO,EAAE;gBACP,GAAG,GAAG,CAAC,OAAO;gBACd,gBAAgB,EAAE,uBAAuB,CAAC,GAAG,CAAC,OAAO,CAAC,gBAAgB,EAAE,SAAS,CAAC;aACnF;SACF;QACD,aAAa;KACd,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,uBAAuB,CAC9B,gBAAsD,EACtD,SAA8B;IAE9B,IAAI,CAAC,IAAA,wCAAqB,EAAC,gBAAgB,CAAC,EAAE,CAAC;QAC7C,OAAO,gBAAgB,CAAA;IACzB,CAAC;IAED,OAAO,SAAS,CAAC,+BAA+B,EAAE,GAAG,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAA;AAC7F,CAAC"}
|
|
@@ -17,29 +17,44 @@ class IOSEntitlementsMutationError extends summary_1.VoltraCliError {
|
|
|
17
17
|
exports.IOSEntitlementsMutationError = IOSEntitlementsMutationError;
|
|
18
18
|
async function ensureEntitlements(options) {
|
|
19
19
|
const { projectRoot, ios, discovery } = options;
|
|
20
|
-
const
|
|
21
|
-
if (
|
|
22
|
-
|
|
23
|
-
return {};
|
|
24
|
-
}
|
|
20
|
+
const entitlementsPaths = resolveEntitlementsPathsToMutate(ios, discovery);
|
|
21
|
+
if (entitlementsPaths.length === 0) {
|
|
22
|
+
return { changes: [] };
|
|
25
23
|
}
|
|
26
|
-
const entitlements = (await (0, readWrite_1.pathExists)(entitlementsPath))
|
|
27
|
-
? await (0, plist_1.parsePlistFile)(entitlementsPath, 'main app entitlements', createEntitlementsError)
|
|
28
|
-
: {};
|
|
29
24
|
const previousVoltraValues = await readPreviousVoltraEntitlementValues(discovery.infoPlistPath);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
25
|
+
const changes = [];
|
|
26
|
+
for (const entitlementsPath of entitlementsPaths) {
|
|
27
|
+
const entitlements = (await (0, readWrite_1.pathExists)(entitlementsPath))
|
|
28
|
+
? await (0, plist_1.parsePlistFile)(entitlementsPath, 'main app entitlements', createEntitlementsError)
|
|
29
|
+
: {};
|
|
30
|
+
ensureStringArrayValue(entitlements, 'com.apple.security.application-groups', ios.groupIdentifier, previousVoltraValues.appGroupIdentifier);
|
|
31
|
+
ensureStringArrayValue(entitlements, 'keychain-access-groups', ios.keychainGroup, previousVoltraValues.keychainGroup);
|
|
32
|
+
if (ios.enablePushNotifications && entitlements['aps-environment'] === undefined) {
|
|
33
|
+
entitlements['aps-environment'] = 'development';
|
|
34
|
+
}
|
|
35
|
+
else if (!ios.enablePushNotifications &&
|
|
36
|
+
previousVoltraValues.pushNotificationsEnabled &&
|
|
37
|
+
entitlements['aps-environment'] === 'development') {
|
|
38
|
+
delete entitlements['aps-environment'];
|
|
39
|
+
}
|
|
40
|
+
const nextContent = (0, plist_1.buildPlistXml)(entitlements, createEntitlementsError);
|
|
41
|
+
const change = await writeEntitlementsIfChanged(projectRoot, entitlementsPath, nextContent);
|
|
42
|
+
if (change) {
|
|
43
|
+
changes.push(change);
|
|
44
|
+
}
|
|
34
45
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
46
|
+
return { changes };
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Every entitlements file the app target references, so each build configuration of a
|
|
50
|
+
* multi-environment app keeps its own file. Falls back to the standard path when the project
|
|
51
|
+
* references none and Voltra has values to write.
|
|
52
|
+
*/
|
|
53
|
+
function resolveEntitlementsPathsToMutate(ios, discovery) {
|
|
54
|
+
if (discovery.entitlementsPaths.length > 0) {
|
|
55
|
+
return discovery.entitlementsPaths;
|
|
39
56
|
}
|
|
40
|
-
|
|
41
|
-
const change = await writeEntitlementsIfChanged(projectRoot, entitlementsPath, nextContent);
|
|
42
|
-
return { change };
|
|
57
|
+
return needsEntitlementsMutation(ios) ? [(0, mainAppEntitlements_1.resolveMainAppEntitlementsPath)(discovery)] : [];
|
|
43
58
|
}
|
|
44
59
|
function needsEntitlementsMutation(ios) {
|
|
45
60
|
return ios.enablePushNotifications || ios.groupIdentifier !== undefined || ios.keychainGroup !== undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entitlements.js","sourceRoot":"","sources":["../../../../src/platforms/ios/entitlements.ts"],"names":[],"mappings":";;;AAkCA,
|
|
1
|
+
{"version":3,"file":"entitlements.js","sourceRoot":"","sources":["../../../../src/platforms/ios/entitlements.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.IOSGeneratedFilesError = void 0;
|
|
6
|
+
exports.__test__ = exports.IOSGeneratedFilesError = void 0;
|
|
7
7
|
exports.generateIOSFiles = generateIOSFiles;
|
|
8
8
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
9
|
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
@@ -14,6 +14,7 @@ const readWrite_1 = require("../../fs/readWrite");
|
|
|
14
14
|
const path_1 = require("../../fs/path");
|
|
15
15
|
const summary_1 = require("../../reporting/summary");
|
|
16
16
|
const widgetModule_1 = require("../shared/widgetModule");
|
|
17
|
+
const widgetKind_1 = require("../../config/widgetKind");
|
|
17
18
|
const plist_1 = require("./plist");
|
|
18
19
|
const targetName_1 = require("./targetName");
|
|
19
20
|
const VALID_IMAGE_EXTENSIONS = new Set(['.png', '.jpg', '.jpeg']);
|
|
@@ -101,15 +102,17 @@ function createGeneratedFilesError(message) {
|
|
|
101
102
|
}
|
|
102
103
|
async function generateIOSFiles(options) {
|
|
103
104
|
const { projectRoot, ios, discovery } = options;
|
|
105
|
+
const voltraVersion = (0, platformPackages_1.getPlatformClientPackageVersion)(projectRoot, 'ios');
|
|
104
106
|
const targetName = (0, targetName_1.resolveIOSWidgetTargetName)(ios, discovery);
|
|
105
107
|
const targetPath = node_path_1.default.join(discovery.iosRoot, targetName);
|
|
106
|
-
const detectedWidgets = detectClientRenderedWidgets(projectRoot, ios.widgets);
|
|
107
108
|
const mainAppMetadata = await readMainAppMetadata(discovery.infoPlistPath);
|
|
108
109
|
const changes = [];
|
|
109
|
-
const warnings = [];
|
|
110
|
+
const warnings = [...(await getDivergentMainAppMetadataWarnings(discovery, mainAppMetadata))];
|
|
110
111
|
const generatedFiles = new Set();
|
|
112
|
+
const widgetModuleLoader = (0, widgetModule_1.createGeneratedWidgetModuleLoader)(projectRoot, 'ios', createGeneratedFilesError, (message) => warnings.push(message));
|
|
113
|
+
const detectedWidgets = detectClientRenderedWidgets(projectRoot, widgetModuleLoader, ios.widgets);
|
|
111
114
|
mergeSingleResult(await writeGeneratedTextFile(projectRoot, node_path_1.default.join(projectRoot, IOS_DYNAMIC_WIDGET_MANIFEST_PATH), `${JSON.stringify(createDynamicWidgetsManifest(detectedWidgets), null, 2)}\n`), changes, generatedFiles);
|
|
112
|
-
const infoPlistResult = await generateInfoPlistFile(projectRoot, targetPath, targetName, ios, mainAppMetadata, detectedWidgets);
|
|
115
|
+
const infoPlistResult = await generateInfoPlistFile(projectRoot, targetPath, targetName, ios, mainAppMetadata, detectedWidgets, voltraVersion);
|
|
113
116
|
mergeSingleResult(infoPlistResult, changes, generatedFiles);
|
|
114
117
|
const entitlementsResult = await generateEntitlementsFile(projectRoot, targetPath, targetName, ios);
|
|
115
118
|
mergeSingleResult(entitlementsResult, changes, generatedFiles);
|
|
@@ -117,7 +120,7 @@ async function generateIOSFiles(options) {
|
|
|
117
120
|
mergeResult(assetResult, changes, warnings, generatedFiles);
|
|
118
121
|
const fontsResult = await copyIOSFonts(projectRoot, targetPath, ios.fonts);
|
|
119
122
|
mergeResult(fontsResult, changes, warnings, generatedFiles);
|
|
120
|
-
const initialStatesResult = await generateInitialStatesSwift(projectRoot, detectedWidgets);
|
|
123
|
+
const initialStatesResult = await generateInitialStatesSwift(projectRoot, widgetModuleLoader, detectedWidgets, voltraVersion);
|
|
121
124
|
mergeSingleResult(await writeGeneratedTextFile(projectRoot, node_path_1.default.join(targetPath, 'VoltraWidgetInitialStates.swift'), initialStatesResult), changes, generatedFiles);
|
|
122
125
|
const widgetBundleResult = await writeGeneratedTextFile(projectRoot, node_path_1.default.join(targetPath, 'VoltraWidgetBundle.swift'), generateWidgetBundleSwift(detectedWidgets));
|
|
123
126
|
mergeSingleResult(widgetBundleResult, changes, generatedFiles);
|
|
@@ -131,12 +134,16 @@ async function generateIOSFiles(options) {
|
|
|
131
134
|
targetPath,
|
|
132
135
|
};
|
|
133
136
|
}
|
|
134
|
-
async function generateInfoPlistFile(projectRoot, targetPath, targetName, ios, mainAppMetadata, widgets) {
|
|
137
|
+
async function generateInfoPlistFile(projectRoot, targetPath, targetName, ios, mainAppMetadata, widgets, voltraVersion) {
|
|
135
138
|
const plistPath = node_path_1.default.join(targetPath, 'Info.plist');
|
|
136
139
|
const fontNames = ios.fonts.map((fontPath) => node_path_1.default.basename(fontPath)).sort();
|
|
137
140
|
const serverWidgets = widgets.filter((widget) => widget.serverUpdate);
|
|
138
141
|
const hasClientRenderedWidget = widgets.some((widget) => widget.clientRendered);
|
|
139
|
-
|
|
142
|
+
// Keys of the intervals dictionary are the set of server-driven widget ids; a URL appears only
|
|
143
|
+
// when app.json set one, because it may instead arrive at runtime via setWidgetServerUpdate.
|
|
144
|
+
const serverUrls = Object.fromEntries(serverWidgets
|
|
145
|
+
.filter((widget) => widget.serverUpdate?.url !== undefined)
|
|
146
|
+
.map((widget) => [widget.id, widget.serverUpdate?.url]));
|
|
140
147
|
const serverIntervals = Object.fromEntries(serverWidgets.map((widget) => [widget.id, widget.serverUpdate?.intervalMinutes]));
|
|
141
148
|
const serverRefresh = Object.fromEntries(serverWidgets.map((widget) => [widget.id, widget.serverUpdate?.refresh ?? false]));
|
|
142
149
|
const infoPlist = (0, plist_1.buildPlistXml)({
|
|
@@ -157,6 +164,10 @@ async function generateInfoPlistFile(projectRoot, targetPath, targetName, ios, m
|
|
|
157
164
|
UIAppFonts: fontNames.length > 0 ? fontNames : undefined,
|
|
158
165
|
Voltra_AppGroupIdentifier: ios.groupIdentifier,
|
|
159
166
|
Voltra_KeychainGroup: ios.keychainGroup,
|
|
167
|
+
Voltra_Version: voltraVersion,
|
|
168
|
+
// The extension resolves its own kinds too, and Bundle.main there is the extension bundle,
|
|
169
|
+
// so the map has to be written here as well as into the app's Info.plist.
|
|
170
|
+
Voltra_WidgetKinds: (0, widgetKind_1.iosWidgetKindOverrides)(widgets),
|
|
160
171
|
Voltra_WidgetServerIntervals: Object.keys(serverIntervals).length > 0 ? serverIntervals : undefined,
|
|
161
172
|
Voltra_WidgetServerRefresh: Object.keys(serverRefresh).length > 0 ? serverRefresh : undefined,
|
|
162
173
|
NSAppTransportSecurity: createWidgetAppTransportSecurity(hasClientRenderedWidget, serverWidgets.length > 0),
|
|
@@ -265,6 +276,23 @@ async function generateLocalizedWidgetStrings(projectRoot, targetPath, widgets)
|
|
|
265
276
|
targetPath,
|
|
266
277
|
};
|
|
267
278
|
}
|
|
279
|
+
/**
|
|
280
|
+
* The widget extension has a single Info.plist, so its version has to come from one of the app's.
|
|
281
|
+
* An app whose build configurations disagree on the version would ship an extension that matches
|
|
282
|
+
* only some of them, which App Store validation rejects, so say so rather than picking silently.
|
|
283
|
+
*/
|
|
284
|
+
async function getDivergentMainAppMetadataWarnings(discovery, mainAppMetadata) {
|
|
285
|
+
const warnings = [];
|
|
286
|
+
for (const infoPlistPath of discovery.infoPlistPaths.slice(1)) {
|
|
287
|
+
const metadata = await readMainAppMetadata(infoPlistPath);
|
|
288
|
+
if (metadata.shortVersionString === mainAppMetadata.shortVersionString &&
|
|
289
|
+
metadata.buildNumber === mainAppMetadata.buildNumber) {
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
warnings.push(`${(0, path_1.toRelativePath)(discovery.iosRoot, infoPlistPath)} sets version ${metadata.shortVersionString} (${metadata.buildNumber}) while ${(0, path_1.toRelativePath)(discovery.iosRoot, discovery.infoPlistPath)} sets ${mainAppMetadata.shortVersionString} (${mainAppMetadata.buildNumber}). The widget extension is generated with the version of the default build configuration. Set ios.project.infoPlistPath to choose a different one.`);
|
|
293
|
+
}
|
|
294
|
+
return warnings;
|
|
295
|
+
}
|
|
268
296
|
async function readMainAppMetadata(infoPlistPath) {
|
|
269
297
|
const dict = await (0, plist_1.parsePlistFile)(infoPlistPath, 'main app Info.plist', (message) => new IOSGeneratedFilesError(message));
|
|
270
298
|
const shortVersionString = readPlistString(dict, 'CFBundleShortVersionString') ?? '1.0.0';
|
|
@@ -276,11 +304,11 @@ async function readMainAppMetadata(infoPlistPath) {
|
|
|
276
304
|
urlTypes: urlTypes.length > 0 ? urlTypes : undefined,
|
|
277
305
|
};
|
|
278
306
|
}
|
|
279
|
-
async function generateInitialStatesSwift(projectRoot, widgets) {
|
|
307
|
+
async function generateInitialStatesSwift(projectRoot, loader, widgets, voltraVersion) {
|
|
280
308
|
const serverWidgets = widgets.filter((widget) => !widget.clientRendered);
|
|
281
309
|
const prerenderableServerWidgets = serverWidgets.filter((widget) => widget.initialStatePath);
|
|
282
|
-
const serverStates = await prerenderWidgetStates(
|
|
283
|
-
const clientStates = await prerenderClientRenderedWidgets(projectRoot, widgets);
|
|
310
|
+
const serverStates = await prerenderWidgetStates(loader, prerenderableServerWidgets, loadIOSWidgetRenderer(projectRoot));
|
|
311
|
+
const clientStates = await prerenderClientRenderedWidgets(projectRoot, loader, widgets, voltraVersion);
|
|
284
312
|
const prerenderedStates = new Map([...serverStates, ...clientStates]);
|
|
285
313
|
if (prerenderedStates.size === 0) {
|
|
286
314
|
return [
|
|
@@ -349,7 +377,7 @@ function generateWidgetBundleSwift(widgets) {
|
|
|
349
377
|
appIntentWidgets.length > 0 ? 'import AppIntents' : undefined,
|
|
350
378
|
'import SwiftUI',
|
|
351
379
|
'import WidgetKit',
|
|
352
|
-
'import
|
|
380
|
+
'import VoltraRuntime',
|
|
353
381
|
]
|
|
354
382
|
.filter((value) => value !== undefined)
|
|
355
383
|
.join('\n');
|
|
@@ -409,9 +437,12 @@ function generateWidgetStruct(widget) {
|
|
|
409
437
|
const familiesSwift = widget.supportedFamilies.map((family) => IOS_WIDGET_FAMILY_MAP[family]).join(', ');
|
|
410
438
|
const displayNameExpr = createSwiftLabelExpression(widget.id, 'displayName', widget.displayName);
|
|
411
439
|
const descriptionExpr = createSwiftLabelExpression(widget.id, 'description', widget.description);
|
|
440
|
+
// `entry` picks the render engine and `serverUpdate` picks where the data comes from, so the two
|
|
441
|
+
// keys together select one of four providers. Runtime code never asks "is this server-driven?" —
|
|
442
|
+
// the answer is baked in here, once, at generate time.
|
|
412
443
|
const providerAndContent = widget.clientRendered
|
|
413
444
|
? [
|
|
414
|
-
|
|
445
|
+
` provider: ${widget.serverUpdate ? 'VoltraDynamicWidgetServerUpdateProvider' : 'VoltraClientWidgetProvider'}(`,
|
|
415
446
|
' widgetId: widgetId,',
|
|
416
447
|
' initialState: VoltraWidgetInitialStates.getInitialState(for: widgetId)',
|
|
417
448
|
' )',
|
|
@@ -437,7 +468,7 @@ function generateWidgetStruct(widget) {
|
|
|
437
468
|
'',
|
|
438
469
|
' public var body: some WidgetConfiguration {',
|
|
439
470
|
' StaticConfiguration(',
|
|
440
|
-
` kind: ${JSON.stringify(
|
|
471
|
+
` kind: ${JSON.stringify((0, widgetKind_1.iosWidgetKind)(widget))},`,
|
|
441
472
|
providerAndContent,
|
|
442
473
|
' }',
|
|
443
474
|
` .configurationDisplayName(${displayNameExpr})`,
|
|
@@ -467,6 +498,22 @@ function generateClientAppIntentWidgetCode(widget) {
|
|
|
467
498
|
.join('\n');
|
|
468
499
|
const configuredDictionary = createSwiftDictionaryLiteral(widget.appIntent.parameters.map((parameter) => `${JSON.stringify(parameter.name)}: configuration.${parameter.name}`));
|
|
469
500
|
const defaultDictionary = createSwiftDictionaryLiteral(widget.appIntent.parameters.map((parameter) => `${JSON.stringify(parameter.name)}: ${swiftDefaultValue(parameter)}`));
|
|
501
|
+
// A server-driven Dynamic Widget fetches on every timeline request and schedules the next one
|
|
502
|
+
// from its resolved interval; a plain one has nothing to ask again for, so its policy is .never.
|
|
503
|
+
const timelineBody = widget.serverUpdate
|
|
504
|
+
? [
|
|
505
|
+
' return await VoltraDynamicWidgetServerUpdateProvider.timeline(',
|
|
506
|
+
' widgetId: widgetId,',
|
|
507
|
+
' family: context.family,',
|
|
508
|
+
` configuration: ${configuredDictionary}`,
|
|
509
|
+
' )',
|
|
510
|
+
' }',
|
|
511
|
+
]
|
|
512
|
+
: [
|
|
513
|
+
` let entry = await VoltraClientWidgetProvider.loadEntry(widgetId: widgetId, configuration: ${configuredDictionary})`,
|
|
514
|
+
' return Timeline(entries: [entry], policy: .never)',
|
|
515
|
+
' }',
|
|
516
|
+
];
|
|
470
517
|
return [
|
|
471
518
|
`@available(iOS 17.0, *)`,
|
|
472
519
|
`struct ${intentName}: WidgetConfigurationIntent {`,
|
|
@@ -495,10 +542,8 @@ function generateClientAppIntentWidgetCode(widget) {
|
|
|
495
542
|
` await VoltraClientWidgetProvider.loadEntry(widgetId: widgetId, configuration: ${configuredDictionary})`,
|
|
496
543
|
' }',
|
|
497
544
|
'',
|
|
498
|
-
` func timeline(for configuration: ${intentName}, in
|
|
499
|
-
|
|
500
|
-
' return Timeline(entries: [entry], policy: .never)',
|
|
501
|
-
' }',
|
|
545
|
+
` func timeline(for configuration: ${intentName}, in context: Context) async -> Timeline<VoltraClientWidgetEntry> {`,
|
|
546
|
+
...timelineBody,
|
|
502
547
|
'}',
|
|
503
548
|
'',
|
|
504
549
|
`@available(iOS 17.0, *)`,
|
|
@@ -509,7 +554,7 @@ function generateClientAppIntentWidgetCode(widget) {
|
|
|
509
554
|
'',
|
|
510
555
|
' public var body: some WidgetConfiguration {',
|
|
511
556
|
' AppIntentConfiguration(',
|
|
512
|
-
` kind: ${JSON.stringify(
|
|
557
|
+
` kind: ${JSON.stringify((0, widgetKind_1.iosWidgetKind)(widget))},`,
|
|
513
558
|
` intent: ${intentName}.self,`,
|
|
514
559
|
` provider: ${providerName}()`,
|
|
515
560
|
' ) { entry in',
|
|
@@ -540,7 +585,7 @@ function swiftDefaultValue(parameter) {
|
|
|
540
585
|
function createSwiftDictionaryLiteral(entries) {
|
|
541
586
|
return entries.length > 0 ? `[${entries.join(', ')}]` : '[:]';
|
|
542
587
|
}
|
|
543
|
-
async function prerenderWidgetStates(
|
|
588
|
+
async function prerenderWidgetStates(loader, widgets, renderer) {
|
|
544
589
|
const prerenderedStates = new Map();
|
|
545
590
|
for (const widget of widgets) {
|
|
546
591
|
const initialStatePath = widget.initialStatePath;
|
|
@@ -553,16 +598,15 @@ async function prerenderWidgetStates(projectRoot, widgets, renderer) {
|
|
|
553
598
|
if (!(await (0, readWrite_1.pathExists)(modulePath))) {
|
|
554
599
|
throw new IOSGeneratedFilesError(`Initial state file not found for widget '${widget.id}' at ${modulePath}`);
|
|
555
600
|
}
|
|
556
|
-
const widgetVariants = evaluateLegacyWidgetModule(
|
|
601
|
+
const widgetVariants = evaluateLegacyWidgetModule(loader, modulePath);
|
|
557
602
|
localeStates.set(localeKey, renderer(widgetVariants));
|
|
558
603
|
}
|
|
559
604
|
prerenderedStates.set(widget.id, localeStates);
|
|
560
605
|
}
|
|
561
606
|
return prerenderedStates;
|
|
562
607
|
}
|
|
563
|
-
function evaluateLegacyWidgetModule(
|
|
564
|
-
const
|
|
565
|
-
const widgetVariants = exports.default ?? exports;
|
|
608
|
+
function evaluateLegacyWidgetModule(loader, filePath) {
|
|
609
|
+
const widgetVariants = loader.loadDefaultExport(filePath);
|
|
566
610
|
if (!widgetVariants || typeof widgetVariants !== 'object') {
|
|
567
611
|
throw new IOSGeneratedFilesError(`Widget file must export widget variants: ${filePath}`);
|
|
568
612
|
}
|
|
@@ -594,10 +638,10 @@ function createDynamicWidgetsManifest(widgets) {
|
|
|
594
638
|
})),
|
|
595
639
|
};
|
|
596
640
|
}
|
|
597
|
-
function detectClientRenderedWidgets(projectRoot, widgets) {
|
|
598
|
-
return widgets.map((widget) => detectSingleWidget(projectRoot, widget));
|
|
641
|
+
function detectClientRenderedWidgets(projectRoot, loader, widgets) {
|
|
642
|
+
return widgets.map((widget) => detectSingleWidget(projectRoot, loader, widget));
|
|
599
643
|
}
|
|
600
|
-
function detectSingleWidget(projectRoot, widget) {
|
|
644
|
+
function detectSingleWidget(projectRoot, loader, widget) {
|
|
601
645
|
if (!widget.entry) {
|
|
602
646
|
return {
|
|
603
647
|
...widget,
|
|
@@ -608,7 +652,7 @@ function detectSingleWidget(projectRoot, widget) {
|
|
|
608
652
|
if (!node_fs_1.default.existsSync(clientSourcePath) || !node_fs_1.default.statSync(clientSourcePath).isFile()) {
|
|
609
653
|
throw createGeneratedFilesError(`[voltra] Dynamic Widget "${widget.id}" entry not found at ${widget.entry}`);
|
|
610
654
|
}
|
|
611
|
-
const widgetModule = safelyEvaluateDynamicWidget(
|
|
655
|
+
const widgetModule = safelyEvaluateDynamicWidget(loader, widget.id, widget.entry, clientSourcePath);
|
|
612
656
|
const widgetFn = readDynamicWidgetExport(widget.id, widget.entry, widgetModule);
|
|
613
657
|
if (typeof widgetFn !== 'function') {
|
|
614
658
|
throw createGeneratedFilesError(`[voltra] Dynamic Widget "${widget.id}" at ${widget.entry} must default-export a function or component.`);
|
|
@@ -620,7 +664,7 @@ function detectSingleWidget(projectRoot, widget) {
|
|
|
620
664
|
clientSourcePath,
|
|
621
665
|
};
|
|
622
666
|
}
|
|
623
|
-
async function prerenderClientRenderedWidgets(projectRoot, widgets) {
|
|
667
|
+
async function prerenderClientRenderedWidgets(projectRoot, loader, widgets, voltraVersion) {
|
|
624
668
|
const clientWidgets = widgets.filter((widget) => widget.clientRendered);
|
|
625
669
|
if (clientWidgets.length === 0) {
|
|
626
670
|
return new Map();
|
|
@@ -634,12 +678,12 @@ async function prerenderClientRenderedWidgets(projectRoot, widgets) {
|
|
|
634
678
|
widgetRenderingMode: 'fullColor',
|
|
635
679
|
showsWidgetContainerBackground: true,
|
|
636
680
|
configuration: undefined,
|
|
637
|
-
build: widgetModule_1.
|
|
681
|
+
build: (0, widgetModule_1.createDynamicWidgetBuildInfo)(voltraVersion),
|
|
638
682
|
};
|
|
639
683
|
const prerenderedStates = new Map();
|
|
640
684
|
for (const widget of clientWidgets) {
|
|
641
685
|
try {
|
|
642
|
-
const widgetModule = safelyEvaluateDynamicWidget(
|
|
686
|
+
const widgetModule = safelyEvaluateDynamicWidget(loader, widget.id, widget.entry, widget.clientSourcePath);
|
|
643
687
|
const widgetFn = readDynamicWidgetExport(widget.id, widget.entry, widgetModule);
|
|
644
688
|
const element = widgetFn({}, placeholderEnv);
|
|
645
689
|
prerenderedStates.set(widget.id, new Map([[DEFAULT_INITIAL_STATE_LOCALE, JSON.stringify(renderer(element))]]));
|
|
@@ -653,9 +697,9 @@ async function prerenderClientRenderedWidgets(projectRoot, widgets) {
|
|
|
653
697
|
}
|
|
654
698
|
return prerenderedStates;
|
|
655
699
|
}
|
|
656
|
-
function safelyEvaluateDynamicWidget(
|
|
700
|
+
function safelyEvaluateDynamicWidget(loader, widgetId, widgetEntry, clientSourcePath) {
|
|
657
701
|
try {
|
|
658
|
-
return
|
|
702
|
+
return loader.load(clientSourcePath);
|
|
659
703
|
}
|
|
660
704
|
catch (error) {
|
|
661
705
|
if (error instanceof IOSGeneratedFilesError) {
|
|
@@ -882,4 +926,7 @@ function mergeSingleResult(result, changes, generatedFiles) {
|
|
|
882
926
|
}
|
|
883
927
|
generatedFiles.add((0, path_1.normalizeRelativePath)(result.relativePath));
|
|
884
928
|
}
|
|
929
|
+
exports.__test__ = {
|
|
930
|
+
generateWidgetBundleSwift,
|
|
931
|
+
};
|
|
885
932
|
//# sourceMappingURL=generated.js.map
|