@htmlplus/element 2.1.4 → 2.1.6
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/client/utils/event.js +3 -1
- package/client/utils/merge.js +3 -1
- package/client/utils/request.js +40 -40
- package/client/utils/task.d.ts +1 -1
- package/client/utils/task.js +8 -8
- package/package.json +3 -4
- package/transformer/plugins/customElement.js +9 -3
- package/transformer/plugins/document.js +44 -72
- package/transformer/plugins/extract.js +12 -23
- package/transformer/plugins/parse.js +1 -2
- package/transformer/plugins/read.js +1 -2
- package/transformer/plugins/visualStudioCode.js +9 -12
- package/transformer/plugins/webTypes.js +18 -37
- package/transformer/transformer.types.d.ts +3 -3
- package/transformer/utils/extractFromComment.d.ts +4 -0
- package/transformer/utils/extractFromComment.js +48 -0
- package/transformer/utils/getType.js +1 -1
- package/transformer/utils/index.d.ts +1 -1
- package/transformer/utils/index.js +1 -1
- package/transformer/utils/tags.d.ts +0 -13
- package/transformer/utils/tags.js +0 -44
package/client/utils/event.js
CHANGED
|
@@ -5,7 +5,9 @@ const outsides = [];
|
|
|
5
5
|
export const off = (target, type, handler, options) => {
|
|
6
6
|
if (type != 'outside')
|
|
7
7
|
return target.removeEventListener(type, handler, options);
|
|
8
|
-
const index = outsides.findIndex((outside) =>
|
|
8
|
+
const index = outsides.findIndex((outside) => {
|
|
9
|
+
return outside.target == target && outside.handler == handler && outside.options == options;
|
|
10
|
+
});
|
|
9
11
|
const outside = outsides[index];
|
|
10
12
|
if (!outside)
|
|
11
13
|
return;
|
package/client/utils/merge.js
CHANGED
|
@@ -8,7 +8,9 @@ export const merge = (target, ...sources) => {
|
|
|
8
8
|
continue;
|
|
9
9
|
}
|
|
10
10
|
for (const key of Object.keys(source)) {
|
|
11
|
-
if (target[key] instanceof Object &&
|
|
11
|
+
if (target[key] instanceof Object &&
|
|
12
|
+
source[key] instanceof Object &&
|
|
13
|
+
target[key] !== source[key]) {
|
|
12
14
|
target[key] = merge(target[key], source[key]);
|
|
13
15
|
}
|
|
14
16
|
else {
|
package/client/utils/request.js
CHANGED
|
@@ -15,52 +15,52 @@ export const request = (target, name, previous, callback) => {
|
|
|
15
15
|
var _a, _b;
|
|
16
16
|
// Creates/Gets a stacks.
|
|
17
17
|
const stacks = (target[_a = CONSTANTS.API_STACKS] || (target[_a] = new Map()));
|
|
18
|
-
// Creates/Updates a stack
|
|
18
|
+
// Creates/Updates a stack.
|
|
19
19
|
const stack = stacks.get(name) || { callbacks: [], previous };
|
|
20
20
|
// Adds the callback to the stack, if exists.
|
|
21
21
|
callback && stack.callbacks.push(callback);
|
|
22
22
|
// Stores the stack.
|
|
23
23
|
stacks.set(name, stack);
|
|
24
|
-
//
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
callback(callbacks.length - 1 != index);
|
|
54
|
-
});
|
|
24
|
+
// Defines a handler.
|
|
25
|
+
const handler = () => {
|
|
26
|
+
// Skips the rendering phase if DOM isn't ready.
|
|
27
|
+
if (!target[CONSTANTS.API_CONNECTED])
|
|
28
|
+
return;
|
|
29
|
+
// Calculates the states to pass into lifecycles' callbacks.
|
|
30
|
+
const states = new Map(Array.from(stacks)
|
|
31
|
+
.filter((stack) => stack[0])
|
|
32
|
+
.map((stack) => [stack[0], stack[1].previous]));
|
|
33
|
+
// Calls the lifecycle's callback before the rendering phase.
|
|
34
|
+
call(target, CONSTANTS.LIFECYCLE_UPDATE, states);
|
|
35
|
+
// Calculates the template.
|
|
36
|
+
const template = () => {
|
|
37
|
+
// Calculates the markup.
|
|
38
|
+
const markup = call(target, CONSTANTS.METHOD_RENDER);
|
|
39
|
+
// Calculates the styles.
|
|
40
|
+
const styles = getStyles(target);
|
|
41
|
+
// Returns the markup if styles don't exist.
|
|
42
|
+
if (!styles)
|
|
43
|
+
return markup;
|
|
44
|
+
// Returns the markup and styles together.
|
|
45
|
+
return html `<style>${styles}</style>${markup}`;
|
|
46
|
+
};
|
|
47
|
+
// Renders template to the DOM.
|
|
48
|
+
render(shadowRoot(target), template);
|
|
49
|
+
// Invokes requests' callback.
|
|
50
|
+
stacks.forEach((state) => {
|
|
51
|
+
state.callbacks.forEach((callback, index, callbacks) => {
|
|
52
|
+
callback(callbacks.length - 1 != index);
|
|
55
53
|
});
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
54
|
+
});
|
|
55
|
+
// Calls the lifecycle's callback after the rendering phase.
|
|
56
|
+
call(target, CONSTANTS.LIFECYCLE_UPDATED, states);
|
|
57
|
+
// Clears stacks.
|
|
58
|
+
stacks.clear();
|
|
59
|
+
// TODO: releated to the @Watch decorator.
|
|
60
|
+
target[CONSTANTS.API_RENDER_COMPLETED] = true;
|
|
61
|
+
};
|
|
62
|
+
// Creates/Gets a micro task function.
|
|
63
|
+
target[_b = CONSTANTS.API_REQUEST] || (target[_b] = task({ handler }));
|
|
64
64
|
// Calls the micro task.
|
|
65
65
|
call(target, CONSTANTS.API_REQUEST);
|
|
66
66
|
};
|
package/client/utils/task.d.ts
CHANGED
package/client/utils/task.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
export const task = (options) => {
|
|
2
|
-
let
|
|
2
|
+
let running, promise;
|
|
3
3
|
const run = () => {
|
|
4
4
|
if (options.canStart && !options.canStart())
|
|
5
5
|
return Promise.resolve(false);
|
|
6
|
-
if (!
|
|
6
|
+
if (!running)
|
|
7
7
|
promise = enqueue();
|
|
8
8
|
return promise;
|
|
9
9
|
};
|
|
10
10
|
const enqueue = async () => {
|
|
11
|
-
|
|
11
|
+
running = true;
|
|
12
12
|
try {
|
|
13
13
|
await promise;
|
|
14
14
|
}
|
|
@@ -16,17 +16,17 @@ export const task = (options) => {
|
|
|
16
16
|
Promise.reject(error);
|
|
17
17
|
}
|
|
18
18
|
// TODO: maybe is optional
|
|
19
|
-
if (!
|
|
19
|
+
if (!running)
|
|
20
20
|
return promise;
|
|
21
21
|
try {
|
|
22
22
|
if (options.canRun && !options.canRun())
|
|
23
|
-
return (
|
|
24
|
-
options.
|
|
25
|
-
|
|
23
|
+
return (running = false);
|
|
24
|
+
options.handler();
|
|
25
|
+
running = false;
|
|
26
26
|
return true;
|
|
27
27
|
}
|
|
28
28
|
catch (error) {
|
|
29
|
-
|
|
29
|
+
running = false;
|
|
30
30
|
throw error;
|
|
31
31
|
}
|
|
32
32
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@htmlplus/element",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.6",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"author": "Masood Abdolian <m.abdolian@gmail.com>",
|
|
@@ -37,11 +37,10 @@
|
|
|
37
37
|
"@babel/template": "^7.23.9",
|
|
38
38
|
"@babel/traverse": "^7.23.9",
|
|
39
39
|
"@babel/types": "^7.23.9",
|
|
40
|
-
"@types/node": "^20.11.
|
|
40
|
+
"@types/node": "^20.11.20",
|
|
41
41
|
"change-case": "^5.4.3",
|
|
42
42
|
"fs-extra": "^11.2.0",
|
|
43
43
|
"glob": "^10.3.10",
|
|
44
|
-
"handlebars": "^4.7.8",
|
|
45
44
|
"ora": "^8.0.1",
|
|
46
45
|
"typescript": "^4.9.5"
|
|
47
46
|
},
|
|
@@ -58,6 +57,6 @@
|
|
|
58
57
|
"rimraf": "^5.0.5",
|
|
59
58
|
"semantic-release": "^23.0.2",
|
|
60
59
|
"tsx": "^4.7.1",
|
|
61
|
-
"vite": "^5.1.
|
|
60
|
+
"vite": "^5.1.4"
|
|
62
61
|
}
|
|
63
62
|
}
|
|
@@ -48,7 +48,10 @@ export const customElement = (options) => {
|
|
|
48
48
|
const { name, value } = path.node;
|
|
49
49
|
if (name.name != 'className')
|
|
50
50
|
return;
|
|
51
|
-
const hasClass = path.parentPath.node.attributes.some((attribute) => {
|
|
51
|
+
const hasClass = path.parentPath.node.attributes.some((attribute) => {
|
|
52
|
+
var _a;
|
|
53
|
+
return ((_a = attribute.name) === null || _a === void 0 ? void 0 : _a.name) == 'class';
|
|
54
|
+
});
|
|
52
55
|
if (hasClass)
|
|
53
56
|
return path.remove();
|
|
54
57
|
path.replaceWith(t.jsxAttribute(t.jsxIdentifier('class'), value));
|
|
@@ -108,7 +111,9 @@ export const customElement = (options) => {
|
|
|
108
111
|
const children = node.children.map(render).flat();
|
|
109
112
|
const parts = [];
|
|
110
113
|
parts.push('<', name);
|
|
111
|
-
const hasSpreadAttribute = attributes.some((attribute) =>
|
|
114
|
+
const hasSpreadAttribute = attributes.some((attribute) => {
|
|
115
|
+
return attribute.type == 'JSXSpreadAttribute';
|
|
116
|
+
});
|
|
112
117
|
if (hasSpreadAttribute) {
|
|
113
118
|
parts.push(' ', TODO(t.identifier('TODO'), attributes));
|
|
114
119
|
}
|
|
@@ -251,7 +256,8 @@ export const customElement = (options) => {
|
|
|
251
256
|
break;
|
|
252
257
|
}
|
|
253
258
|
// TODO
|
|
254
|
-
if ((input === null || input === void 0 ? void 0 : input.type) == 'TSParenthesizedType' &&
|
|
259
|
+
if ((input === null || input === void 0 ? void 0 : input.type) == 'TSParenthesizedType' &&
|
|
260
|
+
((_a = input === null || input === void 0 ? void 0 : input.typeAnnotation) === null || _a === void 0 ? void 0 : _a.type) == 'TSIntersectionType') {
|
|
255
261
|
let types = input.types || input.typeAnnotation.types;
|
|
256
262
|
if (types.length != 2)
|
|
257
263
|
return;
|
|
@@ -3,7 +3,7 @@ import fs from 'fs-extra';
|
|
|
3
3
|
import { glob } from 'glob';
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import * as CONSTANTS from '../../constants/index.js';
|
|
6
|
-
import {
|
|
6
|
+
import { extractFromComment, getInitializer, getTypeReference, print } from '../utils/index.js';
|
|
7
7
|
export const DOCUMENT_OPTIONS = {
|
|
8
8
|
destination: path.join('dist', 'document.json')
|
|
9
9
|
};
|
|
@@ -11,15 +11,13 @@ export const document = (options) => {
|
|
|
11
11
|
const name = 'document';
|
|
12
12
|
options = Object.assign({}, DOCUMENT_OPTIONS, options);
|
|
13
13
|
const finish = (global) => {
|
|
14
|
-
var _a, _b
|
|
14
|
+
var _a, _b;
|
|
15
15
|
const json = {
|
|
16
16
|
elements: []
|
|
17
17
|
};
|
|
18
18
|
for (const context of global.contexts) {
|
|
19
|
-
const deprecated = hasTag(context.class, 'deprecated');
|
|
20
|
-
const description = (_a = getTags(context.class).find((tag) => !tag.key)) === null || _a === void 0 ? void 0 : _a.value;
|
|
21
19
|
const events = context.classEvents.map((event) => {
|
|
22
|
-
var _a, _b
|
|
20
|
+
var _a, _b;
|
|
23
21
|
const cancelable = (() => {
|
|
24
22
|
if (!event.decorators)
|
|
25
23
|
return false;
|
|
@@ -41,56 +39,41 @@ export const document = (options) => {
|
|
|
41
39
|
catch (_a) { }
|
|
42
40
|
return false;
|
|
43
41
|
})();
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
const detail = print((_b = event.typeAnnotation) === null || _b === void 0 ? void 0 : _b['typeAnnotation']);
|
|
47
|
-
const detailReference = getTypeReference(context.fileAST, (_c = event.typeAnnotation) === null || _c === void 0 ? void 0 : _c['typeAnnotation'].typeParameters.params[0]);
|
|
48
|
-
const experimental = hasTag(event, 'experimental');
|
|
49
|
-
const model = hasTag(event, 'model');
|
|
42
|
+
const detail = print((_a = event.typeAnnotation) === null || _a === void 0 ? void 0 : _a['typeAnnotation']);
|
|
43
|
+
const detailReference = getTypeReference(context.fileAST, (_b = event.typeAnnotation) === null || _b === void 0 ? void 0 : _b['typeAnnotation'].typeParameters.params[0]);
|
|
50
44
|
const name = event.key['name'];
|
|
51
|
-
|
|
52
|
-
return {
|
|
45
|
+
return Object.assign({
|
|
53
46
|
cancelable,
|
|
54
|
-
deprecated,
|
|
55
|
-
description,
|
|
56
47
|
detail,
|
|
57
48
|
detailReference,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
name,
|
|
61
|
-
tags
|
|
62
|
-
};
|
|
49
|
+
name
|
|
50
|
+
}, extractFromComment(event));
|
|
63
51
|
});
|
|
64
|
-
const experimental = hasTag(context.class, 'experimental');
|
|
65
|
-
const group = (_b = getTag(context.class, 'group')) === null || _b === void 0 ? void 0 : _b.value;
|
|
66
52
|
const lastModified = glob
|
|
67
53
|
.sync('**/*.*', { cwd: context.directoryPath })
|
|
68
54
|
.map((file) => fs.statSync(path.join(context.directoryPath, file)).mtime)
|
|
69
55
|
.sort((a, b) => (a > b ? 1 : -1))
|
|
70
56
|
.pop();
|
|
71
57
|
const methods = context.classMethods.map((method) => {
|
|
72
|
-
var _a, _b
|
|
58
|
+
var _a, _b;
|
|
73
59
|
const async = method.async;
|
|
74
|
-
const description = (_a = getTags(method).find((tag) => !tag.key)) === null || _a === void 0 ? void 0 : _a.value;
|
|
75
|
-
const deprecated = hasTag(method, 'deprecated');
|
|
76
|
-
const experimental = hasTag(method, 'experimental');
|
|
77
60
|
const name = method.key['name'];
|
|
61
|
+
const comments = extractFromComment(method);
|
|
78
62
|
// TODO
|
|
79
63
|
const parameters = method.params.map((param) => {
|
|
80
|
-
var _a, _b, _c;
|
|
64
|
+
var _a, _b, _c, _d;
|
|
81
65
|
return ({
|
|
82
|
-
description: (_a =
|
|
83
|
-
.map((tag) => parseTag(tag, ' '))
|
|
84
|
-
.find((tag) => tag.name == param['name'])) === null || _a === void 0 ? void 0 : _a.description,
|
|
66
|
+
description: (_b = (_a = comments.params) === null || _a === void 0 ? void 0 : _a.find((item) => item.name == param['name'])) === null || _b === void 0 ? void 0 : _b.description,
|
|
85
67
|
required: !param['optional'],
|
|
86
68
|
name: param['name'],
|
|
87
|
-
type: print((
|
|
88
|
-
typeReference: getTypeReference(context.fileAST, (
|
|
69
|
+
type: print((_c = param === null || param === void 0 ? void 0 : param['typeAnnotation']) === null || _c === void 0 ? void 0 : _c.typeAnnotation) || undefined,
|
|
70
|
+
typeReference: getTypeReference(context.fileAST, (_d = param === null || param === void 0 ? void 0 : param['typeAnnotation']) === null || _d === void 0 ? void 0 : _d.typeAnnotation)
|
|
89
71
|
});
|
|
90
72
|
});
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const
|
|
73
|
+
// TODO
|
|
74
|
+
delete comments.params;
|
|
75
|
+
const returns = print((_a = method.returnType) === null || _a === void 0 ? void 0 : _a['typeAnnotation']) || 'void';
|
|
76
|
+
const returnsReference = getTypeReference(context.fileAST, (_b = method.returnType) === null || _b === void 0 ? void 0 : _b['typeAnnotation']);
|
|
94
77
|
const signature = [
|
|
95
78
|
method.key['name'],
|
|
96
79
|
'(',
|
|
@@ -109,29 +92,34 @@ export const document = (options) => {
|
|
|
109
92
|
' => ',
|
|
110
93
|
returns
|
|
111
94
|
].join('');
|
|
112
|
-
return {
|
|
95
|
+
return Object.assign({
|
|
113
96
|
async,
|
|
114
|
-
description,
|
|
115
|
-
deprecated,
|
|
116
|
-
experimental,
|
|
117
97
|
name,
|
|
118
98
|
parameters,
|
|
119
99
|
returns,
|
|
120
100
|
returnsReference,
|
|
121
|
-
tags,
|
|
122
101
|
signature
|
|
123
|
-
}
|
|
102
|
+
}, comments,
|
|
103
|
+
// TODO
|
|
104
|
+
{
|
|
105
|
+
returns
|
|
106
|
+
},
|
|
107
|
+
// TODO
|
|
108
|
+
returns != 'void' &&
|
|
109
|
+
comments.returns && {
|
|
110
|
+
tags: [
|
|
111
|
+
{
|
|
112
|
+
key: 'returns',
|
|
113
|
+
value: `${comments.returns}`
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
});
|
|
124
117
|
});
|
|
125
|
-
const parts = getTags(context.class, 'part').map((tag) => parseTag(tag));
|
|
126
118
|
const properties = context.classProperties.map((property) => {
|
|
127
|
-
var _a, _b
|
|
119
|
+
var _a, _b;
|
|
128
120
|
const attribute = kebabCase(property.key['name']);
|
|
129
|
-
const deprecated = hasTag(property, 'deprecated');
|
|
130
|
-
const description = (_a = getTags(property).find((tag) => !tag.key)) === null || _a === void 0 ? void 0 : _a.value;
|
|
131
|
-
const experimental = hasTag(property, 'experimental');
|
|
132
121
|
// TODO
|
|
133
122
|
const initializer = getInitializer(property.value);
|
|
134
|
-
const model = hasTag(property, 'model');
|
|
135
123
|
const name = property.key['name'];
|
|
136
124
|
// TODO
|
|
137
125
|
const reflects = (() => {
|
|
@@ -156,31 +144,23 @@ export const document = (options) => {
|
|
|
156
144
|
return false;
|
|
157
145
|
})();
|
|
158
146
|
const required = !property.optional;
|
|
159
|
-
const
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
return {
|
|
147
|
+
const type = print((_a = property.typeAnnotation) === null || _a === void 0 ? void 0 : _a['typeAnnotation']);
|
|
148
|
+
const typeReference = getTypeReference(context.fileAST, (_b = property.typeAnnotation) === null || _b === void 0 ? void 0 : _b['typeAnnotation']);
|
|
149
|
+
return Object.assign({
|
|
163
150
|
attribute,
|
|
164
|
-
deprecated,
|
|
165
|
-
description,
|
|
166
|
-
experimental,
|
|
167
151
|
initializer,
|
|
168
|
-
model,
|
|
169
152
|
name,
|
|
170
153
|
reflects,
|
|
171
154
|
required,
|
|
172
|
-
tags,
|
|
173
155
|
type,
|
|
174
156
|
typeReference
|
|
175
|
-
};
|
|
157
|
+
}, extractFromComment(property));
|
|
176
158
|
});
|
|
177
|
-
const slots = getTags(context.class, 'slot').map((tag) => parseTag(tag));
|
|
178
159
|
// TODO
|
|
179
160
|
const styles = (() => {
|
|
180
|
-
if (!context.
|
|
161
|
+
if (!context.styleContent)
|
|
181
162
|
return [];
|
|
182
|
-
return
|
|
183
|
-
.readFileSync(context.stylePath, 'utf8')
|
|
163
|
+
return context.styleContent
|
|
184
164
|
.split(CONSTANTS.DECORATOR_CSS_VARIABLE)
|
|
185
165
|
.slice(1)
|
|
186
166
|
.map((section) => {
|
|
@@ -195,26 +175,18 @@ export const document = (options) => {
|
|
|
195
175
|
};
|
|
196
176
|
});
|
|
197
177
|
})();
|
|
198
|
-
const tags = getTags(context.class).filter((tag) => !['part', 'slot'].includes(tag.key));
|
|
199
178
|
const title = capitalCase(context.elementKey);
|
|
200
|
-
const element = {
|
|
179
|
+
const element = Object.assign({
|
|
201
180
|
events,
|
|
202
|
-
group,
|
|
203
|
-
deprecated,
|
|
204
|
-
description,
|
|
205
|
-
experimental,
|
|
206
181
|
key: context.elementKey,
|
|
207
182
|
lastModified,
|
|
208
183
|
methods,
|
|
209
|
-
parts,
|
|
210
184
|
properties,
|
|
211
185
|
readmeContent: context.readmeContent,
|
|
212
|
-
slots,
|
|
213
186
|
styles,
|
|
214
|
-
tags,
|
|
215
187
|
title
|
|
216
|
-
};
|
|
217
|
-
const transformed = ((
|
|
188
|
+
}, extractFromComment(context.class));
|
|
189
|
+
const transformed = ((_b = (_a = options).transformer) === null || _b === void 0 ? void 0 : _b.call(_a, context, element)) || element;
|
|
218
190
|
json.elements.push(transformed);
|
|
219
191
|
}
|
|
220
192
|
json.elements = json.elements.sort((a, b) => (a.title > b.title ? 1 : -1));
|
|
@@ -1,34 +1,23 @@
|
|
|
1
1
|
import t from '@babel/types';
|
|
2
2
|
import { kebabCase } from 'change-case';
|
|
3
3
|
import * as CONSTANTS from '../../constants/index.js';
|
|
4
|
-
import { hasDecorator
|
|
4
|
+
import { hasDecorator } from '../utils/index.js';
|
|
5
5
|
export const extract = () => {
|
|
6
6
|
const name = 'extract';
|
|
7
7
|
const run = (context) => {
|
|
8
|
-
var _a, _b;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
exit(path) {
|
|
12
|
-
var _a, _b, _c;
|
|
13
|
-
context.class = path.node;
|
|
14
|
-
context.classMembers = ((_b = (_a = context.class) === null || _a === void 0 ? void 0 : _a.body) === null || _b === void 0 ? void 0 : _b.body) || [];
|
|
15
|
-
// TODO
|
|
16
|
-
if (path.parentPath.isExportNamedDeclaration() && !((_c = context.class) === null || _c === void 0 ? void 0 : _c.leadingComments)) {
|
|
17
|
-
context.class['_leadingComments'] = t.cloneNode(path.parentPath.node, true).leadingComments || [];
|
|
18
|
-
}
|
|
19
|
-
path.skip();
|
|
20
|
-
}
|
|
21
|
-
}
|
|
8
|
+
var _a, _b, _c, _d, _e;
|
|
9
|
+
const { declaration, leadingComments } = (_a = context.fileAST) === null || _a === void 0 ? void 0 : _a.program.body.find((child) => {
|
|
10
|
+
return t.isExportNamedDeclaration(child);
|
|
22
11
|
});
|
|
23
|
-
context.
|
|
12
|
+
context.class = declaration;
|
|
13
|
+
context.class.leadingComments = leadingComments; // TODO
|
|
14
|
+
context.classMembers = ((_c = (_b = context.class) === null || _b === void 0 ? void 0 : _b.body) === null || _c === void 0 ? void 0 : _c.body) || [];
|
|
15
|
+
context.className = (_e = (_d = context.class) === null || _d === void 0 ? void 0 : _d.id) === null || _e === void 0 ? void 0 : _e.name;
|
|
24
16
|
context.elementKey = kebabCase(context.className || '');
|
|
25
|
-
context.classEvents =
|
|
26
|
-
context.classMethods =
|
|
27
|
-
context.classProperties =
|
|
28
|
-
context.classStates =
|
|
29
|
-
context.classHasMount = (context.classMembers || []).some((member) => member['key'].name == CONSTANTS.LIFECYCLE_CONNECTED);
|
|
30
|
-
context.classHasUnmount = (context.classMembers || []).some((member) => member['key'].name == CONSTANTS.LIFECYCLE_DISCONNECTED);
|
|
31
|
-
context.classRender = (context.classMembers || []).find((member) => member['key'].name == CONSTANTS.METHOD_RENDER);
|
|
17
|
+
context.classEvents = context.classMembers.filter((member) => hasDecorator(member, CONSTANTS.DECORATOR_EVENT));
|
|
18
|
+
context.classMethods = context.classMembers.filter((member) => hasDecorator(member, CONSTANTS.DECORATOR_METHOD));
|
|
19
|
+
context.classProperties = context.classMembers.filter((member) => hasDecorator(member, CONSTANTS.DECORATOR_PROPERTY));
|
|
20
|
+
context.classStates = context.classMembers.filter((member) => hasDecorator(member, CONSTANTS.DECORATOR_STATE));
|
|
32
21
|
};
|
|
33
22
|
return { name, run };
|
|
34
23
|
};
|
|
@@ -7,8 +7,7 @@ export const parse = (options) => {
|
|
|
7
7
|
const name = 'parse';
|
|
8
8
|
options = Object.assign({}, PARSE_OPTIONS, options);
|
|
9
9
|
const run = (context) => {
|
|
10
|
-
|
|
11
|
-
(_a = context.fileAST) !== null && _a !== void 0 ? _a : (context.fileAST = parser(context.fileContent, options));
|
|
10
|
+
context.fileAST = parser(context.fileContent, options);
|
|
12
11
|
};
|
|
13
12
|
return { name, run };
|
|
14
13
|
};
|
|
@@ -7,10 +7,9 @@ export const read = (options) => {
|
|
|
7
7
|
const name = 'read';
|
|
8
8
|
options = Object.assign({}, READ_OPTIONS, options);
|
|
9
9
|
const run = (context) => {
|
|
10
|
-
var _a;
|
|
11
10
|
if (!context.filePath)
|
|
12
11
|
return;
|
|
13
|
-
|
|
12
|
+
context.fileContent = fs.readFileSync(context.filePath, options);
|
|
14
13
|
context.fileExtension = path.extname(context.filePath);
|
|
15
14
|
context.fileName = path.basename(context.filePath, context.fileExtension);
|
|
16
15
|
context.directoryPath = path.dirname(context.filePath);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { kebabCase } from 'change-case';
|
|
2
2
|
import fs from 'fs-extra';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
import {
|
|
4
|
+
import { extractFromComment, getType, print } from '../utils/index.js';
|
|
5
5
|
export const VISUAL_STUDIO_CODE_OPTIONS = {
|
|
6
6
|
destination: path.join('dist', 'visual-studio-code.json')
|
|
7
7
|
};
|
|
@@ -9,7 +9,7 @@ export const visualStudioCode = (options) => {
|
|
|
9
9
|
const name = 'visualStudioCode';
|
|
10
10
|
options = Object.assign({}, VISUAL_STUDIO_CODE_OPTIONS, options);
|
|
11
11
|
const finish = (global) => {
|
|
12
|
-
var _a, _b, _c, _d, _e
|
|
12
|
+
var _a, _b, _c, _d, _e;
|
|
13
13
|
const contexts = global.contexts.sort((a, b) => {
|
|
14
14
|
return a.elementKey.toUpperCase() > b.elementKey.toUpperCase() ? +1 : -1;
|
|
15
15
|
});
|
|
@@ -19,25 +19,22 @@ export const visualStudioCode = (options) => {
|
|
|
19
19
|
tags: []
|
|
20
20
|
};
|
|
21
21
|
for (const context of contexts) {
|
|
22
|
-
const
|
|
23
|
-
const tag = {
|
|
22
|
+
const tag = Object.assign({
|
|
24
23
|
name: context.elementKey,
|
|
25
|
-
description: description,
|
|
26
24
|
attributes: [],
|
|
27
25
|
references: [
|
|
28
26
|
{
|
|
29
27
|
name: 'Source code',
|
|
30
|
-
url: (
|
|
28
|
+
url: (_b = (_a = options).reference) === null || _b === void 0 ? void 0 : _b.call(_a, context)
|
|
31
29
|
}
|
|
32
30
|
]
|
|
33
|
-
};
|
|
31
|
+
}, extractFromComment(context.class, ['description']));
|
|
34
32
|
for (const property of context.classProperties || []) {
|
|
35
|
-
const attribute = {
|
|
33
|
+
const attribute = Object.assign({
|
|
36
34
|
name: kebabCase(property.key['name']),
|
|
37
|
-
description: (_d = getTags(property).find((tag) => !tag.key)) === null || _d === void 0 ? void 0 : _d.value,
|
|
38
35
|
values: []
|
|
39
|
-
};
|
|
40
|
-
const type = print(getType(context.directoryPath, context.fileAST, (
|
|
36
|
+
}, extractFromComment(property, ['description']));
|
|
37
|
+
const type = print(getType(context.directoryPath, context.fileAST, (_c = property.typeAnnotation) === null || _c === void 0 ? void 0 : _c['typeAnnotation']));
|
|
41
38
|
const sections = type.split('|');
|
|
42
39
|
for (const section of sections) {
|
|
43
40
|
const trimmed = section.trim();
|
|
@@ -66,7 +63,7 @@ export const visualStudioCode = (options) => {
|
|
|
66
63
|
}
|
|
67
64
|
tag.attributes.push(attribute);
|
|
68
65
|
}
|
|
69
|
-
const transformed = ((
|
|
66
|
+
const transformed = ((_e = (_d = options).transformer) === null || _e === void 0 ? void 0 : _e.call(_d, context, tag)) || tag;
|
|
70
67
|
json.tags.push(transformed);
|
|
71
68
|
}
|
|
72
69
|
const dirname = path.dirname(options.destination);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { kebabCase } from 'change-case';
|
|
2
2
|
import fs from 'fs-extra';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
import {
|
|
4
|
+
import { extractFromComment, getInitializer, getType, print } from '../utils/index.js';
|
|
5
5
|
export const WEB_TYPES_OPTIONS = {
|
|
6
6
|
destination: path.join('dist', 'web-types.json'),
|
|
7
7
|
packageName: '',
|
|
@@ -11,7 +11,7 @@ export const webTypes = (options) => {
|
|
|
11
11
|
const name = 'webTypes';
|
|
12
12
|
options = Object.assign({}, WEB_TYPES_OPTIONS, options);
|
|
13
13
|
const finish = (global) => {
|
|
14
|
-
var _a, _b, _c, _d, _e, _f, _g, _h
|
|
14
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
15
15
|
const contexts = global.contexts.sort((a, b) => {
|
|
16
16
|
return a.elementKey.toUpperCase() > b.elementKey.toUpperCase() ? +1 : -1;
|
|
17
17
|
});
|
|
@@ -31,19 +31,10 @@ export const webTypes = (options) => {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
};
|
|
34
|
-
const common = (member) => {
|
|
35
|
-
var _a;
|
|
36
|
-
return ({
|
|
37
|
-
name: member.key['name'],
|
|
38
|
-
description: (_a = getTags(member).find((tag) => !tag.key)) === null || _a === void 0 ? void 0 : _a.value,
|
|
39
|
-
deprecated: hasTag(member, 'deprecated'),
|
|
40
|
-
experimental: hasTag(member, 'experimental')
|
|
41
|
-
});
|
|
42
|
-
};
|
|
43
34
|
for (const context of contexts) {
|
|
44
35
|
const attributes = (_a = context.classProperties) === null || _a === void 0 ? void 0 : _a.map((property) => {
|
|
45
36
|
var _a;
|
|
46
|
-
return Object.assign(
|
|
37
|
+
return Object.assign({
|
|
47
38
|
name: kebabCase(property.key['name']),
|
|
48
39
|
value: {
|
|
49
40
|
// kind: TODO
|
|
@@ -52,41 +43,31 @@ export const webTypes = (options) => {
|
|
|
52
43
|
// default: TODO
|
|
53
44
|
},
|
|
54
45
|
default: getInitializer(property.value)
|
|
55
|
-
});
|
|
46
|
+
}, extractFromComment(property, ['description', 'deprecated', 'experimental']));
|
|
56
47
|
});
|
|
57
|
-
const
|
|
58
|
-
const events = (_c = context.classEvents) === null || _c === void 0 ? void 0 : _c.map((event) => Object.assign(common(event), {
|
|
48
|
+
const events = (_b = context.classEvents) === null || _b === void 0 ? void 0 : _b.map((event) => Object.assign({
|
|
59
49
|
name: kebabCase(event.key['name']) // TODO
|
|
60
50
|
// 'value': TODO
|
|
61
|
-
}));
|
|
62
|
-
const methods = (
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
51
|
+
}, extractFromComment(event, ['description', 'deprecated', 'experimental'])));
|
|
52
|
+
const methods = (_c = context.classMethods) === null || _c === void 0 ? void 0 : _c.map((method) => Object.assign({
|
|
53
|
+
name: method.key['name']
|
|
54
|
+
// 'value': TODO
|
|
55
|
+
}, extractFromComment(method, ['description', 'deprecated', 'experimental'])));
|
|
56
|
+
const properties = (_d = context.classProperties) === null || _d === void 0 ? void 0 : _d.map((property) => Object.assign({
|
|
57
|
+
name: property.key['name'],
|
|
66
58
|
// 'value': TODO
|
|
67
59
|
default: getInitializer(property.value)
|
|
68
|
-
}));
|
|
69
|
-
const
|
|
70
|
-
const { description, name } = parseTag(tag);
|
|
71
|
-
return {
|
|
72
|
-
name,
|
|
73
|
-
description
|
|
74
|
-
};
|
|
75
|
-
});
|
|
76
|
-
const element = {
|
|
60
|
+
}, extractFromComment(property, ['description', 'deprecated', 'experimental'])));
|
|
61
|
+
const element = Object.assign({
|
|
77
62
|
'name': context.elementKey,
|
|
78
|
-
'
|
|
79
|
-
'doc-url': (_g = (_f = options).reference) === null || _g === void 0 ? void 0 : _g.call(_f, context),
|
|
80
|
-
'deprecated': hasTag(context.class, 'deprecated'),
|
|
81
|
-
'experimental': hasTag(context.class, 'experimental'),
|
|
63
|
+
'doc-url': (_f = (_e = options).reference) === null || _f === void 0 ? void 0 : _f.call(_e, context),
|
|
82
64
|
'js': {
|
|
83
65
|
events,
|
|
84
66
|
properties: [].concat(properties, methods)
|
|
85
67
|
},
|
|
86
|
-
attributes
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const transformed = ((_j = (_h = options).transformer) === null || _j === void 0 ? void 0 : _j.call(_h, context, element)) || element;
|
|
68
|
+
attributes
|
|
69
|
+
}, extractFromComment(context.class, ['description', 'deprecated', 'experimental', 'slots']));
|
|
70
|
+
const transformed = ((_h = (_g = options).transformer) === null || _h === void 0 ? void 0 : _h.call(_g, context, element)) || element;
|
|
90
71
|
json.contributions.html.elements.push(transformed);
|
|
91
72
|
}
|
|
92
73
|
const dirname = path.dirname(options.destination);
|
|
@@ -7,13 +7,10 @@ export interface TransformerPluginContext {
|
|
|
7
7
|
assetsSource?: string;
|
|
8
8
|
class?: ClassDeclaration;
|
|
9
9
|
classEvents?: Array<ClassProperty>;
|
|
10
|
-
classHasMount?: boolean;
|
|
11
|
-
classHasUnmount?: boolean;
|
|
12
10
|
classMembers?: ClassBody['body'];
|
|
13
11
|
classMethods?: Array<ClassMethod>;
|
|
14
12
|
className?: string;
|
|
15
13
|
classProperties?: Array<ClassProperty>;
|
|
16
|
-
classRender?: ClassMethod;
|
|
17
14
|
classStates?: Array<ClassProperty>;
|
|
18
15
|
directoryName?: string;
|
|
19
16
|
directoryPath?: string;
|
|
@@ -39,6 +36,9 @@ export interface TransformerPluginContext {
|
|
|
39
36
|
}
|
|
40
37
|
export interface TransformerPluginGlobal {
|
|
41
38
|
contexts: Array<TransformerPluginContext>;
|
|
39
|
+
metadata?: {
|
|
40
|
+
[key: string]: any;
|
|
41
|
+
};
|
|
42
42
|
}
|
|
43
43
|
export interface TransformerPlugin {
|
|
44
44
|
name: string;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export const extractFromComment = (node, whitelist) => {
|
|
2
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
3
|
+
const normalized = [];
|
|
4
|
+
const result = {
|
|
5
|
+
description: ''
|
|
6
|
+
};
|
|
7
|
+
const lines = (_d = (_c = (_b = (_a = node.leadingComments) === null || _a === void 0 ? void 0 : _a.map((comment) => {
|
|
8
|
+
if (comment.type == 'CommentLine')
|
|
9
|
+
return comment.value;
|
|
10
|
+
return comment.value.split('\n');
|
|
11
|
+
})) === null || _b === void 0 ? void 0 : _b.flat()) === null || _c === void 0 ? void 0 : _c.map((line) => line.trim().replace(/^\*/, '').trim())) === null || _d === void 0 ? void 0 : _d.filter((line) => line.trim());
|
|
12
|
+
for (const line of lines || []) {
|
|
13
|
+
if (line.startsWith('@')) {
|
|
14
|
+
normalized.push(line);
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (!normalized.length)
|
|
18
|
+
normalized.push('');
|
|
19
|
+
normalized[normalized.length - 1] += ' ' + line;
|
|
20
|
+
}
|
|
21
|
+
for (const line of normalized) {
|
|
22
|
+
if (!line.startsWith('@')) {
|
|
23
|
+
result.description = line.trim();
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
const regex = /@(\w+)(?:\s*({\w+})\s*)?(?:\s*([-a-zA-Z\s]+)\s*-\s*)?(.*)/;
|
|
27
|
+
const groups = regex.exec(line);
|
|
28
|
+
if (!groups)
|
|
29
|
+
continue;
|
|
30
|
+
const tag = (_e = groups[1]) === null || _e === void 0 ? void 0 : _e.trim();
|
|
31
|
+
const type = (_f = groups[2]) === null || _f === void 0 ? void 0 : _f.trim().slice(1, -1);
|
|
32
|
+
const name = (_g = groups[3]) === null || _g === void 0 ? void 0 : _g.trim();
|
|
33
|
+
const description = (_h = groups[4]) === null || _h === void 0 ? void 0 : _h.trim();
|
|
34
|
+
if (name && description) {
|
|
35
|
+
const key = tag + 's';
|
|
36
|
+
if (whitelist && !whitelist.includes(key))
|
|
37
|
+
continue;
|
|
38
|
+
(result[key] || (result[key] = [])).push({ name, type, description });
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
const key = tag;
|
|
42
|
+
if (whitelist && !whitelist.includes(key))
|
|
43
|
+
continue;
|
|
44
|
+
result[key] = description || true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return result;
|
|
48
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export * from './addDependency.js';
|
|
2
|
+
export * from './extractFromComment.js';
|
|
2
3
|
export * from './getInitializer.js';
|
|
3
4
|
export * from './getType.js';
|
|
4
5
|
export * from './getTypeReference.js';
|
|
5
6
|
export * from './hasDecorator.js';
|
|
6
7
|
export * from './printType.js';
|
|
7
8
|
export * from './print.js';
|
|
8
|
-
export * from './tags.js';
|
|
9
9
|
export * from './visitor.js';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export * from './addDependency.js';
|
|
2
|
+
export * from './extractFromComment.js';
|
|
2
3
|
export * from './getInitializer.js';
|
|
3
4
|
export * from './getType.js';
|
|
4
5
|
export * from './getTypeReference.js';
|
|
5
6
|
export * from './hasDecorator.js';
|
|
6
7
|
export * from './printType.js';
|
|
7
8
|
export * from './print.js';
|
|
8
|
-
export * from './tags.js';
|
|
9
9
|
export * from './visitor.js';
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import t from '@babel/types';
|
|
2
|
-
export interface Tag {
|
|
3
|
-
key?: string;
|
|
4
|
-
value?: string;
|
|
5
|
-
}
|
|
6
|
-
export interface TagParsed {
|
|
7
|
-
name?: string;
|
|
8
|
-
description?: string;
|
|
9
|
-
}
|
|
10
|
-
export declare const getTag: (node: t.Node, key?: string) => Tag | undefined;
|
|
11
|
-
export declare const getTags: (node: t.Node, filter?: string) => Array<Tag>;
|
|
12
|
-
export declare const hasTag: (node: t.Node, name: string) => Boolean;
|
|
13
|
-
export declare const parseTag: (tag: Tag, spliter?: string) => TagParsed;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
export const getTag = (node, key) => {
|
|
2
|
-
return getTags(node, key).pop();
|
|
3
|
-
};
|
|
4
|
-
export const getTags = (node, filter) => {
|
|
5
|
-
var _a, _b, _c;
|
|
6
|
-
const tags = [];
|
|
7
|
-
// TODO
|
|
8
|
-
const comments = node['_leadingComments'] || node.leadingComments;
|
|
9
|
-
const lines = (_c = (_b = (_a = comments === null || comments === void 0 ? void 0 : comments.map((comment) => {
|
|
10
|
-
const { type, value } = comment;
|
|
11
|
-
if (type == 'CommentLine')
|
|
12
|
-
return value;
|
|
13
|
-
return value.replace(/\r\n/g, '\n').split('\n');
|
|
14
|
-
})) === null || _a === void 0 ? void 0 : _a.flat()) === null || _b === void 0 ? void 0 : _b.filter((line) => line.trim().replace(/\*/g, ''))) === null || _c === void 0 ? void 0 : _c.map((line) => line.replace(/^( +)?(\*+)?( +)?/, ''));
|
|
15
|
-
for (const line of lines || []) {
|
|
16
|
-
const has = !!tags.length;
|
|
17
|
-
const isTag = line.startsWith('@');
|
|
18
|
-
if (isTag) {
|
|
19
|
-
const [key, ...values] = line.split(' ');
|
|
20
|
-
tags.push({
|
|
21
|
-
key: key.slice(1).trim(),
|
|
22
|
-
value: values.join(' ').trimStart()
|
|
23
|
-
});
|
|
24
|
-
continue;
|
|
25
|
-
}
|
|
26
|
-
if (!has)
|
|
27
|
-
tags.push({ key: '', value: '' });
|
|
28
|
-
tags[tags.length - 1].value += line;
|
|
29
|
-
}
|
|
30
|
-
return tags.filter((tag) => !filter || filter === tag.key);
|
|
31
|
-
};
|
|
32
|
-
export const hasTag = (node, name) => {
|
|
33
|
-
return getTags(node).some((tag) => tag.key === name);
|
|
34
|
-
};
|
|
35
|
-
export const parseTag = (tag, spliter = ' - ') => {
|
|
36
|
-
var _a, _b;
|
|
37
|
-
const sections = ((_a = tag.value) === null || _a === void 0 ? void 0 : _a.split(spliter)) || [];
|
|
38
|
-
const name = (_b = sections[0]) === null || _b === void 0 ? void 0 : _b.trim();
|
|
39
|
-
const description = sections.slice(1).join(spliter).trim();
|
|
40
|
-
return {
|
|
41
|
-
name,
|
|
42
|
-
description
|
|
43
|
-
};
|
|
44
|
-
};
|