@capacitor-plus/ios 8.0.0-beta.0

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.
Files changed (106) hide show
  1. package/Capacitor/Capacitor/AppUUID.swift +51 -0
  2. package/Capacitor/Capacitor/Array+Capacitor.swift +31 -0
  3. package/Capacitor/Capacitor/CAPApplicationDelegateProxy.swift +32 -0
  4. package/Capacitor/Capacitor/CAPBridge.swift +25 -0
  5. package/Capacitor/Capacitor/CAPBridgeDelegate.swift +6 -0
  6. package/Capacitor/Capacitor/CAPBridgeProtocol.swift +148 -0
  7. package/Capacitor/Capacitor/CAPBridgeViewController+CDVScreenOrientationDelegate.h +6 -0
  8. package/Capacitor/Capacitor/CAPBridgeViewController+CDVScreenOrientationDelegate.m +5 -0
  9. package/Capacitor/Capacitor/CAPBridgeViewController.swift +384 -0
  10. package/Capacitor/Capacitor/CAPBridgedJSTypes.h +18 -0
  11. package/Capacitor/Capacitor/CAPBridgedJSTypes.m +43 -0
  12. package/Capacitor/Capacitor/CAPBridgedPlugin+getMethod.swift +13 -0
  13. package/Capacitor/Capacitor/CAPBridgedPlugin.h +41 -0
  14. package/Capacitor/Capacitor/CAPFile.swift +14 -0
  15. package/Capacitor/Capacitor/CAPInstanceConfiguration.h +38 -0
  16. package/Capacitor/Capacitor/CAPInstanceConfiguration.m +93 -0
  17. package/Capacitor/Capacitor/CAPInstanceConfiguration.swift +78 -0
  18. package/Capacitor/Capacitor/CAPInstanceDescriptor.h +167 -0
  19. package/Capacitor/Capacitor/CAPInstanceDescriptor.m +56 -0
  20. package/Capacitor/Capacitor/CAPInstanceDescriptor.swift +198 -0
  21. package/Capacitor/Capacitor/CAPInstancePlugin.swift +10 -0
  22. package/Capacitor/Capacitor/CAPLog.swift +11 -0
  23. package/Capacitor/Capacitor/CAPNotifications.swift +69 -0
  24. package/Capacitor/Capacitor/CAPPlugin+LoadInstance.swift +20 -0
  25. package/Capacitor/Capacitor/CAPPlugin.h +60 -0
  26. package/Capacitor/Capacitor/CAPPlugin.m +180 -0
  27. package/Capacitor/Capacitor/CAPPluginCall.h +25 -0
  28. package/Capacitor/Capacitor/CAPPluginCall.m +36 -0
  29. package/Capacitor/Capacitor/CAPPluginCall.swift +97 -0
  30. package/Capacitor/Capacitor/CAPPluginMethod.h +36 -0
  31. package/Capacitor/Capacitor/CAPPluginMethod.m +44 -0
  32. package/Capacitor/Capacitor/CAPPluginMethod.swift +17 -0
  33. package/Capacitor/Capacitor/Capacitor.h +15 -0
  34. package/Capacitor/Capacitor/Capacitor.modulemap +8 -0
  35. package/Capacitor/Capacitor/CapacitorBridge.swift +768 -0
  36. package/Capacitor/Capacitor/CapacitorExtension.swift +24 -0
  37. package/Capacitor/Capacitor/Codable/JSValueDecoder.swift +479 -0
  38. package/Capacitor/Capacitor/Codable/JSValueEncoder.swift +671 -0
  39. package/Capacitor/Capacitor/Data+Capacitor.swift +22 -0
  40. package/Capacitor/Capacitor/DocLinks.swift +8 -0
  41. package/Capacitor/Capacitor/Info.plist +24 -0
  42. package/Capacitor/Capacitor/JS.swift +122 -0
  43. package/Capacitor/Capacitor/JSExport.swift +218 -0
  44. package/Capacitor/Capacitor/JSTypes.swift +254 -0
  45. package/Capacitor/Capacitor/KeyPath.swift +60 -0
  46. package/Capacitor/Capacitor/KeyValueStore.swift +303 -0
  47. package/Capacitor/Capacitor/NotificationHandlerProtocol.swift +6 -0
  48. package/Capacitor/Capacitor/NotificationRouter.swift +60 -0
  49. package/Capacitor/Capacitor/PluginCallResult.swift +106 -0
  50. package/Capacitor/Capacitor/PluginConfig.swift +56 -0
  51. package/Capacitor/Capacitor/Plugins/CapacitorCookieManager.swift +141 -0
  52. package/Capacitor/Capacitor/Plugins/CapacitorCookies.swift +57 -0
  53. package/Capacitor/Capacitor/Plugins/CapacitorHttp.swift +57 -0
  54. package/Capacitor/Capacitor/Plugins/CapacitorUrlRequest.swift +225 -0
  55. package/Capacitor/Capacitor/Plugins/Console.swift +16 -0
  56. package/Capacitor/Capacitor/Plugins/HttpRequestHandler.swift +236 -0
  57. package/Capacitor/Capacitor/Plugins/SystemBars.swift +133 -0
  58. package/Capacitor/Capacitor/Plugins/WebView.swift +44 -0
  59. package/Capacitor/Capacitor/PrivacyInfo.xcprivacy +14 -0
  60. package/Capacitor/Capacitor/Router.swift +29 -0
  61. package/Capacitor/Capacitor/TmpViewController.swift +8 -0
  62. package/Capacitor/Capacitor/UIColor.swift +55 -0
  63. package/Capacitor/Capacitor/UIStatusBarManager+CAPHandleTapAction.m +37 -0
  64. package/Capacitor/Capacitor/WKWebView+Capacitor.m +15 -0
  65. package/Capacitor/Capacitor/WKWebView+Capacitor.swift +80 -0
  66. package/Capacitor/Capacitor/WebViewAssetHandler.swift +550 -0
  67. package/Capacitor/Capacitor/WebViewDelegationHandler.swift +361 -0
  68. package/Capacitor/Capacitor/assets/native-bridge.js +1029 -0
  69. package/Capacitor.podspec +23 -0
  70. package/CapacitorCordova/CapacitorCordova/CapacitorCordova.h +25 -0
  71. package/CapacitorCordova/CapacitorCordova/CapacitorCordova.modulemap +6 -0
  72. package/CapacitorCordova/CapacitorCordova/Classes/Public/AppDelegate.h +8 -0
  73. package/CapacitorCordova/CapacitorCordova/Classes/Public/AppDelegate.m +5 -0
  74. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDV.h +28 -0
  75. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVAvailability.h +109 -0
  76. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVAvailabilityDeprecated.h +21 -0
  77. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegate.h +49 -0
  78. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegateImpl.h +39 -0
  79. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegateImpl.m +149 -0
  80. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVConfigParser.h +31 -0
  81. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVConfigParser.m +81 -0
  82. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVInvokedUrlCommand.h +52 -0
  83. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVInvokedUrlCommand.m +116 -0
  84. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin+Resources.h +39 -0
  85. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin+Resources.m +38 -0
  86. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin.h +76 -0
  87. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin.m +136 -0
  88. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginManager.h +25 -0
  89. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginManager.m +77 -0
  90. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginResult.h +82 -0
  91. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginResult.m +216 -0
  92. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVScreenOrientationDelegate.h +33 -0
  93. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVURLProtocol.h +27 -0
  94. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVURLProtocol.m +74 -0
  95. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVViewController.h +30 -0
  96. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVViewController.m +37 -0
  97. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVWebViewProcessPoolFactory.h +34 -0
  98. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVWebViewProcessPoolFactory.m +55 -0
  99. package/CapacitorCordova/CapacitorCordova/Classes/Public/NSDictionary+CordovaPreferences.h +35 -0
  100. package/CapacitorCordova/CapacitorCordova/Classes/Public/NSDictionary+CordovaPreferences.m +63 -0
  101. package/CapacitorCordova/CapacitorCordova/Info.plist +26 -0
  102. package/CapacitorCordova/CapacitorCordova/PrivacyInfo.xcprivacy +14 -0
  103. package/CapacitorCordova.podspec +26 -0
  104. package/LICENSE +21 -0
  105. package/package.json +33 -0
  106. package/scripts/pods_helpers.rb +12 -0
@@ -0,0 +1,24 @@
1
+ import Foundation
2
+
3
+ public protocol CapacitorExtension {
4
+ associatedtype CapacitorType
5
+ var capacitor: CapacitorType { get }
6
+ static var capacitor: CapacitorType.Type { get }
7
+ }
8
+
9
+ public extension CapacitorExtension {
10
+ var capacitor: CapacitorExtensionTypeWrapper<Self> {
11
+ return CapacitorExtensionTypeWrapper(self)
12
+ }
13
+
14
+ static var capacitor: CapacitorExtensionTypeWrapper<Self>.Type {
15
+ return CapacitorExtensionTypeWrapper.self
16
+ }
17
+ }
18
+
19
+ public struct CapacitorExtensionTypeWrapper<T> {
20
+ var baseType: T
21
+ init(_ baseType: T) {
22
+ self.baseType = baseType
23
+ }
24
+ }
@@ -0,0 +1,479 @@
1
+ //
2
+ // JSValueDecoder.swift
3
+ // Capacitor
4
+ //
5
+ // Created by Steven Sherry on 12/8/23.
6
+ // Copyright © 2023 Drifty Co. All rights reserved.
7
+ //
8
+
9
+ import Foundation
10
+ import Combine
11
+
12
+ /// A decoder that can decode ``JSValue`` objects into `Decodable` types.
13
+ public final class JSValueDecoder: TopLevelDecoder {
14
+ /// The strategies available for formatting dates when decoding from a ``JSValue``
15
+ public typealias DateDecodingStrategy = JSONDecoder.DateDecodingStrategy
16
+ /// The strategies available for decoding raw data.
17
+ public typealias DataDecodingStrategy = JSONDecoder.DataDecodingStrategy
18
+
19
+ /// The strategies availble for decoding NaN, Infinity, and -Infinity
20
+ public enum NonConformingFloatDecodingStrategy {
21
+ /// Decodes directly into the floating point type as .infinity, -.infinity, or .nan
22
+ case deferred
23
+ /// Throw an error when a non-conforming float is encountered
24
+ case `throw`
25
+ /// Converts from the provided strings into .infinity, -.infinity, or .nan
26
+ case convertFromString(positiveInfinity: String, negativeInfinity: String, nan: String)
27
+ }
28
+
29
+ fileprivate struct Options {
30
+ var dataStrategy: DataDecodingStrategy
31
+ var dateStrategy: DateDecodingStrategy
32
+ var nonConformingStrategy: NonConformingFloatDecodingStrategy
33
+ }
34
+
35
+ private var options: Options
36
+
37
+ /// Creates a new JSValueDecoder with the provided decoding and formatting strategies
38
+ /// - Parameters:
39
+ /// - dateDecodingStrategy: Defaults to `DateDecodingStrategy.deferredToDate`
40
+ /// - dataDecodingStrategy: Defaults to `DataDecodingStrategy.deferredToData`
41
+ /// - nonConformingFloatDecodingStrategy: Defaults to ``NonConformingFloatDecodingStrategy/deferred``
42
+ public init(
43
+ dateDecodingStrategy: DateDecodingStrategy = .deferredToDate,
44
+ dataDecodingStrategy: DataDecodingStrategy = .deferredToData,
45
+ nonConformingFloatDecodingStrategy: NonConformingFloatDecodingStrategy = .deferred
46
+ ) {
47
+ self.options = .init(dataStrategy: dataDecodingStrategy, dateStrategy: dateDecodingStrategy, nonConformingStrategy: nonConformingFloatDecodingStrategy)
48
+ }
49
+
50
+ fileprivate init(options: Options) {
51
+ self.options = options
52
+ }
53
+
54
+ /// The strategy to use when decoding dates from a ``JSValue``
55
+ public var dateDecodingStrategy: DateDecodingStrategy {
56
+ get { options.dateStrategy }
57
+ set { options.dateStrategy = newValue }
58
+ }
59
+
60
+ /// The strategy to use when decoding raw data from a ``JSValue``
61
+ public var dataDecodingStrategy: DataDecodingStrategy {
62
+ get { options.dataStrategy }
63
+ set { options.dataStrategy = newValue }
64
+ }
65
+
66
+ /// The strategy used by a decoder when it encounters exceptional floating-point values
67
+ public var nonConformingFloatDecodingStrategy: NonConformingFloatDecodingStrategy {
68
+ get { options.nonConformingStrategy }
69
+ set { options.nonConformingStrategy = newValue }
70
+ }
71
+
72
+ /// Decodes a ``JSValue`` into the provided `Decodable` type
73
+ /// - Parameters:
74
+ /// - type: The type of the value to decode from the provided ``JSValue`` object
75
+ /// - data: The ``JSValue`` to decode
76
+ /// - Returns: A value of the specified type.
77
+ ///
78
+ /// An error will be thrown from this method for two possible reasons:
79
+ /// 1. A type mismatch was found.
80
+ /// 2. A key was not found in the `data` field that is required in the `type` provided.
81
+ public func decode<T>(_ type: T.Type, from data: JSValue) throws -> T where T: Decodable {
82
+ let decoder = _JSValueDecoder(data: data, options: options)
83
+ return try decoder.decodeData(as: T.self)
84
+ }
85
+ }
86
+
87
+ typealias CodingUserInfo = [CodingUserInfoKey: Any]
88
+ private typealias Options = JSValueDecoder.Options
89
+
90
+ private final class _JSValueDecoder {
91
+ var codingPath: [CodingKey] = []
92
+ var userInfo: CodingUserInfo = [:]
93
+ var options: Options
94
+ fileprivate var data: JSValue
95
+
96
+ init(data: JSValue, options: Options) {
97
+ self.data = data
98
+ self.options = options
99
+ }
100
+ }
101
+
102
+ extension _JSValueDecoder: Decoder {
103
+ func container<Key>(keyedBy type: Key.Type) throws -> KeyedDecodingContainer<Key> where Key: CodingKey {
104
+ guard let data = data as? JSObject else {
105
+ throw DecodingError.typeMismatch(JSObject.self, on: data, codingPath: codingPath)
106
+ }
107
+
108
+ return KeyedDecodingContainer(
109
+ KeyedContainer(
110
+ data: data,
111
+ codingPath: codingPath,
112
+ userInfo: userInfo,
113
+ options: options
114
+ )
115
+ )
116
+ }
117
+
118
+ func unkeyedContainer() throws -> UnkeyedDecodingContainer {
119
+ guard let data = data as? JSArray else {
120
+ throw DecodingError.typeMismatch(JSArray.self, on: data, codingPath: codingPath)
121
+ }
122
+
123
+ return UnkeyedContainer(data: data, codingPath: codingPath, userInfo: userInfo, options: options)
124
+ }
125
+
126
+ func singleValueContainer() throws -> SingleValueDecodingContainer {
127
+ SingleValueContainer(data: data, codingPath: codingPath, userInfo: userInfo, options: options)
128
+ }
129
+
130
+ // force casting is fine becasue we've already determined that T is the type in the case
131
+ // the swift standard library also force casts in their similar functions
132
+ // https://github.com/swiftlang/swift-foundation/blob/da80d51fa3e77f3e7ed57c4300a870689e755713/Sources/FoundationEssentials/JSON/JSONEncoder.swift#L1140
133
+ // swiftlint:disable force_cast
134
+ fileprivate func decodeData<T>(as type: T.Type) throws -> T where T: Decodable {
135
+ switch type {
136
+ case is Date.Type:
137
+ return try decodeDate() as! T
138
+ case is URL.Type:
139
+ return try decodeUrl() as! T
140
+ case is Data.Type:
141
+ return try decodeData() as! T
142
+ default:
143
+ return try T(from: self)
144
+ }
145
+ }
146
+ // swiftlint:enable force_cast
147
+
148
+ private func decodeDate() throws -> Date {
149
+ switch options.dateStrategy {
150
+ case .deferredToDate:
151
+ return try Date(from: self)
152
+ case .secondsSince1970:
153
+ guard let value = data as? NSNumber else { throw DecodingError.dataCorrupted(data, target: Double.self, codingPath: codingPath) }
154
+ return Date(timeIntervalSince1970: value.doubleValue)
155
+ case .millisecondsSince1970:
156
+ guard let value = data as? NSNumber else { throw DecodingError.dataCorrupted(data, target: Double.self, codingPath: codingPath) }
157
+ return Date(timeIntervalSince1970: value.doubleValue / Double(MSEC_PER_SEC))
158
+ case .iso8601:
159
+ guard let value = data as? String else { throw DecodingError.dataCorrupted(data, target: String.self, codingPath: codingPath) }
160
+ let formatter = ISO8601DateFormatter()
161
+ guard let date = formatter.date(from: value) else { throw DecodingError.dataCorrupted(value, target: Date.self, codingPath: codingPath) }
162
+ return date
163
+ case .formatted(let formatter):
164
+ guard let value = data as? String else { throw DecodingError.dataCorrupted(data, target: String.self, codingPath: codingPath) }
165
+ guard let date = formatter.date(from: value) else { throw DecodingError.dataCorrupted(value, target: Date.self, codingPath: codingPath) }
166
+ return date
167
+ case .custom(let decode):
168
+ return try decode(self)
169
+ @unknown default:
170
+ return try Date(from: self)
171
+ }
172
+ }
173
+
174
+ private func decodeUrl() throws -> URL {
175
+ guard let str = data as? String,
176
+ let url = URL(string: str)
177
+ else { throw DecodingError.dataCorrupted(data, target: URL.self, codingPath: codingPath) }
178
+
179
+ return url
180
+ }
181
+
182
+ private func decodeData() throws -> Data {
183
+ switch options.dataStrategy {
184
+ case .deferredToData:
185
+ return try Data(from: self)
186
+ case .base64:
187
+ guard let value = data as? String else { throw DecodingError.dataCorrupted(data, target: String.self, codingPath: codingPath) }
188
+ guard let data = Data(base64Encoded: value) else { throw DecodingError.dataCorrupted(value, target: Data.self, codingPath: codingPath) }
189
+ return data
190
+ case .custom(let decode):
191
+ return try decode(self)
192
+ @unknown default:
193
+ return try Data(from: self)
194
+ }
195
+ }
196
+ }
197
+
198
+ private final class KeyedContainer<Key> where Key: CodingKey {
199
+ var data: JSObject
200
+ var codingPath: [CodingKey]
201
+ var userInfo: CodingUserInfo
202
+ var allKeys: [Key]
203
+ var options: Options
204
+
205
+ init(data: JSObject, codingPath: [CodingKey], userInfo: CodingUserInfo, options: Options) {
206
+ self.data = data
207
+ self.codingPath = codingPath
208
+ self.userInfo = userInfo
209
+ self.allKeys = data.keys.compactMap(Key.init(stringValue:))
210
+ self.options = options
211
+ }
212
+ }
213
+
214
+ extension KeyedContainer: KeyedDecodingContainerProtocol {
215
+ func contains(_ key: Key) -> Bool {
216
+ allKeys.contains { $0.stringValue == key.stringValue }
217
+ }
218
+
219
+ func decodeNil(forKey key: Key) throws -> Bool {
220
+ data[key.stringValue] == nil || data[key.stringValue] is NSNull
221
+ }
222
+
223
+ func decode<T>(_ type: T.Type, forKey key: Key) throws -> T where T: Decodable {
224
+ guard let rawValue = data[key.stringValue] else {
225
+ throw DecodingError.keyNotFound(key, on: data, codingPath: codingPath)
226
+ }
227
+
228
+ var newPath = codingPath
229
+ newPath.append(key)
230
+ let decoder = _JSValueDecoder(data: rawValue, options: options)
231
+ return try decoder.decodeData(as: T.self)
232
+ }
233
+
234
+ func nestedUnkeyedContainer(forKey key: Key) throws -> UnkeyedDecodingContainer {
235
+ var newPath = codingPath
236
+ newPath.append(key)
237
+ guard let data = data[key.stringValue] as? JSArray else {
238
+ throw DecodingError.typeMismatch(
239
+ JSArray.self,
240
+ on: data[key.stringValue] ?? "null value",
241
+ codingPath: newPath
242
+ )
243
+ }
244
+
245
+ return UnkeyedContainer(data: data, codingPath: newPath, userInfo: userInfo, options: options)
246
+ }
247
+
248
+ func nestedContainer<NestedKey>(keyedBy type: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer<NestedKey> where NestedKey: CodingKey {
249
+ var newPath = codingPath
250
+ newPath.append(key)
251
+ guard let data = data[key.stringValue] as? JSObject else {
252
+ throw DecodingError.typeMismatch(
253
+ JSObject.self,
254
+ on: data[key.stringValue] ?? "null value",
255
+ codingPath: newPath
256
+ )
257
+ }
258
+
259
+ return KeyedDecodingContainer(KeyedContainer<NestedKey>(data: data, codingPath: newPath, userInfo: userInfo, options: options))
260
+ }
261
+
262
+ enum SuperKey: String, CodingKey { case `super` }
263
+
264
+ func superDecoder() throws -> Decoder {
265
+ var newPath = codingPath
266
+ newPath.append(SuperKey.super)
267
+ guard let data = data[SuperKey.super.stringValue] else {
268
+ throw DecodingError.keyNotFound(SuperKey.super, on: data, codingPath: newPath)
269
+ }
270
+
271
+ return _JSValueDecoder(data: data, options: options)
272
+ }
273
+
274
+ func superDecoder(forKey key: Key) throws -> Decoder {
275
+ var newPath = codingPath
276
+ newPath.append(key)
277
+ guard let data = data[key.stringValue] else {
278
+ throw DecodingError.keyNotFound(key, on: data, codingPath: newPath)
279
+ }
280
+
281
+ return _JSValueDecoder(data: data, options: options)
282
+ }
283
+ }
284
+
285
+ private final class UnkeyedContainer {
286
+ var data: JSArray
287
+ var codingPath: [CodingKey]
288
+ var userInfo: CodingUserInfo
289
+ private(set) var currentIndex = 0
290
+ var options: Options
291
+
292
+ init(data: JSArray, codingPath: [CodingKey], userInfo: CodingUserInfo, options: Options) {
293
+ self.data = data
294
+ self.codingPath = codingPath
295
+ self.userInfo = userInfo
296
+ self.options = options
297
+ }
298
+ }
299
+
300
+ extension UnkeyedContainer: UnkeyedDecodingContainer {
301
+ var count: Int? {
302
+ data.count
303
+ }
304
+
305
+ var isAtEnd: Bool {
306
+ currentIndex == data.endIndex
307
+ }
308
+
309
+ func decodeNil() throws -> Bool {
310
+ defer { currentIndex += 1 }
311
+ return data[currentIndex] is NSNull
312
+ }
313
+
314
+ func decode<T>(_ type: T.Type) throws -> T where T: Decodable {
315
+ defer { currentIndex += 1 }
316
+ let decoder = _JSValueDecoder(data: data[currentIndex], options: options)
317
+ return try decoder.decodeData(as: T.self)
318
+ }
319
+
320
+ func nestedUnkeyedContainer() throws -> UnkeyedDecodingContainer {
321
+ defer { currentIndex += 1 }
322
+ guard let data = data[currentIndex] as? JSArray else {
323
+ throw DecodingError.typeMismatch(JSArray.self, on: data[currentIndex], codingPath: codingPath)
324
+ }
325
+
326
+ return UnkeyedContainer(data: data, codingPath: codingPath, userInfo: userInfo, options: options)
327
+ }
328
+
329
+ func nestedContainer<NestedKey>(keyedBy type: NestedKey.Type) throws -> KeyedDecodingContainer<NestedKey> where NestedKey: CodingKey {
330
+ defer { currentIndex += 1 }
331
+ guard let data = data[currentIndex] as? JSObject else {
332
+ throw DecodingError.typeMismatch(JSObject.self, on: data[currentIndex], codingPath: codingPath)
333
+ }
334
+
335
+ return KeyedDecodingContainer(KeyedContainer(data: data, codingPath: codingPath, userInfo: userInfo, options: options))
336
+ }
337
+
338
+ func superDecoder() throws -> Decoder {
339
+ defer { currentIndex += 1 }
340
+ let data = data[currentIndex]
341
+ return _JSValueDecoder(data: data, options: options)
342
+ }
343
+ }
344
+
345
+ private final class SingleValueContainer {
346
+ var data: JSValue
347
+ var codingPath: [CodingKey]
348
+ var userInfo: CodingUserInfo
349
+ var options: Options
350
+
351
+ init(data: JSValue, codingPath: [CodingKey], userInfo: CodingUserInfo, options: Options) {
352
+ self.data = data
353
+ self.codingPath = codingPath
354
+ self.userInfo = userInfo
355
+ self.options = options
356
+ }
357
+ }
358
+
359
+ extension SingleValueContainer: SingleValueDecodingContainer {
360
+ func decodeNil() -> Bool {
361
+ return data is NSNull
362
+ }
363
+
364
+ private func cast<T>(to type: T.Type) throws -> T {
365
+ guard let data = data as? T else {
366
+ throw DecodingError.typeMismatch(type, on: data, codingPath: codingPath)
367
+ }
368
+
369
+ return data
370
+ }
371
+
372
+ private func castFloat<N>(to type: N.Type) throws -> N where N: FloatingPoint {
373
+ if let data = data as? String,
374
+ case let .convertFromString(positiveInfinity: pos, negativeInfinity: neg, nan: nan) = options.nonConformingStrategy {
375
+ switch data {
376
+ case pos:
377
+ return N.infinity
378
+ case neg:
379
+ return -N.infinity
380
+ case nan:
381
+ return N.nan
382
+ default:
383
+ throw DecodingError.typeMismatch(type, on: data, codingPath: codingPath)
384
+ }
385
+ }
386
+
387
+ let data = try cast(to: N.self)
388
+ if !data.isFinite, case .throw = options.nonConformingStrategy {
389
+ throw DecodingError.dataCorrupted(.init(codingPath: codingPath, debugDescription: "\(data) is a non-conforming floating point number"))
390
+ }
391
+ return data
392
+ }
393
+
394
+ func decode(_ type: Bool.Type) throws -> Bool {
395
+ try cast(to: type)
396
+ }
397
+
398
+ func decode(_ type: String.Type) throws -> String {
399
+ try cast(to: type)
400
+ }
401
+
402
+ func decode(_ type: Double.Type) throws -> Double {
403
+ try castFloat(to: type)
404
+ }
405
+
406
+ func decode(_ type: Float.Type) throws -> Float {
407
+ try castFloat(to: type)
408
+ }
409
+
410
+ func decode(_ type: Int.Type) throws -> Int {
411
+ try cast(to: type)
412
+ }
413
+
414
+ func decode(_ type: Int8.Type) throws -> Int8 {
415
+ try cast(to: type)
416
+ }
417
+
418
+ func decode(_ type: Int16.Type) throws -> Int16 {
419
+ try cast(to: type)
420
+ }
421
+
422
+ func decode(_ type: Int32.Type) throws -> Int32 {
423
+ try cast(to: type)
424
+ }
425
+
426
+ func decode(_ type: Int64.Type) throws -> Int64 {
427
+ try cast(to: type)
428
+ }
429
+
430
+ func decode(_ type: UInt.Type) throws -> UInt {
431
+ try cast(to: type)
432
+ }
433
+
434
+ func decode(_ type: UInt8.Type) throws -> UInt8 {
435
+ try cast(to: type)
436
+ }
437
+
438
+ func decode(_ type: UInt16.Type) throws -> UInt16 {
439
+ try cast(to: type)
440
+ }
441
+
442
+ func decode(_ type: UInt32.Type) throws -> UInt32 {
443
+ try cast(to: type)
444
+ }
445
+
446
+ func decode(_ type: UInt64.Type) throws -> UInt64 {
447
+ try cast(to: type)
448
+ }
449
+
450
+ func decode<T>(_ type: T.Type) throws -> T where T: Decodable {
451
+ let decoder = _JSValueDecoder(data: data, options: options)
452
+ return try decoder.decodeData(as: T.self)
453
+ }
454
+ }
455
+
456
+ extension DecodingError {
457
+ static func typeMismatch(_ type: Any.Type, on data: any JSValue, codingPath: [CodingKey]) -> DecodingError {
458
+ return .typeMismatch(
459
+ type,
460
+ .init(
461
+ codingPath: codingPath,
462
+ debugDescription: "\(data) was unable to be cast to \(type)."
463
+ )
464
+ )
465
+ }
466
+
467
+ static func keyNotFound(_ key: any CodingKey, on data: any JSValue, codingPath: [CodingKey]) -> DecodingError {
468
+ return .keyNotFound(
469
+ key,
470
+ .init(
471
+ codingPath: codingPath,
472
+ debugDescription: "Key \(key.stringValue) not found in \(data)")
473
+ )
474
+ }
475
+
476
+ static func dataCorrupted<T>(_ value: any JSValue, target type: T.Type, codingPath: [CodingKey]) -> DecodingError where T: Decodable {
477
+ return .dataCorrupted(.init(codingPath: codingPath, debugDescription: "\(value) was not in the format expected for \(T.self)"))
478
+ }
479
+ }