babel-plugin-vasille 5.0.4 → 5.1.1
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/README.md +56 -45
- package/lib/index.js +1 -0
- package/lib/jsx.js +31 -6
- package/lib/lib.js +17 -0
- package/lib/mesh.js +66 -3
- package/lib/process-types.js +83 -0
- package/lib/transformer.js +45 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
`SteelFrameKit` is a front-end development kit, which is developed to provide fault tolerant web applications.
|
|
6
6
|
|
|
7
|
-
[](https://www.npmjs.com/package/steel-frame)
|
|
8
8
|
[](https://deepwiki.com/vasille-js/steel-frame)
|
|
9
9
|
[](https://coveralls.io/github/vasille-js/steel-frame?branch=v5)
|
|
10
10
|
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
- [How POWERFUL is SteelFrameKit](#how-powerful-is-steelframekit)
|
|
22
22
|
- [Road map](#road-map)
|
|
23
23
|
- [Change log](#change-log)
|
|
24
|
+
- [5.1](#51)
|
|
24
25
|
- [5.0](#50)
|
|
25
26
|
- [4.0 - 4.3](#40---43)
|
|
26
27
|
- [3.0 - 3.2](#30---32)
|
|
@@ -28,7 +29,6 @@
|
|
|
28
29
|
- [1.0 - 1.2](#10---12)
|
|
29
30
|
- [Questions](#questions)
|
|
30
31
|
|
|
31
|
-
|
|
32
32
|
<hr>
|
|
33
33
|
|
|
34
34
|
## Installation
|
|
@@ -46,37 +46,41 @@ $ npm create steel-frame
|
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
### Full documentation:
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
|
|
50
|
+
- [Learn `SteelFrameKit` in 5 minutes](https://github.com/vasille-js/vasille-js/blob/v5/doc/V4-API.md)
|
|
51
|
+
- [Router Documentation](https://github.com/vasille-js/vasille-js/blob/v5/doc/Router-API.md)
|
|
52
|
+
- [Compostion functions](https://github.com/vasille-js/vasille-js/blob/v5/doc/Compositions.md)
|
|
53
|
+
- [Dependency injection](https://github.com/vasille-js/vasille-js/blob/v5/doc/Context.md)
|
|
53
54
|
|
|
54
55
|
### Examples
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
|
|
57
|
+
- [TypeScript Example](https://github.com/vasille-js/example-typescript)
|
|
58
|
+
- [JavaScript Example](https://github.com/vasille-js/example-javascript)
|
|
57
59
|
|
|
58
60
|
<hr>
|
|
59
61
|
|
|
60
62
|
## How SAFE is SteelFrameKit
|
|
61
63
|
|
|
62
64
|
The safe of your application is ensured by
|
|
63
|
-
|
|
65
|
+
|
|
66
|
+
- `100%` coverage of code by unit tests.
|
|
64
67
|
Each function, each branch is working as designed.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
All entities of `SteelFrameKit` core library are strongly typed, including:
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
68
|
+
- OOP, DRY, KISS and SOLID principles are applied.
|
|
69
|
+
- `strong typing` makes your code safe.
|
|
70
|
+
All entities of `SteelFrameKit` core library are strongly typed, including:
|
|
71
|
+
- data fields & properties.
|
|
72
|
+
- computed properties (function parameters and result).
|
|
73
|
+
- methods.
|
|
74
|
+
- events (defined handlers & event emit).
|
|
75
|
+
- DOM events & DOM operation (attributing, styling, etc.).
|
|
76
|
+
- slots of components.
|
|
77
|
+
- references to children.
|
|
78
|
+
- No asynchronous code, when the line of code is executed, the DOM and reactive things are already synced.
|
|
76
79
|
|
|
77
80
|
## How INTUITIVE is SteelFrameKit
|
|
78
81
|
|
|
79
82
|
There is the "Hello World":
|
|
83
|
+
|
|
80
84
|
```typescript jsx
|
|
81
85
|
import { compose, mount } from "steel-frame";
|
|
82
86
|
|
|
@@ -90,39 +94,46 @@ mount(document.body, App, {});
|
|
|
90
94
|
## How POWERFUL is SteelFrameKit
|
|
91
95
|
|
|
92
96
|
All of these are supported:
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
97
|
+
|
|
98
|
+
- Components.
|
|
99
|
+
- Reactive values (observables).
|
|
100
|
+
- Inline computed values.
|
|
101
|
+
- Multiline computed values.
|
|
102
|
+
- HTML tags.
|
|
103
|
+
- Component custom slots.
|
|
104
|
+
- 2-way data binding in components.
|
|
105
|
+
- Logic block (if, else).
|
|
106
|
+
- Loops (array, map, set).
|
|
107
|
+
- Dependency injection.
|
|
103
108
|
|
|
104
109
|
<hr>
|
|
105
110
|
|
|
106
111
|
## Road map
|
|
107
112
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
113
|
+
- [x] `100%` Test Coverage for core Library v3.
|
|
114
|
+
- [x] Develop the `JSX` library.
|
|
115
|
+
- [x] `100%` Test Coverage for the JSX library.
|
|
116
|
+
- [x] Develop the `Babel Plugin`.
|
|
117
|
+
- [x] `100%` Test Coverage fot babel plugin.
|
|
118
|
+
- [x] Add CSS support (define styles in components).
|
|
119
|
+
- [x] Add router.
|
|
120
|
+
- [x] Add SSG (static site generation).
|
|
121
|
+
- [ ] Develop tools extension for debugging (WIP).
|
|
122
|
+
- [ ] Add SSR (server side rendering).
|
|
118
123
|
|
|
119
124
|
## Change log
|
|
120
125
|
|
|
121
126
|
We respect semantic versioning:
|
|
122
|
-
|
|
123
|
-
-
|
|
127
|
+
|
|
128
|
+
- A major version is increased when we make incompatible API changes.
|
|
129
|
+
- A minor version is increased when we add functionality.
|
|
124
130
|
- Patch version is increased when we fix bugs.
|
|
125
131
|
|
|
132
|
+
### 5.1
|
|
133
|
+
|
|
134
|
+
Add support for web components compile target `web build components`.
|
|
135
|
+
_Web components as custom tags are supported in any version._
|
|
136
|
+
|
|
126
137
|
### 5.0
|
|
127
138
|
|
|
128
139
|
- Add support for context and dependencies injection.
|
|
@@ -142,7 +153,7 @@ We respect semantic versioning:
|
|
|
142
153
|
### 3.0 - 3.2
|
|
143
154
|
|
|
144
155
|
- Switch to a babel plugin to compile components code. **[API change]**
|
|
145
|
-
- 100% of code has been covered with unit tests.
|
|
156
|
+
- 100% of the code has been covered with unit tests.
|
|
146
157
|
- New developement direction: `keep it simple`.
|
|
147
158
|
|
|
148
159
|
### 2.0 - 2.3
|
|
@@ -152,11 +163,11 @@ We respect semantic versioning:
|
|
|
152
163
|
|
|
153
164
|
### 1.0 - 1.2
|
|
154
165
|
|
|
155
|
-
- Initial version of core library.
|
|
166
|
+
- Initial version of a core library.
|
|
156
167
|
- Developemnt direction: `performance-first`.
|
|
157
168
|
|
|
158
169
|
## Questions
|
|
159
170
|
|
|
160
171
|
If you have questions, feel free to contact the maintainer of the project:
|
|
161
172
|
|
|
162
|
-
|
|
173
|
+
- [Author's Email](mailto:vas.lixcode@gmail.com)
|
package/lib/index.js
CHANGED
package/lib/jsx.js
CHANGED
|
@@ -615,12 +615,37 @@ function transformJsxElement(path, conditions, internal) {
|
|
|
615
615
|
}
|
|
616
616
|
return ret;
|
|
617
617
|
}
|
|
618
|
-
|
|
619
|
-
t.
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
618
|
+
if (internal.shadow && mapped === "Slot") {
|
|
619
|
+
const model = props.find(item => t.isObjectProperty(item) && t.isIdentifier(item.key) && item.key.name === "model");
|
|
620
|
+
const modelName = t.isObjectProperty(model) &&
|
|
621
|
+
((t.isIdentifier(model.value) && model.value.name) ||
|
|
622
|
+
((t.isMemberExpression(model.value) || t.isOptionalMemberExpression(model.value)) &&
|
|
623
|
+
t.isIdentifier(model.value.property) &&
|
|
624
|
+
model.value.property.name));
|
|
625
|
+
const call = t.callExpression(t.memberExpression(internal_js_1.ctx, t.identifier("tag")), [
|
|
626
|
+
t.stringLiteral("slot"),
|
|
627
|
+
t.objectExpression(modelName && modelName !== "slot"
|
|
628
|
+
? [
|
|
629
|
+
t.objectProperty(t.identifier("a"), t.objectExpression([t.objectProperty(t.identifier("name"), t.stringLiteral(modelName))])),
|
|
630
|
+
]
|
|
631
|
+
: []),
|
|
632
|
+
...(run ? [run] : []),
|
|
633
|
+
]);
|
|
634
|
+
run = t.arrowFunctionExpression([internal_js_1.ctx], call);
|
|
635
|
+
}
|
|
636
|
+
const localComponentName = internal.shadow && internal.componentsImports.get(name.name);
|
|
637
|
+
const call = localComponentName
|
|
638
|
+
? t.callExpression(t.memberExpression(internal_js_1.ctx, t.identifier("tag")), [
|
|
639
|
+
t.stringLiteral((0, lib_js_1.toKebabCase)(localComponentName)),
|
|
640
|
+
t.objectExpression([t.objectProperty(t.identifier("b"), t.objectExpression(props))]),
|
|
641
|
+
...(run ? [run] : []),
|
|
642
|
+
])
|
|
643
|
+
: t.callExpression(t.identifier(name.name), [
|
|
644
|
+
t.objectExpression(props),
|
|
645
|
+
internal_js_1.ctx,
|
|
646
|
+
...(run ? [run] : internal.devLayer ? [t.buildUndefinedNode()] : []),
|
|
647
|
+
...(internal.devLayer ? [(0, transformer_1.nodeToStaticPosition)(path.node)] : []),
|
|
648
|
+
]);
|
|
624
649
|
call.loc = path.node.loc;
|
|
625
650
|
return [...ret, t.expressionStatement(call)];
|
|
626
651
|
}
|
package/lib/lib.js
CHANGED
|
@@ -46,6 +46,8 @@ exports.mapModel = mapModel;
|
|
|
46
46
|
exports.processModelCall = processModelCall;
|
|
47
47
|
exports.checkReactiveName = checkReactiveName;
|
|
48
48
|
exports.checkNonReactiveName = checkNonReactiveName;
|
|
49
|
+
exports.toKebabCase = toKebabCase;
|
|
50
|
+
exports.nameIsRestricted = nameIsRestricted;
|
|
49
51
|
const t = __importStar(require("@babel/types"));
|
|
50
52
|
const expression_js_1 = require("./expression.js");
|
|
51
53
|
const internal_js_1 = require("./internal.js");
|
|
@@ -189,3 +191,18 @@ function checkNonReactiveName(idPath, internal) {
|
|
|
189
191
|
err(Errors.RulesOfVasille, idPath, "Non-reactive variable name must not start with $", internal);
|
|
190
192
|
}
|
|
191
193
|
}
|
|
194
|
+
function toKebabCase(name) {
|
|
195
|
+
let index = 0;
|
|
196
|
+
let fixed = name[index].toLowerCase();
|
|
197
|
+
for (index++; index < name.length; index++) {
|
|
198
|
+
const curr = name[index];
|
|
199
|
+
if (curr === curr.toUpperCase()) {
|
|
200
|
+
fixed += "-";
|
|
201
|
+
}
|
|
202
|
+
fixed += curr.toLowerCase();
|
|
203
|
+
}
|
|
204
|
+
return fixed;
|
|
205
|
+
}
|
|
206
|
+
function nameIsRestricted(name) {
|
|
207
|
+
return name.endsWith("Model") || name.startsWith("prompt");
|
|
208
|
+
}
|
package/lib/mesh.js
CHANGED
|
@@ -60,6 +60,7 @@ const order_check_1 = require("./order-check");
|
|
|
60
60
|
const router_1 = require("./router");
|
|
61
61
|
const utils_1 = require("./utils");
|
|
62
62
|
const transformer_1 = require("./transformer");
|
|
63
|
+
const process_types_1 = require("./process-types");
|
|
63
64
|
function meshOrIgnoreAllExpressions(nodePaths, internal) {
|
|
64
65
|
for (const path of nodePaths) {
|
|
65
66
|
/* istanbul ignore else */
|
|
@@ -73,9 +74,19 @@ function meshAllExpressions(nodePaths, internal) {
|
|
|
73
74
|
meshExpression(path, internal);
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
|
-
|
|
77
|
+
const restrictedNames = [
|
|
78
|
+
"annotation-xml",
|
|
79
|
+
"color-profile",
|
|
80
|
+
"font-face",
|
|
81
|
+
"font-face-src",
|
|
82
|
+
"font-face-uri",
|
|
83
|
+
"font-face-format",
|
|
84
|
+
"font-face-name",
|
|
85
|
+
"missing-glyph",
|
|
86
|
+
];
|
|
87
|
+
function meshComposeCall(name, path, internal, isExported = false) {
|
|
77
88
|
const args = path.isCallExpression() && path.get("arguments");
|
|
78
|
-
const arg = args && (args[0].isFunctionExpression() || args[0].isArrowFunctionExpression()) && args[0];
|
|
89
|
+
const arg = args && args[0] && (args[0].isFunctionExpression() || args[0].isArrowFunctionExpression()) && args[0];
|
|
79
90
|
if (!args || !arg || args.length !== 1) {
|
|
80
91
|
return (0, lib_js_1.err)(lib_js_1.Errors.IncorrectArguments, path, "Invalid arguments number", internal);
|
|
81
92
|
}
|
|
@@ -84,6 +95,33 @@ function meshComposeCall(name, path, internal) {
|
|
|
84
95
|
if (internal.devLayer && path.isCallExpression()) {
|
|
85
96
|
path.node.arguments.push((0, transformer_1.nodeToStaticPosition)(path.node), t.stringLiteral(name ? name : "#"));
|
|
86
97
|
}
|
|
98
|
+
if (internal.shadow && isExported && name && path.isCallExpression()) {
|
|
99
|
+
const call = path.node;
|
|
100
|
+
const generics = call.typeParameters?.params;
|
|
101
|
+
const args = call.arguments;
|
|
102
|
+
const params = (t.isFunctionExpression(args[0]) || t.isArrowFunctionExpression(args[0])) && args[0].params;
|
|
103
|
+
const annotation = (generics && generics[0]) ||
|
|
104
|
+
(params && params[1] && !t.isVoidPattern(params[1]) && params[1].typeAnnotation) ||
|
|
105
|
+
null;
|
|
106
|
+
const type = (t.isTSTypeAnnotation(annotation) && annotation.typeAnnotation) || (t.isTSType(annotation) && annotation) || null;
|
|
107
|
+
const kebabName = (0, lib_js_1.toKebabCase)(name);
|
|
108
|
+
let fields;
|
|
109
|
+
if (t.isTSTypeLiteral(type)) {
|
|
110
|
+
fields = (0, process_types_1.processTypeLiteral)(type);
|
|
111
|
+
}
|
|
112
|
+
if (t.isTSTypeReference(type)) {
|
|
113
|
+
fields = (0, process_types_1.processReference)(type, internal);
|
|
114
|
+
}
|
|
115
|
+
if (kebabName.indexOf("-") === -1 || restrictedNames.indexOf(kebabName) !== -1) {
|
|
116
|
+
(0, lib_js_1.err)(lib_js_1.Errors.ParserError, path, `The name '${kebabName}' is not allowed by WHATWG`, internal);
|
|
117
|
+
}
|
|
118
|
+
if (fields) {
|
|
119
|
+
path.node.arguments.push(t.stringLiteral(kebabName), fields);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
(0, lib_js_1.err)(lib_js_1.Errors.RulesOfVasille, path, "Missing type for web component composition", internal);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
87
125
|
}
|
|
88
126
|
function meshAllUnknown(paths, internal) {
|
|
89
127
|
for (const path of paths) {
|
|
@@ -204,6 +242,12 @@ function meshExpression(nodePath, internal) {
|
|
|
204
242
|
(0, lib_js_1.err)(lib_js_1.Errors.IncompatibleContext, path, "Prompts can be constructed only from components", internal);
|
|
205
243
|
}
|
|
206
244
|
path.node.arguments.unshift(internal_js_1.ctx);
|
|
245
|
+
if (internal.devLayer) {
|
|
246
|
+
while (path.node.arguments.length < 3) {
|
|
247
|
+
path.node.arguments.push(t.buildUndefinedNode());
|
|
248
|
+
}
|
|
249
|
+
path.node.arguments.push((0, transformer_1.nodeToStaticPosition)(path.node));
|
|
250
|
+
}
|
|
207
251
|
}
|
|
208
252
|
// dependency injection
|
|
209
253
|
else if (internal.isComposing &&
|
|
@@ -407,6 +451,9 @@ function ignoreParams(path, internal, allowReactiveId) {
|
|
|
407
451
|
if (!allowReactiveId || !allowReactiveId.includes("id")) {
|
|
408
452
|
(0, lib_js_1.checkNonReactiveName)(path, internal);
|
|
409
453
|
}
|
|
454
|
+
if ((0, lib_js_1.nameIsRestricted)(path.node.name)) {
|
|
455
|
+
(0, lib_js_1.err)(lib_js_1.Errors.RulesOfVasille, path, "This name is restricted (start with `prompt` or ends with `Model`)", internal);
|
|
456
|
+
}
|
|
410
457
|
}
|
|
411
458
|
// param is object destruction
|
|
412
459
|
else if (path.isObjectPattern()) {
|
|
@@ -816,7 +863,7 @@ function meshStatement(path, internal) {
|
|
|
816
863
|
report(`File name is not correct, expected ${name}.ts, ${name}.tsx, ${name}.js or ${name}.jsx`);
|
|
817
864
|
}
|
|
818
865
|
}
|
|
819
|
-
meshComposeCall(id.name, initPath, internal);
|
|
866
|
+
meshComposeCall(id.name, initPath, internal, isExported);
|
|
820
867
|
}
|
|
821
868
|
// calculate call
|
|
822
869
|
else if ((0, call_js_1.calls)(initPath, ["calculate"], internal) &&
|
|
@@ -892,6 +939,19 @@ function meshStatement(path, internal) {
|
|
|
892
939
|
meshClassBody(declarationPath.get("body"), internal);
|
|
893
940
|
}
|
|
894
941
|
}
|
|
942
|
+
break;
|
|
943
|
+
}
|
|
944
|
+
case "TSInterfaceDeclaration": {
|
|
945
|
+
const declaration = path.node;
|
|
946
|
+
(0, process_types_1.registerInterface)(declaration.id.name, declaration.body.body, internal);
|
|
947
|
+
break;
|
|
948
|
+
}
|
|
949
|
+
case "TSTypeAliasDeclaration": {
|
|
950
|
+
const alias = path.node;
|
|
951
|
+
if (t.isTSTypeLiteral(alias.typeAnnotation)) {
|
|
952
|
+
(0, process_types_1.registerInterface)(alias.id.name, alias.typeAnnotation.members, internal);
|
|
953
|
+
}
|
|
954
|
+
break;
|
|
895
955
|
}
|
|
896
956
|
}
|
|
897
957
|
}
|
|
@@ -902,6 +962,9 @@ function meshFunction(path, internal) {
|
|
|
902
962
|
if (idPath.isIdentifier()) {
|
|
903
963
|
internal.stack.set(path.node.id.name, {});
|
|
904
964
|
(0, lib_js_1.checkNonReactiveName)(idPath, internal);
|
|
965
|
+
if (internal.devLayer) {
|
|
966
|
+
path.insertAfter(internal.setupPosition(idPath.node, path.node));
|
|
967
|
+
}
|
|
905
968
|
}
|
|
906
969
|
}
|
|
907
970
|
internal.stack.push();
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerInterface = registerInterface;
|
|
4
|
+
exports.processUnion = processUnion;
|
|
5
|
+
exports.processType = processType;
|
|
6
|
+
exports.processSignatures = processSignatures;
|
|
7
|
+
exports.processTypeLiteral = processTypeLiteral;
|
|
8
|
+
exports.processReference = processReference;
|
|
9
|
+
const types_1 = require("@babel/types");
|
|
10
|
+
const any = 0;
|
|
11
|
+
const string = 1;
|
|
12
|
+
const number = 2;
|
|
13
|
+
const boolean = 3;
|
|
14
|
+
function registerInterface(name, members, internal) {
|
|
15
|
+
internal.interfaces.set(name, members);
|
|
16
|
+
}
|
|
17
|
+
function processUnion(type) {
|
|
18
|
+
let isString = false;
|
|
19
|
+
let isNumber = false;
|
|
20
|
+
let isBoolean = false;
|
|
21
|
+
let isAny = false;
|
|
22
|
+
for (const keyword of type.types) {
|
|
23
|
+
if ((0, types_1.isTSStringKeyword)(keyword)) {
|
|
24
|
+
isString = true;
|
|
25
|
+
}
|
|
26
|
+
else if ((0, types_1.isTSNumberKeyword)(keyword)) {
|
|
27
|
+
isNumber = true;
|
|
28
|
+
}
|
|
29
|
+
else if ((0, types_1.isTSBooleanKeyword)(keyword)) {
|
|
30
|
+
isBoolean = true;
|
|
31
|
+
}
|
|
32
|
+
else if (!(0, types_1.isTSNullKeyword)(keyword) && !(0, types_1.isTSUndefinedKeyword)(keyword)) {
|
|
33
|
+
isAny = true;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (isAny) {
|
|
37
|
+
return any;
|
|
38
|
+
}
|
|
39
|
+
if (isString) {
|
|
40
|
+
return string;
|
|
41
|
+
}
|
|
42
|
+
if (isNumber && !isBoolean) {
|
|
43
|
+
return number;
|
|
44
|
+
}
|
|
45
|
+
if (isBoolean && !isNumber) {
|
|
46
|
+
return boolean;
|
|
47
|
+
}
|
|
48
|
+
return any;
|
|
49
|
+
}
|
|
50
|
+
function processType(type) {
|
|
51
|
+
if ((0, types_1.isTSUnionType)(type)) {
|
|
52
|
+
return processUnion(type);
|
|
53
|
+
}
|
|
54
|
+
if ((0, types_1.isTSStringKeyword)(type)) {
|
|
55
|
+
return string;
|
|
56
|
+
}
|
|
57
|
+
if ((0, types_1.isTSNumberKeyword)(type)) {
|
|
58
|
+
return number;
|
|
59
|
+
}
|
|
60
|
+
if ((0, types_1.isTSBooleanKeyword)(type)) {
|
|
61
|
+
return boolean;
|
|
62
|
+
}
|
|
63
|
+
return any;
|
|
64
|
+
}
|
|
65
|
+
function processSignatures(members) {
|
|
66
|
+
const props = [];
|
|
67
|
+
for (const member of members) {
|
|
68
|
+
if ((0, types_1.isTSPropertySignature)(member)) {
|
|
69
|
+
props.push((0, types_1.objectProperty)(member.key, (0, types_1.numericLiteral)(member.typeAnnotation ? processType(member.typeAnnotation.typeAnnotation) : any)));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return (0, types_1.objectExpression)(props);
|
|
73
|
+
}
|
|
74
|
+
function processTypeLiteral(literal) {
|
|
75
|
+
return processSignatures(literal.members);
|
|
76
|
+
}
|
|
77
|
+
function processReference(id, internal) {
|
|
78
|
+
/* istanbul ignore else */
|
|
79
|
+
if ((0, types_1.isIdentifier)(id.typeName)) {
|
|
80
|
+
const members = internal.interfaces.get(id.typeName.name);
|
|
81
|
+
return members ? processSignatures(members) : undefined;
|
|
82
|
+
}
|
|
83
|
+
}
|
package/lib/transformer.js
CHANGED
|
@@ -69,12 +69,44 @@ function extractText(node) {
|
|
|
69
69
|
// no case found for string literal
|
|
70
70
|
return node.name;
|
|
71
71
|
}
|
|
72
|
+
function extractComponentImport(node, internal) {
|
|
73
|
+
const name = node.source.value;
|
|
74
|
+
const match = /^(@\/components|\.)\/([^\/.]+)\.[tj]sx?$/.exec(name);
|
|
75
|
+
if (!match) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const filename = match[2];
|
|
79
|
+
const toRemove = [];
|
|
80
|
+
for (const specifier of node.specifiers) {
|
|
81
|
+
if (t.isImportDefaultSpecifier(specifier)) {
|
|
82
|
+
toRemove.push(specifier);
|
|
83
|
+
internal.componentsImports.set(specifier.local.name, filename);
|
|
84
|
+
}
|
|
85
|
+
if (t.isImportSpecifier(specifier)) {
|
|
86
|
+
const imported = extractText(specifier.imported);
|
|
87
|
+
// the exported component name must match the file name
|
|
88
|
+
/* istanbul ignore else */
|
|
89
|
+
if (imported === filename) {
|
|
90
|
+
toRemove.push(specifier);
|
|
91
|
+
internal.componentsImports.set(specifier.local.name, filename);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/* istanbul ignore else */
|
|
96
|
+
if (toRemove.length) {
|
|
97
|
+
node.specifiers = node.specifiers.filter(item => !toRemove.includes(item));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
72
100
|
// Handles import declarations and updates internal state
|
|
73
101
|
function handleImportDeclaration(statementPath, internal, ids) {
|
|
74
102
|
const statement = statementPath.node;
|
|
75
103
|
const name = imports.get(statement.source.value);
|
|
76
|
-
if (!name)
|
|
104
|
+
if (!name) {
|
|
105
|
+
if (internal.shadow) {
|
|
106
|
+
extractComponentImport(statement, internal);
|
|
107
|
+
}
|
|
77
108
|
return;
|
|
109
|
+
}
|
|
78
110
|
statement.source.value = internal.replaceWeb;
|
|
79
111
|
internal.prefix = name;
|
|
80
112
|
for (const specifier of statement.specifiers) {
|
|
@@ -162,6 +194,7 @@ function transformProgram(path, filename, opts) {
|
|
|
162
194
|
executionPosition: "VasilleExePos",
|
|
163
195
|
runFn: "VasilleRun",
|
|
164
196
|
wrapFn: "VasilleWrap",
|
|
197
|
+
setupPosition: "VasilleSetupPosition",
|
|
165
198
|
shareStateById: "VasilleState",
|
|
166
199
|
positionedText: "VasillePosText",
|
|
167
200
|
earlyInspector: "VasilleInspector",
|
|
@@ -177,6 +210,8 @@ function transformProgram(path, filename, opts) {
|
|
|
177
210
|
const internal = {
|
|
178
211
|
stack: new internal_js_1.StackedStates(),
|
|
179
212
|
mapping: new Map(),
|
|
213
|
+
interfaces: new Map(),
|
|
214
|
+
componentsImports: new Map(),
|
|
180
215
|
global: "",
|
|
181
216
|
prefix: "Vasille_",
|
|
182
217
|
importStatement: null,
|
|
@@ -189,6 +224,7 @@ function transformProgram(path, filename, opts) {
|
|
|
189
224
|
replaceWeb: opts.replaceWeb ?? (opts.devLayer ? "steel-frame" : "vasille-web"),
|
|
190
225
|
headTag: opts.headTag,
|
|
191
226
|
bodyTag: opts.bodyTag,
|
|
227
|
+
shadow: opts.shadow,
|
|
192
228
|
ref(arg, area, name) {
|
|
193
229
|
if (opts.devLayer) {
|
|
194
230
|
return named(call("ref", [arg ? arg : t.buildUndefinedNode(), nodeToStaticPosition(area), getInspector()]), name);
|
|
@@ -256,12 +292,12 @@ function transformProgram(path, filename, opts) {
|
|
|
256
292
|
return t.callExpression(t.memberExpression(left, t.identifier("update")), [right, getExecutionPosition(assign)]);
|
|
257
293
|
},
|
|
258
294
|
wrapFunctionBody(fn) {
|
|
259
|
-
const params = fn.params.map((item) => {
|
|
260
|
-
return t.isFunctionParameter(item) ? item : item.parameter;
|
|
261
|
-
});
|
|
262
|
-
const body = fn.body;
|
|
263
|
-
const args = t.identifier("VasilleArgs");
|
|
264
295
|
if (opts.devLayer) {
|
|
296
|
+
const params = fn.params.map((item) => {
|
|
297
|
+
return t.isFunctionParameter(item) ? item : item.parameter;
|
|
298
|
+
});
|
|
299
|
+
const body = fn.body;
|
|
300
|
+
const args = t.identifier("VasilleArgs");
|
|
265
301
|
fn.body = t.blockStatement([
|
|
266
302
|
t.returnStatement(call("runFn", [
|
|
267
303
|
t.arrowFunctionExpression(params, body, fn.async),
|
|
@@ -281,6 +317,9 @@ function transformProgram(path, filename, opts) {
|
|
|
281
317
|
}
|
|
282
318
|
return fn;
|
|
283
319
|
},
|
|
320
|
+
setupPosition(target, area) {
|
|
321
|
+
return call("setupPosition", [target, nodeToStaticPosition(area)]);
|
|
322
|
+
},
|
|
284
323
|
shareStateById(value, name) {
|
|
285
324
|
return shareStateById(value, name);
|
|
286
325
|
},
|