@npaw/forge-react-native 9.6.1

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 (74) hide show
  1. package/LICENSE +10 -0
  2. package/NPAWForgeReactNative.podspec +44 -0
  3. package/README.md +51 -0
  4. package/android/build.gradle +77 -0
  5. package/android/src/main/AndroidManifest.xml +14 -0
  6. package/android/src/main/java/com/npaw/forge/reactnative/ForgeDtoMapper.java +295 -0
  7. package/android/src/main/java/com/npaw/forge/reactnative/ForgeInstanceRegistry.java +61 -0
  8. package/android/src/main/java/com/npaw/forge/reactnative/NPAWForgeModule.java +735 -0
  9. package/android/src/main/java/com/npaw/forge/reactnative/NPAWForgePackage.java +53 -0
  10. package/android/src/test/java/com/npaw/forge/reactnative/ForgeDtoMapperTest.java +133 -0
  11. package/ios/ForgeApple/ForgeKernelFFI.xcframework/Info.plist +82 -0
  12. package/ios/ForgeApple/ForgeKernelFFI.xcframework/ios-arm64/Headers/ForgeKernelFFI.h +17 -0
  13. package/ios/ForgeApple/ForgeKernelFFI.xcframework/ios-arm64/Headers/forge_kernelFFI.h +873 -0
  14. package/ios/ForgeApple/ForgeKernelFFI.xcframework/ios-arm64/Headers/module.modulemap +7 -0
  15. package/ios/ForgeApple/ForgeKernelFFI.xcframework/ios-arm64/libForgeKernelFFI.a +0 -0
  16. package/ios/ForgeApple/ForgeKernelFFI.xcframework/ios-arm64_x86_64-simulator/Headers/ForgeKernelFFI.h +17 -0
  17. package/ios/ForgeApple/ForgeKernelFFI.xcframework/ios-arm64_x86_64-simulator/Headers/forge_kernelFFI.h +873 -0
  18. package/ios/ForgeApple/ForgeKernelFFI.xcframework/ios-arm64_x86_64-simulator/Headers/module.modulemap +7 -0
  19. package/ios/ForgeApple/ForgeKernelFFI.xcframework/ios-arm64_x86_64-simulator/libForgeKernelFFI.a +0 -0
  20. package/ios/ForgeApple/ForgeKernelFFI.xcframework/tvos-arm64/Headers/ForgeKernelFFI.h +17 -0
  21. package/ios/ForgeApple/ForgeKernelFFI.xcframework/tvos-arm64/Headers/forge_kernelFFI.h +873 -0
  22. package/ios/ForgeApple/ForgeKernelFFI.xcframework/tvos-arm64/Headers/module.modulemap +7 -0
  23. package/ios/ForgeApple/ForgeKernelFFI.xcframework/tvos-arm64/libForgeKernelFFI.a +0 -0
  24. package/ios/ForgeApple/ForgeKernelFFI.xcframework/tvos-arm64-simulator/Headers/ForgeKernelFFI.h +17 -0
  25. package/ios/ForgeApple/ForgeKernelFFI.xcframework/tvos-arm64-simulator/Headers/forge_kernelFFI.h +873 -0
  26. package/ios/ForgeApple/ForgeKernelFFI.xcframework/tvos-arm64-simulator/Headers/module.modulemap +7 -0
  27. package/ios/ForgeApple/ForgeKernelFFI.xcframework/tvos-arm64-simulator/libForgeKernelFFI.a +0 -0
  28. package/ios/ForgeApple/Sources/ForgeKernelUniFFI/forge_kernel.swift +3931 -0
  29. package/ios/ForgeApple/Sources/ForgeKernelUniFFI/forge_kernelFFI.h +873 -0
  30. package/ios/ForgeApple/Sources/ForgeKernelUniFFI/forge_kernelFFI.modulemap +7 -0
  31. package/ios/ForgeApple/Sources/NPAWForgeAVPlayerAdapter/AVPlayerAccessLogFacts.swift +152 -0
  32. package/ios/ForgeApple/Sources/NPAWForgeAVPlayerAdapter/AVPlayerAdapter.swift +877 -0
  33. package/ios/ForgeApple/Sources/NPAWForgeCapture/AttributionCapture.swift +158 -0
  34. package/ios/ForgeApple/Sources/NPAWForgeCapture/CapturePlanGate.swift +189 -0
  35. package/ios/ForgeApple/Sources/NPAWForgeCapture/CrashCapture.swift +120 -0
  36. package/ios/ForgeApple/Sources/NPAWForgeCapture/ForgeAutomaticCapture.swift +639 -0
  37. package/ios/ForgeApple/Sources/NPAWForgeCapture/SectionsCapture.swift +1176 -0
  38. package/ios/ForgeApple/Sources/NPAWForgeCapture/SectionsEngine.swift +674 -0
  39. package/ios/ForgeApple/Sources/NPAWForgeCapture/SectionsMarkers.swift +105 -0
  40. package/ios/ForgeApple/Sources/NPAWForgeCapture/SectionsSwiftUI.swift +284 -0
  41. package/ios/ForgeApple/Sources/NPAWForgeCapture/SwiftUICapture.swift +44 -0
  42. package/ios/ForgeApple/Sources/NPAWForgeCore/AdAdapter.swift +199 -0
  43. package/ios/ForgeApple/Sources/NPAWForgeCore/AdSemantics.swift +136 -0
  44. package/ios/ForgeApple/Sources/NPAWForgeCore/ForgeApple.swift +596 -0
  45. package/ios/ForgeApple/Sources/NPAWForgeCore/ForgeCapturePlan.swift +297 -0
  46. package/ios/ForgeApple/Sources/NPAWForgeCore/ForgeClock.swift +29 -0
  47. package/ios/ForgeApple/Sources/NPAWForgeCore/ForgeLogging.swift +109 -0
  48. package/ios/ForgeApple/Sources/NPAWForgeCore/ForgeOutcome.swift +89 -0
  49. package/ios/ForgeApple/Sources/NPAWForgeCore/ForgeRuntime.swift +291 -0
  50. package/ios/ForgeApple/Sources/NPAWForgeCore/ForgeStorage.swift +70 -0
  51. package/ios/ForgeApple/Sources/NPAWForgeCore/ManualAdReporter.swift +180 -0
  52. package/ios/ForgeApple/Sources/NPAWForgeCore/NPAWForge.swift +453 -0
  53. package/ios/ForgeApple/Sources/NPAWForgeCore/NativeUniFFIRuntime.swift +594 -0
  54. package/ios/ForgeApple/Sources/NPAWForgeCore/NetworkRequestRecord.swift +191 -0
  55. package/ios/ForgeApple/Sources/NPAWForgeCore/ObjectiveCWrappers.swift +191 -0
  56. package/ios/ForgeApple/Sources/NPAWForgeCore/PlayerAdapter.swift +299 -0
  57. package/ios/ForgeApple/Sources/NPAWForgeCore/PlayerSemantics.swift +266 -0
  58. package/ios/ForgeApple/Sources/NPAWForgeCore/PrivacySanitizer.swift +59 -0
  59. package/ios/ForgeApple/Sources/NPAWForgeCore/VideoAdapter.swift +478 -0
  60. package/ios/ForgeApple/Sources/NPAWForgeCore/VideoOptions.swift +431 -0
  61. package/ios/ForgeApple/Sources/NPAWForgeNetworkCapture/ForgeNetworkCapture.swift +116 -0
  62. package/ios/ForgeApple/Sources/NPAWForgeNetworkCaptureObjC/NPAWForgeNetworkSwizzler.m +293 -0
  63. package/ios/ForgeApple/Sources/NPAWForgeNetworkCaptureObjC/include/NPAWForgeNetworkSwizzler.h +33 -0
  64. package/ios/ForgeModuleImpl.swift +1131 -0
  65. package/ios/NPAWForgeTurboModule.mm +399 -0
  66. package/package.json +33 -0
  67. package/src/ForgeAdReporter.ts +101 -0
  68. package/src/ForgeVideo.ts +169 -0
  69. package/src/NPAWForge.ts +177 -0
  70. package/src/capture.ts +192 -0
  71. package/src/events.ts +40 -0
  72. package/src/index.ts +37 -0
  73. package/src/specs/NativeNPAWForge.ts +168 -0
  74. package/src/types.ts +114 -0
@@ -0,0 +1,266 @@
1
+ /**
2
+ * Copyright (C) NPAW - All Rights Reserved
3
+ *
4
+ * This source code is protected under international copyright law. All rights
5
+ * reserved and protected by the copyright holders.
6
+ * This file is confidential and only available to authorized individuals with the
7
+ * permission of the copyright holders. If you encounter this file and do not have
8
+ * permission, please contact the copyright holders and delete this file.
9
+ *
10
+ *
11
+ * @author: Victor Soto <victor.soto@nicepeopleatwork.com>
12
+ * @description: Apple player semantic event and metadata snapshot model.
13
+ */
14
+
15
+ import Foundation
16
+
17
+ public enum PlayerEvent: String {
18
+ case initEvent = "INIT"
19
+ case start = "START"
20
+ case join = "JOIN"
21
+ case pause = "PAUSE"
22
+ case resume = "RESUME"
23
+ case seekBegin = "SEEK_BEGIN"
24
+ case seekEnd = "SEEK_END"
25
+ case bufferBegin = "BUFFER_BEGIN"
26
+ case bufferEnd = "BUFFER_END"
27
+ case stop = "STOP"
28
+ case error = "ERROR"
29
+ case fatalError = "FATAL_ERROR"
30
+ case destroy = "DESTROY"
31
+ case customVideoEvent = "CUSTOM_VIDEO_EVENT"
32
+ case customVideoEventEnd = "CUSTOM_VIDEO_EVENT_END"
33
+ case metadataUpdate = "METADATA_UPDATE"
34
+ }
35
+
36
+ public enum ContentType: String {
37
+ case live = "LIVE"
38
+ case vod = "VOD"
39
+ case audio = "AUDIO"
40
+ case unknown = "UNKNOWN"
41
+ }
42
+
43
+ public struct CustomVideoEventPayload: Equatable {
44
+ public var name: String
45
+ public var dimensions: [String: String]
46
+ public var values: [String: Double]
47
+ public var topLevel: [String: String]
48
+ public var streamKey: String?
49
+ public var hasEndDatetime: Bool
50
+
51
+ public init(
52
+ name: String,
53
+ dimensions: [String: String] = [:],
54
+ values: [String: Double] = [:],
55
+ topLevel: [String: String] = [:],
56
+ streamKey: String? = nil,
57
+ hasEndDatetime: Bool = false
58
+ ) {
59
+ self.name = name
60
+ self.dimensions = dimensions
61
+ self.values = values
62
+ self.topLevel = topLevel
63
+ self.streamKey = streamKey
64
+ self.hasEndDatetime = hasEndDatetime
65
+ }
66
+ }
67
+
68
+ public struct PlayerMetadataSnapshot: Equatable {
69
+ public var playerName: String
70
+ public var playerVersion: String?
71
+ public var adapterVersion: String?
72
+ public var resourceUrl: String?
73
+ public var parsedResource: String?
74
+ public var title: String?
75
+ public var program: String?
76
+ public var contentType: ContentType
77
+ public var playheadMs: Int64?
78
+ public var durationMs: Int64?
79
+ public var bitrate: Int64?
80
+ public var rendition: String?
81
+ public var videoCodec: String?
82
+ public var audioCodec: String?
83
+ public var codecProfile: String?
84
+ public var containerFormat: String?
85
+ public var errorCode: String?
86
+ public var errorMessage: String?
87
+ public var errorMetadata: String?
88
+ public var errorLevel: String?
89
+ public var forceInit: Bool?
90
+ public var convertFromBuffer: Bool?
91
+ public var convertFromSeek: Bool?
92
+ public var customEvent: CustomVideoEventPayload?
93
+ /// Legacy `param1`..`param20` content dimensions; only indices 1-20 are
94
+ /// transmitted. A non-empty map wins over
95
+ /// `__legacyContentDimension.<name>` extraParams keys entirely.
96
+ public var legacyCustomDimensions: [String: String]
97
+ /// Custom content dimensions. Values that parse as numbers become JSON
98
+ /// numbers core-side (same coercion as the `__contentDimension.<name>`
99
+ /// extraParams contract); a non-empty map wins over those overlay keys.
100
+ public var customDimensions: [String: String]
101
+ /// Numeric custom content metrics (metric surfaces are numeric-only;
102
+ /// non-finite values are dropped). A non-empty map wins over
103
+ /// `__contentMetric.<name>` extraParams keys entirely.
104
+ public var customMetrics: [String: Double]
105
+ /// Additive string-key metadata overlay forwarded to the shared Rust
106
+ /// core. Keys follow the same contract as the Android metadata map
107
+ /// (for example `contentLanguage`, `cdn`, `__contentDimension.<name>`);
108
+ /// typed snapshot fields always win over overlay keys.
109
+ public var extraParams: [String: String]
110
+
111
+ public init(
112
+ playerName: String,
113
+ playerVersion: String? = nil,
114
+ adapterVersion: String? = nil,
115
+ resourceUrl: String? = nil,
116
+ parsedResource: String? = nil,
117
+ title: String? = nil,
118
+ contentType: ContentType = .unknown,
119
+ playheadMs: Int64? = nil,
120
+ durationMs: Int64? = nil,
121
+ bitrate: Int64? = nil,
122
+ rendition: String? = nil,
123
+ videoCodec: String? = nil,
124
+ audioCodec: String? = nil,
125
+ codecProfile: String? = nil,
126
+ containerFormat: String? = nil,
127
+ errorCode: String? = nil,
128
+ errorMessage: String? = nil,
129
+ errorMetadata: String? = nil,
130
+ errorLevel: String? = nil,
131
+ forceInit: Bool? = nil,
132
+ convertFromBuffer: Bool? = nil,
133
+ convertFromSeek: Bool? = nil,
134
+ customEvent: CustomVideoEventPayload? = nil,
135
+ legacyCustomDimensions: [String: String] = [:],
136
+ customDimensions: [String: String] = [:],
137
+ customMetrics: [String: Double] = [:],
138
+ program: String? = nil,
139
+ extraParams: [String: String] = [:]
140
+ ) {
141
+ self.playerName = playerName
142
+ self.playerVersion = playerVersion
143
+ self.adapterVersion = adapterVersion
144
+ self.resourceUrl = resourceUrl
145
+ self.parsedResource = parsedResource
146
+ self.title = title
147
+ self.program = program
148
+ self.contentType = contentType
149
+ self.playheadMs = playheadMs
150
+ self.durationMs = durationMs
151
+ self.bitrate = bitrate
152
+ self.rendition = rendition
153
+ self.videoCodec = videoCodec
154
+ self.audioCodec = audioCodec
155
+ self.codecProfile = codecProfile
156
+ self.containerFormat = containerFormat
157
+ self.errorCode = errorCode
158
+ self.errorMessage = errorMessage
159
+ self.errorMetadata = errorMetadata
160
+ self.errorLevel = errorLevel
161
+ self.forceInit = forceInit
162
+ self.convertFromBuffer = convertFromBuffer
163
+ self.convertFromSeek = convertFromSeek
164
+ self.customEvent = customEvent
165
+ self.legacyCustomDimensions = legacyCustomDimensions
166
+ self.customDimensions = customDimensions
167
+ self.customMetrics = customMetrics
168
+ self.extraParams = extraParams
169
+ }
170
+
171
+ public init(
172
+ playerName: String,
173
+ playerVersion: String? = nil,
174
+ adapterVersion: String? = nil,
175
+ resourceUrl: String? = nil,
176
+ parsedResource: String? = nil,
177
+ title: String? = nil,
178
+ contentType: ContentType = .unknown,
179
+ playheadMs: Int64? = nil,
180
+ durationMs: Int64? = nil,
181
+ bitrate: Int64? = nil,
182
+ rendition: String? = nil,
183
+ videoCodec: String? = nil,
184
+ audioCodec: String? = nil,
185
+ codecProfile: String? = nil,
186
+ containerFormat: String? = nil,
187
+ errorCode: String? = nil,
188
+ errorMessage: String? = nil,
189
+ errorMetadata: String? = nil,
190
+ errorLevel: String? = nil,
191
+ forceInit: Bool? = nil,
192
+ convertFromBuffer: Bool? = nil,
193
+ convertFromSeek: Bool? = nil,
194
+ customEvent: CustomVideoEventPayload? = nil,
195
+ legacyCustomDimensions: [String: String] = [:],
196
+ customDimensions: [String: String] = [:],
197
+ customMetrics: [String: Double] = [:],
198
+ extraParams: [String: String] = [:]
199
+ ) {
200
+ self.init(
201
+ playerName: playerName,
202
+ playerVersion: playerVersion,
203
+ adapterVersion: adapterVersion,
204
+ resourceUrl: resourceUrl,
205
+ parsedResource: parsedResource,
206
+ title: title,
207
+ contentType: contentType,
208
+ playheadMs: playheadMs,
209
+ durationMs: durationMs,
210
+ bitrate: bitrate,
211
+ rendition: rendition,
212
+ videoCodec: videoCodec,
213
+ audioCodec: audioCodec,
214
+ codecProfile: codecProfile,
215
+ containerFormat: containerFormat,
216
+ errorCode: errorCode,
217
+ errorMessage: errorMessage,
218
+ errorMetadata: errorMetadata,
219
+ errorLevel: errorLevel,
220
+ forceInit: forceInit,
221
+ convertFromBuffer: convertFromBuffer,
222
+ convertFromSeek: convertFromSeek,
223
+ customEvent: customEvent,
224
+ legacyCustomDimensions: legacyCustomDimensions,
225
+ customDimensions: customDimensions,
226
+ customMetrics: customMetrics,
227
+ program: nil,
228
+ extraParams: extraParams
229
+ )
230
+ }
231
+ }
232
+
233
+ public struct QosSnapshot: Equatable {
234
+ public var throughput: Double?
235
+ public var fps: Double?
236
+ public var latency: Double?
237
+ public var playrate: Double?
238
+ public var droppedFrames: Int64?
239
+ public var totalBytes: Int64?
240
+
241
+ public init(
242
+ throughput: Double? = nil,
243
+ fps: Double? = nil,
244
+ latency: Double? = nil,
245
+ playrate: Double? = nil,
246
+ droppedFrames: Int64? = nil,
247
+ totalBytes: Int64? = nil
248
+ ) {
249
+ self.throughput = throughput
250
+ self.fps = fps
251
+ self.latency = latency
252
+ self.playrate = playrate
253
+ self.droppedFrames = droppedFrames
254
+ self.totalBytes = totalBytes
255
+ }
256
+ }
257
+
258
+ public struct MetadataSnapshot: Equatable {
259
+ public var content: PlayerMetadataSnapshot
260
+ public var qos: QosSnapshot?
261
+
262
+ public init(content: PlayerMetadataSnapshot, qos: QosSnapshot? = nil) {
263
+ self.content = content
264
+ self.qos = qos
265
+ }
266
+ }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Copyright (C) NPAW - All Rights Reserved
3
+ *
4
+ * This source code is protected under international copyright law. All rights
5
+ * reserved and protected by the copyright holders.
6
+ * This file is confidential and only available to authorized individuals with the
7
+ * permission of the copyright holders. If you encounter this file and do not have
8
+ * permission, please contact the copyright holders and delete this file.
9
+ *
10
+ *
11
+ * @author: Victor Soto <victor.soto@nicepeopleatwork.com>
12
+ * @description: Shared Apple binding privacy sanitizer for metadata, capture, and network payloads.
13
+ */
14
+
15
+ import Foundation
16
+
17
+ public enum PrivacySanitizer {
18
+ private static let sensitiveFragments = [
19
+ "password",
20
+ "passwd",
21
+ "token",
22
+ "secret",
23
+ "authorization",
24
+ "auth",
25
+ "key",
26
+ "session",
27
+ ]
28
+
29
+ public static func sanitize(_ payload: [String: String], maxValueLength: Int = 512) -> [String: String] {
30
+ var output: [String: String] = [:]
31
+ output.reserveCapacity(payload.count)
32
+ for (key, value) in payload {
33
+ let normalized = key.lowercased()
34
+ if sensitiveFragments.contains(where: { normalized.contains($0) }) {
35
+ output[key] = "[redacted]"
36
+ } else {
37
+ output[key] = String(value.prefix(max(0, maxValueLength)))
38
+ }
39
+ }
40
+ return output
41
+ }
42
+
43
+ public static func redactUrl(_ value: String, maxLength: Int = 1024) -> String {
44
+ guard var components = URLComponents(string: value) else {
45
+ return String(value.prefix(maxLength))
46
+ }
47
+ components.user = nil
48
+ components.password = nil
49
+ components.fragment = nil
50
+ components.queryItems = components.queryItems?.map { item in
51
+ let normalized = item.name.lowercased()
52
+ if sensitiveFragments.contains(where: { normalized.contains($0) }) {
53
+ return URLQueryItem(name: item.name, value: "redacted")
54
+ }
55
+ return item
56
+ }
57
+ return String((components.string ?? value).prefix(maxLength))
58
+ }
59
+ }