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.
- package/eslint.config.cjs +6 -0
- package/examples/index.js +41 -0
- package/examples/views/components/layout/main.edge +26 -0
- package/examples/views/components/modal.edge +27 -0
- package/examples/views/home.edge +84 -0
- package/examples/views/partials/button.edge +1 -0
- package/examples/views/partials/home-footer.edge +49 -0
- package/examples/views/partials/home-header.edge +61 -0
- package/examples/views/welcome.edge +22 -0
- package/index.d.ts +7 -0
- package/package.json +12 -4
- package/src/cache_manager.d.ts +28 -0
- package/src/cache_manager.js +58 -0
- package/src/compiler.d.ts +73 -0
- package/src/compiler.js +319 -0
- package/src/component/props.d.ts +53 -0
- package/src/component/props.js +110 -0
- package/src/edge/globals.d.ts +5 -0
- package/src/edge/globals.js +95 -0
- package/src/edge/main.d.ts +192 -0
- package/src/edge/main.js +334 -0
- package/src/edge/renderer.d.ts +44 -0
- package/src/edge/renderer.js +85 -0
- package/src/edge/stacks.d.ts +22 -0
- package/src/edge/stacks.js +98 -0
- package/src/loader.d.ts +138 -0
- package/src/loader.js +347 -0
- package/src/migrate/globals.d.ts +1 -0
- package/src/migrate/globals.js +100 -0
- package/src/migrate/plugin.d.ts +2 -0
- package/src/migrate/plugin.js +58 -0
- package/src/migrate/props.d.ts +66 -0
- package/src/migrate/props.js +129 -0
- package/src/migrate/tags/layout.d.ts +6 -0
- package/src/migrate/tags/layout.js +25 -0
- package/src/migrate/tags/main.d.ts +4 -0
- package/src/migrate/tags/main.js +19 -0
- package/src/migrate/tags/section.d.ts +6 -0
- package/src/migrate/tags/section.js +23 -0
- package/src/migrate/tags/set.d.ts +26 -0
- package/src/migrate/tags/set.js +104 -0
- package/src/migrate/tags/super.d.ts +9 -0
- package/src/migrate/tags/super.js +31 -0
- package/src/plugins/supercharged.d.ts +4 -0
- package/src/plugins/supercharged.js +88 -0
- package/src/processor.d.ts +42 -0
- package/src/processor.js +86 -0
- package/src/tags/assign.d.ts +5 -0
- package/src/tags/assign.js +42 -0
- package/src/tags/component.d.ts +6 -0
- package/src/tags/component.js +299 -0
- package/src/tags/debugger.d.ts +5 -0
- package/src/tags/debugger.js +26 -0
- package/src/tags/each.d.ts +20 -0
- package/src/tags/each.js +185 -0
- package/src/tags/else.d.ts +2 -0
- package/src/tags/else.js +22 -0
- package/src/tags/else_if.d.ts +7 -0
- package/src/tags/else_if.js +39 -0
- package/src/tags/eval.d.ts +7 -0
- package/src/tags/eval.js +30 -0
- package/src/tags/if.d.ts +5 -0
- package/src/tags/if.js +45 -0
- package/src/tags/include.d.ts +27 -0
- package/src/tags/include.js +78 -0
- package/src/tags/include_if.d.ts +10 -0
- package/src/tags/include_if.js +61 -0
- package/src/tags/inject.d.ts +6 -0
- package/src/tags/inject.js +40 -0
- package/src/tags/let.d.ts +6 -0
- package/src/tags/let.js +69 -0
- package/src/tags/main.d.ts +18 -0
- package/src/tags/main.js +47 -0
- package/src/tags/new_error.d.ts +6 -0
- package/src/tags/new_error.js +47 -0
- package/src/tags/push_once_to.d.ts +13 -0
- package/src/tags/push_once_to.js +65 -0
- package/src/tags/push_to.d.ts +7 -0
- package/src/tags/push_to.js +62 -0
- package/src/tags/slot.d.ts +6 -0
- package/src/tags/slot.js +29 -0
- package/src/tags/stack.d.ts +5 -0
- package/src/tags/stack.js +38 -0
- package/src/tags/unless.d.ts +12 -0
- package/src/tags/unless.js +52 -0
- package/src/template.d.ts +127 -0
- package/src/template.js +203 -0
- package/src/types.d.ts +144 -0
- package/src/types.js +10 -0
- package/src/utils.d.ts +96 -0
- package/src/utils.js +297 -0
- package/tsconfig.json +16 -0
package/src/types.d.ts
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* edge
|
|
3
|
+
*
|
|
4
|
+
* (c) EdgeJS
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
import type { TagToken } from 'edge-lexer/types'
|
|
10
|
+
import type { Parser, EdgeBuffer } from 'edge-parser'
|
|
11
|
+
import type { ParserTagDefinitionContract } from 'edge-parser/types'
|
|
12
|
+
import type { Edge } from './edge/main.js'
|
|
13
|
+
import type { Template } from './template.js'
|
|
14
|
+
/**
|
|
15
|
+
* The shape in which the loader must resolve the template
|
|
16
|
+
*/
|
|
17
|
+
export type LoaderTemplate = {
|
|
18
|
+
template: string
|
|
19
|
+
}
|
|
20
|
+
export type ComponentsTree = {
|
|
21
|
+
diskName: string
|
|
22
|
+
components: {
|
|
23
|
+
componentName: string
|
|
24
|
+
tagName: string
|
|
25
|
+
}[]
|
|
26
|
+
}[]
|
|
27
|
+
/**
|
|
28
|
+
* Loader contract that every loader must adheres to.
|
|
29
|
+
*/
|
|
30
|
+
export interface LoaderContract {
|
|
31
|
+
/**
|
|
32
|
+
* List of mounted disks
|
|
33
|
+
*/
|
|
34
|
+
mounted: {
|
|
35
|
+
[diskName: string]: string
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* List of pre-registered template
|
|
39
|
+
*/
|
|
40
|
+
templates: {
|
|
41
|
+
[templatePath: string]: LoaderTemplate
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Save disk name and dirPath to resolve views
|
|
45
|
+
*/
|
|
46
|
+
mount(diskName: string, dirPath: string | URL): void
|
|
47
|
+
/**
|
|
48
|
+
* Remove disk from the previously saved paths
|
|
49
|
+
*/
|
|
50
|
+
unmount(diskName: string): void
|
|
51
|
+
/**
|
|
52
|
+
* Resolve template contents
|
|
53
|
+
*/
|
|
54
|
+
resolve(templatePath: string): LoaderTemplate
|
|
55
|
+
/**
|
|
56
|
+
* Make absolute path to a template
|
|
57
|
+
*/
|
|
58
|
+
makePath(templatePath: string): string
|
|
59
|
+
/**
|
|
60
|
+
* Register in memory template and presenter
|
|
61
|
+
*/
|
|
62
|
+
register(templatePath: string, contents: LoaderTemplate): void
|
|
63
|
+
/**
|
|
64
|
+
* Remove the pre-registered template
|
|
65
|
+
*/
|
|
66
|
+
remove(templatePath: string): void
|
|
67
|
+
/**
|
|
68
|
+
* Returns a list of components for all the registered disks
|
|
69
|
+
*/
|
|
70
|
+
listComponents(): ComponentsTree
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The tag must have a tagName along with other properties
|
|
74
|
+
* required by lexer and parser
|
|
75
|
+
*/
|
|
76
|
+
export interface TagContract extends ParserTagDefinitionContract {
|
|
77
|
+
tagName: string
|
|
78
|
+
boot?(template: typeof Template): void
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Shape of collection of tags
|
|
82
|
+
*/
|
|
83
|
+
export type TagsContract = {
|
|
84
|
+
[tagName: string]: TagContract
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Shape of compiled template as a function
|
|
88
|
+
*/
|
|
89
|
+
export type CompiledTemplate = (
|
|
90
|
+
template: Template,
|
|
91
|
+
state: Record<string, any>,
|
|
92
|
+
$context: Record<string, any> | undefined,
|
|
93
|
+
...localVariables: any[]
|
|
94
|
+
) => any
|
|
95
|
+
/**
|
|
96
|
+
* Shape of the cache manager
|
|
97
|
+
*/
|
|
98
|
+
export interface CacheManagerContract {
|
|
99
|
+
enabled: boolean
|
|
100
|
+
get(templatePath: string): undefined | CompiledTemplate
|
|
101
|
+
set(templatePath: string, compiledOutput: CompiledTemplate): void
|
|
102
|
+
has(templatePath: string): boolean
|
|
103
|
+
delete(templatePath: string): void
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Compiler constructor options
|
|
107
|
+
*/
|
|
108
|
+
export type CompilerOptions = {
|
|
109
|
+
cache?: boolean
|
|
110
|
+
async?: boolean
|
|
111
|
+
compat?: boolean
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Shape of options that can be passed to the
|
|
115
|
+
* edge constructor
|
|
116
|
+
*/
|
|
117
|
+
export type EdgeOptions = {
|
|
118
|
+
loader?: LoaderContract
|
|
119
|
+
cache?: boolean
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Shape of edge plugin
|
|
123
|
+
*/
|
|
124
|
+
export type PluginFn<T> = (edge: Edge, firstRun: boolean, options: T) => void
|
|
125
|
+
/**
|
|
126
|
+
* Shape of global helpers
|
|
127
|
+
*/
|
|
128
|
+
export type EdgeGlobals = Record<string, any>
|
|
129
|
+
/**
|
|
130
|
+
* Required when creating custom tags
|
|
131
|
+
*/
|
|
132
|
+
export type ParserContract = Parser
|
|
133
|
+
export type TagTokenContract = TagToken
|
|
134
|
+
export type EdgeBufferContract = EdgeBuffer
|
|
135
|
+
export type * from 'edge-lexer/types'
|
|
136
|
+
export type {
|
|
137
|
+
AcornLoc,
|
|
138
|
+
ClaimTagFn,
|
|
139
|
+
MustacheTransformer,
|
|
140
|
+
OnLineFn,
|
|
141
|
+
ParserOptions,
|
|
142
|
+
ParserTagDefinitionContract,
|
|
143
|
+
TagTransformer,
|
|
144
|
+
} from 'edge-parser/types'
|
package/src/types.js
ADDED
package/src/utils.d.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { TagToken } from 'edge-lexer/types'
|
|
2
|
+
import { type expressions as expressionsList, type Parser } from 'edge-parser'
|
|
3
|
+
type ExpressionList = readonly (keyof typeof expressionsList | 'ObjectPattern' | 'ArrayPattern')[]
|
|
4
|
+
/**
|
|
5
|
+
* Raise an `E_UNALLOWED_EXPRESSION` exception. Filename and expression is
|
|
6
|
+
* required to point the error stack to the correct file
|
|
7
|
+
*/
|
|
8
|
+
export declare function unallowedExpression(
|
|
9
|
+
message: string,
|
|
10
|
+
filename: string,
|
|
11
|
+
loc: {
|
|
12
|
+
line: number
|
|
13
|
+
col: number
|
|
14
|
+
}
|
|
15
|
+
): void
|
|
16
|
+
/**
|
|
17
|
+
* Validates the expression type to be part of the allowed
|
|
18
|
+
* expressions only.
|
|
19
|
+
*
|
|
20
|
+
* The filename is required to report errors.
|
|
21
|
+
*
|
|
22
|
+
* ```js
|
|
23
|
+
* isNotSubsetOf(expression, ['Literal', 'Identifier'], () => {})
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function isSubsetOf(
|
|
27
|
+
expression: any,
|
|
28
|
+
expressions: ExpressionList,
|
|
29
|
+
errorCallback: () => void
|
|
30
|
+
): void
|
|
31
|
+
/**
|
|
32
|
+
* Validates the expression type not to be part of the disallowed
|
|
33
|
+
* expressions.
|
|
34
|
+
*
|
|
35
|
+
* The filename is required to report errors.
|
|
36
|
+
*
|
|
37
|
+
* ```js
|
|
38
|
+
* isNotSubsetOf(expression, 'SequenceExpression', () => {})
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare function isNotSubsetOf(
|
|
42
|
+
expression: any,
|
|
43
|
+
expressions: ExpressionList,
|
|
44
|
+
errorCallback: () => void
|
|
45
|
+
): void
|
|
46
|
+
/**
|
|
47
|
+
* Parses the jsArg by generating and transforming its AST
|
|
48
|
+
*/
|
|
49
|
+
export declare function parseJsArg(parser: Parser, token: TagToken): any
|
|
50
|
+
/**
|
|
51
|
+
* Each loop. A soft replacement for `lodash.each` that we were using earlier
|
|
52
|
+
*/
|
|
53
|
+
export declare function each(collection: any, iteratee: (value: any, key: any) => void): void
|
|
54
|
+
/**
|
|
55
|
+
* Async each loop. A soft replacement for `lodash.each` that we were
|
|
56
|
+
* using earlier with support for async await
|
|
57
|
+
*/
|
|
58
|
+
export declare function asyncEach(
|
|
59
|
+
collection: any,
|
|
60
|
+
iteratee: (value: any, key: any) => Promise<void>
|
|
61
|
+
): Promise<void>
|
|
62
|
+
/**
|
|
63
|
+
* This class generates a valid object as a string, which is written to the template
|
|
64
|
+
* output. The reason we need a string like object, since we don't want it's
|
|
65
|
+
* properties to be evaluated during the object creation, instead it must
|
|
66
|
+
* be evaluated when the compiled output is invoked.
|
|
67
|
+
*/
|
|
68
|
+
export declare class StringifiedObject {
|
|
69
|
+
#private
|
|
70
|
+
addSpread(key: string): void
|
|
71
|
+
/**
|
|
72
|
+
* Add key/value pair to the object.
|
|
73
|
+
*
|
|
74
|
+
* ```js
|
|
75
|
+
* stringifiedObject.add('username', `'virk'`)
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
add(key: any, value: any, isComputed?: boolean): void
|
|
79
|
+
/**
|
|
80
|
+
* Returns the object alike string back.
|
|
81
|
+
*
|
|
82
|
+
* ```js
|
|
83
|
+
* stringifiedObject.flush()
|
|
84
|
+
*
|
|
85
|
+
* // returns
|
|
86
|
+
* `{ username: 'virk' }`
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
flush(): string
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Stringify an object to props to HTML attributes
|
|
93
|
+
*/
|
|
94
|
+
export declare function stringifyAttributes(props: any, namespace?: string): string
|
|
95
|
+
export declare let nanoid: (length?: number) => string
|
|
96
|
+
export {}
|
package/src/utils.js
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
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.nanoid = exports.StringifiedObject = void 0;
|
|
15
|
+
exports.unallowedExpression = unallowedExpression;
|
|
16
|
+
exports.isSubsetOf = isSubsetOf;
|
|
17
|
+
exports.isNotSubsetOf = isNotSubsetOf;
|
|
18
|
+
exports.parseJsArg = parseJsArg;
|
|
19
|
+
exports.each = each;
|
|
20
|
+
exports.asyncEach = asyncEach;
|
|
21
|
+
exports.stringifyAttributes = stringifyAttributes;
|
|
22
|
+
const classnames_1 = __importDefault(require("classnames"));
|
|
23
|
+
const edge_error_1 = require("edge-error");
|
|
24
|
+
const property_information_1 = require("property-information");
|
|
25
|
+
/**
|
|
26
|
+
* Function to register custom properties
|
|
27
|
+
* with "property-information" package.
|
|
28
|
+
*/
|
|
29
|
+
function definePropertyInformation(property, value) {
|
|
30
|
+
property_information_1.html.normal[property] = property;
|
|
31
|
+
property_information_1.html.property[property] = {
|
|
32
|
+
attribute: property,
|
|
33
|
+
boolean: true,
|
|
34
|
+
property: property,
|
|
35
|
+
space: 'html',
|
|
36
|
+
booleanish: false,
|
|
37
|
+
commaOrSpaceSeparated: false,
|
|
38
|
+
commaSeparated: false,
|
|
39
|
+
spaceSeparated: false,
|
|
40
|
+
number: false,
|
|
41
|
+
overloadedBoolean: false,
|
|
42
|
+
defined: false,
|
|
43
|
+
mustUseProperty: false,
|
|
44
|
+
...value,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
definePropertyInformation('x-cloak');
|
|
48
|
+
definePropertyInformation('x-ignore');
|
|
49
|
+
definePropertyInformation('x-transition:enterstart', {
|
|
50
|
+
attribute: 'x-transition:enter-start',
|
|
51
|
+
property: 'x-transition:enterStart',
|
|
52
|
+
boolean: false,
|
|
53
|
+
spaceSeparated: true,
|
|
54
|
+
commaOrSpaceSeparated: true,
|
|
55
|
+
});
|
|
56
|
+
definePropertyInformation('x-transition:enterend', {
|
|
57
|
+
attribute: 'x-transition:enter-end',
|
|
58
|
+
property: 'x-transition:enterEnd',
|
|
59
|
+
boolean: false,
|
|
60
|
+
spaceSeparated: true,
|
|
61
|
+
commaOrSpaceSeparated: true,
|
|
62
|
+
});
|
|
63
|
+
definePropertyInformation('x-transition:leavestart', {
|
|
64
|
+
attribute: 'x-transition:leave-start',
|
|
65
|
+
property: 'x-transition:leaveStart',
|
|
66
|
+
boolean: false,
|
|
67
|
+
spaceSeparated: true,
|
|
68
|
+
commaOrSpaceSeparated: true,
|
|
69
|
+
});
|
|
70
|
+
definePropertyInformation('x-transition:leaveend', {
|
|
71
|
+
attribute: 'x-transition:leave-end',
|
|
72
|
+
property: 'x-transition:leaveEnd',
|
|
73
|
+
boolean: false,
|
|
74
|
+
spaceSeparated: true,
|
|
75
|
+
commaOrSpaceSeparated: true,
|
|
76
|
+
});
|
|
77
|
+
/**
|
|
78
|
+
* Alpine namespaces we handle with special
|
|
79
|
+
* rules when stringifying attributes
|
|
80
|
+
*/
|
|
81
|
+
const alpineNamespaces = {
|
|
82
|
+
x: 'x-',
|
|
83
|
+
xOn: 'x-on:',
|
|
84
|
+
xBind: 'x-bind:',
|
|
85
|
+
xTransition: 'x-transition:',
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Raise an `E_UNALLOWED_EXPRESSION` exception. Filename and expression is
|
|
89
|
+
* required to point the error stack to the correct file
|
|
90
|
+
*/
|
|
91
|
+
function unallowedExpression(message, filename, loc) {
|
|
92
|
+
throw new edge_error_1.EdgeError(message, 'E_UNALLOWED_EXPRESSION', {
|
|
93
|
+
line: loc.line,
|
|
94
|
+
col: loc.col,
|
|
95
|
+
filename: filename,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Validates the expression type to be part of the allowed
|
|
100
|
+
* expressions only.
|
|
101
|
+
*
|
|
102
|
+
* The filename is required to report errors.
|
|
103
|
+
*
|
|
104
|
+
* ```js
|
|
105
|
+
* isNotSubsetOf(expression, ['Literal', 'Identifier'], () => {})
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
function isSubsetOf(expression, expressions, errorCallback) {
|
|
109
|
+
if (!expressions.includes(expression.type)) {
|
|
110
|
+
errorCallback();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Validates the expression type not to be part of the disallowed
|
|
115
|
+
* expressions.
|
|
116
|
+
*
|
|
117
|
+
* The filename is required to report errors.
|
|
118
|
+
*
|
|
119
|
+
* ```js
|
|
120
|
+
* isNotSubsetOf(expression, 'SequenceExpression', () => {})
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
function isNotSubsetOf(expression, expressions, errorCallback) {
|
|
124
|
+
if (expressions.includes(expression.type)) {
|
|
125
|
+
errorCallback();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Parses the jsArg by generating and transforming its AST
|
|
130
|
+
*/
|
|
131
|
+
function parseJsArg(parser, token) {
|
|
132
|
+
return parser.utils.transformAst(parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename), token.filename, parser);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Each loop. A soft replacement for `lodash.each` that we were using earlier
|
|
136
|
+
*/
|
|
137
|
+
function each(collection, iteratee) {
|
|
138
|
+
if (Array.isArray(collection)) {
|
|
139
|
+
for (let [key, value] of collection.entries()) {
|
|
140
|
+
iteratee(value, key);
|
|
141
|
+
}
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (typeof collection === 'string') {
|
|
145
|
+
let index = 0;
|
|
146
|
+
for (let value of collection) {
|
|
147
|
+
iteratee(value, index++);
|
|
148
|
+
}
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (collection && typeof collection === 'object') {
|
|
152
|
+
for (let [key, value] of Object.entries(collection)) {
|
|
153
|
+
iteratee(value, key);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Async each loop. A soft replacement for `lodash.each` that we were
|
|
159
|
+
* using earlier with support for async await
|
|
160
|
+
*/
|
|
161
|
+
async function asyncEach(collection, iteratee) {
|
|
162
|
+
if (Array.isArray(collection)) {
|
|
163
|
+
for (let [key, value] of collection.entries()) {
|
|
164
|
+
await iteratee(value, key);
|
|
165
|
+
}
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (typeof collection === 'string') {
|
|
169
|
+
let index = 0;
|
|
170
|
+
for (let value of collection) {
|
|
171
|
+
await iteratee(value, index++);
|
|
172
|
+
}
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (collection && typeof collection === 'object') {
|
|
176
|
+
for (let [key, value] of Object.entries(collection)) {
|
|
177
|
+
await iteratee(value, key);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* This class generates a valid object as a string, which is written to the template
|
|
183
|
+
* output. The reason we need a string like object, since we don't want it's
|
|
184
|
+
* properties to be evaluated during the object creation, instead it must
|
|
185
|
+
* be evaluated when the compiled output is invoked.
|
|
186
|
+
*/
|
|
187
|
+
class StringifiedObject {
|
|
188
|
+
#obj = '';
|
|
189
|
+
addSpread(key) {
|
|
190
|
+
this.#obj += this.#obj.length ? `, ${key}` : `${key}`;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Add key/value pair to the object.
|
|
194
|
+
*
|
|
195
|
+
* ```js
|
|
196
|
+
* stringifiedObject.add('username', `'virk'`)
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
add(key, value, isComputed = false) {
|
|
200
|
+
key = isComputed ? `[${key}]` : key;
|
|
201
|
+
this.#obj += this.#obj.length ? `, ${key}: ${value}` : `${key}: ${value}`;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Returns the object alike string back.
|
|
205
|
+
*
|
|
206
|
+
* ```js
|
|
207
|
+
* stringifiedObject.flush()
|
|
208
|
+
*
|
|
209
|
+
* // returns
|
|
210
|
+
* `{ username: 'virk' }`
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
213
|
+
flush() {
|
|
214
|
+
const obj = `{ ${this.#obj} }`;
|
|
215
|
+
this.#obj = '';
|
|
216
|
+
return obj;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
exports.StringifiedObject = StringifiedObject;
|
|
220
|
+
/**
|
|
221
|
+
* Stringify an object to props to HTML attributes
|
|
222
|
+
*/
|
|
223
|
+
function stringifyAttributes(props, namespace) {
|
|
224
|
+
const attributes = Object.keys(props);
|
|
225
|
+
if (attributes.length === 0) {
|
|
226
|
+
return '';
|
|
227
|
+
}
|
|
228
|
+
return attributes
|
|
229
|
+
.reduce((result, key) => {
|
|
230
|
+
let value = props[key];
|
|
231
|
+
key = namespace ? `${namespace}${key}` : key;
|
|
232
|
+
/**
|
|
233
|
+
* No value defined, remove attribute
|
|
234
|
+
*/
|
|
235
|
+
if (!value) {
|
|
236
|
+
return result;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Handle alpine properties separately
|
|
240
|
+
*/
|
|
241
|
+
if (alpineNamespaces[key] && typeof value === 'object') {
|
|
242
|
+
result = result.concat(stringifyAttributes(value, alpineNamespaces[key]));
|
|
243
|
+
return result;
|
|
244
|
+
}
|
|
245
|
+
const propInfo = (0, property_information_1.find)(property_information_1.html, key);
|
|
246
|
+
/**
|
|
247
|
+
* Ignore unknown attributes
|
|
248
|
+
*/
|
|
249
|
+
if (!propInfo) {
|
|
250
|
+
return result;
|
|
251
|
+
}
|
|
252
|
+
const attribute = propInfo.attribute;
|
|
253
|
+
/**
|
|
254
|
+
* Boolean properties
|
|
255
|
+
*/
|
|
256
|
+
if (value === true) {
|
|
257
|
+
result.push(attribute);
|
|
258
|
+
return result;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Encoding rules for certain properties.
|
|
262
|
+
*
|
|
263
|
+
* - Class values can be objects with conditionals
|
|
264
|
+
* - Non-booleanish and numeric properties will be html escaped
|
|
265
|
+
* - Arrays will be concatenated into a string list and html escaped
|
|
266
|
+
*/
|
|
267
|
+
if (key === 'class') {
|
|
268
|
+
value = `"${(0, classnames_1.default)(value)}"`;
|
|
269
|
+
}
|
|
270
|
+
else if (Array.isArray(value)) {
|
|
271
|
+
value = `"${value.join(propInfo.commaSeparated ? ',' : ' ')}"`;
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
value = `"${String(value)}"`;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Push attribute value string
|
|
278
|
+
*/
|
|
279
|
+
result.push(`${attribute}=${value}`);
|
|
280
|
+
return result;
|
|
281
|
+
}, [])
|
|
282
|
+
.join(' ');
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Copy-pasted from
|
|
286
|
+
* https://github.com/ai/nanoid/blob/main/nanoid.js
|
|
287
|
+
*/
|
|
288
|
+
const seed = 'useandom26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict';
|
|
289
|
+
let nanoid = (length = 15) => {
|
|
290
|
+
let output = '';
|
|
291
|
+
const random = crypto.getRandomValues(new Uint8Array(length));
|
|
292
|
+
for (let n = 0; n < length; n++) {
|
|
293
|
+
output += seed[63 & random[n]];
|
|
294
|
+
}
|
|
295
|
+
return output;
|
|
296
|
+
};
|
|
297
|
+
exports.nanoid = nanoid;
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020", // modern JS target
|
|
4
|
+
"module": "CommonJS", // Node.js module system
|
|
5
|
+
"declaration": true, // generate .d.ts files
|
|
6
|
+
"outDir": ".", // compiled JS output
|
|
7
|
+
"rootDir": "./src", // source folder
|
|
8
|
+
"strict": true, // enable strict type checks
|
|
9
|
+
"esModuleInterop": true, // allow default imports from CJS modules
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"sourceMap": false // set true if debugging is needed
|
|
13
|
+
},
|
|
14
|
+
"include": ["src/**/*.ts", "index.ts"],
|
|
15
|
+
"exclude": ["node_modules", "tests"]
|
|
16
|
+
}
|