Skip to content

Commit

Permalink
📚 Add relevant readme and increment version number
Browse files Browse the repository at this point in the history
  • Loading branch information
actuallymentor committed Nov 6, 2023
1 parent defcdd6 commit 2650078
Show file tree
Hide file tree
Showing 10 changed files with 212 additions and 73 deletions.
40 changes: 40 additions & 0 deletions .github/workflows/deploy-to-npm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Deploy to npm

on:
push:
branches:
- main
paths:
- "package.json"
- ".github/workflows/deploy-to-npm.yml"

jobs:
# Deploy npm module
deploy-npm-module:
name: Deploy changes to npm

runs-on: ubuntu-latest

steps:
# Environment and dependency setup
- name: Cloning repository
uses: actions/checkout@v4

- name: Set up Node.js (.nvmrc)
uses: actions/setup-node@v3
with:
node-version-file: ".nvmrc"
cache: "npm"

# install dependencies
- name: Install dependencies
run: npm ci

- name: Build module files
run: npm run build

- name: "Publish to NPM"
run: |
npm publish --access public
env:
NPM_ACCESS_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }}
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
18
20
51 changes: 5 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,49 +1,8 @@
# NPM package template
# POAP Data validations and sanetisers

> Note: this repo is a work in progress
This package contains a number of regex-based validations as well as string sanetisers that are common in POAP-related dApps.

This template by default assumes you are building a module that should run in `node.js` but also the browser. It assumes you want to ship both raw and bundled & minified versions of your library. If you disable `package.json` fields for specific platforms, the build process will skip building them
You can view the complete list of included elements here:

This repository is configured by default with `eslint` and `husky` based on the preferences of the [POAP Skunkworks team](https://github.com/poap-xyz/skunk-linter/).

This repository also assumed you will be publishing new versions through Github actions.

## One-time setup

1. Generate an npm access token [here](https://www.npmjs.com/settings/actuallymentor/tokens)
- ideally use a granular access token that has read/write only to the package you are creating
- granular access tokens _expire_, so make sure you keep that in account (hopefully npm optioanlly changes this soon)
2. Add it as a Github Actions secret with the name `NPM_ACCESS_TOKEN`
3. New versions are deployed when you push code with a new `version` in `package.json`
- It's recommended to use strict [Semver](https://semver.org/) for this
4. Change the `package.json` fields: `name`, `description`, `author`, and `license` as you see fit
5. Disable package fields that are not useful to your project
- Browser module: remove `package.module` and `package.exports.node`
- Node-only module: remove `package.browser`

## Setting up previews

The preview templates are in `previews`. The default preview formats are a `react.js` app and a default `node.js` environment.

The local publishing of your package is done by running `npm run publish:local` which uses `yalc` under the hood.

When setting up your package, make sure to:

1. Change the `package.name` field
2. Change it in the `previews/{react,node}/package.json` `name` fields too
3. Run `npm run publish:local` in the root directory
4. Run `yalc add your-package-name` in the `previews/{react,node}` folders

## Writing your code

All source files are in `src` and the default entry point is `index.js`. To publish changes to your local preview in `previews/` you can run `npm run build && npm run publish:local`.

## Publishing locally

If you want to deploy a new version without pushing code to Github, add your access token to a `.npntoken` file in the project root. Then run `npm publish` to publish your package.

## Changing defaults

You might have other assumptions than I did when creating this template. Chief among them, consider:

1. Whether the `esbuild.mjs` settings make sense for your project
- [View all regex validations](./src/modules/validations.js)
- [View all sanitisation functions](./src/modules/sanitisers.js)
2 changes: 1 addition & 1 deletion esbuild.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as esbuild from 'esbuild'

// Set the LTS version to support
// see https://github.com/nodejs/release#release-schedule
const node_lts_version = 18
const node_lts_version = 20
const oldest_node_to_support = '6.10'

// Set browser support
Expand Down
15 changes: 13 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 3 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"name": "xplatform-npm-package",
"name": "@poap/sane-data",
"private": false,
"version": "0.0.1",
"description": "This is a template repository for the creation of new npm packages",
"description": "A collection of data validations and sanetisers",
"main": "./src/index.js",
"browser": "./dist/browser/index.js",
"module": "./dist/legacy-node/index.js",
Expand Down Expand Up @@ -30,8 +31,5 @@
"eslint-plugin-react": "^7.33.2",
"husky": "^8.0.3",
"yalc": "^1.0.0-pre.53"
},
"dependencies": {
"xplatform-npm-package": "file:.yalc/xplatform-npm-package"
}
}
6 changes: 5 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
export { log } from './modules/helpers.js'
// Export all validations
export * from './modules/validations'

// Export all sanitisers
export * from './modules/sanitisers'
17 changes: 0 additions & 17 deletions src/modules/helpers.js

This file was deleted.

116 changes: 116 additions & 0 deletions src/modules/sanitisers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/**
* General purpose sanitiser
* @param {String} input - Input to be sanetised
* @param {String} type - String that describes the input type, used for error messaging
* @param {RegExp} regex - Regular expression to match the input against
* @param {Boolean} throw_on_fail - Whether to throw an error if the input fails validation
* @returns a lowercased and trimmed string version of the input
*/
const sanetize = ( input, type, regex, throw_on_fail = true ) => {

// Check for validation match
if( !`${ input }`.match( regex ) && throw_on_fail ) throw new Error( `${ type } input ${ input } is not valid` )

// If string is invalid, but throwing is disabled, log a warning
if( !`${ input }`.match( regex ) && !throw_on_fail ) console.warn( `${ type } input ${ input } is not valid` )

// Return normalised string version of input
return `${ input?.toLowerCase().trim() }`

}

/* /////////////////////////////////
// Ethereum related sanitisations */
// ///////////////////////////////*/

/**
* Validate and sanetise an Ethereum address. Throws on failed validation by default. NOTE: this check does not use checksummed addresses but a naive regex. If you require checksummed addresses, use the checksum function of your favored library.
* @param {String} input - Input to be sanetised
* @param {Boolean} throw_on_fail - Whether to throw an error if the input fails validation, when set to false, it will log a warning instead of throwing
* @returns {String} Validated, lowercased, trimmed string version of the input
*/
import { eth_address_regex } from './validations'
export const sanetise_eth_address = ( input, throw_on_fail = true ) => sanetize(
input,
'Ethereum address',
eth_address_regex,
throw_on_fail
)

/**
* Validate and sanetise an Ethereum Name Service address. Throws on failed validation by default. NOTE: this allowd all DNSSEC enabled domain names
* @param {String} input - Input to be sanetised
* @param {Boolean} throw_on_fail - Whether to throw an error if the input fails validation, when set to false, it will log a warning instead of throwing
* @returns {String} Validated, lowercased, trimmed string version of the input
*/
import { ens_regex } from './validations'
export const sanetise_ens_address = ( input, throw_on_fail = true ) => sanetize(
input,
'Ethereum ENS',
ens_regex,
throw_on_fail
)

/**
* Validate and sanetise an Ethereum address OR an Ethereum Name Service address. Throws on failed validation by default. NOTE: this check does not use checksummed addresses but a naive regex. If you require checksummed addresses, use the checksum function of your favored library. The ENS addresses allow all DNSSEC enabled domain names
* @param {String} input - Input to be sanetised
* @param {Boolean} throw_on_fail - Whether to throw an error if the input fails validation, when set to false, it will log a warning instead of throwing
* @returns {String} Validated, lowercased, trimmed string version of the input
*/
import { eth_or_ens_address_regex } from './validations'
export const sanetise_eth_or_ens_address = ( input, throw_on_fail = true ) => sanetize(
input,
'Ethereum address or ENS',
eth_or_ens_address_regex,
throw_on_fail
)

/* ///////////////////////////////
// POAP related sanitisations
// /////////////////////////////*/

/**
* Validate and sanetise a POAP drop ID. Throws on failed validation by default. NOTE: drop IDs are numbers, but this function returns a string. If you rely on types, be sure to cast the return value to a number if you need that.
* @param {String} input - Input to be sanetised
* @param {Boolean} throw_on_fail - Whether to throw an error if the input fails validation, when set to false, it will log a warning instead of throwing
* @returns {String} Validated, lowercased, trimmed string version of the input
*/
import { poap_id_regex } from './validations'
export const sanetise_poap_id = ( input, throw_on_fail = true ) => sanetize(
input,
'POAP ID',
poap_id_regex,
throw_on_fail
)

/**
* Validate and sanetise a POAP drop ID. Throws on failed validation by default. NOTE: drop IDs are numbers, but this function returns a string. If you rely on types, be sure to cast the return value to a number if you need that.
* @param {String} input - Input to be sanetised
* @param {Boolean} throw_on_fail - Whether to throw an error if the input fails validation, when set to false, it will log a warning instead of throwing
* @returns {String} Validated, lowercased, trimmed string version of the input
*/
import { poap_edit_code_regex } from './validations'
export const sanetise_poap_edit_code = ( input, throw_on_fail = true ) => sanetize(
input,
'POAP edit code',
poap_edit_code_regex,
throw_on_fail
)

/* ///////////////////////////////
// Web2 related sanitisations
// /////////////////////////////*/

/**
* Validate and sanetise an email address. Throws on failed validation by default.
* @param {String} input - Input to be sanetised
* @param {Boolean} throw_on_fail - Whether to throw an error if the input fails validation, when set to false, it will log a warning instead of throwing
* @returns {String} Validated, lowercased, trimmed string version of the input
*/
import { email_regex } from './validations'
export const sanetise_email = ( input, throw_on_fail = true ) => sanetize(
input,
'email',
email_regex,
throw_on_fail
)
28 changes: 28 additions & 0 deletions src/modules/validations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* ///////////////////////////////
// Ethereum-related validations */

// Valid Ethereum address
export const eth_address_regex = /(0x[a-f0-9]{40})/i

// Valid ENS regex, note that this may be any TLD or subdomain that supports DNSSEC
// valid domain names are ASCII, case-insensitive, and may contain digits, hyphens, and dots, but may not start with a hyphen (ending was illegal but is ok since RFC 2181)
// see https://en.wikipedia.org/wiki/Hostname#Syntax
export const ens_regex = /^(?!-)(?:[a-zA-Z0-9-]{1,63}(?<!-)\.)+(?:[a-zA-Z]{2,})$/i

// Combined regex for Ethereum address or ENS name
export const eth_or_ens_address_regex = new RegExp( `(${ eth_address_regex.source }|${ ens_regex.source })`, 'i' )

/* ///////////////////////////////
// Web2 reated validations */

// Taken from https://emailregex.com/
export const email_regex = /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/i

/* ///////////////////////////////
// POAP related validations */

// Valid POAP ID
export const poap_id_regex = /([0-9]+)/i

// Valid POAP edit code
export const poap_edit_code_regex = /([0-9]{6})/i

0 comments on commit 2650078

Please sign in to comment.