diff --git a/.DS_Store b/.DS_Store index cbb3da7..dd2070c 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/README.md b/README.md index 8f441e7..7754789 100644 --- a/README.md +++ b/README.md @@ -1,115 +1,15 @@ -# Storage +# slugify [![Language](https://img.shields.io/badge/Swift-3-brightgreen.svg)](http://swift.org) -[![Build Status](https://travis-ci.org/nodes-vapor/storage.svg?branch=master)](https://travis-ci.org/nodes-vapor/storage) -[![codecov](https://codecov.io/gh/nodes-vapor/storage/branch/master/graph/badge.svg)](https://codecov.io/gh/nodes-vapor/storage) -[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nodes-vapor/storage/master/LICENSE) - -A package to ease the use of multiple storage and CDN services. - -##### Table of Contents -* [Getting started](#getting-started-) -* [Upload a file](#upload-a-file-) - * [Base 64 and data URI](#base-64-and-data-uri-) -* [Download a file](#download-a-file-) -* [Delete a file](#delete-a-file-) -* [Configuration](#configuration-) - * [Network driver](#network-driver-) - * [Upload path](#upload-path-) +[![Build Status](https://travis-ci.org/nodes-vapor/slugify.svg?branch=master)](https://travis-ci.org/nodes-vapor/slugify) +[![codecov](https://codecov.io/gh/nodes-vapor/slugify/branch/master/graph/badge.svg)](https://codecov.io/gh/nodes-vapor/slugify) +[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nodes-vapor/slugify/master/LICENSE) ## Integration Update your `Package.swift` file. ```swift -.Package(url: "https://github.com/nodes-vapor/storage", majorVersion: 0) -``` - -## Getting started 🚀 -`Storage` offers a [Provider](https://vapor.github.io/documentation/guide/provider.html) and does all configuration through JSON files. - -```swift -import Storage -try drop.addProvider(StorageProvider.self) -``` - -Now, create a JSON file named `Config/storage.json` with the following contents: - -```json -{ - "driver": "s3", - "accessKey": "$YOUR_AWS_ACCESS_KEY", - "secretKey": "$YOUR_AWS_SECRET_KEY", - "template": "$folder/$file" -} -``` -Learn about [these fields and more](#configuration-). - -## Upload a file 🌐 -There are a few different interfaces for uploading a file, the simplest being the following: -```swift -Storage.upload( - bytes: [UInt8], - fileName: String?, - fileExtension: String?, - mime: String?, - folder: String -) throws -> String -``` -The aforementioned function will attempt to upload the file using your [selected driver and template](#configuration-) and will return a `String` representing the location of the file. - -If you want to upload an image named `profile.png` your call site would look like: -```swift -let path = try Storage.upload(bytes: bytes, fileName: "profile", fileExtension: "png") -print(path) //prints `images/profile.png` +.Package(url: "https://github.com/nodes-vapor/slugify", majorVersion: 0) ``` -#### Base64 and data URI 📡 -Is your file a base64 or data URI? No problem! -```swift -Storage.upload(base64: String, //...) -Storage.upload(dataURI: String, //...) -``` - -## Download a file ✅ -To download a file that was previously uploaded you simply use the generated path. -```swift -//download image as `Foundation.Data` -let data = try Storage.get("images/profile.png") -``` - -## Delete a file ❌ -Deleting a file using this package isn't the recommended way to handle removal, but is still possible. -```swift -try Storage.delete("images/profile.png") -``` -## Configuration ⚙ -`Storage` has a variety of configurable options. -#### Network driver 🔨 -The network driver is the module responsible for interacting with your 3rd party service. The default, and currently the only, driver is `s3`. -```json -{ - "driver": "s3", - "accessKey": "$YOUR_AWS_ACCESS_KEY", - "secretKey": "$YOUR_AWS_SECRET_KEY" -} -``` -The `driver` key is optional and will default to `aws`. `accessKey` and `secretKey` are both required by the AWS driver. - -#### Upload path 🛣 -A times, you may need to upload files to a different scheme than `folder/file.ext`. You can achieve this by adding the `"template"` field to your `Config/storage.json`. If the field is omitted it will default to `$folder/$file`. - -The following template will upload `profile.png` from the folder `images` to `myapp/images/profile.png` -```json -"template": "myapp/$folder/$file" -``` - -##### Aliases -There are a few aliases that will be replaced by the real metadata of the file at the time of upload. They are: - -* `$file`: The file's name and extension. -* `$fileName`: The file's name. -* `$fileExtension`: The file's extension. -* `$folder`: The provided folder -* `$mimeFolder`: A folder generated according to the file's mime. - ## 🏆 Credits This package is developed and maintained by the Vapor team at [Nodes](https://www.nodes.dk). diff --git a/Sources/.DS_Store b/Sources/.DS_Store index 26862d7..bfe9b48 100644 Binary files a/Sources/.DS_Store and b/Sources/.DS_Store differ diff --git a/Tests/.DS_Store b/Tests/.DS_Store index 57fb53f..5008ddf 100644 Binary files a/Tests/.DS_Store and b/Tests/.DS_Store differ diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift deleted file mode 100644 index 999ddc3..0000000 --- a/Tests/LinuxMain.swift +++ /dev/null @@ -1,9 +0,0 @@ -import XCTest -@testable import StorageTests - -XCTMain([ - testCase(StorageTests.allTests), - testCase(FileEntityTests.allTests), - testCase(TemplateTests.allTests), - testCase(PathBuilderTests.allTests) -]) diff --git a/Tests/StorageTests/.DS_Store b/Tests/StorageTests/.DS_Store deleted file mode 100644 index 26d5b6e..0000000 Binary files a/Tests/StorageTests/.DS_Store and /dev/null differ diff --git a/Tests/StorageTests/FileEntityTests.swift b/Tests/StorageTests/FileEntityTests.swift deleted file mode 100644 index bed1d87..0000000 --- a/Tests/StorageTests/FileEntityTests.swift +++ /dev/null @@ -1,89 +0,0 @@ -import XCTest -@testable import Storage - -class FileEntityTests: XCTestCase { - static var allTests = [ - ("testFileEntityInit", testFileEntityInit), - ("testFileEntityInitNil", testFileEntityInitNil), - ("testFileEntityValidate", testFileEntityValidate), - ("testFileEntityValidateFailed", testFileEntityValidateFailed), - ("testFileEntityGetFilePath", testFileEntityGetFilePath), - ("testFileEntityGetFilePathFailed", testFileEntityGetFilePathFailed) - ] - - func testFileEntityInit() { - let entity = FileEntity( - fileName: "test_image", - fileExtension: "png", - folder: "images" - ) - - XCTAssertNotNil(entity.fileName) - XCTAssertNotNil(entity.folder) - XCTAssertNotNil(entity.fileExtension) - - XCTAssertEqual(entity.fileName, "test_image") - XCTAssertEqual(entity.fileExtension, "png") - XCTAssertEqual(entity.folder, "images") - } - - func testFileEntityInitNil() { - let entity = FileEntity() - - XCTAssertNil(entity.bytes) - XCTAssertNil(entity.fileName) - XCTAssertNil(entity.fileExtension) - XCTAssertNil(entity.folder) - } - - func testFileEntityValidate() { - let entity = FileEntity( - fileName: "test_image", - fileExtension: "png", - folder: "images" - ) - - expectNoThrow(entity.verify) - } - - func testFileEntityValidateFailed() { - let entity = FileEntity( - fileName: "test_image", - folder: "images" - ) - - expect(toThrow: FileEntity.Error.missingFileExtension, from: entity.verify) - - let entity2 = FileEntity( - fileExtension: "png", - folder: "images" - ) - expect(toThrow: FileEntity.Error.missingFilename, from: entity2.verify) - } - - func testFileEntityGetFilePath() { - let entity = FileEntity( - fileName: "test_image", - fileExtension: "png", - folder: "images" - ) - - expect(entity.getFilePath, toReturn: "images/test_image.png") - } - - func testFileEntityGetFilePathFailed() { - let entity = FileEntity( - fileExtension: "jpg", - folder: "images" - ) - - expect(toThrow: FileEntity.Error.missingFilename, from: entity.getFilePath) - - let entity2 = FileEntity( - fileName: "profileImage", - folder: "images" - ) - - expect(toThrow: FileEntity.Error.missingFileExtension, from: entity2.getFilePath) - } -} diff --git a/Tests/StorageTests/PathBuilderTests.swift b/Tests/StorageTests/PathBuilderTests.swift deleted file mode 100644 index 02dd7aa..0000000 --- a/Tests/StorageTests/PathBuilderTests.swift +++ /dev/null @@ -1,27 +0,0 @@ -import XCTest -@testable import Storage - -class PathBuilderTests: XCTestCase { - static var allTests = [ - ("testConfigurablePathBuilder", testConfigurablePathBuilder), - ("testConfigurablePathBuilderFailed", testConfigurablePathBuilderFailed) - ] - - func testConfigurablePathBuilder() { - let entity = FileEntity( - fileName: "smile", - fileExtension: "jpg", - folder: "images", - mime: "image/jpg" - ) - - expectNoThrow() { - let builder = try ConfigurablePathBuilder(template: "$folder/$file") - let path = try builder.build(entity: entity) - XCTAssertEqual(path, "images/smile.jpg") - } - } - - func testConfigurablePathBuilderFailed() { - } -} diff --git a/Tests/StorageTests/StorageTests.swift b/Tests/StorageTests/StorageTests.swift deleted file mode 100644 index 2ba2ea9..0000000 --- a/Tests/StorageTests/StorageTests.swift +++ /dev/null @@ -1,12 +0,0 @@ -import XCTest -@testable import Storage - -class StorageTests: XCTestCase { - static var allTests = [ - ("testExample", testExample) - ] - - func testExample() { - XCTAssertEqual(2+2, 4) - } -} diff --git a/Tests/StorageTests/TemplateTests.swift b/Tests/StorageTests/TemplateTests.swift deleted file mode 100644 index 47309a6..0000000 --- a/Tests/StorageTests/TemplateTests.swift +++ /dev/null @@ -1,78 +0,0 @@ -import XCTest - -@testable import Storage - -class TemplateTests: XCTestCase { - static var allTests = [ - ("testExtractPartBasic", testExtractPartBasic), - ("testExtractPartFailed", testExtractPartFailed), - ("testExtractPartDoubleAlias", testExtractPartDoubleAlias), - ("testExtractPartMatchingPrefixes", testExtractPartMatchingPrefixes) - ] - - func testExtractPartBasic() { - let template = "$folder/$file" - let expected: [Template.PathPart] = [ - .alias(.folder), - .literal("/".bytes), - .alias(.file) - ] - - expectParts(expected, fromTemplate: template) - } - - func testExtractPartFailed() { - let templateString = "$madeupAlias" - let scanner = Scanner(templateString.bytes) - var template = Template(scanner: scanner) - - expect(toThrow: Template.Error.invalidAlias("$madeupAlias")) { - _ = try template.extractPart() - } - } - - func testExtractPartDoubleAlias() { - let template = "$folder$file" - let expected: [Template.PathPart] = [ - .alias(.folder), - .alias(.file) - ] - - expectParts(expected, fromTemplate: template) - } - - func testExtractPartMatchingPrefixes() { - let template = "$file$fileName$fileExtension" - let expected: [Template.PathPart] = [ - .alias(.file), - .alias(.fileName), - .alias(.fileExtension) - ] - - expectParts(expected, fromTemplate: template) - } -} - -extension TemplateTests { - func expectParts( - _ expectedParts: [Template.PathPart], - fromTemplate template: String, - file: StaticString = #file, - line: UInt = #line - ) { - let bytes = template.bytes - let scanner = Scanner(bytes) - var template = Template(scanner: scanner) - - for expected in expectedParts { - var part: Template.PathPart? = nil - - expectNoThrow() { - part = try template.extractPart() - } - - XCTAssertNotNil(part, "should have extracted non-nil", file: file, line: line) - XCTAssert(part! == expected, file: file, line: line) - } - } -} diff --git a/Tests/StorageTests/Utilities/Expect.swift b/Tests/StorageTests/Utilities/Expect.swift deleted file mode 100644 index 6a915aa..0000000 --- a/Tests/StorageTests/Utilities/Expect.swift +++ /dev/null @@ -1,47 +0,0 @@ -import XCTest - -func expect( - toThrow expectedError: E, - file: StaticString = #file, - line: UInt = #line, - from closure: (Void) throws -> ReturnType -) where E: Equatable { - do { - let _ = try closure() - XCTFail("should have thrown", file: file, line: line) - } catch let error as E { - XCTAssertEqual(error, expectedError) - } catch { - XCTFail( - "expected type \(type(of: expectedError)) got \(type(of: error))", - file: file, - line: line - ) - } -} - -func expectNoThrow( - file: StaticString = #file, - line: UInt = #line, - _ closure: (Void) throws -> ReturnType -) { - do { - let _ = try closure() - } catch { - XCTFail("closure threw: \(error)", file: file, line: line) - } -} - -func expect( - _ closure: (Void) throws -> ReturnType, - file: StaticString = #file, - line: UInt = #line, - toReturn expectedResult: ReturnType -) where ReturnType: Equatable { - do { - let result = try closure() - XCTAssertEqual(result, expectedResult, file: file, line: line) - } catch { - XCTFail("closure threw: \(error)", file: file, line: line) - } -}