Swiftpack.co - Package - nodes-vapor/sugar

Sugar 🍬

Swift Version Vapor Version Circle CI codebeat badge codecov Readme Score GitHub license

📦 Installation

Update your Package.swift file.

.package(url: "https://github.com/nodes-vapor/sugar.git", from: "3.0.0-beta")

Getting started 🚀

Make sure that you've imported Sugar everywhere when needed:

import Sugar


This package contains a lot of misc. functionality that might not fit into it's own package or that would best to get PR'ed into Vapor. Some examples of what this package contains:

How to use it in a package

To have your package register the tags to the shared config, you can do the following:

public func didBoot(_ container: Container) throws -> Future<Void> {
    let tags: MutableLeafTagConfig = try container.make()
    tags.use(MyTag(), as: "mytag")

    return .done(on: container)

How to use it in a project

If you're using a package that uses the shared MutableLeafTagConfig, these tags will become available in your project automatically. If you have additional tags you want to add, these has to be registered in boot.swift instead of configure.swift to allow the different providers to have registered their tags to the config first. Here's how you could do it:

public func boot(_ app: Application) throws {
    // Register Leaf tags using the shared config.
    // This allows third party packages to register their own tags.
    let tags: MutableLeafTagConfig = try app.make()

You don't have to register tags when adding this in boot.swift.

In the case where multiple packages is registering a tag using the same name, the tags can be added manually by defining your own name for the tags.

Environment variables

Access environment variables by writing

env("my-key", "my-fallback-value")

Seeder commands

If you want to make your model seedable, you can conform it to Seedable and use SeederCommand to wrap your seedable model. This basically means that you can focus on how your model gets initialized when running your command, and save a little code on actually performing the database work.

Seeding multiple instances of your model will be added - feel free to PR.


This package contains a lot of convenience related to JWT, usernames and passwords which is used in JWTKeychain and Admin Panel.


Sugar contains a helper function for adding properties while excluding some specific ones. This makes it a bit more convenient if you want to only modify how a single one or a couple of fields gets prepared.

extension MyModel: Migration {
    static func prepare(on connection: MySQLConnection) -> Future<Void> {
        return MySQLDatabase.create(self, on: connection) { builder in
            try addProperties(to: builder, excluding: [\.title])
            builder.field(for: \.title, type: .varchar(191))

🏆 Credits

This package is developed and maintained by the Vapor team at Nodes. The package owner for this project is Siemen.

📄 License

This package is open-sourced software licensed under the MIT license


Stars: 18
Help us keep the lights on


3.0.0 - Dec 4, 2018


  • This package now correctly pins towards Swift 4.1 in Package.swift (thanks @cb1674).


  • Removed the static function get on Environment since it was already defined in vapor/service (thanks @cb1674).
  • Removed the MutableLeafTagConfig since we will encourage the use...LeafTags pattern moving on.

3.0.0-rc.3 - Nov 8, 2018


  • Validator for a "Strong password". The behaviour can be overwritten, but the default behaviour is that the input needs to satisfy 3 out of 4 categories: a lower char, an upper char, a digit or a special char.

3.0.0-rc.2 - Nov 7, 2018


  • Small helper for creating time durations in secs. E.g. 2.hoursInSecs.

3.0.0-rc.1 - Oct 31, 2018


  • Helper on URL to add query parameters (manually or from another URL).


  • Bumped to Swift 4.2.


  • SwiftLint now runs without any errors/warnings.

This should be the 3.0.0 release if no issues occurs.

3.0.0-beta.18 - Oct 24, 2018


  • convenience for passing request into render function via the new userInfo parameter so it can be retrieved in the tag context:

When rendering the view:

    try req.view().render("...", on: req)

In the TagRenderer:

public func render(tag: TagContext) throws -> Future<TemplateData> {
    let req = try tag.requireRequest()