diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ca9bc90 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.DS_Store +.build +.swiftpm +Packages +*.xcodeproj +xcuserdata/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5735690 --- /dev/null +++ b/LICENSE @@ -0,0 +1,17 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + +Copyright (C) 2018-2019 Binary Birds + +Authors: + + Tibor Bodecs + +Everyone is permitted to copy and distribute verbatim or modified +copies of this license document, and changing it is allowed as long +as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..141be36 --- /dev/null +++ b/Package.swift @@ -0,0 +1,23 @@ +// swift-tools-version:5.2 +import PackageDescription + +let package = Package( + name: "liquid", + platforms: [ + .macOS(.v10_15) + ], + products: [ + .library(name: "Liquid", targets: ["Liquid"]), + ], + dependencies: [ + .package(url: "https://github.com/vapor/vapor.git", from: "4.4.0"), + .package(url: "https://github.com/binarybirds/liquid-kit.git", from: "1.0.0"), + ], + targets: [ + .target(name: "Liquid", dependencies: [ + .product(name: "Vapor", package: "vapor"), + .product(name: "LiquidKit", package: "liquid-kit"), + ]), + .testTarget(name: "LiquidTests", dependencies: ["Liquid"]), + ] +) diff --git a/README.md b/README.md new file mode 100644 index 0000000..9993c70 --- /dev/null +++ b/README.md @@ -0,0 +1,85 @@ +# Liquid + +Abstract file storage component made for Vapor 4. + + +## Usage example + +Add Liquid as a dependency using SPM, you can choose between the local and the AWS S3 driver. + +```swift +// swift-tools-version:5.2 +import PackageDescription + +let package = Package( + name: "myProject", + platforms: [ + .macOS(.v10_15) + ], + dependencies: [ + // 💧 A server-side Swift web framework. + .package(url: "https://github.com/vapor/vapor.git", from: "4.4.0"), + .package(url: "https://github.com/binarybirds/liquid.git", from: "0.0.1"), + .package(url: "https://github.com/binarybirds/liquid-local-driver.git", from: "0.0.1"), + .package(url: "https://github.com/binarybirds/liquid-aws-s3-driver.git", from: "0.0.1"), + ], + targets: [ + .target(name: "App", dependencies: [ + .product(name: "Vapor", package: "vapor"), + .product(name: "Liquid", package: "liquid"), + .product(name: "LiquidLocalDriver", package: "liquid-local-driver"), + .product(name: "LiquidAwsS3Driver", package: "liquid-aws-s3-driver"), + ]), + ] +) +``` + +Driver configuration + +```swift +import Liquid +import LiquidLocalDriver +import LiquidAwsS3Driver + +public func configure(_ app: Application) throws { + + app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory)) + + // using the local driver + app.fileStorages.use(.local(publicUrl: "http://localhost:8080/", + publicPath: app.directory.publicDirectory, + workDirectory: "assets"), as: .local) + + // using the AWS S3 driver + app.fileStorages.use(.awsS3(key: Environment.awsKey, + secret: Environment.awsSecret, + bucket: "vaportestbucket", + region: .uswest1), as: .awsS3) + +} +``` + +File upload example: + +```swift + +func testUpload(req: Request) -> EventLoopFuture { + let data: Data! = //... + let key = "path/to/my/file.txt" + return req.fs.upload(key: key, data: data) + // returns the full public url of the uploaded image +} + +// resolve public url based on a key +// func resolve(key: String) -> String +req.fs.resolve(key: myImageKey) + +// delete file based on a key +// func delete(key: String) -> EventLoopFuture +req.fs.delete(key: myImageKey) +``` + + +## License + +[WTFPL](LICENSE) - Do what the fuck you want to. diff --git a/Sources/Liquid/Application+Liquid.swift b/Sources/Liquid/Application+Liquid.swift new file mode 100644 index 0000000..0df2a76 --- /dev/null +++ b/Sources/Liquid/Application+Liquid.swift @@ -0,0 +1,78 @@ +// +// File.swift +// +// +// Created by Tibor Bodecs on 2020. 04. 28.. +// + +import Vapor +import LiquidKit +import NIO + +extension Application { + + public struct Liquid { + final class Storage { + let fileStorages: FileStorages + + init(fileio: NonBlockingFileIO) { + self.fileStorages = FileStorages(fileio: fileio) + } + } + + struct Key: StorageKey { + typealias Value = Storage + } + + struct Lifecycle: LifecycleHandler { + func shutdown(_ application: Application) { + application.fileStorages.shutdown() + } + } + + let application: Application + + var storage: Storage { + if self.application.storage[Key.self] == nil { + self.initialize() + } + return self.application.storage[Key.self]! + } + + func initialize() { + self.application.storage[Key.self] = .init(fileio: self.application.fileio) + self.application.lifecycle.use(Lifecycle()) + } + } + + public var liquid: Liquid { + .init(application: self) + } + +} + +public extension Request { + + var fs: FileStorage { + self.fs(nil) + } + + func fs(_ id: FileStorageID?) -> FileStorage { + self.application.fileStorages.fileStorage(id, logger: self.logger, on: self.eventLoop)! + } +} + +public extension Application { + + var fs: FileStorage { + self.fs(nil) + } + + func fs(_ id: FileStorageID?) -> FileStorage { + self.fileStorages.fileStorage(id, logger: self.logger, on: self.eventLoopGroup.next())! + } + + var fileStorages: FileStorages { + self.liquid.storage.fileStorages + } +} diff --git a/Sources/Liquid/Exports.swift b/Sources/Liquid/Exports.swift new file mode 100644 index 0000000..b7b7bb1 --- /dev/null +++ b/Sources/Liquid/Exports.swift @@ -0,0 +1,8 @@ +// +// File.swift +// +// +// Created by Tibor Bodecs on 2020. 04. 28.. +// + +@_exported import LiquidKit diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift new file mode 100644 index 0000000..05b1268 --- /dev/null +++ b/Tests/LinuxMain.swift @@ -0,0 +1,7 @@ +import XCTest + +import LiquidTests + +var tests = [XCTestCaseEntry]() +tests += LiquidTests.allTests() +XCTMain(tests) diff --git a/Tests/LiquidTests/LiquidTests.swift b/Tests/LiquidTests/LiquidTests.swift new file mode 100644 index 0000000..e2207af --- /dev/null +++ b/Tests/LiquidTests/LiquidTests.swift @@ -0,0 +1,13 @@ +import XCTest +@testable import Liquid + +final class LiquidTests: XCTestCase { + + static var allTests = [ + ("testExample", testExample), + ] + + func testExample() { + XCTAssertEqualTrue(true) + } +} diff --git a/Tests/LiquidTests/XCTestManifests.swift b/Tests/LiquidTests/XCTestManifests.swift new file mode 100644 index 0000000..56fd7e2 --- /dev/null +++ b/Tests/LiquidTests/XCTestManifests.swift @@ -0,0 +1,9 @@ +import XCTest + +#if !canImport(ObjectiveC) +public func allTests() -> [XCTestCaseEntry] { + return [ + testCase(LiquidTests.allTests), + ] +} +#endif