littoral-templates 0.3.0 → 0.4.0-rc.2
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/.editorconfig +9 -0
- package/.eslintrc.cjs +15 -0
- package/CHANGELOG.md +9 -0
- package/dist/functions.d.ts +70 -0
- package/dist/functions.d.ts.map +1 -0
- package/dist/functions.js +119 -0
- package/dist/functions.js.map +1 -0
- package/dist/index.d.ts +3 -68
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -123
- package/dist/index.js.map +1 -1
- package/dist/internals.d.ts +23 -0
- package/dist/internals.d.ts.map +1 -0
- package/dist/internals.js +84 -0
- package/dist/internals.js.map +1 -0
- package/dist/strings.d.ts +10 -0
- package/dist/strings.d.ts.map +1 -0
- package/dist/strings.js +25 -0
- package/dist/strings.js.map +1 -0
- package/dist/types.d.ts +13 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +46 -37
package/.editorconfig
ADDED
package/.eslintrc.cjs
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
/* eslint-env node */
|
2
|
+
module.exports = {
|
3
|
+
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
|
4
|
+
parser: "@typescript-eslint/parser",
|
5
|
+
plugins: ["@typescript-eslint"],
|
6
|
+
root: true,
|
7
|
+
rules: {
|
8
|
+
"@typescript-eslint/no-unused-vars": ["error", {"argsIgnorePattern": "^_"}],
|
9
|
+
"@typescript-eslint/ban-ts-ignore": "off",
|
10
|
+
"@typescript-eslint/prefer-spread": ["off"]
|
11
|
+
},
|
12
|
+
env: {
|
13
|
+
browser: true,
|
14
|
+
node: true
|
15
|
+
}}
|
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 0.4.0
|
4
|
+
|
5
|
+
* Thunks returning a `Template` are now `Template`s as well.
|
6
|
+
* The 3rd (Curried) argument of `indentWith`, and the 2nd (Curried) argument of `when` are now variadic.
|
7
|
+
* The EOL string can now be set explicitly (with the `setEOLExplicitly` function), or be taken from the OS (with the asynchronous `setEOLFromOS` function).
|
8
|
+
This EOL string is then used to insert newlines, and – to some extent – normalize them.
|
9
|
+
* An object constant `commonIndentations` is added with the most common indentation styles: “2 spaces”, “4 spaces”, and “1 tab”.
|
10
|
+
* The `flatten` function now splits on `/\r*\n/` rather than just `/\n/`.
|
11
|
+
|
3
12
|
|
4
13
|
## 0.3.0
|
5
14
|
|
@@ -0,0 +1,70 @@
|
|
1
|
+
import { Template } from "./index.js";
|
2
|
+
/**
|
3
|
+
* @returns {string} - the given template joined as one string, taking care of proper newline endings.
|
4
|
+
*/
|
5
|
+
export declare const asString: (template: Template) => string;
|
6
|
+
/**
|
7
|
+
* @returns a function to instantiate a function to indent a sub-template.
|
8
|
+
* The function always returns an array of strings.
|
9
|
+
*
|
10
|
+
* Its usage looks as follows:
|
11
|
+
* <pre>
|
12
|
+
* indentWith(" ")(2)([
|
13
|
+
* `this is indented 2 levels`
|
14
|
+
* ])
|
15
|
+
* </pre>
|
16
|
+
* Note that the third Curried argument is variadic, so the array brackets (`[]`) can be elided.
|
17
|
+
*
|
18
|
+
* Usually, one sets up the following function constant before:
|
19
|
+
* <pre>
|
20
|
+
* const indent = indentWith(" ")
|
21
|
+
* </pre>
|
22
|
+
*/
|
23
|
+
export declare const indentWith: (singleIndentation: string) => (indentLevel?: number) => (...templates: Template[]) => string[];
|
24
|
+
/**
|
25
|
+
* An enumeration of common indentation styles.
|
26
|
+
* Use these in a type-safe way as follows, e.g. for “1 tab”:
|
27
|
+
*
|
28
|
+
* ```
|
29
|
+
* const indent = indentWith(commonIndentations["1 tab"])
|
30
|
+
*
|
31
|
+
* indent([`foo`])
|
32
|
+
* ```
|
33
|
+
*/
|
34
|
+
export declare const commonIndentations: {
|
35
|
+
readonly "2 spaces": " ";
|
36
|
+
readonly "4 spaces": " ";
|
37
|
+
readonly "1 tab": "\t";
|
38
|
+
};
|
39
|
+
/**
|
40
|
+
* Allows for the following syntax:
|
41
|
+
* <pre>
|
42
|
+
* [
|
43
|
+
* when(<some boolean condition>)(
|
44
|
+
* <stuff to include when boolean condition is true>
|
45
|
+
* )
|
46
|
+
* ]
|
47
|
+
* </pre>
|
48
|
+
*
|
49
|
+
* and
|
50
|
+
*
|
51
|
+
* <pre>
|
52
|
+
* [
|
53
|
+
* when(<some boolean condition>)(
|
54
|
+
* () => <stuff to include when boolean condition is true>
|
55
|
+
* )
|
56
|
+
* ]
|
57
|
+
* </pre>
|
58
|
+
*
|
59
|
+
* In the latter case, it's guaranteed that the thunk ({@see https://en.wikipedia.org/wiki/Thunk})
|
60
|
+
* is only evaluated (/run) when the boolean condition is true.
|
61
|
+
* That is useful in case the stuff to include produces side effects.
|
62
|
+
*
|
63
|
+
* Note that the second Curried argument is variadic, so it doesn't require array brackets (`[]`).
|
64
|
+
*/
|
65
|
+
export declare const when: (bool: boolean) => (...whenResults: Template[]) => Template;
|
66
|
+
/**
|
67
|
+
* @return a function that composes the given template function with the action of "adding a newline after".
|
68
|
+
*/
|
69
|
+
export declare const withNewlineAppended: <T>(templateFunc: (t: T) => Template) => (t: T) => Template[];
|
70
|
+
//# sourceMappingURL=functions.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../src/functions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,QAAQ,EAAC,MAAM,YAAY,CAAA;AAkB3C;;GAEG;AACH,eAAO,MAAM,QAAQ,aAAc,QAAQ,KAAG,MACI,CAAA;AAGlD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,UAAU,sBAAuB,MAAM,oBAClC,MAAM,oBAGM,QAAQ,EAAE,aAEnC,CAAA;AAGL;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB;;;;CAIrB,CAAA;AAGV;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,IAAI,SAAU,OAAO,sBAAqB,QAAQ,EAAE,KAAK,QAGnD,CAAA;AAGnB;;GAEG;AACH,eAAO,MAAM,mBAAmB,8BAA+B,QAAQ,yBACpC,CAAA"}
|
@@ -0,0 +1,119 @@
|
|
1
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
2
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
3
|
+
if (ar || !(i in from)) {
|
4
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
5
|
+
ar[i] = from[i];
|
6
|
+
}
|
7
|
+
}
|
8
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
9
|
+
};
|
10
|
+
import { repeat } from "./index.js";
|
11
|
+
import { withEOLEnsured } from "./internals.js";
|
12
|
+
/**
|
13
|
+
* “Flattens” the given template to an array of strings, each of which represent exactly one line.
|
14
|
+
*/
|
15
|
+
var flatten = function (template) {
|
16
|
+
if (typeof template === "function") {
|
17
|
+
return flatten(template());
|
18
|
+
}
|
19
|
+
if (Array.isArray(template)) {
|
20
|
+
return template.map(flatten).reduce(function (arrL, arrR) { return __spreadArray(__spreadArray([], arrL, true), arrR, true); }, []);
|
21
|
+
}
|
22
|
+
return template.split(/\r*\n/);
|
23
|
+
};
|
24
|
+
/**
|
25
|
+
* @returns {string} - the given template joined as one string, taking care of proper newline endings.
|
26
|
+
*/
|
27
|
+
export var asString = function (template) {
|
28
|
+
return flatten(template).map(withEOLEnsured).join("");
|
29
|
+
};
|
30
|
+
/**
|
31
|
+
* @returns a function to instantiate a function to indent a sub-template.
|
32
|
+
* The function always returns an array of strings.
|
33
|
+
*
|
34
|
+
* Its usage looks as follows:
|
35
|
+
* <pre>
|
36
|
+
* indentWith(" ")(2)([
|
37
|
+
* `this is indented 2 levels`
|
38
|
+
* ])
|
39
|
+
* </pre>
|
40
|
+
* Note that the third Curried argument is variadic, so the array brackets (`[]`) can be elided.
|
41
|
+
*
|
42
|
+
* Usually, one sets up the following function constant before:
|
43
|
+
* <pre>
|
44
|
+
* const indent = indentWith(" ")
|
45
|
+
* </pre>
|
46
|
+
*/
|
47
|
+
export var indentWith = function (singleIndentation) {
|
48
|
+
return function (indentLevel) {
|
49
|
+
if (indentLevel === void 0) { indentLevel = 1; }
|
50
|
+
var prefix = repeat(singleIndentation, indentLevel);
|
51
|
+
var indenter = function (line) { return line.length > 0 ? (prefix + line) : line; };
|
52
|
+
return function () {
|
53
|
+
var templates = [];
|
54
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
55
|
+
templates[_i] = arguments[_i];
|
56
|
+
}
|
57
|
+
return flatten(templates).map(indenter);
|
58
|
+
}; // Note: Template[] has type Template as well!
|
59
|
+
};
|
60
|
+
};
|
61
|
+
/**
|
62
|
+
* An enumeration of common indentation styles.
|
63
|
+
* Use these in a type-safe way as follows, e.g. for “1 tab”:
|
64
|
+
*
|
65
|
+
* ```
|
66
|
+
* const indent = indentWith(commonIndentations["1 tab"])
|
67
|
+
*
|
68
|
+
* indent([`foo`])
|
69
|
+
* ```
|
70
|
+
*/
|
71
|
+
export var commonIndentations = {
|
72
|
+
"2 spaces": " ",
|
73
|
+
"4 spaces": " ",
|
74
|
+
"1 tab": "\t"
|
75
|
+
};
|
76
|
+
/**
|
77
|
+
* Allows for the following syntax:
|
78
|
+
* <pre>
|
79
|
+
* [
|
80
|
+
* when(<some boolean condition>)(
|
81
|
+
* <stuff to include when boolean condition is true>
|
82
|
+
* )
|
83
|
+
* ]
|
84
|
+
* </pre>
|
85
|
+
*
|
86
|
+
* and
|
87
|
+
*
|
88
|
+
* <pre>
|
89
|
+
* [
|
90
|
+
* when(<some boolean condition>)(
|
91
|
+
* () => <stuff to include when boolean condition is true>
|
92
|
+
* )
|
93
|
+
* ]
|
94
|
+
* </pre>
|
95
|
+
*
|
96
|
+
* In the latter case, it's guaranteed that the thunk ({@see https://en.wikipedia.org/wiki/Thunk})
|
97
|
+
* is only evaluated (/run) when the boolean condition is true.
|
98
|
+
* That is useful in case the stuff to include produces side effects.
|
99
|
+
*
|
100
|
+
* Note that the second Curried argument is variadic, so it doesn't require array brackets (`[]`).
|
101
|
+
*/
|
102
|
+
export var when = function (bool) {
|
103
|
+
return bool
|
104
|
+
? function () {
|
105
|
+
var whenResults = [];
|
106
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
107
|
+
whenResults[_i] = arguments[_i];
|
108
|
+
}
|
109
|
+
return flatten(whenResults);
|
110
|
+
} // (need to be explicit here, or it doesn't work – despite having specified the return type...)
|
111
|
+
: function (_) { return []; };
|
112
|
+
};
|
113
|
+
/**
|
114
|
+
* @return a function that composes the given template function with the action of "adding a newline after".
|
115
|
+
*/
|
116
|
+
export var withNewlineAppended = function (templateFunc) {
|
117
|
+
return function (t) { return [templateFunc(t), ""]; };
|
118
|
+
};
|
119
|
+
//# sourceMappingURL=functions.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"functions.js","sourceRoot":"","sources":["../src/functions.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAC,MAAM,EAAW,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAC,cAAc,EAAC,MAAM,gBAAgB,CAAA;AAG7C;;GAEG;AACH,IAAM,OAAO,GAAG,UAAC,QAAkB;IAC/B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QACjC,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAA;IAC9B,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,UAAC,IAAI,EAAE,IAAI,IAAK,uCAAI,IAAI,SAAK,IAAI,SAAjB,CAAkB,EAAE,EAAE,CAAC,CAAA;IAC/E,CAAC;IACD,OAAO,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;AAClC,CAAC,CAAA;AAGD;;GAEG;AACH,MAAM,CAAC,IAAM,QAAQ,GAAG,UAAC,QAAkB;IACvC,OAAA,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;AAA9C,CAA8C,CAAA;AAGlD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,IAAM,UAAU,GAAG,UAAC,iBAAyB;IAChD,OAAA,UAAC,WAAuB;QAAvB,4BAAA,EAAA,eAAuB;QACpB,IAAM,MAAM,GAAG,MAAM,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAA;QACrD,IAAM,QAAQ,GAAG,UAAC,IAAY,IAAK,OAAA,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAxC,CAAwC,CAAA;QAC3E,OAAO;YAAC,mBAAwB;iBAAxB,UAAwB,EAAxB,qBAAwB,EAAxB,IAAwB;gBAAxB,8BAAwB;;YAC5B,OAAA,OAAO,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;QAAhC,CAAgC,CAAA,CAAI,8CAA8C;IAC1F,CAAC;AALD,CAKC,CAAA;AAGL;;;;;;;;;GASG;AACH,MAAM,CAAC,IAAM,kBAAkB,GAAG;IAC9B,UAAU,EAAE,IAAI;IAChB,UAAU,EAAE,MAAM;IAClB,OAAO,EAAE,IAAI;CACP,CAAA;AAGV;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,IAAM,IAAI,GAAG,UAAC,IAAa;IAC9B,OAAA,IAAI;QACA,CAAC,CAAC;YAAC,qBAA0B;iBAA1B,UAA0B,EAA1B,qBAA0B,EAA1B,IAA0B;gBAA1B,gCAA0B;;YAAK,OAAA,OAAO,CAAC,WAAW,CAAC;QAApB,CAAoB,CAAE,+FAA+F;QACvJ,CAAC,CAAC,UAAC,CAAC,IAAK,OAAA,EAAE,EAAF,CAAE;AAFf,CAEe,CAAA;AAGnB;;GAEG;AACH,MAAM,CAAC,IAAM,mBAAmB,GAAG,UAAI,YAAgC;IACnE,OAAA,UAAC,CAAI,IAAK,OAAA,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAArB,CAAqB;AAA/B,CAA+B,CAAA"}
|
package/dist/index.d.ts
CHANGED
@@ -1,69 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
*
|
5
|
-
* @since version 0.3.0
|
6
|
-
*/
|
7
|
-
export type Template = string | Array<Template>;
|
8
|
-
/**
|
9
|
-
* An alias for the {@link Template} type definition.
|
10
|
-
* Note: this type might be deprecated and removed (per a major version) in the future.
|
11
|
-
*/
|
12
|
-
export type NestedString = Template;
|
13
|
-
type TemplateFunction<T> = (_: Template) => T;
|
14
|
-
/**
|
15
|
-
* @returns {string} - the given template joined as one string, taking care of proper newline endings.
|
16
|
-
*/
|
17
|
-
export declare const asString: (template: Template) => string;
|
18
|
-
/**
|
19
|
-
* @returns {function} - a function to instantiate a function to indent a sub-template.
|
20
|
-
* The function always returns an array of strings.
|
21
|
-
*
|
22
|
-
* Its usage looks as follows:
|
23
|
-
* <pre>
|
24
|
-
* indentWith(" ")(2)([
|
25
|
-
* `this is indented 2 levels`
|
26
|
-
* ])
|
27
|
-
* </pre>
|
28
|
-
*
|
29
|
-
* Usually, one sets up the following function constant before:
|
30
|
-
* <pre>
|
31
|
-
* const indent = indentWith(" ")
|
32
|
-
* </pre>
|
33
|
-
*/
|
34
|
-
export declare const indentWith: (singleIndentation: string) => (indentLevel?: number) => TemplateFunction<string[]>;
|
35
|
-
/**
|
36
|
-
* Allows for the following syntax:
|
37
|
-
* <pre>
|
38
|
-
* [
|
39
|
-
* when(<some boolean condition>)(
|
40
|
-
* <stuff to include when boolean condition is true>
|
41
|
-
* )
|
42
|
-
* ]
|
43
|
-
* </pre>
|
44
|
-
*
|
45
|
-
* and
|
46
|
-
*
|
47
|
-
* <pre>
|
48
|
-
* [
|
49
|
-
* when(<some boolean condition>)(
|
50
|
-
* () => <stuff to include when boolean condition is true>
|
51
|
-
* )
|
52
|
-
* ]
|
53
|
-
* </pre>
|
54
|
-
*
|
55
|
-
* In the latter case, it's guaranteed that the thunk ({@see https://en.wikipedia.org/wiki/Thunk})
|
56
|
-
* is only evaluated (/run) when the boolean condition is true.
|
57
|
-
* That is useful in case the stuff to include produces side effects.
|
58
|
-
*/
|
59
|
-
export declare const when: (bool: boolean) => (whenResult: (() => Template) | Template) => Template;
|
60
|
-
/**
|
61
|
-
* @return a function that composes the given template function with the action of "adding a newline after".
|
62
|
-
*/
|
63
|
-
export declare const withNewlineAppended: <T>(templateFunc: (t: T) => Template) => (t: T) => Template[];
|
64
|
-
/**
|
65
|
-
* @return the given array of strings but with commas added after each string except the last one.
|
66
|
-
*/
|
67
|
-
export declare const commaSeparated: (strings: string[]) => string[];
|
68
|
-
export {};
|
1
|
+
export { Template, NestedString } from "./types.js";
|
2
|
+
export { asString, indentWith, when, withNewlineAppended } from "./functions.js";
|
3
|
+
export { commaSeparated, repeat } from "./strings.js";
|
69
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,YAAY,EAAC,MAAM,YAAY,CAAA;AACjD,OAAO,EAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,mBAAmB,EAAC,MAAM,gBAAgB,CAAA;AAC9E,OAAO,EAAC,cAAc,EAAE,MAAM,EAAC,MAAM,cAAc,CAAA"}
|
package/dist/index.js
CHANGED
@@ -1,124 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
if (ar || !(i in from)) {
|
4
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
5
|
-
ar[i] = from[i];
|
6
|
-
}
|
7
|
-
}
|
8
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
9
|
-
};
|
10
|
-
/**
|
11
|
-
* Polyfill/shim for ES2019's Array.prototype.flat(..).
|
12
|
-
*/
|
13
|
-
var flatten = function (template) {
|
14
|
-
return Array.isArray(template)
|
15
|
-
? template.map(flatten).reduce(function (arrL, arrR) { return __spreadArray(__spreadArray([], arrL, true), arrR, true); }, [])
|
16
|
-
: [template];
|
17
|
-
};
|
18
|
-
/**
|
19
|
-
* @returns {function(*=): *} - a function that maps over a single string using mapString, or an array of strings using mapStrings.
|
20
|
-
* If an array is given, that array is completely (i.e.: recursively) flattened first, before the mapStrings function is applied.
|
21
|
-
* (This function is only used internally.)
|
22
|
-
*/
|
23
|
-
var mapNestedString = function (mapString, mapStrings) {
|
24
|
-
return function (template) {
|
25
|
-
return Array.isArray(template)
|
26
|
-
? mapStrings(flatten(template))
|
27
|
-
: mapString(template);
|
28
|
-
};
|
29
|
-
};
|
30
|
-
var withNewlineEnsured = function (str) {
|
31
|
-
return str.charAt(str.length - 1) === '\n'
|
32
|
-
? str
|
33
|
-
: (str + "\n");
|
34
|
-
};
|
35
|
-
/**
|
36
|
-
* @returns {string} - the given template joined as one string, taking care of proper newline endings.
|
37
|
-
*/
|
38
|
-
export var asString = mapNestedString(withNewlineEnsured, function (strings) { return strings.map(withNewlineEnsured).join(""); });
|
39
|
-
/**
|
40
|
-
* Polyfill/shim for ES2015's String.prototype.repeat which doesn't work for some reason in the test...
|
41
|
-
*/
|
42
|
-
var repeat = function (str, n) {
|
43
|
-
var result = "";
|
44
|
-
while (n > 0) {
|
45
|
-
if (n % 2 === 1) {
|
46
|
-
result += str;
|
47
|
-
}
|
48
|
-
if (n > 1) {
|
49
|
-
str += str;
|
50
|
-
}
|
51
|
-
n >>= 1;
|
52
|
-
}
|
53
|
-
return result;
|
54
|
-
};
|
55
|
-
/**
|
56
|
-
* @returns {function} - a function to instantiate a function to indent a sub-template.
|
57
|
-
* The function always returns an array of strings.
|
58
|
-
*
|
59
|
-
* Its usage looks as follows:
|
60
|
-
* <pre>
|
61
|
-
* indentWith(" ")(2)([
|
62
|
-
* `this is indented 2 levels`
|
63
|
-
* ])
|
64
|
-
* </pre>
|
65
|
-
*
|
66
|
-
* Usually, one sets up the following function constant before:
|
67
|
-
* <pre>
|
68
|
-
* const indent = indentWith(" ")
|
69
|
-
* </pre>
|
70
|
-
*/
|
71
|
-
export var indentWith = function (singleIndentation) {
|
72
|
-
return function (indentLevel) {
|
73
|
-
if (indentLevel === void 0) { indentLevel = 1; }
|
74
|
-
var indentationPrefix = repeat(singleIndentation, indentLevel);
|
75
|
-
var indentLine = function (str) { return str.split("\n").map(function (line) { return (line.length > 0 ? indentationPrefix : "") + line; }).join("\n"); };
|
76
|
-
return mapNestedString(function (string) { return [indentLine(string)]; }, function (strings) { return strings.map(indentLine); });
|
77
|
-
};
|
78
|
-
};
|
79
|
-
/**
|
80
|
-
* Allows for the following syntax:
|
81
|
-
* <pre>
|
82
|
-
* [
|
83
|
-
* when(<some boolean condition>)(
|
84
|
-
* <stuff to include when boolean condition is true>
|
85
|
-
* )
|
86
|
-
* ]
|
87
|
-
* </pre>
|
88
|
-
*
|
89
|
-
* and
|
90
|
-
*
|
91
|
-
* <pre>
|
92
|
-
* [
|
93
|
-
* when(<some boolean condition>)(
|
94
|
-
* () => <stuff to include when boolean condition is true>
|
95
|
-
* )
|
96
|
-
* ]
|
97
|
-
* </pre>
|
98
|
-
*
|
99
|
-
* In the latter case, it's guaranteed that the thunk ({@see https://en.wikipedia.org/wiki/Thunk})
|
100
|
-
* is only evaluated (/run) when the boolean condition is true.
|
101
|
-
* That is useful in case the stuff to include produces side effects.
|
102
|
-
*/
|
103
|
-
export var when = function (bool) {
|
104
|
-
return bool
|
105
|
-
? function (whenResult) {
|
106
|
-
return typeof whenResult === "function"
|
107
|
-
? whenResult()
|
108
|
-
: whenResult;
|
109
|
-
}
|
110
|
-
: function (_whenResult) { return []; };
|
111
|
-
};
|
112
|
-
/**
|
113
|
-
* @return a function that composes the given template function with the action of "adding a newline after".
|
114
|
-
*/
|
115
|
-
export var withNewlineAppended = function (templateFunc) {
|
116
|
-
return function (t) { return [templateFunc(t), ""]; };
|
117
|
-
};
|
118
|
-
/**
|
119
|
-
* @return the given array of strings but with commas added after each string except the last one.
|
120
|
-
*/
|
121
|
-
export var commaSeparated = function (strings) {
|
122
|
-
return strings.map(function (str, index) { return "".concat(str).concat(index + 1 < strings.length ? "," : ""); });
|
123
|
-
};
|
1
|
+
export { asString, indentWith, when, withNewlineAppended } from "./functions.js";
|
2
|
+
export { commaSeparated, repeat } from "./strings.js";
|
124
3
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,mBAAmB,EAAC,MAAM,gBAAgB,CAAA;AAC9E,OAAO,EAAC,cAAc,EAAE,MAAM,EAAC,MAAM,cAAc,CAAA"}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
export declare const eolStyles: {
|
2
|
+
readonly lf: "\n";
|
3
|
+
readonly crlf: "\r\n";
|
4
|
+
};
|
5
|
+
/**
|
6
|
+
* The value of the EOL string: typically, either "\n" (=LF-style, compatible with POSIX/Linux/macOS), or "\r\n" (=CRLF-style, compatible with Windows).
|
7
|
+
*/
|
8
|
+
export declare let eol: string;
|
9
|
+
/**
|
10
|
+
* Sets the EOL to the OS-dependent value.
|
11
|
+
*/
|
12
|
+
export declare const setEOLFromOS: () => Promise<void>;
|
13
|
+
/**
|
14
|
+
* Sets the EOL explicitly to the given value.
|
15
|
+
* (This is especially useful for testing.)
|
16
|
+
*/
|
17
|
+
export declare const setEOLExplicitly: (newEol: string) => void;
|
18
|
+
/**
|
19
|
+
* Ensures that the given string ends with an EOL, adding one if necessary.
|
20
|
+
*/
|
21
|
+
export declare const withEOLEnsured: (str: string) => string;
|
22
|
+
export declare const splitOnEOL: (str: string) => string[];
|
23
|
+
//# sourceMappingURL=internals.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"internals.d.ts","sourceRoot":"","sources":["../src/internals.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,SAAS;;;CAGZ,CAAA;AAEV;;GAEG;AACH,eAAO,IAAI,GAAG,EAAE,MAAqB,CAAA;AAGrC;;GAEG;AACH,eAAO,MAAM,YAAY,QAAa,QAAQ,IAAI,CAG5C,CAAA;AAGN;;;GAGG;AACH,eAAO,MAAM,gBAAgB,WAAY,MAAM,SAE9C,CAAA;AAKD;;GAEG;AACH,eAAO,MAAM,cAAc,QAAS,MAAM,KAAG,MAK5C,CAAA;AAKD,eAAO,MAAM,UAAU,QAAS,MAAM,KAAG,MAAM,EACtB,CAAA"}
|
@@ -0,0 +1,84 @@
|
|
1
|
+
/*
|
2
|
+
* Note: don't export internals from {@see index.ts}!
|
3
|
+
*/
|
4
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
5
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
6
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
7
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
8
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
9
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
10
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
11
|
+
});
|
12
|
+
};
|
13
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
14
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
15
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
16
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
17
|
+
function step(op) {
|
18
|
+
if (f) throw new TypeError("Generator is already executing.");
|
19
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
20
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
21
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
22
|
+
switch (op[0]) {
|
23
|
+
case 0: case 1: t = op; break;
|
24
|
+
case 4: _.label++; return { value: op[1], done: false };
|
25
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
26
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
27
|
+
default:
|
28
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
29
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
30
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
31
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
32
|
+
if (t[2]) _.ops.pop();
|
33
|
+
_.trys.pop(); continue;
|
34
|
+
}
|
35
|
+
op = body.call(thisArg, _);
|
36
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
37
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
38
|
+
}
|
39
|
+
};
|
40
|
+
export var eolStyles = {
|
41
|
+
lf: "\n",
|
42
|
+
crlf: "\r\n"
|
43
|
+
};
|
44
|
+
/**
|
45
|
+
* The value of the EOL string: typically, either "\n" (=LF-style, compatible with POSIX/Linux/macOS), or "\r\n" (=CRLF-style, compatible with Windows).
|
46
|
+
*/
|
47
|
+
export var eol = eolStyles.lf;
|
48
|
+
/**
|
49
|
+
* Sets the EOL to the OS-dependent value.
|
50
|
+
*/
|
51
|
+
export var setEOLFromOS = function () { return __awaiter(void 0, void 0, void 0, function () {
|
52
|
+
return __generator(this, function (_a) {
|
53
|
+
return [2 /*return*/, import("os").then(function (os) {
|
54
|
+
eol = os.EOL;
|
55
|
+
})
|
56
|
+
/**
|
57
|
+
* Sets the EOL explicitly to the given value.
|
58
|
+
* (This is especially useful for testing.)
|
59
|
+
*/
|
60
|
+
];
|
61
|
+
});
|
62
|
+
}); };
|
63
|
+
/**
|
64
|
+
* Sets the EOL explicitly to the given value.
|
65
|
+
* (This is especially useful for testing.)
|
66
|
+
*/
|
67
|
+
export var setEOLExplicitly = function (newEol) {
|
68
|
+
eol = newEol;
|
69
|
+
};
|
70
|
+
var normalizeRegex = new RegExp(/\r*\n?$/);
|
71
|
+
/**
|
72
|
+
* Ensures that the given string ends with an EOL, adding one if necessary.
|
73
|
+
*/
|
74
|
+
export var withEOLEnsured = function (str) {
|
75
|
+
var match = str.match(normalizeRegex);
|
76
|
+
return match === null
|
77
|
+
? str // (should not happen, but OK...)
|
78
|
+
: (str.substring(0, match.index) + eol);
|
79
|
+
};
|
80
|
+
var splitRegex = new RegExp(/\r*\n/);
|
81
|
+
export var splitOnEOL = function (str) {
|
82
|
+
return str.split(splitRegex);
|
83
|
+
};
|
84
|
+
//# sourceMappingURL=internals.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"internals.js","sourceRoot":"","sources":["../src/internals.ts"],"names":[],"mappings":"AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGH,MAAM,CAAC,IAAM,SAAS,GAAG;IACrB,EAAE,EAAE,IAAI;IACR,IAAI,EAAE,MAAM;CACN,CAAA;AAEV;;GAEG;AACH,MAAM,CAAC,IAAI,GAAG,GAAW,SAAS,CAAC,EAAE,CAAA;AAGrC;;GAEG;AACH,MAAM,CAAC,IAAM,YAAY,GAAG;;QACxB,sBAAA,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAC,EAAE;gBACjB,GAAG,GAAG,EAAE,CAAC,GAAG,CAAA;YAChB,CAAC,CAAC;YAGN;;;eAGG;UANG;;KAAA,CAAA;AAGN;;;GAGG;AACH,MAAM,CAAC,IAAM,gBAAgB,GAAG,UAAC,MAAc;IAC3C,GAAG,GAAG,MAAM,CAAA;AAChB,CAAC,CAAA;AAGD,IAAM,cAAc,GAAG,IAAI,MAAM,CAAC,SAAS,CAAC,CAAA;AAE5C;;GAEG;AACH,MAAM,CAAC,IAAM,cAAc,GAAG,UAAC,GAAW;IACtC,IAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAA;IACvC,OAAO,KAAK,KAAK,IAAI;QACjB,CAAC,CAAC,GAAG,CAAG,iCAAiC;QACzC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAA;AAC/C,CAAC,CAAA;AAGD,IAAM,UAAU,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,CAAA;AAEtC,MAAM,CAAC,IAAM,UAAU,GAAG,UAAC,GAAW;IAClC,OAAA,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC;AAArB,CAAqB,CAAA"}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
/**
|
2
|
+
* @return the given array of strings but with commas added after each string except the last one.
|
3
|
+
*/
|
4
|
+
export declare const commaSeparated: (strings: string[]) => string[];
|
5
|
+
/**
|
6
|
+
* Polyfill/shim for ES2015's String.prototype.repeat which doesn't work for some reason in the test...
|
7
|
+
* (Implementation uses the binary representation of n.)
|
8
|
+
*/
|
9
|
+
export declare const repeat: (str: string, n: number) => string;
|
10
|
+
//# sourceMappingURL=strings.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../src/strings.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,cAAc,YAAa,MAAM,EAAE,aACiC,CAAA;AAEjF;;;GAGG;AACH,eAAO,MAAM,MAAM,QAAS,MAAM,KAAK,MAAM,KAAG,MAY/C,CAAA"}
|
package/dist/strings.js
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
/**
|
2
|
+
* @return the given array of strings but with commas added after each string except the last one.
|
3
|
+
*/
|
4
|
+
export var commaSeparated = function (strings) {
|
5
|
+
return strings.map(function (str, index) { return "".concat(str).concat(index + 1 < strings.length ? "," : ""); });
|
6
|
+
};
|
7
|
+
/**
|
8
|
+
* Polyfill/shim for ES2015's String.prototype.repeat which doesn't work for some reason in the test...
|
9
|
+
* (Implementation uses the binary representation of n.)
|
10
|
+
*/
|
11
|
+
export var repeat = function (str, n) {
|
12
|
+
var result = "";
|
13
|
+
while (n > 0) {
|
14
|
+
if (n % 2 === 1) {
|
15
|
+
result += str;
|
16
|
+
}
|
17
|
+
if (n > 1) {
|
18
|
+
str += str;
|
19
|
+
}
|
20
|
+
n >>= 1;
|
21
|
+
}
|
22
|
+
return result;
|
23
|
+
};
|
24
|
+
// TODO more common string utils, e.g. withFirst{Upper|Lower}, etc.
|
25
|
+
//# sourceMappingURL=strings.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"strings.js","sourceRoot":"","sources":["../src/strings.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,IAAM,cAAc,GAAG,UAAC,OAAiB;IAC5C,OAAA,OAAO,CAAC,GAAG,CAAC,UAAC,GAAG,EAAE,KAAK,IAAK,OAAA,UAAG,GAAG,SAAG,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAE,EAAhD,CAAgD,CAAC;AAA7E,CAA6E,CAAA;AAEjF;;;GAGG;AACH,MAAM,CAAC,IAAM,MAAM,GAAG,UAAC,GAAW,EAAE,CAAS;IACzC,IAAI,MAAM,GAAG,EAAE,CAAA;IACf,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACd,MAAM,IAAI,GAAG,CAAA;QACjB,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACR,GAAG,IAAI,GAAG,CAAA;QACd,CAAC;QACD,CAAC,KAAK,CAAC,CAAA;IACX,CAAC;IACD,OAAO,MAAM,CAAA;AACjB,CAAC,CAAA;AAGD,oEAAoE"}
|
package/dist/types.d.ts
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
/**
|
2
|
+
* A type definition for “templates” that consist of a string, or an array of templates, or a thunk returning a template.
|
3
|
+
* Note that nesting can occur to arbitrary (finite) depth.
|
4
|
+
*
|
5
|
+
* @since version 0.3.0
|
6
|
+
*/
|
7
|
+
export type Template = string | Array<Template> | (() => Template);
|
8
|
+
/**
|
9
|
+
* An alias for the {@link Template} type definition.
|
10
|
+
* Note: this type might be deprecated and removed (per a major version) in the future.
|
11
|
+
*/
|
12
|
+
export type NestedString = Template;
|
13
|
+
//# sourceMappingURL=types.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,QAAQ,CAAC,CAAA;AAElE;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAA"}
|
package/dist/types.js
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
@@ -1,39 +1,48 @@
|
|
1
1
|
{
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
"
|
33
|
-
"
|
34
|
-
"
|
35
|
-
|
36
|
-
|
37
|
-
"
|
38
|
-
|
2
|
+
"name": "littoral-templates",
|
3
|
+
"version": "0.4.0-rc.2",
|
4
|
+
"description": "A small JavaScript/TypeScript framework to do templating comfortably using the template literal syntax in either JavaScript or TypeScript.",
|
5
|
+
"type": "module",
|
6
|
+
"main": "dist/index.js",
|
7
|
+
"types": "dist/index.d.ts",
|
8
|
+
"scripts": {
|
9
|
+
"build": "tsc",
|
10
|
+
"watch-build": "tsc --watch",
|
11
|
+
"clean": "rm -rf dist node_modules",
|
12
|
+
"pretest": "npm run build",
|
13
|
+
"test": "mocha dist/test/*.js",
|
14
|
+
"watch-test": "mocha --watch dist/test/*.js",
|
15
|
+
"lint": "eslint src",
|
16
|
+
"prep:pre-release": "npm run clean && npm install && npm test",
|
17
|
+
"prerelease": "npm run prep:pre-release",
|
18
|
+
"release": "npm publish",
|
19
|
+
"prerelease-alpha": "npm run prep:pre-release",
|
20
|
+
"release-alpha": "npm publish --tag beta",
|
21
|
+
"prerelease-beta": "npm run prep:pre-release",
|
22
|
+
"release-beta": "npm publish --tag beta"
|
23
|
+
},
|
24
|
+
"repository": {
|
25
|
+
"type": "git",
|
26
|
+
"url": "git+https://github.com/dslmeinte/littoral-templates.git"
|
27
|
+
},
|
28
|
+
"keywords": [
|
29
|
+
"template",
|
30
|
+
"engine"
|
31
|
+
],
|
32
|
+
"author": "Meinte Boersma",
|
33
|
+
"license": "MIT",
|
34
|
+
"bugs": {
|
35
|
+
"url": "https://github.com/dslmeinte/littoral-templates/issues"
|
36
|
+
},
|
37
|
+
"homepage": "https://github.com/dslmeinte/littoral-templates#readme",
|
38
|
+
"devDependencies": {
|
39
|
+
"@types/chai": "5.2.2",
|
40
|
+
"@types/mocha": "10.0.10",
|
41
|
+
"@types/node": "18.19.112",
|
42
|
+
"@typescript-eslint/eslint-plugin": "6.21.0",
|
43
|
+
"@typescript-eslint/parser": "6.21.0",
|
44
|
+
"chai": "5.2.0",
|
45
|
+
"mocha": "10.8.2",
|
46
|
+
"typescript": "5.3.3"
|
47
|
+
}
|
39
48
|
}
|