paraphrase 3.0.0 → 3.1.0

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.
package/CHANGELOG.md CHANGED
@@ -1,21 +1,33 @@
1
+ # 3.1.0 2022-11-29
2
+
3
+ ## Features
4
+
5
+ Add type definitions for TypeScript.
6
+
7
+ ## Internal
8
+
9
+ Move to TypeScript.
10
+
1
11
  # 3.0.0 2021-09-21
2
12
 
3
13
  ## Breaking change
4
14
 
5
- ### All exports are named
15
+ - All exports are named.
16
+
6
17
  ```js
7
- import { paraphrase } from 'paraphrase'
18
+ import { paraphrase } from "paraphrase";
8
19
  ```
9
20
 
10
21
  ### Flavoured imports included
22
+
11
23
  Flavoured pre-made versions should be imported from main entry and not from directory.
24
+
12
25
  ```js
13
- import { dollar } from 'paraphrase'
26
+ import { dollar } from "paraphrase";
14
27
  ```
15
28
 
16
29
  # 2.0.0 2021-05-11
17
30
 
18
31
  ## Breaking change
19
32
 
20
- ### Remove compiled version.
21
- If you are using a bundler with babel, make sure you transpile this package to your liking
33
+ - Remove compiled version: If you are using a bundler with babel, make sure you transpile this package to your liking.
package/README.md CHANGED
@@ -11,113 +11,131 @@ npm i paraphrase
11
11
  Creates new paraphrase method instance
12
12
 
13
13
  ```js
14
- import { paraphrase } from 'paraphrase';
14
+ import { paraphrase } from "paraphrase";
15
15
  const phrase = paraphrase(/\${([^{}]*)}/gm); // Create a new phrase function using a RegExp match
16
16
 
17
- phrase('Hello, ${name}', {name: 'Martin'}); // Hello, Martin
17
+ phrase("Hello, ${name}", { name: "Martin" }); // Hello, Martin
18
18
  ```
19
19
 
20
20
  Acceptable replacements (values) are strings and numbers
21
21
 
22
22
  ### Arguments and Options
23
- One or more RegExp replacers, an optional options object at the end
24
23
 
25
- | option | meaning | type | default
26
- | - | - | - | -
27
- | recursive | Should continue to resolve result string until replacements have been exhausted | `Boolean` | `true`
28
- | resolve | Should resolve dot notations within the template | `Boolean` | `true`
29
- | clean | Should remove unmatched template instances | `Boolean` | `false`
24
+ One or more RegExp replacers, an optional options object at the end
30
25
 
26
+ | option | meaning | type | default |
27
+ | --------- | ------------------------------------------------------------------------------- | --------- | ------- |
28
+ | recursive | Should continue to resolve result string until replacements have been exhausted | `Boolean` | `true` |
29
+ | resolve | Should resolve dot notations within the template | `Boolean` | `true` |
30
+ | clean | Should remove unmatched template instances | `Boolean` | `false` |
31
31
 
32
32
  ##### Multiple replacers
33
+
33
34
  ```js
34
35
  const phrase = paraphrase(/\${([^{}]*)}/gm, /\{{([^{}]*)}}/gm);
35
36
 
36
- phrase('Hello, ${firstname} {{lastname}}', {firstname: 'Martin', 'lastname': 'Prince'}); // Hello, Martin Prince
37
+ phrase("Hello, ${firstname} {{lastname}}", {
38
+ firstname: "Martin",
39
+ lastname: "Prince",
40
+ }); // Hello, Martin Prince
37
41
  ```
38
42
 
39
43
  ##### Dot notation resolve
44
+
40
45
  Treat dots as part of the key instead of notation marks
46
+
41
47
  ```js
42
- const phrase = paraphrase(/\${([^{}]*)}/gm, {resolve: false});
48
+ const phrase = paraphrase(/\${([^{}]*)}/gm, { resolve: false });
43
49
 
44
- phrase('Hello, ${name} ${last.name}', {name: 'Martin', 'last.name': 'Prince'}); // Hello, Martin Prince
50
+ phrase("Hello, ${name} ${last.name}", {
51
+ name: "Martin",
52
+ "last.name": "Prince",
53
+ }); // Hello, Martin Prince
45
54
  ```
46
55
 
47
56
  ##### Unmatched cleanup
57
+
48
58
  Remove unmatched template instances from the result string
59
+
49
60
  ```js
50
- const phrase = paraphrase(/\${([^{}]*)}/gm, {clean: true});
61
+ const phrase = paraphrase(/\${([^{}]*)}/gm, { clean: true });
51
62
 
52
- phrase('Hello, ${firstname} ${lastname}', {firstname: 'Martin'}); // Hello, Martin
63
+ phrase("Hello, ${firstname} ${lastname}", { firstname: "Martin" }); // Hello, Martin
53
64
  ```
54
65
 
55
66
  ## Examples
67
+
56
68
  ### Objects
57
69
 
58
70
  ```js
59
- phrase('Hello, ${name}', {name: 'Martin'}); // Hello, Martin
71
+ phrase("Hello, ${name}", { name: "Martin" }); // Hello, Martin
60
72
  ```
61
73
 
62
74
  ### Objects with dot notation
63
75
 
64
76
  ```js
65
77
  const user = {
66
- name: {first: 'Martin', last: 'Prince'}
78
+ name: { first: "Martin", last: "Prince" },
67
79
  };
68
- phrase('Hello, ${name.first} ${name.last}', user); // Hello, Martin Prince
80
+ phrase("Hello, ${name.first} ${name.last}", user); // Hello, Martin Prince
69
81
  ```
70
82
 
71
83
  ### Arrays
72
84
 
73
85
  ```js
74
- phrase('Hello, ${0} ${1}', ['Martin', 'Prince']); // Hello, Martin Prince
86
+ phrase("Hello, ${0} ${1}", ["Martin", "Prince"]); // Hello, Martin Prince
75
87
  ```
76
88
 
77
89
  ### Spread arguments
78
90
 
79
91
  ```js
80
- phrase('Hello, ${0} ${1}', 'Martin', 'Prince'); // Hello, Martin Prince
92
+ phrase("Hello, ${0} ${1}", "Martin", "Prince"); // Hello, Martin Prince
81
93
  ```
82
94
 
83
95
  ## Premade
84
96
 
85
97
  ### dollar `${...}`
98
+
86
99
  ```js
87
- import { dollar as phrase } from 'paraphrase';
100
+ import { dollar as phrase } from "paraphrase";
88
101
 
89
- phrase('Hello, ${name}', {name: 'Martin'}); // Hello, Martin
102
+ phrase("Hello, ${name}", { name: "Martin" }); // Hello, Martin
90
103
  ```
91
104
 
92
105
  ### double `{{...}}`
106
+
93
107
  ```js
94
- import { double as phrase } from 'paraphrase';
108
+ import { double as phrase } from "paraphrase";
95
109
 
96
- phrase('Hello, {{name}}', {name: 'Martin'}); // Hello, Martin
110
+ phrase("Hello, {{name}}", { name: "Martin" }); // Hello, Martin
97
111
  ```
98
112
 
99
113
  ### single `{...}`
114
+
100
115
  ```js
101
- import { single as phrase } from 'paraphrase';
116
+ import { single as phrase } from "paraphrase";
102
117
 
103
- phrase('Hello, {name}', {name: 'Martin'}); // Hello, Martin
118
+ phrase("Hello, {name}", { name: "Martin" }); // Hello, Martin
104
119
  ```
105
120
 
106
121
  ### percent `%{...}` (i18n style)
122
+
107
123
  ```js
108
- const phrase = require('paraphrase/percent');
124
+ import { percent as phrase } from "paraphrase";
109
125
 
110
- phrase('Hello, %{name}', {name: 'Martin'}); // Hello, Martin
126
+ phrase("Hello, %{name}", { name: "Martin" }); // Hello, Martin
111
127
  ```
112
128
 
113
129
  ### hash `#{...}` (ruby style)
130
+
114
131
  ```js
115
- import { hash as phrase } from 'paraphrase';
132
+ import { hash as phrase } from "paraphrase";
116
133
 
117
- phrase('Hello, #{name}', {name: 'Martin'}); // Hello, Martin
134
+ phrase("Hello, #{name}", { name: "Martin" }); // Hello, Martin
118
135
  ```
119
136
 
120
137
  ### loose. Accommodate all of the above
138
+
121
139
  ```js
122
140
  import { loose as phrase } from 'paraphrase';
123
141
 
@@ -125,9 +143,11 @@ phrase('Hello, #{name.first} {name.last}', {name: { first: 'Martin', last: 'Prin
125
143
  ```
126
144
 
127
145
  ## patterns
146
+
128
147
  A paraphrase instance exposes view to its patterns array (immutable)
148
+
129
149
  ```js
130
- import { hash as phrase } from 'paraphrase';
150
+ import { hash as phrase } from "paraphrase";
131
151
 
132
- phrase.patterns // [ /#{([^{}]*)}/gm ]
152
+ phrase.patterns; // [ /#{([^{}]*)}/gm ]
133
153
  ```
package/index.js CHANGED
@@ -1,71 +1,51 @@
1
- Object.defineProperty(exports, '__esModule', { value: true });
2
-
3
- function _typeof(obj) {
4
- "@babel/helpers - typeof";
5
-
6
- if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
7
- _typeof = function (obj) {
8
- return typeof obj;
9
- };
10
- } else {
11
- _typeof = function (obj) {
12
- return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
13
- };
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
14
  }
15
-
16
- return _typeof(obj);
17
- }
18
-
19
- /**
20
- * Resolve dot notation strings
21
- *
22
- * @param {Object} context Object to start notation search (defaults to global scope)
23
- * @param {String} [string=''] Dot notation representation
24
- * @return {Any} Whatever it finds / undefined
25
- *
26
- * @example
27
- * const obj = {
28
- * top_level: {
29
- * nested: {
30
- * value: 'My Value'
31
- * }
32
- * }
33
- * };
34
- *
35
- * notate(obj, 'top_level.nested.value');
36
- * // 'My Value'
37
- *
38
- * notate(obj, 'top_level.missing.value');
39
- * // undefined
40
- */
41
- function notate(source) {
42
- var string = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
43
-
44
- if (typeof string !== 'string') {
45
- throw new TypeError("Expected notation query to be a string, instead got ".concat(_typeof(string), " (").concat(string, ")"));
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/index.ts
20
+ var src_exports = {};
21
+ __export(src_exports, {
22
+ dollar: () => dollar,
23
+ double: () => double,
24
+ hash: () => hash,
25
+ loose: () => loose,
26
+ paraphrase: () => paraphrase,
27
+ percent: () => percent,
28
+ single: () => single
29
+ });
30
+ module.exports = __toCommonJS(src_exports);
31
+
32
+ // src/notate/index.ts
33
+ function notate(source, string = "") {
34
+ if (typeof string !== "string") {
35
+ throw new TypeError(
36
+ `Expected notation query to be a string, instead got ${typeof string} (${string})`
37
+ );
46
38
  }
47
-
48
- return string.split('.').reduce(function (previous, current) {
49
- return _typeof(previous) === 'object' && previous ? previous[current] : previous;
50
- }, source);
39
+ return string.split(".").reduce(
40
+ (previous, current) => typeof previous === "object" && previous ? previous[current] : previous,
41
+ source
42
+ );
51
43
  }
52
44
 
53
- /**
54
- * Is this a basic object?
55
- * @param {any} obj
56
- * @return {boolean}
57
- */
58
- var isObject = function isObject(obj) {
59
- return "".concat(obj) === '[object Object]';
60
- };
45
+ // src/isObject/index.ts
46
+ var isObject = (obj) => `${obj}` === "[object Object]";
61
47
 
62
- /**
63
- * @property {RegExp} dollar 'Hello, ${name}'
64
- * @property {RegExp} double 'Hello, {{name}}'
65
- * @property {RegExp} single 'Hello, {name}'
66
- * @property {RegExp} hash 'Hello, #{name}'
67
- * @property {RegExp} percent 'Hello, %{name}'
68
- */
48
+ // src/flavours/index.ts
69
49
  var flavours = {
70
50
  dollar: /\${([^{}]*)}/gm,
71
51
  double: /{{([^{}]*)}}/gm,
@@ -74,92 +54,46 @@ var flavours = {
74
54
  percent: /%{([^{}]*)}/gm
75
55
  };
76
56
 
77
- /**
78
- * Valid types of results for the interpolated string
79
- * @private
80
- * @type {Array}
81
- * @member {String|Number}
82
- */
83
-
84
- var VALID_RESULT_TYPES = Object.seal(['string', 'number']);
85
- /**
86
- * Create new paraphrase method instance
87
- * @param {...RegExp[]} replacers
88
- * @param {Boolean} [options.resolve=true] Should resolve dot notation within template
89
- * @param {Boolean} [options.clean=false] Should remove unmatched template instances
90
- * @returns {Function} phraser function instance
91
- *
92
- * @example const phraser = paraphrase(/\${([^{}]*)}/gm);
93
- *
94
- * phraser('Hello, ${name}', {name: 'Martin'})
95
- */
96
-
97
- function paraphrase() {
98
- for (var _len = arguments.length, replacers = new Array(_len), _key = 0; _key < _len; _key++) {
99
- replacers[_key] = arguments[_key];
100
- }
101
-
102
- var options = {
57
+ // src/index.ts
58
+ var VALID_RESULT_TYPES = Object.seal([
59
+ "string",
60
+ "number"
61
+ ]);
62
+ function paraphrase(...args) {
63
+ const options = {
103
64
  recursive: true,
104
65
  resolve: true,
105
66
  clean: false
106
67
  };
107
-
108
- if (replacers.length && isObject(replacers[replacers.length - 1])) {
109
- Object.assign(options, replacers.pop());
68
+ if (args.length && isObject(args[args.length - 1])) {
69
+ Object.assign(options, args.pop());
110
70
  }
111
-
112
- Object.freeze(replacers);
113
- /**
114
- * phraser description
115
- * @param {String} string Template
116
- * @param {Object|(String|number)} data Data for filling
117
- * @param {...(String|number)} replacements Replacement for filling
118
- * @return {String} Result
119
- */
120
-
121
- function phraser() {
122
- var string = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
123
- var data = arguments.length > 1 ? arguments[1] : undefined;
124
-
125
- if (typeof string !== 'string') {
126
- throw new TypeError("paraphrase expects first argument to be a string, got a ".concat(_typeof(string), " (").concat(string, ")"));
71
+ const patterns = args.flat().filter((arg) => arg instanceof RegExp);
72
+ Object.freeze(patterns);
73
+ function phraser(string = "", data, ...replacements) {
74
+ if (typeof string !== "string") {
75
+ throw new TypeError(
76
+ `paraphrase expects first argument to be a string, got a ${typeof string} (${string})`
77
+ );
127
78
  }
128
-
129
79
  if (!data) {
130
80
  return string;
131
81
  }
132
-
133
- for (var _len2 = arguments.length, replacements = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
134
- replacements[_key2 - 2] = arguments[_key2];
135
- }
136
-
137
- if (VALID_RESULT_TYPES.includes(_typeof(data))) {
138
- data = [data].concat(replacements);
82
+ if (VALID_RESULT_TYPES.includes(typeof data)) {
83
+ data = [data, ...replacements];
139
84
  }
140
- /**
141
- * Replace method build with internal reference to the passed in data structure
142
- * @param {String} haystack The full string match
143
- * @param {String} needle The content to identify as data member
144
- * @return {String} Found value
145
- */
146
-
147
-
148
85
  function replace(haystack, needle) {
149
- var replacement = options.resolve ? notate(data, needle.trim()) : data[needle.trim()];
150
- return VALID_RESULT_TYPES.includes(_typeof(replacement)) ? replacement : options.clean ? '' : haystack;
86
+ const replacement = options.resolve ? notate(data, needle.trim()) : data[needle.trim()];
87
+ return VALID_RESULT_TYPES.includes(typeof replacement) ? replacement : options.clean ? "" : haystack;
151
88
  }
152
-
153
- var result = replacers.reduce(function (string, replacer) {
154
- return string.replace(replacer, replace);
155
- }, string);
156
- return !options.recursive || string === result ? result : phraser.apply(void 0, [result, data].concat(replacements));
89
+ const result = patterns.reduce(
90
+ (string2, pattern) => string2.replace(pattern, replace),
91
+ string
92
+ );
93
+ return !options.recursive || string === result ? result : phraser(result, data, ...replacements);
157
94
  }
158
-
159
- Object.defineProperty(phraser, 'patterns', {
160
- get: function get() {
161
- return replacers;
162
- }
95
+ Object.defineProperty(phraser, "patterns", {
96
+ get: () => patterns
163
97
  });
164
98
  return phraser;
165
99
  }
@@ -168,13 +102,20 @@ var double = paraphrase(flavours.double);
168
102
  var single = paraphrase(flavours.single);
169
103
  var percent = paraphrase(flavours.percent);
170
104
  var hash = paraphrase(flavours.hash);
171
- var loose = paraphrase(flavours.dollar, flavours.double, flavours.percent, flavours.hash, flavours.single);
172
-
173
- exports.dollar = dollar;
174
- exports.double = double;
175
- exports.hash = hash;
176
- exports.loose = loose;
177
- exports.paraphrase = paraphrase;
178
- exports.percent = percent;
179
- exports.single = single;
180
- //# sourceMappingURL=index.js.map
105
+ var loose = paraphrase(
106
+ flavours.dollar,
107
+ flavours.double,
108
+ flavours.percent,
109
+ flavours.hash,
110
+ flavours.single
111
+ );
112
+ // Annotate the CommonJS export names for ESM import in node:
113
+ 0 && (module.exports = {
114
+ dollar,
115
+ double,
116
+ hash,
117
+ loose,
118
+ paraphrase,
119
+ percent,
120
+ single
121
+ });
package/index.mjs CHANGED
@@ -1,69 +1,20 @@
1
- function _typeof(obj) {
2
- "@babel/helpers - typeof";
3
-
4
- if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
5
- _typeof = function (obj) {
6
- return typeof obj;
7
- };
8
- } else {
9
- _typeof = function (obj) {
10
- return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
11
- };
1
+ // src/notate/index.ts
2
+ function notate(source, string = "") {
3
+ if (typeof string !== "string") {
4
+ throw new TypeError(
5
+ `Expected notation query to be a string, instead got ${typeof string} (${string})`
6
+ );
12
7
  }
13
-
14
- return _typeof(obj);
15
- }
16
-
17
- /**
18
- * Resolve dot notation strings
19
- *
20
- * @param {Object} context Object to start notation search (defaults to global scope)
21
- * @param {String} [string=''] Dot notation representation
22
- * @return {Any} Whatever it finds / undefined
23
- *
24
- * @example
25
- * const obj = {
26
- * top_level: {
27
- * nested: {
28
- * value: 'My Value'
29
- * }
30
- * }
31
- * };
32
- *
33
- * notate(obj, 'top_level.nested.value');
34
- * // 'My Value'
35
- *
36
- * notate(obj, 'top_level.missing.value');
37
- * // undefined
38
- */
39
- function notate(source) {
40
- var string = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
41
-
42
- if (typeof string !== 'string') {
43
- throw new TypeError("Expected notation query to be a string, instead got ".concat(_typeof(string), " (").concat(string, ")"));
44
- }
45
-
46
- return string.split('.').reduce(function (previous, current) {
47
- return _typeof(previous) === 'object' && previous ? previous[current] : previous;
48
- }, source);
8
+ return string.split(".").reduce(
9
+ (previous, current) => typeof previous === "object" && previous ? previous[current] : previous,
10
+ source
11
+ );
49
12
  }
50
13
 
51
- /**
52
- * Is this a basic object?
53
- * @param {any} obj
54
- * @return {boolean}
55
- */
56
- var isObject = function isObject(obj) {
57
- return "".concat(obj) === '[object Object]';
58
- };
14
+ // src/isObject/index.ts
15
+ var isObject = (obj) => `${obj}` === "[object Object]";
59
16
 
60
- /**
61
- * @property {RegExp} dollar 'Hello, ${name}'
62
- * @property {RegExp} double 'Hello, {{name}}'
63
- * @property {RegExp} single 'Hello, {name}'
64
- * @property {RegExp} hash 'Hello, #{name}'
65
- * @property {RegExp} percent 'Hello, %{name}'
66
- */
17
+ // src/flavours/index.ts
67
18
  var flavours = {
68
19
  dollar: /\${([^{}]*)}/gm,
69
20
  double: /{{([^{}]*)}}/gm,
@@ -72,92 +23,46 @@ var flavours = {
72
23
  percent: /%{([^{}]*)}/gm
73
24
  };
74
25
 
75
- /**
76
- * Valid types of results for the interpolated string
77
- * @private
78
- * @type {Array}
79
- * @member {String|Number}
80
- */
81
-
82
- var VALID_RESULT_TYPES = Object.seal(['string', 'number']);
83
- /**
84
- * Create new paraphrase method instance
85
- * @param {...RegExp[]} replacers
86
- * @param {Boolean} [options.resolve=true] Should resolve dot notation within template
87
- * @param {Boolean} [options.clean=false] Should remove unmatched template instances
88
- * @returns {Function} phraser function instance
89
- *
90
- * @example const phraser = paraphrase(/\${([^{}]*)}/gm);
91
- *
92
- * phraser('Hello, ${name}', {name: 'Martin'})
93
- */
94
-
95
- function paraphrase() {
96
- for (var _len = arguments.length, replacers = new Array(_len), _key = 0; _key < _len; _key++) {
97
- replacers[_key] = arguments[_key];
98
- }
99
-
100
- var options = {
26
+ // src/index.ts
27
+ var VALID_RESULT_TYPES = Object.seal([
28
+ "string",
29
+ "number"
30
+ ]);
31
+ function paraphrase(...args) {
32
+ const options = {
101
33
  recursive: true,
102
34
  resolve: true,
103
35
  clean: false
104
36
  };
105
-
106
- if (replacers.length && isObject(replacers[replacers.length - 1])) {
107
- Object.assign(options, replacers.pop());
37
+ if (args.length && isObject(args[args.length - 1])) {
38
+ Object.assign(options, args.pop());
108
39
  }
109
-
110
- Object.freeze(replacers);
111
- /**
112
- * phraser description
113
- * @param {String} string Template
114
- * @param {Object|(String|number)} data Data for filling
115
- * @param {...(String|number)} replacements Replacement for filling
116
- * @return {String} Result
117
- */
118
-
119
- function phraser() {
120
- var string = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
121
- var data = arguments.length > 1 ? arguments[1] : undefined;
122
-
123
- if (typeof string !== 'string') {
124
- throw new TypeError("paraphrase expects first argument to be a string, got a ".concat(_typeof(string), " (").concat(string, ")"));
40
+ const patterns = args.flat().filter((arg) => arg instanceof RegExp);
41
+ Object.freeze(patterns);
42
+ function phraser(string = "", data, ...replacements) {
43
+ if (typeof string !== "string") {
44
+ throw new TypeError(
45
+ `paraphrase expects first argument to be a string, got a ${typeof string} (${string})`
46
+ );
125
47
  }
126
-
127
48
  if (!data) {
128
49
  return string;
129
50
  }
130
-
131
- for (var _len2 = arguments.length, replacements = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
132
- replacements[_key2 - 2] = arguments[_key2];
51
+ if (VALID_RESULT_TYPES.includes(typeof data)) {
52
+ data = [data, ...replacements];
133
53
  }
134
-
135
- if (VALID_RESULT_TYPES.includes(_typeof(data))) {
136
- data = [data].concat(replacements);
137
- }
138
- /**
139
- * Replace method build with internal reference to the passed in data structure
140
- * @param {String} haystack The full string match
141
- * @param {String} needle The content to identify as data member
142
- * @return {String} Found value
143
- */
144
-
145
-
146
54
  function replace(haystack, needle) {
147
- var replacement = options.resolve ? notate(data, needle.trim()) : data[needle.trim()];
148
- return VALID_RESULT_TYPES.includes(_typeof(replacement)) ? replacement : options.clean ? '' : haystack;
55
+ const replacement = options.resolve ? notate(data, needle.trim()) : data[needle.trim()];
56
+ return VALID_RESULT_TYPES.includes(typeof replacement) ? replacement : options.clean ? "" : haystack;
149
57
  }
150
-
151
- var result = replacers.reduce(function (string, replacer) {
152
- return string.replace(replacer, replace);
153
- }, string);
154
- return !options.recursive || string === result ? result : phraser.apply(void 0, [result, data].concat(replacements));
58
+ const result = patterns.reduce(
59
+ (string2, pattern) => string2.replace(pattern, replace),
60
+ string
61
+ );
62
+ return !options.recursive || string === result ? result : phraser(result, data, ...replacements);
155
63
  }
156
-
157
- Object.defineProperty(phraser, 'patterns', {
158
- get: function get() {
159
- return replacers;
160
- }
64
+ Object.defineProperty(phraser, "patterns", {
65
+ get: () => patterns
161
66
  });
162
67
  return phraser;
163
68
  }
@@ -166,7 +71,19 @@ var double = paraphrase(flavours.double);
166
71
  var single = paraphrase(flavours.single);
167
72
  var percent = paraphrase(flavours.percent);
168
73
  var hash = paraphrase(flavours.hash);
169
- var loose = paraphrase(flavours.dollar, flavours.double, flavours.percent, flavours.hash, flavours.single);
170
-
171
- export { dollar, double, hash, loose, paraphrase, percent, single };
172
- //# sourceMappingURL=index.mjs.map
74
+ var loose = paraphrase(
75
+ flavours.dollar,
76
+ flavours.double,
77
+ flavours.percent,
78
+ flavours.hash,
79
+ flavours.single
80
+ );
81
+ export {
82
+ dollar,
83
+ double,
84
+ hash,
85
+ loose,
86
+ paraphrase,
87
+ percent,
88
+ single
89
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "paraphrase",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "🧩 Create flavoured string template interpolation",
5
5
  "keywords": [
6
6
  "string",
@@ -24,28 +24,33 @@
24
24
  "module": "./index.mjs",
25
25
  "browser": "./index.mjs",
26
26
  "exports": {
27
+ "./package.json": "./package.json",
27
28
  ".": {
28
- "browser": "./index.mjs",
29
+ "browser": {
30
+ "import": "./index.mjs",
31
+ "require": "./index.js"
32
+ },
33
+ "node": {
34
+ "import": "./index.mjs",
35
+ "require": "./index.js"
36
+ },
29
37
  "import": "./index.mjs",
30
38
  "require": "./index.js",
31
- "node": "./index.js",
32
39
  "default": "./index.js"
33
40
  }
34
41
  },
42
+ "types": "./types/index.d.ts",
35
43
  "scripts": {
36
- "test": "mocha src/*",
37
- "lint": "standard --parser @babel/eslint-parser",
38
- "build": "rollup --config .rollup.js"
44
+ "test": "jest",
45
+ "format": "prettier --write .",
46
+ "build": "./scripts/build.sh",
47
+ "prepublishOnly": "npm run build"
39
48
  },
40
49
  "devDependencies": {
41
- "@babel/core": "^7.15.5",
42
- "@babel/eslint-parser": "^7.15.7",
43
- "@babel/preset-env": "^7.15.6",
44
- "@rollup/plugin-babel": "^5.3.0",
45
- "chai": "^4.3.4",
46
- "eslint-plugin-log": "^1.2.7",
47
- "mocha": "^9.1.1",
48
- "rollup": "^2.56.3",
49
- "standard": "^16.0.3"
50
+ "@types/jest": "^29.2.3",
51
+ "esbuild": "^0.15.16",
52
+ "jest": "^29.3.1",
53
+ "prettier": "^2.8.0",
54
+ "ts-jest": "^29.0.3"
50
55
  }
51
56
  }
@@ -0,0 +1 @@
1
+ export declare const flavours: Record<string, RegExp>;
@@ -0,0 +1,44 @@
1
+ interface IParaphraseOptions {
2
+ /**
3
+ * Should continue to resolve result string until replacements have been exhausted
4
+ */
5
+ recursive?: boolean;
6
+ /**
7
+ * Should resolve dot notation within template
8
+ */
9
+ resolve?: boolean;
10
+ /**
11
+ * Should remove unmatched template instances
12
+ */
13
+ clean?: boolean;
14
+ }
15
+ interface Phraser {
16
+ (
17
+ /**
18
+ * Template string to parse
19
+ */
20
+ string: string | undefined,
21
+ /**
22
+ * Data to use for interpolation, preferrably an object, but an array will work too, and a primitive values will be treated as an array of "...rest" arguments
23
+ */
24
+ ...data: (Record<string, any> | any)[]): string;
25
+ patterns: RegExp[];
26
+ }
27
+ /**
28
+ * Create new paraphrase method instance
29
+ * @param {...RegExp[]} replacers[] One or more patterns to use for string replacement
30
+ * @param {IParaphraseOptions} [options] The last argument can be an options object
31
+ * @returns {Phraser} phraser function instance
32
+ *
33
+ * @example const phraser = paraphrase(/\${([^{}]*)}/gm);
34
+ *
35
+ * phraser('Hello, ${name}', {name: 'Martin'})
36
+ */
37
+ export declare function paraphrase(...args: (RegExp | RegExp[] | IParaphraseOptions)[]): Phraser;
38
+ export declare const dollar: Phraser;
39
+ export declare const double: Phraser;
40
+ export declare const single: Phraser;
41
+ export declare const percent: Phraser;
42
+ export declare const hash: Phraser;
43
+ export declare const loose: Phraser;
44
+ export {};
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Is this a basic object?
3
+ * @param {any} obj Target to test
4
+ * @return {boolean} true if object
5
+ */
6
+ export declare const isObject: (obj: any) => boolean;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Resolve dot notation strings
3
+ *
4
+ * @param {any} context Object to start notation search on (defaults to global scope)
5
+ * @param {string} [string=''] Dot notation representation
6
+ * @return {any} Whatever it finds / undefined
7
+ *
8
+ * @example
9
+ * const obj = {
10
+ * top_level: {
11
+ * nested: {
12
+ * value: 'My Value'
13
+ * }
14
+ * }
15
+ * };
16
+ *
17
+ * notate(obj, 'top_level.nested.value');
18
+ * // 'My Value'
19
+ *
20
+ * notate(obj, 'top_level.missing.value');
21
+ * // undefined
22
+ */
23
+ export declare function notate(source: any, string?: string): any;
package/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js.map","sources":["src/notate/index.js","src/isObject/index.js","src/flavours/index.js","src/index.js"],"sourcesContent":["/**\n * Resolve dot notation strings\n *\n * @param {Object} context Object to start notation search (defaults to global scope)\n * @param {String} [string=''] Dot notation representation\n * @return {Any} Whatever it finds / undefined\n *\n * @example\n * const obj = {\n * top_level: {\n * nested: {\n * value: 'My Value'\n * }\n * }\n * };\n *\n * notate(obj, 'top_level.nested.value');\n * // 'My Value'\n *\n * notate(obj, 'top_level.missing.value');\n * // undefined\n */\nexport function notate (source, string = '') {\n if (typeof string !== 'string') {\n throw new TypeError(`Expected notation query to be a string, instead got ${typeof string} (${string})`)\n }\n return string\n .split('.')\n .reduce(\n (previous, current) => typeof previous === 'object' && previous\n ? previous[current]\n : previous,\n source\n )\n}\n","/**\n * Is this a basic object?\n * @param {any} obj\n * @return {boolean}\n */\nexport const isObject = obj => `${obj}` === '[object Object]'\n","/**\n * @property {RegExp} dollar 'Hello, ${name}'\n * @property {RegExp} double 'Hello, {{name}}'\n * @property {RegExp} single 'Hello, {name}'\n * @property {RegExp} hash 'Hello, #{name}'\n * @property {RegExp} percent 'Hello, %{name}'\n */\nexport const flavours = {\n dollar: /\\${([^{}]*)}/gm,\n double: /{{([^{}]*)}}/gm,\n single: /{([^{}]*)}/gm,\n hash: /#{([^{}]*)}/gm,\n percent: /%{([^{}]*)}/gm\n}\n","import { notate } from './notate/index.js'\nimport { isObject } from './isObject/index.js'\nimport { flavours } from './flavours/index.js'\n\n/**\n * Valid types of results for the interpolated string\n * @private\n * @type {Array}\n * @member {String|Number}\n */\nconst VALID_RESULT_TYPES = Object.seal(['string', 'number'])\n\n/**\n * Create new paraphrase method instance\n * @param {...RegExp[]} replacers\n * @param {Boolean} [options.resolve=true] Should resolve dot notation within template\n * @param {Boolean} [options.clean=false] Should remove unmatched template instances\n * @returns {Function} phraser function instance\n *\n * @example const phraser = paraphrase(/\\${([^{}]*)}/gm);\n *\n * phraser('Hello, ${name}', {name: 'Martin'})\n */\n\nexport function paraphrase (...replacers) {\n const options = {\n recursive: true,\n resolve: true,\n clean: false\n }\n if (replacers.length && isObject(replacers[replacers.length - 1])) {\n Object.assign(options, replacers.pop())\n }\n\n Object.freeze(replacers)\n\n /**\n * phraser description\n * @param {String} string Template\n * @param {Object|(String|number)} data Data for filling\n * @param {...(String|number)} replacements Replacement for filling\n * @return {String} Result\n */\n function phraser (string = '', data, ...replacements) {\n if (typeof string !== 'string') {\n throw new TypeError(`paraphrase expects first argument to be a string, got a ${typeof string} (${string})`)\n }\n\n if (!data) {\n return string\n }\n\n if (VALID_RESULT_TYPES.includes(typeof data)) {\n data = [data, ...replacements]\n }\n\n /**\n * Replace method build with internal reference to the passed in data structure\n * @param {String} haystack The full string match\n * @param {String} needle The content to identify as data member\n * @return {String} Found value\n */\n function replace (haystack, needle) {\n const replacement = options.resolve ? notate(data, needle.trim()) : data[needle.trim()]\n\n return VALID_RESULT_TYPES.includes(typeof replacement) ? replacement : options.clean ? '' : haystack\n }\n\n const result = replacers.reduce((string, replacer) => string.replace(replacer, replace), string)\n\n return !options.recursive || string === result\n ? result\n : phraser(result, data, ...replacements)\n }\n\n Object.defineProperty(\n phraser,\n 'patterns',\n {\n get: () => replacers\n }\n )\n\n return phraser\n}\n\nexport const dollar = paraphrase(flavours.dollar)\nexport const double = paraphrase(flavours.double)\nexport const single = paraphrase(flavours.single)\nexport const percent = paraphrase(flavours.percent)\nexport const hash = paraphrase(flavours.hash)\nexport const loose = paraphrase(\n flavours.dollar,\n flavours.double,\n flavours.percent,\n flavours.hash,\n flavours.single\n)\n"],"names":["notate","source","string","TypeError","split","reduce","previous","current","isObject","obj","flavours","dollar","double","single","hash","percent","VALID_RESULT_TYPES","Object","seal","paraphrase","replacers","options","recursive","resolve","clean","length","assign","pop","freeze","phraser","data","replacements","includes","replace","haystack","needle","replacement","trim","result","replacer","defineProperty","get","loose"],"mappings":"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"}
package/index.mjs.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.mjs.map","sources":["src/notate/index.js","src/isObject/index.js","src/flavours/index.js","src/index.js"],"sourcesContent":["/**\n * Resolve dot notation strings\n *\n * @param {Object} context Object to start notation search (defaults to global scope)\n * @param {String} [string=''] Dot notation representation\n * @return {Any} Whatever it finds / undefined\n *\n * @example\n * const obj = {\n * top_level: {\n * nested: {\n * value: 'My Value'\n * }\n * }\n * };\n *\n * notate(obj, 'top_level.nested.value');\n * // 'My Value'\n *\n * notate(obj, 'top_level.missing.value');\n * // undefined\n */\nexport function notate (source, string = '') {\n if (typeof string !== 'string') {\n throw new TypeError(`Expected notation query to be a string, instead got ${typeof string} (${string})`)\n }\n return string\n .split('.')\n .reduce(\n (previous, current) => typeof previous === 'object' && previous\n ? previous[current]\n : previous,\n source\n )\n}\n","/**\n * Is this a basic object?\n * @param {any} obj\n * @return {boolean}\n */\nexport const isObject = obj => `${obj}` === '[object Object]'\n","/**\n * @property {RegExp} dollar 'Hello, ${name}'\n * @property {RegExp} double 'Hello, {{name}}'\n * @property {RegExp} single 'Hello, {name}'\n * @property {RegExp} hash 'Hello, #{name}'\n * @property {RegExp} percent 'Hello, %{name}'\n */\nexport const flavours = {\n dollar: /\\${([^{}]*)}/gm,\n double: /{{([^{}]*)}}/gm,\n single: /{([^{}]*)}/gm,\n hash: /#{([^{}]*)}/gm,\n percent: /%{([^{}]*)}/gm\n}\n","import { notate } from './notate/index.js'\nimport { isObject } from './isObject/index.js'\nimport { flavours } from './flavours/index.js'\n\n/**\n * Valid types of results for the interpolated string\n * @private\n * @type {Array}\n * @member {String|Number}\n */\nconst VALID_RESULT_TYPES = Object.seal(['string', 'number'])\n\n/**\n * Create new paraphrase method instance\n * @param {...RegExp[]} replacers\n * @param {Boolean} [options.resolve=true] Should resolve dot notation within template\n * @param {Boolean} [options.clean=false] Should remove unmatched template instances\n * @returns {Function} phraser function instance\n *\n * @example const phraser = paraphrase(/\\${([^{}]*)}/gm);\n *\n * phraser('Hello, ${name}', {name: 'Martin'})\n */\n\nexport function paraphrase (...replacers) {\n const options = {\n recursive: true,\n resolve: true,\n clean: false\n }\n if (replacers.length && isObject(replacers[replacers.length - 1])) {\n Object.assign(options, replacers.pop())\n }\n\n Object.freeze(replacers)\n\n /**\n * phraser description\n * @param {String} string Template\n * @param {Object|(String|number)} data Data for filling\n * @param {...(String|number)} replacements Replacement for filling\n * @return {String} Result\n */\n function phraser (string = '', data, ...replacements) {\n if (typeof string !== 'string') {\n throw new TypeError(`paraphrase expects first argument to be a string, got a ${typeof string} (${string})`)\n }\n\n if (!data) {\n return string\n }\n\n if (VALID_RESULT_TYPES.includes(typeof data)) {\n data = [data, ...replacements]\n }\n\n /**\n * Replace method build with internal reference to the passed in data structure\n * @param {String} haystack The full string match\n * @param {String} needle The content to identify as data member\n * @return {String} Found value\n */\n function replace (haystack, needle) {\n const replacement = options.resolve ? notate(data, needle.trim()) : data[needle.trim()]\n\n return VALID_RESULT_TYPES.includes(typeof replacement) ? replacement : options.clean ? '' : haystack\n }\n\n const result = replacers.reduce((string, replacer) => string.replace(replacer, replace), string)\n\n return !options.recursive || string === result\n ? result\n : phraser(result, data, ...replacements)\n }\n\n Object.defineProperty(\n phraser,\n 'patterns',\n {\n get: () => replacers\n }\n )\n\n return phraser\n}\n\nexport const dollar = paraphrase(flavours.dollar)\nexport const double = paraphrase(flavours.double)\nexport const single = paraphrase(flavours.single)\nexport const percent = paraphrase(flavours.percent)\nexport const hash = paraphrase(flavours.hash)\nexport const loose = paraphrase(\n flavours.dollar,\n flavours.double,\n flavours.percent,\n flavours.hash,\n flavours.single\n)\n"],"names":["notate","source","string","TypeError","split","reduce","previous","current","isObject","obj","flavours","dollar","double","single","hash","percent","VALID_RESULT_TYPES","Object","seal","paraphrase","replacers","options","recursive","resolve","clean","length","assign","pop","freeze","phraser","data","replacements","includes","replace","haystack","needle","replacement","trim","result","replacer","defineProperty","get","loose"],"mappings":"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"}