babel-plugin-vasille 0.99.2 → 0.99.3
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 +2 -2
- package/lib/call.js +26 -39
- package/lib/css-transformer.js +206 -0
- package/lib/expression.js +13 -48
- package/lib/index.js +3 -6
- package/lib/internal.js +3 -30
- package/lib/jsx-detect.js +4 -32
- package/lib/jsx.js +30 -57
- package/lib/lib.js +31 -65
- package/lib/mesh.js +73 -112
- package/lib/transformer.js +47 -32
- package/lib-node/call.js +19 -5
- package/lib-node/css-transformer.js +232 -0
- package/lib-node/mesh.js +11 -8
- package/lib-node/transformer.js +42 -1
- package/package.json +8 -7
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.findStyleInNode = findStyleInNode;
|
|
27
|
+
const t = __importStar(require("@babel/types"));
|
|
28
|
+
const call_1 = require("./call");
|
|
29
|
+
function tryProcessProp(path, pseudo, media, internal) {
|
|
30
|
+
if (t.isObjectMethod(path.node)) {
|
|
31
|
+
throw path.buildCodeFrameError("Object methods not supported here");
|
|
32
|
+
}
|
|
33
|
+
if (t.isSpreadElement(path.node)) {
|
|
34
|
+
throw path.buildCodeFrameError("Spread element not suppored here");
|
|
35
|
+
}
|
|
36
|
+
return processProp(path, pseudo, media, internal);
|
|
37
|
+
}
|
|
38
|
+
const mediaDefaults = ["mobile", "tablet", "laptop", "prefersDark", "prefersLight"];
|
|
39
|
+
function processValue(name, path, pseudo, theme, media, mediaDefault, allowFallback, internal) {
|
|
40
|
+
if ((0, call_1.calls)(path.node, ["theme"], internal)) {
|
|
41
|
+
const call = path.node;
|
|
42
|
+
if (theme) {
|
|
43
|
+
throw path.buildCodeFrameError("Vasille: Theme seem the be defined twince");
|
|
44
|
+
}
|
|
45
|
+
if (t.isStringLiteral(call.arguments[0])) {
|
|
46
|
+
return processValue(name, path.get("arguments")[1], pseudo, `body.${call.arguments[0].value}`, media, mediaDefault, false, internal);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
throw path
|
|
50
|
+
.get("arguments")[0]
|
|
51
|
+
.buildCodeFrameError("Vasille: Expected string literal");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if ((0, call_1.calls)(path.node, ["dark"], internal)) {
|
|
55
|
+
if (theme) {
|
|
56
|
+
throw path.buildCodeFrameError("Vasille: Theme seem the be defined twince");
|
|
57
|
+
}
|
|
58
|
+
return processValue(name, path.get("arguments")[0], pseudo, `.dark`, media, mediaDefault, false, internal);
|
|
59
|
+
}
|
|
60
|
+
let callee;
|
|
61
|
+
if ((callee = (0, call_1.calls)(path.node, mediaDefaults, internal))) {
|
|
62
|
+
const index = mediaDefaults.indexOf(callee) + 1;
|
|
63
|
+
if (mediaDefault.includes(index)) {
|
|
64
|
+
return processValue(name, path.get("arguments")[0], pseudo, theme, media, mediaDefault, false, internal);
|
|
65
|
+
}
|
|
66
|
+
return processValue(name, path.get("arguments")[0], pseudo, theme, media, [...mediaDefault, index], false, internal);
|
|
67
|
+
}
|
|
68
|
+
function composeRules(value) {
|
|
69
|
+
return mediaDefault.length
|
|
70
|
+
? mediaDefault.map(index => {
|
|
71
|
+
return {
|
|
72
|
+
defaultMediaRule: index,
|
|
73
|
+
mediaRule: media,
|
|
74
|
+
pseudo: pseudo,
|
|
75
|
+
theme: theme,
|
|
76
|
+
rule: `${name}:${value}`,
|
|
77
|
+
};
|
|
78
|
+
})
|
|
79
|
+
: [
|
|
80
|
+
{
|
|
81
|
+
defaultMediaRule: 0,
|
|
82
|
+
mediaRule: media,
|
|
83
|
+
pseudo: pseudo,
|
|
84
|
+
theme: theme,
|
|
85
|
+
rule: `${name}:${value}`,
|
|
86
|
+
},
|
|
87
|
+
];
|
|
88
|
+
}
|
|
89
|
+
if (t.isStringLiteral(path.node)) {
|
|
90
|
+
return composeRules(path.node.value);
|
|
91
|
+
}
|
|
92
|
+
if (t.isNumericLiteral(path.node)) {
|
|
93
|
+
return composeRules(`${path.node.value}px`);
|
|
94
|
+
}
|
|
95
|
+
if (t.isArrayExpression(path.node)) {
|
|
96
|
+
if (path.node.elements.every(item => t.isNumericLiteral(item))) {
|
|
97
|
+
return composeRules(path.node.elements.map(item => `${item.value}px`).join(" "));
|
|
98
|
+
}
|
|
99
|
+
else if (allowFallback) {
|
|
100
|
+
return [
|
|
101
|
+
...path.get("elements").map(path => {
|
|
102
|
+
if (t.isExpression(path.node)) {
|
|
103
|
+
return processValue(name, path, pseudo, theme, media, mediaDefault, false, internal);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
throw path.buildCodeFrameError("Vasille: Exprected expression");
|
|
107
|
+
}
|
|
108
|
+
}).flat(1),
|
|
109
|
+
];
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
throw path.buildCodeFrameError("Vasille: Only numbers arrays are suppored here");
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
throw path.buildCodeFrameError("Vasille: Failed o parse value, it is not a string, number or array");
|
|
116
|
+
}
|
|
117
|
+
function processProp(path, pseudo, media, internal) {
|
|
118
|
+
let name;
|
|
119
|
+
if (t.isIdentifier(path.node.key)) {
|
|
120
|
+
name = path.node.key.name;
|
|
121
|
+
}
|
|
122
|
+
else if (t.isStringLiteral(path.node.key)) {
|
|
123
|
+
name = path.node.key.value;
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
throw path.get("key").buildCodeFrameError("Vasille: Incompaible key, exprect idenifier or string literal");
|
|
127
|
+
}
|
|
128
|
+
if (name.startsWith("@")) {
|
|
129
|
+
if (media || pseudo) {
|
|
130
|
+
throw path.get("key").buildCodeFrameError("Vasille: Media queries allowed inly in the root of style");
|
|
131
|
+
}
|
|
132
|
+
if (t.isObjectExpression(path.node.value)) {
|
|
133
|
+
return path.get("value").get("properties").map(item => {
|
|
134
|
+
return tryProcessProp(item, "", name, internal);
|
|
135
|
+
}).flat(1);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
throw path.get("value").buildCodeFrameError("Vasille: Exprected object expression");
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (name.startsWith(":")) {
|
|
142
|
+
if (pseudo) {
|
|
143
|
+
throw path.get("key").buildCodeFrameError("Recursive pseudo classes are restriced");
|
|
144
|
+
}
|
|
145
|
+
if (t.isObjectExpression(path.node.value)) {
|
|
146
|
+
return path.get("value").get("properties").map(item => {
|
|
147
|
+
return tryProcessProp(item, name, media, internal);
|
|
148
|
+
}).flat(1);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
throw path.get("value").buildCodeFrameError("Vasille: Exprected object expression");
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return processValue(name, path.get("value"), pseudo, "", media, [], true, internal);
|
|
155
|
+
}
|
|
156
|
+
function findStyleInNode(path, internal) {
|
|
157
|
+
if (t.isExpressionStatement(path.node)) {
|
|
158
|
+
return findStyleInNode(path.get("expression"), internal);
|
|
159
|
+
}
|
|
160
|
+
if (t.isExportNamedDeclaration(path.node)) {
|
|
161
|
+
return findStyleInNode(path.get("declaration"), internal);
|
|
162
|
+
}
|
|
163
|
+
if (t.isVariableDeclaration(path.node) &&
|
|
164
|
+
path.node.declarations.length === 1 &&
|
|
165
|
+
(0, call_1.calls)(path.node.declarations[0].init, ["webStyleSheet"], internal)) {
|
|
166
|
+
const call = path.node.declarations[0].init;
|
|
167
|
+
const callPath = path
|
|
168
|
+
.get("declarations")[0]
|
|
169
|
+
.get("init");
|
|
170
|
+
const objPath = callPath.get("arguments")[0];
|
|
171
|
+
if (call.arguments.length !== 1) {
|
|
172
|
+
throw callPath.buildCodeFrameError("Vasille: webStyleSheet function has 1 parameter");
|
|
173
|
+
}
|
|
174
|
+
if (!t.isObjectExpression(call.arguments[0])) {
|
|
175
|
+
throw objPath.buildCodeFrameError("Vasille: expected object expression");
|
|
176
|
+
}
|
|
177
|
+
for (const path of objPath.get("properties")) {
|
|
178
|
+
if (!t.isObjectProperty(path.node)) {
|
|
179
|
+
throw path.buildCodeFrameError("Vasille: Expected object property");
|
|
180
|
+
}
|
|
181
|
+
const prop = path;
|
|
182
|
+
if (!t.isObjectExpression(prop.node.value)) {
|
|
183
|
+
throw prop.get("value").buildCodeFrameError("Vasille: Exprected object expression");
|
|
184
|
+
}
|
|
185
|
+
if (!(t.isIdentifier(prop.node.key) || t.isStringLiteral(prop.node.key))) {
|
|
186
|
+
throw prop.get("key").buildCodeFrameError("Vasille: Expected identifier of string literal");
|
|
187
|
+
}
|
|
188
|
+
const unsorted = [];
|
|
189
|
+
const sorted = {};
|
|
190
|
+
for (const path of prop.get("value").get("properties")) {
|
|
191
|
+
unsorted.push(...tryProcessProp(path, "", "", internal));
|
|
192
|
+
}
|
|
193
|
+
for (const rule of unsorted) {
|
|
194
|
+
if (!sorted[rule.defaultMediaRule]) {
|
|
195
|
+
sorted[rule.defaultMediaRule] = {};
|
|
196
|
+
}
|
|
197
|
+
const defaultMediaRule = sorted[rule.defaultMediaRule];
|
|
198
|
+
if (!defaultMediaRule[rule.mediaRule]) {
|
|
199
|
+
defaultMediaRule[rule.mediaRule] = {};
|
|
200
|
+
}
|
|
201
|
+
const mediaRule = defaultMediaRule[rule.mediaRule];
|
|
202
|
+
if (!mediaRule[rule.theme]) {
|
|
203
|
+
mediaRule[rule.theme] = {};
|
|
204
|
+
}
|
|
205
|
+
const theme = mediaRule[rule.theme];
|
|
206
|
+
if (!theme[rule.pseudo]) {
|
|
207
|
+
theme[rule.pseudo] = [];
|
|
208
|
+
}
|
|
209
|
+
theme[rule.pseudo].push(rule.rule);
|
|
210
|
+
}
|
|
211
|
+
const expressions = [];
|
|
212
|
+
for (const defaultMediaRule in sorted) {
|
|
213
|
+
for (const mediaRule in sorted[defaultMediaRule]) {
|
|
214
|
+
for (const theme in sorted[defaultMediaRule][mediaRule]) {
|
|
215
|
+
for (const pseudo in sorted[defaultMediaRule][mediaRule][theme]) {
|
|
216
|
+
const rulePack = sorted[defaultMediaRule][mediaRule][theme][pseudo].join(";");
|
|
217
|
+
const pseudoPack = pseudo ? `{}${pseudo}{${rulePack}}` : `{}{${rulePack}}`;
|
|
218
|
+
const themePack = theme ? `${theme} ${pseudoPack}` : pseudoPack;
|
|
219
|
+
const mediaRulePack = t.stringLiteral(mediaRule ? `${mediaRule}{${themePack}}` : themePack);
|
|
220
|
+
expressions.push(defaultMediaRule !== '0'
|
|
221
|
+
? t.arrayExpression([t.numericLiteral(parseInt(defaultMediaRule)), mediaRulePack])
|
|
222
|
+
: mediaRulePack);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
prop.get("value").replaceWith(t.arrayExpression(expressions));
|
|
228
|
+
}
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
return false;
|
|
232
|
+
}
|
package/lib-node/mesh.js
CHANGED
|
@@ -139,11 +139,20 @@ function meshExpression(nodePath, internal) {
|
|
|
139
139
|
meshAllUnknown(path.get("elements"), internal);
|
|
140
140
|
break;
|
|
141
141
|
}
|
|
142
|
-
case "CallExpression":
|
|
142
|
+
case "CallExpression":
|
|
143
|
+
case "OptionalCallExpression": {
|
|
143
144
|
const path = nodePath;
|
|
144
145
|
const callsFn = (0, call_1.calls)(path.node, call_1.composeOnly, internal);
|
|
146
|
+
const callsStyleHint = (0, call_1.calls)(path.node, call_1.styleOnly, internal);
|
|
147
|
+
const callsStyleCreate = (0, call_1.calls)(path.node, ["webStyleSheet"], internal);
|
|
145
148
|
if (callsFn) {
|
|
146
|
-
throw path.buildCodeFrameError(`Vasille: Usage of
|
|
149
|
+
throw path.buildCodeFrameError(`Vasille: Usage of hint "${callsFn}" is restricted here`);
|
|
150
|
+
}
|
|
151
|
+
if (callsStyleHint) {
|
|
152
|
+
throw path.buildCodeFrameError(`Vasille: Usage of style hint "${callsStyleHint}" is restricted here`);
|
|
153
|
+
}
|
|
154
|
+
if (callsStyleCreate) {
|
|
155
|
+
throw path.buildCodeFrameError("Vasille: Styles can be created in moldule level code only");
|
|
147
156
|
}
|
|
148
157
|
meshOrIgnoreExpression(path.get("callee"), internal);
|
|
149
158
|
meshAllUnknown(path.get("arguments"), internal);
|
|
@@ -155,12 +164,6 @@ function meshExpression(nodePath, internal) {
|
|
|
155
164
|
}
|
|
156
165
|
break;
|
|
157
166
|
}
|
|
158
|
-
case "OptionalCallExpression": {
|
|
159
|
-
const path = nodePath;
|
|
160
|
-
meshExpression(path.get("callee"), internal);
|
|
161
|
-
meshAllUnknown(path.get("arguments"), internal);
|
|
162
|
-
break;
|
|
163
|
-
}
|
|
164
167
|
case "AssignmentExpression": {
|
|
165
168
|
const path = nodePath;
|
|
166
169
|
const left = path.node.left;
|
package/lib-node/transformer.js
CHANGED
|
@@ -27,6 +27,7 @@ exports.trProgram = trProgram;
|
|
|
27
27
|
const t = __importStar(require("@babel/types"));
|
|
28
28
|
const internal_1 = require("./internal");
|
|
29
29
|
const mesh_1 = require("./mesh");
|
|
30
|
+
const css_transformer_1 = require("./css-transformer");
|
|
30
31
|
const imports = new Map([
|
|
31
32
|
["vasille-dx", "VasilleDX"],
|
|
32
33
|
["vasille-web", "VasilleWeb"],
|
|
@@ -41,12 +42,20 @@ const ignoreMembers = new Set([
|
|
|
41
42
|
"mapModel",
|
|
42
43
|
"reactiveObject",
|
|
43
44
|
"setModel",
|
|
45
|
+
"theme",
|
|
46
|
+
"dark",
|
|
47
|
+
"mobile",
|
|
48
|
+
"tablet",
|
|
49
|
+
"laptop",
|
|
50
|
+
"prefersDark",
|
|
51
|
+
"prefersLight",
|
|
44
52
|
]);
|
|
45
53
|
function extractText(node) {
|
|
46
54
|
return t.isIdentifier(node) ? node.name : node.value;
|
|
47
55
|
}
|
|
48
56
|
function trProgram(path, devMode) {
|
|
49
57
|
let id;
|
|
58
|
+
let stylesConnected = false;
|
|
50
59
|
const internal = {
|
|
51
60
|
get id() {
|
|
52
61
|
this.internalUsed = true;
|
|
@@ -58,6 +67,7 @@ function trProgram(path, devMode) {
|
|
|
58
67
|
stack: new internal_1.StackedStates(),
|
|
59
68
|
mapping: new Map(),
|
|
60
69
|
global: "",
|
|
70
|
+
cssGlobal: "",
|
|
61
71
|
prefix: "Vasille_",
|
|
62
72
|
importStatement: null,
|
|
63
73
|
internalUsed: false,
|
|
@@ -72,12 +82,19 @@ function trProgram(path, devMode) {
|
|
|
72
82
|
for (const specifier of statement.specifiers) {
|
|
73
83
|
if (t.isImportNamespaceSpecifier(specifier)) {
|
|
74
84
|
internal.global = specifier.local.name;
|
|
85
|
+
if (statement.source.value === "vasille-web") {
|
|
86
|
+
internal.cssGlobal = internal.global;
|
|
87
|
+
stylesConnected = true;
|
|
88
|
+
}
|
|
75
89
|
id = t.memberExpression(t.identifier(internal.global), t.identifier("$"));
|
|
76
90
|
}
|
|
77
91
|
else if (t.isImportSpecifier(specifier)) {
|
|
78
92
|
const imported = extractText(specifier.imported);
|
|
79
93
|
const local = specifier.local.name;
|
|
80
94
|
internal.mapping.set(local, imported);
|
|
95
|
+
if (imported === "webStyleSheet") {
|
|
96
|
+
stylesConnected = true;
|
|
97
|
+
}
|
|
81
98
|
if (!id) {
|
|
82
99
|
id = t.identifier(name);
|
|
83
100
|
}
|
|
@@ -93,12 +110,36 @@ function trProgram(path, devMode) {
|
|
|
93
110
|
}
|
|
94
111
|
});
|
|
95
112
|
}
|
|
113
|
+
else if (statement.source.value === "vasille-css") {
|
|
114
|
+
for (const specifier of statement.specifiers) {
|
|
115
|
+
if (t.isImportSpecifier(specifier)) {
|
|
116
|
+
internal.mapping.set(specifier.local.name, extractText(specifier.imported));
|
|
117
|
+
}
|
|
118
|
+
else if (t.isImportNamespaceSpecifier(specifier)) {
|
|
119
|
+
internal.cssGlobal = specifier.local.name;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
statement.specifiers = statement.specifiers.filter(spec => {
|
|
123
|
+
if (!t.isImportSpecifier(spec)) {
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
return !ignoreMembers.has(extractText(spec.imported));
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
stylesConnected = true;
|
|
131
|
+
}
|
|
96
132
|
}
|
|
97
133
|
else {
|
|
98
134
|
if (!id) {
|
|
135
|
+
if (stylesConnected) {
|
|
136
|
+
(0, css_transformer_1.findStyleInNode)(statementPath, internal);
|
|
137
|
+
}
|
|
99
138
|
return;
|
|
100
139
|
}
|
|
101
|
-
(0,
|
|
140
|
+
if (!stylesConnected || !(0, css_transformer_1.findStyleInNode)(statementPath, internal)) {
|
|
141
|
+
(0, mesh_1.meshStatement)(statementPath, internal);
|
|
142
|
+
}
|
|
102
143
|
}
|
|
103
144
|
}
|
|
104
145
|
if (internal.internalUsed && !internal.global && internal.importStatement) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "babel-plugin-vasille",
|
|
3
|
-
"version": "0.99.
|
|
4
|
-
"description": "",
|
|
3
|
+
"version": "0.99.3",
|
|
4
|
+
"description": "Convert Vasille Meta Language code to pure JavaScript",
|
|
5
5
|
"main": "lib-node/index.js",
|
|
6
6
|
"type": "commonjs",
|
|
7
7
|
"exports": {
|
|
@@ -21,7 +21,9 @@
|
|
|
21
21
|
"keywords": [
|
|
22
22
|
"front-end",
|
|
23
23
|
"framework",
|
|
24
|
-
"
|
|
24
|
+
"web",
|
|
25
|
+
"compiler",
|
|
26
|
+
"babel"
|
|
25
27
|
],
|
|
26
28
|
"author": "lixcode",
|
|
27
29
|
"license": "MIT",
|
|
@@ -29,9 +31,6 @@
|
|
|
29
31
|
"url": "https://github.com/vasille-js/vasille-js/issues"
|
|
30
32
|
},
|
|
31
33
|
"homepage": "https://github.com/vasille-js/vasille-js#readme",
|
|
32
|
-
"dependencies": {
|
|
33
|
-
"vasille-dx": "^3.0.3"
|
|
34
|
-
},
|
|
35
34
|
"devDependencies": {
|
|
36
35
|
"@babel/parser": "^7.26.1",
|
|
37
36
|
"@babel/plugin-syntax-jsx": "^7.25.9",
|
|
@@ -46,6 +45,8 @@
|
|
|
46
45
|
"path": "^0.12.7",
|
|
47
46
|
"prettier": "^3.3.3",
|
|
48
47
|
"ts-jest": "^29.2.5",
|
|
49
|
-
"typescript": "^5.6.3"
|
|
48
|
+
"typescript": "^5.6.3",
|
|
49
|
+
"vasille-css": "^3.0.3",
|
|
50
|
+
"vasille-dx": "^3.0.3"
|
|
50
51
|
}
|
|
51
52
|
}
|