edgexpress 3.0.0 → 3.0.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.
Files changed (92) hide show
  1. package/eslint.config.cjs +6 -0
  2. package/examples/index.js +41 -0
  3. package/examples/views/components/layout/main.edge +26 -0
  4. package/examples/views/components/modal.edge +27 -0
  5. package/examples/views/home.edge +84 -0
  6. package/examples/views/partials/button.edge +1 -0
  7. package/examples/views/partials/home-footer.edge +49 -0
  8. package/examples/views/partials/home-header.edge +61 -0
  9. package/examples/views/welcome.edge +22 -0
  10. package/index.d.ts +7 -0
  11. package/package.json +12 -4
  12. package/src/cache_manager.d.ts +28 -0
  13. package/src/cache_manager.js +58 -0
  14. package/src/compiler.d.ts +73 -0
  15. package/src/compiler.js +319 -0
  16. package/src/component/props.d.ts +53 -0
  17. package/src/component/props.js +110 -0
  18. package/src/edge/globals.d.ts +5 -0
  19. package/src/edge/globals.js +95 -0
  20. package/src/edge/main.d.ts +192 -0
  21. package/src/edge/main.js +334 -0
  22. package/src/edge/renderer.d.ts +44 -0
  23. package/src/edge/renderer.js +85 -0
  24. package/src/edge/stacks.d.ts +22 -0
  25. package/src/edge/stacks.js +98 -0
  26. package/src/loader.d.ts +138 -0
  27. package/src/loader.js +347 -0
  28. package/src/migrate/globals.d.ts +1 -0
  29. package/src/migrate/globals.js +100 -0
  30. package/src/migrate/plugin.d.ts +2 -0
  31. package/src/migrate/plugin.js +58 -0
  32. package/src/migrate/props.d.ts +66 -0
  33. package/src/migrate/props.js +129 -0
  34. package/src/migrate/tags/layout.d.ts +6 -0
  35. package/src/migrate/tags/layout.js +25 -0
  36. package/src/migrate/tags/main.d.ts +4 -0
  37. package/src/migrate/tags/main.js +19 -0
  38. package/src/migrate/tags/section.d.ts +6 -0
  39. package/src/migrate/tags/section.js +23 -0
  40. package/src/migrate/tags/set.d.ts +26 -0
  41. package/src/migrate/tags/set.js +104 -0
  42. package/src/migrate/tags/super.d.ts +9 -0
  43. package/src/migrate/tags/super.js +31 -0
  44. package/src/plugins/supercharged.d.ts +4 -0
  45. package/src/plugins/supercharged.js +88 -0
  46. package/src/processor.d.ts +42 -0
  47. package/src/processor.js +86 -0
  48. package/src/tags/assign.d.ts +5 -0
  49. package/src/tags/assign.js +42 -0
  50. package/src/tags/component.d.ts +6 -0
  51. package/src/tags/component.js +299 -0
  52. package/src/tags/debugger.d.ts +5 -0
  53. package/src/tags/debugger.js +26 -0
  54. package/src/tags/each.d.ts +20 -0
  55. package/src/tags/each.js +185 -0
  56. package/src/tags/else.d.ts +2 -0
  57. package/src/tags/else.js +22 -0
  58. package/src/tags/else_if.d.ts +7 -0
  59. package/src/tags/else_if.js +39 -0
  60. package/src/tags/eval.d.ts +7 -0
  61. package/src/tags/eval.js +30 -0
  62. package/src/tags/if.d.ts +5 -0
  63. package/src/tags/if.js +45 -0
  64. package/src/tags/include.d.ts +27 -0
  65. package/src/tags/include.js +78 -0
  66. package/src/tags/include_if.d.ts +10 -0
  67. package/src/tags/include_if.js +61 -0
  68. package/src/tags/inject.d.ts +6 -0
  69. package/src/tags/inject.js +40 -0
  70. package/src/tags/let.d.ts +6 -0
  71. package/src/tags/let.js +69 -0
  72. package/src/tags/main.d.ts +18 -0
  73. package/src/tags/main.js +47 -0
  74. package/src/tags/new_error.d.ts +6 -0
  75. package/src/tags/new_error.js +47 -0
  76. package/src/tags/push_once_to.d.ts +13 -0
  77. package/src/tags/push_once_to.js +65 -0
  78. package/src/tags/push_to.d.ts +7 -0
  79. package/src/tags/push_to.js +62 -0
  80. package/src/tags/slot.d.ts +6 -0
  81. package/src/tags/slot.js +29 -0
  82. package/src/tags/stack.d.ts +5 -0
  83. package/src/tags/stack.js +38 -0
  84. package/src/tags/unless.d.ts +12 -0
  85. package/src/tags/unless.js +52 -0
  86. package/src/template.d.ts +127 -0
  87. package/src/template.js +203 -0
  88. package/src/types.d.ts +144 -0
  89. package/src/types.js +10 -0
  90. package/src/utils.d.ts +96 -0
  91. package/src/utils.js +297 -0
  92. package/tsconfig.json +16 -0
@@ -0,0 +1,319 @@
1
+ "use strict";
2
+ /*
3
+ * edge.js
4
+ *
5
+ * (c) EdgeJS
6
+ *
7
+ * For the full copyright and license information, please view the LICENSE
8
+ * file that was distributed with this source code.
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.Compiler = void 0;
45
+ const edge_error_1 = require("edge-error");
46
+ const lexerUtils = __importStar(require("edge-lexer/utils"));
47
+ const edge_parser_1 = require("edge-parser");
48
+ const cache_manager_js_1 = require("./cache_manager.js");
49
+ const AsyncFunction = Object.getPrototypeOf(async function () { }).constructor;
50
+ /**
51
+ * Compiler is to used to compile templates using the `edge-parser`. Along with that
52
+ * it natively merges the contents of a layout with a parent template.
53
+ */
54
+ class Compiler {
55
+ /**
56
+ * The variables someone can access inside templates. All other
57
+ * variables will get prefixed with `state` property name
58
+ */
59
+ #inlineVariables = ['$filename', 'state', '$context'];
60
+ /**
61
+ * A fixed set of params to pass to the template every time.
62
+ */
63
+ #templateParams = ['template', 'state', '$context'];
64
+ #claimTagFn;
65
+ #loader;
66
+ #tags;
67
+ #processor;
68
+ /**
69
+ * Caches compiled templates
70
+ */
71
+ cacheManager;
72
+ /**
73
+ * A boolean to know if compat mode is enabled
74
+ */
75
+ compat;
76
+ /**
77
+ * Know if compiler is compiling in the async mode or not
78
+ */
79
+ async;
80
+ constructor(loader, tags, processor, options = {
81
+ cache: true,
82
+ async: false,
83
+ compat: false,
84
+ }) {
85
+ this.#processor = processor;
86
+ this.#loader = loader;
87
+ this.#tags = tags;
88
+ this.async = !!options.async;
89
+ this.compat = options.compat === true;
90
+ this.cacheManager = new cache_manager_js_1.CacheManager(!!options.cache);
91
+ }
92
+ /**
93
+ * Merges sections of base template and parent template tokens
94
+ */
95
+ #mergeSections(base, extended) {
96
+ /**
97
+ * Collection of all sections from the extended tokens
98
+ */
99
+ const extendedSections = {};
100
+ /**
101
+ * Collection of extended set calls as top level nodes. The set
102
+ * calls are hoisted just like `var` statements in Javascript.
103
+ */
104
+ const extendedSetCalls = [];
105
+ extended.forEach((node) => {
106
+ /**
107
+ * Ignore new lines, comments, layout tag and empty raw nodes inside the parent
108
+ * template
109
+ */
110
+ if (lexerUtils.isTag(node, 'layout') ||
111
+ node.type === 'newline' ||
112
+ (node.type === 'raw' && !node.value.trim()) ||
113
+ node.type === 'comment') {
114
+ return;
115
+ }
116
+ /**
117
+ * Collect parent template sections
118
+ */
119
+ if (lexerUtils.isTag(node, 'section')) {
120
+ extendedSections[node.properties.jsArg.trim()] = node;
121
+ return;
122
+ }
123
+ /**
124
+ * Collect set calls inside parent templates
125
+ */
126
+ if (lexerUtils.isTag(node, 'set')) {
127
+ extendedSetCalls.push(node);
128
+ return;
129
+ }
130
+ /**
131
+ * Everything else is not allowed as top level nodes
132
+ */
133
+ const [line, col] = lexerUtils.getLineAndColumn(node);
134
+ throw new edge_error_1.EdgeError('Template extending a layout can only use "@section" or "@set" tags as top level nodes', 'E_UNALLOWED_EXPRESSION', { line, col, filename: node.filename });
135
+ });
136
+ /**
137
+ * Replace/extend sections inside base tokens list
138
+ */
139
+ const finalNodes = base.map((node) => {
140
+ if (!lexerUtils.isTag(node, 'section')) {
141
+ return node;
142
+ }
143
+ const sectionName = node.properties.jsArg.trim();
144
+ const extendedNode = extendedSections[sectionName];
145
+ if (!extendedNode) {
146
+ return node;
147
+ }
148
+ /**
149
+ * Concat children when super was called
150
+ */
151
+ if (extendedNode.children.length) {
152
+ if (lexerUtils.isTag(extendedNode.children[0], 'super')) {
153
+ extendedNode.children.shift();
154
+ extendedNode.children = node.children.concat(extendedNode.children);
155
+ }
156
+ else if (lexerUtils.isTag(extendedNode.children[1], 'super')) {
157
+ extendedNode.children.shift();
158
+ extendedNode.children.shift();
159
+ extendedNode.children = node.children.concat(extendedNode.children);
160
+ }
161
+ }
162
+ return extendedNode;
163
+ });
164
+ /**
165
+ * Set calls are hoisted to the top
166
+ */
167
+ return [].concat(extendedSetCalls).concat(finalNodes);
168
+ }
169
+ /**
170
+ * Generates an array of lexer tokens from the template string. Further tokens
171
+ * are checked for layouts and if layouts are used, their sections will be
172
+ * merged together.
173
+ */
174
+ #templateContentToTokens(content, parser, absPath) {
175
+ let templateTokens = parser.tokenize(content, { filename: absPath });
176
+ /**
177
+ * Parse layout and section in compat mode only
178
+ */
179
+ if (this.compat) {
180
+ const firstToken = templateTokens[0];
181
+ /**
182
+ * The `layout` is inbuilt feature from core, where we merge the layout
183
+ * and parent template sections together
184
+ */
185
+ if (lexerUtils.isTag(firstToken, 'layout')) {
186
+ const layoutName = firstToken.properties.jsArg.replace(/'|"/g, '');
187
+ templateTokens = this.#mergeSections(this.tokenize(layoutName, parser), templateTokens);
188
+ }
189
+ }
190
+ return templateTokens;
191
+ }
192
+ /**
193
+ * Returns the parser instance for a given template
194
+ */
195
+ #getParserFor(templatePath, localVariables) {
196
+ const parser = new edge_parser_1.Parser(this.#tags, new edge_parser_1.Stack(), {
197
+ claimTag: this.#claimTagFn,
198
+ async: this.async,
199
+ statePropertyName: 'state',
200
+ escapeCallPath: ['template', 'escape'],
201
+ localVariables: this.#inlineVariables,
202
+ onTag: (tag) => this.#processor.executeTag({ tag, path: templatePath }),
203
+ });
204
+ /**
205
+ * Define local variables on the parser. This is helpful when trying to compile
206
+ * a partail and we want to share the local state of the parent template
207
+ * with it
208
+ */
209
+ if (localVariables) {
210
+ localVariables.forEach((localVariable) => parser.stack.defineVariable(localVariable));
211
+ }
212
+ return parser;
213
+ }
214
+ /**
215
+ * Returns the parser instance for a given template
216
+ */
217
+ #getBufferFor(templatePath) {
218
+ return new edge_parser_1.EdgeBuffer(templatePath, {
219
+ outputVar: 'out',
220
+ rethrowCallPath: ['template', 'reThrow'],
221
+ });
222
+ }
223
+ /**
224
+ * Wraps template output to a function along with local variables
225
+ */
226
+ #wrapToFunction(template, localVariables) {
227
+ const args = localVariables ? this.#templateParams.concat(localVariables) : this.#templateParams;
228
+ if (this.async) {
229
+ return new AsyncFunction(...args, template);
230
+ }
231
+ return new Function(...args, template);
232
+ }
233
+ /**
234
+ * Define a function to claim tags
235
+ */
236
+ claimTag(fn) {
237
+ this.#claimTagFn = fn;
238
+ return this;
239
+ }
240
+ /**
241
+ * Converts the template content to an array of lexer tokens. The method is
242
+ * same as the `parser.tokenize`, but it also handles layouts natively.
243
+ *
244
+ * ```
245
+ * compiler.tokenize('<template-path>')
246
+ * ```
247
+ */
248
+ tokenize(templatePath, parser) {
249
+ const absPath = this.#loader.makePath(templatePath);
250
+ let { template } = this.#loader.resolve(absPath);
251
+ return this.tokenizeRaw(template, absPath, parser);
252
+ }
253
+ /**
254
+ * Tokenize a raw template
255
+ */
256
+ tokenizeRaw(contents, templatePath = 'eval.edge', parser) {
257
+ contents = this.#processor.executeRaw({ path: templatePath, raw: contents });
258
+ return this.#templateContentToTokens(contents, parser || this.#getParserFor(templatePath), templatePath);
259
+ }
260
+ /**
261
+ * Compiles the template contents to string. The output is same as the `edge-parser`,
262
+ * it's just that the compiler uses the loader to load the templates and also
263
+ * handles layouts.
264
+ *
265
+ * ```js
266
+ * compiler.compile('welcome')
267
+ * ```
268
+ */
269
+ compile(templatePath, localVariables) {
270
+ const absPath = this.#loader.makePath(templatePath);
271
+ let cachedResponse = localVariables ? null : this.cacheManager.get(absPath);
272
+ /**
273
+ * Process the template and cache it
274
+ */
275
+ if (!cachedResponse) {
276
+ const parser = this.#getParserFor(absPath, localVariables);
277
+ const buffer = this.#getBufferFor(absPath);
278
+ /**
279
+ * Generate tokens and process them
280
+ */
281
+ const templateTokens = this.tokenize(absPath, parser);
282
+ templateTokens.forEach((token) => parser.processToken(token, buffer));
283
+ /**
284
+ * Processing template via hook
285
+ */
286
+ const template = this.#processor.executeCompiled({
287
+ path: absPath,
288
+ compiled: buffer.flush(),
289
+ });
290
+ const compiledTemplate = this.#wrapToFunction(template, localVariables);
291
+ if (!localVariables) {
292
+ this.cacheManager.set(absPath, compiledTemplate);
293
+ }
294
+ cachedResponse = compiledTemplate;
295
+ }
296
+ return cachedResponse;
297
+ }
298
+ /**
299
+ * Compiles the template contents to string. The output is same as the `edge-parser`,
300
+ * it's just that the compiler uses the loader to load the templates and also
301
+ * handles layouts.
302
+ *
303
+ * ```js
304
+ * compiler.compileRaw('welcome')
305
+ * ```
306
+ */
307
+ compileRaw(contents, templatePath = 'eval.edge') {
308
+ const parser = this.#getParserFor(templatePath);
309
+ const buffer = this.#getBufferFor(templatePath);
310
+ const templateTokens = this.tokenizeRaw(contents, templatePath, parser);
311
+ templateTokens.forEach((token) => parser.processToken(token, buffer));
312
+ const template = this.#processor.executeCompiled({
313
+ path: templatePath,
314
+ compiled: buffer.flush(),
315
+ });
316
+ return this.#wrapToFunction(template);
317
+ }
318
+ }
319
+ exports.Compiler = Compiler;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Representation of component props with ability to serialize
3
+ * them into HTML attributes
4
+ */
5
+ export declare class ComponentProps {
6
+ #private
7
+ constructor(values: Record<string, any>)
8
+ /**
9
+ * Create a typed instance of Component props with properties
10
+ */
11
+ static create<T extends Record<string, any>>(values: T): ComponentProps & T
12
+ /**
13
+ * Reference to props raw values
14
+ */
15
+ all(): Record<string, any>
16
+ /**
17
+ * Check if a key exists
18
+ */
19
+ has(key: string): any
20
+ /**
21
+ * Get key value
22
+ */
23
+ get(key: string, defaultValue?: any): any
24
+ /**
25
+ * Returns a new props bag with only the mentioned keys
26
+ */
27
+ only(keys: string[]): ComponentProps
28
+ /**
29
+ * Returns a new props bag with except the mentioned keys
30
+ */
31
+ except(keys: string[]): ComponentProps
32
+ /**
33
+ * Merge defaults with the props
34
+ *
35
+ * - All other attributes will be overwritten when defined in props
36
+ * - Classes will be merged together.
37
+ */
38
+ merge(values: Record<string, any>): ComponentProps
39
+ /**
40
+ * Merge defaults with the props, if the given condition is truthy
41
+ */
42
+ mergeIf(conditional: any, values: Record<string, any>): ComponentProps
43
+ /**
44
+ * Merge defaults with the props, if the given condition is falsy
45
+ */
46
+ mergeUnless(conditional: any, values: Record<string, any>): ComponentProps
47
+ /**
48
+ * Converts props to HTML attributes
49
+ */
50
+ toAttrs(): {
51
+ value: any
52
+ }
53
+ }
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ /*
3
+ * edge.js
4
+ *
5
+ * (c) EdgeJS
6
+ *
7
+ * For the full copyright and license information, please view the LICENSE
8
+ * file that was distributed with this source code.
9
+ */
10
+ var __importDefault = (this && this.__importDefault) || function (mod) {
11
+ return (mod && mod.__esModule) ? mod : { "default": mod };
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.ComponentProps = void 0;
15
+ const lodash_1 = __importDefault(require("@poppinss/utils/lodash"));
16
+ const template_js_1 = require("../template.js");
17
+ const utils_js_1 = require("../utils.js");
18
+ /**
19
+ * Representation of component props with ability to serialize
20
+ * them into HTML attributes
21
+ */
22
+ class ComponentProps {
23
+ #values;
24
+ constructor(values) {
25
+ this.#values = values;
26
+ Object.assign(this, values);
27
+ }
28
+ /**
29
+ * Create a typed instance of Component props with properties
30
+ */
31
+ static create(values) {
32
+ return new ComponentProps(values);
33
+ }
34
+ /**
35
+ * Reference to props raw values
36
+ */
37
+ all() {
38
+ return this.#values;
39
+ }
40
+ /**
41
+ * Check if a key exists
42
+ */
43
+ has(key) {
44
+ return lodash_1.default.has(this.#values, key);
45
+ }
46
+ /**
47
+ * Get key value
48
+ */
49
+ get(key, defaultValue) {
50
+ return lodash_1.default.get(this.#values, key, defaultValue);
51
+ }
52
+ /**
53
+ * Returns a new props bag with only the mentioned keys
54
+ */
55
+ only(keys) {
56
+ return new ComponentProps(lodash_1.default.pick(this.#values, keys));
57
+ }
58
+ /**
59
+ * Returns a new props bag with except the mentioned keys
60
+ */
61
+ except(keys) {
62
+ return new ComponentProps(lodash_1.default.omit(this.#values, keys));
63
+ }
64
+ /**
65
+ * Merge defaults with the props
66
+ *
67
+ * - All other attributes will be overwritten when defined in props
68
+ * - Classes will be merged together.
69
+ */
70
+ merge(values) {
71
+ if (values.class && this.#values['class']) {
72
+ const classesSet = new Set();
73
+ (Array.isArray(values.class) ? values.class : [values]).forEach((item) => {
74
+ classesSet.add(item);
75
+ });
76
+ (Array.isArray(this.#values['class'])
77
+ ? this.#values['class']
78
+ : [this.#values['class']]).forEach((item) => {
79
+ classesSet.add(item);
80
+ });
81
+ return new ComponentProps({ ...values, ...this.#values, class: Array.from(classesSet) });
82
+ }
83
+ return new ComponentProps({ ...values, ...this.#values });
84
+ }
85
+ /**
86
+ * Merge defaults with the props, if the given condition is truthy
87
+ */
88
+ mergeIf(conditional, values) {
89
+ if (conditional) {
90
+ return this.merge(values);
91
+ }
92
+ return this;
93
+ }
94
+ /**
95
+ * Merge defaults with the props, if the given condition is falsy
96
+ */
97
+ mergeUnless(conditional, values) {
98
+ if (!conditional) {
99
+ return this.merge(values);
100
+ }
101
+ return this;
102
+ }
103
+ /**
104
+ * Converts props to HTML attributes
105
+ */
106
+ toAttrs() {
107
+ return (0, template_js_1.htmlSafe)((0, utils_js_1.stringifyAttributes)(this.#values));
108
+ }
109
+ }
110
+ exports.ComponentProps = ComponentProps;
@@ -0,0 +1,5 @@
1
+ import type { EdgeGlobals } from '../types.js'
2
+ /**
3
+ * Inbuilt globals
4
+ */
5
+ export declare const edgeGlobals: EdgeGlobals
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ /*
3
+ * edge.js.js
4
+ *
5
+ * (c) EdgeJS
6
+ *
7
+ * For the full copyright and license information, please view the LICENSE
8
+ * file that was distributed with this source code.
9
+ */
10
+ var __importDefault = (this && this.__importDefault) || function (mod) {
11
+ return (mod && mod.__esModule) ? mod : { "default": mod };
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.edgeGlobals = void 0;
15
+ // @ts-expect-error untyped module
16
+ const js_stringify_1 = __importDefault(require("js-stringify"));
17
+ const classnames_1 = __importDefault(require("classnames"));
18
+ // @ts-expect-error untyped module
19
+ const inspect_1 = __importDefault(require("@poppinss/inspect"));
20
+ const string_1 = __importDefault(require("@poppinss/utils/string"));
21
+ const template_js_1 = require("../template.js");
22
+ const utils_js_1 = require("../utils.js");
23
+ /**
24
+ * Inbuilt globals
25
+ */
26
+ exports.edgeGlobals = {
27
+ /**
28
+ * Converts new lines to break
29
+ */
30
+ nl2br: (value) => {
31
+ if (!value) {
32
+ return;
33
+ }
34
+ return String(value).replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1<br>');
35
+ },
36
+ /**
37
+ * Inspect state
38
+ */
39
+ inspect: (value) => {
40
+ return (0, template_js_1.htmlSafe)(inspect_1.default.string.html(value));
41
+ },
42
+ /**
43
+ * Truncate a sentence
44
+ */
45
+ truncate: (value, length = 20, options) => {
46
+ options = options || {};
47
+ return string_1.default.truncate(value, length, {
48
+ completeWords: options.completeWords !== undefined ? options.completeWords : !options.strict,
49
+ suffix: options.suffix,
50
+ });
51
+ },
52
+ /**
53
+ * Generate an excerpt
54
+ */
55
+ excerpt: (value, length = 20, options) => {
56
+ options = options || {};
57
+ return string_1.default.excerpt(value, length, {
58
+ completeWords: options.completeWords !== undefined ? options.completeWords : !options.strict,
59
+ suffix: options.suffix,
60
+ });
61
+ },
62
+ /**
63
+ * Helpers related to HTML
64
+ */
65
+ html: {
66
+ escape: template_js_1.escape,
67
+ safe: template_js_1.htmlSafe,
68
+ classNames: classnames_1.default,
69
+ attrs: (values) => {
70
+ return (0, template_js_1.htmlSafe)((0, utils_js_1.stringifyAttributes)(values));
71
+ },
72
+ },
73
+ /**
74
+ * Helpers related to JavaScript
75
+ */
76
+ js: {
77
+ stringify: js_stringify_1.default,
78
+ },
79
+ camelCase: string_1.default.camelCase,
80
+ snakeCase: string_1.default.snakeCase,
81
+ dashCase: string_1.default.dashCase,
82
+ pascalCase: string_1.default.pascalCase,
83
+ capitalCase: string_1.default.capitalCase,
84
+ sentenceCase: string_1.default.sentenceCase,
85
+ dotCase: string_1.default.dotCase,
86
+ noCase: string_1.default.noCase,
87
+ titleCase: string_1.default.titleCase,
88
+ pluralize: string_1.default.pluralize,
89
+ sentence: string_1.default.sentence,
90
+ prettyMs: string_1.default.milliseconds.format,
91
+ toMs: string_1.default.milliseconds.parse,
92
+ prettyBytes: string_1.default.bytes.format,
93
+ toBytes: string_1.default.bytes.parse,
94
+ ordinal: string_1.default.ordinal,
95
+ };