Git Product home page Git Product logo

andculturecode.javascript.core's Introduction

AndcultureCode.JavaScript.Core

build status codecov All Contributors

Common patterns, functions, etc... used when building javascript applications

Getting started

This package is installed via npm or yarn

# npm
npm install --save-dev andculturecode-javascript-core

# yarn
yarn add andculturecode-javascript-core --dev

From there you can import the variety of modules.

import { CollectionUtils, CoreUtils } from "andculturecode-javascript-core";

You can also reference the global distribution package within a website which gives you access to the AndcultureCode namespace. See the example below

<script src="https://unpkg.com/browse/andculturecode-javascript-core@[version-number]/dist/global/index.js"></script>

<script>
    var myAuthObject = AndcultureCode.RouteUtils.queryStringToObject(
        "#token=bada55cafe"
    );
</script>

Peer dependencies

This package wraps several external packages for our own configuration and ease of use, such as axios, i18next, lodash, etc. If you are using the standard distribution of this package, these will need to be installed alongside this package, even if you do not plan on leveraging features that rely on them.

If using the global distribution, you will likely want to reference these in your website prior to referencing this package. See test-global-distribution.html for the full list of dependencies. Unlike the standard distribution, peer dependencies are only required if your code will be executing code paths that rely on those packages.

Internationalization

This package offers a variety of functions for localizing an application, wrapping i18next and i18next-browser-languagedetector. A complete setup guide can be found in the wiki here.

If developing in VS Code, the kazoo extension can be used to quickly insert typed keys and placeholder translations from Google Translate. (source | install)

Documentation

Full API documentation

Contributing

Information on contributing to this repo is in the Contributing Guide

Contributors โœจ

Thanks goes to these wonderful people (emoji key):


Winton DeShong

๐Ÿ’ป ๐Ÿ“– ๐Ÿšง โš ๏ธ ๐Ÿ‘€

Brandon Scott

๐Ÿ’ป ๐Ÿšง โš ๏ธ ๐Ÿ‘€

Said B Shah

๐Ÿ’ป โš ๏ธ ๐Ÿšง

Mat Jones

๐Ÿ’ป โš ๏ธ

Dylan Justice

๐Ÿ’ป โš ๏ธ ๐Ÿ‘€

Kevin Busch

๐Ÿš‡ ๐Ÿšง

Stefanie Leitch

๐Ÿ‘€

Nhinh Dao

โš ๏ธ ๐Ÿšง

Michael Tyson

๐Ÿ’ป โš ๏ธ ๐Ÿ‘€

Joshua Hughes

๐Ÿ‘€

Jeb

๐Ÿ‘€

This project follows the all-contributors specification. Contributions of any kind welcome!

andculturecode.javascript.core's People

Contributors

brandongregoryscott avatar wintondeshong avatar allcontributors[bot] avatar dtnhinh avatar myty avatar dependabot[bot] avatar heykos avatar dylanjustice avatar kevinbusch avatar mrjones2014 avatar snsavage avatar nhinhdao avatar

Stargazers

Tom Piarulli avatar Zac Ball avatar Joshua Hughes avatar  avatar  avatar

Watchers

 avatar  avatar James Cloos avatar Shane Shearer avatar Shane Shearer avatar Zach McCleaf avatar  avatar

andculturecode.javascript.core's Issues

Update README with section on internationalization

Update the README to include a section linking to the internationalization documentation in the wiki as it may be hard for consumers to find (we don't store much in the wiki, but it's easy to update)

https://github.com/AndcultureCode/AndcultureCode.JavaScript.Core/wiki/Internationalization-(i18n)

Additionally, the VS Code extension I recently published for adding resource keys + translations should be linked to speed up development using our library:

https://github.com/brandongregoryscott/kazoo
https://marketplace.visualstudio.com/items?itemName=brandongregoryscott.kazoo

Lighten peer dependency version further

Just got around to updating a client project to the latest version of Core & React, as well as upgrading axios. I am getting a warning from npm about a missing peer dependency, despite having a higher version of axios installed:

npm WARN [email protected] requires a peer of axios@^0.19.2 but none is installed. You must install peer dependencies yourself.

package.json:

"axios": "0.21.1",

We may want to provide a range of tested versions, ie 0.19 - 0.21, or perhaps an or: 0.19 || 0.21

Reevaluate production vs. peer/dev dependencies

After some recent debugging during the attempted axios upgrade, and looking at other packages for reference, @wintondeshong and I are suspecting that the current dependencies list is incorrect, and most (if not all) of them should be listed as peerDependencies and devDependencies. This leaves it up to the consumer to install them if they are using external libraries we are referencing, such as axios, react, react-dom, etc, while maintaining copies for local development.

This should alleviate potential issues with multiple versions of the same package, ie having multiple instances of axios configured differently, or React errors from running multiple instances. It should also remove the need to re-export react-router-dom components, which was a workaround solution to use our routing abstraction in another project.

In addition to specifying these external libraries as peer dependencies, we should lighten the version requirement on them so consumers are not locked in to just the specific version of the package we are using for development, which is rigid and can cause dependency update nightmare. Use your best judgement for specifying a range or minimum version requirement based on the versions we're currently pulling in. This may need to be tweaked as the new package structure rolls out.

Because this is a pretty major change to the way the package is being used currently, we'll want to make sure we update the readme to reflect this new behavior.

Fix skipped LocalizationUtils.detectCultureCode test

There's one test that was added and skipped due to time constraints. I believe the test case itself is valid, and should be accounted for, but the test setup may be incorrect.

The basic idea is:

detectCultureCode should set & return the culture code by priority/validity of the format.

  1. If the culture code is available in the first path index, and it matches the culture code format, use that.
  2. If the culture code is already set as the current culture code, don't change it again - just return it.

https://github.com/AndcultureCode/AndcultureCode.JavaScript.Core/blob/f537b50529ef9c84cce59c1c1f4da1639c101095/src/utilities/localization-utils.test.ts#L264-L279

preinstall -> configure:git script prevents installation on unix-based systems (ie, TravisCI or MacOS)

Bleh. I think we'll have to backpedal on the preinstall steps added to some of our repositories. I was hoping to ease the burden of a developer setting up their environment after cloning, but it's causing more headaches than it is worth right now.

See output from a recent AndcultureCode.Cli build on my forked repository, where I upgraded to v0.1.9:

https://travis-ci.org/github/brandongregoryscott/AndcultureCode.Cli/jobs/729614616

> [email protected] preinstall /home/travis/build/brandongregoryscott/AndcultureCode.Cli
> npm run configure:git
> [email protected] configure:git /home/travis/build/brandongregoryscott/AndcultureCode.Cli
> echo Ensuring git hooksPath is set to .githooks directory; git config core.hooksPath .githooks; chmod +x .githooks/*
Ensuring git hooksPath is set to .githooks directory
> [email protected] preinstall /home/travis/build/brandongregoryscott/AndcultureCode.Cli/node_modules/andculturecode-javascript-core
> npm run configure:git
> [email protected] configure:git /home/travis/build/brandongregoryscott/AndcultureCode.Cli/node_modules/andculturecode-javascript-core
> echo Ensuring git hooksPath is set to .githooks directory; git config core.hooksPath .githooks; chmod +x .githooks/*
Ensuring git hooksPath is set to .githooks directory
chmod: cannot access '.githooks/*': No such file or directory
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] configure:git: `echo Ensuring git hooksPath is set to .githooks directory; git config core.hooksPath .githooks; chmod +x .githooks/*`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] configure:git script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?
npm ERR! A complete log of this run can be found in:
npm ERR!     /home/travis/.npm/_logs/2020-09-23T13_11_37_403Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] preinstall: `npm run configure:git`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] preinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR!     /home/travis/.npm/_logs/2020-09-23T13_11_37_430Z-debug.log

Consider removing peer dependency usage directly in exported objects

Where possible, we should consider updating any currently exported module objects that reference peer dependencies directly and instead reference a private function that calls the peer dependency. This will eliminate errors if a consumer does not reference the peer dependency library before referencing the global distribution package

Port 'UnitOfTime' enum

Port a generic 'UnitOfTime' enum for ease of use with libraries like momentjs

/**
 * Typed enum based on `moment`'s unitOfTime.Base type which does not seem to be publicly exported
 *
 * @export
 * @enum {number}
 */
export enum UnitOfTime {
    Day = "day",
    Days = "days",
    Hour = "hour",
    Hours = "hours",
    Millisecond = "millisecond",
    Milliseconds = "milliseconds",
    Minute = "minute",
    Minutes = "minutes",
    Month = "month",
    Months = "months",
    Second = "second",
    Seconds = "seconds",
    Week = "week",
    Weeks = "weeks",
    Year = "year",
    Years = "years",
}

Add functionality to pull culture from route

Similar to the cultureCodeFromQueryString function in LocalizationUtils, we'd like the ability to pull the culture code from the current route. The detectCultureCode function may need to be modified to support this, since right now it is only pulling from the query param or defaulting to English.

Move @types/lodash to production deps

Being we are forwarding lodash members in various utils, to keep projects from requiring the addition of the types, we could forward them automatically by moving '@types/lodash' to production deps.

npm run watch no longer runs tsc --watch

Looks like the watch npm script is no longer forwarding the --watch param to tsc correctly, probably due to the additional steps that were added (webpack && npm run validate-peer-dependencies). It acts just like the build step now, exiting after the documentation has been generated.

A solution would be to swap out the npm run build call with tsc directly:

"watch": "tsc --pretty --watch",

Publish process not publishing global distribution file(s)

Recently, we added support for non-modular front-end applications to utilize our AndcultureCode.Javascript.Core project via a global distribution. As it turns out, while a dist-global folder is generated as part of the npm run build command, the npm publish command is not utilizing this folder during the publish process.

Allow consumer to control 'debug' option for LocalizationUtils/i18next

Plumb through the 'debug' flag to allow consumers to control whether or not i18next logs debugging info to the console. Right now it is set to EnvironmentUtils.isDevelopment(), but it is quite chatty and it would be nice to be able to turn it off.

Consider making the option in the initialization options object nullable, and defaulting to EnvironmentUtils.isDevelopment() if not provided.

Update custom Constructor type to better align with generic constructor from TS Handbook

While the current version of the Constructor type seems to work, we recently encountered a scenario where we needed to leverage TS Mixins to extend a base class. The generic constructor signature they provide in the example docs has the values rest parameter typed as any[], not any, and would not accept otherwise. Thinking about it more, it probably should be any[].

Suggested signature (reference):

export type Constructor<T = {}> = new (...values: any[]) => T;

Implementation of all core functionality into an AndcultureCode window namespace?

In terms of projects that do not leverage module based or TypeScript based systems (think Sitefinity and Anthm), I do not a see a way within this repo to output these core functionalities into a shared, single javascript library that something like Sitefinity could reference. What I'm thinking is that we add a simple exported function (something like initCoreWindowNamespace()) to initialize all core functionality to the window by binding it to a namespace (something like com.andculturecode). Then we could have this funcitonality readily available through namespacing such as com.andculturecode.coreutils and com.andculturecode.emailconstants, com.andculturecode.contenttype, etc.... Thoughts?

Module not found: Can't resolve 'utilities/collection-utils'

This one was me ๐Ÿคฆ Looks like my editor put in an absolute path based on the tsconfig baseUrl, which breaks in the transpiled JS.

Failed to compile.

./node_modules/andculturecode-javascript-core/dist/utilities/service-utils.js
Module not found: Can't resolve 'utilities/collection-utils' in '/Users/Brandon/SpotifySync/frontend/node_modules/andculturecode-javascript-core/dist/utilities'

Cannot find module 'query-string' from 'route-utils.js'

Wanted to update andculturecode-javascript-react to use the latest version of this package, 0.0.8, and the tests for that project are now bombing out. Looks like query-string will need to be moved to a prod dependency in package.json. Again, not direly urgent - these packages are very much a work-in-progress. I'll backtrack on the version upgrade for now, since 0.0.7 seems to be running without issue.

 FAIL  src/utilities/route-utils.test.ts
  โ— Test suite failed to run

    Cannot find module 'query-string' from 'route-utils.js'

    Require stack:
      node_modules/andculturecode-javascript-core/dist/utilities/route-utils.js
      node_modules/andculturecode-javascript-core/dist/index.js
      src/utilities/route-utils.ts
      src/utilities/route-utils.test.ts

      at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:299:11)
      at Object.<anonymous> (node_modules/andculturecode-javascript-core/src/utilities/route-utils.ts:1:1)

Port 'PagedQuery' interface

Simple new interface for consumers to extend when building out list query parameter interfaces, something that would define skip and take params.

In our current project, I believe they are optional - but I wonder if we should make them required in the interface, and let the consumer decide if they should be optional (by wrapping the interface as Partial<PagedQueryParams>)

Update `Do.try` to allow configuring a default error handler

It would be really useful to be able to, at a global level, configure a default error handler which will always run on error, regardless of whether a catch() call exists in the call chain.

One example use-case would be adding a global error handler to console.error the results on error in the development environment.

ServiceUtils.mapPagedAxiosResponse returns rowCount of current result set, not total result set

Looks like this was lost in translation when porting

rowCount on the ServiceResponse is being set from data.resultObject.length (row count of the currently returned set), when it really should be set off of data.rowCount (total result set of the current query) which matches our C# PagedResult model:

https://github.com/AndcultureCode/AndcultureCode.JavaScript.Core/blob/master/src/utilities/service-utils.ts#L138

    return {
        results: new ResultRecord<TRecord[]>(data),
        resultObjects: resultObjects,
        rowCount: data?.resultObject?.length ?? 0, // should be rowCount: data.rowCount,
        status: axiosResponse.status,
    };

https://github.com/AndcultureCode/AndcultureCode.CSharp.Core/blob/master/src/AndcultureCode.CSharp.Core/Models/Errors/PagedResult.cs

        public T                          ResultObject   { get; set; }
        public long                       RowCount       { get; set; }

I think this transformation method is used for all list service calls, whether or not the controller is returning paged results. Maybe it would be best to default it to the current calculated value if data.rowCount is null or undefined.

Add type guard for RecordUtils.isRecord

Changing the return type for RecordUtils.isRecord to be maybeRecord is T should alleviate the need to cast the record after calling the function and verifying it is an instance of T.

Currently:

const maybeRecord: any = new UserRecord();

if (RecordUtils.isRecord(maybeRecord, UserRecord)) {
    // in order to call any `UserRecord` functions here, we need to cast it first, or TS still thinks it is any
    console.log(`First name: ${(maybeRecord as UserRecord).getFirstName()}`);
}

After:

const maybeRecord: any = new UserRecord();

if (RecordUtils.isRecord(maybeRecord, UserRecord)) {
    // TS now knows maybeRecord *is* a UserRecord
    console.log(`First name: ${maybeRecord.getFirstName()}`);
}

Update RouteUtils.appendQueryParams to use QueryString to build string

Currently, passing an array as a query param will generate a comma separated list, which the backend receiving the quest may not support parsing out-of-the-box. The QueryString library we are already leveraging for the queryStringToObject method is more configurable and can generate arrays in several different formats.

We'll want to swap out the instantiation of URLSearchParams for building the string to use QueryString.stringify(object) instead. Make sure tests are added or updated with this change.

Export intersection function from lodash

It'd be nice to have at least one of the intersections functions from lodash. The intersectionWith function seems to give the most flexibility with a comparator function for each element:

https://lodash.com/docs/4.17.15#intersectionWith

var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
 
_.intersectionWith(objects, others, _.isEqual);
// => [{ 'x': 1, 'y': 2 }]

Forward this function from CollectionUtils

Declaration files do not retain JSDoc comments

After publish, the JSDoc comments are not retained in neither the typescript declaration files or transpiled javascript. The reason being this line:
https://github.com/AndcultureCode/AndcultureCode.JavaScript.React/blob/c5d923dc395e1fcc1943ac12f91e03f5194bc9a7/tsconfig.json#L18

This is a known issue, but there still isn't a solution that allows for removing comments but still keeping the JSDoc comments. See here: microsoft/TypeScript#14619

The simplest solution for the time being is to set "removeComments": false

Similar to rsm-hcd/AndcultureCode.JavaScript.React#37

StringUtils.isEmpty type guard types value as 'never' when false

Attempted upgrading a client project to 0.4.0 to leverage the new type guards and I believe this is incorrect:

image

If StringUtils.isEmpty returns true, it should probably act like the CollectionUtils.isEmpty function and return value is undefined. Otherwise, when it is false, the TS compiler thinks it is never and you need to force it as non-null with !

image

Port `TargetTypes` enum

Port an enum for Anchor TargetTypes:

export enum TargetTypes {
Blank = "_blank",
Parent = "_parent",
Self = "_self",
Top = "_top",
}

Update rosie/jest to be prod deps, or exclude tests/mocks/factories from dist

Running into a similar issue to AndcultureCode.JavaScript.React#7 when importing this package - I think we need to remove the exports for tests/ and __mocks__, or update rosie and jest to be production dependencies. I'm not sure there's really a benefit to exporting these, unless we find them useful to leverage across packages for their respective testing suites.

At that point, it might be worth breaking out into a separate testing package, similar to our C# testing package.

Add Lodash chunk and flatten to collection utils

We have found a use for the Lodash flatten and chunk methods in a client project. Add them as methods in src/utilities/collection-utils.ts.

An alternative would be to make all Lodash methods available from AndcultureCode.JavaScript.Core.

The implementation in the client project has been tagged with this issue for reference.

Rename default branch from "master" to "main".

Feature request

What is the expected behavior?
To have the default branch named main instead of master

What is motivation or use case for adding/changing the behavior?
Removing terminology in technology evocative of racial inequality.

How should this be implemented in your opinion?
Following Scott Hanselman's advice

  1. Move master to main (maintains branch history)
git branch -m master main
git push -u origin main
  1. Update the default branch in repo settings from master to main.
  2. Repoint HEAD, and delete master branch.
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
git push origin --delete master

Are you willing to work on this yourself?
no

Implement network information utilities

All modern browsers offer the Navigator.onLine property, and most modern browsers offer some form of NetworkInformation, Safari and Firefox being the exception. Having a common way of getting this information enables online/offline scenarios in the browser.

This is a proposal to merge the two into a common utility as well as offer up a much needed interface for typescript.

The key interfaces for this:

enum NetworkType {
    Bluetooth = "bluetooth",
    Cellular = "cellular",
    Ethernet = "ethernet",
    None = "none",
    Wifi = "wifi",
    Wimax = "wimax",
    Other = "other",
    Uknown = "unknown",
}

enum NetworkEffectiveType {
    Slow2g = "slow-2g",
    Cellular2g = "2g",
    Cellular3g = "3g",
    Cellular4g = "4g",
}

interface NetworkInformation {
    downlink?: number;
    downlinkMax?: number;
    effectiveType?: NetworkEffectiveType;
    saveData?: boolean;
    type?: NetworkType;
}

interface NetworkState extends NetworkInformation {
    isOnline: boolean;
}

Identify and add Type Guards to methods that return a boolean

For methods that return a boolean value, extra type introspection can be given to the typescript compiler and language service by utilizing type guards. This doesn't apply to all methods that return a boolean, but it would be good update those that have been identified as one's that would benefit.

Typescript Docs:
https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards

For context, an example,

const hasValue = (value?: string): boolean =>
    // toString is called here to ensure handling all edge cases when a non string value is passed in this function
    value != null && value?.toString().trim() !== "";

by adding a type guard to the method,

const hasValue = (value?: string): value is string =>
    // toString is called here to ensure handling all edge cases when a non string value is passed in this function
    value != null && value?.toString().trim() !== "";

any line referencing the string that's run through hasValue and is returned as true, the compiler knows that the value is a string and not string | undefined

Identified methods:

  • StringUtils.hasValue
  • StringUtils.isValidEmail
  • CollectionUtils.hasValues
  • CollectionUtils.isNotEmpty

Remove baseUrl from tsconfig.json

Because baseUrl is defined as ./src in the tsconfig.json file, editors like VSCode will automatically import modules relative to that path instead of relative to their location.

In a normal project setting, this would be preferred - it cleans up the import pathing, and we know we're always going to be importing from under src anyway.

Nothing appears to be wrong when you're working in the context of this project, but when the Typescript is compiled down to plain JS, the imports get mucked up and modules won't resolve correctly. See #17 for an example of this.

We should remove this setting and verify the project still runs/builds as expected.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.