@agnos-ui/svelte-preprocess 0.3.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 +65 -0
- package/index.cjs +96 -0
- package/index.d.ts +3 -0
- package/index.js +96 -0
- package/package.json +45 -0
package/README.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# @agnos-ui/svelte-preprocess
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@agnos-ui/svelte-preprocess)
|
|
4
|
+
|
|
5
|
+
Preprocessor to run [Svelte](https://svelte.dev/) [actions](https://svelte.dev/docs/svelte-action) server-side, which are called [directives](https://amadeusitgroup.github.io/AgnosUI/latest/docs/angular/headless/directives) in AgnosUI.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install @agnos-ui/svelte-preprocess
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
Add the `directivesPreprocess()` preprocessor to your `svelte.config.js`:
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
import {directivesPreprocess} from '@agnos-ui/svelte-preprocess';
|
|
19
|
+
|
|
20
|
+
// ...
|
|
21
|
+
|
|
22
|
+
/** @type {import('@sveltejs/kit').Config} */
|
|
23
|
+
const config = {
|
|
24
|
+
// ...
|
|
25
|
+
|
|
26
|
+
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
|
27
|
+
// for more information about preprocessors
|
|
28
|
+
preprocess: [
|
|
29
|
+
// ... existing preprocessors
|
|
30
|
+
|
|
31
|
+
// Add the following line:
|
|
32
|
+
directivesPreprocess(),
|
|
33
|
+
],
|
|
34
|
+
|
|
35
|
+
// ...
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default config;
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Given the following file:
|
|
42
|
+
|
|
43
|
+
```svelte
|
|
44
|
+
<script>
|
|
45
|
+
import {myDirective} from './myDirective';
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<div use:myDirective></div>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The preprocessor will transform it into something like:
|
|
52
|
+
|
|
53
|
+
```svelte
|
|
54
|
+
<script>
|
|
55
|
+
import {ssrAttributes} from '@agnos-ui/svelte-headless/utils/directive';
|
|
56
|
+
import {BROWSER} from 'esm-env';
|
|
57
|
+
import {myDirective} from './myDirective';
|
|
58
|
+
</script>
|
|
59
|
+
|
|
60
|
+
<div use:myDirective {...BROWSER ? {} : ssrAttributes(myDirective)}></div>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
On the server, `ssrAttributes` runs all the provided directives with an [`SSRHTMLElement`](https://github.com/AmadeusITGroup/AgnosUI/blob/ffc1339eb60e02e07d3415efd3f6fac890c8a39d/core/src/types.ts#L94) that implements a subset of the full [`HTMLElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement). The attributes added by the directives on this element are returned by `ssrAttributes` to be included in the SSR-generated markup.
|
|
64
|
+
|
|
65
|
+
If the element has a `class` attribute, the preprocessor will replace it with the `classDirective` directive to make sure the value of the class attribute is correctly merged both on the server and on the client with any other class that may be added by some other directive.
|
package/index.cjs
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const MagicString = require("magic-string");
|
|
4
|
+
const compiler = require("svelte/compiler");
|
|
5
|
+
const directivesPreprocess = () => {
|
|
6
|
+
return {
|
|
7
|
+
name: "AgnosUI",
|
|
8
|
+
markup: async ({ content, filename }) => {
|
|
9
|
+
const varPrefix = "__AgnosUISveltePreprocess__";
|
|
10
|
+
if (content.includes(varPrefix)) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const str = new MagicString(content, { filename });
|
|
14
|
+
const parsedCode = compiler.parse(content, { filename });
|
|
15
|
+
const requiredImports = /* @__PURE__ */ new Set();
|
|
16
|
+
const extractValue = (attribute) => {
|
|
17
|
+
const res = [];
|
|
18
|
+
const value = attribute.value;
|
|
19
|
+
for (const part of value) {
|
|
20
|
+
if (part.type === "Text") {
|
|
21
|
+
res.push(JSON.stringify(part.data));
|
|
22
|
+
} else if (part.type === "MustacheTag") {
|
|
23
|
+
res.push(`(${content.substring(part.expression.start, part.expression.end)})`);
|
|
24
|
+
} else {
|
|
25
|
+
throw new Error(`Unexpected part type: ${part.type}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return res.join("+");
|
|
29
|
+
};
|
|
30
|
+
const processItem = (item) => {
|
|
31
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
32
|
+
const actionAttributes = [];
|
|
33
|
+
const classAttributes = [];
|
|
34
|
+
if (item.attributes) {
|
|
35
|
+
for (const attribute of item.attributes) {
|
|
36
|
+
if (attribute.type === "Action") {
|
|
37
|
+
actionAttributes.push(attribute);
|
|
38
|
+
} else if (attribute.type === "Attribute" && attribute.name === "class") {
|
|
39
|
+
classAttributes.push(attribute);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (actionAttributes.length > 0) {
|
|
43
|
+
const end = item.attributes[item.attributes.length - 1].end;
|
|
44
|
+
let first = true;
|
|
45
|
+
str.appendRight(end, ` {...${varPrefix}BROWSER ? {} : ${varPrefix}ssrAttributes(`);
|
|
46
|
+
requiredImports.add("ssrAttributes");
|
|
47
|
+
for (const attribute of actionAttributes) {
|
|
48
|
+
if (first) {
|
|
49
|
+
first = false;
|
|
50
|
+
} else {
|
|
51
|
+
str.appendRight(end, `, `);
|
|
52
|
+
}
|
|
53
|
+
if (attribute.expression) {
|
|
54
|
+
str.appendRight(end, `[${attribute.name}, ${content.substring(attribute.expression.start, attribute.expression.end)}]`);
|
|
55
|
+
} else {
|
|
56
|
+
str.appendRight(end, attribute.name);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
for (const attribute of classAttributes) {
|
|
60
|
+
const value = extractValue(attribute);
|
|
61
|
+
str.overwrite(attribute.start, attribute.end, `use:${varPrefix}classDirective={${value}}`);
|
|
62
|
+
str.appendRight(end, `, [${varPrefix}classDirective, ${value}]`);
|
|
63
|
+
requiredImports.add("classDirective");
|
|
64
|
+
}
|
|
65
|
+
str.appendRight(end, `)}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
(_a = item.children) == null ? void 0 : _a.forEach(processItem);
|
|
69
|
+
(_c = (_b = item.else) == null ? void 0 : _b.children) == null ? void 0 : _c.forEach(processItem);
|
|
70
|
+
(_e = (_d = item.pending) == null ? void 0 : _d.children) == null ? void 0 : _e.forEach(processItem);
|
|
71
|
+
(_g = (_f = item.then) == null ? void 0 : _f.children) == null ? void 0 : _g.forEach(processItem);
|
|
72
|
+
(_i = (_h = item.catch) == null ? void 0 : _h.children) == null ? void 0 : _i.forEach(processItem);
|
|
73
|
+
};
|
|
74
|
+
processItem(parsedCode.html);
|
|
75
|
+
if (requiredImports.size > 0) {
|
|
76
|
+
const importStatement = `
|
|
77
|
+
import {${[...requiredImports].map((importName) => `${importName} as ${varPrefix}${importName}`).join(", ")}} from '@agnos-ui/svelte-headless/utils/directive';
|
|
78
|
+
import {BROWSER as ${varPrefix}BROWSER} from 'esm-env';
|
|
79
|
+
`;
|
|
80
|
+
const moduleOrInstance = parsedCode.module ?? parsedCode.instance;
|
|
81
|
+
if (moduleOrInstance) {
|
|
82
|
+
const start = content.indexOf(">", moduleOrInstance.start) + 1;
|
|
83
|
+
str.prependLeft(start, importStatement);
|
|
84
|
+
} else {
|
|
85
|
+
str.prepend(`<script>${importStatement}<\/script>
|
|
86
|
+
`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
code: str.toString(),
|
|
91
|
+
map: str.generateMap()
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
exports.directivesPreprocess = directivesPreprocess;
|
package/index.d.ts
ADDED
package/index.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import MagicString from "magic-string";
|
|
2
|
+
import { parse } from "svelte/compiler";
|
|
3
|
+
const directivesPreprocess = () => {
|
|
4
|
+
return {
|
|
5
|
+
name: "AgnosUI",
|
|
6
|
+
markup: async ({ content, filename }) => {
|
|
7
|
+
const varPrefix = "__AgnosUISveltePreprocess__";
|
|
8
|
+
if (content.includes(varPrefix)) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const str = new MagicString(content, { filename });
|
|
12
|
+
const parsedCode = parse(content, { filename });
|
|
13
|
+
const requiredImports = /* @__PURE__ */ new Set();
|
|
14
|
+
const extractValue = (attribute) => {
|
|
15
|
+
const res = [];
|
|
16
|
+
const value = attribute.value;
|
|
17
|
+
for (const part of value) {
|
|
18
|
+
if (part.type === "Text") {
|
|
19
|
+
res.push(JSON.stringify(part.data));
|
|
20
|
+
} else if (part.type === "MustacheTag") {
|
|
21
|
+
res.push(`(${content.substring(part.expression.start, part.expression.end)})`);
|
|
22
|
+
} else {
|
|
23
|
+
throw new Error(`Unexpected part type: ${part.type}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return res.join("+");
|
|
27
|
+
};
|
|
28
|
+
const processItem = (item) => {
|
|
29
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
30
|
+
const actionAttributes = [];
|
|
31
|
+
const classAttributes = [];
|
|
32
|
+
if (item.attributes) {
|
|
33
|
+
for (const attribute of item.attributes) {
|
|
34
|
+
if (attribute.type === "Action") {
|
|
35
|
+
actionAttributes.push(attribute);
|
|
36
|
+
} else if (attribute.type === "Attribute" && attribute.name === "class") {
|
|
37
|
+
classAttributes.push(attribute);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (actionAttributes.length > 0) {
|
|
41
|
+
const end = item.attributes[item.attributes.length - 1].end;
|
|
42
|
+
let first = true;
|
|
43
|
+
str.appendRight(end, ` {...${varPrefix}BROWSER ? {} : ${varPrefix}ssrAttributes(`);
|
|
44
|
+
requiredImports.add("ssrAttributes");
|
|
45
|
+
for (const attribute of actionAttributes) {
|
|
46
|
+
if (first) {
|
|
47
|
+
first = false;
|
|
48
|
+
} else {
|
|
49
|
+
str.appendRight(end, `, `);
|
|
50
|
+
}
|
|
51
|
+
if (attribute.expression) {
|
|
52
|
+
str.appendRight(end, `[${attribute.name}, ${content.substring(attribute.expression.start, attribute.expression.end)}]`);
|
|
53
|
+
} else {
|
|
54
|
+
str.appendRight(end, attribute.name);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
for (const attribute of classAttributes) {
|
|
58
|
+
const value = extractValue(attribute);
|
|
59
|
+
str.overwrite(attribute.start, attribute.end, `use:${varPrefix}classDirective={${value}}`);
|
|
60
|
+
str.appendRight(end, `, [${varPrefix}classDirective, ${value}]`);
|
|
61
|
+
requiredImports.add("classDirective");
|
|
62
|
+
}
|
|
63
|
+
str.appendRight(end, `)}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
(_a = item.children) == null ? void 0 : _a.forEach(processItem);
|
|
67
|
+
(_c = (_b = item.else) == null ? void 0 : _b.children) == null ? void 0 : _c.forEach(processItem);
|
|
68
|
+
(_e = (_d = item.pending) == null ? void 0 : _d.children) == null ? void 0 : _e.forEach(processItem);
|
|
69
|
+
(_g = (_f = item.then) == null ? void 0 : _f.children) == null ? void 0 : _g.forEach(processItem);
|
|
70
|
+
(_i = (_h = item.catch) == null ? void 0 : _h.children) == null ? void 0 : _i.forEach(processItem);
|
|
71
|
+
};
|
|
72
|
+
processItem(parsedCode.html);
|
|
73
|
+
if (requiredImports.size > 0) {
|
|
74
|
+
const importStatement = `
|
|
75
|
+
import {${[...requiredImports].map((importName) => `${importName} as ${varPrefix}${importName}`).join(", ")}} from '@agnos-ui/svelte-headless/utils/directive';
|
|
76
|
+
import {BROWSER as ${varPrefix}BROWSER} from 'esm-env';
|
|
77
|
+
`;
|
|
78
|
+
const moduleOrInstance = parsedCode.module ?? parsedCode.instance;
|
|
79
|
+
if (moduleOrInstance) {
|
|
80
|
+
const start = content.indexOf(">", moduleOrInstance.start) + 1;
|
|
81
|
+
str.prependLeft(start, importStatement);
|
|
82
|
+
} else {
|
|
83
|
+
str.prepend(`<script>${importStatement}<\/script>
|
|
84
|
+
`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
code: str.toString(),
|
|
89
|
+
map: str.generateMap()
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
export {
|
|
95
|
+
directivesPreprocess
|
|
96
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agnos-ui/svelte-preprocess",
|
|
3
|
+
"description": "Preprocessor to run Svelte directives server-side.",
|
|
4
|
+
"version": "0.3.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./index.cjs",
|
|
7
|
+
"module": "./index.js",
|
|
8
|
+
"types": "./index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./index.d.ts",
|
|
12
|
+
"require": "./index.cjs",
|
|
13
|
+
"default": "./index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"magic-string": "^0.30.10"
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"svelte": "*"
|
|
21
|
+
},
|
|
22
|
+
"sideEffects": false,
|
|
23
|
+
"homepage": "https://amadeusitgroup.github.io/AgnosUI/latest/",
|
|
24
|
+
"bugs": "https://github.com/AmadeusITGroup/AgnosUI/issues",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/AmadeusITGroup/AgnosUI.git",
|
|
29
|
+
"directory": "svelte/preprocess"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"svelte",
|
|
33
|
+
"AgnosUI",
|
|
34
|
+
"accordion",
|
|
35
|
+
"alert",
|
|
36
|
+
"components",
|
|
37
|
+
"modal",
|
|
38
|
+
"pagination",
|
|
39
|
+
"progressbar",
|
|
40
|
+
"rating",
|
|
41
|
+
"slider",
|
|
42
|
+
"toast",
|
|
43
|
+
"widgets"
|
|
44
|
+
]
|
|
45
|
+
}
|