Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions Sources/FigmaGenerator/Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ extension File {
let components = Array(pair.1.dropFirst())
return (pair.0, components)
}

func findAllComponents(componentID: String) -> [(Node, [NameComponent])] {
return document.findAllWith(componentID: componentID, path: [])
.map { ($0.0, Array($0.1.dropFirst())) }
}
}

extension Style {
Expand Down Expand Up @@ -89,6 +94,18 @@ extension Node {
return nil
}
}

func findAllWith(componentID id: String, path: [String]) -> [(Node, [NameComponent])] {
let currentPath = path + [name]
var results: [(Node, [NameComponent])] = []
if componentId == id {
results.append((self, currentPath))
}
for ch in children ?? [] {
results.append(contentsOf: ch.findAllWith(componentID: id, path: currentPath))
}
return results
}
}

extension Paint {
Expand Down
36 changes: 36 additions & 0 deletions Sources/FigmaGenerator/IconDownloader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,42 @@ final class IconDownloader {
}
}

func downloadSpecialPDFs(output: URL) throws {
for (key, _) in file.components {
for pair in file.findAllComponents(componentID: key) {
guard pair.0.name.contains("/") == false else {
print("Skip component with id: \(pair.0.id) ... invalid name: \(pair.0.name)")
continue
}

let fullName = pair.1.joined(separator: "/")

guard docPaths?.contains(where: { fullName.hasPrefix($0) }) ?? true else {
continue
}

let assetRelatedPath = (dropCanvaName ? pair.1.dropFirst().joined(separator: "/") : fullName) + ".imageset"

let assetURL = output.appendingPathComponent(assetRelatedPath)
guard FileManager.default.fileExists(atPath: assetURL.path, isDirectory: nil) == false else {
continue
}

missedAssets[assetURL] = pair.0
}
}

let ids = missedAssets.map { $0.value.id }
guard ids.isEmpty == false else { return }

let info = try getDownloadInfo(ids: ids, format: "pdf")
try downloadMissedPDFs(links: info)

try Set(missedAssets.map { $0.key.deletingLastPathComponent() }).forEach {
try placeContentJSON(folder: $0, topLevel: output)
}
}

private func placeContentJSON(folder: URL, topLevel: URL) throws {
guard topLevel.path != folder.path else { return }

Expand Down
13 changes: 13 additions & 0 deletions Sources/FigmaGenerator/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ struct FigmaGenerator: ParsableCommand {

@Option(name: .customLong("ios-icons-output"), parsing: .next, help: "iOS Icon Output Folder (.xcassets)")
var ios_icons_output_folder: String?

@Option(name: .customLong("ios-icons-special-output"), parsing: .next, help: "iOS Special Icon Output Folder (.xcassets), only ✅ For Developers canvas")
var ios_icons_special_output_folder: String?

@Option(name: .customLong("ios-typo-output"), parsing: .next, help: "iOS Fonts Output File")
var ios_typo_output: String?
Expand Down Expand Up @@ -98,6 +101,16 @@ struct FigmaGenerator: ParsableCommand {
downloaded.useAbsoluteBounds = use_absolute_bounds
try downloaded.downloadPDFs(output: output)
}

if let folder = ios_icons_special_output_folder {
let output = folder.absoluteFileURL(baseURL: homeDir)
let downloaded = IconDownloader(file: file, fileKey: figma_file_key, accessToken: personal_access_tokens)
downloaded.docPaths = doc_paths
downloaded.dropCanvaName = drop_canva_name
downloaded.iconsAsTemplate = icons_as_template
downloaded.useAbsoluteBounds = use_absolute_bounds
try downloaded.downloadSpecialPDFs(output: output)
}
}
}

Expand Down