@swiftbrowser/swift 0.1.0 → 0.2.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 (393) hide show
  1. package/Package.swift +200 -9
  2. package/README.md +7 -9
  3. package/Sources/AVFoundation/AVFoundation.swift +131 -0
  4. package/Sources/AVFoundation/Asset.swift +487 -0
  5. package/Sources/AVFoundation/AudioSession.swift +144 -0
  6. package/Sources/AVFoundation/CMTime.swift +303 -0
  7. package/Sources/AVFoundation/Capture.swift +688 -0
  8. package/Sources/AVFoundation/Player.swift +749 -0
  9. package/Sources/AVFoundation/PlayerView.swift +117 -0
  10. package/Sources/AVKit/AVKit.swift +132 -0
  11. package/Sources/Accelerate/Accelerate.swift +122 -0
  12. package/Sources/AppIntents/AppIntents.swift +144 -0
  13. package/Sources/AppIntents/Parameters.swift +220 -0
  14. package/Sources/AppIntents/Shortcuts.swift +159 -0
  15. package/Sources/AudioToolbox/AudioToolbox.swift +55 -0
  16. package/Sources/AuthenticationServices/AuthenticationServices.swift +257 -0
  17. package/Sources/AuthenticationServices/Authorization.swift +251 -0
  18. package/Sources/Charts/Charts.swift +0 -4
  19. package/Sources/Combine/AnyCancellable.swift +65 -0
  20. package/Sources/Combine/AnyPublisher.swift +148 -0
  21. package/Sources/Combine/AnySubscriber.swift +230 -0
  22. package/Sources/Combine/Cancellable.swift +35 -0
  23. package/Sources/Combine/Codable.swift +29 -0
  24. package/Sources/Combine/CombineIdentifier.swift +45 -0
  25. package/Sources/Combine/Concurrency/ConcurrencyHelpers.swift +24 -0
  26. package/Sources/Combine/Concurrency/Future+Concurrency.swift +136 -0
  27. package/Sources/Combine/Concurrency/GENERATED-Publisher+Concurrency.swift +397 -0
  28. package/Sources/Combine/CurrentValueSubject.swift +252 -0
  29. package/Sources/Combine/CustomCombineIdentifierConvertible.swift +28 -0
  30. package/Sources/Combine/Future.swift +228 -0
  31. package/Sources/Combine/GENERATED-RootProtocols.swift +426 -0
  32. package/Sources/Combine/Helpers/ConduitBase.swift +40 -0
  33. package/Sources/Combine/Helpers/ConduitList.swift +59 -0
  34. package/Sources/Combine/Helpers/DebugHook.swift +177 -0
  35. package/Sources/Combine/Helpers/FilterProducer.swift +174 -0
  36. package/Sources/Combine/Helpers/Locking.swift +30 -0
  37. package/Sources/Combine/Helpers/PartialCompletion.swift +26 -0
  38. package/Sources/Combine/Helpers/ReduceProducer.swift +249 -0
  39. package/Sources/Combine/Helpers/SubjectSubscriber.swift +96 -0
  40. package/Sources/Combine/Helpers/SubscriberTap.swift +69 -0
  41. package/Sources/Combine/Helpers/SubscriptionStatus.swift +33 -0
  42. package/Sources/Combine/Helpers/SubscriptionTap.swift +33 -0
  43. package/Sources/Combine/Helpers/Utils.swift +30 -0
  44. package/Sources/Combine/Helpers/Violations.swift +33 -0
  45. package/Sources/Combine/ImmediateScheduler.swift +178 -0
  46. package/Sources/Combine/LICENSE +21 -0
  47. package/Sources/Combine/NotificationPublisher.swift +48 -0
  48. package/Sources/Combine/ObjectWillChange.swift +46 -0
  49. package/Sources/Combine/PassthroughSubject.swift +222 -0
  50. package/Sources/Combine/Publisher+Subscribe.swift +53 -0
  51. package/Sources/Combine/Publishers/Deferred.swift +48 -0
  52. package/Sources/Combine/Publishers/Empty.swift +54 -0
  53. package/Sources/Combine/Publishers/Fail.swift +42 -0
  54. package/Sources/Combine/Publishers/GENERATED-Publishers.Catch.swift +673 -0
  55. package/Sources/Combine/Publishers/GENERATED-Publishers.Encode.swift +388 -0
  56. package/Sources/Combine/Publishers/GENERATED-Publishers.MapKeyPath.swift +384 -0
  57. package/Sources/Combine/Publishers/Just.swift +313 -0
  58. package/Sources/Combine/Publishers/Optional.Publisher.swift +315 -0
  59. package/Sources/Combine/Publishers/Publishers.AllSatisfy.swift +217 -0
  60. package/Sources/Combine/Publishers/Publishers.AssertNoFailure.swift +158 -0
  61. package/Sources/Combine/Publishers/Publishers.Autoconnect.swift +193 -0
  62. package/Sources/Combine/Publishers/Publishers.Breakpoint.swift +231 -0
  63. package/Sources/Combine/Publishers/Publishers.Buffer.swift +356 -0
  64. package/Sources/Combine/Publishers/Publishers.Collect.swift +102 -0
  65. package/Sources/Combine/Publishers/Publishers.CollectByCount.swift +195 -0
  66. package/Sources/Combine/Publishers/Publishers.CompactMap.swift +241 -0
  67. package/Sources/Combine/Publishers/Publishers.Comparison.swift +371 -0
  68. package/Sources/Combine/Publishers/Publishers.Concatenate.swift +474 -0
  69. package/Sources/Combine/Publishers/Publishers.Contains.swift +293 -0
  70. package/Sources/Combine/Publishers/Publishers.Count.swift +87 -0
  71. package/Sources/Combine/Publishers/Publishers.Debounce.swift +332 -0
  72. package/Sources/Combine/Publishers/Publishers.Delay.swift +269 -0
  73. package/Sources/Combine/Publishers/Publishers.Drop.swift +155 -0
  74. package/Sources/Combine/Publishers/Publishers.DropUntilOutput.swift +283 -0
  75. package/Sources/Combine/Publishers/Publishers.DropWhile.swift +378 -0
  76. package/Sources/Combine/Publishers/Publishers.Filter.swift +248 -0
  77. package/Sources/Combine/Publishers/Publishers.First.swift +261 -0
  78. package/Sources/Combine/Publishers/Publishers.FlatMap.swift +533 -0
  79. package/Sources/Combine/Publishers/Publishers.HandleEvents.swift +260 -0
  80. package/Sources/Combine/Publishers/Publishers.IgnoreOutput.swift +109 -0
  81. package/Sources/Combine/Publishers/Publishers.Last.swift +252 -0
  82. package/Sources/Combine/Publishers/Publishers.MakeConnectable.swift +82 -0
  83. package/Sources/Combine/Publishers/Publishers.Map.swift +351 -0
  84. package/Sources/Combine/Publishers/Publishers.MapError.swift +140 -0
  85. package/Sources/Combine/Publishers/Publishers.MeasureInterval.swift +187 -0
  86. package/Sources/Combine/Publishers/Publishers.Multicast.swift +284 -0
  87. package/Sources/Combine/Publishers/Publishers.Output.swift +241 -0
  88. package/Sources/Combine/Publishers/Publishers.PrefixUntilOutput.swift +197 -0
  89. package/Sources/Combine/Publishers/Publishers.PrefixWhile.swift +176 -0
  90. package/Sources/Combine/Publishers/Publishers.Print.swift +206 -0
  91. package/Sources/Combine/Publishers/Publishers.ReceiveOn.swift +227 -0
  92. package/Sources/Combine/Publishers/Publishers.Reduce.swift +204 -0
  93. package/Sources/Combine/Publishers/Publishers.RemoveDuplicates.swift +264 -0
  94. package/Sources/Combine/Publishers/Publishers.ReplaceEmpty.swift +201 -0
  95. package/Sources/Combine/Publishers/Publishers.ReplaceError.swift +211 -0
  96. package/Sources/Combine/Publishers/Publishers.Retry.swift +274 -0
  97. package/Sources/Combine/Publishers/Publishers.Scan.swift +331 -0
  98. package/Sources/Combine/Publishers/Publishers.Sequence.swift +437 -0
  99. package/Sources/Combine/Publishers/Publishers.SetFailureType.swift +120 -0
  100. package/Sources/Combine/Publishers/Publishers.Share.swift +104 -0
  101. package/Sources/Combine/Publishers/Publishers.SubscribeOn.swift +197 -0
  102. package/Sources/Combine/Publishers/Publishers.SwitchToLatest.swift +444 -0
  103. package/Sources/Combine/Publishers/Publishers.Throttle.swift +359 -0
  104. package/Sources/Combine/Publishers/Publishers.Timeout.swift +301 -0
  105. package/Sources/Combine/Publishers/Publishers.Zip.swift +720 -0
  106. package/Sources/Combine/Publishers/Publishers.swift +13 -0
  107. package/Sources/Combine/Publishers/Record.swift +237 -0
  108. package/Sources/Combine/Publishers/Result.Publisher.swift +337 -0
  109. package/Sources/Combine/Result.swift +46 -0
  110. package/Sources/Combine/Scheduler.swift +89 -0
  111. package/Sources/Combine/Schedulers.swift +211 -0
  112. package/Sources/Combine/Subject+Void.swift +17 -0
  113. package/Sources/Combine/Subscriber+Void.swift +20 -0
  114. package/Sources/Combine/Subscribers/Subscribers.Assign.swift +175 -0
  115. package/Sources/Combine/Subscribers/Subscribers.Completion.swift +90 -0
  116. package/Sources/Combine/Subscribers/Subscribers.Demand.swift +476 -0
  117. package/Sources/Combine/Subscribers/Subscribers.Sink.swift +206 -0
  118. package/Sources/Combine/Subscribers/Subscribers.swift +9 -0
  119. package/Sources/Combine/Subscription.swift +22 -0
  120. package/Sources/Combine/Subscriptions.swift +42 -0
  121. package/Sources/Combine/SwiftUIObservation.swift +10 -0
  122. package/Sources/Combine/_Introspection.swift +107 -0
  123. package/Sources/CommonCrypto/CommonCrypto.swift +80 -0
  124. package/Sources/Compression/Compression.swift +365 -0
  125. package/Sources/Compression/Deflate.swift +407 -0
  126. package/Sources/Compression/Zlib.swift +179 -0
  127. package/Sources/CoreFoundationTypes/CoreFoundationTypes.swift +101 -0
  128. package/Sources/CoreGraphics/CoreGraphics.swift +411 -0
  129. package/Sources/CoreGraphics/ProjectionTransforms.swift +28 -0
  130. package/Sources/CoreHaptics/CoreHaptics.swift +399 -0
  131. package/Sources/CoreImage/CIColor.swift +41 -0
  132. package/Sources/CoreImage/CIContext.swift +31 -0
  133. package/Sources/CoreImage/CIDetector.swift +57 -0
  134. package/Sources/CoreImage/CIFilter.swift +243 -0
  135. package/Sources/CoreImage/CIFilterBuiltins.swift +136 -0
  136. package/Sources/CoreImage/CIImage.swift +162 -0
  137. package/Sources/CoreImage/QRCode.swift +393 -0
  138. package/Sources/CoreLocation/Coordinate.swift +30 -0
  139. package/Sources/CoreLocation/Location.swift +65 -0
  140. package/Sources/CoreML/Evaluation.swift +414 -0
  141. package/Sources/CoreML/FeatureValue.swift +266 -0
  142. package/Sources/CoreML/Model.swift +269 -0
  143. package/Sources/CoreML/MultiArray.swift +92 -0
  144. package/Sources/CoreML/Specification.swift +233 -0
  145. package/Sources/CoreText/CoreText.swift +64 -0
  146. package/Sources/CoreTransferable/CoreTransferable.swift +606 -0
  147. package/Sources/CryptoKit/ChaChaPoly.swift +258 -0
  148. package/Sources/CryptoKit/CryptoKit.swift +375 -0
  149. package/Sources/CryptoKit/Curve25519.swift +317 -0
  150. package/Sources/CryptoKit/P256.swift +321 -0
  151. package/Sources/FoundationBridge/AppStorage.swift +165 -0
  152. package/Sources/FoundationBridge/AssetResources.swift +90 -0
  153. package/Sources/FoundationBridge/AsyncBytes.swift +128 -0
  154. package/Sources/FoundationBridge/AsyncImage.swift +116 -0
  155. package/Sources/FoundationBridge/AttributedStrings.swift +16 -0
  156. package/Sources/{_FoundationCommon → FoundationBridge}/Bundle.swift +41 -4
  157. package/Sources/FoundationBridge/CombineExports.swift +8 -0
  158. package/Sources/FoundationBridge/CoreFoundation.swift +77 -0
  159. package/Sources/FoundationBridge/Dispatch.swift +458 -0
  160. package/Sources/FoundationBridge/EnvironmentFoundation.swift +41 -0
  161. package/Sources/FoundationBridge/FileImporter.swift +128 -0
  162. package/Sources/FoundationBridge/FileSystem.swift +68 -0
  163. package/Sources/FoundationBridge/FoundationBridge.swift +24 -72
  164. package/Sources/FoundationBridge/HostResolution.swift +31 -0
  165. package/Sources/FoundationBridge/ItemProvider.swift +655 -0
  166. package/Sources/FoundationBridge/KeyValueObserving.swift +138 -0
  167. package/Sources/FoundationBridge/Links.swift +127 -0
  168. package/Sources/FoundationBridge/ListFormatter.swift +32 -0
  169. package/Sources/FoundationBridge/Localization.swift +149 -0
  170. package/Sources/FoundationBridge/Locks.swift +50 -0
  171. package/Sources/FoundationBridge/Markdown.swift +527 -0
  172. package/Sources/FoundationBridge/MeasurementFormat.swift +95 -0
  173. package/Sources/FoundationBridge/NotificationCenter.swift +154 -0
  174. package/Sources/FoundationBridge/OpenURLHandlers.swift +60 -0
  175. package/Sources/FoundationBridge/Operation.swift +195 -0
  176. package/Sources/FoundationBridge/ProcessInfo.swift +32 -0
  177. package/Sources/FoundationBridge/RelativeDateTimeFormatter.swift +136 -0
  178. package/Sources/FoundationBridge/SceneStorage.swift +78 -0
  179. package/Sources/FoundationBridge/SecurityExports.swift +8 -0
  180. package/Sources/FoundationBridge/Selector.swift +226 -0
  181. package/Sources/FoundationBridge/StringComparators.swift +17 -0
  182. package/Sources/FoundationBridge/Table.swift +211 -0
  183. package/Sources/FoundationBridge/TextAttributes.swift +42 -0
  184. package/Sources/FoundationBridge/Timer.swift +6 -1
  185. package/Sources/FoundationBridge/URLSession.swift +718 -0
  186. package/Sources/{_FoundationCommon → FoundationBridge}/UserDefaults.swift +17 -4
  187. package/Sources/FoundationBridge/WebAuthRedirects.swift +227 -0
  188. package/Sources/FoundationBridge/WebSocket.swift +187 -0
  189. package/Sources/FoundationModels/FoundationModels.swift +1098 -0
  190. package/Sources/ImageIO/GIF.swift +72 -0
  191. package/Sources/ImageIO/ImageIO.swift +248 -0
  192. package/Sources/ImageIO/ImageTypes.swift +28 -0
  193. package/Sources/LinkPresentation/LinkPresentation.swift +249 -0
  194. package/Sources/LocalAuthentication/LAContext.swift +86 -0
  195. package/Sources/MapKit/Geometry.swift +223 -0
  196. package/Sources/MapKit/Map.swift +638 -0
  197. package/Sources/MapKit/MapView.swift +229 -0
  198. package/Sources/MobileCoreServices/MobileCoreServices.swift +28 -0
  199. package/Sources/NaturalLanguage/LanguageIdentifier.swift +317 -0
  200. package/Sources/NaturalLanguage/NaturalLanguage.swift +135 -0
  201. package/Sources/OSLog/OSLog.swift +6 -0
  202. package/Sources/Photos/Photos.swift +572 -0
  203. package/Sources/PhotosUI/PhotosPicker.swift +248 -0
  204. package/Sources/PhotosUI/PhotosPickerItem.swift +261 -0
  205. package/Sources/QuickLook/QuickLook.swift +168 -0
  206. package/Sources/SafariServices/SafariServices.swift +106 -0
  207. package/Sources/Security/Security.swift +332 -0
  208. package/Sources/StoreKit/AppStore.swift +207 -0
  209. package/Sources/StoreKit/Products.swift +280 -0
  210. package/Sources/StoreKit/RequestReview.swift +28 -0
  211. package/Sources/StoreKit/StoreKit1.swift +486 -0
  212. package/Sources/StoreKit/StoreViews.swift +428 -0
  213. package/Sources/StoreKit/Transactions.swift +197 -0
  214. package/Sources/SwiftData/Macros.swift +58 -0
  215. package/Sources/SwiftData/ModelActor.swift +38 -0
  216. package/Sources/SwiftData/ModelContainer.swift +129 -0
  217. package/Sources/SwiftData/ModelContext.swift +451 -0
  218. package/Sources/SwiftData/PersistentModel.swift +238 -0
  219. package/Sources/SwiftData/Properties.swift +261 -0
  220. package/Sources/SwiftData/Query.swift +256 -0
  221. package/Sources/SwiftData/Schema.swift +192 -0
  222. package/Sources/SwiftData/Store.swift +146 -0
  223. package/Sources/SwiftData/StringPredicates.swift +125 -0
  224. package/Sources/SwiftDataMacros/EntryMacro.swift +82 -0
  225. package/Sources/SwiftDataMacros/GenerableMacro.swift +183 -0
  226. package/Sources/SwiftDataMacros/ModelActorMacro.swift +46 -0
  227. package/Sources/SwiftDataMacros/ModelMacro.swift +260 -0
  228. package/Sources/SwiftDataMacros/Plugin.swift +18 -0
  229. package/Sources/SwiftDataMacros/PredicateMacro.swift +1244 -0
  230. package/Sources/SwiftUI/API/Accessibility.swift +55 -6
  231. package/Sources/SwiftUI/API/AccessibilityExtras.swift +33 -0
  232. package/Sources/SwiftUI/API/AccessibilityFocus.swift +63 -0
  233. package/Sources/SwiftUI/API/Alert.swift +1 -1
  234. package/Sources/SwiftUI/API/AlignmentGuides.swift +65 -0
  235. package/Sources/SwiftUI/API/Animation.swift +37 -5
  236. package/Sources/SwiftUI/API/App.swift +31 -1
  237. package/Sources/SwiftUI/API/BindingCollections.swift +35 -0
  238. package/Sources/SwiftUI/API/BindingForEach.swift +27 -0
  239. package/Sources/SwiftUI/API/Bitmaps.swift +254 -0
  240. package/Sources/SwiftUI/API/ButtonStyles.swift +96 -0
  241. package/Sources/SwiftUI/API/Canvas.swift +337 -0
  242. package/Sources/SwiftUI/API/Color.swift +104 -28
  243. package/Sources/SwiftUI/API/ColorEffects.swift +52 -0
  244. package/Sources/SwiftUI/API/ColorPickerAndLabeledContent.swift +138 -0
  245. package/Sources/SwiftUI/API/ColorSpaces.swift +161 -0
  246. package/Sources/SwiftUI/API/Commands.swift +106 -0
  247. package/Sources/SwiftUI/API/ContainerBackground.swift +28 -0
  248. package/Sources/SwiftUI/API/ContentShape.swift +33 -0
  249. package/Sources/SwiftUI/API/ContentSizeCategory.swift +35 -0
  250. package/Sources/SwiftUI/API/ContentUnavailable.swift +101 -0
  251. package/Sources/SwiftUI/API/Controls.swift +59 -27
  252. package/Sources/SwiftUI/API/CustomLayout.swift +49 -10
  253. package/Sources/SwiftUI/API/CustomToolbarContent.swift +46 -0
  254. package/Sources/SwiftUI/API/Decorations.swift +1 -1
  255. package/Sources/SwiftUI/API/EditMode.swift +25 -82
  256. package/Sources/SwiftUI/API/Effects.swift +105 -7
  257. package/Sources/SwiftUI/API/Entry.swift +8 -0
  258. package/Sources/SwiftUI/API/Environment.swift +93 -9
  259. package/Sources/SwiftUI/API/EnvironmentSendable.swift +6 -0
  260. package/Sources/SwiftUI/API/Focus.swift +11 -3
  261. package/Sources/SwiftUI/API/Gauge.swift +3 -2
  262. package/Sources/SwiftUI/API/GeometryEffects.swift +232 -0
  263. package/Sources/SwiftUI/API/GeometryReader.swift +13 -2
  264. package/Sources/SwiftUI/API/GestureState.swift +65 -0
  265. package/Sources/SwiftUI/API/Gestures.swift +1 -1
  266. package/Sources/SwiftUI/API/Glass.swift +127 -0
  267. package/Sources/SwiftUI/API/Grid.swift +1 -1
  268. package/Sources/SwiftUI/API/GroupBoxAndControlGroup.swift +130 -0
  269. package/Sources/SwiftUI/API/KeyPress.swift +54 -0
  270. package/Sources/SwiftUI/API/LabelStyle.swift +13 -6
  271. package/Sources/SwiftUI/API/Layout.swift +67 -12
  272. package/Sources/SwiftUI/API/LazyStacks.swift +49 -0
  273. package/Sources/SwiftUI/API/LegacyAlert.swift +97 -0
  274. package/Sources/SwiftUI/API/Lists.swift +61 -6
  275. package/Sources/SwiftUI/API/Menu.swift +8 -1
  276. package/Sources/SwiftUI/API/Modifiers.swift +80 -10
  277. package/Sources/SwiftUI/API/MoreModifiers.swift +100 -0
  278. package/Sources/SwiftUI/API/Namespace.swift +44 -0
  279. package/Sources/SwiftUI/API/Navigation.swift +24 -9
  280. package/Sources/SwiftUI/API/NavigationDestinationBindings.swift +55 -0
  281. package/Sources/SwiftUI/API/ObservableObject.swift +16 -2
  282. package/Sources/SwiftUI/API/Path.swift +543 -0
  283. package/Sources/SwiftUI/API/Phase8Controls.swift +48 -31
  284. package/Sources/SwiftUI/API/PhaseAnimator.swift +130 -0
  285. package/Sources/SwiftUI/API/Picker.swift +11 -2
  286. package/Sources/SwiftUI/API/PointerAndKeyboard.swift +77 -0
  287. package/Sources/SwiftUI/API/Popover.swift +41 -0
  288. package/Sources/SwiftUI/API/Preferences.swift +262 -0
  289. package/Sources/SwiftUI/API/Presentation.swift +17 -4
  290. package/Sources/SwiftUI/API/PresentationExtras.swift +60 -0
  291. package/Sources/SwiftUI/API/Primitives.swift +164 -37
  292. package/Sources/SwiftUI/API/Publishers.swift +4 -4
  293. package/Sources/SwiftUI/API/Redaction.swift +75 -0
  294. package/Sources/SwiftUI/API/RowActions.swift +3 -2
  295. package/Sources/SwiftUI/API/Scenes.swift +131 -0
  296. package/Sources/SwiftUI/API/ScrollModifiers.swift +132 -0
  297. package/Sources/SwiftUI/API/ScrollTargets.swift +3 -3
  298. package/Sources/SwiftUI/API/ScrollViewReader.swift +144 -0
  299. package/Sources/SwiftUI/API/SectionSupplements.swift +96 -0
  300. package/Sources/SwiftUI/API/Shape.swift +214 -0
  301. package/Sources/SwiftUI/API/ShapeStyle.swift +105 -7
  302. package/Sources/SwiftUI/API/ShapeTrim.swift +78 -0
  303. package/Sources/SwiftUI/API/Sharing.swift +193 -0
  304. package/Sources/SwiftUI/API/StackLayouts.swift +199 -0
  305. package/Sources/SwiftUI/API/State.swift +18 -1
  306. package/Sources/SwiftUI/API/StatusGaps.swift +121 -0
  307. package/Sources/SwiftUI/API/SymbolEffects.swift +203 -0
  308. package/Sources/SwiftUI/API/TabContent.swift +841 -0
  309. package/Sources/SwiftUI/API/Table.swift +382 -0
  310. package/Sources/SwiftUI/API/Tabs.swift +148 -4
  311. package/Sources/SwiftUI/API/Tasks.swift +2 -2
  312. package/Sources/SwiftUI/API/Text.swift +386 -0
  313. package/Sources/SwiftUI/API/TextDates.swift +61 -0
  314. package/Sources/SwiftUI/API/TextDecorations.swift +52 -0
  315. package/Sources/SwiftUI/API/TextFieldAxis.swift +103 -0
  316. package/Sources/SwiftUI/API/TextFieldCommit.swift +52 -0
  317. package/Sources/SwiftUI/API/Toolbar.swift +52 -16
  318. package/Sources/SwiftUI/API/Transfer.swift +145 -0
  319. package/Sources/SwiftUI/API/UnevenRoundedRectangle.swift +66 -0
  320. package/Sources/SwiftUI/API/Video.swift +64 -0
  321. package/Sources/SwiftUI/API/View.swift +10 -2
  322. package/Sources/SwiftUI/API/ViewModifier.swift +4 -1
  323. package/Sources/SwiftUI/API/VisualEffect.swift +74 -1
  324. package/Sources/SwiftUI/API/Windows.swift +25 -0
  325. package/Sources/SwiftUI/Charts/Axis.swift +7 -1
  326. package/Sources/SwiftUI/Charts/AxisFormatsAndRanges.swift +68 -0
  327. package/Sources/SwiftUI/Charts/Chart.swift +17 -3
  328. package/Sources/SwiftUI/Charts/ChartProxy.swift +57 -0
  329. package/Sources/SwiftUI/Localization/Localization.swift +498 -0
  330. package/Sources/SwiftUI/Localization/PluralRules.swift +127 -0
  331. package/Sources/SwiftUI/Runtime/Executor.swift +2 -0
  332. package/Sources/SwiftUI/Runtime/Exports.swift +37 -1
  333. package/Sources/SwiftUI/Runtime/ImageSource.swift +310 -0
  334. package/Sources/SwiftUI/Runtime/JSON.swift +76 -4
  335. package/Sources/SwiftUI/Runtime/LazyRows.swift +99 -0
  336. package/Sources/SwiftUI/Runtime/Measurements.swift +140 -0
  337. package/Sources/SwiftUI/Runtime/Ops.swift +58 -12
  338. package/Sources/SwiftUI/Runtime/Reconciler.swift +10 -1
  339. package/Sources/SwiftUI/Runtime/Replay.swift +382 -0
  340. package/Sources/SwiftUI/Runtime/Runtime.swift +977 -198
  341. package/Sources/SwiftUI/Runtime/Sameness.swift +152 -0
  342. package/Sources/SwiftUI/Runtime/ViewPath.swift +89 -0
  343. package/Sources/SwiftUI/Runtime/ViewTraits.swift +175 -0
  344. package/Sources/SwiftUI/Runtime/WebAuthHeadless.swift +49 -0
  345. package/Sources/Symbols/Symbols.swift +25 -0
  346. package/Sources/Translation/Translation.swift +423 -0
  347. package/Sources/UIKit/Activity.swift +213 -0
  348. package/Sources/UIKit/Alerts.swift +69 -0
  349. package/Sources/UIKit/AppDelegate.swift +222 -0
  350. package/Sources/UIKit/Appearance.swift +84 -0
  351. package/Sources/UIKit/ColorConversions.swift +70 -0
  352. package/Sources/UIKit/Controls.swift +225 -0
  353. package/Sources/UIKit/Device.swift +200 -0
  354. package/Sources/UIKit/Feedback.swift +65 -0
  355. package/Sources/UIKit/Font.swift +307 -0
  356. package/Sources/UIKit/Graphics.swift +204 -0
  357. package/Sources/UIKit/HostingController.swift +185 -0
  358. package/Sources/UIKit/Identity.swift +24 -0
  359. package/Sources/UIKit/Introspectable.swift +510 -0
  360. package/Sources/UIKit/Pasteboard.swift +363 -0
  361. package/Sources/UIKit/PhotoAlbum.swift +81 -0
  362. package/Sources/UIKit/RemoteNotifications.swift +15 -0
  363. package/Sources/UIKit/Representable.swift +288 -0
  364. package/Sources/UIKit/SafeArea.swift +12 -0
  365. package/Sources/UIKit/SceneDelegates.swift +132 -0
  366. package/Sources/UIKit/Scenes.swift +40 -0
  367. package/Sources/UIKit/ScrollView.swift +157 -0
  368. package/Sources/UIKit/ShortcutItems.swift +67 -0
  369. package/Sources/UIKit/SymbolConfiguration.swift +124 -0
  370. package/Sources/UIKit/TargetAction.swift +123 -0
  371. package/Sources/UIKit/TextPaste.swift +161 -0
  372. package/Sources/UIKit/TextView.swift +538 -0
  373. package/Sources/UIKit/UIKit.swift +292 -0
  374. package/Sources/UIKit/UIView.swift +855 -0
  375. package/Sources/UIKit/ViewTranslation.swift +311 -0
  376. package/Sources/UniformTypeIdentifiers/UTType.swift +196 -0
  377. package/Sources/UserNotifications/Content.swift +370 -0
  378. package/Sources/UserNotifications/NotificationCenter.swift +309 -0
  379. package/Sources/WeatherKit/WeatherKit.swift +228 -0
  380. package/Sources/WebKit/WebKit.swift +245 -0
  381. package/Sources/os/os.swift +376 -0
  382. package/Sources/zlib/zlib.swift +6 -0
  383. package/index.d.ts +1 -1
  384. package/index.mjs +2 -2
  385. package/manifest.d.mts +2 -0
  386. package/manifest.mjs +39 -0
  387. package/package.json +5 -3
  388. package/sync-sources.mjs +21 -7
  389. package/Sources/FoundationLite/Common.swift +0 -3
  390. package/Sources/FoundationLite/FoundationLite.swift +0 -171
  391. package/Sources/FoundationLite/Interaction.swift +0 -146
  392. package/Sources/FoundationLite/Timer.swift +0 -48
  393. package/Sources/_FoundationCommon/_FoundationCommon.swift +0 -10
@@ -0,0 +1,106 @@
1
+ // `import SafariServices` for the browser: `SFSafariViewController`, the
2
+ // in-app Safari sheet, becomes a new tab. Presenting one (any view
3
+ // controller's `present`) asks the page to open its URL as a link would (an
4
+ // `openURL` host request; docs/ops-protocol.md, "Rich text"), and the
5
+ // controller is then done: it dismisses itself and tells its delegate
6
+ // `safariViewControllerDidFinish`, since the tab is the viewer's own from
7
+ // there. A URL that is not http(s) is refused, as on iOS (where the
8
+ // initializer raises). The configuration and tint colors are kept with
9
+ // nothing to style; Reader mode is the browser's own.
10
+
11
+ import Foundation
12
+ import FoundationBridge
13
+ import SwiftUI
14
+ import UIKit
15
+
16
+ /// The in-app browser: a new tab on the page (see the top of this file).
17
+ @MainActor
18
+ open class SFSafariViewController: UIViewController {
19
+ /// How the controller is set up; kept, with nothing in a tab to apply it to.
20
+ @MainActor
21
+ open class Configuration {
22
+ open var entersReaderIfAvailable = false
23
+ open var barCollapsingEnabled = true
24
+ public init() {}
25
+ }
26
+
27
+ public enum DismissButtonStyle: Int, Sendable {
28
+ case done = 0, close, cancel
29
+ }
30
+
31
+ /// Opens a URL on the page; tests replace it.
32
+ static var openOnPage: @MainActor (URL) -> Void = { url in
33
+ _Runtime.shared._openLinkOnPage(url.absoluteString)
34
+ }
35
+
36
+ public let url: URL
37
+ public let configuration: Configuration
38
+ open weak var delegate: (any SFSafariViewControllerDelegate)?
39
+ open var preferredBarTintColor: UIColor?
40
+ open var preferredControlTintColor: UIColor?
41
+ open var dismissButtonStyle: DismissButtonStyle = .done
42
+ private var opened = false
43
+
44
+ public init(url URL: URL, configuration: Configuration = Configuration()) {
45
+ self.url = URL
46
+ self.configuration = configuration
47
+ super.init(nibName: nil, bundle: nil)
48
+ }
49
+
50
+ @available(*, deprecated, renamed: "init(url:configuration:)")
51
+ public convenience init(url URL: URL, entersReaderIfAvailable: Bool) {
52
+ let configuration = Configuration()
53
+ configuration.entersReaderIfAvailable = entersReaderIfAvailable
54
+ self.init(url: URL, configuration: configuration)
55
+ }
56
+
57
+ public required init?(coder: NSCoder) { nil }
58
+
59
+ /// Presented: the URL opens in a new tab, and the controller finishes.
60
+ open override func viewDidAppear(_ animated: Bool) {
61
+ super.viewDidAppear(animated)
62
+ guard !opened else { return }
63
+ opened = true
64
+ if let scheme = url.scheme?.lowercased(), scheme == "http" || scheme == "https" {
65
+ Self.openOnPage(url)
66
+ delegate?.safariViewControllerWillOpenInBrowser(self)
67
+ }
68
+ dismiss(animated: animated)
69
+ delegate?.safariViewControllerDidFinish(self)
70
+ }
71
+
72
+ /// Nothing to warm up: the browser loads the page when the tab opens.
73
+ public static func prewarmConnections(to URLs: [URL]) -> PrewarmingToken { PrewarmingToken() }
74
+
75
+ public final class PrewarmingToken: Sendable {
76
+ public func invalidate() {}
77
+ }
78
+ }
79
+
80
+ /// What a Safari view controller tells its owner. Every method is optional.
81
+ @MainActor
82
+ public protocol SFSafariViewControllerDelegate: AnyObject {
83
+ /// The controller is done: in the browser, right after it opened its tab.
84
+ func safariViewControllerDidFinish(_ controller: SFSafariViewController)
85
+ /// Never called: the page cannot see another site's tab load.
86
+ func safariViewController(_ controller: SFSafariViewController, didCompleteInitialLoad didLoadSuccessfully: Bool)
87
+ /// Never called, for the same reason.
88
+ func safariViewController(_ controller: SFSafariViewController, initialLoadDidRedirectTo URL: URL)
89
+ /// Called as the URL opens in its tab.
90
+ func safariViewControllerWillOpenInBrowser(_ controller: SFSafariViewController)
91
+ }
92
+
93
+ extension SFSafariViewControllerDelegate {
94
+ public func safariViewControllerDidFinish(_ controller: SFSafariViewController) {}
95
+ public func safariViewController(_ controller: SFSafariViewController, didCompleteInitialLoad didLoadSuccessfully: Bool) {}
96
+ public func safariViewController(_ controller: SFSafariViewController, initialLoadDidRedirectTo URL: URL) {}
97
+ public func safariViewControllerWillOpenInBrowser(_ controller: SFSafariViewController) {}
98
+ }
99
+
100
+ // MARK: - Authentication sessions (deprecated)
101
+
102
+ /// `SFAuthenticationSession`, iOS 11's sign-in session, deprecated for
103
+ /// AuthenticationServices' `ASWebAuthenticationSession`: not here. An app
104
+ /// that still uses it fails to compile with this message.
105
+ @available(*, unavailable, message: "use AuthenticationServices' ASWebAuthenticationSession, which the browser has")
106
+ public final class SFAuthenticationSession {}
@@ -0,0 +1,332 @@
1
+ // `import Security` for the browser: the keychain's item functions
2
+ // (`SecItemAdd`, `SecItemCopyMatching`, `SecItemUpdate`, `SecItemDelete`) over
3
+ // a store of generic and internet passwords. The store is a file in the app's
4
+ // home (`$HOME/Library/Keychains/keychain.json`, `/data` in the browser),
5
+ // which the page keeps across launches like the app's other files. That makes
6
+ // it as private as the rest of the page's storage for its origin, not
7
+ // encrypted, and with one access group: the app's.
8
+ //
9
+ // Queries are dictionaries keyed by the `kSec…` constants, as on Apple
10
+ // platforms, and the constants have Apple's values ("acct", "svce", …), so
11
+ // code that spells them as strings works too. Certificates, keys, identities
12
+ // and access control are not here.
13
+
14
+ import Foundation
15
+ // `OSStatus`, `CFString`, `CFDictionary`…
16
+ @_exported import CoreFoundationTypes
17
+
18
+ public let errSecSuccess: OSStatus = 0
19
+ public let noErr: OSStatus = 0
20
+ public let errSecUnimplemented: OSStatus = -4
21
+ public let errSecParam: OSStatus = -50
22
+ public let errSecAllocate: OSStatus = -108
23
+ public let errSecDuplicateItem: OSStatus = -25299
24
+ public let errSecInvalidValue: OSStatus = -67695
25
+ public let errSecItemNotFound: OSStatus = -25300
26
+ public let errSecInteractionNotAllowed: OSStatus = -25308
27
+ public let errSecDecode: OSStatus = -26275
28
+ public let errSecAuthFailed: OSStatus = -25293
29
+ public let errSecMissingEntitlement: OSStatus = -34018
30
+
31
+ // Item classes.
32
+ public let kSecClass: CFString = "class"
33
+ public let kSecClassGenericPassword: CFString = "genp"
34
+ public let kSecClassInternetPassword: CFString = "inet"
35
+
36
+ // Attributes.
37
+ public let kSecAttrAccount: CFString = "acct"
38
+ public let kSecAttrService: CFString = "svce"
39
+ public let kSecAttrServer: CFString = "srvr"
40
+ public let kSecAttrProtocol: CFString = "ptcl"
41
+ public let kSecAttrPort: CFString = "port"
42
+ public let kSecAttrPath: CFString = "path"
43
+ public let kSecAttrLabel: CFString = "labl"
44
+ public let kSecAttrDescription: CFString = "desc"
45
+ public let kSecAttrComment: CFString = "icmt"
46
+ public let kSecAttrGeneric: CFString = "gena"
47
+ public let kSecAttrAccessGroup: CFString = "agrp"
48
+ public let kSecAttrSynchronizable: CFString = "sync"
49
+ public let kSecAttrSynchronizableAny: CFString = "syna"
50
+ public let kSecAttrCreationDate: CFString = "cdat"
51
+ public let kSecAttrModificationDate: CFString = "mdat"
52
+ public let kSecAttrAccessible: CFString = "pdmn"
53
+ public let kSecAttrAccessibleWhenUnlocked: CFString = "ak"
54
+ public let kSecAttrAccessibleAfterFirstUnlock: CFString = "ck"
55
+ public let kSecAttrAccessibleWhenUnlockedThisDeviceOnly: CFString = "aku"
56
+ public let kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly: CFString = "cku"
57
+ public let kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly: CFString = "akpu"
58
+ public let kSecAttrAccessibleAlways: CFString = "dk"
59
+ public let kSecAttrAccessibleAlwaysThisDeviceOnly: CFString = "dku"
60
+
61
+ // Values, returns and search.
62
+ public let kSecValueData: CFString = "v_Data"
63
+ public let kSecValueRef: CFString = "v_Ref"
64
+ public let kSecValuePersistentRef: CFString = "v_PersistentRef"
65
+ public let kSecReturnData: CFString = "r_Data"
66
+ public let kSecReturnAttributes: CFString = "r_Attributes"
67
+ public let kSecReturnRef: CFString = "r_Ref"
68
+ public let kSecReturnPersistentRef: CFString = "r_PersistentRef"
69
+ public let kSecMatchLimit: CFString = "m_Limit"
70
+ public let kSecMatchLimitOne: CFString = "m_LimitOne"
71
+ public let kSecMatchLimitAll: CFString = "m_LimitAll"
72
+ public let kSecUseDataProtectionKeychain: CFString = "nleg"
73
+ public let kSecUseAuthenticationUI: CFString = "u_AuthUI"
74
+
75
+ /// Adds an item; `result` receives what the attributes' `kSecReturn…` keys ask for.
76
+ public func SecItemAdd(_ attributes: CFDictionary, _ result: UnsafeMutablePointer<CFTypeRef?>?) -> OSStatus {
77
+ _Keychain.shared.add(attributes, result)
78
+ }
79
+
80
+ /// Finds the items matching the query; `result` receives what its `kSecReturn…` keys ask for.
81
+ public func SecItemCopyMatching(_ query: CFDictionary, _ result: UnsafeMutablePointer<CFTypeRef?>?) -> OSStatus {
82
+ _Keychain.shared.copyMatching(query, result)
83
+ }
84
+
85
+ /// Changes the attributes (and data) of every item matching the query.
86
+ public func SecItemUpdate(_ query: CFDictionary, _ attributesToUpdate: CFDictionary) -> OSStatus {
87
+ _Keychain.shared.update(query, attributesToUpdate)
88
+ }
89
+
90
+ /// Deletes every item matching the query.
91
+ public func SecItemDelete(_ query: CFDictionary) -> OSStatus {
92
+ _Keychain.shared.delete(query)
93
+ }
94
+
95
+ public func SecCopyErrorMessageString(_ status: OSStatus, _ reserved: UnsafeMutableRawPointer?) -> CFString? {
96
+ switch status {
97
+ case errSecSuccess: "No error."
98
+ case errSecParam: "One or more parameters passed to a function were not valid."
99
+ case errSecDuplicateItem: "The specified item already exists in the keychain."
100
+ case errSecItemNotFound: "The specified item could not be found in the keychain."
101
+ case errSecUnimplemented: "Function or operation not implemented."
102
+ case errSecDecode: "Unable to decode the provided data."
103
+ default: "OSStatus \(status)"
104
+ }
105
+ }
106
+
107
+ /// The keychain's items, kept in a file in the app's home.
108
+ final class _Keychain: @unchecked Sendable {
109
+ nonisolated(unsafe) static var shared = _Keychain(file: _Keychain.defaultFile)
110
+
111
+ static var defaultFile: URL {
112
+ let home = ProcessInfo.processInfo.environment["HOME"].flatMap { $0.hasPrefix("/") ? $0 : nil } ?? "/data"
113
+ return URL(fileURLWithPath: home).appendingPathComponent("Library/Keychains/keychain.json")
114
+ }
115
+
116
+ /// The attributes an item is matched on and returns, besides its data.
117
+ static let attributeKeys: Set<String> = [
118
+ kSecClass, kSecAttrAccount, kSecAttrService, kSecAttrServer, kSecAttrProtocol, kSecAttrPort, kSecAttrPath,
119
+ kSecAttrLabel, kSecAttrDescription, kSecAttrComment, kSecAttrGeneric, kSecAttrAccessGroup,
120
+ kSecAttrSynchronizable, kSecAttrAccessible,
121
+ ]
122
+ static let classes: Set<String> = [kSecClassGenericPassword, kSecClassInternetPassword]
123
+ /// The access group of items added without one.
124
+ static let defaultGroup = "app"
125
+
126
+ struct Item: Codable {
127
+ var id: Int
128
+ var attributes: [String: _Value]
129
+ var data: Data?
130
+ var created: Double
131
+ var modified: Double
132
+ }
133
+
134
+ /// An attribute value the store keeps: what the attributes Apple defines can hold.
135
+ enum _Value: Codable, Equatable {
136
+ case string(String), number(Double), bool(Bool), data(Data)
137
+
138
+ init?(_ value: Any) {
139
+ switch value {
140
+ case let v as String: self = .string(v)
141
+ case let v as Bool: self = .bool(v)
142
+ case let v as Int: self = .number(Double(v))
143
+ case let v as Double: self = .number(v)
144
+ case let v as Data: self = .data(v)
145
+ default: return nil
146
+ }
147
+ }
148
+
149
+ var any: Any {
150
+ switch self {
151
+ case .string(let v): v
152
+ case .number(let v): v == v.rounded() ? Int(v) as Any : v as Any
153
+ case .bool(let v): v
154
+ case .data(let v): v
155
+ }
156
+ }
157
+ }
158
+
159
+ struct Store: Codable {
160
+ var nextID = 1
161
+ var items: [Item] = []
162
+ }
163
+
164
+ let file: URL
165
+ private var loaded: Store?
166
+
167
+ init(file: URL) { self.file = file }
168
+
169
+ private var store: Store {
170
+ get {
171
+ if let loaded { return loaded }
172
+ let read = (try? Data(contentsOf: file)).flatMap { try? JSONDecoder().decode(Store.self, from: $0) } ?? Store()
173
+ loaded = read
174
+ return read
175
+ }
176
+ set {
177
+ loaded = newValue
178
+ try? FileManager.default.createDirectory(at: file.deletingLastPathComponent(), withIntermediateDirectories: true)
179
+ if let data = try? JSONEncoder().encode(newValue) { try? data.write(to: file) }
180
+ }
181
+ }
182
+
183
+ // MARK: Item functions
184
+
185
+ func add(_ attributes: [String: Any], _ result: UnsafeMutablePointer<CFTypeRef?>?) -> OSStatus {
186
+ guard let itemClass = attributes[kSecClass] as? String, Self.classes.contains(itemClass) else { return errSecParam }
187
+ var values: [String: _Value] = [:]
188
+ for (key, value) in attributes where Self.attributeKeys.contains(key) {
189
+ guard let stored = _Value(value) else { return errSecParam }
190
+ values[key] = stored
191
+ }
192
+ values[kSecAttrAccessGroup] = values[kSecAttrAccessGroup] ?? .string(Self.defaultGroup)
193
+ values[kSecAttrSynchronizable] = .bool(Self.isTrue(attributes[kSecAttrSynchronizable]))
194
+ values[kSecAttrAccessible] = values[kSecAttrAccessible] ?? .string(kSecAttrAccessibleWhenUnlocked)
195
+ var store = self.store
196
+ if store.items.contains(where: { Self.sameIdentity($0.attributes, values) }) { return errSecDuplicateItem }
197
+ let now = Date().timeIntervalSince1970
198
+ let item = Item(id: store.nextID, attributes: values, data: attributes[kSecValueData] as? Data, created: now, modified: now)
199
+ store.nextID += 1
200
+ store.items.append(item)
201
+ self.store = store
202
+ if let result { result.pointee = Self.answer([item], to: attributes, one: true) }
203
+ return errSecSuccess
204
+ }
205
+
206
+ func copyMatching(_ query: [String: Any], _ result: UnsafeMutablePointer<CFTypeRef?>?) -> OSStatus {
207
+ guard query[kSecClass] is String else { return errSecParam }
208
+ let one = (query[kSecMatchLimit] as? String) != kSecMatchLimitAll
209
+ var found = store.items.filter { Self.matches($0, query) }
210
+ if found.isEmpty { return errSecItemNotFound }
211
+ if one { found = [found[0]] }
212
+ if let result { result.pointee = Self.answer(found, to: query, one: one) }
213
+ return errSecSuccess
214
+ }
215
+
216
+ func update(_ query: [String: Any], _ changes: [String: Any]) -> OSStatus {
217
+ guard query[kSecClass] is String else { return errSecParam }
218
+ var store = self.store
219
+ let indices = store.items.indices.filter { Self.matches(store.items[$0], query) }
220
+ if indices.isEmpty { return errSecItemNotFound }
221
+ let now = Date().timeIntervalSince1970
222
+ for index in indices {
223
+ for (key, value) in changes {
224
+ if key == kSecValueData {
225
+ store.items[index].data = value as? Data
226
+ } else if Self.attributeKeys.contains(key), key != kSecClass {
227
+ guard let stored = key == kSecAttrSynchronizable ? .bool(Self.isTrue(value)) : _Value(value) else { return errSecParam }
228
+ store.items[index].attributes[key] = stored
229
+ }
230
+ }
231
+ store.items[index].modified = now
232
+ }
233
+ // An update must not make two items the same.
234
+ for index in indices {
235
+ let item = store.items[index]
236
+ if store.items.contains(where: { $0.id != item.id && Self.sameIdentity($0.attributes, item.attributes) }) {
237
+ return errSecDuplicateItem
238
+ }
239
+ }
240
+ self.store = store
241
+ return errSecSuccess
242
+ }
243
+
244
+ func delete(_ query: [String: Any]) -> OSStatus {
245
+ guard query[kSecClass] is String else { return errSecParam }
246
+ var store = self.store
247
+ let before = store.items.count
248
+ store.items.removeAll { Self.matches($0, query) }
249
+ if store.items.count == before { return errSecItemNotFound }
250
+ self.store = store
251
+ return errSecSuccess
252
+ }
253
+
254
+ // MARK: Matching
255
+
256
+ static func isTrue(_ value: Any?) -> Bool {
257
+ switch value {
258
+ case let v as Bool: v
259
+ case let v as Int: v != 0
260
+ case let v as String: v == "1" || v == "true"
261
+ default: false
262
+ }
263
+ }
264
+
265
+ /// Whether the item has the query's attributes. Without
266
+ /// `kSecAttrSynchronizable` a query finds the items that do not
267
+ /// synchronize; `kSecAttrSynchronizableAny` finds both.
268
+ static func matches(_ item: Item, _ query: [String: Any]) -> Bool {
269
+ if let ref = query[kSecValuePersistentRef] as? Data, ref != persistentRef(item) { return false }
270
+ for (key, value) in query where attributeKeys.contains(key) && key != kSecAttrSynchronizable && key != kSecAttrAccessible {
271
+ guard let wanted = _Value(value), item.attributes[key] == wanted else { return false }
272
+ }
273
+ let synchronizes = item.attributes[kSecAttrSynchronizable] == .bool(true)
274
+ switch query[kSecAttrSynchronizable] {
275
+ case let any as String where any == kSecAttrSynchronizableAny: return true
276
+ case let value?: return isTrue(value) == synchronizes
277
+ case nil: return !synchronizes
278
+ }
279
+ }
280
+
281
+ /// Two items are the same item when their class and primary key attributes match.
282
+ static func sameIdentity(_ a: [String: _Value], _ b: [String: _Value]) -> Bool {
283
+ let keys = [kSecClass, kSecAttrAccount, kSecAttrService, kSecAttrServer, kSecAttrProtocol, kSecAttrPort, kSecAttrPath,
284
+ kSecAttrAccessGroup, kSecAttrSynchronizable]
285
+ return keys.allSatisfy { a[$0] == b[$0] }
286
+ }
287
+
288
+ static func persistentRef(_ item: Item) -> Data { Data("keychain-item-\(item.id)".utf8) }
289
+
290
+ /// What the query's `kSecReturn…` keys ask for: the data, a persistent
291
+ /// reference, or a dictionary of attributes (with those when asked too);
292
+ /// an array of them when the match limit is all.
293
+ static func answer(_ items: [Item], to query: [String: Any], one: Bool) -> CFTypeRef? {
294
+ let wantsData = isTrue(query[kSecReturnData])
295
+ let wantsAttributes = isTrue(query[kSecReturnAttributes])
296
+ let wantsRef = isTrue(query[kSecReturnPersistentRef]) || isTrue(query[kSecReturnRef])
297
+ func value(of item: Item) -> Any? {
298
+ if wantsAttributes {
299
+ var dictionary: [String: Any] = item.attributes.mapValues(\.any)
300
+ dictionary[kSecAttrCreationDate] = Date(timeIntervalSince1970: item.created)
301
+ dictionary[kSecAttrModificationDate] = Date(timeIntervalSince1970: item.modified)
302
+ if wantsData { dictionary[kSecValueData] = item.data ?? Data() }
303
+ if wantsRef { dictionary[kSecValuePersistentRef] = persistentRef(item) }
304
+ return dictionary
305
+ }
306
+ if wantsData { return item.data ?? Data() }
307
+ if wantsRef { return persistentRef(item) }
308
+ return nil
309
+ }
310
+ if one { return items.first.flatMap(value(of:)).map { $0 as AnyObject } }
311
+ // Typed arrays, so `result as? [[String: Any]]` (or `[Data]`) reads them back.
312
+ if wantsAttributes { return items.compactMap { value(of: $0) as? [String: Any] } as AnyObject }
313
+ if wantsData || wantsRef { return items.compactMap { value(of: $0) as? Data } as AnyObject }
314
+ return nil
315
+ }
316
+ }
317
+
318
+ // MARK: - Randomness
319
+
320
+ /// A random number generator; the default one is the only one.
321
+ public typealias SecRandomRef = OpaquePointer
322
+ nonisolated(unsafe) public let kSecRandomDefault: SecRandomRef? = nil
323
+
324
+ /// Fills `bytes` with `count` cryptographically secure random bytes (the
325
+ /// system's generator: `crypto.getRandomValues` in the browser). On Apple
326
+ /// platforms Foundation brings this along, and FoundationBridge re-exports it.
327
+ public func SecRandomCopyBytes(_ rnd: SecRandomRef?, _ count: Int, _ bytes: UnsafeMutableRawPointer) -> Int32 {
328
+ var generator = SystemRandomNumberGenerator()
329
+ let buffer = bytes.bindMemory(to: UInt8.self, capacity: count)
330
+ for index in 0..<count { buffer[index] = generator.next() }
331
+ return errSecSuccess
332
+ }
@@ -0,0 +1,207 @@
1
+ // StoreKit 2's App Store: whether payments can be made, the storefront,
2
+ // StoreKit's errors, purchase intents, App Store messages, external purchase
3
+ // links and the sheets StoreKit presents. A web app has no App Store behind
4
+ // it: payments cannot be made, the storefront is unknown, no intents or
5
+ // messages arrive (their sequences end at once), external purchase links
6
+ // are not eligible, and the sheets (manage subscriptions, redeem an offer
7
+ // code) are not shown: the calls that present them fail with
8
+ // `StoreKitError.unsupported`.
9
+
10
+ import Foundation
11
+ import SwiftUI
12
+ // As on iOS, StoreKit brings UIKit along: its sheets present in UIKit's scenes.
13
+ @_exported import UIKit
14
+
15
+ /// The scene StoreKit presents its sheets in.
16
+ public typealias _StoreKitScene = UIWindowScene
17
+
18
+ /// The App Store, as far as the browser has one.
19
+ public enum AppStore {
20
+ /// The environment a transaction happened in.
21
+ public struct Environment: Hashable, Sendable, RawRepresentable {
22
+ public let rawValue: String
23
+ public init(rawValue: String) { self.rawValue = rawValue }
24
+ public static let production = Environment(rawValue: "Production")
25
+ public static let sandbox = Environment(rawValue: "Sandbox")
26
+ public static let xcode = Environment(rawValue: "Xcode")
27
+ }
28
+
29
+ /// The platform an app was first bought on.
30
+ public struct Platform: Hashable, Sendable, RawRepresentable {
31
+ public let rawValue: String
32
+ public init(rawValue: String) { self.rawValue = rawValue }
33
+ public static let iOS = Platform(rawValue: "iOS")
34
+ public static let macOS = Platform(rawValue: "macOS")
35
+ public static let tvOS = Platform(rawValue: "tvOS")
36
+ public static let visionOS = Platform(rawValue: "visionOS")
37
+ }
38
+
39
+ /// False: the browser has no App Store to pay through.
40
+ public static var canMakePayments: Bool { false }
41
+
42
+ /// The device's identifier for verifying transactions: none in the browser.
43
+ public static var deviceVerificationID: UUID? { nil }
44
+
45
+ /// Nothing to sync with; returns at once.
46
+ public static func sync() async throws {}
47
+
48
+ /// The manage-subscriptions sheet does not exist in the browser: throws
49
+ /// `StoreKitError.unsupported`.
50
+ @MainActor public static func showManageSubscriptions(in scene: UIWindowScene) async throws {
51
+ throw StoreKitError.unsupported
52
+ }
53
+
54
+ @MainActor public static func showManageSubscriptions(in scene: UIWindowScene, subscriptionGroupID: String) async throws {
55
+ throw StoreKitError.unsupported
56
+ }
57
+
58
+ /// The offer-code sheet does not exist in the browser: throws
59
+ /// `StoreKitError.unsupported`.
60
+ @MainActor public static func presentOfferCodeRedeemSheet(in scene: UIWindowScene) async throws {
61
+ throw StoreKitError.unsupported
62
+ }
63
+
64
+ /// Asks for a review: a no-op, as `requestReview` is.
65
+ @MainActor public static func requestReview(in scene: UIWindowScene) {}
66
+ }
67
+
68
+ /// The App Store region. The browser's is unknown: `current` is nil and
69
+ /// `updates` ends at once.
70
+ public struct Storefront: Identifiable, Hashable, Sendable {
71
+ public let countryCode: String
72
+ public let id: String
73
+ public var currency: Locale.Currency? { nil }
74
+
75
+ public static var current: Storefront? { get async { nil } }
76
+
77
+ public static var updates: Storefronts { Storefronts() }
78
+
79
+ public struct Storefronts: AsyncSequence, Sendable {
80
+ public typealias Element = Storefront
81
+ public struct AsyncIterator: AsyncIteratorProtocol {
82
+ public mutating func next() async -> Storefront? { nil }
83
+ }
84
+ public func makeAsyncIterator() -> AsyncIterator { AsyncIterator() }
85
+ }
86
+ }
87
+
88
+ /// StoreKit 2's errors.
89
+ public enum StoreKitError: LocalizedError, Sendable {
90
+ case unknown
91
+ case userCancelled
92
+ case networkError(URLError)
93
+ case systemError(any Error)
94
+ case notAvailableInStorefront
95
+ case notEntitled
96
+ case unsupported
97
+ case invalidPresentationContext
98
+
99
+ public var errorDescription: String? {
100
+ switch self {
101
+ case .unknown: "An unknown error occurred."
102
+ case .userCancelled: "The user cancelled."
103
+ case .networkError(let error): error.localizedDescription
104
+ case .systemError(let error): error.localizedDescription
105
+ case .notAvailableInStorefront: "The item is not available in this storefront."
106
+ case .notEntitled: "The app is not entitled to this."
107
+ case .unsupported: "The App Store is not available in the browser."
108
+ case .invalidPresentationContext: "There is no context to present the App Store's sheet in."
109
+ }
110
+ }
111
+ }
112
+
113
+ /// A purchase someone started on the App Store, outside the app. None
114
+ /// arrive in the browser: `intents` ends at once.
115
+ public struct PurchaseIntent: Identifiable, Equatable, Sendable {
116
+ public let product: Product
117
+ public let offer: Product.SubscriptionOffer?
118
+ public var id: Product.ID { product.id }
119
+
120
+ public static var intents: PurchaseIntents { PurchaseIntents() }
121
+
122
+ public struct PurchaseIntents: AsyncSequence, Sendable {
123
+ public typealias Element = PurchaseIntent
124
+ public struct AsyncIterator: AsyncIteratorProtocol {
125
+ public mutating func next() async -> PurchaseIntent? { nil }
126
+ }
127
+ public func makeAsyncIterator() -> AsyncIterator { AsyncIterator() }
128
+ }
129
+ }
130
+
131
+ /// A message the App Store wants to show (a price increase, a billing
132
+ /// issue). None arrive in the browser: `messages` ends at once.
133
+ public struct Message: Hashable, Sendable {
134
+ public struct Reason: Hashable, Sendable, RawRepresentable {
135
+ public let rawValue: String
136
+ public init(rawValue: String) { self.rawValue = rawValue }
137
+ public static let generic = Reason(rawValue: "generic")
138
+ public static let priceIncreaseConsent = Reason(rawValue: "priceIncreaseConsent")
139
+ public static let billingIssue = Reason(rawValue: "billingIssue")
140
+ public static let winBackOffer = Reason(rawValue: "winBackOffer")
141
+ }
142
+
143
+ public let reason: Reason
144
+
145
+ @MainActor public func display(in scene: UIWindowScene) throws {
146
+ throw StoreKitError.unsupported
147
+ }
148
+
149
+ public static var messages: Messages { Messages() }
150
+
151
+ public struct Messages: AsyncSequence, Sendable {
152
+ public typealias Element = Message
153
+ public struct AsyncIterator: AsyncIteratorProtocol {
154
+ public mutating func next() async -> Message? { nil }
155
+ }
156
+ public func makeAsyncIterator() -> AsyncIterator { AsyncIterator() }
157
+ }
158
+ }
159
+
160
+ /// Shows an App Store message over the current scene (iOS 16), from the
161
+ /// environment's `displayStoreKitMessage`. No message arrives in the
162
+ /// browser; one passed in is not shown, which is not an error.
163
+ public struct DisplayMessageAction: Sendable {
164
+ public init() {}
165
+
166
+ @MainActor public func callAsFunction(_ message: Message) throws {}
167
+ }
168
+
169
+ private struct _DisplayStoreKitMessageKey: EnvironmentKey {
170
+ static let defaultValue = DisplayMessageAction()
171
+ }
172
+
173
+ extension EnvironmentValues {
174
+ public var displayStoreKitMessage: DisplayMessageAction {
175
+ get { self[_DisplayStoreKitMessageKey.self] }
176
+ set { self[_DisplayStoreKitMessageKey.self] = newValue }
177
+ }
178
+ }
179
+
180
+ /// Links to buying outside the App Store (iOS 18.1). A web app is not
181
+ /// eligible: `isEligible` is false and the notice and tokens are unsupported.
182
+ public enum ExternalPurchaseCustomLink {
183
+ public struct NoticeType: Hashable, Sendable, RawRepresentable {
184
+ public let rawValue: String
185
+ public init(rawValue: String) { self.rawValue = rawValue }
186
+ public static let browser = NoticeType(rawValue: "browser")
187
+ public static let withinApp = NoticeType(rawValue: "withinApp")
188
+ }
189
+
190
+ public enum NoticeResult: Hashable, Sendable {
191
+ case continued, cancelled
192
+ }
193
+
194
+ public struct Token: Hashable, Sendable {
195
+ public let value: String
196
+ }
197
+
198
+ public static var isEligible: Bool { get async { false } }
199
+
200
+ public static func token(for tokenType: String) async throws -> Token? {
201
+ throw StoreKitError.unsupported
202
+ }
203
+
204
+ @MainActor public static func showNotice(type: NoticeType) async throws -> NoticeResult {
205
+ throw StoreKitError.unsupported
206
+ }
207
+ }