babel-plugin-vasille 3.1.5 → 4.0.0
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 +9 -17
- package/lib/call.js +45 -34
- package/lib/css-transformer.js +45 -47
- package/lib/expression.js +147 -139
- package/lib/index.js +4 -1
- package/lib/internal.js +4 -19
- package/lib/jsx-detect.js +3 -54
- package/lib/jsx.js +253 -123
- package/lib/lib.js +116 -80
- package/lib/mesh.js +580 -400
- package/lib/order-check.js +48 -0
- package/lib/router.js +41 -0
- package/lib/transformer.js +121 -75
- package/{lib-node/internal.js → lib/utils.js} +10 -37
- package/package.json +12 -14
- package/lib-node/call.js +0 -104
- package/lib-node/css-transformer.js +0 -248
- package/lib-node/expression.js +0 -573
- package/lib-node/index.js +0 -14
- package/lib-node/jsx-detect.js +0 -100
- package/lib-node/jsx.js +0 -439
- package/lib-node/lib.js +0 -153
- package/lib-node/mesh.js +0 -919
- package/lib-node/transformer.js +0 -144
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Vasille
|
|
2
2
|
|
|
3
|
-

|
|
4
4
|
|
|
5
|
-
`Vasille Web` is a front-end framework, which is developed to provide
|
|
5
|
+
`Vasille Web` is a front-end framework, which is developed to provide bulletproof frontends.
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/vasille)
|
|
8
8
|
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* [Installation](#installation)
|
|
12
12
|
* [How to use Vasille](#how-to-use-vasille)
|
|
13
13
|
* [How SAFE is Vasille](#how-safe-is-vasille)
|
|
14
|
-
* [How
|
|
14
|
+
* [How INTUITIVE is Vasille](#how-intuitive-is-vasille)
|
|
15
15
|
* [How POWERFUL is Vasille](#how-powerful-is-vasille)
|
|
16
16
|
* [Road Map](#road-map)
|
|
17
17
|
|
|
@@ -32,18 +32,9 @@ Create an app from a template
|
|
|
32
32
|
$ npm create vasille
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
Alternative method to create a TypeScript app.
|
|
36
|
-
```bash
|
|
37
|
-
$ npx degit vasille-js/example-typescript my-project
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Alternative method to create a JavaScript app.
|
|
41
|
-
```bash
|
|
42
|
-
$ npx degit vasille-js/example-javascript my-project
|
|
43
|
-
```
|
|
44
|
-
|
|
45
35
|
### Full documentation:
|
|
46
|
-
* [Learn `Vasille` in 5 minutes](https://github.com/vasille-js/vasille-js/blob/
|
|
36
|
+
* [Learn `Vasille` in 5 minutes](https://github.com/vasille-js/vasille-js/blob/v4/doc/V4-API.md)
|
|
37
|
+
* [Vasille Router Documentation](https://github.com/vasille-js/vasille-js/blob/v4/doc/Router-API.md)
|
|
47
38
|
|
|
48
39
|
### Examples
|
|
49
40
|
* [TypeScript Example](https://github.com/vasille-js/example-typescript)
|
|
@@ -60,7 +51,7 @@ The safe of your application is ensured by
|
|
|
60
51
|
* `strong typing` makes your javascript/typescript code safe as C++ code.
|
|
61
52
|
All entities of `vasille` core library are strongly typed, including:
|
|
62
53
|
* data fields & properties.
|
|
63
|
-
* computed properties (function parameters
|
|
54
|
+
* computed properties (function parameters and result).
|
|
64
55
|
* methods.
|
|
65
56
|
* events (defined handlers & event emit).
|
|
66
57
|
* DOM events & DOM operation (attributing, styling, etc.).
|
|
@@ -68,7 +59,7 @@ All entities of `vasille` core library are strongly typed, including:
|
|
|
68
59
|
* references to children.
|
|
69
60
|
* No asynchronous code, when the line of code is executed, the DOM and reactive things are already synced.
|
|
70
61
|
|
|
71
|
-
## How
|
|
62
|
+
## How INTUITIVE is Vasille
|
|
72
63
|
|
|
73
64
|
There is the "Hello World":
|
|
74
65
|
```typescript jsx
|
|
@@ -105,7 +96,8 @@ All of these are supported:
|
|
|
105
96
|
* [x] Develop the `Vasille Babel Plugin`.
|
|
106
97
|
* [x] `100%` Test Coverage fot babel plugin.
|
|
107
98
|
* [x] Add CSS support (define styles in components).
|
|
108
|
-
* [
|
|
99
|
+
* [x] Add router.
|
|
100
|
+
* [ ] Add SSG (static site generation).
|
|
109
101
|
* [ ] Add SSR (server side rendering).
|
|
110
102
|
* [ ] Develop tools extension for debugging.
|
|
111
103
|
|
package/lib/call.js
CHANGED
|
@@ -33,22 +33,25 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.
|
|
36
|
+
exports.hintFunctions = exports.styleOnly = exports.composeOnly = exports.boundaryFunctions = exports.modelFunctions = exports.bindFunctions = exports.reactivityFunctions = exports.composeFunctions = void 0;
|
|
37
37
|
exports.calls = calls;
|
|
38
38
|
const t = __importStar(require("@babel/types"));
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"setModel",
|
|
50
|
-
"reactiveObject",
|
|
39
|
+
exports.composeFunctions = [
|
|
40
|
+
"compose",
|
|
41
|
+
"store",
|
|
42
|
+
"model",
|
|
43
|
+
"view",
|
|
44
|
+
"component",
|
|
45
|
+
"page",
|
|
46
|
+
"modal",
|
|
47
|
+
"prompt",
|
|
48
|
+
"screen",
|
|
51
49
|
];
|
|
50
|
+
exports.reactivityFunctions = ["ref", "awaited"];
|
|
51
|
+
exports.bindFunctions = ["watch", "calculate", "bind"];
|
|
52
|
+
exports.modelFunctions = ["arrayModel", "mapModel", "setModel"];
|
|
53
|
+
exports.boundaryFunctions = ["forward", "backward"];
|
|
54
|
+
exports.composeOnly = ["router", "beforeMount", "afterMount", "beforeDestroy"];
|
|
52
55
|
exports.styleOnly = [
|
|
53
56
|
"theme",
|
|
54
57
|
"dark",
|
|
@@ -59,31 +62,39 @@ exports.styleOnly = [
|
|
|
59
62
|
"prefersLight",
|
|
60
63
|
"styleSheet",
|
|
61
64
|
];
|
|
62
|
-
exports.
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
exports.hintFunctions = [
|
|
66
|
+
...exports.reactivityFunctions,
|
|
67
|
+
...exports.composeFunctions,
|
|
68
|
+
...exports.bindFunctions,
|
|
69
|
+
...exports.modelFunctions,
|
|
70
|
+
...exports.composeOnly,
|
|
71
|
+
...exports.styleOnly,
|
|
72
|
+
...exports.boundaryFunctions,
|
|
73
|
+
];
|
|
74
|
+
function checkCall(name, internal) {
|
|
75
|
+
if (name === "store" || name === "model") {
|
|
76
|
+
internal.stateOnly = true;
|
|
77
|
+
}
|
|
78
|
+
else if (exports.composeFunctions.includes(name)) {
|
|
79
|
+
internal.stateOnly = false;
|
|
80
|
+
}
|
|
81
|
+
return name;
|
|
82
|
+
}
|
|
83
|
+
function calls(path, names, internal) {
|
|
84
|
+
const node = path.node;
|
|
65
85
|
const set = new Set(names);
|
|
66
86
|
const callee = t.isCallExpression(node) ? node.callee : null;
|
|
67
87
|
if (callee) {
|
|
68
88
|
if (t.isIdentifier(callee)) {
|
|
69
89
|
const mapped = internal.mapping.get(callee.name);
|
|
70
90
|
if (mapped && set.has(mapped) && internal.stack.get(callee.name) === undefined) {
|
|
71
|
-
|
|
72
|
-
node.arguments.unshift(internal_js_1.ctx);
|
|
73
|
-
}
|
|
74
|
-
if (mapped === "store") {
|
|
75
|
-
internal.stateOnly = true;
|
|
76
|
-
}
|
|
77
|
-
if (mapped === "compose") {
|
|
78
|
-
internal.stateOnly = false;
|
|
79
|
-
}
|
|
80
|
-
return mapped;
|
|
91
|
+
return !!checkCall(mapped, internal);
|
|
81
92
|
}
|
|
82
93
|
return false;
|
|
83
94
|
}
|
|
84
|
-
const global = internal.stack.get(internal.global) === undefined;
|
|
85
95
|
let propName = null;
|
|
86
96
|
if (t.isMemberExpression(callee)) {
|
|
97
|
+
/* istanbul ignore else */
|
|
87
98
|
if (t.isIdentifier(callee.property)) {
|
|
88
99
|
propName = callee.property.name;
|
|
89
100
|
}
|
|
@@ -91,13 +102,13 @@ function calls(node, names, internal) {
|
|
|
91
102
|
propName = callee.property.value;
|
|
92
103
|
}
|
|
93
104
|
}
|
|
94
|
-
if (
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
105
|
+
if (propName &&
|
|
106
|
+
set.has(propName) &&
|
|
107
|
+
t.isMemberExpression(callee) &&
|
|
108
|
+
t.isIdentifier(callee.object) &&
|
|
109
|
+
callee.object.name === internal.global &&
|
|
110
|
+
internal.stack.get(internal.global) === undefined) {
|
|
111
|
+
return !!checkCall(propName, internal);
|
|
101
112
|
}
|
|
102
113
|
}
|
|
103
114
|
return false;
|
package/lib/css-transformer.js
CHANGED
|
@@ -36,40 +36,39 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.findStyleInNode = findStyleInNode;
|
|
37
37
|
const t = __importStar(require("@babel/types"));
|
|
38
38
|
const call_js_1 = require("./call.js");
|
|
39
|
+
const lib_1 = require("./lib");
|
|
39
40
|
function tryProcessProp(path, pseudo, media, internal) {
|
|
40
|
-
if (
|
|
41
|
-
|
|
41
|
+
if (path.isObjectMethod()) {
|
|
42
|
+
return (0, lib_1.err)(lib_1.Errors.TokenNotSupported, path, "Object methods not supported here", internal, []);
|
|
42
43
|
}
|
|
43
|
-
if (
|
|
44
|
-
|
|
44
|
+
if (path.isSpreadElement()) {
|
|
45
|
+
return (0, lib_1.err)(lib_1.Errors.TokenNotSupported, path, "Spread element not supported here", internal, []);
|
|
45
46
|
}
|
|
46
47
|
return processProp(path, pseudo, media, internal);
|
|
47
48
|
}
|
|
48
49
|
const mediaDefaults = ["mobile", "tablet", "laptop", "prefersDark", "prefersLight"];
|
|
49
50
|
function processValue(name, path, pseudo, theme, media, mediaDefault, allowFallback, internal) {
|
|
50
|
-
if ((0, call_js_1.calls)(path
|
|
51
|
+
if ((0, call_js_1.calls)(path, ["theme"], internal)) {
|
|
51
52
|
const call = path.node;
|
|
52
53
|
if (theme) {
|
|
53
|
-
|
|
54
|
+
(0, lib_1.err)(lib_1.Errors.Dilemma, path, "The theme seems the be defined twice", internal, false);
|
|
54
55
|
}
|
|
55
56
|
if (t.isStringLiteral(call.arguments[0])) {
|
|
56
57
|
return processValue(name, path.get("arguments")[1], pseudo, `body.${call.arguments[0].value}`, media, mediaDefault, false, internal);
|
|
57
58
|
}
|
|
58
59
|
else {
|
|
59
|
-
|
|
60
|
-
.get("arguments")[0]
|
|
61
|
-
.buildCodeFrameError("Vasille: Expected string literal");
|
|
60
|
+
return (0, lib_1.err)(lib_1.Errors.TokenNotSupported, path.get("arguments")[0], "Expected string literal", internal, []);
|
|
62
61
|
}
|
|
63
62
|
}
|
|
64
|
-
if ((0, call_js_1.calls)(path
|
|
63
|
+
if ((0, call_js_1.calls)(path, ["dark"], internal)) {
|
|
65
64
|
if (theme) {
|
|
66
|
-
|
|
65
|
+
(0, lib_1.err)(lib_1.Errors.Dilemma, path, "The theme seems the be defined twice", internal);
|
|
67
66
|
}
|
|
68
67
|
return processValue(name, path.get("arguments")[0], pseudo, `.dark`, media, mediaDefault, false, internal);
|
|
69
68
|
}
|
|
70
|
-
|
|
71
|
-
if (
|
|
72
|
-
const index =
|
|
69
|
+
const called = mediaDefaults.map(item => (0, call_js_1.calls)(path, [item], internal));
|
|
70
|
+
if (called.some(v => v)) {
|
|
71
|
+
const index = called.indexOf(true) + 1;
|
|
73
72
|
if (mediaDefault.includes(index)) {
|
|
74
73
|
return processValue(name, path.get("arguments")[0], pseudo, theme, media, mediaDefault, false, internal);
|
|
75
74
|
}
|
|
@@ -96,13 +95,13 @@ function processValue(name, path, pseudo, theme, media, mediaDefault, allowFallb
|
|
|
96
95
|
},
|
|
97
96
|
];
|
|
98
97
|
}
|
|
99
|
-
if (
|
|
98
|
+
if (path.isStringLiteral()) {
|
|
100
99
|
return composeRules(path.node.value);
|
|
101
100
|
}
|
|
102
|
-
if (
|
|
101
|
+
if (path.isNumericLiteral()) {
|
|
103
102
|
return composeRules(`${path.node.value}px`);
|
|
104
103
|
}
|
|
105
|
-
if (
|
|
104
|
+
if (path.isArrayExpression()) {
|
|
106
105
|
if (path.node.elements.every(item => t.isNumericLiteral(item))) {
|
|
107
106
|
return composeRules(path.node.elements.map(item => `${item.value}px`).join(" "));
|
|
108
107
|
}
|
|
@@ -111,21 +110,21 @@ function processValue(name, path, pseudo, theme, media, mediaDefault, allowFallb
|
|
|
111
110
|
...path
|
|
112
111
|
.get("elements")
|
|
113
112
|
.map(path => {
|
|
114
|
-
if (
|
|
113
|
+
if (path.isExpression()) {
|
|
115
114
|
return processValue(name, path, pseudo, theme, media, mediaDefault, false, internal);
|
|
116
115
|
}
|
|
117
116
|
else {
|
|
118
|
-
|
|
117
|
+
return (0, lib_1.err)(lib_1.Errors.TokenNotSupported, path, "Expected expression", internal, []);
|
|
119
118
|
}
|
|
120
119
|
})
|
|
121
120
|
.flat(1),
|
|
122
121
|
];
|
|
123
122
|
}
|
|
124
123
|
else {
|
|
125
|
-
|
|
124
|
+
(0, lib_1.err)(lib_1.Errors.TokenNotSupported, path, "Only numbers arrays are supported here", internal);
|
|
126
125
|
}
|
|
127
126
|
}
|
|
128
|
-
|
|
127
|
+
return (0, lib_1.err)(lib_1.Errors.ParserError, path, "Failed o parse value, it is not a string, number or array", internal, []);
|
|
129
128
|
}
|
|
130
129
|
function processProp(path, pseudo, media, internal) {
|
|
131
130
|
let name;
|
|
@@ -136,14 +135,15 @@ function processProp(path, pseudo, media, internal) {
|
|
|
136
135
|
name = path.node.key.value;
|
|
137
136
|
}
|
|
138
137
|
else {
|
|
139
|
-
|
|
138
|
+
return (0, lib_1.err)(lib_1.Errors.TokenNotSupported, path.get("key"), "Incompatible key, expect identifier or string literal", internal, []);
|
|
140
139
|
}
|
|
140
|
+
const valuePath = path.get("value");
|
|
141
141
|
if (name.startsWith("@")) {
|
|
142
142
|
if (media || pseudo) {
|
|
143
|
-
|
|
143
|
+
return (0, lib_1.err)(lib_1.Errors.TokenNotSupported, path.get("key"), "Media queries allowed only in the root of style", internal, []);
|
|
144
144
|
}
|
|
145
|
-
if (
|
|
146
|
-
return
|
|
145
|
+
if (valuePath.isObjectExpression()) {
|
|
146
|
+
return valuePath
|
|
147
147
|
.get("properties")
|
|
148
148
|
.map(item => {
|
|
149
149
|
return tryProcessProp(item, "", name, internal);
|
|
@@ -151,15 +151,15 @@ function processProp(path, pseudo, media, internal) {
|
|
|
151
151
|
.flat(1);
|
|
152
152
|
}
|
|
153
153
|
else {
|
|
154
|
-
|
|
154
|
+
(0, lib_1.err)(lib_1.Errors.TokenNotSupported, path.get("value"), "Expected object expression", internal, []);
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
if (name.startsWith(":")) {
|
|
158
158
|
if (pseudo) {
|
|
159
|
-
|
|
159
|
+
(0, lib_1.err)(lib_1.Errors.ParserError, path.get("key"), "Recursive pseudo classes are restricted", internal, []);
|
|
160
160
|
}
|
|
161
|
-
if (
|
|
162
|
-
return
|
|
161
|
+
if (valuePath.isObjectExpression()) {
|
|
162
|
+
return valuePath
|
|
163
163
|
.get("properties")
|
|
164
164
|
.map(item => {
|
|
165
165
|
return tryProcessProp(item, name, media, internal);
|
|
@@ -167,43 +167,41 @@ function processProp(path, pseudo, media, internal) {
|
|
|
167
167
|
.flat(1);
|
|
168
168
|
}
|
|
169
169
|
else {
|
|
170
|
-
|
|
170
|
+
(0, lib_1.err)(lib_1.Errors.TokenNotSupported, path.get("value"), "Expected object expression", internal, []);
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
return processValue(name, path.get("value"), pseudo, "", media, [], true, internal);
|
|
174
174
|
}
|
|
175
175
|
function findStyleInNode(path, internal) {
|
|
176
|
-
if (
|
|
176
|
+
if (path.isExportNamedDeclaration()) {
|
|
177
177
|
return findStyleInNode(path.get("declaration"), internal);
|
|
178
178
|
}
|
|
179
|
-
if (
|
|
179
|
+
if (path.isVariableDeclaration() &&
|
|
180
180
|
path.node.declarations.length === 1 &&
|
|
181
|
-
(0, call_js_1.calls)(path.
|
|
181
|
+
(0, call_js_1.calls)(path.get("declarations")[0].get("init"), ["styleSheet"], internal)) {
|
|
182
182
|
const call = path.node.declarations[0].init;
|
|
183
|
-
const callPath = path
|
|
184
|
-
.get("declarations")[0]
|
|
185
|
-
.get("init");
|
|
183
|
+
const callPath = path.get("declarations")[0].get("init");
|
|
186
184
|
const objPath = callPath.get("arguments")[0];
|
|
187
185
|
if (call.arguments.length !== 1) {
|
|
188
|
-
|
|
186
|
+
return (0, lib_1.err)(lib_1.Errors.IncorrectArguments, callPath, "styleSheet function has 1 parameter", internal, true);
|
|
189
187
|
}
|
|
190
188
|
if (!t.isObjectExpression(call.arguments[0])) {
|
|
191
|
-
|
|
189
|
+
return (0, lib_1.err)(lib_1.Errors.TokenNotSupported, objPath, "Expected object expression", internal, true);
|
|
192
190
|
}
|
|
193
191
|
for (const path of objPath.get("properties")) {
|
|
194
|
-
if (!
|
|
195
|
-
|
|
192
|
+
if (!path.isObjectProperty()) {
|
|
193
|
+
return (0, lib_1.err)(lib_1.Errors.TokenNotSupported, path, "Expected object property", internal, true);
|
|
196
194
|
}
|
|
197
|
-
const
|
|
198
|
-
if (!
|
|
199
|
-
|
|
195
|
+
const valuePath = path.get("value");
|
|
196
|
+
if (!valuePath.isObjectExpression()) {
|
|
197
|
+
return (0, lib_1.err)(lib_1.Errors.TokenNotSupported, path, "Expected object expression", internal, true);
|
|
200
198
|
}
|
|
201
|
-
if (!((t.isIdentifier(
|
|
202
|
-
|
|
199
|
+
if (!((t.isIdentifier(path.node.key) && !path.node.computed) || t.isStringLiteral(path.node.key))) {
|
|
200
|
+
return (0, lib_1.err)(lib_1.Errors.TokenNotSupported, path.get("key"), "Expected identifier of string literal", internal, true);
|
|
203
201
|
}
|
|
204
202
|
const unsorted = [];
|
|
205
203
|
const sorted = {};
|
|
206
|
-
for (const path of
|
|
204
|
+
for (const path of valuePath.get("properties")) {
|
|
207
205
|
unsorted.push(...tryProcessProp(path, "", "", internal));
|
|
208
206
|
}
|
|
209
207
|
for (const rule of unsorted) {
|
|
@@ -240,7 +238,7 @@ function findStyleInNode(path, internal) {
|
|
|
240
238
|
}
|
|
241
239
|
}
|
|
242
240
|
}
|
|
243
|
-
|
|
241
|
+
valuePath.replaceWith(t.arrayExpression(expressions));
|
|
244
242
|
}
|
|
245
243
|
return true;
|
|
246
244
|
}
|