shinkansen-rails 1.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ . "$(dirname "$0")/_/husky.sh"
3
+
4
+ npm run pre-commit
package/README.md ADDED
@@ -0,0 +1,36 @@
1
+ ## `shinkansen-rails`
2
+
3
+ # Shinkansen Rails
4
+
5
+ *Rails* transforms objects into strings to be consumed by `<Link />` components for *React Router*.
6
+
7
+ ## Usage
8
+
9
+ ```javascript
10
+ import {
11
+ Rails
12
+ } from 'shinkansen-rails'
13
+ ```
14
+
15
+ *Rails* exposes the methods `pattern`, `go`, `to`, and `rail`.
16
+
17
+ ```javascript
18
+ export class Rails {
19
+ static pattern () { }
20
+ static go () { }
21
+ static to () { }
22
+ static rail () { }
23
+ }
24
+ ```
25
+
26
+ - `pattern` returns a string which is the transformation pattern
27
+ - `go` returns a boolean which describes whether an object can be transformed by the pattern
28
+ - `to` returns a string which is the product of that transformation
29
+ - `rail` caches and returns a product of `to`
30
+
31
+ The method `rail` should be used whenever the computation is (or expected to be) idempotent.
32
+
33
+ ## See also
34
+
35
+ - [Shinkansen Gears](https://github.com/modernpoacher/shinkansen-gears)
36
+ - [Shinkansen Pantograph](https://github.com/modernpoacher/shinkansen-pantograph)
@@ -0,0 +1,61 @@
1
+ const debug = require('debug')
2
+
3
+ const log = debug('shinkansen-rails')
4
+
5
+ const {
6
+ env: {
7
+ NODE_ENV = 'development'
8
+ }
9
+ } = process
10
+
11
+ log('`shinkansen` is awake')
12
+
13
+ function env () {
14
+ log({ NODE_ENV })
15
+
16
+ return (
17
+ NODE_ENV === 'production'
18
+ )
19
+ }
20
+
21
+ const presets = [
22
+ [
23
+ '@babel/env', {
24
+ targets: {
25
+ node: '12.19.0',
26
+ browsers: [
27
+ 'last 4 versions',
28
+ 'safari >= 9',
29
+ 'ios >= 8',
30
+ 'ie >= 9',
31
+ '> 2%'
32
+ ]
33
+ },
34
+ useBuiltIns: 'usage',
35
+ corejs: 3
36
+ }
37
+ ]
38
+ ]
39
+
40
+ const plugins = [
41
+ '@babel/proposal-export-default-from',
42
+ '@babel/proposal-class-properties',
43
+ [
44
+ 'module-resolver', {
45
+ alias: {
46
+ 'shinkansen-rails': './src'
47
+ }
48
+ }
49
+ ]
50
+ ]
51
+
52
+ module.exports = (api) => {
53
+ if (api) api.cache.using(env)
54
+
55
+ return {
56
+ compact: true,
57
+ comments: false,
58
+ presets,
59
+ plugins
60
+ }
61
+ }
package/index.js ADDED
@@ -0,0 +1,7 @@
1
+ const debug = require('debug')
2
+
3
+ const log = debug('shinkansen-rails')
4
+
5
+ log('`rails` is awake')
6
+
7
+ module.exports = require('./lib')
package/lib/index.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";require("core-js/modules/es.object.define-property.js");Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"Rails",{enumerable:true,get:function get(){return _rails["default"];}});var _rails=_interopRequireDefault(require("./rails"));function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{"default":obj};}
@@ -0,0 +1 @@
1
+ "use strict";require("core-js/modules/es.object.define-property.js");Object.defineProperty(exports,"__esModule",{value:true});exports.rail=_rail;exports.go=_go;exports.to=_to;exports["default"]=exports.get=exports.has=exports.any=void 0;require("core-js/modules/es.array.iterator.js");require("core-js/modules/es.map.js");require("core-js/modules/es.object.to-string.js");require("core-js/modules/es.string.iterator.js");require("core-js/modules/web.dom-collections.iterator.js");require("core-js/modules/es.reflect.own-keys.js");require("core-js/modules/es.reflect.has.js");require("core-js/modules/es.reflect.get.js");require("core-js/modules/es.regexp.exec.js");require("core-js/modules/es.string.replace.js");require("core-js/modules/es.string.trim.js");require("core-js/modules/es.string.match.js");function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);return Constructor;}var _pattern;var map=new Map();var PATTERN='/:alpha/:omega';var CHAR32=String.fromCharCode(32);var CHAR45=String.fromCharCode(45);var any=function any(o){return!!Reflect.ownKeys(o).length;};exports.any=any;var has=function has(o,k){return Reflect.has(o,k);};exports.has=has;var get=function get(o,k){return Reflect.get(o,k);};exports.get=get;function _rail(s){return s.toLowerCase().replace(/[^\w\-\d]/g,CHAR32).trim().replace(/[\s]+/g,CHAR45).replace(/[\s\s|\-\-]+/g,CHAR45);}function _go(o,s){var b=any(o);if(b){var k;var a=s.match(/(\w+)/g);while(b&&(k=a.shift())){b=has(o,k);}}return b;}function _to(o,s){return s.replace(/(?::)(\w+)/g,function(m,k){return m?has(o,k)?get(o,k):m:m;});}var Rails=function(){function Rails(){_classCallCheck(this,Rails);}_createClass(Rails,null,[{key:"pattern",value:function pattern(p){return p?_pattern=String(p):_pattern||(_pattern=PATTERN);}},{key:"rail",value:function rail(s){var k=String(s);if(map.has(k))return map.get(k);var S=_rail(k);map.set(k,S);return S;}},{key:"go",value:function go(){var o=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};var s=arguments.length>1&&arguments[1]!==undefined?arguments[1]:Rails.pattern();return any(o)?(s=String(s))?_go(o,s):false:false;}},{key:"to",value:function to(){var o=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};var s=arguments.length>1&&arguments[1]!==undefined?arguments[1]:Rails.pattern();return any(o)?(s=String(s))?_to(o,s):s:s;}}]);return Rails;}();exports["default"]=Rails;
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "shinkansen-rails",
3
+ "version": "1.0.18",
4
+ "description": "Shinkansen Rails",
5
+ "keywords": [
6
+ "Shinkansen",
7
+ "Rails",
8
+ "Zashiki Karakuri",
9
+ "Zashiki",
10
+ "Karakuri"
11
+ ],
12
+ "main": "./index.js",
13
+ "author": "Jonathan Perry for Modern Poacher Limited <modernpoacher@modernpoacher.com>",
14
+ "license": "MIT",
15
+ "engines": {
16
+ "node": ">=12.19.0"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git@github.com/modernpoacher/shinkansen-rails.git"
21
+ },
22
+ "scripts": {
23
+ "prepublishOnly": "cross-env NODE_ENV=production npm run build",
24
+ "prebuild": "npm run clean",
25
+ "build": "npm run babel",
26
+ "build:watch": "npm run babel:watch",
27
+ "clean": "rimraf lib",
28
+ "babel": "babel src -d lib",
29
+ "babel:watch": "npm run build -- -w",
30
+ "lint": "eslint .",
31
+ "lint:fix": "npm run lint -- --fix",
32
+ "test": "NODE_ENV=test mocha -r @babel/register test --recursive",
33
+ "pre-commit": "npm run lint && npm test && npm run build && git add lib"
34
+ },
35
+ "dependencies": {
36
+ "debug": "^4.3.2"
37
+ },
38
+ "devDependencies": {
39
+ "@babel/cli": "^7.15.4",
40
+ "@babel/core": "^7.15.5",
41
+ "@babel/eslint-parser": "^7.15.4",
42
+ "@babel/plugin-proposal-class-properties": "^7.14.5",
43
+ "@babel/plugin-proposal-export-default-from": "^7.14.5",
44
+ "@babel/preset-env": "^7.15.6",
45
+ "@babel/register": "^7.15.3",
46
+ "babel-loader": "^8.2.2",
47
+ "babel-plugin-module-resolver": "^4.1.0",
48
+ "chai": "^4.3.4",
49
+ "core-js": "^3.17.3",
50
+ "cross-env": "^7.0.3",
51
+ "eslint": "^7.32.0",
52
+ "eslint-config-standard": "^16.0.3",
53
+ "eslint-import-resolver-babel-module": "^5.3.1",
54
+ "eslint-plugin-import": "^2.24.2",
55
+ "eslint-plugin-node": "^11.1.0",
56
+ "eslint-plugin-promise": "^5.1.0",
57
+ "husky": "^7.0.2",
58
+ "mocha": "^9.1.1",
59
+ "rimraf": "^3.0.2",
60
+ "sinon": "^11.1.2",
61
+ "sinon-chai": "^3.7.0"
62
+ }
63
+ }
package/src/index.js ADDED
@@ -0,0 +1 @@
1
+ export Rails from './rails'
@@ -0,0 +1,112 @@
1
+ let pattern
2
+
3
+ const map = new Map()
4
+
5
+ const PATTERN = '/:alpha/:omega'
6
+
7
+ const CHAR32 = String.fromCharCode(32)
8
+ const CHAR45 = String.fromCharCode(45)
9
+
10
+ export const any = (o) => !!Reflect.ownKeys(o).length
11
+ export const has = (o, k) => Reflect.has(o, k)
12
+ export const get = (o, k) => Reflect.get(o, k)
13
+
14
+ /**
15
+ * Format simple latin character strings as URL compatible
16
+ *
17
+ * @param {String} s The string to convert
18
+ * @return {String} The string, converted
19
+ */
20
+ export function rail (s) {
21
+ return (
22
+ s.toLowerCase().replace(/[^\w\-\d]/g, CHAR32).trim().replace(/[\s]+/g, CHAR45).replace(/[\s\s|\-\-]+/g, CHAR45)
23
+ )
24
+ }
25
+
26
+ /**
27
+ * Interrogate parameters to determine whether or not components can be created
28
+ *
29
+ * @param {Object} o The object containing values for the 'pattern'
30
+ * @param {String} s The 'pattern' according to which URLs should be created
31
+ * @param {Boolean} b Whether the Rails can go
32
+ * @return {Boolean}
33
+ *
34
+ * @description
35
+ *
36
+ * Split the pattern into useful strings (such that '/:alpha/:omega' becomes ['alpha', 'omega']
37
+ * For each string in the array
38
+ * If the string exists as a key in the object
39
+ * If the boolean is true
40
+ * set the boolean = whether the object has a property for that key
41
+ * return that boolean (to the loop. It doesn't exit here)
42
+ * Else set the boolean as false and return it (to the loop. It doesn't exit here, either)
43
+ * Return the boolean
44
+ *
45
+ * A `reduce` cannot break when `b` is false
46
+ */
47
+ export function go (o, s) {
48
+ let b = any(o)
49
+
50
+ if (b) {
51
+ let k
52
+ const a = s.match(/(\w+)/g)
53
+ while (b && (k = a.shift())) b = has(o, k) // it is only necessary that the `o` has key `k`. Otherwise, `b = has(o, k) && !!get(o, k)` to enforce a truthy field value for field key `k`
54
+ }
55
+
56
+ return b
57
+ }
58
+
59
+ /**
60
+ * Interrogate parameters for object field names
61
+ *
62
+ * @param {Object} o The object containing fields
63
+ * @param {String} s The string containing field names to be found
64
+ * @return {String}
65
+ *
66
+ * @description
67
+ *
68
+ * A valid object is
69
+ *
70
+ * { fieldName: 'field Value' }
71
+ *
72
+ * A valid string is
73
+ *
74
+ * /:fieldName
75
+ */
76
+ export function to (o, s) {
77
+ return (
78
+ s.replace(/(?::)(\w+)/g, (m, k) => m ? has(o, k) ? get(o, k) : m : m)
79
+ )
80
+ }
81
+
82
+ /**
83
+ * Rails.go() Boolean
84
+ * Rails.to() String
85
+ */
86
+ export default class Rails {
87
+ static pattern (p) {
88
+ return (
89
+ p ? (pattern = String(p)) : pattern || (pattern = PATTERN)
90
+ )
91
+ }
92
+
93
+ static rail (s) {
94
+ const k = String(s)
95
+ if (map.has(k)) return map.get(k)
96
+ const S = rail(k)
97
+ map.set(k, S)
98
+ return S
99
+ }
100
+
101
+ static go (o = {}, s = Rails.pattern()) {
102
+ return (
103
+ any(o) ? (s = String(s)) ? go(o, s) : false : false // return is s is truthy true then go else false
104
+ )
105
+ }
106
+
107
+ static to (o = {}, s = Rails.pattern()) {
108
+ return (
109
+ any(o) ? (s = String(s)) ? to(o, s) : s : s
110
+ )
111
+ }
112
+ }