forked from swiftwasm/JavaScriptKit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBridgeJSConfig.swift
More file actions
81 lines (70 loc) · 2.97 KB
/
BridgeJSConfig.swift
File metadata and controls
81 lines (70 loc) · 2.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import struct Foundation.URL
import struct Foundation.Data
import class Foundation.FileManager
import class Foundation.JSONDecoder
/// Configuration file representation for BridgeJS.
public struct BridgeJSConfig: Codable {
/// A mapping of tool names to their override paths.
///
/// If not present, the tool will be searched for in the system PATH.
public var tools: [String: String]?
/// Whether to expose exported Swift APIs to the global namespace.
///
/// When `true`, exported functions, classes, and namespaces are available
/// via `globalThis` in JavaScript. When `false`, they are only available
/// through the exports object returned by `createExports()`.
///
/// Default: `false`
public var exposeToGlobal: Bool
public init(tools: [String: String]? = nil, exposeToGlobal: Bool = false) {
self.tools = tools
self.exposeToGlobal = exposeToGlobal
}
enum CodingKeys: String, CodingKey {
case tools
case exposeToGlobal
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
tools = try container.decodeIfPresent([String: String].self, forKey: .tools)
exposeToGlobal = try container.decodeIfPresent(Bool.self, forKey: .exposeToGlobal) ?? false
}
/// Load the configuration file from the SwiftPM package target directory.
///
/// Files are loaded **in this order** and merged (later files override earlier ones):
/// 1. `bridge-js.config.json`
/// 2. `bridge-js.config.local.json`
public static func load(targetDirectory: URL) throws -> BridgeJSConfig {
// Define file paths in priority order: base first, then local overrides
let files = [
targetDirectory.appendingPathComponent("bridge-js.config.json"),
targetDirectory.appendingPathComponent("bridge-js.config.local.json"),
]
var config = BridgeJSConfig()
for file in files {
do {
if let loaded = try loadConfig(from: file) {
config = config.merging(overrides: loaded)
}
} catch {
throw BridgeJSCoreError("Failed to parse \(file.path): \(error)")
}
}
return config
}
/// Load a config file from the given URL if it exists, otherwise return nil
private static func loadConfig(from url: URL) throws -> BridgeJSConfig? {
guard FileManager.default.fileExists(atPath: url.path) else {
return nil
}
let data = try Data(contentsOf: url)
return try JSONDecoder().decode(BridgeJSConfig.self, from: data)
}
/// Merge the current configuration with the overrides.
func merging(overrides: BridgeJSConfig) -> BridgeJSConfig {
return BridgeJSConfig(
tools: (tools ?? [:]).merging(overrides.tools ?? [:], uniquingKeysWith: { $1 }),
exposeToGlobal: overrides.exposeToGlobal
)
}
}