diff --git a/.github/ISSUE_TEMPLATE/general-issue.md b/.github/ISSUE_TEMPLATE/general-issue.md new file mode 100644 index 0000000..92ea455 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/general-issue.md @@ -0,0 +1,34 @@ +--- +name: General issue +about: Report a reproducible bug or issue +title: '[Bug] [Feature Request] Short description of the issue' +labels: '' +assignees: '' +--- + +## 🐞 Expected Behavior + + +## ❌ Actual Behavior + + +## 🔄 Steps to Reproduce +1. +2. +3. + +## 📄 Logs / Error Messages + + +## 📸 Screenshots + + +## 💻 Code Snippets +```swift +// Include relevant code snippets that help reproduce the issue. +``` + +## 🛠 System Information +- **Package Version**: +- **Operating System**: +- **Device / Hardware**: diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..0391634 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,8 @@ +## What + + +## Why + + +## Changes + diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..0ff9013 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,47 @@ +name: Tests + +on: + pull_request: + branches: [ main ] + +jobs: + test: + runs-on: macos-latest + + steps: + - uses: actions/checkout@v4 + + - name: Select Xcode + run: sudo xcode-select -s /Applications/Xcode.app/Contents/Developer + + - name: List available iOS runtimes + run: xcrun simctl list runtimes + + - name: Create and boot iOS Simulator + run: | + # Get the latest iOS runtime available + RUNTIME=$(xcrun simctl list runtimes | grep "iOS" | tail -1 | grep -oE "com\.apple\.CoreSimulator\.SimRuntime\.iOS-[0-9-]+") + echo "Using runtime: $RUNTIME" + + # Create simulator + SIMULATOR_ID=$(xcrun simctl create test-device com.apple.CoreSimulator.SimDeviceType.iPhone-15 "$RUNTIME" 2>&1 | tail -1) + echo "Created simulator: $SIMULATOR_ID" + + # Boot it + xcrun simctl boot "$SIMULATOR_ID" + + # Wait for it to boot + sleep 5 + + echo "SIMULATOR_ID=$SIMULATOR_ID" >> $GITHUB_ENV + + - name: Run tests with iOS Simulator + run: | + xcodebuild test \ + -scheme ZeplinKit \ + -skipPackagePluginValidation \ + -destination "id=${{ env.SIMULATOR_ID }}" \ + -derivedDataPath .build \ + -enableCodeCoverage YES \ + -sdk iphonesimulator \ + -verbose diff --git a/.spi.yml b/.spi.yml new file mode 100644 index 0000000..b715877 --- /dev/null +++ b/.spi.yml @@ -0,0 +1,5 @@ +version: 1 +builder: + configs: + - documentation_targets: [ZeplinKit] + platform: ios diff --git a/.swiftformat b/.swiftformat new file mode 100644 index 0000000..57584ae --- /dev/null +++ b/.swiftformat @@ -0,0 +1,70 @@ +{ + "fileScopedDeclarationPrivacy" : { + "accessLevel" : "private" + }, + "indentConditionalCompilationBlocks" : true, + "indentSwitchCaseLabels" : false, + "indentation" : { + "spaces" : 4 + }, + "lineBreakAroundMultilineExpressionChainComponents" : false, + "lineBreakBeforeControlFlowKeywords" : false, + "lineBreakBeforeEachArgument" : false, + "lineBreakBeforeEachGenericRequirement" : false, + "lineLength" : 140, + "maximumBlankLines" : 1, + "multiElementCollectionTrailingCommas" : true, + "noAssignmentInExpressions" : { + "allowedFunctions" : [ + "XCTAssertNoThrow" + ] + }, + "prioritizeKeepingFunctionOutputTogether" : false, + "respectsExistingLineBreaks" : true, + "rules" : { + "AllPublicDeclarationsHaveDocumentation" : false, + "AlwaysUseLiteralForEmptyCollectionInit" : false, + "AlwaysUseLowerCamelCase" : true, + "AmbiguousTrailingClosureOverload" : true, + "BeginDocumentationCommentWithOneLineSummary" : false, + "DoNotUseSemicolons" : true, + "DontRepeatTypeInStaticProperties" : true, + "FileScopedDeclarationPrivacy" : true, + "FullyIndirectEnum" : true, + "GroupNumericLiterals" : true, + "IdentifiersMustBeASCII" : true, + "NeverForceUnwrap" : false, + "NeverUseForceTry" : false, + "NeverUseImplicitlyUnwrappedOptionals" : false, + "NoAccessLevelOnExtensionDeclaration" : true, + "NoAssignmentInExpressions" : true, + "NoBlockComments" : true, + "NoCasesWithOnlyFallthrough" : true, + "NoEmptyTrailingClosureParentheses" : true, + "NoLabelsInCasePatterns" : true, + "NoLeadingUnderscores" : false, + "NoParensAroundConditions" : true, + "NoPlaygroundLiterals" : true, + "NoVoidReturnOnFunctionSignature" : true, + "OmitExplicitReturns" : false, + "OneCasePerLine" : true, + "OneVariableDeclarationPerLine" : true, + "OnlyOneTrailingClosureArgument" : true, + "OrderedImports" : true, + "ReplaceForEachWithForLoop" : true, + "ReturnVoidInsteadOfEmptyTuple" : true, + "TypeNamesShouldBeCapitalized" : true, + "UseEarlyExits" : false, + "UseExplicitNilCheckInConditions" : true, + "UseLetInEveryBoundCaseVariable" : true, + "UseShorthandTypeNames" : true, + "UseSingleLinePropertyGetter" : true, + "UseSynthesizedInitializer" : true, + "UseTripleSlashForDocumentationComments" : true, + "UseWhereClausesInForLoops" : false, + "ValidateDocumentationComments" : false + }, + "spacesAroundRangeFormationOperators" : true, + "tabWidth" : 4, + "version" : 1 +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..b54736d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,59 @@ +# Change Log +All notable changes to this project will be documented in this file. + + + +## [0.1.0] - 2026-01-12 + +Initial public release of ZeplinKit. + +### Added +- MIT License for the project +- Continuous Integration workflow +- Issue template for GitHub +- Pull request template for GitHub +- Swift Package Index configuration (.spi.yml) +- Shield badges to README +- Format plugin for code formatting + +### Changed +- Restructured project folders for better organization +- Formatted entire codebase with consistent style +- Updated and polished documentation metadata +- Enhanced README with better documentation + +### Fixed +- Logo image source reference in README.md +- Documentation references in README +- Various typos throughout the project + +## [0.0.4] + +- Updated models with Sendable conformance + +## [0.0.3] + +- Build against Fetcher v0.0.2 + +## [0.0.2] + +- Conform ZeplinSection to Identifiable + +## [0.0.1] + +- Initial implementation diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d94f8c1 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Snapp-Mobile + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Package.swift b/Package.swift index e7abf37..7d46a7e 100644 --- a/Package.swift +++ b/Package.swift @@ -1,5 +1,4 @@ // swift-tools-version: 5.6 -// The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription @@ -7,33 +6,34 @@ let package = Package( name: "ZeplinKit", platforms: [ .iOS(.v13), - .macOS(.v11) + .macOS(.v11), ], products: [ - // Products define the executables and libraries a package produces, and make them visible to other packages. .library( name: "ZeplinKit", targets: ["ZeplinKit"] - ), + ) ], dependencies: [ - // Dependencies declare other packages that this package depends on. - .package(url: "https://github.com/Snapp-Mobile/Fetcher", from: "0.0.2"), - .package(url: "https://github.com/marmelroy/Zip", from: "2.0.0") + .package(url: "https://github.com/Snapp-Mobile/Fetcher.git", from: "0.0.2"), + .package(url: "https://github.com/marmelroy/Zip", from: "2.0.0"), + .package(url: "https://github.com/Snapp-Mobile/SwiftFormatLintPlugin.git", from: "1.0.4"), ], targets: [ - // Targets are the basic building blocks of a package. A target can define a module or a test suite. - // Targets can depend on other targets in this package, and on products in packages this package depends on. .target( name: "ZeplinKit", dependencies: ["Fetcher", "Zip"], + path: "Sources", resources: [ .process("Mocks") - ] + ], + plugins: [.plugin(name: "Lint", package: "SwiftFormatLintPlugin")], ), .testTarget( name: "ZeplinKitTests", - dependencies: ["ZeplinKit", "Fetcher"] - ) + dependencies: ["ZeplinKit", "Fetcher"], + path: "Tests", + plugins: [.plugin(name: "Lint", package: "SwiftFormatLintPlugin")], + ), ] ) diff --git a/README.md b/README.md index 1172966..05f36e5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,58 @@ +
+ ZeplinKit Logo +
+ # ZeplinKit Swift client library for the public Zeplin API + +[![Swift Package Index](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FSnapp-Mobile%2FZeplinKit%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/Snapp-Mobile/ZeplinKit) +[![iOS 13.0+](https://img.shields.io/badge/iOS-13.0+-007AFF?logo=apple&logoColor=white)](https://www.apple.com/ios/) +[![Latest Release](https://img.shields.io/github/v/release/Snapp-Mobile/ZeplinKit?color=8B5CF6&logo=github&logoColor=white)](https://github.com/Snapp-Mobile/ZeplinKit/releases) +[![Tests](https://github.com/Snapp-Mobile/ZeplinKit/actions/workflows/test.yml/badge.svg)](https://github.com/Snapp-Mobile/ZeplinKit/actions) +[![License: MIT](https://img.shields.io/badge/License-MIT-22C55E)](LICENSE) + +## Overview + +ZeplinKit provides data models and preconfigured API endpoints for the [Zeplin API](https://docs.zeplin.dev/docs/getting-started-with-zeplin-api). It offers a flexible client that integrates with any workflow, supporting both Combine publishers and Swift Concurrency (iOS 13+/macOS 11+). + +The library includes `Fetcher`, a lightweight network client, and `ZeplinAPIURL`, an enumeration of API endpoints that encapsulates the required parameters for each call. + +### Installation + +```swift +// Swift Package Manager +.package(url: "https://github.com/Snapp-Mobile/ZeplinKit.git", from: "0.1.0") +``` + +### Authentication + +To use ZeplinKit, you'll need a Zeplin access token. Learn how to generate one in the [Zeplin API documentation](https://blog.zeplin.io/collaboration/getting-started-with-zeplin-javascript-sdk/). + +### Setup + +```swift +import ZeplinKit + +let fetcher = Fetcher( + environment: .production, + accessToken: "your_zeplin_access_token" +) +``` + +### Usage + +To fetch the first 10 projects for your account: + +```swift +func loadProjects() async { + let url = ZeplinAPIURL.getProjects(10, 0) + + do { + let projects: [ZeplinProject] = try await fetcher.fetch(url) + // Handle projects + } catch { + print("Failed to fetch projects: \(error.localizedDescription)") + } +} +``` diff --git a/Sources/ZeplinKit/Configuration/ZeplinAPIConfiguration.swift b/Sources/Configuration/ZeplinAPIConfiguration.swift similarity index 99% rename from Sources/ZeplinKit/Configuration/ZeplinAPIConfiguration.swift rename to Sources/Configuration/ZeplinAPIConfiguration.swift index a65e03a..6558ebb 100644 --- a/Sources/ZeplinKit/Configuration/ZeplinAPIConfiguration.swift +++ b/Sources/Configuration/ZeplinAPIConfiguration.swift @@ -1,6 +1,6 @@ // // ZeplinAPIConfiguration.swift -// +// // // Created by Ilian Konchev on 24.03.20. // Copyright © 2020 Ilian Konchev. All rights reserved. diff --git a/Sources/ZeplinKit/Extensions/Date+beforize.swift b/Sources/Extensions/Date+beforize.swift similarity index 86% rename from Sources/ZeplinKit/Extensions/Date+beforize.swift rename to Sources/Extensions/Date+beforize.swift index bafe238..4590f45 100644 --- a/Sources/ZeplinKit/Extensions/Date+beforize.swift +++ b/Sources/Extensions/Date+beforize.swift @@ -1,6 +1,6 @@ // // Date+beforize.swift -// +// // // Created by Ilian Konchev on 28.01.21. // Copyright © 2021 Ilian Konchev. All rights reserved. @@ -8,11 +8,11 @@ import Foundation -public extension Date { +extension Date { /// Formate the date using ``ZeplinKit/SharedFormatters/relativeDateFormatter`` /// - Returns: A string containing the formatted date - func beforized() -> String { + public func beforized() -> String { return SharedFormatters.relativeDateFormatter.localizedString(for: self, relativeTo: Date()) } } diff --git a/Sources/ZeplinKit/Extensions/Fetcher+download.swift b/Sources/Extensions/Fetcher+download.swift similarity index 78% rename from Sources/ZeplinKit/Extensions/Fetcher+download.swift rename to Sources/Extensions/Fetcher+download.swift index 0d867c5..5c60cf2 100644 --- a/Sources/ZeplinKit/Extensions/Fetcher+download.swift +++ b/Sources/Extensions/Fetcher+download.swift @@ -1,6 +1,6 @@ // // Fetcher+download.swift -// +// // // Created by Ilian Konchev on 29.01.22. // @@ -9,10 +9,12 @@ import Fetcher import Foundation extension Fetcher { - func download(by urlString: String, - with format: String, - displayName: String, - density: Double? = nil) async throws -> String { + func download( + by urlString: String, + with format: String, + displayName: String, + density: Double? = nil + ) async throws -> String { guard let url = URL(string: urlString) else { return "" } let request = URLRequest(url: url) diff --git a/Sources/ZeplinKit/Extensions/SharedFormatters.swift b/Sources/Extensions/SharedFormatters.swift similarity index 99% rename from Sources/ZeplinKit/Extensions/SharedFormatters.swift rename to Sources/Extensions/SharedFormatters.swift index b751f54..68f1814 100644 --- a/Sources/ZeplinKit/Extensions/SharedFormatters.swift +++ b/Sources/Extensions/SharedFormatters.swift @@ -1,6 +1,6 @@ // // SharedFormatters.swift -// +// // // Created by Ilian Konchev on 28.01.21. // Copyright © 2021 Ilian Konchev. All rights reserved. diff --git a/Sources/ZeplinKit/Mocks/createComment.json b/Sources/Mocks/createComment.json similarity index 100% rename from Sources/ZeplinKit/Mocks/createComment.json rename to Sources/Mocks/createComment.json diff --git a/Sources/ZeplinKit/Mocks/createNote.json b/Sources/Mocks/createNote.json similarity index 100% rename from Sources/ZeplinKit/Mocks/createNote.json rename to Sources/Mocks/createNote.json diff --git a/Sources/ZeplinKit/Mocks/emptyResponse.json b/Sources/Mocks/emptyResponse.json similarity index 100% rename from Sources/ZeplinKit/Mocks/emptyResponse.json rename to Sources/Mocks/emptyResponse.json diff --git a/Sources/ZeplinKit/Mocks/flagNotificationsAsUnread.json b/Sources/Mocks/flagNotificationsAsUnread.json similarity index 100% rename from Sources/ZeplinKit/Mocks/flagNotificationsAsUnread.json rename to Sources/Mocks/flagNotificationsAsUnread.json diff --git a/Sources/ZeplinKit/Mocks/getCurrentUser.json b/Sources/Mocks/getCurrentUser.json similarity index 100% rename from Sources/ZeplinKit/Mocks/getCurrentUser.json rename to Sources/Mocks/getCurrentUser.json diff --git a/Sources/ZeplinKit/Mocks/getNote.json b/Sources/Mocks/getNote.json similarity index 100% rename from Sources/ZeplinKit/Mocks/getNote.json rename to Sources/Mocks/getNote.json diff --git a/Sources/ZeplinKit/Mocks/getNotes.json b/Sources/Mocks/getNotes.json similarity index 100% rename from Sources/ZeplinKit/Mocks/getNotes.json rename to Sources/Mocks/getNotes.json diff --git a/Sources/ZeplinKit/Mocks/getNotifications.json b/Sources/Mocks/getNotifications.json similarity index 100% rename from Sources/ZeplinKit/Mocks/getNotifications.json rename to Sources/Mocks/getNotifications.json diff --git a/Sources/ZeplinKit/Mocks/getProject.json b/Sources/Mocks/getProject.json similarity index 100% rename from Sources/ZeplinKit/Mocks/getProject.json rename to Sources/Mocks/getProject.json diff --git a/Sources/ZeplinKit/Mocks/getProjectMembers.json b/Sources/Mocks/getProjectMembers.json similarity index 100% rename from Sources/ZeplinKit/Mocks/getProjectMembers.json rename to Sources/Mocks/getProjectMembers.json diff --git a/Sources/ZeplinKit/Mocks/getProjects.json b/Sources/Mocks/getProjects.json similarity index 100% rename from Sources/ZeplinKit/Mocks/getProjects.json rename to Sources/Mocks/getProjects.json diff --git a/Sources/ZeplinKit/Mocks/getScreen.json b/Sources/Mocks/getScreen.json similarity index 100% rename from Sources/ZeplinKit/Mocks/getScreen.json rename to Sources/Mocks/getScreen.json diff --git a/Sources/ZeplinKit/Mocks/getScreenVersion.json b/Sources/Mocks/getScreenVersion.json similarity index 100% rename from Sources/ZeplinKit/Mocks/getScreenVersion.json rename to Sources/Mocks/getScreenVersion.json diff --git a/Sources/ZeplinKit/Mocks/getScreenVersions.json b/Sources/Mocks/getScreenVersions.json similarity index 100% rename from Sources/ZeplinKit/Mocks/getScreenVersions.json rename to Sources/Mocks/getScreenVersions.json diff --git a/Sources/ZeplinKit/Mocks/getScreens.json b/Sources/Mocks/getScreens.json similarity index 100% rename from Sources/ZeplinKit/Mocks/getScreens.json rename to Sources/Mocks/getScreens.json diff --git a/Sources/ZeplinKit/Mocks/getSections.json b/Sources/Mocks/getSections.json similarity index 100% rename from Sources/ZeplinKit/Mocks/getSections.json rename to Sources/Mocks/getSections.json diff --git a/Sources/ZeplinKit/Mocks/getToken.json b/Sources/Mocks/getToken.json similarity index 100% rename from Sources/ZeplinKit/Mocks/getToken.json rename to Sources/Mocks/getToken.json diff --git a/Sources/ZeplinKit/Mocks/inviteMember.json b/Sources/Mocks/inviteMember.json similarity index 100% rename from Sources/ZeplinKit/Mocks/inviteMember.json rename to Sources/Mocks/inviteMember.json diff --git a/Sources/ZeplinKit/Mocks/refreshToken.json b/Sources/Mocks/refreshToken.json similarity index 100% rename from Sources/ZeplinKit/Mocks/refreshToken.json rename to Sources/Mocks/refreshToken.json diff --git a/Sources/ZeplinKit/Models/Layers/ZeplinAsset.swift b/Sources/Models/Layers/ZeplinAsset.swift similarity index 99% rename from Sources/ZeplinKit/Models/Layers/ZeplinAsset.swift rename to Sources/Models/Layers/ZeplinAsset.swift index 3047a0e..80ae854 100644 --- a/Sources/ZeplinKit/Models/Layers/ZeplinAsset.swift +++ b/Sources/Models/Layers/ZeplinAsset.swift @@ -1,6 +1,6 @@ // // ZeplinAsset.swift -// +// // // Created by Ilian Konchev on 13.12.21. // diff --git a/Sources/ZeplinKit/Models/Layers/ZeplinBoundingRectangle.swift b/Sources/Models/Layers/ZeplinBoundingRectangle.swift similarity index 66% rename from Sources/ZeplinKit/Models/Layers/ZeplinBoundingRectangle.swift rename to Sources/Models/Layers/ZeplinBoundingRectangle.swift index 1fb80bd..b4a3852 100644 --- a/Sources/ZeplinKit/Models/Layers/ZeplinBoundingRectangle.swift +++ b/Sources/Models/Layers/ZeplinBoundingRectangle.swift @@ -1,6 +1,6 @@ // // ZeplinBoundingRectangle.swift -// +// // // Created by Ilian Konchev on 13.12.21. // @@ -27,11 +27,12 @@ public struct ZeplinBoundingRectangle: Decodable, Hashable, Sendable { } public static func * (left: ZeplinBoundingRectangle, right: CGFloat) -> ZeplinBoundingRectangle { - return ZeplinBoundingRectangle(originY: left.absolute.originY * right, - originX: left.absolute.originX * right, - width: left.width * right, - height: left.height * right, - absolute: left.absolute) + return ZeplinBoundingRectangle( + originY: left.absolute.originY * right, + originX: left.absolute.originX * right, + width: left.width * right, + height: left.height * right, + absolute: left.absolute) } // swiftlint:disable shorthand_operator @@ -41,10 +42,10 @@ public struct ZeplinBoundingRectangle: Decodable, Hashable, Sendable { public static func == (lhs: Self, rhs: Self) -> Bool { return lhs.originX == rhs.originX - && lhs.originY == rhs.originY - && lhs.width == rhs.width - && lhs.height == rhs.height - && lhs.absolute == rhs.absolute + && lhs.originY == rhs.originY + && lhs.width == rhs.width + && lhs.height == rhs.height + && lhs.absolute == rhs.absolute } public var rectangle: CGRect { @@ -53,9 +54,9 @@ public struct ZeplinBoundingRectangle: Decodable, Hashable, Sendable { public func contains(_ point: CGPoint) -> Bool { return point.x >= absolute.originX - && point.x <= absolute.originX + width - && point.y >= absolute.originY - && point.y <= absolute.originY + height + && point.x <= absolute.originX + width + && point.y >= absolute.originY + && point.y <= absolute.originY + height } } diff --git a/Sources/ZeplinKit/Models/Layers/ZeplinFont.swift b/Sources/Models/Layers/ZeplinFont.swift similarity index 97% rename from Sources/ZeplinKit/Models/Layers/ZeplinFont.swift rename to Sources/Models/Layers/ZeplinFont.swift index faa9f58..bb70f74 100644 --- a/Sources/ZeplinKit/Models/Layers/ZeplinFont.swift +++ b/Sources/Models/Layers/ZeplinFont.swift @@ -1,6 +1,6 @@ // // File.swift -// +// // // Created by Ilian Konchev on 19.01.22. // diff --git a/Sources/ZeplinKit/Models/Layers/ZeplinGroupedAssetContent.swift b/Sources/Models/Layers/ZeplinGroupedAssetContent.swift similarity index 79% rename from Sources/ZeplinKit/Models/Layers/ZeplinGroupedAssetContent.swift rename to Sources/Models/Layers/ZeplinGroupedAssetContent.swift index a226a25..aa76034 100644 --- a/Sources/ZeplinKit/Models/Layers/ZeplinGroupedAssetContent.swift +++ b/Sources/Models/Layers/ZeplinGroupedAssetContent.swift @@ -8,9 +8,9 @@ import CoreGraphics import Fetcher import Foundation -import os.log import UIKit import Zip +import os.log public class ZeplinGroupedAssetContent: Hashable, Equatable, @unchecked Sendable { public let format: ZeplinAssetContent.Format @@ -36,10 +36,12 @@ public class ZeplinGroupedAssetContent: Hashable, Equatable, @unchecked Sendable return lhs.format == rhs.format && lhs.displayName == rhs.displayName } - public init(format: ZeplinAssetContent.Format, - items: [ZeplinAssetContent], - displayName: String, - layerName: String?) { + public init( + format: ZeplinAssetContent.Format, + items: [ZeplinAssetContent], + displayName: String, + layerName: String? + ) { let sortedAssets = items.sorted(by: { $0.format.rawValue < $1.format.rawValue }) self.format = format @@ -54,9 +56,10 @@ public class ZeplinGroupedAssetContent: Hashable, Equatable, @unchecked Sendable os_log("Unexpected amount of assets", log: .viewCycle, type: .debug) return nil } - return try await fetcher.download(by: item.url, - with: item.format.rawValue, - displayName: displayName) + return try await fetcher.download( + by: item.url, + with: item.format.rawValue, + displayName: displayName) } else { return try await fetchZIPURL(using: fetcher) } @@ -70,10 +73,11 @@ public class ZeplinGroupedAssetContent: Hashable, Equatable, @unchecked Sendable for assetContent in items where isAllowedDensity(assetContent.density) { fileName = displayName + "_" + format.rawValue group.addTask { - return try await fetcher.download(by: assetContent.url, - with: assetContent.format.rawValue, - displayName: self.displayName, - density: assetContent.density) + return try await fetcher.download( + by: assetContent.url, + with: assetContent.format.rawValue, + displayName: self.displayName, + density: assetContent.density) } } for try await fileURL in group { diff --git a/Sources/ZeplinKit/Models/Layers/ZeplinLayer.swift b/Sources/Models/Layers/ZeplinLayer.swift similarity index 99% rename from Sources/ZeplinKit/Models/Layers/ZeplinLayer.swift rename to Sources/Models/Layers/ZeplinLayer.swift index 772f4de..00890ac 100644 --- a/Sources/ZeplinKit/Models/Layers/ZeplinLayer.swift +++ b/Sources/Models/Layers/ZeplinLayer.swift @@ -1,6 +1,6 @@ // // ZeplinLayer.swift -// +// // // Created by Ilian Konchev on 26.01.22. // diff --git a/Sources/ZeplinKit/Models/Layers/ZeplinLayerBlur.swift b/Sources/Models/Layers/ZeplinLayerBlur.swift similarity index 98% rename from Sources/ZeplinKit/Models/Layers/ZeplinLayerBlur.swift rename to Sources/Models/Layers/ZeplinLayerBlur.swift index 05a28b0..8258f64 100644 --- a/Sources/ZeplinKit/Models/Layers/ZeplinLayerBlur.swift +++ b/Sources/Models/Layers/ZeplinLayerBlur.swift @@ -1,6 +1,6 @@ // // ZeplinLayerBlur.swift -// +// // // Created by Ann Kirillova on 12.01.2022. // diff --git a/Sources/ZeplinKit/Models/Layers/ZeplinLayerBorder.swift b/Sources/Models/Layers/ZeplinLayerBorder.swift similarity index 98% rename from Sources/ZeplinKit/Models/Layers/ZeplinLayerBorder.swift rename to Sources/Models/Layers/ZeplinLayerBorder.swift index b02c849..cf3bdd3 100644 --- a/Sources/ZeplinKit/Models/Layers/ZeplinLayerBorder.swift +++ b/Sources/Models/Layers/ZeplinLayerBorder.swift @@ -1,6 +1,6 @@ // // ZeplinLayerBorder.swift -// +// // // Created by Ann Kirillova on 12.01.2022. // diff --git a/Sources/ZeplinKit/Models/Layers/ZeplinLayerFill.swift b/Sources/Models/Layers/ZeplinLayerFill.swift similarity index 86% rename from Sources/ZeplinKit/Models/Layers/ZeplinLayerFill.swift rename to Sources/Models/Layers/ZeplinLayerFill.swift index 0b3bc0e..f83b1d7 100644 --- a/Sources/ZeplinKit/Models/Layers/ZeplinLayerFill.swift +++ b/Sources/Models/Layers/ZeplinLayerFill.swift @@ -1,6 +1,6 @@ // // ZeplinLayerFill.swift -// +// // // Created by Ann Kirillova on 12.01.2022. // @@ -52,18 +52,19 @@ public struct ZeplinColorData: Decodable, Hashable, Equatable, Sendable, CustomS /// `UIColor` representation of the color public var color: UIColor { - return UIColor(displayP3Red: CGFloat(red) / 255.0, - green: CGFloat(green) / 255.0, - blue: CGFloat(blue) / 255, - alpha: CGFloat(alpha)) + return UIColor( + displayP3Red: CGFloat(red) / 255.0, + green: CGFloat(green) / 255.0, + blue: CGFloat(blue) / 255, + alpha: CGFloat(alpha)) } public static func == (lhs: Self, rhs: Self) -> Bool { return lhs.red == rhs.red - && lhs.green == rhs.green - && lhs.blue == rhs.blue - && lhs.alpha == rhs.alpha - && lhs.sourceId == rhs.sourceId + && lhs.green == rhs.green + && lhs.blue == rhs.blue + && lhs.alpha == rhs.alpha + && lhs.sourceId == rhs.sourceId } public var description: String { diff --git a/Sources/ZeplinKit/Models/Layers/ZeplinLayerShadow.swift b/Sources/Models/Layers/ZeplinLayerShadow.swift similarity index 99% rename from Sources/ZeplinKit/Models/Layers/ZeplinLayerShadow.swift rename to Sources/Models/Layers/ZeplinLayerShadow.swift index 65fc071..db7f95a 100644 --- a/Sources/ZeplinKit/Models/Layers/ZeplinLayerShadow.swift +++ b/Sources/Models/Layers/ZeplinLayerShadow.swift @@ -1,6 +1,6 @@ // // ZeplinLayerShadow.swift -// +// // // Created by Ann Kirillova on 12.01.2022. // diff --git a/Sources/ZeplinKit/Models/Layers/ZeplinLayerTextStyle.swift b/Sources/Models/Layers/ZeplinLayerTextStyle.swift similarity index 58% rename from Sources/ZeplinKit/Models/Layers/ZeplinLayerTextStyle.swift rename to Sources/Models/Layers/ZeplinLayerTextStyle.swift index 6dec74c..617e645 100644 --- a/Sources/ZeplinKit/Models/Layers/ZeplinLayerTextStyle.swift +++ b/Sources/Models/Layers/ZeplinLayerTextStyle.swift @@ -1,6 +1,6 @@ // // ZeplinLayerTextStyle.swift -// +// // // Created by Ilian Konchev on 13.12.21. // @@ -23,15 +23,15 @@ public struct ZeplinTextStyleData: Decodable, Sendable { public let color: ZeplinColor? enum CodingKeys: String, CodingKey { - case postscriptName = "postscript_name" - case fontFamily = "font_family" - case fontSize = "font_size" - case fontWeight = "font_weight" - case fontStyle = "font_style" - case fontStretch = "font_stretch" - case lineHeight = "line_height" - case letterSpacing = "letter_spacing" - case textAlign = "text_align" - case color - } + case postscriptName = "postscript_name" + case fontFamily = "font_family" + case fontSize = "font_size" + case fontWeight = "font_weight" + case fontStyle = "font_style" + case fontStretch = "font_stretch" + case lineHeight = "line_height" + case letterSpacing = "letter_spacing" + case textAlign = "text_align" + case color + } } diff --git a/Sources/ZeplinKit/Models/Layers/ZeplinLayerWithAssets.swift b/Sources/Models/Layers/ZeplinLayerWithAssets.swift similarity index 99% rename from Sources/ZeplinKit/Models/Layers/ZeplinLayerWithAssets.swift rename to Sources/Models/Layers/ZeplinLayerWithAssets.swift index 6f4d33d..b2bcfb4 100644 --- a/Sources/ZeplinKit/Models/Layers/ZeplinLayerWithAssets.swift +++ b/Sources/Models/Layers/ZeplinLayerWithAssets.swift @@ -1,6 +1,6 @@ // // ZeplinLayerWithAssets.swift -// +// // // Created by Ilian Konchev on 27.01.22. // diff --git a/Sources/ZeplinKit/Models/Layers/ZeplinPosition.swift b/Sources/Models/Layers/ZeplinPosition.swift similarity index 99% rename from Sources/ZeplinKit/Models/Layers/ZeplinPosition.swift rename to Sources/Models/Layers/ZeplinPosition.swift index cc4e5cb..6e4ae8e 100644 --- a/Sources/ZeplinKit/Models/Layers/ZeplinPosition.swift +++ b/Sources/Models/Layers/ZeplinPosition.swift @@ -1,6 +1,6 @@ // // ZeplinPosition.swift -// +// // // Created by Ilian Konchev on 13.12.21. // diff --git a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationActor.swift b/Sources/Models/NotificationComponents/ZeplinNotificationActor.swift similarity index 98% rename from Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationActor.swift rename to Sources/Models/NotificationComponents/ZeplinNotificationActor.swift index 33a248f..2d9f337 100644 --- a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationActor.swift +++ b/Sources/Models/NotificationComponents/ZeplinNotificationActor.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationActor.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationColor.swift b/Sources/Models/NotificationComponents/ZeplinNotificationColor.swift similarity index 99% rename from Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationColor.swift rename to Sources/Models/NotificationComponents/ZeplinNotificationColor.swift index c1fad18..beae35e 100644 --- a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationColor.swift +++ b/Sources/Models/NotificationComponents/ZeplinNotificationColor.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationColor.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationComponent.swift b/Sources/Models/NotificationComponents/ZeplinNotificationComponent.swift similarity index 98% rename from Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationComponent.swift rename to Sources/Models/NotificationComponents/ZeplinNotificationComponent.swift index 9038d66..9b70b1a 100644 --- a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationComponent.swift +++ b/Sources/Models/NotificationComponents/ZeplinNotificationComponent.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationComponent.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationExtension.swift b/Sources/Models/NotificationComponents/ZeplinNotificationExtension.swift similarity index 98% rename from Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationExtension.swift rename to Sources/Models/NotificationComponents/ZeplinNotificationExtension.swift index 601f38c..4060e6b 100644 --- a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationExtension.swift +++ b/Sources/Models/NotificationComponents/ZeplinNotificationExtension.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationExtension.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationJiraIntegration.swift b/Sources/Models/NotificationComponents/ZeplinNotificationJiraIntegration.swift similarity index 98% rename from Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationJiraIntegration.swift rename to Sources/Models/NotificationComponents/ZeplinNotificationJiraIntegration.swift index 955d674..b83e8d8 100644 --- a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationJiraIntegration.swift +++ b/Sources/Models/NotificationComponents/ZeplinNotificationJiraIntegration.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationJiraIntegration.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationOrganization.swift b/Sources/Models/NotificationComponents/ZeplinNotificationOrganization.swift similarity index 98% rename from Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationOrganization.swift rename to Sources/Models/NotificationComponents/ZeplinNotificationOrganization.swift index 53ad03b..7f9d1c7 100644 --- a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationOrganization.swift +++ b/Sources/Models/NotificationComponents/ZeplinNotificationOrganization.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationOrganization.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationOrganizationMember.swift b/Sources/Models/NotificationComponents/ZeplinNotificationOrganizationMember.swift similarity index 98% rename from Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationOrganizationMember.swift rename to Sources/Models/NotificationComponents/ZeplinNotificationOrganizationMember.swift index 3ec8700..f4ab89a 100644 --- a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationOrganizationMember.swift +++ b/Sources/Models/NotificationComponents/ZeplinNotificationOrganizationMember.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationOrganizationMember.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationProject.swift b/Sources/Models/NotificationComponents/ZeplinNotificationProject.swift similarity index 99% rename from Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationProject.swift rename to Sources/Models/NotificationComponents/ZeplinNotificationProject.swift index 48b2109..d6898e5 100644 --- a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationProject.swift +++ b/Sources/Models/NotificationComponents/ZeplinNotificationProject.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationProject.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationScreen.swift b/Sources/Models/NotificationComponents/ZeplinNotificationScreen.swift similarity index 98% rename from Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationScreen.swift rename to Sources/Models/NotificationComponents/ZeplinNotificationScreen.swift index 2f0f9ed..aa81d2a 100644 --- a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationScreen.swift +++ b/Sources/Models/NotificationComponents/ZeplinNotificationScreen.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationScreen.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationScreenNote.swift b/Sources/Models/NotificationComponents/ZeplinNotificationScreenNote.swift similarity index 99% rename from Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationScreenNote.swift rename to Sources/Models/NotificationComponents/ZeplinNotificationScreenNote.swift index a881553..c133fab 100644 --- a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationScreenNote.swift +++ b/Sources/Models/NotificationComponents/ZeplinNotificationScreenNote.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationScreenNote.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationScreenNoteComment.swift b/Sources/Models/NotificationComponents/ZeplinNotificationScreenNoteComment.swift similarity index 98% rename from Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationScreenNoteComment.swift rename to Sources/Models/NotificationComponents/ZeplinNotificationScreenNoteComment.swift index 928a1df..d22cb0e 100644 --- a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationScreenNoteComment.swift +++ b/Sources/Models/NotificationComponents/ZeplinNotificationScreenNoteComment.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationScreenNoteComment.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationScreenSection.swift b/Sources/Models/NotificationComponents/ZeplinNotificationScreenSection.swift similarity index 98% rename from Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationScreenSection.swift rename to Sources/Models/NotificationComponents/ZeplinNotificationScreenSection.swift index 4af8070..a50c359 100644 --- a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationScreenSection.swift +++ b/Sources/Models/NotificationComponents/ZeplinNotificationScreenSection.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationScreenSection.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationScreenVersion.swift b/Sources/Models/NotificationComponents/ZeplinNotificationScreenVersion.swift similarity index 99% rename from Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationScreenVersion.swift rename to Sources/Models/NotificationComponents/ZeplinNotificationScreenVersion.swift index dadbd22..b80c3a2 100644 --- a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationScreenVersion.swift +++ b/Sources/Models/NotificationComponents/ZeplinNotificationScreenVersion.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationScreenVersion.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationSlackIntegration.swift b/Sources/Models/NotificationComponents/ZeplinNotificationSlackIntegration.swift similarity index 98% rename from Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationSlackIntegration.swift rename to Sources/Models/NotificationComponents/ZeplinNotificationSlackIntegration.swift index 554b509..be4ffb9 100644 --- a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationSlackIntegration.swift +++ b/Sources/Models/NotificationComponents/ZeplinNotificationSlackIntegration.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationSlackIntegration.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationSpacingToken.swift b/Sources/Models/NotificationComponents/ZeplinNotificationSpacingToken.swift similarity index 99% rename from Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationSpacingToken.swift rename to Sources/Models/NotificationComponents/ZeplinNotificationSpacingToken.swift index 917e7f6..6e8b8bb 100644 --- a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationSpacingToken.swift +++ b/Sources/Models/NotificationComponents/ZeplinNotificationSpacingToken.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationSpacingToken.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationStyleguide.swift b/Sources/Models/NotificationComponents/ZeplinNotificationStyleguide.swift similarity index 99% rename from Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationStyleguide.swift rename to Sources/Models/NotificationComponents/ZeplinNotificationStyleguide.swift index c5f9292..382835c 100644 --- a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationStyleguide.swift +++ b/Sources/Models/NotificationComponents/ZeplinNotificationStyleguide.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationStyleguide.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationTextStyle.swift b/Sources/Models/NotificationComponents/ZeplinNotificationTextStyle.swift similarity index 98% rename from Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationTextStyle.swift rename to Sources/Models/NotificationComponents/ZeplinNotificationTextStyle.swift index 2d75a1d..426bdd7 100644 --- a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationTextStyle.swift +++ b/Sources/Models/NotificationComponents/ZeplinNotificationTextStyle.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationTextStyle.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationUser.swift b/Sources/Models/NotificationComponents/ZeplinNotificationUser.swift similarity index 98% rename from Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationUser.swift rename to Sources/Models/NotificationComponents/ZeplinNotificationUser.swift index 7907474..f9fe265 100644 --- a/Sources/ZeplinKit/Models/NotificationComponents/ZeplinNotificationUser.swift +++ b/Sources/Models/NotificationComponents/ZeplinNotificationUser.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationUser.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/Requests/ZeplinAddCommentRequest.swift b/Sources/Models/Requests/ZeplinAddCommentRequest.swift similarity index 99% rename from Sources/ZeplinKit/Models/Requests/ZeplinAddCommentRequest.swift rename to Sources/Models/Requests/ZeplinAddCommentRequest.swift index 20a3a05..d788ae0 100644 --- a/Sources/ZeplinKit/Models/Requests/ZeplinAddCommentRequest.swift +++ b/Sources/Models/Requests/ZeplinAddCommentRequest.swift @@ -1,6 +1,6 @@ // // ZeplinAddCommentRequest.swift -// +// // // Created by Ilian Konchev on 17.07.20. // Copyright © 2020 Ilian Konchev. All rights reserved. diff --git a/Sources/ZeplinKit/Models/Requests/ZeplinAddNoteRequest.swift b/Sources/Models/Requests/ZeplinAddNoteRequest.swift similarity index 87% rename from Sources/ZeplinKit/Models/Requests/ZeplinAddNoteRequest.swift rename to Sources/Models/Requests/ZeplinAddNoteRequest.swift index 8ec4a88..0d766ec 100644 --- a/Sources/ZeplinKit/Models/Requests/ZeplinAddNoteRequest.swift +++ b/Sources/Models/Requests/ZeplinAddNoteRequest.swift @@ -1,6 +1,6 @@ // // ZeplinAddNoteRequest.swift -// +// // // Created by Ilian Konchev on 17.07.20. // Copyright © 2020 Ilian Konchev. All rights reserved. @@ -37,11 +37,13 @@ public struct ZeplinAddNoteRequest: Sendable { /// - position: Normalized position of the note /// - color: Note pin color /// - content: Content of the note - public init(project: ZeplinProject, - screen: ZeplinScreen, - position: ZeplinNotePosition, - color: String, - content: String) { + public init( + project: ZeplinProject, + screen: ZeplinScreen, + position: ZeplinNotePosition, + color: String, + content: String + ) { self.project = project self.screen = screen self.position = position diff --git a/Sources/ZeplinKit/Models/Requests/ZeplinUpdateCommentRequest.swift b/Sources/Models/Requests/ZeplinUpdateCommentRequest.swift similarity index 88% rename from Sources/ZeplinKit/Models/Requests/ZeplinUpdateCommentRequest.swift rename to Sources/Models/Requests/ZeplinUpdateCommentRequest.swift index 868126f..d72eb9b 100644 --- a/Sources/ZeplinKit/Models/Requests/ZeplinUpdateCommentRequest.swift +++ b/Sources/Models/Requests/ZeplinUpdateCommentRequest.swift @@ -1,6 +1,6 @@ // // ZeplinUpdateCommentRequest.swift -// +// // // Created by Ilian Konchev on 17.07.20. // Copyright © 2020 Ilian Konchev. All rights reserved. @@ -37,11 +37,13 @@ public struct ZeplinUpdateCommentRequest: Sendable { /// - note: Note that owns the comment /// - comment: The comment to update /// - content: The updated content - public init(project: ZeplinProject, - screen: ZeplinScreen, - note: ZeplinNote, - comment: ZeplinComment, - content: String) { + public init( + project: ZeplinProject, + screen: ZeplinScreen, + note: ZeplinNote, + comment: ZeplinComment, + content: String + ) { self.project = project self.screen = screen self.note = note diff --git a/Sources/ZeplinKit/Models/Requests/ZeplinUpdateNoteRequest.swift b/Sources/Models/Requests/ZeplinUpdateNoteRequest.swift similarity index 87% rename from Sources/ZeplinKit/Models/Requests/ZeplinUpdateNoteRequest.swift rename to Sources/Models/Requests/ZeplinUpdateNoteRequest.swift index 50be6f6..1410837 100644 --- a/Sources/ZeplinKit/Models/Requests/ZeplinUpdateNoteRequest.swift +++ b/Sources/Models/Requests/ZeplinUpdateNoteRequest.swift @@ -1,6 +1,6 @@ // // ZeplinAddNoteRequest.swift -// +// // // Created by Ilian Konchev on 17.07.20. // Copyright © 2020 Ilian Konchev. All rights reserved. @@ -37,11 +37,13 @@ public struct ZeplinUpdateNoteRequest: Sendable { /// - note: The note to update /// - position: The updated note position /// - status: The updated note status - public init(project: ZeplinProject, - screen: ZeplinScreen, - note: ZeplinNote, - position: ZeplinNotePosition, - status: String?) { + public init( + project: ZeplinProject, + screen: ZeplinScreen, + note: ZeplinNote, + position: ZeplinNotePosition, + status: String? + ) { self.project = project self.screen = screen self.note = note diff --git a/Sources/ZeplinKit/Models/Responses/ZeplinCreateCommentResponse.swift b/Sources/Models/Responses/ZeplinCreateCommentResponse.swift similarity index 98% rename from Sources/ZeplinKit/Models/Responses/ZeplinCreateCommentResponse.swift rename to Sources/Models/Responses/ZeplinCreateCommentResponse.swift index c03c636..04b14cd 100644 --- a/Sources/ZeplinKit/Models/Responses/ZeplinCreateCommentResponse.swift +++ b/Sources/Models/Responses/ZeplinCreateCommentResponse.swift @@ -1,6 +1,6 @@ // // ZeplinCreateCommentResponse.swift -// +// // // Created by Ilian Konchev on 13.02.20. // Copyright © 2020 Ilian Konchev. All rights reserved. diff --git a/Sources/ZeplinKit/Models/Responses/ZeplinCreateNoteResponse.swift b/Sources/Models/Responses/ZeplinCreateNoteResponse.swift similarity index 98% rename from Sources/ZeplinKit/Models/Responses/ZeplinCreateNoteResponse.swift rename to Sources/Models/Responses/ZeplinCreateNoteResponse.swift index c0b85ff..c9dea31 100644 --- a/Sources/ZeplinKit/Models/Responses/ZeplinCreateNoteResponse.swift +++ b/Sources/Models/Responses/ZeplinCreateNoteResponse.swift @@ -1,6 +1,6 @@ // // ZeplinCreateNoteResponse.swift -// +// // // Created by Ilian Konchev on 13.02.20. // Copyright © 2020 Ilian Konchev. All rights reserved. diff --git a/Sources/ZeplinKit/Models/Wrapper.swift b/Sources/Models/Wrapper.swift similarity index 99% rename from Sources/ZeplinKit/Models/Wrapper.swift rename to Sources/Models/Wrapper.swift index 022fc08..e1724aa 100644 --- a/Sources/ZeplinKit/Models/Wrapper.swift +++ b/Sources/Models/Wrapper.swift @@ -1,6 +1,6 @@ // // Wrapper.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/ZeplinColor.swift b/Sources/Models/ZeplinColor.swift similarity index 99% rename from Sources/ZeplinKit/Models/ZeplinColor.swift rename to Sources/Models/ZeplinColor.swift index 052cb4c..ff7d850 100644 --- a/Sources/ZeplinKit/Models/ZeplinColor.swift +++ b/Sources/Models/ZeplinColor.swift @@ -1,6 +1,6 @@ // // ZeplinColor.swift -// +// // // Created by Ilian Konchev on 13.02.20. // Copyright © 2020 Ilian Konchev. All rights reserved. diff --git a/Sources/ZeplinKit/Models/ZeplinComment.swift b/Sources/Models/ZeplinComment.swift similarity index 89% rename from Sources/ZeplinKit/Models/ZeplinComment.swift rename to Sources/Models/ZeplinComment.swift index 602226b..4fd65bc 100644 --- a/Sources/ZeplinKit/Models/ZeplinComment.swift +++ b/Sources/Models/ZeplinComment.swift @@ -1,6 +1,6 @@ // // ZeplinComment.swift -// +// // // Created by Ilian Konchev on 13.02.20. // Copyright © 2020 Ilian Konchev. All rights reserved. @@ -25,10 +25,12 @@ public struct ZeplinComment: Decodable, Hashable, Equatable, Sendable { /// - author: Author of the comment /// - content: Content of the comment /// - updated: The unix timestamp when the comment was updated - public init(id: String, - author: ZeplinUser, - content: String, - updated: Double) { + public init( + id: String, + author: ZeplinUser, + content: String, + updated: Double + ) { self.id = id self.author = author self.content = content diff --git a/Sources/ZeplinKit/Models/ZeplinGrid.swift b/Sources/Models/ZeplinGrid.swift similarity index 84% rename from Sources/ZeplinKit/Models/ZeplinGrid.swift rename to Sources/Models/ZeplinGrid.swift index 1775a9d..b089c5a 100644 --- a/Sources/ZeplinKit/Models/ZeplinGrid.swift +++ b/Sources/Models/ZeplinGrid.swift @@ -1,6 +1,6 @@ // // ZeplinGrid.swift -// +// // // Created by Ilian Konchev on 4.02.22. // @@ -26,8 +26,8 @@ public struct ZeplinHorizontalGrid: Decodable, Hashable, Equatable, Sendable { public static func == (lhs: Self, rhs: Self) -> Bool { return lhs.gutterHeight == rhs.gutterHeight - && lhs.numberOfRows == rhs.numberOfRows - && lhs.rowHeight == rhs.rowHeight + && lhs.numberOfRows == rhs.numberOfRows + && lhs.rowHeight == rhs.rowHeight } } @@ -53,9 +53,9 @@ public struct ZeplinVerticalGrid: Decodable, Hashable, Equatable, Sendable { public static func == (lhs: Self, rhs: Self) -> Bool { return lhs.gutterWidth == rhs.gutterWidth - && lhs.numberOfColumns == rhs.numberOfColumns - && lhs.columnWidth == rhs.columnWidth - && lhs.guttersOnOutside == rhs.guttersOnOutside + && lhs.numberOfColumns == rhs.numberOfColumns + && lhs.columnWidth == rhs.columnWidth + && lhs.guttersOnOutside == rhs.guttersOnOutside } } @@ -82,8 +82,8 @@ public struct ZeplinGrid: Decodable, Hashable, Equatable, Sendable { public static func == (lhs: Self, rhs: Self) -> Bool { return lhs.horizontalOffset == rhs.horizontalOffset - && lhs.verticalOffset == rhs.verticalOffset - && lhs.horizontalGrid == rhs.horizontalGrid - && lhs.verticalGrid == rhs.verticalGrid + && lhs.verticalOffset == rhs.verticalOffset + && lhs.horizontalGrid == rhs.horizontalGrid + && lhs.verticalGrid == rhs.verticalGrid } } diff --git a/Sources/ZeplinKit/Models/ZeplinImage.swift b/Sources/Models/ZeplinImage.swift similarity index 99% rename from Sources/ZeplinKit/Models/ZeplinImage.swift rename to Sources/Models/ZeplinImage.swift index 2c128ae..7568c36 100644 --- a/Sources/ZeplinKit/Models/ZeplinImage.swift +++ b/Sources/Models/ZeplinImage.swift @@ -1,6 +1,6 @@ // // ZeplinImage.swift -// +// // // Created by Ilian Konchev on 13.02.20. // Copyright © 2020 Ilian Konchev. All rights reserved. diff --git a/Sources/ZeplinKit/Models/ZeplinLink.swift b/Sources/Models/ZeplinLink.swift similarity index 99% rename from Sources/ZeplinKit/Models/ZeplinLink.swift rename to Sources/Models/ZeplinLink.swift index 5b44689..921fa53 100644 --- a/Sources/ZeplinKit/Models/ZeplinLink.swift +++ b/Sources/Models/ZeplinLink.swift @@ -1,6 +1,6 @@ // // ZeplinLink.swift -// +// // // Created by Ilian Konchev on 4.02.22. // diff --git a/Sources/ZeplinKit/Models/ZeplinLinkDestination.swift b/Sources/Models/ZeplinLinkDestination.swift similarity index 98% rename from Sources/ZeplinKit/Models/ZeplinLinkDestination.swift rename to Sources/Models/ZeplinLinkDestination.swift index 567b53a..aceac50 100644 --- a/Sources/ZeplinKit/Models/ZeplinLinkDestination.swift +++ b/Sources/Models/ZeplinLinkDestination.swift @@ -1,6 +1,6 @@ // // ZeplinLinkDestination.swift -// +// // // Created by Ilian Konchev on 4.02.22. // diff --git a/Sources/ZeplinKit/Models/ZeplinNamedColor.swift b/Sources/Models/ZeplinNamedColor.swift similarity index 91% rename from Sources/ZeplinKit/Models/ZeplinNamedColor.swift rename to Sources/Models/ZeplinNamedColor.swift index fb94095..d3679e0 100644 --- a/Sources/ZeplinKit/Models/ZeplinNamedColor.swift +++ b/Sources/Models/ZeplinNamedColor.swift @@ -1,6 +1,6 @@ // // ZeplinNamedColor.swift -// +// // // Created by Ilian Konchev on 7.02.20. // Copyright © 2020 Ilian Konchev. All rights reserved. @@ -12,7 +12,9 @@ import UIKit /// /// There are 7 predefined colors to use with the Zeplin API. These colors are used for the note pins public enum ZeplinNamedColor: String, Sendable { - case yellow, orange, peach, green, turquoise, cornflowerBlue = "cornflower_blue", deepPurple = "deep_purple" + case yellow, orange, peach, green, turquoise + case cornflowerBlue = "cornflower_blue" + case deepPurple = "deep_purple" public var color: UIColor { switch self { diff --git a/Sources/ZeplinKit/Models/ZeplinNote.swift b/Sources/Models/ZeplinNote.swift similarity index 79% rename from Sources/ZeplinKit/Models/ZeplinNote.swift rename to Sources/Models/ZeplinNote.swift index 0ab5438..dfb755c 100644 --- a/Sources/ZeplinKit/Models/ZeplinNote.swift +++ b/Sources/Models/ZeplinNote.swift @@ -1,6 +1,6 @@ // // ZeplinNote.swift -// +// // // Created by Ilian Konchev on 13.02.20. // Copyright © 2020 Ilian Konchev. All rights reserved. @@ -33,14 +33,16 @@ public struct ZeplinNote: Decodable, Hashable, Equatable, Sendable { /// The unix timestamp when the note was created public let created: Double - public init(id: String, - order: String, - color: ZeplinColor, - position: ZeplinNotePosition, - comments: [ZeplinComment], - creator: ZeplinUser, - status: Status, - created: Double) { + public init( + id: String, + order: String, + color: ZeplinColor, + position: ZeplinNotePosition, + comments: [ZeplinComment], + creator: ZeplinUser, + status: Status, + created: Double + ) { self.id = id self.order = order self.color = color @@ -54,7 +56,8 @@ public struct ZeplinNote: Decodable, Hashable, Equatable, Sendable { /// `UIColor` representation of the note pin color public var pinColor: UIColor { guard let colorName = color.name, let zeplinColor = ZeplinNamedColor(rawValue: colorName) else { - return UIColor(displayP3Red: CGFloat(color.red) / 255, green: CGFloat(color.green) / 255, blue: CGFloat(color.blue) / 255, alpha: 1.0) + return UIColor( + displayP3Red: CGFloat(color.red) / 255, green: CGFloat(color.green) / 255, blue: CGFloat(color.blue) / 255, alpha: 1.0) } return zeplinColor.color } diff --git a/Sources/ZeplinKit/Models/ZeplinNotePosition.swift b/Sources/Models/ZeplinNotePosition.swift similarity index 99% rename from Sources/ZeplinKit/Models/ZeplinNotePosition.swift rename to Sources/Models/ZeplinNotePosition.swift index 0444550..f46d9e5 100644 --- a/Sources/ZeplinKit/Models/ZeplinNotePosition.swift +++ b/Sources/Models/ZeplinNotePosition.swift @@ -1,6 +1,6 @@ // // ZeplinNotePosition.swift -// +// // // Created by Ilian Konchev on 13.02.20. // Copyright © 2020 Ilian Konchev. All rights reserved. diff --git a/Sources/ZeplinKit/Models/ZeplinNotification.swift b/Sources/Models/ZeplinNotification.swift similarity index 90% rename from Sources/ZeplinKit/Models/ZeplinNotification.swift rename to Sources/Models/ZeplinNotification.swift index 54a5256..2362f5e 100644 --- a/Sources/ZeplinKit/Models/ZeplinNotification.swift +++ b/Sources/Models/ZeplinNotification.swift @@ -1,6 +1,6 @@ // // ZeplinNotification.swift -// +// // // Created by Ilian Konchev on 4.11.21. // @@ -42,15 +42,17 @@ public struct ZeplinNotification: Codable, Hashable, Identifiable, Equatable, Se case isRead = "is_read" } - public init(id: String, - created: Double, - updated: Double?, - isRead: Bool, - type: String, - action: ZeplinNotificationAction?, - actor: ZeplinNotificationActor, - resource: ZeplinNotificationResource?, - context: ZeplinNotificationContext?) { + public init( + id: String, + created: Double, + updated: Double?, + isRead: Bool, + type: String, + action: ZeplinNotificationAction?, + actor: ZeplinNotificationActor, + resource: ZeplinNotificationResource?, + context: ZeplinNotificationContext? + ) { self.id = id self.created = created self.updated = updated @@ -66,7 +68,7 @@ public struct ZeplinNotification: Codable, Hashable, Identifiable, Equatable, Se public var actionDescription: String { let resourceDescription = resource?.description ?? "" guard let actionDescription = action?.description else { return resourceDescription } - return [actionDescription, resourceDescription].filter { !$0.isEmpty } .joined(separator: " ") + return [actionDescription, resourceDescription].filter { !$0.isEmpty }.joined(separator: " ") } /// User-friendly representation of the context that the notification is triggered from (e.g. _Welcome screen - @@ -88,8 +90,7 @@ public struct ZeplinNotification: Codable, Hashable, Identifiable, Equatable, Se /// A flag that determines whether the notification has an attachment /// (an image to complement the presentation) or not public var hasAttachment: Bool { - return (resource?.type == .version && resource?.extra as? ZeplinNotificationScreenVersion != nil) || - context?.version?.extra != nil + return (resource?.type == .version && resource?.extra as? ZeplinNotificationScreenVersion != nil) || context?.version?.extra != nil } /// User-friendly representation of the screen version related to the notification, if available diff --git a/Sources/ZeplinKit/Models/ZeplinNotificationAction.swift b/Sources/Models/ZeplinNotificationAction.swift similarity index 99% rename from Sources/ZeplinKit/Models/ZeplinNotificationAction.swift rename to Sources/Models/ZeplinNotificationAction.swift index 6de937b..1267201 100644 --- a/Sources/ZeplinKit/Models/ZeplinNotificationAction.swift +++ b/Sources/Models/ZeplinNotificationAction.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationAction.swift -// +// // // Created by Ilian Konchev on 29.01.20. // Copyright © 2020 Ilian Konchev. All rights reserved. diff --git a/Sources/ZeplinKit/Models/ZeplinNotificationContext.swift b/Sources/Models/ZeplinNotificationContext.swift similarity index 98% rename from Sources/ZeplinKit/Models/ZeplinNotificationContext.swift rename to Sources/Models/ZeplinNotificationContext.swift index 3705657..cb80825 100644 --- a/Sources/ZeplinKit/Models/ZeplinNotificationContext.swift +++ b/Sources/Models/ZeplinNotificationContext.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationContext.swift -// +// // // Created by Ilian Konchev on 29.01.21. // Copyright © 2021 Ilian Konchev. All rights reserved. @@ -45,7 +45,7 @@ public struct ZeplinNotificationContext: Codable, CustomStringConvertible, Senda section?.description, styleguide?.description, project?.description, - organization?.description + organization?.description, ] return components.compactMap { $0 }.joined(separator: " ◦ ") diff --git a/Sources/ZeplinKit/Models/ZeplinNotificationRepresentation.swift b/Sources/Models/ZeplinNotificationRepresentation.swift similarity index 87% rename from Sources/ZeplinKit/Models/ZeplinNotificationRepresentation.swift rename to Sources/Models/ZeplinNotificationRepresentation.swift index bf416f7..9c4b690 100644 --- a/Sources/ZeplinKit/Models/ZeplinNotificationRepresentation.swift +++ b/Sources/Models/ZeplinNotificationRepresentation.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationRepresentation.swift -// +// // // Created by Ilian Konchev on 4.11.21. // @@ -31,8 +31,8 @@ public struct ZeplinNotificationRepresentation: Hashable, Identifiable, Equatabl public static func == (lhs: Self, rhs: Self) -> Bool { return lhs.id == rhs.id - && lhs.created == rhs.created - && lhs.lastUpdated == rhs.lastUpdated - && lhs.isRead == rhs.isRead + && lhs.created == rhs.created + && lhs.lastUpdated == rhs.lastUpdated + && lhs.isRead == rhs.isRead } } diff --git a/Sources/ZeplinKit/Models/ZeplinNotificationResource.swift b/Sources/Models/ZeplinNotificationResource.swift similarity index 99% rename from Sources/ZeplinKit/Models/ZeplinNotificationResource.swift rename to Sources/Models/ZeplinNotificationResource.swift index e5d9c8f..de6911f 100644 --- a/Sources/ZeplinKit/Models/ZeplinNotificationResource.swift +++ b/Sources/Models/ZeplinNotificationResource.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationResource.swift -// +// // // Created by Ilian Konchev on 29.01.21. // Copyright © 2021 Ilian Konchev. All rights reserved. diff --git a/Sources/ZeplinKit/Models/ZeplinNotificationResourceType.swift b/Sources/Models/ZeplinNotificationResourceType.swift similarity index 99% rename from Sources/ZeplinKit/Models/ZeplinNotificationResourceType.swift rename to Sources/Models/ZeplinNotificationResourceType.swift index ae800fc..226fb1f 100644 --- a/Sources/ZeplinKit/Models/ZeplinNotificationResourceType.swift +++ b/Sources/Models/ZeplinNotificationResourceType.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationResourceType.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/ZeplinNotificationUserInfo.swift b/Sources/Models/ZeplinNotificationUserInfo.swift similarity index 98% rename from Sources/ZeplinKit/Models/ZeplinNotificationUserInfo.swift rename to Sources/Models/ZeplinNotificationUserInfo.swift index 9525c01..f777155 100644 --- a/Sources/ZeplinKit/Models/ZeplinNotificationUserInfo.swift +++ b/Sources/Models/ZeplinNotificationUserInfo.swift @@ -1,6 +1,6 @@ // // ZeplinNotificationUserInfo.swift -// +// // // Created by Ilian Konchev on 4.11.21. // diff --git a/Sources/ZeplinKit/Models/ZeplinOrganizationMember.swift b/Sources/Models/ZeplinOrganizationMember.swift similarity index 77% rename from Sources/ZeplinKit/Models/ZeplinOrganizationMember.swift rename to Sources/Models/ZeplinOrganizationMember.swift index a59a622..07a6572 100644 --- a/Sources/ZeplinKit/Models/ZeplinOrganizationMember.swift +++ b/Sources/Models/ZeplinOrganizationMember.swift @@ -1,6 +1,6 @@ // // ZeplinOrganizationMember.swift -// +// // // Created by Ilian Konchev on 7.02.22. // @@ -21,9 +21,9 @@ public struct ZeplinOrganizationMember: Decodable, Hashable, Equatable, Sendable public static func == (lhs: Self, rhs: Self) -> Bool { return lhs.user == rhs.user - && lhs.role == rhs.role - && lhs.restricted == rhs.restricted - && lhs.tags == rhs.tags - && lhs.invited == rhs.invited + && lhs.role == rhs.role + && lhs.restricted == rhs.restricted + && lhs.tags == rhs.tags + && lhs.invited == rhs.invited } } diff --git a/Sources/ZeplinKit/Models/ZeplinOrganizationSummary.swift b/Sources/Models/ZeplinOrganizationSummary.swift similarity index 99% rename from Sources/ZeplinKit/Models/ZeplinOrganizationSummary.swift rename to Sources/Models/ZeplinOrganizationSummary.swift index c974995..9473251 100644 --- a/Sources/ZeplinKit/Models/ZeplinOrganizationSummary.swift +++ b/Sources/Models/ZeplinOrganizationSummary.swift @@ -1,6 +1,6 @@ // // ZeplinOrganizationSummary.swift -// +// // // Created by Ilian Konchev on 12.02.21. // Copyright © 2021 Ilian Konchev. All rights reserved. diff --git a/Sources/ZeplinKit/Models/ZeplinProject.swift b/Sources/Models/ZeplinProject.swift similarity index 93% rename from Sources/ZeplinKit/Models/ZeplinProject.swift rename to Sources/Models/ZeplinProject.swift index 310f598..576cc93 100644 --- a/Sources/ZeplinKit/Models/ZeplinProject.swift +++ b/Sources/Models/ZeplinProject.swift @@ -1,6 +1,6 @@ // // ZeplinProject.swift -// +// // // Created by Ilian Konchev on 13.02.20. // Copyright © 2020 Ilian Konchev. All rights reserved. @@ -91,17 +91,17 @@ public struct ZeplinProject: Decodable, Hashable, Identifiable, Equatable, Senda } } -public extension ZeplinProject { +extension ZeplinProject { /// Identifier for the user activity type - static let domainIdentifier = "io.snappmobile.zeplin.project" + public static let domainIdentifier = "io.snappmobile.zeplin.project" /// The user info assigned with the user activiy - var userActivityUserInfo: [AnyHashable: Any] { + public var userActivityUserInfo: [AnyHashable: Any] { return ["id": id] } /// The attribute set that describe the searchable item for the project - var attributeSet: CSSearchableItemAttributeSet { + public var attributeSet: CSSearchableItemAttributeSet { let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeBookmark as String) attributeSet.title = name attributeSet.contentDescription = "\(platform.description) project" @@ -109,7 +109,7 @@ public extension ZeplinProject { } /// The user activity that gets triggered when the user engages the searchable item - var userActivity: NSUserActivity { + public var userActivity: NSUserActivity { let activity = NSUserActivity(activityType: ZeplinProject.domainIdentifier) activity.title = name activity.contentAttributeSet = attributeSet diff --git a/Sources/ZeplinKit/Models/ZeplinProjectMember.swift b/Sources/Models/ZeplinProjectMember.swift similarity index 99% rename from Sources/ZeplinKit/Models/ZeplinProjectMember.swift rename to Sources/Models/ZeplinProjectMember.swift index ce80e08..7a87c90 100644 --- a/Sources/ZeplinKit/Models/ZeplinProjectMember.swift +++ b/Sources/Models/ZeplinProjectMember.swift @@ -1,6 +1,6 @@ // // ZeplinProjectMember.swift -// +// // // Created by Ilian Konchev on 6.03.20. // Copyright © 2020 Ilian Konchev. All rights reserved. diff --git a/Sources/ZeplinKit/Models/ZeplinRectangle.swift b/Sources/Models/ZeplinRectangle.swift similarity index 85% rename from Sources/ZeplinKit/Models/ZeplinRectangle.swift rename to Sources/Models/ZeplinRectangle.swift index 87eeae1..c1d5561 100644 --- a/Sources/ZeplinKit/Models/ZeplinRectangle.swift +++ b/Sources/Models/ZeplinRectangle.swift @@ -1,6 +1,6 @@ // // ZeplinRectangle.swift -// +// // // Created by Ilian Konchev on 4.02.22. // @@ -28,8 +28,8 @@ public struct ZeplinRectangle: Decodable, Hashable, Equatable, Sendable { public static func == (lhs: Self, rhs: Self) -> Bool { return lhs.originX == rhs.originX - && lhs.originY == rhs.originY - && lhs.width == rhs.width - && lhs.height == rhs.height + && lhs.originY == rhs.originY + && lhs.width == rhs.width + && lhs.height == rhs.height } } diff --git a/Sources/ZeplinKit/Models/ZeplinRole.swift b/Sources/Models/ZeplinRole.swift similarity index 99% rename from Sources/ZeplinKit/Models/ZeplinRole.swift rename to Sources/Models/ZeplinRole.swift index de1b67c..a1760d3 100644 --- a/Sources/ZeplinKit/Models/ZeplinRole.swift +++ b/Sources/Models/ZeplinRole.swift @@ -1,6 +1,6 @@ // // ZeplinRole.swift -// +// // // Created by Ilian Konchev on 6.03.20. // Copyright © 2020 Ilian Konchev. All rights reserved. diff --git a/Sources/ZeplinKit/Models/ZeplinScreen.swift b/Sources/Models/ZeplinScreen.swift similarity index 99% rename from Sources/ZeplinKit/Models/ZeplinScreen.swift rename to Sources/Models/ZeplinScreen.swift index 6c89f05..ede203f 100644 --- a/Sources/ZeplinKit/Models/ZeplinScreen.swift +++ b/Sources/Models/ZeplinScreen.swift @@ -1,6 +1,6 @@ // // ZeplinScreen.swift -// +// // // Created by Ilian Konchev on 13.02.20. // Copyright © 2020 Ilian Konchev. All rights reserved. diff --git a/Sources/ZeplinKit/Models/ZeplinScreenVersion.swift b/Sources/Models/ZeplinScreenVersion.swift similarity index 100% rename from Sources/ZeplinKit/Models/ZeplinScreenVersion.swift rename to Sources/Models/ZeplinScreenVersion.swift diff --git a/Sources/ZeplinKit/Models/ZeplinScreenVersionCommit.swift b/Sources/Models/ZeplinScreenVersionCommit.swift similarity index 99% rename from Sources/ZeplinKit/Models/ZeplinScreenVersionCommit.swift rename to Sources/Models/ZeplinScreenVersionCommit.swift index c4aa000..0487746 100644 --- a/Sources/ZeplinKit/Models/ZeplinScreenVersionCommit.swift +++ b/Sources/Models/ZeplinScreenVersionCommit.swift @@ -1,6 +1,6 @@ // // ZeplinScreenVersionCommit.swift -// +// // // Created by Ilian Konchev on 27.02.20. // Copyright © 2020 Ilian Konchev. All rights reserved. diff --git a/Sources/ZeplinKit/Models/ZeplinScreenVersionSummary.swift b/Sources/Models/ZeplinScreenVersionSummary.swift similarity index 99% rename from Sources/ZeplinKit/Models/ZeplinScreenVersionSummary.swift rename to Sources/Models/ZeplinScreenVersionSummary.swift index 558e367..981344f 100644 --- a/Sources/ZeplinKit/Models/ZeplinScreenVersionSummary.swift +++ b/Sources/Models/ZeplinScreenVersionSummary.swift @@ -1,6 +1,6 @@ // // ZeplinScreenVersionSummary.swift -// +// // // Created by Ilian Konchev on 27.02.20. // Copyright © 2020 Ilian Konchev. All rights reserved. diff --git a/Sources/ZeplinKit/Models/ZeplinSection.swift b/Sources/Models/ZeplinSection.swift similarity index 99% rename from Sources/ZeplinKit/Models/ZeplinSection.swift rename to Sources/Models/ZeplinSection.swift index 15aa4d3..6490fa9 100644 --- a/Sources/ZeplinKit/Models/ZeplinSection.swift +++ b/Sources/Models/ZeplinSection.swift @@ -1,6 +1,6 @@ // // ZeplinSection.swift -// +// // // Created by Ilian Konchev on 13.02.20. // Copyright © 2020 Ilian Konchev. All rights reserved. diff --git a/Sources/ZeplinKit/Models/ZeplinUser.swift b/Sources/Models/ZeplinUser.swift similarity index 87% rename from Sources/ZeplinKit/Models/ZeplinUser.swift rename to Sources/Models/ZeplinUser.swift index cab5347..f6e35ed 100644 --- a/Sources/ZeplinKit/Models/ZeplinUser.swift +++ b/Sources/Models/ZeplinUser.swift @@ -1,6 +1,6 @@ // // ZeplinUser.swift -// +// // // Created by Ilian Konchev on 13.02.20. // Copyright © 2020 Ilian Konchev. All rights reserved. @@ -39,6 +39,10 @@ public struct ZeplinUser: Codable, Equatable, Sendable { } public static func == (lhs: Self, rhs: Self) -> Bool { - return lhs.id == rhs.id && lhs.email == rhs.email && lhs.username == rhs.username && lhs.emotar == rhs.emotar && lhs.avatarURL == rhs.avatarURL + return lhs.id == rhs.id + && lhs.email == rhs.email + && lhs.username == rhs.username + && lhs.emotar == rhs.emotar + && lhs.avatarURL == rhs.avatarURL } } diff --git a/Sources/ZeplinKit/Networking/ZeplinAPIURL.swift b/Sources/Networking/ZeplinAPIURL.swift similarity index 77% rename from Sources/ZeplinKit/Networking/ZeplinAPIURL.swift rename to Sources/Networking/ZeplinAPIURL.swift index 858fa28..22ea17e 100644 --- a/Sources/ZeplinKit/Networking/ZeplinAPIURL.swift +++ b/Sources/Networking/ZeplinAPIURL.swift @@ -1,6 +1,6 @@ // // ZeplinAPIURL.swift -// +// // // Created by Ilian Konchev on 13.02.20. // Copyright © 2020 Ilian Konchev. All rights reserved. @@ -47,48 +47,48 @@ public enum ZeplinAPIURL: APIURL { switch self { case .getToken, .refreshToken: return "/oauth/token" - case let .getProjects(limit, offset): + case .getProjects(let limit, let offset): return "/projects?limit=\(limit)&offset=\(offset)" - case let .getProject(projectId): + case .getProject(let projectId): return "/projects/\(projectId)" - case let .getProjectMembers(project, limit, offset): + case .getProjectMembers(let project, let limit, let offset): return "/projects/\(project.id)/members?limit=\(limit)&offset=\(offset)" - case let .inviteMember(organization, _): + case .inviteMember(let organization, _): return "/organizations/\(organization.id)/members" - case let .updateMemberRole(organization, member, _): + case .updateMemberRole(let organization, let member, _): return "/organizations/\(organization.id)/members/\(member.user.id)" - case let .removeMember(organization, member): + case .removeMember(let organization, let member): return "/organizations/\(organization.id)/members/\(member.user.id)" - case let .getScreens(project, limit, offset): + case .getScreens(let project, let limit, let offset): return "/projects/\(project.id)/screens?sort=section&limit=\(limit)&offset=\(offset)" - case let .getScreen(projectId, screenId): + case .getScreen(let projectId, let screenId): return "/projects/\(projectId)/screens/\(screenId)" - case let .getSections(project, limit, offset): + case .getSections(let project, let limit, let offset): return "/projects/\(project.id)/screen_sections?limit=\(limit)&offset=\(offset)" - case let .getScreenVersions(project, screen, limit, offset): + case .getScreenVersions(let project, let screen, let limit, let offset): return "/projects/\(project.id)/screens/\(screen.id)/versions?limit=\(limit)&offset=\(offset)" - case let .getNotes(project, screen, limit, offset): + case .getNotes(let project, let screen, let limit, let offset): return "/projects/\(project.id)/screens/\(screen.id)/notes?limit=\(limit)&offset=\(offset)" - case let .getNote(project, screen, noteId): + case .getNote(let project, let screen, let noteId): return "/projects/\(project.id)/screens/\(screen.id)/notes/\(noteId)" - case let .addNote(request): + case .addNote(let request): return "/projects/\(request.project.id)/screens/\(request.screen.id)/notes" - case let .getNotifications(limit, offset): + case .getNotifications(let limit, let offset): return "/users/me/notifications?limit=\(limit)&offset=\(offset)" - case let .flagNotificationAsRead(id): + case .flagNotificationAsRead(let id): return "/users/me/notifications/\(id)" - case let .updateReadState(representations, _): + case .updateReadState(let representations, _): let ids = representations.map(\.id).joined(separator: "&id=") return "/users/me/notifications?id=\(ids)" - case let .updateNote(request): + case .updateNote(let request): return "/projects/\(request.project.id)/screens/\(request.screen.id)/notes/\(request.note.id)" - case let .addComment(request): + case .addComment(let request): return "/projects/\(request.project.id)/screens/\(request.screen.id)/notes/\(request.note.id)/comments" - case let .updateComment(request): + case .updateComment(let request): return "/projects/\(request.project.id)/screens/\(request.screen.id)/notes/\(request.note.id)/comments/\(request.comment.id)" case .getCurrentUser: return "/users/me" - case let .getScreenVersion(projectId, screenId, versionId): + case .getScreenVersion(let projectId, let screenId, let versionId): return "/projects/\(projectId)/screens/\(screenId)/versions/\(versionId)" } } @@ -109,13 +109,13 @@ public enum ZeplinAPIURL: APIURL { // swiftlint:disable cyclomatic_complexity function_body_length public func bodyParams(token: Token?) -> [String: Any]? { switch self { - case let .getToken(code, configuration): + case .getToken(let code, let configuration): return [ "client_id": configuration.clientId, "client_secret": configuration.clientSecret, "redirect_uri": configuration.redirectURI, "grant_type": "authorization_code", - "code": code + "code": code, ] case .refreshToken(let configuration): guard let token = token else { return nil } @@ -123,49 +123,49 @@ public enum ZeplinAPIURL: APIURL { "client_id": configuration.clientId, "client_secret": configuration.clientSecret, "refresh_token": token.refreshToken, - "grant_type": "refresh_token" + "grant_type": "refresh_token", ] - case let .addComment(request): + case .addComment(let request): return [ "content": request.content ] - case let .updateComment(request): + case .updateComment(let request): return [ "content": request.content ] - case let .addNote(request): + case .addNote(let request): return [ "content": request.content, "position": [ "x": request.position.originX, - "y": request.position.originY + "y": request.position.originY, ], - "color": request.color + "color": request.color, ] - case let .updateNote(request): + case .updateNote(let request): return [ "status": request.status ?? request.note.status, "position": [ "x": request.position.originX, - "y": request.position.originY + "y": request.position.originY, ], - "color": request.note.color.name ?? "" + "color": request.note.color.name ?? "", ] case .flagNotificationAsRead: return [ "is_read": true ] - case let .updateReadState(_, isRead): + case .updateReadState(_, let isRead): return [ "is_read": isRead ] - case let .inviteMember(_, handle): + case .inviteMember(_, let handle): return [ "handle": handle, "role": "member", - "restricted": true + "restricted": true, ] - case let .updateMemberRole(_, _, role): + case .updateMemberRole(_, _, let role): return [ "role": role.rawValue ] @@ -191,7 +191,8 @@ public enum ZeplinAPIURL: APIURL { } if let bodyParams = bodyParams(token: token), - let jsonData = try? JSONSerialization.data(withJSONObject: bodyParams) { + let jsonData = try? JSONSerialization.data(withJSONObject: bodyParams) + { request.httpBody = jsonData } diff --git a/Sources/ZeplinKit/Protocols/ZeplinColorRepresentable.swift b/Sources/Protocols/ZeplinColorRepresentable.swift similarity index 98% rename from Sources/ZeplinKit/Protocols/ZeplinColorRepresentable.swift rename to Sources/Protocols/ZeplinColorRepresentable.swift index 1486976..03c58af 100644 --- a/Sources/ZeplinKit/Protocols/ZeplinColorRepresentable.swift +++ b/Sources/Protocols/ZeplinColorRepresentable.swift @@ -1,6 +1,6 @@ // // ZeplinColorRepresentable.swift -// +// // // Created by Ilian Konchev on 22.01.22. // diff --git a/Sources/ZeplinKit/ZeplinKit.docc/Resources/ZeplinKit-logo.png b/Sources/ZeplinKit.docc/Resources/ZeplinKit-logo.png similarity index 100% rename from Sources/ZeplinKit/ZeplinKit.docc/Resources/ZeplinKit-logo.png rename to Sources/ZeplinKit.docc/Resources/ZeplinKit-logo.png diff --git a/Sources/ZeplinKit/ZeplinKit.docc/Resources/ZeplinKit-logo@2x.png b/Sources/ZeplinKit.docc/Resources/ZeplinKit-logo@2x.png similarity index 100% rename from Sources/ZeplinKit/ZeplinKit.docc/Resources/ZeplinKit-logo@2x.png rename to Sources/ZeplinKit.docc/Resources/ZeplinKit-logo@2x.png diff --git a/Sources/ZeplinKit/ZeplinKit.docc/Resources/ZeplinKit-logo@3x.png b/Sources/ZeplinKit.docc/Resources/ZeplinKit-logo@3x.png similarity index 100% rename from Sources/ZeplinKit/ZeplinKit.docc/Resources/ZeplinKit-logo@3x.png rename to Sources/ZeplinKit.docc/Resources/ZeplinKit-logo@3x.png diff --git a/Sources/ZeplinKit/ZeplinKit.docc/ZeplinKit.md b/Sources/ZeplinKit.docc/ZeplinKit.md similarity index 62% rename from Sources/ZeplinKit/ZeplinKit.docc/ZeplinKit.md rename to Sources/ZeplinKit.docc/ZeplinKit.md index 7dd3f4f..b20b916 100644 --- a/Sources/ZeplinKit/ZeplinKit.docc/ZeplinKit.md +++ b/Sources/ZeplinKit.docc/ZeplinKit.md @@ -1,16 +1,18 @@ # ``ZeplinKit`` +@Metadata { + @PageImage(purpose: icon, source:"ZeplinKit-logo") +} + Swift client library for the public Zeplin API. ## Overview -![ZeplinKit logo](ZeplinKit-logo.png) - ZeplinKit is a collection of data models and preconfigured API URLs to consume the public Zeplin API. Adding ZeplinKit to your app gives you a flexible client for consuming the Zeplin API that fits in any workflow. Zeplin kit utilizes `Fetcher` - a tiny network client for fetching data off the web. The client exposes both a `Combine` publisher for the desired Zeplin endpoints and a Swift Concurrency interface (where available). -The the core of the ZeplinKit library is ``ZeplinKit/ZeplinAPIURL`` - an enumeration of the Zeplin API endpoints which +The core of the ZeplinKit library is ``ZeplinKit/ZeplinAPIURL`` - an enumeration of the Zeplin API endpoints which encapsulates the parameters needed to do the API calls. The enum values should be passed to the `Fetcher` client after populating the associated values where needed. @@ -18,22 +20,24 @@ For example, if you want to fetch the first 10 projects for your account, you wo ```swift import ZeplinKit -// init the fetcher with an environment -let fetcher = Fetcher(environment: ...) -// prepare the APIURL + +let fetcher = Fetcher( + environment: .production, + accessToken: "your_zeplin_access_token" +) + let url = ZeplinAPIURL.getProjects(10, 0) + do { - // execute the request and get the list of projects let projects: [ZeplinProject] = try await fetcher.fetch(url) - // do something with the projects -} catch let error { - // handle any possible error - print("Error:", error.localizedDescription) + // Handle projects +} catch { + print("Failed to fetch projects: \(error.localizedDescription)") } ``` ## Topics -### Group +### API -- ``Symbol`` +- ``ZeplinAPIURL`` diff --git a/Tests/ZeplinKitTests/MemberTests.swift b/Tests/MemberTests.swift similarity index 99% rename from Tests/ZeplinKitTests/MemberTests.swift rename to Tests/MemberTests.swift index 60695e9..9947f98 100644 --- a/Tests/ZeplinKitTests/MemberTests.swift +++ b/Tests/MemberTests.swift @@ -1,12 +1,13 @@ // // MemberTests.swift -// +// // // Created by Ilian Konchev on 8.02.22. // -@testable import Fetcher import XCTest + +@testable import Fetcher @testable import ZeplinKit final class MemberTests: XCTestCase { diff --git a/Tests/ZeplinKitTests/NoteTests.swift b/Tests/NoteTests.swift similarity index 84% rename from Tests/ZeplinKitTests/NoteTests.swift rename to Tests/NoteTests.swift index dda4d72..656f5b7 100644 --- a/Tests/ZeplinKitTests/NoteTests.swift +++ b/Tests/NoteTests.swift @@ -1,12 +1,13 @@ // // NoteTests.swift -// +// // // Created by Ilian Konchev on 8.02.22. // -@testable import Fetcher import XCTest + +@testable import Fetcher @testable import ZeplinKit final class NoteTests: XCTestCase { @@ -22,7 +23,10 @@ final class NoteTests: XCTestCase { let response: [ZeplinNote] = try await fetcher.fetch(sut.apiURL) // THEN - XCTAssertEqual(sut.apiURL.url?.absoluteString, "https://api.zeplin.dev/v1/projects/\(projectId)/screens/\(screenId)/notes?limit=1&offset=0") + XCTAssertEqual( + sut.apiURL.url?.absoluteString, + "https://api.zeplin.dev/v1/projects/\(projectId)/screens/\(screenId)/notes?limit=1&offset=0" + ) XCTAssertEqual(sut.apiURL.requestMethod, "GET") XCTAssertEqual(response.count, 1) guard let note = response.first else { @@ -42,7 +46,10 @@ final class NoteTests: XCTestCase { let note: ZeplinNote = try await fetcher.fetch(sut.apiURL) // THEN - XCTAssertEqual(sut.apiURL.url?.absoluteString, "https://api.zeplin.dev/v1/projects/\(projectId)/screens/\(screenId)/notes/\(noteId)") + XCTAssertEqual( + sut.apiURL.url?.absoluteString, + "https://api.zeplin.dev/v1/projects/\(projectId)/screens/\(screenId)/notes/\(noteId)" + ) XCTAssertEqual(sut.apiURL.requestMethod, "GET") SharedAssertions.assertNote(note) } @@ -59,7 +66,8 @@ final class NoteTests: XCTestCase { // THEN XCTAssertEqual(sut.apiURL.url?.absoluteString, "https://api.zeplin.dev/v1/projects/\(projectId)/screens/\(screenId)/notes") XCTAssertEqual(sut.apiURL.requestMethod, "POST") - guard let bodyParams = sut.apiURL.bodyParams(token: ZeplinKitMocks.token), let position = bodyParams["position"] as? [String: Float] else { + guard let bodyParams = sut.apiURL.bodyParams(token: ZeplinKitMocks.token), let position = bodyParams["position"] as? [String: Float] + else { return XCTFail("Unable to infer the request body") } XCTAssertEqual(bodyParams["content"] as? String, ZeplinKitMocks.addNoteRequest.content) @@ -82,9 +90,13 @@ final class NoteTests: XCTestCase { let isMatchingResponseCode = try await fetcher.matchHTTPCode(sut.apiURL, code: 204) // THEN - XCTAssertEqual(sut.apiURL.url?.absoluteString, "https://api.zeplin.dev/v1/projects/\(projectId)/screens/\(screenId)/notes/\(noteId)") + XCTAssertEqual( + sut.apiURL.url?.absoluteString, + "https://api.zeplin.dev/v1/projects/\(projectId)/screens/\(screenId)/notes/\(noteId)" + ) XCTAssertEqual(sut.apiURL.requestMethod, "PATCH") - guard let bodyParams = sut.apiURL.bodyParams(token: ZeplinKitMocks.token), let position = bodyParams["position"] as? [String: Float] else { + guard let bodyParams = sut.apiURL.bodyParams(token: ZeplinKitMocks.token), let position = bodyParams["position"] as? [String: Float] + else { return XCTFail("Unable to infer the request body") } XCTAssertEqual(bodyParams["status"] as? String, ZeplinKitMocks.updateNoteRequest.status) @@ -105,7 +117,10 @@ final class NoteTests: XCTestCase { let response: ZeplinCreateCommentResponse = try await fetcher.fetch(sut.apiURL) // THEN - XCTAssertEqual(sut.apiURL.url?.absoluteString, "https://api.zeplin.dev/v1/projects/\(projectId)/screens/\(screenId)/notes/\(noteId)/comments") + XCTAssertEqual( + sut.apiURL.url?.absoluteString, + "https://api.zeplin.dev/v1/projects/\(projectId)/screens/\(screenId)/notes/\(noteId)/comments" + ) XCTAssertEqual(sut.apiURL.requestMethod, "POST") guard let bodyParams = sut.apiURL.bodyParams(token: ZeplinKitMocks.token) else { return XCTFail("Unable to infer the request body") @@ -128,7 +143,10 @@ final class NoteTests: XCTestCase { let isMatchingResponseCode = try await fetcher.matchHTTPCode(sut.apiURL, code: 204) // THEN - XCTAssertEqual(sut.apiURL.url?.absoluteString, "https://api.zeplin.dev/v1/projects/\(projectId)/screens/\(screenId)/notes/\(noteId)/comments/\(commentId)") + XCTAssertEqual( + sut.apiURL.url?.absoluteString, + "https://api.zeplin.dev/v1/projects/\(projectId)/screens/\(screenId)/notes/\(noteId)/comments/\(commentId)" + ) XCTAssertEqual(sut.apiURL.requestMethod, "PATCH") guard let bodyParams = sut.apiURL.bodyParams(token: ZeplinKitMocks.token) else { return XCTFail("Unable to infer the request body") diff --git a/Tests/ZeplinKitTests/NotificationTests.swift b/Tests/NotificationTests.swift similarity index 99% rename from Tests/ZeplinKitTests/NotificationTests.swift rename to Tests/NotificationTests.swift index 05826f4..c939e79 100644 --- a/Tests/ZeplinKitTests/NotificationTests.swift +++ b/Tests/NotificationTests.swift @@ -1,12 +1,13 @@ // // NotificationTests.swift -// +// // // Created by Ilian Konchev on 8.02.22. // -@testable import Fetcher import XCTest + +@testable import Fetcher @testable import ZeplinKit final class NotificationTests: XCTestCase { diff --git a/Tests/ZeplinKitTests/ProjectTests.swift b/Tests/ProjectTests.swift similarity index 99% rename from Tests/ZeplinKitTests/ProjectTests.swift rename to Tests/ProjectTests.swift index b54854b..6d1df89 100644 --- a/Tests/ZeplinKitTests/ProjectTests.swift +++ b/Tests/ProjectTests.swift @@ -5,8 +5,9 @@ // Created by Ilian Konchev on 8.02.22. // -@testable import Fetcher import XCTest + +@testable import Fetcher @testable import ZeplinKit final class ProjectTests: XCTestCase { diff --git a/Tests/ZeplinKitTests/ScreenTests.swift b/Tests/ScreenTests.swift similarity index 92% rename from Tests/ZeplinKitTests/ScreenTests.swift rename to Tests/ScreenTests.swift index d0dad3f..8790ce2 100644 --- a/Tests/ZeplinKitTests/ScreenTests.swift +++ b/Tests/ScreenTests.swift @@ -1,12 +1,13 @@ // // ScreenTests.swift -// +// // // Created by Ilian Konchev on 8.02.22. // -@testable import Fetcher import XCTest + +@testable import Fetcher @testable import ZeplinKit final class ScreenTests: XCTestCase { @@ -36,7 +37,8 @@ final class ScreenTests: XCTestCase { let response: [ZeplinScreen] = try await fetcher.fetch(sut.apiURL) // THEN - XCTAssertEqual(sut.apiURL.url?.absoluteString, "https://api.zeplin.dev/v1/projects/\(projectId)/screens?sort=section&limit=1&offset=0") + XCTAssertEqual( + sut.apiURL.url?.absoluteString, "https://api.zeplin.dev/v1/projects/\(projectId)/screens?sort=section&limit=1&offset=0") XCTAssertEqual(sut.apiURL.requestMethod, "GET") XCTAssertEqual(response.count, 1) guard let screen = response.first else { diff --git a/Tests/ZeplinKitTests/ScreenVersionTests.swift b/Tests/ScreenVersionTests.swift similarity index 90% rename from Tests/ZeplinKitTests/ScreenVersionTests.swift rename to Tests/ScreenVersionTests.swift index 99fed20..12acefa 100644 --- a/Tests/ZeplinKitTests/ScreenVersionTests.swift +++ b/Tests/ScreenVersionTests.swift @@ -1,12 +1,13 @@ // // ScreenVersionTests.swift -// +// // // Created by Ilian Konchev on 8.02.22. // -@testable import Fetcher import XCTest + +@testable import Fetcher @testable import ZeplinKit final class ScreenVersionTests: XCTestCase { @@ -22,13 +23,16 @@ final class ScreenVersionTests: XCTestCase { let response: [ZeplinScreenVersionSummary] = try await fetcher.fetch(sut.apiURL) // THEN - XCTAssertEqual(sut.apiURL.url?.absoluteString, "https://api.zeplin.dev/v1/projects/\(projectId)/screens/\(screenId)/versions?limit=1&offset=0") + XCTAssertEqual( + sut.apiURL.url?.absoluteString, + "https://api.zeplin.dev/v1/projects/\(projectId)/screens/\(screenId)/versions?limit=1&offset=0" + ) XCTAssertEqual(sut.apiURL.requestMethod, "GET") XCTAssertEqual(response.count, 1) guard let version = response.first, - let commit = version.commit, - let creator = version.creator, - let commitCreator = commit.author + let commit = version.commit, + let creator = version.creator, + let commitCreator = commit.author else { return XCTFail("unable to get the note or the first comment") } @@ -62,13 +66,16 @@ final class ScreenVersionTests: XCTestCase { let version: ZeplinScreenVersion = try await fetcher.fetch(sut.apiURL) // THEN - XCTAssertEqual(sut.apiURL.url?.absoluteString, "https://api.zeplin.dev/v1/projects/\(projectId)/screens/\(screenId)/versions/latest") + XCTAssertEqual( + sut.apiURL.url?.absoluteString, + "https://api.zeplin.dev/v1/projects/\(projectId)/screens/\(screenId)/versions/latest" + ) XCTAssertEqual(sut.apiURL.requestMethod, "GET") guard let creator = version.creator, - let commit = version.commit, - let commitAuthor = commit.author, - let grid = version.grid, - let backgroundColor = version.backgroundColor + let commit = version.commit, + let commitAuthor = commit.author, + let grid = version.grid, + let backgroundColor = version.backgroundColor else { return XCTFail("unable to get the versiion creator") } diff --git a/Tests/ZeplinKitTests/Shared/MockZeplinAPIConfiguration.swift b/Tests/Shared/MockZeplinAPIConfiguration.swift similarity index 99% rename from Tests/ZeplinKitTests/Shared/MockZeplinAPIConfiguration.swift rename to Tests/Shared/MockZeplinAPIConfiguration.swift index 0ed6112..222d582 100644 --- a/Tests/ZeplinKitTests/Shared/MockZeplinAPIConfiguration.swift +++ b/Tests/Shared/MockZeplinAPIConfiguration.swift @@ -1,6 +1,6 @@ // // MockZeplinAPIConfiguration.swift -// +// // // Created by Ilian Konchev on 9.02.22. // diff --git a/Tests/ZeplinKitTests/Shared/SharedAssertions.swift b/Tests/Shared/SharedAssertions.swift similarity index 99% rename from Tests/ZeplinKitTests/Shared/SharedAssertions.swift rename to Tests/Shared/SharedAssertions.swift index ef38443..ad24cff 100644 --- a/Tests/ZeplinKitTests/Shared/SharedAssertions.swift +++ b/Tests/Shared/SharedAssertions.swift @@ -1,6 +1,6 @@ // // SharedAssertions.swift -// +// // // Created by Ilian Konchev on 8.02.22. // diff --git a/Tests/ZeplinKitTests/Shared/ZeplinKitMockEnvironment.swift b/Tests/Shared/ZeplinKitMockEnvironment.swift similarity index 99% rename from Tests/ZeplinKitTests/Shared/ZeplinKitMockEnvironment.swift rename to Tests/Shared/ZeplinKitMockEnvironment.swift index f7423be..c8e5fd9 100644 --- a/Tests/ZeplinKitTests/Shared/ZeplinKitMockEnvironment.swift +++ b/Tests/Shared/ZeplinKitMockEnvironment.swift @@ -1,12 +1,13 @@ // // ZeplinKitMockEnvironment.swift -// +// // // Created by Ilian Konchev on 2.02.22. // -@testable import Fetcher import Foundation + +@testable import Fetcher @testable import ZeplinKit final class ZeplinKitMockEnvironment: FetcherEnvironment { diff --git a/Tests/ZeplinKitTests/Shared/ZeplinKitMockURLProtocol.swift b/Tests/Shared/ZeplinKitMockURLProtocol.swift similarity index 99% rename from Tests/ZeplinKitTests/Shared/ZeplinKitMockURLProtocol.swift rename to Tests/Shared/ZeplinKitMockURLProtocol.swift index ed5971b..aafe146 100644 --- a/Tests/ZeplinKitTests/Shared/ZeplinKitMockURLProtocol.swift +++ b/Tests/Shared/ZeplinKitMockURLProtocol.swift @@ -1,11 +1,12 @@ // // ZeplinKitMockURLProtocol.swift -// +// // // Created by Ilian Konchev on 4.02.22. // import Foundation + @testable import ZeplinKit final class ZeplinKitMockURLProtocol: URLProtocol { diff --git a/Tests/Shared/ZeplinKitMocks.swift b/Tests/Shared/ZeplinKitMocks.swift new file mode 100644 index 0000000..4822cfa --- /dev/null +++ b/Tests/Shared/ZeplinKitMocks.swift @@ -0,0 +1,178 @@ +// +// ZeplinKitMocks.swift +// +// +// Created by Ilian Konchev on 3.02.22. +// + +import Fetcher +import Foundation + +@testable import ZeplinKit + +struct ZeplinKitMocks { + // swiftlint:disable large_tuple + static func mocked(request: URLRequest) -> (HTTPURLResponse, Data?, Error?) { + var mockFileName: String? + var wantedResponseCode: Int = 200 + for urlMock in ZeplinKitURLMock.allCases { + let mapRequest = urlMock.apiURL.request(token: ZeplinKitMocks.token) + if mapRequest?.url == request.url && mapRequest?.httpMethod == request.httpMethod { + mockFileName = urlMock.fileName + wantedResponseCode = urlMock.responseCode + break + } + } + guard let mockFileName = mockFileName, + let url = Bundle.module.url(forResource: mockFileName, withExtension: "json"), + let data = try? Data(contentsOf: url) + else { + let response = HTTPURLResponse(url: request.url!, statusCode: 500, httpVersion: nil, headerFields: nil) + return (response!, nil, APIError.unknown) + } + + let response = HTTPURLResponse(url: request.url!, statusCode: wantedResponseCode, httpVersion: nil, headerFields: nil) + return (response!, data, nil) + } + + static let code = "mockCode" + + static let addNoteRequest = ZeplinAddNoteRequest( + project: ZeplinKitMocks.project, + screen: ZeplinKitMocks.screen, + position: ZeplinNotePosition(originX: 0.3, originY: 0.3), + color: "purple", + content: "Test comment" + ) + + static let updateNoteRequest = ZeplinUpdateNoteRequest( + project: ZeplinKitMocks.project, + screen: ZeplinKitMocks.screen, + note: ZeplinKitMocks.note, + position: ZeplinNotePosition(originX: 0.5, originY: 0.5), + status: ZeplinNote.Status.open.rawValue + ) + + static let addCommentRequest = ZeplinAddCommentRequest( + project: ZeplinKitMocks.project, + screen: ZeplinKitMocks.screen, + note: ZeplinKitMocks.note, + content: "Test comment" + ) + + static let updateCommentRequest = ZeplinUpdateCommentRequest( + project: ZeplinKitMocks.project, + screen: ZeplinKitMocks.screen, + note: ZeplinKitMocks.note, + comment: ZeplinKitMocks.comment, + content: "Updated content" + ) + + static let token = Token( + accessToken: "abc123", + expiresIn: Int32(Date().addingTimeInterval(3600).timeIntervalSince1970), + refreshToken: "123abc", + refreshExpiresIn: Int32(Date().addingTimeInterval(86_400).timeIntervalSince1970), + tokenType: "bearer" + ) + + static let project = ZeplinProject( + id: "5db81e73e1e36ee19f138c1a", + name: "HAL 9000", + description: "UI designs for the onboard computer on the spaceship Discovery 1", + thumbnailURL: "http://placekitten.com/200/300", + platform: .web, + status: "active", + created: 1_517_184_000.0, + updated: 1_572_347_818.0, + numberOfScreens: 112, + numberOfSpacingTokens: 63, + numberOfComponents: 46, + numberOfTextStyles: 28, + numberOfColors: 17, + numberOfMembers: 47, + linkedStyleguide: LinkedStyleguide(id: "5db81e6e6a4462065f04d932"), + organization: ZeplinOrganizationSummary( + id: "5d9caaecb4a3fa9b972f86ce", + name: "Acme, Inc.", + logo: "http://placekitten.com/200/300" + ) + ) + + static let screen = ZeplinScreen( + id: "5dbad85a76ea51c1f35b6f69", + name: "Login", + description: "Login screen for HAL 9000", + created: 1_517_184_000.0, + updated: 1_572_347_818.0, + image: ZeplinImage( + width: 2560.0, + height: 1920.0, + originalURL: "http://placekitten.com/2560/1920" + ), + backgroundColor: nil, + section: ZeplinSection(id: "5db81e6e6a4462065f04d932"), + tags: ["mobile", "login"], + numberOfNotes: 7, + numberOfVersions: 4 + ) + + static let user = ZeplinUser( + id: "5d9caaecb4a3fa9bc9718686", + email: "5d9caaecb4a3fa9bc9718686@user.zeplin.io", + username: "zozo", + emotar: "🍎", + avatarURL: "http://placekitten.com/200/300", + lastSeen: 1_616_739_240.0 + ) + + static let organization = ZeplinOrganizationSummary( + id: "5d9caaecb4a3fa9b972f86ce", + name: "Acme, Inc.", + logo: "http://placekitten.com/200/300" + ) + + static let color = ZeplinColor(alpha: 1, red: 254, green: 207, blue: 51, name: "yellow") + + static let notificationId = "5fbe387f8c72ef23659fb500" + + static let notifications: [ZeplinNotificationRepresentation] = [ + ZeplinNotificationRepresentation( + id: "5fbe387f8c72ef23659fb500", + created: 1_586_852_836.0, + lastUpdated: 1_586_852_836.0, + isRead: false + ) + ] + + static let notificationsAlt: [ZeplinNotificationRepresentation] = [ + ZeplinNotificationRepresentation( + id: "5fbe387f8c72ef23659fb501", + created: 1_586_852_836.0, + lastUpdated: 1_586_852_836.0, + isRead: true + ) + ] + + static let comment = ZeplinComment( + id: "5dbad85a89ea51c1f35bcffe", + author: ZeplinKitMocks.user, + content: "Hey ho! Let's go!", + updated: 1_572_347_818.0 + ) + + static let note = ZeplinNote( + id: "5dbad85a76ea51c1f35b6f69", + order: "1", + color: ZeplinKitMocks.color, + position: ZeplinNotePosition(originX: 0.93, originY: 0.1), + comments: [ZeplinKitMocks.comment], + creator: ZeplinKitMocks.user, + status: .open, + created: 1_572_347_818.0 + ) + + static let member = ZeplinProjectMember(user: ZeplinKitMocks.user, role: .owner) + + static let zeplinAPIConfiguration = MockZeplinAPIConfiguration() +} diff --git a/Tests/ZeplinKitTests/Shared/ZeplinKitURLMock.swift b/Tests/Shared/ZeplinKitURLMock.swift similarity index 91% rename from Tests/ZeplinKitTests/Shared/ZeplinKitURLMock.swift rename to Tests/Shared/ZeplinKitURLMock.swift index ad253ac..8dd0995 100644 --- a/Tests/ZeplinKitTests/Shared/ZeplinKitURLMock.swift +++ b/Tests/Shared/ZeplinKitURLMock.swift @@ -1,6 +1,6 @@ // // ZeplinKitURLMock.swift -// +// // // Created by Ilian Konchev on 9.02.22. // @@ -11,9 +11,9 @@ import ZeplinKit enum ZeplinKitURLMock: String, CaseIterable { case getScreen, getScreens, getProject, getProjects, getNotes, getCurrentUser, getProjectMembers, getSections, - getScreenVersions, getNotifications, updateNotification, updateNotifications, flagNotificationsAsUnread, - getScreenVersion, inviteMember, updateMemberRole, removeMember, getToken, refreshToken, - getNote, createNote, updateNote, createComment, updateComment + getScreenVersions, getNotifications, updateNotification, updateNotifications, flagNotificationsAsUnread, + getScreenVersion, inviteMember, updateMemberRole, removeMember, getToken, refreshToken, + getNote, createNote, updateNote, createComment, updateComment var apiURL: APIURL { switch self { @@ -72,7 +72,8 @@ enum ZeplinKitURLMock: String, CaseIterable { switch self { case .createNote, .inviteMember, .createComment: return 201 - case .updateNote, .updateComment, .updateNotification, .updateNotifications, .flagNotificationsAsUnread, .updateMemberRole, .removeMember: + case .updateNote, .updateComment, .updateNotification, .updateNotifications, .flagNotificationsAsUnread, .updateMemberRole, + .removeMember: return 204 default: return 200 @@ -81,7 +82,8 @@ enum ZeplinKitURLMock: String, CaseIterable { var fileName: String? { switch self { - case .updateNote, .updateComment, .updateNotification, .updateNotifications, .flagNotificationsAsUnread, .updateMemberRole, .removeMember: + case .updateNote, .updateComment, .updateNotification, .updateNotifications, .flagNotificationsAsUnread, .updateMemberRole, + .removeMember: return "emptyResponse" default: return rawValue diff --git a/Tests/ZeplinKitTests/TokenTests.swift b/Tests/TokenTests.swift similarity index 99% rename from Tests/ZeplinKitTests/TokenTests.swift rename to Tests/TokenTests.swift index f61857e..bd7c622 100644 --- a/Tests/ZeplinKitTests/TokenTests.swift +++ b/Tests/TokenTests.swift @@ -1,12 +1,13 @@ // // TokenTests.swift -// +// // // Created by Ilian Konchev on 8.02.22. // -@testable import Fetcher import XCTest + +@testable import Fetcher @testable import ZeplinKit final class TokenTests: XCTestCase { diff --git a/Tests/ZeplinKitTests/Shared/ZeplinKitMocks.swift b/Tests/ZeplinKitTests/Shared/ZeplinKitMocks.swift deleted file mode 100644 index 2650219..0000000 --- a/Tests/ZeplinKitTests/Shared/ZeplinKitMocks.swift +++ /dev/null @@ -1,147 +0,0 @@ -// -// ZeplinKitMocks.swift -// -// -// Created by Ilian Konchev on 3.02.22. -// - -import Fetcher -import Foundation -@testable import ZeplinKit - -struct ZeplinKitMocks { - // swiftlint:disable large_tuple - static func mocked(request: URLRequest) -> (HTTPURLResponse, Data?, Error?) { - var mockFileName: String? - var wantedResponseCode: Int = 200 - for urlMock in ZeplinKitURLMock.allCases { - let mapRequest = urlMock.apiURL.request(token: ZeplinKitMocks.token) - if mapRequest?.url == request.url && mapRequest?.httpMethod == request.httpMethod { - mockFileName = urlMock.fileName - wantedResponseCode = urlMock.responseCode - break - } - } - guard let mockFileName = mockFileName, - let url = Bundle.module.url(forResource: mockFileName, withExtension: "json"), - let data = try? Data(contentsOf: url) - else { - let response = HTTPURLResponse(url: request.url!, statusCode: 500, httpVersion: nil, headerFields: nil) - return (response!, nil, APIError.unknown) - } - - let response = HTTPURLResponse(url: request.url!, statusCode: wantedResponseCode, httpVersion: nil, headerFields: nil) - return (response!, data, nil) - } - - static let code = "mockCode" - - static let addNoteRequest = ZeplinAddNoteRequest(project: ZeplinKitMocks.project, - screen: ZeplinKitMocks.screen, - position: ZeplinNotePosition(originX: 0.3, originY: 0.3), - color: "purple", - content: "Test comment") - - static let updateNoteRequest = ZeplinUpdateNoteRequest(project: ZeplinKitMocks.project, - screen: ZeplinKitMocks.screen, - note: ZeplinKitMocks.note, - position: ZeplinNotePosition(originX: 0.5, originY: 0.5), - status: ZeplinNote.Status.open.rawValue) - - static let addCommentRequest = ZeplinAddCommentRequest(project: ZeplinKitMocks.project, - screen: ZeplinKitMocks.screen, - note: ZeplinKitMocks.note, - content: "Test comment") - - static let updateCommentRequest = ZeplinUpdateCommentRequest(project: ZeplinKitMocks.project, - screen: ZeplinKitMocks.screen, - note: ZeplinKitMocks.note, - comment: ZeplinKitMocks.comment, - content: "Updated content") - - static let token = Token(accessToken: "abc123", - expiresIn: Int32(Date().addingTimeInterval(3600).timeIntervalSince1970), - refreshToken: "123abc", - refreshExpiresIn: Int32(Date().addingTimeInterval(86_400).timeIntervalSince1970), - tokenType: "bearer") - - static let project = ZeplinProject(id: "5db81e73e1e36ee19f138c1a", - name: "HAL 9000", - description: "UI designs for the onboard computer on the spaceship Discovery 1", - thumbnailURL: "http://placekitten.com/200/300", - platform: .web, - status: "active", - created: 1_517_184_000.0, - updated: 1_572_347_818.0, - numberOfScreens: 112, - numberOfSpacingTokens: 63, - numberOfComponents: 46, - numberOfTextStyles: 28, - numberOfColors: 17, - numberOfMembers: 47, - linkedStyleguide: LinkedStyleguide(id: "5db81e6e6a4462065f04d932"), - organization: ZeplinOrganizationSummary(id: "5d9caaecb4a3fa9b972f86ce", - name: "Acme, Inc.", - logo: "http://placekitten.com/200/300")) - - static let screen = ZeplinScreen(id: "5dbad85a76ea51c1f35b6f69", - name: "Login", - description: "Login screen for HAL 9000", - created: 1_517_184_000.0, - updated: 1_572_347_818.0, - image: ZeplinImage(width: 2560.0, - height: 1920.0, - originalURL: "http://placekitten.com/2560/1920"), - backgroundColor: nil, - section: ZeplinSection(id: "5db81e6e6a4462065f04d932"), - tags: ["mobile", "login"], - numberOfNotes: 7, - numberOfVersions: 4) - - static let user = ZeplinUser(id: "5d9caaecb4a3fa9bc9718686", - email: "5d9caaecb4a3fa9bc9718686@user.zeplin.io", - username: "zozo", - emotar: "🍎", - avatarURL: "http://placekitten.com/200/300", - lastSeen: 1_616_739_240.0) - - static let organization = ZeplinOrganizationSummary(id: "5d9caaecb4a3fa9b972f86ce", - name: "Acme, Inc.", - logo: "http://placekitten.com/200/300") - - static let color = ZeplinColor(alpha: 1, red: 254, green: 207, blue: 51, name: "yellow") - - static let notificationId = "5fbe387f8c72ef23659fb500" - - static let notifications: [ZeplinNotificationRepresentation] = [ - ZeplinNotificationRepresentation(id: "5fbe387f8c72ef23659fb500", - created: 1_586_852_836.0, - lastUpdated: 1_586_852_836.0, - isRead: false) - ] - - static let notificationsAlt: [ZeplinNotificationRepresentation] = [ - ZeplinNotificationRepresentation(id: "5fbe387f8c72ef23659fb501", - created: 1_586_852_836.0, - lastUpdated: 1_586_852_836.0, - isRead: true) - ] - - static let comment = ZeplinComment(id: "5dbad85a89ea51c1f35bcffe", - author: ZeplinKitMocks.user, - content: "Hey ho! Let's go!", - updated: 1_572_347_818.0) - - static let note = ZeplinNote(id: "5dbad85a76ea51c1f35b6f69", - order: "1", - color: ZeplinKitMocks.color, - position: ZeplinNotePosition(originX: 0.93, originY: 0.1), - comments: [ZeplinKitMocks.comment], - creator: ZeplinKitMocks.user, - status: .open, - created: 1_572_347_818.0) - - static let member = ZeplinProjectMember(user: ZeplinKitMocks.user, role: .owner) - - static let zeplinAPIConfiguration = MockZeplinAPIConfiguration() -}