@silvermine/toolbox 0.1.0 → 0.2.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.
Files changed (95) hide show
  1. package/commitlint.config.js +1 -1
  2. package/dist/commonjs/index.js +12 -1
  3. package/dist/commonjs/index.js.map +1 -1
  4. package/dist/commonjs/types/KeyValueStringObject.js +8 -8
  5. package/dist/commonjs/types/KeyValueStringObject.js.map +1 -1
  6. package/dist/commonjs/types/StringArrayOfStringsMap.js +6 -6
  7. package/dist/commonjs/types/StringArrayOfStringsMap.js.map +1 -1
  8. package/dist/commonjs/types/StringMap.js +6 -6
  9. package/dist/commonjs/types/StringMap.js.map +1 -1
  10. package/dist/commonjs/types/StringUnknownMap.js +4 -3
  11. package/dist/commonjs/types/StringUnknownMap.js.map +1 -1
  12. package/dist/commonjs/utils/chunk.js +3 -2
  13. package/dist/commonjs/utils/chunk.js.map +1 -1
  14. package/dist/commonjs/utils/delay.js +3 -2
  15. package/dist/commonjs/utils/delay.js.map +1 -1
  16. package/dist/commonjs/utils/escape-html.js +23 -0
  17. package/dist/commonjs/utils/escape-html.js.map +1 -0
  18. package/dist/commonjs/utils/flatten.js +3 -6
  19. package/dist/commonjs/utils/flatten.js.map +1 -1
  20. package/dist/commonjs/utils/get-tag-string.js +1 -0
  21. package/dist/commonjs/utils/get-tag-string.js.map +1 -1
  22. package/dist/commonjs/utils/get.js +99 -0
  23. package/dist/commonjs/utils/get.js.map +1 -0
  24. package/dist/commonjs/utils/has-defined.js +2 -1
  25. package/dist/commonjs/utils/has-defined.js.map +1 -1
  26. package/dist/commonjs/utils/is-arguments.js +2 -1
  27. package/dist/commonjs/utils/is-arguments.js.map +1 -1
  28. package/dist/commonjs/utils/is-array-of-strings.js +4 -4
  29. package/dist/commonjs/utils/is-array-of-strings.js.map +1 -1
  30. package/dist/commonjs/utils/is-array.js +1 -0
  31. package/dist/commonjs/utils/is-array.js.map +1 -1
  32. package/dist/commonjs/utils/is-empty.js +5 -4
  33. package/dist/commonjs/utils/is-empty.js.map +1 -1
  34. package/dist/commonjs/utils/is-enum-value.js +3 -2
  35. package/dist/commonjs/utils/is-enum-value.js.map +1 -1
  36. package/dist/commonjs/utils/is-map-with-values-of-type.js +3 -3
  37. package/dist/commonjs/utils/is-map-with-values-of-type.js.map +1 -1
  38. package/dist/commonjs/utils/is-not-null-or-undefined.js +13 -0
  39. package/dist/commonjs/utils/is-not-null-or-undefined.js.map +1 -0
  40. package/dist/commonjs/utils/is-null.js +8 -0
  41. package/dist/commonjs/utils/is-null.js.map +1 -0
  42. package/dist/commonjs/utils/is-number.js +3 -2
  43. package/dist/commonjs/utils/is-number.js.map +1 -1
  44. package/dist/commonjs/utils/is-object.js +2 -1
  45. package/dist/commonjs/utils/is-object.js.map +1 -1
  46. package/dist/commonjs/utils/is-promise-like.js +3 -2
  47. package/dist/commonjs/utils/is-promise-like.js.map +1 -1
  48. package/dist/commonjs/utils/is-promise.js +3 -2
  49. package/dist/commonjs/utils/is-promise.js.map +1 -1
  50. package/dist/commonjs/utils/is-string.js +3 -2
  51. package/dist/commonjs/utils/is-string.js.map +1 -1
  52. package/dist/commonjs/utils/is-undefined.js +1 -0
  53. package/dist/commonjs/utils/is-undefined.js.map +1 -1
  54. package/dist/commonjs/utils/make-template.js +73 -0
  55. package/dist/commonjs/utils/make-template.js.map +1 -0
  56. package/dist/commonjs/utils/pluck.js +2 -1
  57. package/dist/commonjs/utils/pluck.js.map +1 -1
  58. package/dist/esm/index.js +11 -0
  59. package/dist/esm/index.js.map +1 -1
  60. package/dist/esm/utils/chunk.js.map +1 -1
  61. package/dist/esm/utils/escape-html.js +19 -0
  62. package/dist/esm/utils/escape-html.js.map +1 -0
  63. package/dist/esm/utils/flatten.js.map +1 -1
  64. package/dist/esm/utils/get.js +96 -0
  65. package/dist/esm/utils/get.js.map +1 -0
  66. package/dist/esm/utils/is-not-null-or-undefined.js +9 -0
  67. package/dist/esm/utils/is-not-null-or-undefined.js.map +1 -0
  68. package/dist/esm/utils/is-null.js +4 -0
  69. package/dist/esm/utils/is-null.js.map +1 -0
  70. package/dist/esm/utils/is-undefined.js.map +1 -1
  71. package/dist/esm/utils/make-template.js +69 -0
  72. package/dist/esm/utils/make-template.js.map +1 -0
  73. package/dist/esm/utils/pluck.js.map +1 -1
  74. package/dist/types/index.d.ts +5 -0
  75. package/dist/types/utils/chunk.d.ts +1 -1
  76. package/dist/types/utils/escape-html.d.ts +1 -0
  77. package/dist/types/utils/flatten.d.ts +1 -1
  78. package/dist/types/utils/get.d.ts +8 -0
  79. package/dist/types/utils/is-not-null-or-undefined.d.ts +4 -0
  80. package/dist/types/utils/is-null.d.ts +1 -0
  81. package/dist/types/utils/is-undefined.d.ts +1 -1
  82. package/dist/types/utils/make-template.d.ts +41 -0
  83. package/dist/types/utils/pluck.d.ts +1 -1
  84. package/package.json +10 -10
  85. package/src/index.ts +5 -0
  86. package/src/utils/chunk.ts +1 -1
  87. package/src/utils/escape-html.ts +24 -0
  88. package/src/utils/flatten.ts +2 -2
  89. package/src/utils/get.ts +156 -0
  90. package/src/utils/is-not-null-or-undefined.ts +10 -0
  91. package/src/utils/is-null.ts +3 -0
  92. package/src/utils/is-undefined.ts +1 -1
  93. package/src/utils/make-template.ts +90 -0
  94. package/src/utils/pluck.ts +1 -1
  95. package/.nvmrc +0 -1
@@ -0,0 +1,24 @@
1
+ import { isString } from './is-string';
2
+
3
+ const ESCAPE_ENTITIES: Record<string, string> = {
4
+ '&': '&amp;',
5
+ '<': '&lt;',
6
+ '>': '&gt;',
7
+ '"': '&quot;',
8
+ "'": '&#x27;', // eslint-disable-line quotes
9
+ '`': '&#x60;',
10
+ };
11
+
12
+ const ESCAPE_ENTITIES_PATTERN = '(?:' + Object.keys(ESCAPE_ENTITIES).join('|') + ')',
13
+ ESCAPE_ENTITIES_REGEX = new RegExp(ESCAPE_ENTITIES_PATTERN),
14
+ ESCAPE_ENTITIES_REPLACE_REGEX = new RegExp(ESCAPE_ENTITIES_PATTERN, 'g');
15
+
16
+ export function escapeHTML(str: unknown): unknown {
17
+ if (isString(str) && ESCAPE_ENTITIES_REGEX.test(str)) {
18
+ return str.replace(ESCAPE_ENTITIES_REPLACE_REGEX, (match) => {
19
+ return ESCAPE_ENTITIES[match];
20
+ });
21
+ }
22
+
23
+ return str;
24
+ }
@@ -1,5 +1,5 @@
1
- export function flatten<T>(...lists: T[][]): T[] {
2
- return lists.reduce((memo, list) => {
1
+ export function flatten<T>(...lists: Readonly<Readonly<T[]>[]>): T[] {
2
+ return lists.reduce((memo: T[], list) => {
3
3
  return memo.concat(list);
4
4
  }, [] as T[]);
5
5
  }
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Much of the code in this file is adapted from Lodash's _.get implementation:
3
+ *
4
+ * https://github.com/lodash/lodash/blob/2da024c3b4f9947a48517639de7560457cd4ec6c/get.js
5
+ * https://github.com/lodash/lodash/blob/2da024c3b4f9947a48517639de7560457cd4ec6c/.internal/baseGet.js
6
+ * https://github.com/lodash/lodash/blob/2da024c3b4f9947a48517639de7560457cd4ec6c/.internal/castPath.js
7
+ * https://github.com/lodash/lodash/blob/2da024c3b4f9947a48517639de7560457cd4ec6c/.internal/stringToPath.js
8
+ * https://github.com/lodash/lodash/blob/2da024c3b4f9947a48517639de7560457cd4ec6c/.internal/toKey.js
9
+ */
10
+ import { getTagString } from './get-tag-string';
11
+ import { isObject } from './is-object';
12
+
13
+ function isSymbol(value: unknown): value is symbol {
14
+ const type = typeof value;
15
+
16
+ return (type === 'symbol') || (
17
+ type === 'object' &&
18
+ value !== undefined &&
19
+ value !== null &&
20
+ getTagString(value) === '[object Symbol]'
21
+ );
22
+ }
23
+
24
+ function toKey(value: unknown): string | symbol {
25
+ if (typeof value === 'string' || isSymbol(value)) {
26
+ return value;
27
+ }
28
+
29
+ return Object.is(value, -0) ? '-0' : `${value}`;
30
+ }
31
+
32
+ const IS_DEEP_PROP_REGEX = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
33
+ IS_PLAIN_PROP_REGEX = /^\w*$/;
34
+
35
+ function isKey(value: any, object: any): boolean {
36
+ if (Array.isArray(value)) {
37
+ return false;
38
+ }
39
+ const type = typeof value;
40
+
41
+ if (type === 'number' || type === 'boolean' || value === null || value === undefined || isSymbol(value)) {
42
+ return true;
43
+ }
44
+
45
+ return IS_PLAIN_PROP_REGEX.test(value) || !IS_DEEP_PROP_REGEX.test(value) ||
46
+ (object !== null && object !== undefined && value in Object(object));
47
+ }
48
+
49
+ const DOT_CHAR_CODE = '.'.charCodeAt(0),
50
+ ESCAPE_CHAR_REGEX = /\\(\\)?/g;
51
+
52
+ /* eslint-disable no-useless-concat */
53
+ const PROP_NAME_REGEX = RegExp(
54
+ // Match anything that isn't a dot or bracket.
55
+ '[^.[\\]]+' + '|' +
56
+ // Or match property names within brackets.
57
+ '\\[(?:' +
58
+ // Match a non-string expression.
59
+ '([^"\'][^[]*)' + '|' +
60
+ // Or match strings (supports escaping characters).
61
+ '(["\'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2' +
62
+ ')\\]' + '|' +
63
+ // Or match "" as the space between consecutive dots or empty brackets.
64
+ '(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))',
65
+ 'g'
66
+ );
67
+ /* eslint-enable no-useless-concat */
68
+
69
+ function stringToPath(str: string): string[] {
70
+ const result: string[] = [];
71
+
72
+ if (str.charCodeAt(0) === DOT_CHAR_CODE) {
73
+ result.push('');
74
+ }
75
+
76
+ str.replace(PROP_NAME_REGEX, (match, expression, quote, subString) => {
77
+ let key = match;
78
+
79
+ if (quote) {
80
+ key = subString.replace(ESCAPE_CHAR_REGEX, '$1');
81
+ } else if (expression) {
82
+ key = expression;
83
+ }
84
+
85
+ result.push(key);
86
+
87
+ // The types for this callback require us to return a string, but we don't really
88
+ // care about the result of the call to `replace`, so we just return an empty string
89
+ // here.
90
+ return '';
91
+ });
92
+
93
+ return result;
94
+ }
95
+
96
+ function createPathArray(value: any, object: any): string[] {
97
+ if (Array.isArray(value)) {
98
+ return value;
99
+ }
100
+
101
+ return isKey(value, object) ? [ value ] : stringToPath(value);
102
+ }
103
+
104
+ interface StringRepresentable {
105
+ toString(): string;
106
+ }
107
+
108
+ function get<TObject extends object, TKey extends keyof TObject>(
109
+ obj: TObject,
110
+ path: TKey | [TKey]
111
+ ): TObject[TKey] | undefined;
112
+ function get<TObject extends object, TKey extends keyof TObject>(
113
+ obj: TObject,
114
+ path: TKey | [TKey],
115
+ defaultValue: TObject[TKey]
116
+ ): TObject[TKey];
117
+ function get<TObject extends object, TResult = unknown>(
118
+ obj: TObject,
119
+ path: StringRepresentable | StringRepresentable[],
120
+ defaultValue: TResult
121
+ ): TResult;
122
+ function get<TObject extends object, TResult = unknown>(
123
+ obj: TObject,
124
+ path: StringRepresentable | StringRepresentable[]
125
+ ): TResult | undefined;
126
+ function get<TResult = unknown>(
127
+ obj: unknown,
128
+ path: StringRepresentable | StringRepresentable[],
129
+ defaultValue?: TResult
130
+ ): TResult | undefined {
131
+ if (!isObject(obj)) {
132
+ return defaultValue;
133
+ }
134
+
135
+ const pathArray = createPathArray(path, obj),
136
+ length = pathArray.length;
137
+
138
+ let index = 0,
139
+ resultObj: unknown = obj;
140
+
141
+ while (resultObj !== null && resultObj !== undefined && index < length) {
142
+ resultObj = (resultObj as any)[toKey(pathArray[index])];
143
+
144
+ index += 1;
145
+ }
146
+
147
+ const result = (index > 0 && index === length) ? resultObj : undefined;
148
+
149
+ if (result === undefined) {
150
+ return defaultValue;
151
+ }
152
+
153
+ return result as TResult | undefined;
154
+ }
155
+
156
+ export { get };
@@ -0,0 +1,10 @@
1
+ import { isNull } from './is-null';
2
+ import { isUndefined } from './is-undefined';
3
+
4
+
5
+ /**
6
+ * Checks if `o` is not either null or undefined
7
+ */
8
+ export function isNotNullOrUndefined<T>(o: T | null | undefined): o is T {
9
+ return !(isNull(o) || isUndefined(o));
10
+ }
@@ -0,0 +1,3 @@
1
+ export function isNull(val: unknown): val is null {
2
+ return val === null;
3
+ }
@@ -1,3 +1,3 @@
1
- export function isUndefined(val: any): val is undefined {
1
+ export function isUndefined(val: unknown): val is undefined {
2
2
  return (typeof val === 'undefined');
3
3
  }
@@ -0,0 +1,90 @@
1
+ import { get } from './get';
2
+ import { escapeHTML } from './escape-html';
3
+
4
+ const DEFAULT_SETTINGS: ToolboxTemplateSettings = {
5
+ escape: /<%-([\s\S]+?)%>/g,
6
+ interpolate: /<%=([\s\S]+?)%>/g,
7
+ };
8
+
9
+ function getValue(path: string, data: any): unknown {
10
+ return get(data, (path || '').trim(), '');
11
+ }
12
+
13
+ export interface ToolboxTemplateSettings {
14
+ escape: { source: string };
15
+ interpolate: { source: string };
16
+ }
17
+
18
+ export interface ToolboxTemplateFunction {
19
+ (data: Record<string, any>): string;
20
+ }
21
+
22
+ /**
23
+ * A simple replacement for _.template from either Underscore or Lodash that removes the
24
+ * features that make those libraries incompatible with Content Security Policy (CSP).
25
+ * Specifically, this implementation supports only interpolation (escaped and unescaped)
26
+ * and does not support JS evaluation.
27
+ *
28
+ * Use this function just like you would have used _.template:
29
+ *
30
+ * ```ts
31
+ * template = template('Hello <%= name %>');
32
+ * console.log(template({ name: 'John Smith' }));
33
+ * ```
34
+ *
35
+ * This function only supports:
36
+ *
37
+ * `<%= … %>`: interpolate a value
38
+ * `<%- … %>`: interpolate and HTML escape a value
39
+ *
40
+ * The following are NOT supported:
41
+ *
42
+ * `<% … %>`: JS evaluation
43
+ * `<% print('Hello ' + epithet); %>`: JS evaluation with the print function
44
+ *
45
+ * Templating in Underscore/Lodash works by building/evaluation a JS function using a
46
+ * string, essentially using `eval()` to evaluate the string as JS. This meant that if
47
+ * your template referred to a variable that did not exist, you would see a JS error
48
+ * thrown. In this function, however, undefined variables in the template will result in
49
+ * an empty string placed in that location.
50
+ */
51
+ export function makeTemplate(text: string, userSettings?: ToolboxTemplateSettings): (data: unknown) => string {
52
+ type TemplateFunction = (data: unknown) => unknown;
53
+
54
+ let parts: (TemplateFunction | string)[] = [],
55
+ index = 0,
56
+ settings = Object.assign({}, DEFAULT_SETTINGS, userSettings || {}),
57
+ regExpPattern, matcher;
58
+
59
+ regExpPattern = [
60
+ settings.escape.source,
61
+ settings.interpolate.source,
62
+ ];
63
+ matcher = new RegExp(regExpPattern.join('|') + '|$', 'g');
64
+
65
+ text.replace(matcher, (match, escape, interpolate, offset) => {
66
+ parts.push(text.slice(index, offset));
67
+ index = offset + match.length;
68
+
69
+ if (escape) {
70
+ parts.push((data: any) => {
71
+ return escapeHTML(getValue(escape, data));
72
+ });
73
+ } else if (interpolate) {
74
+ parts.push(getValue.bind(null, interpolate));
75
+ }
76
+
77
+ // The types for this callback require us to return a string, but we don't really
78
+ // care about the result of the call to `replace`, so we just return an empty string
79
+ // here.
80
+ return '';
81
+ });
82
+
83
+ return (data: unknown): string => {
84
+ return parts.reduce((memo, part): string => {
85
+ const result = (typeof part === 'function') ? `${part(data)}` : part;
86
+
87
+ return memo + result;
88
+ }, '') as string;
89
+ };
90
+ }
@@ -1,4 +1,4 @@
1
- export function pluck<T, K extends keyof T>(sources: T[], key: K): T[K][] {
1
+ export function pluck<T, K extends keyof T>(sources: readonly T[], key: K): T[K][] {
2
2
  return sources.map((o) => {
3
3
  return o[key];
4
4
  });
package/.nvmrc DELETED
@@ -1 +0,0 @@
1
- 12.14.0