Skip to content

Commit 03ff1dc

Browse files
authored
fix(widget): handle configs with other SPMPackages (#5972)
1 parent 92ec091 commit 03ff1dc

File tree

3 files changed

+137
-9
lines changed

3 files changed

+137
-9
lines changed

lib/commands/widget.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import * as plist from "plist";
88
import { injector } from "../common/yok";
99
import { capitalizeFirstLetter } from "../common/utils";
1010
import { EOL } from "os";
11-
import { SupportedConfigValues } from "../tools/config-manipulation/config-transformer";
1211

1312
export class WidgetCommand implements ICommand {
1413
public allowedParameters: ICommandParameter[] = [];
@@ -219,10 +218,7 @@ public struct ${capitalizeFirstLetter(name)}Model: ActivityAttributes {
219218
}
220219

221220
configData.ios.SPMPackages = spmPackages;
222-
await this.$projectConfigService.setValue(
223-
"", // root
224-
configData as { [key: string]: SupportedConfigValues },
225-
);
221+
await this.$projectConfigService.setValue("ios.SPMPackages", spmPackages);
226222

227223
if (fs.existsSync(gitIgnorePath)) {
228224
const gitIgnore = fs.readFileSync(gitIgnorePath, {

lib/tools/config-manipulation/config-transformer.ts

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,34 +184,64 @@ export class ConfigTransformer implements IConfigTransformer {
184184
return `{}`;
185185
}
186186

187+
private isBooleanLiteralNode(initializer: any): boolean {
188+
return (
189+
initializer?.getKind() === SyntaxKind.TrueKeyword ||
190+
initializer?.getKind() === SyntaxKind.FalseKeyword
191+
);
192+
}
193+
194+
private replaceInitializer(
195+
initializer: any,
196+
newValue: SupportedConfigValues,
197+
) {
198+
return initializer.replaceWithText(this.createInitializer(newValue));
199+
}
200+
187201
private setInitializerValue(
188202
initializer: any,
189203
newValue: SupportedConfigValues,
190204
) {
191205
if (Node.isStringLiteral(initializer)) {
206+
if (typeof newValue !== "string") {
207+
return this.replaceInitializer(initializer, newValue);
208+
}
192209
return (initializer as StringLiteral).setLiteralValue(newValue as string);
193210
}
194211

195212
if (Node.isNumericLiteral(initializer)) {
213+
if (typeof newValue !== "number") {
214+
return this.replaceInitializer(initializer, newValue);
215+
}
196216
return (initializer as NumericLiteral).setLiteralValue(
197217
newValue as number,
198218
);
199219
}
200220

201-
if (Node.isBooleanKeyword(initializer)) {
221+
if (this.isBooleanLiteralNode(initializer)) {
222+
if (typeof newValue !== "boolean") {
223+
return this.replaceInitializer(initializer, newValue);
224+
}
202225
return (initializer as BooleanLiteral).setLiteralValue(
203226
newValue as boolean,
204227
);
205228
}
206229

230+
if (
231+
Node.isArrayLiteralExpression(initializer) ||
232+
Node.isObjectLiteralExpression(initializer)
233+
) {
234+
return this.replaceInitializer(initializer, newValue);
235+
}
236+
207237
if (Node.isIdentifier(initializer)) {
208238
return this.setIdentifierValue(initializer as Identifier, newValue);
209239
}
210240

211241
throw new Error("Unsupported value type: " + initializer.getKindName());
212242
}
213243

214-
private getInitializerValue(initializer: any) {
244+
private getInitializerValue(initializer: any): any {
215245
if (Node.isStringLiteral(initializer)) {
216246
return (initializer as StringLiteral).getLiteralValue();
217247
}
@@ -220,10 +250,30 @@ export class ConfigTransformer implements IConfigTransformer {
220250
return (initializer as NumericLiteral).getLiteralValue();
221251
}
222252

223-
if (Node.isBooleanKeyword(initializer)) {
253+
if (this.isBooleanLiteralNode(initializer)) {
224254
return (initializer as BooleanLiteral).getLiteralValue();
225255
}
226256

257+
if (Node.isArrayLiteralExpression(initializer)) {
258+
return initializer
259+
.getElements()
260+
.map((element: any) => this.getInitializerValue(element));
261+
}
262+
263+
if (Node.isObjectLiteralExpression(initializer)) {
264+
const result: Record<string, SupportedConfigValues> = {};
265+
for (const property of initializer.getProperties()) {
266+
if (!Node.isPropertyAssignment(property)) {
267+
continue;
268+
}
269+
const name = property.getNameNode().getText().replace(/['\"]/g, "");
270+
result[name] = this.getInitializerValue(
271+
property.getInitializerOrThrow(),
272+
);
273+
}
274+
return result;
275+
}
276+
227277
if (Node.isIdentifier(initializer)) {
228278
return this.getIdentifierValue(initializer as Identifier);
229279
}
@@ -278,10 +328,30 @@ export class ConfigTransformer implements IConfigTransformer {
278328
return (initializer as NumericLiteral).getLiteralValue();
279329
}
280330

281-
if (Node.isBooleanKeyword(initializer)) {
331+
if (this.isBooleanLiteralNode(initializer)) {
282332
return (initializer as BooleanLiteral).getLiteralValue();
283333
}
284334

335+
if (Node.isArrayLiteralExpression(initializer)) {
336+
return initializer
337+
.getElements()
338+
.map((element: any) => this.getInitializerValue(element));
339+
}
340+
341+
if (Node.isObjectLiteralExpression(initializer)) {
342+
const result: Record<string, SupportedConfigValues> = {};
343+
for (const property of initializer.getProperties()) {
344+
if (!Node.isPropertyAssignment(property)) {
345+
continue;
346+
}
347+
const name = property.getNameNode().getText().replace(/['\"]/g, "");
348+
result[name] = this.getInitializerValue(
349+
property.getInitializerOrThrow(),
350+
);
351+
}
352+
return result;
353+
}
354+
285355
if (Node.isIdentifier(initializer)) {
286356
return this.getIdentifierValue(initializer as Identifier);
287357
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { assert } from "chai";
2+
import { ConfigTransformer } from "../../../lib/tools/config-manipulation/config-transformer";
3+
4+
describe("ConfigTransformer", () => {
5+
it("updates existing boolean literals", () => {
6+
const content = `export default {
7+
id: 'org.nativescript.myapp',
8+
discardUncaughtJsExceptions: true,
9+
} as any;`;
10+
11+
const transformer = new ConfigTransformer(content);
12+
const updated = transformer.setValue("discardUncaughtJsExceptions", false);
13+
const updatedTransformer = new ConfigTransformer(updated);
14+
15+
assert.strictEqual(
16+
updatedTransformer.getValue("discardUncaughtJsExceptions"),
17+
false,
18+
);
19+
});
20+
21+
it("updates existing ios.SPMPackages array literals", () => {
22+
const content = `import { NativeScriptConfig } from '@nativescript/core'
23+
24+
export default {
25+
id: 'org.nativescript.myapp',
26+
ios: {
27+
SPMPackages: [
28+
{
29+
name: 'RiveRuntime',
30+
libs: ['RiveRuntime'],
31+
repositoryURL: 'https://github.com/rive-app/rive-ios.git',
32+
version: '6.11.0',
33+
},
34+
],
35+
},
36+
} as NativeScriptConfig`;
37+
38+
const spmPackages = [
39+
{
40+
name: "RiveRuntime",
41+
libs: ["RiveRuntime"],
42+
repositoryURL: "https://github.com/rive-app/rive-ios.git",
43+
version: "6.11.0",
44+
},
45+
{
46+
name: "SharedWidget",
47+
libs: ["SharedWidget"],
48+
path: "./Shared_Resources/iOS/SharedWidget",
49+
targets: ["widget"],
50+
},
51+
];
52+
53+
const transformer = new ConfigTransformer(content);
54+
const updated = transformer.setValue("ios.SPMPackages", spmPackages);
55+
const updatedTransformer = new ConfigTransformer(updated);
56+
57+
assert.deepStrictEqual(
58+
updatedTransformer.getValue("ios.SPMPackages"),
59+
spmPackages,
60+
);
61+
});
62+
});

0 commit comments

Comments
 (0)