Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

hokey-cokey

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hokey-cokey - npm Package Compare versions

Comparing version 1.0.1 to 1.1.0

test/params.test.js

48

lib/exports.js

@@ -11,7 +11,7 @@ // RegExp to find named variables in several formats e.g. `:a`, `${b}`, `{{c}}` or `{d}`

/**
* Split up a template into an array of separator / param / separator / param / separator
* Split up a template into an array of separator → param → separator → param → separator
* i.e. odd numbers are separators (possibly zero length) and even numbers are params.
*
* @param {string} template The template including template parameters, e.g. `:name-${country}/{city}`
* @returns {string[]} Array of strings like separator / param / separator / param / separator
* @returns {string[]} Array of strings alternating separator and param.
*/

@@ -62,2 +62,21 @@ function split(template) {

/**
* Get list of params named in a template string.
*
* @param {string} template The template including template parameters, e.g. `:name-${country}/{city}`
* @returns {string[]} Array of clean string names of found params, e.g. `["name", "country", "city"]`
*/
function params(template) {
// Checks.
if (typeof template !== "string") throw new TypeError("params(): template must be string");
// Get chunks, filter out separators (zero-index even numbers), and map to clean names.
const names = split(template)
.filter((c, i) => i % 2)
.map(cleanParam);
// Return names (frozen).
return Object.freeze(names);
}
/**
* Turn ":year-:month" and "2016-06..." etc ing `{ year: "2016"... }` etc.

@@ -118,4 +137,4 @@ *

* @param {string} template The template including template parameters, e.g. `:name-${country}/{city}`
* @param {string} values An object containing values, e.g. `{ name: "Dave", country: "UK", city: "Manchester" }`
* @return {Object} The rendered string, e.g. `Dave-UK/Manchester`
* @param {Object|string|Function} values An object containing values, e.g. `{ name: "Dave", country: "UK", city: "Manchester" }` (functions are called, everything else converted to string), or a function or string to use for all parameters.
* @return {string} The rendered string, e.g. `Dave-UK/Manchester`
*

@@ -127,3 +146,3 @@ * @throws {ReferenceError} If a param in the template string is not specified in values.

if (typeof template !== "string") throw new TypeError("render(): template must be string");
if (typeof values !== "object" || values === null) throw new TypeError("render(): values must be object");
if (typeof values === "undefined") throw new TypeError("render(): values must be defined");

@@ -140,8 +159,20 @@ // Vars.

const name = cleanParam(param);
let value;
// Missing in params?
if (!values.hasOwnProperty(name)) throw new Error(`render(): values.${name} must be set`);
// Switch on values type.
if (typeof values === "function") {
// Functions are called.
value = values(name);
} else if (typeof values === "object" && values !== null) {
// Object use named key.
if (!values.hasOwnProperty(name)) throw new Error(`render(): values.${name} must be set`);
const v = values[name];
value = typeof v === "function" ? v() : v;
} else {
// Strings are used directly.
value = "" + values;
}
// Update output.
output = output.replace(param, values[name]);
output = output.replace(param, value);
}

@@ -155,3 +186,4 @@

module.exports.split = split;
module.exports.params = params;
module.exports.extract = extract;
module.exports.render = render;

2

package.json
{
"name": "hokey-cokey",
"description": "Render values into templates OR extract values out of templates. That's what it's all about.",
"version": "1.0.1",
"version": "1.1.0",
"license": "0BSD",

@@ -6,0 +6,0 @@ "repository": {

@@ -12,8 +12,8 @@ # Hokey Cokey! Simple string template rendering and parameter value extracting

**Extract:**
- Match a string (e.g. `places/france/paris`) against a template (e.g. `places/:country/{city}`)
- Return found values (e.g. `{ country: "france", city: "paris" }`)
- Match a target string against a template e.g. `places/france/paris` and `places/:country/{city}`
- Return an object listing found values e.g. `{ country: "france", city: "paris" }`
**Render:**
- With a template string (e.g. `places/${country}/:city`) and an object of values (e.g. `{ country: "france", city: "paris" }`)
- Return the rendered output string after variables have been rendered in (e.g. `places/france/paris`).
- Take a template string and merge in some values e.g. `places/${country}/:city` and `{ country: "france", city: "paris" }`
- Return the rendered string after variables have been inserted e.g. `places/france/paris`

@@ -37,20 +37,51 @@ **Things to know:**

### `extract()`: Get values out of a template
### `extract(template: string, target: string)` Extract values from a string
Extracts a set of values out of a target string based on a template string.
- `template` must be a string containing one or more parameters in any allowed format
- Returns an object in `parameter: value` format
```js
const { extract } = require('hokey-cokey');
const values = extract("places/{country}/{city}", "places/france/paris");
// { country: "france", city: "paris" }
console.log(values);
// Extract the values.
extract("places/{country}/{city}", "places/france/paris"); // { country: "france", city: "paris" }
extract("places/:country/:city", "places/france/paris"); // { country: "france", city: "paris" }
```
### `render()`: Inject values into a template
### `render(template, values)` Inject values into a template
Render a set of values into a template string.
- `template` must be a string containing one or more parameters in any allowed format
- `values` can be:
- An object containing string or function keys (keys must correspond to parameters in the template or render will fail)
- A function called for each parameter (receives the parameter name)
- A single string used for all parameters
- Returns the rendered string
```js
const { render } = require("hokey-cokey");
const output = render("blogs-:category-:slug", { category: "cheeses", slug: "stilton" });
// "blogs-cheeses-stilton"
console.log(output);
```
// Render the template with an object.
render("blogs-:category-:slug", { category: "cheeses", slug: "stilton" }); // blogs-cheeses-stilton
render("blogs-:category-:slug", "Arrrrgh"); // blogs-Arrrrgh-Arrrrgh
render("blogs-:category-:slug", (p) => p.toUpperCase()); // blogs-CATEGORY-SLUG
```
### `params(template)` Get parameter names from template string
Parse a template string and return an array of found variables that were found.
- `template` must be a string containing one or more parameters in any allowed format
- Returns an array of string parameter names that were found in the template
```js
const { params } = require("hokey-cokey");
// Extract the parameter names.
params("{username}@{domain}"); // ["username", "domain"]
params(":name // ${age}"); // ["name", "age"]
```

@@ -5,3 +5,13 @@ const { render } = require("../");

describe("render()", () => {
test("Returns correct path", () => {
test("String values", () => {
expect(render("/a", "123")).toBe("/a");
expect(render("/:a", "123")).toBe("/123");
expect(render("/:a/:b", "123")).toBe("/123/123");
});
test("Function values", () => {
expect(render("/a", p => p)).toBe("/a");
expect(render("/:a", p => p)).toBe("/a");
expect(render("/:a/:b", p => p)).toBe("/a/b");
});
test("Object values with string properties", () => {
expect(render("/a", {})).toBe("/a");

@@ -11,2 +21,10 @@ expect(render("/:a", { a: "1" })).toBe("/1");

});
test("Object values with non-string properties", () => {
expect(render("/:a/:b", { a: 1, b: 2 })).toBe("/1/2");
expect(render("/:a/:b", { a: true, b: false })).toBe("/true/false");
expect(render("/:a/:b", { a: null, b: undefined })).toBe("/null/undefined");
});
test("Object values with function properties", () => {
expect(render("/:a/:b", { a: () => "1", b: () => "2" })).toBe("/1/2");
});
test("TypeError for wrong input", () => {

@@ -17,6 +35,3 @@ expect(() => render(123, {})).toThrow("render(): template must be string");

expect(() => render(String, {})).toThrow(TypeError);
expect(() => render("/a", null)).toThrow("render(): values must be object");
expect(() => render("/a", null)).toThrow(TypeError);
expect(() => render("/a", false)).toThrow(TypeError);
expect(() => render("/a", 123)).toThrow(TypeError);
expect(() => render("/a", undefined)).toThrow("render(): values must be defined");
});

@@ -23,0 +38,0 @@ test("TypeError for missing parameters", () => {

@@ -16,6 +16,6 @@ const { split } = require("../");

test("Returned array is frozen", () => {
const breakdown = split("");
expect(Object.isFrozen(breakdown)).toBe(true);
expect(() => breakdown.push("aaaa")).toThrow(TypeError);
expect(() => breakdown.push("aaaa")).toThrow("not extensible");
const chunks = split("");
expect(Object.isFrozen(chunks)).toBe(true);
expect(() => chunks.push("aaaa")).toThrow(TypeError);
expect(() => chunks.push("aaaa")).toThrow("not extensible");
});

@@ -22,0 +22,0 @@ test("TypeError if input is not string", () => {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc