peachsim 0.1.2182 → 0.1.2185

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 (95) hide show
  1. package/cli/outbound-endpoints.ts +11 -1
  2. package/dist-lib/agent-daemon-client.cjs +1 -1
  3. package/dist-lib/agent-events.cjs +1 -1
  4. package/dist-lib/attached-projects.cjs +1 -1
  5. package/dist-lib/auth/shared-session.cjs +1 -1
  6. package/dist-lib/backend-origin.cjs +1 -1
  7. package/dist-lib/beta.cjs +1 -1
  8. package/dist-lib/beta.mjs +1 -1
  9. package/dist-lib/bridge-constants.cjs +1 -1
  10. package/dist-lib/bridge-contract-input.cjs +1 -1
  11. package/dist-lib/bridge-contract-input.mjs +1 -1
  12. package/dist-lib/bridge-contract.cjs +1 -1
  13. package/dist-lib/bridge-contract.mjs +1 -1
  14. package/dist-lib/bundle-channel.cjs +321 -31
  15. package/dist-lib/capture-contract.cjs +1 -1
  16. package/dist-lib/capture-contract.mjs +1 -1
  17. package/dist-lib/cloud-contract.cjs +1 -1
  18. package/dist-lib/cloud-contract.mjs +1 -1
  19. package/dist-lib/cloud-test-args.cjs +1 -1
  20. package/dist-lib/cloud-test-args.mjs +1 -1
  21. package/dist-lib/cloud.cjs +1 -1
  22. package/dist-lib/cloud.mjs +1 -1
  23. package/dist-lib/config.cjs +1 -1
  24. package/dist-lib/config.mjs +1 -1
  25. package/dist-lib/detox/index.cjs +1 -1
  26. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  27. package/dist-lib/expo-swift-bundle.cjs +288 -26
  28. package/dist-lib/expo-swift-metadata.cjs +1 -1
  29. package/dist-lib/expo-swift-metadata.mjs +1 -1
  30. package/dist-lib/home-paths.cjs +1 -1
  31. package/dist-lib/host/bridge-host.cjs +314 -31
  32. package/dist-lib/host/fetch-proxy-handler.cjs +7 -4
  33. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  34. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  35. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  36. package/dist-lib/host/websocket-proxy.cjs +1 -1
  37. package/dist-lib/index.cjs +7 -4
  38. package/dist-lib/jump-to-source-babel.cjs +1 -1
  39. package/dist-lib/jump-to-source-native.cjs +1 -1
  40. package/dist-lib/kotlin-host.cjs +1 -1
  41. package/dist-lib/menu.cjs +1 -1
  42. package/dist-lib/menu.mjs +1 -1
  43. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  44. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  45. package/dist-lib/metro-production-bundle.cjs +1 -1
  46. package/dist-lib/metro-production-bundle.mjs +1 -1
  47. package/dist-lib/metro.cjs +7 -4
  48. package/dist-lib/native-app-identity-project.cjs +6 -3
  49. package/dist-lib/native-app-identity-project.mjs +6 -3
  50. package/dist-lib/native-app-identity.cjs +1 -1
  51. package/dist-lib/native-app-identity.mjs +1 -1
  52. package/dist-lib/native-firebase-metadata.cjs +1 -1
  53. package/dist-lib/native-firebase-metadata.mjs +1 -1
  54. package/dist-lib/pdfium-raster.cjs +1 -1
  55. package/dist-lib/pdfium-raster.mjs +1 -1
  56. package/dist-lib/plist.cjs +1 -1
  57. package/dist-lib/plist.mjs +1 -1
  58. package/dist-lib/profiles.cjs +1 -1
  59. package/dist-lib/public-brand.cjs +1 -1
  60. package/dist-lib/public-origins-lib-esm.json +25 -24
  61. package/dist-lib/public-origins-lib.json +63 -53
  62. package/dist-lib/react-native-host-modules.cjs +1 -1
  63. package/dist-lib/react-native-host-modules.mjs +1 -1
  64. package/dist-lib/reap-browser.cjs +1 -1
  65. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  66. package/dist-lib/sdk.cjs +1 -1
  67. package/dist-lib/sdk.mjs +1 -1
  68. package/dist-lib/skills.cjs +321 -31
  69. package/dist-lib/swift-compile.cjs +2 -2
  70. package/dist-lib/swift-compile.mjs +2 -2
  71. package/dist-lib/swift-package.cjs +26 -1
  72. package/dist-lib/swift-package.mjs +25 -1
  73. package/dist-lib/swift-submit.cjs +1 -1
  74. package/dist-lib/swift-submit.mjs +1 -1
  75. package/dist-lib/swift-toolchain.cjs +1 -1
  76. package/dist-lib/swift.cjs +1 -1
  77. package/dist-lib/vite-swift.cjs +286 -24
  78. package/dist-lib/vite.cjs +7 -4
  79. package/dist-lib/worklet-executable.cjs +1 -1
  80. package/dist-lib/worklet-executable.mjs +1 -1
  81. package/package.json +1 -1
  82. package/sdk/ios/System/Library/Frameworks/ActivityKit.framework/Headers/ActivityKit.h +1 -0
  83. package/sdk/ios/System/Library/Frameworks/ActivityKit.framework/Modules/module.modulemap +4 -0
  84. package/sdk/ios/usr/lib/swift/ActivityKit.swiftmodule/arm64-apple-ios-simulator.swiftinterface +14 -0
  85. package/sdk/ios/usr/lib/swift/CoreGraphics.swiftmodule/arm64-apple-ios-simulator.swiftinterface +14 -0
  86. package/sdk/ios/usr/lib/swift/Dispatch.swiftmodule/arm64-apple-ios-simulator.swiftinterface +3 -0
  87. package/sdk/ios/usr/lib/swift/Foundation.swiftmodule/arm64-apple-ios-simulator.swiftinterface +147 -16
  88. package/sdk/ios/usr/lib/swift/UIKit.swiftmodule/arm64-apple-ios-simulator.swiftinterface +5 -0
  89. package/src/expo-native-workspace.ts +2 -1
  90. package/src/swift-interface-bodies.ts +165 -0
  91. package/src/swift-objc-standin.ts +73 -13
  92. package/src/swift-package.ts +26 -0
  93. package/src/swift-source-pods.ts +27 -4
  94. package/src/swift-standin-emit.ts +30 -3
  95. package/src/swift-standins.ts +75 -12
@@ -0,0 +1,14 @@
1
+ // swift-interface-format-version: 1.0
2
+ // swift-module-flags: -target arm64-apple-ios16.0-simulator -enable-objc-interop -enable-library-evolution -module-name ActivityKit
3
+ @_exported import ActivityKit
4
+ import Foundation
5
+ import Swift
6
+ import _Concurrency
7
+ public protocol ActivityAttributes : Swift.Decodable, Swift.Encodable {
8
+ associatedtype ContentState : Swift.Decodable, Swift.Encodable, Swift.Hashable
9
+ }
10
+ @available(iOS 16.1, *)
11
+ public struct Activity<Attributes> where Attributes : ActivityKit.ActivityAttributes {
12
+ public let id: Swift.String
13
+ public let attributes: Attributes
14
+ }
@@ -6,3 +6,17 @@ import Swift
6
6
  public init()
7
7
  public init(_ value: Swift.Double)
8
8
  }
9
+ extension CoreGraphics.CGPoint {
10
+ public static let zero: CoreGraphics.CGPoint
11
+ }
12
+ extension CoreGraphics.CGSize {
13
+ public static let zero: CoreGraphics.CGSize
14
+ }
15
+ extension CoreGraphics.CGVector {
16
+ public static let zero: CoreGraphics.CGVector
17
+ }
18
+ extension CoreGraphics.CGRect {
19
+ public static let zero: CoreGraphics.CGRect
20
+ public static let null: CoreGraphics.CGRect
21
+ public static let infinite: CoreGraphics.CGRect
22
+ }
@@ -3,3 +3,6 @@
3
3
  @_exported import Dispatch
4
4
  import Swift
5
5
  @_objcRuntimeName(_TtC8Dispatch17_DispatchWorkItem) public class DispatchWorkItem {}
6
+ extension Dispatch.DispatchQueue {
7
+ public class var main: Dispatch.DispatchQueue { get }
8
+ }
@@ -5,27 +5,137 @@
5
5
  @_exported import CoreGraphics
6
6
  import Swift
7
7
  import _Concurrency
8
- public struct URL {}
8
+ public struct URL : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
9
+ public static func == (a: Foundation.URL, b: Foundation.URL) -> Swift.Bool
10
+ public func hash(into hasher: inout Swift.Hasher)
11
+ public func encode(to encoder: any Swift.Encoder) throws
12
+ public init(from decoder: any Swift.Decoder) throws
13
+ public var description: Swift.String { get }
14
+ }
9
15
  public struct Data {
10
16
  public typealias ReadingOptions = Foundation.NSData.ReadingOptions
11
17
  public typealias WritingOptions = Foundation.NSData.WritingOptions
12
18
  public typealias SearchOptions = Foundation.NSData.SearchOptions
19
+ public typealias Index = Swift.Int
20
+ }
21
+ public struct Date : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.Comparable, Swift.CustomStringConvertible {
22
+ public init()
23
+ public static var now: Foundation.Date { get }
24
+ public static let distantPast: Foundation.Date
25
+ public static let distantFuture: Foundation.Date
26
+ public static func == (a: Foundation.Date, b: Foundation.Date) -> Swift.Bool
27
+ public func hash(into hasher: inout Swift.Hasher)
28
+ public func encode(to encoder: any Swift.Encoder) throws
29
+ public init(from decoder: any Swift.Decoder) throws
30
+ public static func < (a: Foundation.Date, b: Foundation.Date) -> Swift.Bool
31
+ public var description: Swift.String { get }
32
+ }
33
+ public struct DateComponents : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
34
+ public static func == (a: Foundation.DateComponents, b: Foundation.DateComponents) -> Swift.Bool
35
+ public func hash(into hasher: inout Swift.Hasher)
36
+ public func encode(to encoder: any Swift.Encoder) throws
37
+ public init(from decoder: any Swift.Decoder) throws
38
+ public var description: Swift.String { get }
39
+ }
40
+ public struct DateInterval : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
41
+ public static func == (a: Foundation.DateInterval, b: Foundation.DateInterval) -> Swift.Bool
42
+ public func hash(into hasher: inout Swift.Hasher)
43
+ public func encode(to encoder: any Swift.Encoder) throws
44
+ public init(from decoder: any Swift.Decoder) throws
45
+ public var description: Swift.String { get }
46
+ }
47
+ public struct URLComponents : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
48
+ public static func == (a: Foundation.URLComponents, b: Foundation.URLComponents) -> Swift.Bool
49
+ public func hash(into hasher: inout Swift.Hasher)
50
+ public func encode(to encoder: any Swift.Encoder) throws
51
+ public init(from decoder: any Swift.Decoder) throws
52
+ public var description: Swift.String { get }
53
+ }
54
+ public struct URLQueryItem : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
55
+ public static func == (a: Foundation.URLQueryItem, b: Foundation.URLQueryItem) -> Swift.Bool
56
+ public func hash(into hasher: inout Swift.Hasher)
57
+ public func encode(to encoder: any Swift.Encoder) throws
58
+ public init(from decoder: any Swift.Decoder) throws
59
+ public var description: Swift.String { get }
60
+ }
61
+ public struct URLRequest : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
62
+ public static func == (a: Foundation.URLRequest, b: Foundation.URLRequest) -> Swift.Bool
63
+ public func hash(into hasher: inout Swift.Hasher)
64
+ public func encode(to encoder: any Swift.Encoder) throws
65
+ public init(from decoder: any Swift.Decoder) throws
66
+ public var description: Swift.String { get }
67
+ }
68
+ public struct UUID : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
69
+ public init()
70
+ public static func == (a: Foundation.UUID, b: Foundation.UUID) -> Swift.Bool
71
+ public func hash(into hasher: inout Swift.Hasher)
72
+ public func encode(to encoder: any Swift.Encoder) throws
73
+ public init(from decoder: any Swift.Decoder) throws
74
+ public var description: Swift.String { get }
75
+ }
76
+ public struct IndexPath : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.Comparable, Swift.CustomStringConvertible {
77
+ public static func == (a: Foundation.IndexPath, b: Foundation.IndexPath) -> Swift.Bool
78
+ public func hash(into hasher: inout Swift.Hasher)
79
+ public func encode(to encoder: any Swift.Encoder) throws
80
+ public init(from decoder: any Swift.Decoder) throws
81
+ public static func < (a: Foundation.IndexPath, b: Foundation.IndexPath) -> Swift.Bool
82
+ public var description: Swift.String { get }
83
+ }
84
+ public struct IndexSet : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
85
+ public static func == (a: Foundation.IndexSet, b: Foundation.IndexSet) -> Swift.Bool
86
+ public func hash(into hasher: inout Swift.Hasher)
87
+ public func encode(to encoder: any Swift.Encoder) throws
88
+ public init(from decoder: any Swift.Decoder) throws
89
+ public var description: Swift.String { get }
90
+ }
91
+ public struct CharacterSet : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
92
+ public static func == (a: Foundation.CharacterSet, b: Foundation.CharacterSet) -> Swift.Bool
93
+ public func hash(into hasher: inout Swift.Hasher)
94
+ public func encode(to encoder: any Swift.Encoder) throws
95
+ public init(from decoder: any Swift.Decoder) throws
96
+ public var description: Swift.String { get }
97
+ }
98
+ public struct Locale : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
99
+ public static var current: Foundation.Locale { get }
100
+ public static func == (a: Foundation.Locale, b: Foundation.Locale) -> Swift.Bool
101
+ public func hash(into hasher: inout Swift.Hasher)
102
+ public func encode(to encoder: any Swift.Encoder) throws
103
+ public init(from decoder: any Swift.Decoder) throws
104
+ public var description: Swift.String { get }
105
+ }
106
+ public struct TimeZone : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
107
+ public static var current: Foundation.TimeZone { get }
108
+ public static func == (a: Foundation.TimeZone, b: Foundation.TimeZone) -> Swift.Bool
109
+ public func hash(into hasher: inout Swift.Hasher)
110
+ public func encode(to encoder: any Swift.Encoder) throws
111
+ public init(from decoder: any Swift.Decoder) throws
112
+ public var description: Swift.String { get }
113
+ }
114
+ public struct Calendar : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
115
+ public static var current: Foundation.Calendar { get }
116
+ public static func == (a: Foundation.Calendar, b: Foundation.Calendar) -> Swift.Bool
117
+ public func hash(into hasher: inout Swift.Hasher)
118
+ public func encode(to encoder: any Swift.Encoder) throws
119
+ public init(from decoder: any Swift.Decoder) throws
120
+ public var description: Swift.String { get }
121
+ }
122
+ public struct Notification {
123
+ public struct Name {}
124
+ }
125
+ public struct Decimal : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.Comparable, Swift.CustomStringConvertible {
126
+ public static func == (a: Foundation.Decimal, b: Foundation.Decimal) -> Swift.Bool
127
+ public func hash(into hasher: inout Swift.Hasher)
128
+ public func encode(to encoder: any Swift.Encoder) throws
129
+ public init(from decoder: any Swift.Decoder) throws
130
+ public static func < (a: Foundation.Decimal, b: Foundation.Decimal) -> Swift.Bool
131
+ public var description: Swift.String { get }
132
+ }
133
+ open class JSONDecoder {
134
+ public init()
135
+ }
136
+ open class JSONEncoder {
137
+ public init()
13
138
  }
14
- public struct Date {}
15
- public struct DateComponents {}
16
- public struct DateInterval {}
17
- public struct URLComponents {}
18
- public struct URLQueryItem {}
19
- public struct URLRequest {}
20
- public struct UUID {}
21
- public struct IndexPath {}
22
- public struct IndexSet {}
23
- public struct CharacterSet {}
24
- public struct Locale {}
25
- public struct TimeZone {}
26
- public struct Calendar {}
27
- public struct Notification {}
28
- public struct Decimal {}
29
139
  public typealias NSErrorPointer = Swift.AutoreleasingUnsafeMutablePointer<Foundation.NSError?>?
30
140
  public typealias ErrorPointer = Foundation.NSErrorPointer
31
141
  public protocol CustomNSError : Swift.Error {
@@ -33,6 +143,18 @@ public protocol CustomNSError : Swift.Error {
33
143
  var errorCode: Swift.Int { get }
34
144
  var errorUserInfo: [Swift.String : Any] { get }
35
145
  }
146
+ public protocol LocalizedError : Swift.Error {
147
+ var errorDescription: Swift.String? { get }
148
+ var failureReason: Swift.String? { get }
149
+ var recoverySuggestion: Swift.String? { get }
150
+ var helpAnchor: Swift.String? { get }
151
+ }
152
+ extension Foundation.LocalizedError {
153
+ public var errorDescription: Swift.String? { get }
154
+ public var failureReason: Swift.String? { get }
155
+ public var recoverySuggestion: Swift.String? { get }
156
+ public var helpAnchor: Swift.String? { get }
157
+ }
36
158
  public protocol _ObjectiveCBridgeableError : Swift.Error {
37
159
  init?(_bridgedNSError: __shared Foundation.NSError)
38
160
  }
@@ -313,6 +435,15 @@ public func _convertErrorToNSError(_ error: any Swift.Error) -> Foundation.NSErr
313
435
  public protocol ContiguousBytes {
314
436
  func withUnsafeBytes<R>(_ body: (Swift.UnsafeRawBufferPointer) throws -> R) rethrows -> R
315
437
  }
438
+ extension Foundation.Data : Swift.RandomAccessCollection, Swift.MutableCollection, Swift.RangeReplaceableCollection {
439
+ public typealias Element = Swift.UInt8
440
+ public typealias Indices = Swift.Range<Swift.Int>
441
+ public init()
442
+ public var startIndex: Swift.Int { get }
443
+ public var endIndex: Swift.Int { get }
444
+ public subscript(position: Swift.Int) -> Swift.UInt8 { get set }
445
+ public mutating func replaceSubrange<C>(_ subrange: Swift.Range<Swift.Int>, with newElements: C) where C : Swift.Collection, C.Element == Swift.UInt8
446
+ }
316
447
  extension Foundation.Data : Swift.Hashable, Swift.Codable, Foundation.ContiguousBytes, Swift.Sendable {
317
448
  public static func == (lhs: Foundation.Data, rhs: Foundation.Data) -> Swift.Bool
318
449
  public func hash(into hasher: inout Swift.Hasher)
@@ -11,3 +11,8 @@ extension UIKit.UIWindow {
11
11
  extension UIKit.UIDevice {
12
12
  public typealias BatteryState = UIKit.UIDeviceBatteryState
13
13
  }
14
+ extension UIKit.NSLayoutConstraint {
15
+ public typealias Relation = UIKit.NSLayoutRelation
16
+ public typealias Attribute = UIKit.NSLayoutAttribute
17
+ public typealias FormatOptions = UIKit.NSLayoutFormatOptions
18
+ }
@@ -745,7 +745,8 @@ function initializeWorkspaceGit(root: string, work: string) {
745
745
  })
746
746
  const tracked = trackedSourceFiles(root, work)
747
747
  if (tracked.length > 0)
748
- execFileSync('git', ['add', '-f', '--pathspec-from-file=-', '--pathspec-file-nul'], {
748
+ // update-index takes exact paths; add matches every file against every pathspec, which is quadratic here
749
+ execFileSync('git', ['update-index', '--add', '-z', '--stdin'], {
749
750
  cwd: work,
750
751
  env: { ...process.env, ...isolatedGitEnv },
751
752
  input: tracked.join('\0'),
@@ -0,0 +1,165 @@
1
+ // a swift interface without function bodies. a library-evolution interface
2
+ // keeps the bodies of its inlinable functions and accessors, and compiling it
3
+ // type-checks them against the sdk it is read with. the objective-c intake
4
+ // declares Foundation and CoreGraphics only as far as headers name them, so a
5
+ // body that builds a Date or reads CGRect.zero fails the whole module although
6
+ // no declaration does. an interface prints every non-inlinable function
7
+ // without a body, so dropping the rest leaves the same public surface. a
8
+ // default argument value is a body of its own kind: it type-checks against the
9
+ // same partial sdk, and the symbol graph spells it into the stand-in, so it
10
+ // stays unless the caller finds the interface does not load with it.
11
+
12
+ const INLINE_ATTRIBUTE =
13
+ /@(?:inlinable|_alwaysEmitIntoClient|_transparent|inline\(__always\)|_effects\([^()]*\)|_specialize\((?:[^()]|\([^()]*\))*\))\s*/g
14
+
15
+ const ACCESSOR = /^(?:mutating|nonmutating|async|throws|rethrows|get|set|_modify|_read)$/
16
+
17
+ type Frame = 'container' | 'accessors' | 'expression'
18
+
19
+ // the keyword that says what a `{` after this line opens.
20
+ function declarationKind(head: string): 'function' | 'property' | 'container' {
21
+ const words = head
22
+ .replace(/@\w+(?:\((?:[^()]|\([^()]*\))*\))?/g, ' ')
23
+ .match(/[A-Za-z_]\w*/g)
24
+ for (const word of words ?? []) {
25
+ if (word === 'func' || word === 'init' || word === 'deinit') return 'function'
26
+ if (word === 'var' || word === 'let' || word === 'subscript') return 'property'
27
+ if (
28
+ word === 'struct' ||
29
+ word === 'class' ||
30
+ word === 'enum' ||
31
+ word === 'protocol' ||
32
+ word === 'extension' ||
33
+ word === 'actor' ||
34
+ word === 'precedencegroup'
35
+ )
36
+ return 'container'
37
+ }
38
+ return 'container'
39
+ }
40
+
41
+ /** the index after the string, comment or character literal starting at `i`, or `i`. */
42
+ function skipLiteral(text: string, i: number): number {
43
+ if (text.startsWith('//', i)) {
44
+ const end = text.indexOf('\n', i)
45
+ return end < 0 ? text.length : end
46
+ }
47
+ if (text.startsWith('/*', i)) {
48
+ const end = text.indexOf('*/', i + 2)
49
+ return end < 0 ? text.length : end + 2
50
+ }
51
+ if (text[i] !== '"' && text[i] !== '#') return i
52
+ let hashes = 0
53
+ let j = i
54
+ while (text[j] === '#') {
55
+ hashes++
56
+ j++
57
+ }
58
+ if (text[j] !== '"') return i
59
+ const multiline = text.startsWith('"""', j)
60
+ const open = multiline ? '"""' : '"'
61
+ j += open.length
62
+ const close = `${open}${'#'.repeat(hashes)}`
63
+ const escape = `\\${'#'.repeat(hashes)}`
64
+ while (j < text.length) {
65
+ if (text.startsWith(escape, j)) j += escape.length + 1
66
+ else if (text.startsWith(close, j)) return j + close.length
67
+ else j++
68
+ }
69
+ return text.length
70
+ }
71
+
72
+ /** the index after the brace block opened at `open`. */
73
+ function skipBlock(text: string, open: number): number {
74
+ let depth = 0
75
+ for (let i = open; i < text.length; ) {
76
+ const after = skipLiteral(text, i)
77
+ if (after !== i) {
78
+ i = after
79
+ continue
80
+ }
81
+ if (text[i] === '{') depth++
82
+ else if (text[i] === '}' && --depth === 0) return i + 1
83
+ i++
84
+ }
85
+ return text.length
86
+ }
87
+
88
+ /** the index of the `,` or `)` that ends the default argument value starting at `i`. */
89
+ function skipExpression(text: string, start: number): number {
90
+ let depth = 0
91
+ for (let i = start; i < text.length; ) {
92
+ const after = skipLiteral(text, i)
93
+ if (after !== i) {
94
+ i = after
95
+ continue
96
+ }
97
+ const char = text[i]!
98
+ if (char === '(' || char === '[' || char === '{' || char === '<') depth++
99
+ else if (char === '>' && text[i - 1] !== '-') depth--
100
+ else if (char === ')' || char === ']' || char === '}') {
101
+ if (depth === 0) return i
102
+ depth--
103
+ } else if (char === ',' && depth === 0) return i
104
+ i++
105
+ }
106
+ return text.length
107
+ }
108
+
109
+ export function swiftInterfaceWithoutBodies(text: string, keepDefaults = false): string {
110
+ let out = ''
111
+ const frames: Frame[] = []
112
+ let parens = 0
113
+ let lineStart = 0
114
+ for (let i = 0; i < text.length; ) {
115
+ const after = skipLiteral(text, i)
116
+ if (after !== i) {
117
+ out += text.slice(i, after)
118
+ i = after
119
+ continue
120
+ }
121
+ const char = text[i]!
122
+ if (char === '=' && parens > 0 && text[i - 1] === ' ' && text[i + 1] === ' ') {
123
+ out = out.trimEnd()
124
+ i = skipExpression(text, i + 1)
125
+ continue
126
+ }
127
+ if (char === '\n') lineStart = out.length + 1
128
+ else if (char === '(') parens++
129
+ else if (char === ')') parens--
130
+ else if (char === '}') {
131
+ frames.pop()
132
+ } else if (char === '{') {
133
+ const parent = frames.at(-1)
134
+ const head = out.slice(lineStart)
135
+ if (parens > 0 || parent === 'expression') frames.push('expression')
136
+ else if (parent === 'accessors') {
137
+ // an accessor's body: keep its keyword, drop the attributes that need one
138
+ out = `${out.slice(0, lineStart)}${head.replace(INLINE_ATTRIBUTE, '')}`.trimEnd()
139
+ i = skipBlock(text, i)
140
+ continue
141
+ } else {
142
+ const kind = declarationKind(head)
143
+ const body = text.slice(i + 1, skipBlock(text, i) - 1)
144
+ if (kind === 'function') {
145
+ out =
146
+ `${out.slice(0, lineStart)}${head.replace(INLINE_ATTRIBUTE, '')}`.trimEnd()
147
+ i = skipBlock(text, i)
148
+ continue
149
+ }
150
+ // `{ get set }` keeps its keywords; `{ get { .. } }` is a property with bodies
151
+ const bare = body.split(/\s+/).every((word) => word === '' || ACCESSOR.test(word))
152
+ frames.push(kind === 'property' && !bare ? 'accessors' : 'container')
153
+ if (kind === 'property' && bare) {
154
+ out += `{${body}}`
155
+ i = skipBlock(text, i)
156
+ frames.pop()
157
+ continue
158
+ }
159
+ }
160
+ }
161
+ out += char
162
+ i++
163
+ }
164
+ return out.replace(INLINE_ATTRIBUTE, '')
165
+ }
@@ -19,6 +19,7 @@ import { createHash } from 'node:crypto'
19
19
  import fs from 'node:fs'
20
20
  import path from 'node:path'
21
21
  import { isRecord } from './is-record'
22
+ import { swiftInterfaceWithoutBodies } from './swift-interface-bodies'
22
23
  import { swiftObjCPlatformFlags } from './swift-objc-platform'
23
24
  import { IOS_SDK_HEADERS, IOS_SDK_OVERLAYS, IOS_SDK_TARGET } from './swift-objc-sdk'
24
25
  import { clangImportNames, moduleMapTokens } from './swift-package'
@@ -460,6 +461,63 @@ function sdkDeclaration(name: string): SdkDeclaration | null {
460
461
  return sdkDeclarations.get(name) ?? null
461
462
  }
462
463
 
464
+ // a swift interface as the intake sdk reads it. the intake reads
465
+ // CoreFoundation's headers textually, so a type the interface qualifies with
466
+ // CoreFoundation lives in CoreGraphics (CGSize, CGFloat) or Foundation, and
467
+ // inlinable bodies would type-check against its partial Foundation, so only
468
+ // the declarations load.
469
+ function intakeInterface(text: string, keepDefaults = false): string {
470
+ return (
471
+ swiftInterfaceWithoutBodies(text, keepDefaults)
472
+ // the intake modules have no clang submodules
473
+ .replace(/^((?:@_exported[ \t]+)?import[ \t]+)(\w+)\.[\w.]+[ \t]*$/gm, '$1$2')
474
+ .replace(/\bCoreFoundation\.(?=CG)/g, 'CoreGraphics.')
475
+ .replace(/\bCoreFoundation\.(?=\w)/g, 'Foundation.')
476
+ // the intake has no Darwin module; OSStatus is its Int32
477
+ .replace(/\bDarwin\.OSStatus\b/g, 'Swift.Int32')
478
+ // Data's base64 option sets live in the swift overlay; the
479
+ // intake only has their NSData spelling, which Data aliases.
480
+ .replace(
481
+ /\bFoundation\.Data\.(?=Base64(?:En|De)codingOptions\b)/g,
482
+ 'Foundation.NSData.',
483
+ )
484
+ )
485
+ }
486
+
487
+ // a vendor framework directory the headers import, its swift interfaces read
488
+ // as the intake reads the surface's own.
489
+ function stageVendorFrameworks(dir: string, stage: string): string {
490
+ fs.mkdirSync(stage, { recursive: true })
491
+ for (const entry of fs.readdirSync(dir)) {
492
+ if (!entry.endsWith('.framework')) continue
493
+ const source = path.join(dir, entry)
494
+ const target = path.join(stage, entry)
495
+ fs.mkdirSync(target, { recursive: true })
496
+ for (const child of fs.readdirSync(source)) {
497
+ if (child !== 'Modules') {
498
+ fs.symlinkSync(path.join(source, child), path.join(target, child))
499
+ continue
500
+ }
501
+ for (const file of fs.readdirSync(path.join(source, child), {
502
+ recursive: true,
503
+ encoding: 'utf8',
504
+ })) {
505
+ const from = path.join(source, child, file)
506
+ const to = path.join(target, child, file)
507
+ if (fs.statSync(from).isDirectory()) {
508
+ fs.mkdirSync(to, { recursive: true })
509
+ continue
510
+ }
511
+ fs.mkdirSync(path.dirname(to), { recursive: true })
512
+ if (file.endsWith('.swiftinterface'))
513
+ fs.writeFileSync(to, intakeInterface(fs.readFileSync(from, 'utf8')))
514
+ else fs.copyFileSync(from, to)
515
+ }
516
+ }
517
+ }
518
+ return stage
519
+ }
520
+
463
521
  /** the symbol graphs, enum values and imports of an objective-c module. */
464
522
  export function objcView(
465
523
  surface: ObjcSurface,
@@ -507,6 +565,7 @@ export function objcView(
507
565
  fs.writeFileSync(file, text)
508
566
  }
509
567
  const interfaceCopies: string[] = []
568
+ let keepDefaults = true
510
569
  if (framework) {
511
570
  fs.mkdirSync(path.join(frameworks, `${surface.module}.framework`, 'Modules'), {
512
571
  recursive: true,
@@ -541,18 +600,7 @@ export function objcView(
541
600
  interfaceCopies.push(path.join(to, name))
542
601
  fs.writeFileSync(
543
602
  path.join(to, name),
544
- fs
545
- .readFileSync(path.join(from, name), 'utf8')
546
- .replace(/\bCoreFoundation\.(?=CG)/g, 'CoreGraphics.')
547
- .replace(/\bCoreFoundation\.(?=\w)/g, 'Foundation.')
548
- // the intake has no Darwin module; OSStatus is its Int32
549
- .replace(/\bDarwin\.OSStatus\b/g, 'Swift.Int32')
550
- // Data's base64 option sets live in the swift overlay; the
551
- // intake only has their NSData spelling, which Data aliases.
552
- .replace(
553
- /\bFoundation\.Data\.(?=Base64(?:En|De)codingOptions\b)/g,
554
- 'Foundation.NSData.',
555
- ),
603
+ intakeInterface(fs.readFileSync(path.join(from, name), 'utf8'), true),
556
604
  )
557
605
  }
558
606
  }
@@ -619,7 +667,10 @@ export function objcView(
619
667
  stubs,
620
668
  '-I',
621
669
  stubIncludes,
622
- ...vendorFrameworks.flatMap((dir) => ['-F', dir]),
670
+ ...vendorFrameworks.flatMap((dir, index) => [
671
+ '-F',
672
+ stageVendorFrameworks(dir, path.join(work, 'vendor-frameworks', String(index))),
673
+ ]),
623
674
  ]
624
675
  const missing: Missing = new Map()
625
676
  const stubbed = new Set<string>()
@@ -853,6 +904,15 @@ export function objcView(
853
904
  )
854
905
  }
855
906
  }
907
+ // a default argument value the intake cannot type-check fails the whole
908
+ // interface, so the declarations load without any
909
+ if ((!progress || round === ROUNDS) && keepDefaults && interfaceCopies.length > 0) {
910
+ keepDefaults = false
911
+ for (const file of interfaceCopies)
912
+ fs.writeFileSync(file, swiftInterfaceWithoutBodies(fs.readFileSync(file, 'utf8')))
913
+ writeHeaders()
914
+ continue
915
+ }
856
916
  if (!progress || round === ROUNDS)
857
917
  throw new Error(
858
918
  `its headers do not import as Swift: ${
@@ -321,6 +321,32 @@ export function moduleMapName(text: string): string | undefined {
321
321
  return index < 0 ? undefined : tokens[index + 1]
322
322
  }
323
323
 
324
+ // the top-level modules a clang module map declares, each with its own text.
325
+ // a uniffi xcframework ships one map holding a module per generated header.
326
+ export function moduleMapModules(text: string): { name: string; text: string }[] {
327
+ const modules: { name: string; text: string }[] = []
328
+ const token = /\/\*[\s\S]*?\*\/|\/\/[^\n]*|"[^"]*"|\{|\}|\bmodule\s+([\w.]+)/g
329
+ let depth = 0
330
+ let start = -1
331
+ let name = ''
332
+ for (const match of text.matchAll(token)) {
333
+ if (match[0] === '{') depth++
334
+ else if (match[0] === '}') {
335
+ depth--
336
+ if (depth === 0 && start >= 0) {
337
+ modules.push({ name, text: text.slice(start, match.index + 1) })
338
+ start = -1
339
+ }
340
+ } else if (match[1] !== undefined && depth === 0) {
341
+ const before = text.slice(0, match.index).trimEnd()
342
+ if (/\bextern$/.test(before)) continue
343
+ start = match.index
344
+ name = match[1]
345
+ }
346
+ }
347
+ return modules
348
+ }
349
+
324
350
  // swiftpm's module name for a target: its name as a c99 identifier, so
325
351
  // target `cmark-gfm` is imported as `cmark_gfm`.
326
352
  export function swiftTargetModuleName(name: string): string {
@@ -96,6 +96,7 @@ async function trunkSpecification(
96
96
  'specifications',
97
97
  `${checksum}.json`,
98
98
  )
99
+ const sha1 = (value: string) => createHash('sha1').update(value).digest('hex')
99
100
  let text: string
100
101
  if (fs.existsSync(file)) text = fs.readFileSync(file, 'utf8')
101
102
  else {
@@ -105,16 +106,38 @@ async function trunkSpecification(
105
106
  .slice(0, 3)
106
107
  .split('')
107
108
  .join('/')
108
- const response = await fetch(
109
- `https://cdn.cocoapods.org/Specs/${shard}/${root}/${version}/${root}.podspec.json`,
110
- )
109
+ const specPath = `Specs/${shard}/${root}/${version}/${root}.podspec.json`
110
+ const response = await fetch(`https://cdn.cocoapods.org/${specPath}`)
111
111
  if (!response.ok)
112
112
  throw new Error(
113
113
  `CocoaPods specification ${root} ${version}: HTTP ${response.status}`,
114
114
  )
115
115
  text = await response.text()
116
+ // trunk edits a published specification in place (a deprecation adds a
117
+ // field), so a lock written earlier names an older revision of the file.
118
+ if (sha1(text) !== checksum) {
119
+ const history = await fetch(
120
+ `https://api.github.com/repos/CocoaPods/Specs/commits?path=${specPath}&per_page=100`,
121
+ )
122
+ if (!history.ok)
123
+ throw new Error(`CocoaPods specification ${root} history: HTTP ${history.status}`)
124
+ const commits: unknown = await history.json()
125
+ for (const commit of Array.isArray(commits) ? commits : []) {
126
+ const sha = record(commit) ? commit.sha : undefined
127
+ if (typeof sha !== 'string') continue
128
+ const revision = await fetch(
129
+ `https://raw.githubusercontent.com/CocoaPods/Specs/${sha}/${specPath}`,
130
+ )
131
+ if (!revision.ok) continue
132
+ const revisionText = await revision.text()
133
+ if (sha1(revisionText) === checksum) {
134
+ text = revisionText
135
+ break
136
+ }
137
+ }
138
+ }
116
139
  }
117
- if (createHash('sha1').update(text).digest('hex') !== checksum)
140
+ if (sha1(text) !== checksum)
118
141
  throw new Error(`${root} podspec checksum differs from ${lockFile}`)
119
142
  const spec: unknown = JSON.parse(text)
120
143
  if (!record(spec) || spec.name !== root || spec.version !== version)