A Javascript library for working with native objects.

Overview

Sugar

Build Status Coverage Status

A Javascript library for working with native objects.



v2.0.4

sugar.js | sugar.min.js (24kb gz)

Install

npm install sugar

bower install sugar

Upgrading

If you are upgrading from v1, there is now an upgrade helper script available that makes upgrading easier by warning you about breaking changes as your code is run. The CAUTIONLOG is also available, which is a vetted changelog showing breaking changes in order of severity.

Getting Started

https://sugarjs.com/quickstart/

Documentation

https://sugarjs.com/docs/

Custom Builds

https://sugarjs.com/download/

Custom browser builds can be created on the site download page. In addition, tools like Browserify can also be used to create custom builds, as npm packages are now fully modular. The main repo also has tasks to create custom builds as well. Simply clone, run npm install then gulp.

Browser

The dist directory holds builds that are ready to be loaded in the browser. These builds include the core module, and so have no dependencies. Bower packages at the moment include only this directory. Use the es5 builds if you require support for environments that do not support ES5 natively (IE8 and below).

npm

The sugar npm package allows methods as well as entire modules to be required individually. If you are using a build tool like Browserify, this will make it simple to create smaller custom builds without going through the download page. All packages also include pre-built distributions in the dist/ directory.

In addition to the main sugar package, there are also packages separated by Sugar module, i.e. sugar-date, sugar-array, etc.

When an entry point is required (the package name or an entire module), it will return a reference to Sugar, which is equivalent to the global object in the browser. All methods will be defined on this object and can be called as normal. Requiring an individual method will define it on Sugar and additionally return a reference to its static form that can be called immediately:

// Require all modules
var Sugar = require('sugar');
Sugar.Number.round(3.1415);

// Require the Number module
var Sugar = require('sugar/number');
Sugar.Number.round(3.1415);

// Require only the "round" method
var round = require('sugar/number/round');
round(3.1415);

As the npm package is designed with node in mind, polyfills must be explicitly required (the sugar entry point will not include them), and will immediately apply themselves if the methods they polyfill are missing.

// Require and apply ES6 polyfills
require('sugar/polyfills/es6');

Similarly, date locales must be explicitly required as well:

// Require the Japanese date locale
require('sugar/locales/ja');
// Require all date locales
require('sugar/locales');

All Sugar npm packages are dependent on the sugar-core package.

Modules

Although Sugar builds can now be customized at method level, modules are still used as an intuitive way of grouping similar methods. Sugar npm packages make use of modules, both in the main sugar package as well as individual module packages beginning with sugar-. The following modules are available:

Default:

Non-default:

  • ES5 (Polyfills, adds IE6-8 Support)
  • Language (Character conversion and script detection)
  • Inflections (Pluralization and string normalization)

Non-default modules are excluded from the main Sugar build, but can be added by creating a custom build. The main npm package includes the ES5 module, polyfills are disabled by default and must be explicitly required. Other non-default modules can be found individually (i.e. sugar-language, etc).

Date Locales

Locale definition files are in the locales directory. They can be simply included as-is after Sugar is loaded, or built together using custom builds. English is included by default and required by the Date module. Currently available locales are:

Adding/Customizing Locales

If a locale or format is missing, it can easily be added by modifying or adding the definition. See here for more on this. Please consider contributing any changes made back to the community!

Timezones

Sugar does not deal with timezone abbreviations (i.e. "PST", etc). Timezone offsets will be correctly parsed if they are in ISO-8601 format (+09:00, +0900, or Z for UTC), however if an abbreviation exists it will be ignored. Sugar however plays nicely with other libraries that offer full timezone support such as timezone.js.

Date.create allows two options for dealing with UTC dates. fromUTC will parse the string as UTC, but return a normal date. In contrast, setUTC tells Sugar to use methods like getUTCHours when handling the date, and is usually used when the date needs to be formatted as UTC. Native methods like getHours still return local values.

Defining Methods

Sugar now makes it easy to define your own methods. This is aimed at developers hoping to release their own plugins with Sugar. After defining methods, they can be extended or used as chainables just like other methods:

Sugar.Number.defineStatic('randomish', function () {
  if (Math.random() > .5) {
    return Math.random();
  } else {
    return 1;
  }
});

Sugar.Number.defineInstance({
  'square': function (n) {
    return n * n;
  },
  'cube': function (n) {
    return n * n * n;
  }
});

Sugar.Number.square(3);         // 9
new Sugar.Number(5).cube().raw; // 125
Sugar.Number.randomish()        // ???

Sugar.extend();
(2).square();       // 4
(4).cube();         // 64
Number.randomish(); // ???

See the docs for options and other helpers.

Plugins

If you are defining methods that are useful to the general public, please consider releasing them as a Sugar plugin! Refer to the plugin boilerplate repo for an example to get started.

Contributing

If you would like to issue a pull request, please first consider adding well formed unit tests. These tests can be run directly in the browser from the test/browser/ directory or in node with npm test.

Road Map

Proposals for core features or major method changes will be added to the road map. New methods may or may not be accepted, depending on their utility. Generally, they will first be delegated to plugins that may eventually be added to the main library when they reach a certain stage of popularity.

Comments
  • SugarJS array methods treat DOM elements of same nodeName as same object

    SugarJS array methods treat DOM elements of same nodeName as same object

    div1 = document.getElementsByTagName('div')[0];
    div2 = document.getElementsByTagName('div')[1];
    
    [div1].subtract([div2]);
    /* should return [div1] */
    /* returns [] */
    
    [div1].union([div2]);
    /* should return [div1, div2] */
    /* returns [div1] */
    
    [div1].intersect([div2]);
    /* should return [] */
    /* returns [div1] */
    
    opened by dlee 54
  • Feature Request: Set/Get Object with 'Dot Notation'

    Feature Request: Set/Get Object with 'Dot Notation'

    var setProp = function (obj, path, val) {
        path = path.split('.');
    
        for (var i = 0, max = path.length - 1; i < max; i += 1) {
            obj = obj[path[i]] = obj[path[i]] || {};
        }
    
        obj[path[i]] = val;
    };
    
    var getProp = function (obj, path) {
        path = path.split('.');
    
        for (var i = 0, max = path.length; i < max; i += 1) {
            obj = obj[path[i]];
        }
    
        return obj;
    };
    

    Which (when extending Object) would let us do:

    var obj = {};
    Object.setProp(obj, 'location.address.street', 'test');
    console.log(obj.location.address.street); // -> test
    

    And retrieve it dynamically with this:

    console.log(Object.getProp(obj, 'location.address.street')); // -> test
    
    Feature 
    opened by DylanPiercey 43
  • String.assign performance

    String.assign performance

    I‘ve discovered that String.assign performance is subotimal for complex templates.

    var s = '{x}  {y} '+('{yy}').repeat(1000)+' {x} {z}',
    a = {x:"123",y:[5,6],z:3,yy:1},
    t = Date.now(); 
    for(var i=0;i<10000;i++) s.assign(a);
    console.log(Date.now()-t);
    

    runs about 4 seconds.

    If we change an approach from in-place handling of each {smth} match to pre-generating regexps for each key in data obj, we can gain about 10x performance boost for an example given. Code

    function assign(str, obj){
        var keys = Object.keys(obj), i=0, acc;
        if (keys.length>100) return str.assign(obj);
        for (acc=str;i<keys.length;i++) 
            acc = acc.replace(new RegExp('\\{'+RegExp.escape(keys[i])+'\\}','g'), obj[keys[i]]);
        return acc;
    }
    t = Date.now(); 
    for(var i=0;i<10000;i++) assign(s,a);
    console.log(Date.now()-t);
    

    runs about half a second.

    Although for small templates this approach is bit slower.

    Performance 
    opened by ermouth 41
  • Using a wrapper instead of modifying native objects

    Using a wrapper instead of modifying native objects

    If Sugar.js used a wrapper around an object instead of modifying it I think it would give a lot of advantages.

    One being that you can use it with other libraries with the same functionalities. If all these modify the native objects we would have a nightmare knowing which one is currently used.

    Another being that you know what methods are from Sugar. So if you want to use another library in the future you can just search for s() eg. in s(object).clone().

    I think many people will avoid using Sugar since it's extending the native objects directly thus making it less popular than Underscore.

    opened by ghost 35
  • Allow offset for timezone when creating internal dates for comparison

    Allow offset for timezone when creating internal dates for comparison

    The gist of this one is that dates relative to the current date such as 1 week ago as well as Date.past('4pm') (which creates the current date internally to enforce the past requirement that the method name suggests) are making comparisons to a new Date. When attempting to simulate working in different timezones it's sometimes required to offset the date in question before making comparisons, so allow a global timezone offset that will be used internally if set.

    Currently going with Date.SugarTimezoneOffset

    This value will be in minutes, same as returned by the native getTimezoneOffset...

    ---- ASIDE ----

    One potential problem that I was also thinking about here was DST (daylight savings time). I was toying with the idea of allowing SugarTimezoneOffset to be a function that could manipulate the newly created date, but I don't think that would address the issue that was raised. As SugarTimezoneOffset will always be an offset for newly created dates, it can be manipulated dynamically (say if you really needed precision, you could set an interval watching for the traversal into a new day and reset SugarTimezoneOffset appropriately).

    The issue that was raised was instead if you have Date.create('2 weeks ago'), if that date traverses a DST threshold, then it may in fact not be 2 weeks ago... however this issue is independent of the one above as it is also a "problem" for local dates that don't have an offset at all to begin with. I put "problem" in quotes as I don't know if it actually is an issue as technically a date 2 weeks ago that (for example) shows a 1 hour discrepancy technically is 2 weeks ago by the strict definition of 2 * 7 * 24 * 60 * 60 * 1000, therefore I think it would be incorrect to mess with the date in an attempt to correct it. Instead, the developer should adjust it accordingly as necessary for the given app/context.

    opened by andrewplummer 33
  • request: mechanism to parse date strings limited to future or past

    request: mechanism to parse date strings limited to future or past

    There are many applications in which a user can be expected to input a date that must be in the future or must be in the past. Sugar's Date.create() mechanism is powerful but doesn't seem to expose a way for the programmer to hint the user's future or past intention if it is known. This limits its utility. In these cases, the user is required what seems to be redundant information. For instance, if I'm scheduling an appointment I should only need to say '4 hours' rather than 'in 4 hours'. Likewise, if I say 'Tuesday' or 'January' I'd expect to get the closest match in the future and rather than having to say 'next Tuesday' or 'next January'. It's possible for a user of the library to work around this by adding prefix/postfix hints to the user input, but this solution isn't portable and can go wrong in unexpected ways. (As an example, try passing the string 'feb of next month' to Date.create())

    opened by ziIizeqQ 32
  • Why does Number#times return the number?

    Why does Number#times return the number?

    Let's say I want to make an array of five random numbers. Having used underscore, my first instinct will be to do this:

    var arr = (5).times(function() { return Number.random(50, 100); });
    

    But this won't work; it'll uselessly kick back 5. So this method lets you do something five times, and then continue chaining the number. I'm not sure why anyone would want to do that. If you want to preserve this behavior, why not return an array of the returned values if the function it calls returns something?

    Feature 
    opened by HugLifeTiZ 27
  • Object.merge, Object.clone and String.has in 1.5.0

    Object.merge, Object.clone and String.has in 1.5.0

    Right now I have 200K+ sloc js codebase built on top of Sugar 1.4.x. This code is running in production for 260К+ users. And this code use Object.merge and Object.clone extensively.

    Changes made in these methods in 1.5 surely lead me – if I wanted to use them – to rewrite, not just refactor, all the code. Also we’ll need to retest it thoroughly.

    Cost of these ops is absolutely enormous.

    So there are three options for me in this situation if I want to use Sugar in versions 1.5+:

    • ask Andrew to rethink
    • ask to add backward-compatible aliases
    • fork Sugar

    May be I’m too late, but I think deep backward incompatibility is a serious issue worth to discuss.

    Also I think there is no reason to remove String.has – it has clean unique syntax and is shorter than .contains. I see no conflict if .has coexisted with .contains.

    What do you think?

    Feature 
    opened by ermouth 27
  • Pulling customized stable release

    Pulling customized stable release

    Hi - The website's customize page let's me download only certain components that I am interested in. However, the downloaded files seem to be missing some variables causing the app to crash.

    Has anyone used this? FWIW, i tried doing "all" from the customize page and even that is not loadable

    opened by smurali31 24
  • toUTC() seems to go the wrong way.

    toUTC() seems to go the wrong way.

    Sugar seems to advance the date rather than rewind it when asking for a UTC version

    Date.create().beginningOfMonth().toUTC()
    

    Returns Wed Aug 01 2012 04:00:00 GMT-0400 (EDT)

    This is the beginning of the month with our offset (-4) subtracted from the date. (This is actually what the docs say it will do, but it is wrong). We are behind UTC and therefore should have a Jul 31 date.

    Compare this to moment.js

    moment.utc().startOf('month').toDate()
    

    Returns Tue Jul 31 2012 20:00:00 GMT-0400 (EDT) which is correct.

    opened by xealot 24
  • String#shorten & Array#punctuate

    String#shorten & Array#punctuate

    String#truncate didn't provide the functionality I needed, as such String#shorten has been added. The use case for the method is primarily URLs, where the beginning and end are more important than the middle. As such shorten defaults to truncating the string in the middle and including the length of the splitter in the length required.

    "https://www.google.co.uk/search?sourceid=chrome&ie=UTF-8&q=sugar+js".shorten(45)
    -> "https://www.google.co...e&ie=UTF-8&q=sugar+js"
    

    Performs similar to String#truncate in that custom splitters can be included, as well as allowing the resultant string's length to omit the length of the splitter. The splitter can also be positioned at the left, right or middle of the string.

    Array#punctuate builds a grammatical list from the array, taking a fn handler to deal with deep arrays. I've been working with long calling patterns for train services and this addition to Sugar help me deal with the headache. The trailing only on single length lists can be omitted too.

    ['Apples', 'Grapes', 'Bears'].punctuate()   -> 'Apples, Grapes and Bears';
    [{type:'Apple', n:2}, {type:'Grape', n:1}, {type:'Bears', n:10}].punctuate(function(item) {
        var name = (item.n == 1) ? item.type.singularize() : item.type.pluralize();
        return item.n.toString() + " " + name;
    })                              -> '2 Apples, 1 Grape and 10 Bears';
    

    Extensive unit testing added for both methods. Tested in Node.js v0.6.14 and Safari 5.1.5 (Snow Leopard). Unable to use unit_test/../sugar.html in Chrome 18.x as XMLHttpRequest won't load local files because of Access-Control-Allow-Origin. Unsure if this is a know issue. The actual unit tests were ran independently and succeeded in Chrome.

    opened by nadinengland 24
  • Date.create can't parse dots in time format

    Date.create can't parse dots in time format

    Example date string (from MacOS localisation settings): Saturday, 2 May 2015 at 23.52.26

    This gives an Invalid Date, while 'Saturday, 2 May 2015 at 23:52:26' works fine.

    I feel that dots in time format is a common format and should be supported.

    opened by tumispro 0
  • Reversed fromUTC fallback logic

    Reversed fromUTC fallback logic

    This fallback logic seems to be adding the tzOffset when it should be subtracting. At least, that would give a more consistent result. There may be some purpose for adding the tzOffset, but I'm not sure what that is.

    The following examples are in the EDT (-04:00) time zone. The expected behavior is for the second and third results to match.

    Chrome

    new Date('10 20 2021 08:00').toISOString()
    // 2021-10-20T12:00:00.000Z
    
    Date.create('10 20 2021 08:00', { fromUTC: true }).toISOString()
    // 2021-10-20T16:00:00.000Z
    // Adds four hours instead of subtracting four hours.
    
    Date.create('10.20.2021 08:00', { fromUTC: true }).toISOString()
    // 2021-10-20T08:00:00.000Z
    // Sugar's native fromUTC parsing results in a toISOString that matches the input.
    

    Safari

    This is just to prove we're falling back to browser-specific parsing.

    new Date('10 20 2021 08:00')
    // Invalid Date
    
    Date.create('10 20 2021 08:00', { fromUTC: true })
    // Invalid Date
    
    Date.create('10.20.2021 08:00', { fromUTC: true }).toISOString()
    // 2021-10-20T08:00:00.000Z
    
    opened by markdascher 0
  • Problem parsing Spanish DateTime string

    Problem parsing Spanish DateTime string

    Testing on the latest version (in console at: https://sugarjs.com/dates/), I notice that this string fails to be parsed: mié, 25 ago. 2021 16:19

    However, this, string succeeds: 25 ago. 2021 16:19

    Any insight into this? I'm able to do some string cleaning if needed :)

    opened by onassar 0
  • Date.create to find a date in complex string

    Date.create to find a date in complex string

    Hi! I have tried the Date.create function with severals date patterns and it works perfectly but I found that it only works if the string only includes the date. If the string has other parts before/after the date, it fails. I think the problem is the way the format RegEx are built: https://github.com/andrewplummer/Sugar/blob/3ca57818332473b601434001ac1445552d7753ff/lib/date.js#L2297 I want to be able to parse a date from the string "New York, 22 August" the same way as from the string "22 August". Is there a way to solve my problem with Sugar?

    Thank you in advance.

    opened by MeloJR 0
  • Formatting large numbers gives unexpected results

    Formatting large numbers gives unexpected results

    When you format a number that would be expressed using exponential notation by javascript and the base has a decimal part the decimals and the exponent is prepended to the original number.

    Sugar.Number.format(10000000000000000000000, 2) => "1e+22" which is expected, but Sugar.Number.format(12000000000000000000000, 2) => "1.2e+22.2e+22" should just be "1.2e+22"

    opened by borglin 0
Releases(2.0.2)
  • 2.0.2(Nov 5, 2016)

  • 2.0.0(Nov 5, 2016)

  • 1.5.0(Nov 5, 2016)

  • 1.4.1(Sep 14, 2015)

  • 1.3.9(Jun 20, 2013)

    The most major point of this release was fixing jQuery 1.9, which broke in one area when Sugar was included in the page. The cause was complex, on jQuery’s side there was an issue that I submitted a pull request for, however the most direct culprit was String#namespace which is a method that never really fit into the library anyway. As a result I have removed this method from String entirely. At the moment I’m not sure if it will be re-added as it feels better for another lib.

    Object.toQueryString

    The inverse to Object.fromQueryString, this method will take an object and turn it into a query string for use in a url. In addition to the main method it is also mapped onto extended objects, making it even easier. Finally, a namespace can be added to scope all parameters by the given namespace.

    var o1 = { foo: 'bar' };
    var o2 = { foo: [1,2,3] };
    Object.toQueryString(o1)        // 'foo=bar'
    Object.toQueryString(o2)        // 'foo[0]=1&foo[1]=2&foo[2]=3'
    Object.toQueryString(o2, 'bar') // 'bar[foo][0]=1&bar[foo][1]=2&foo[2]=3'
    
    var o1 = Object.extended({ foo: 'bar' });
    var o2 = Object.extended({ foo: [1,2,3] });
    
    o1.toQueryString()      // 'foo=bar'
    o2.toQueryString()      // 'foo[0]=1&foo[1]=2&foo[2]=3'
    o2.toQueryString('bar') // 'bar[foo][0]=1&bar[foo][1]=2&foo[2]=3'
    

    Other Minor Fixes

    Fixed issue with timezone offsets like “-0330”. Fixed issue with date comparison methods like isToday not working when another locale is set.

    Source code(tar.gz)
    Source code(zip)
    sugar-full.development.js(290.67 KB)
    sugar.min.js(44.60 KB)
Owner
Andrew Plummer
Andrew Plummer
utility library for async iterable iterators

⚠️ This library is no longer maintained, and should not be used in production applications. Mesh is a utility library for async iterable iterators. Mo

Craig Condon 1k Jul 29, 2022
JavaScript's utility _ belt

__ /\ \ __ __ __ ___ \_\ \ __ _ __ ____ ___ ___ _ __

Jeremy Ashkenas 26.7k Jan 4, 2023
:ram: Practical functional Javascript

Ramda A practical functional library for JavaScript programmers. Why Ramda? There are already several excellent libraries with a functional flavor. Ty

Scott Sauyet 2 Jul 21, 2022
Modular JavaScript Utilities

http://moutjs.com/ All code is library agnostic and consist mostly of helper methods that aren't directly related with the DOM, the purpose of this li

Modular JavaScript Utilities 1.3k Dec 27, 2022
Hardcore Functional Programming for JavaScript

#Preλude-js A truly modular implementation of Haskell's Prelude library in ES6 check out the docs for modules details (WORK IN PROGRESS) install npm i

Alan Soares 96 Jan 1, 2023
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
Solid Forms provides several form control objects useful for making working with forms easier.

Solid Forms Solid Forms provides several form control objects useful for making working with forms easier. Demos and examples below. # solidjs yarn ad

John 28 Jan 2, 2023
A simple Multi Guild Modmail Bot coded in v13 using the enmap Database Working on any host, like repl.it or vps! Its fast and working bug free + Security options!

Multiguild-Modmail A simple Multi Guild Modmail Bot coded in v13 using the enmap Database Working on any host, like repl.it or vps! Its fast and worki

Tomato6966 54 Oct 20, 2022
Base Bot WhatsApp With Baileys Multi Device, Working Heroku No Suspend ☑️, Working Okteto No Suspend ☑️

Base Bot WhatsApp Multi Device With Baileys Multi Device Note Base Ini Free Untuk Semua, Tidak Untuk Diperjualbelikan Kecuali Lu Udah Tambahin Fitur L

Nazril Afandi 36 Dec 25, 2022
Vue Native is a framework to build cross platform native mobile apps using JavaScript

Vue Native Visit our website at vue-native.io or read the official documentation here. Build native mobile apps using Vue Vue Native is a framework to

GeekyAnts 8.4k Jan 6, 2023
ProgressJs is a JavaScript and CSS3 library which help developers to create and manage progress bar for every objects on the page.

ProgressJS ProgressJs is a JavaScript and CSS3 library which helps developers create and manage progress bars for every object on the page. How To Use

usablica 2.4k Dec 30, 2022
A JavaScript library improving inspection of objects

Pro Inspector A JavaScript utility improving inspection of objects on Node.js. Introduction Let's suppose that we have this declaration. class Person

Reiryoku Technologies 60 Dec 30, 2022
A small library for turning RSS XML feeds into JavaScript objects

rss-parser A small library for turning RSS XML feeds into JavaScript objects. Installation npm install --save rss-parser Usage You can parse RSS from

Robert Brennan 1.1k Dec 31, 2022
javascript library to convert a list of objects to a nested json output format, depending on the names in the list

formToNestedJson javascript "library" to convert a list of objects to a nested json output format, depending on the names in the list Basic usage Give

null 2 Aug 2, 2021
Build performant, native and cross-platform desktop applications with native Vue + powerful CSS like styling.🚀

Vue NodeGui Build performant, native and cross-platform desktop applications with Vue. ?? Vue NodeGUI is powered by Vue ?? and Qt5 ?? which makes it C

NodeGui 765 Dec 30, 2022
🎉 toastify-react-native allows you to add notifications to your react-native app (ios, android) with ease. No more nonsense!

toastify-react-native ?? toastify-react-native allows you to add notifications to your react-native app (ios, android) with ease. No more nonsense! De

Zahid Ali 29 Oct 11, 2022
null 136 Dec 30, 2022
Next-level academia! Repository for the Native Overleaf project, attempting to integrate Overleaf with native OS features for macOS, Linux and Windows.

Native Overleaf Overleaf is a fantastic webtool for writing and cooperating on LaTeX documents. However, would it not be even better if it were to beh

Floris-Jan Willemsen 40 Dec 18, 2022