first commit

This commit is contained in:
2026-03-10 16:18:05 +00:00
commit 11f9c069b5
31635 changed files with 3187747 additions and 0 deletions

View File

@@ -0,0 +1,141 @@
// Copyright 2023-present 650 Industries. All rights reserved.
import Foundation
@objc(EXFileSystemLegacyUtilities)
public class FileSystemManager: NSObject, EXInternalModule, EXFileSystemInterface, EXFilePermissionModuleInterface {
@objc
public let documentDirectory: String
@objc
public let cachesDirectory: String
@objc
public let applicationSupportDirectory: String
var appGroupSharedDirectories: [String]?
var isScoped: Bool = false
@objc
public init(documentDirectory: String, cachesDirectory: String, applicationSupportDirectory: String) {
self.documentDirectory = documentDirectory
self.cachesDirectory = cachesDirectory
self.applicationSupportDirectory = applicationSupportDirectory
self.isScoped = true
super.init()
ensureDirExists(withPath: self.cachesDirectory)
ensureDirExists(withPath: self.documentDirectory)
ensureDirExists(withPath: self.applicationSupportDirectory)
}
required public override init() {
let documentPaths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
self.documentDirectory = documentPaths[0]
let cachesPaths = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)
self.cachesDirectory = cachesPaths[0]
let applicationSupportDirectoryPaths =
NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true)
self.applicationSupportDirectory = applicationSupportDirectoryPaths[0]
super.init()
ensureDirExists(withPath: self.cachesDirectory)
ensureDirExists(withPath: self.documentDirectory)
ensureDirExists(withPath: self.applicationSupportDirectory)
}
public convenience init(appGroupSharedDirectories directories: [URL]) {
self.init()
maybeInitAppGroupSharedDirectories(directories)
}
public static func exportedInterfaces() -> [Protocol] {
return [EXFileSystemInterface.self, EXFilePermissionModuleInterface.self]
}
@objc
public func permissions(forURI uri: URL) -> EXFileSystemPermissionFlags {
let validSchemas = [
"assets-library",
"http",
"https",
"ph"
]
if validSchemas.contains(uri.scheme ?? "") {
return EXFileSystemPermissionFlags.read
}
if uri.scheme == "file" {
return getPathPermissions(uri.absoluteString)
}
return []
}
@objc
public func generatePath(inDirectory directory: String, withExtension ext: String) -> String {
let fileName = "\(UUID().uuidString)\(ext)"
ensureDirExists(withPath: directory)
return (directory as NSString).appendingPathComponent(fileName)
}
@objc
@discardableResult
public func ensureDirExists(withPath path: String) -> Bool {
let url = URL(fileURLWithPath: path)
return FileSystemUtilities.ensureDirExists(at: url)
}
@objc
public func getPathPermissions(_ path: String) -> EXFileSystemPermissionFlags {
guard let url = convertToUrl(string: path) else {
return []
}
let permissionsForInternalDirectories = getInternalPathPermissions(url)
if !permissionsForInternalDirectories.isEmpty {
return permissionsForInternalDirectories
}
return getExternalPathPermissions(url)
}
@objc
public func getInternalPathPermissions(_ url: URL) -> EXFileSystemPermissionFlags {
let appGroupSharedDirectories: [String] = self.appGroupSharedDirectories ?? []
let scopedDirs: [String] = [cachesDirectory, documentDirectory, applicationSupportDirectory] + appGroupSharedDirectories
let standardizedPath = url.standardized.path
for scopedDirectory in scopedDirs {
if standardizedPath.hasPrefix(scopedDirectory + "/") || standardizedPath == scopedDirectory {
return [.read, .write]
}
}
return []
}
@objc
public func getExternalPathPermissions(_ url: URL) -> EXFileSystemPermissionFlags {
if self.isScoped && url.path.contains("ExponentExperienceData") {
return []
}
var filePermissions: EXFileSystemPermissionFlags = []
if FileManager.default.isReadableFile(atPath: url.path) {
filePermissions.insert(.read)
}
if FileManager.default.isWritableFile(atPath: url.path) {
filePermissions.insert(.write)
}
return filePermissions
}
internal func maybeInitAppGroupSharedDirectories(_ directories: [URL]) {
if appGroupSharedDirectories != nil {
return
}
var appGroupSharedDirectories: [String] = []
for directory in directories {
appGroupSharedDirectories.append(directory.standardized.path)
}
self.appGroupSharedDirectories = appGroupSharedDirectories
}
}

View File

@@ -0,0 +1,125 @@
import Foundation
public enum FileSystemPermissionFlags {
case none
case read
case write
}
let validSchemas = ["assets-library", "http", "https", "ph"]
public struct FileSystemUtilities {
@discardableResult
public static func ensureDirExists(at url: URL?) -> Bool {
guard let url else {
return false
}
let exists = FileManager.default.fileExists(atPath: url.path)
if !exists {
do {
try FileManager.default.createDirectory(atPath: url.path, withIntermediateDirectories: true)
} catch {
return false
}
}
return true
}
public static func generatePathInCache(_ appContext: AppContext?, in directory: String, extension: String) -> String {
guard let appContext, let dirPath = appContext.config.cacheDirectory?.appendingPathComponent(directory) else {
return ""
}
let fileName = UUID().uuidString.appending(`extension`)
ensureDirExists(at: dirPath)
return dirPath.appendingPathComponent(fileName).path
}
public static func permissions(_ appContext: AppContext?, for uri: URL) -> [FileSystemPermissionFlags] {
guard let scheme = uri.scheme else {
return [.none]
}
if validSchemas.contains(scheme) {
return [.read]
}
if scheme == "file" {
return getPathPermissions(appContext, for: uri)
}
return [.none]
}
public static func isReadableFile(_ appContext: AppContext?, _ uri: URL) -> Bool {
if(!permissions(appContext, for: uri).contains(.read)) {
return false
}
let validSchemas = ["assets-library", "http", "https", "ph"]
guard let scheme = uri.scheme else {
return false
}
if validSchemas.contains(scheme) {
return true
}
return FileManager.default.isReadableFile(atPath: uri.path)
}
private static func getPathPermissions(_ appContext: AppContext?, for path: URL) -> [FileSystemPermissionFlags] {
let permissionForInternalDirs = getInternalPathPermissions(appContext, for: path)
if !permissionForInternalDirs.contains(.none) {
return permissionForInternalDirs
}
return getExternalPathPermissions(path, appContext)
}
public static func getInternalPathPermissions(_ appContext: AppContext?, for url: URL) -> [FileSystemPermissionFlags] {
guard let appContext else {
return [.none]
}
let scopedDirs = [appContext.config.cacheDirectory, appContext.config.documentDirectory] + appContext.config.appGroupSharedDirectories
let standardizedPath = url.standardized.path
for dir in scopedDirs {
guard let dir else {
continue
}
if standardizedPath.hasPrefix(dir.appendingPathComponent("/").path) || standardizedPath == dir.path {
return [.read, .write]
}
}
let bundleDirectory = Bundle.main.bundlePath
if url.path.hasPrefix(bundleDirectory + "/") {
return [.read]
}
return [.none]
}
private static func getExternalPathPermissions(_ url: URL, _ appContext: AppContext?) -> [FileSystemPermissionFlags] {
if appContext?.config.scoped ?? false && url.path.contains("ExponentExperienceData") {
return []
}
// Defer permission checks for external paths to the underlying system at the time of file operations
return [.read, .write]
}
private static func getAppGroupSharedDirectories(_ appContext: AppContext) -> [String] {
let appGroups = appContext.appCodeSignEntitlements.appGroups ?? []
var appGroupSharedDirectories: [String] = []
for appGroup in appGroups {
if let directory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroup) {
appGroupSharedDirectories.append(directory.standardized.path)
}
}
return appGroups
}
}