sveld 0.10.1 → 0.12.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/CHANGELOG.md +16 -0
- package/README.md +36 -5
- package/lib/ComponentParser.d.ts +3 -0
- package/lib/ComponentParser.js +42 -14
- package/lib/path.d.ts +6 -0
- package/lib/path.js +13 -0
- package/lib/rollup-plugin.js +2 -4
- package/lib/writer/writer-json.js +2 -1
- package/lib/writer/writer-ts-definitions.js +12 -2
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
10
10
|
- add isAccessor field to API
|
|
11
11
|
- update Markdown writer to generate a separate table for accessors
|
|
12
12
|
|
|
13
|
+
## [0.12.0](https://github.com/carbon-design-system/sveld/releases/tag/v0.12.0) - 2022-01-02
|
|
14
|
+
|
|
15
|
+
- support props defined via renamed exports (i.e.m `let className; export { className as class }`)
|
|
16
|
+
|
|
17
|
+
## [0.11.1](https://github.com/carbon-design-system/sveld/releases/tag/v0.11.1) - 2021-12-31
|
|
18
|
+
|
|
19
|
+
- replace backslashes with forward slashes in COMPONENT_API.json `filePath` values
|
|
20
|
+
|
|
21
|
+
## [0.11.0](https://github.com/carbon-design-system/sveld/releases/tag/v0.11.0) - 2021-12-16
|
|
22
|
+
|
|
23
|
+
- support writing `<!-- @component -->` comments in Svelte components to TypeScript definitions
|
|
24
|
+
|
|
25
|
+
## [0.10.2](https://github.com/carbon-design-system/sveld/releases/tag/v0.10.2) - 2021-08-29
|
|
26
|
+
|
|
27
|
+
- tolerate slot spread syntax (`<slot {...props} />`) when parsing Svelte components
|
|
28
|
+
|
|
13
29
|
## [0.10.1](https://github.com/carbon-design-system/sveld/releases/tag/v0.10.1) - 2021-08-28
|
|
14
30
|
|
|
15
31
|
- include `.svelte` extension in `index.d.ts` exports
|
package/README.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# sveld
|
|
2
2
|
|
|
3
3
|
[![NPM][npm]][npm-url]
|
|
4
|
-
|
|
4
|
+

|
|
5
|
+

|
|
5
6
|
|
|
6
7
|
`sveld` generates TypeScript definitions for Svelte components by statically analyzing their props, events, slots and more. Prop types and signatures can be defined using [JSDoc notation](https://jsdoc.app/). This documentation generator can also emit component documentation in Markdown and JSON output formats.
|
|
7
8
|
|
|
@@ -13,7 +14,7 @@ The purpose of this project is to make third party Svelte component libraries co
|
|
|
13
14
|
- [Component Index](https://github.com/IBM/carbon-components-svelte/blob/master/COMPONENT_INDEX.md): Markdown file documenting component props, slots, and events
|
|
14
15
|
- [Component API](https://github.com/IBM/carbon-components-svelte/blob/master/docs/src/COMPONENT_API.json): Component API metadata in JSON format
|
|
15
16
|
|
|
16
|
-
**Please note** that the generated TypeScript definitions require [Svelte version 3.31](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md#
|
|
17
|
+
**Please note** that the generated TypeScript definitions require [Svelte version 3.31](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md#3310) or greater.
|
|
17
18
|
|
|
18
19
|
---
|
|
19
20
|
|
|
@@ -399,13 +400,45 @@ Signature:
|
|
|
399
400
|
Example:
|
|
400
401
|
|
|
401
402
|
```js
|
|
402
|
-
/** @extends {"./Button"} ButtonProps */
|
|
403
|
+
/** @extends {"./Button.svelte"} ButtonProps */
|
|
403
404
|
|
|
404
405
|
export const secondary = true;
|
|
405
406
|
|
|
406
407
|
import Button from "./Button.svelte";
|
|
407
408
|
```
|
|
408
409
|
|
|
410
|
+
### `@component` comments
|
|
411
|
+
|
|
412
|
+
The Svelte Language Server supports component-level comments through the following syntax: `<!-- @component [comment] -->`.
|
|
413
|
+
|
|
414
|
+
`sveld` will copy these over to the exported default component in the TypeScript definition.
|
|
415
|
+
|
|
416
|
+
Example:
|
|
417
|
+
|
|
418
|
+
```svelte
|
|
419
|
+
<!-- @component
|
|
420
|
+
@example
|
|
421
|
+
<Button>
|
|
422
|
+
Text
|
|
423
|
+
</Button>
|
|
424
|
+
-->
|
|
425
|
+
<button>
|
|
426
|
+
<slot />
|
|
427
|
+
</button>
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
Output:
|
|
431
|
+
|
|
432
|
+
```ts
|
|
433
|
+
/**
|
|
434
|
+
* @example
|
|
435
|
+
* <Button>
|
|
436
|
+
* Text
|
|
437
|
+
* </Button>
|
|
438
|
+
*/
|
|
439
|
+
export default class Button extends SvelteComponentTyped<ButtonProps, {}, { default: {} }> {}
|
|
440
|
+
```
|
|
441
|
+
|
|
409
442
|
## Contributing
|
|
410
443
|
|
|
411
444
|
Refer to the [contributing guidelines](CONTRIBUTING.md).
|
|
@@ -416,5 +449,3 @@ Refer to the [contributing guidelines](CONTRIBUTING.md).
|
|
|
416
449
|
|
|
417
450
|
[npm]: https://img.shields.io/npm/v/sveld.svg?color=262626&style=for-the-badge
|
|
418
451
|
[npm-url]: https://npmjs.com/package/sveld
|
|
419
|
-
[build]: https://img.shields.io/travis/com/ibm/sveld?color=24a148&style=for-the-badge
|
|
420
|
-
[build-badge]: https://travis-ci.com/ibm/sveld
|
package/lib/ComponentParser.d.ts
CHANGED
|
@@ -58,6 +58,7 @@ export interface ParsedComponent {
|
|
|
58
58
|
typedefs: TypeDef[];
|
|
59
59
|
rest_props: RestProps;
|
|
60
60
|
extends?: Extends;
|
|
61
|
+
componentComment?: string;
|
|
61
62
|
}
|
|
62
63
|
export default class ComponentParser {
|
|
63
64
|
private options?;
|
|
@@ -65,7 +66,9 @@ export default class ComponentParser {
|
|
|
65
66
|
private compiled?;
|
|
66
67
|
private rest_props?;
|
|
67
68
|
private extends?;
|
|
69
|
+
private componentComment?;
|
|
68
70
|
private readonly reactive_vars;
|
|
71
|
+
private readonly vars;
|
|
69
72
|
private readonly props;
|
|
70
73
|
private readonly slots;
|
|
71
74
|
private readonly events;
|
package/lib/ComponentParser.js
CHANGED
|
@@ -27,6 +27,7 @@ var DEFAULT_SLOT_NAME = "__default__";
|
|
|
27
27
|
var ComponentParser = /** @class */ (function () {
|
|
28
28
|
function ComponentParser(options) {
|
|
29
29
|
this.reactive_vars = new Set();
|
|
30
|
+
this.vars = new Set();
|
|
30
31
|
this.props = new Map();
|
|
31
32
|
this.slots = new Map();
|
|
32
33
|
this.events = new Map();
|
|
@@ -160,6 +161,7 @@ var ComponentParser = /** @class */ (function () {
|
|
|
160
161
|
this.compiled = undefined;
|
|
161
162
|
this.rest_props = undefined;
|
|
162
163
|
this["extends"] = undefined;
|
|
164
|
+
this.componentComment = undefined;
|
|
163
165
|
this.reactive_vars.clear();
|
|
164
166
|
this.props.clear();
|
|
165
167
|
this.slots.clear();
|
|
@@ -182,7 +184,7 @@ var ComponentParser = /** @class */ (function () {
|
|
|
182
184
|
var callees = [];
|
|
183
185
|
(0, compiler_1.walk)(this.compiled.ast, {
|
|
184
186
|
enter: function (node, parent, prop) {
|
|
185
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
187
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
186
188
|
if (node.type === "CallExpression") {
|
|
187
189
|
if (node.callee.name === "createEventDispatcher") {
|
|
188
190
|
dispatcher_name = parent === null || parent === void 0 ? void 0 : parent.id.name;
|
|
@@ -200,11 +202,28 @@ var ComponentParser = /** @class */ (function () {
|
|
|
200
202
|
};
|
|
201
203
|
}
|
|
202
204
|
}
|
|
203
|
-
if (node.type === "
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
205
|
+
if (node.type === "VariableDeclaration") {
|
|
206
|
+
_this.vars.add(node);
|
|
207
|
+
}
|
|
208
|
+
if (node.type === "ExportNamedDeclaration") {
|
|
209
|
+
// Handle renamed exports
|
|
210
|
+
var prop_name = void 0;
|
|
211
|
+
if (node.declaration == null && ((_a = node.specifiers[0]) === null || _a === void 0 ? void 0 : _a.type) === "ExportSpecifier") {
|
|
212
|
+
var specifier = node.specifiers[0];
|
|
213
|
+
var localName_1 = specifier.local.name, exportedName = specifier.exported.name;
|
|
214
|
+
var declaration_1;
|
|
215
|
+
// Search through all variable declarations for this variable
|
|
216
|
+
// Limitation: the variable must have been declared before the export
|
|
217
|
+
_this.vars.forEach(function (varDecl) {
|
|
218
|
+
if (varDecl.declarations.some(function (decl) { return decl.id.type === "Identifier" && decl.id.name === localName_1; })) {
|
|
219
|
+
declaration_1 = varDecl;
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
node.declaration = declaration_1;
|
|
223
|
+
prop_name = exportedName;
|
|
224
|
+
}
|
|
225
|
+
var _m = node.declaration.declarations ? node.declaration.declarations[0] : node.declaration, declaration_type = _m.type, id = _m.id, init = _m.init, body = _m.body;
|
|
226
|
+
prop_name !== null && prop_name !== void 0 ? prop_name : (prop_name = id.name);
|
|
208
227
|
var value = undefined;
|
|
209
228
|
var type = undefined;
|
|
210
229
|
var kind = node.declaration.kind;
|
|
@@ -216,7 +235,7 @@ var ComponentParser = /** @class */ (function () {
|
|
|
216
235
|
init.type === "BinaryExpression" ||
|
|
217
236
|
init.type === "ArrayExpression" ||
|
|
218
237
|
init.type === "ArrowFunctionExpression") {
|
|
219
|
-
value = (
|
|
238
|
+
value = (_b = _this.sourceAtPos(init.start, init.end)) === null || _b === void 0 ? void 0 : _b.replace(/\n/g, " ");
|
|
220
239
|
type = value;
|
|
221
240
|
isFunction = init.type === "ArrowFunctionExpression";
|
|
222
241
|
if (init.type === "BinaryExpression") {
|
|
@@ -228,7 +247,7 @@ var ComponentParser = /** @class */ (function () {
|
|
|
228
247
|
else {
|
|
229
248
|
if (init.type === "UnaryExpression") {
|
|
230
249
|
value = _this.sourceAtPos(init.start, init.end);
|
|
231
|
-
type = typeof ((
|
|
250
|
+
type = typeof ((_c = init.argument) === null || _c === void 0 ? void 0 : _c.value);
|
|
232
251
|
}
|
|
233
252
|
else {
|
|
234
253
|
value = init.raw;
|
|
@@ -237,7 +256,7 @@ var ComponentParser = /** @class */ (function () {
|
|
|
237
256
|
}
|
|
238
257
|
}
|
|
239
258
|
if (declaration_type === "FunctionDeclaration") {
|
|
240
|
-
value = "() => " + ((
|
|
259
|
+
value = "() => " + ((_d = _this.sourceAtPos(body.start, body.end)) === null || _d === void 0 ? void 0 : _d.replace(/\n/g, " "));
|
|
241
260
|
type = "() => any";
|
|
242
261
|
kind = "function";
|
|
243
262
|
isFunction = true;
|
|
@@ -246,10 +265,10 @@ var ComponentParser = /** @class */ (function () {
|
|
|
246
265
|
if (node.leadingComments) {
|
|
247
266
|
var last_comment = node.leadingComments[node.leadingComments.length - 1];
|
|
248
267
|
var comment = commentParser(ComponentParser.formatComment(last_comment.value));
|
|
249
|
-
var tag = (
|
|
268
|
+
var tag = (_e = comment[0]) === null || _e === void 0 ? void 0 : _e.tags[((_f = comment[0]) === null || _f === void 0 ? void 0 : _f.tags.length) - 1];
|
|
250
269
|
if ((tag === null || tag === void 0 ? void 0 : tag.tag) === "type")
|
|
251
270
|
type = _this.aliasType(tag.type);
|
|
252
|
-
description = ComponentParser.assignValue((
|
|
271
|
+
description = ComponentParser.assignValue((_g = comment[0]) === null || _g === void 0 ? void 0 : _g.description);
|
|
253
272
|
}
|
|
254
273
|
if (!description && _this.typedefs.has(type)) {
|
|
255
274
|
description = _this.typedefs.get(type).description;
|
|
@@ -266,8 +285,14 @@ var ComponentParser = /** @class */ (function () {
|
|
|
266
285
|
reactive: _this.reactive_vars.has(prop_name)
|
|
267
286
|
});
|
|
268
287
|
}
|
|
288
|
+
if (node.type === "Comment") {
|
|
289
|
+
var data = (_j = (_h = node === null || node === void 0 ? void 0 : node.data) === null || _h === void 0 ? void 0 : _h.trim()) !== null && _j !== void 0 ? _j : "";
|
|
290
|
+
if (/^@component/.test(data)) {
|
|
291
|
+
_this.componentComment = data.replace(/^@component/, "");
|
|
292
|
+
}
|
|
293
|
+
}
|
|
269
294
|
if (node.type === "Slot") {
|
|
270
|
-
var slot_name = (
|
|
295
|
+
var slot_name = (_k = node.attributes.find(function (attr) { return attr.name === "name"; })) === null || _k === void 0 ? void 0 : _k.value[0].data;
|
|
271
296
|
var slot_props = node.attributes
|
|
272
297
|
.filter(function (attr) { return attr.name !== "name"; })
|
|
273
298
|
.reduce(function (slot_props, _a) {
|
|
@@ -277,6 +302,8 @@ var ComponentParser = /** @class */ (function () {
|
|
|
277
302
|
value: undefined,
|
|
278
303
|
replace: false
|
|
279
304
|
};
|
|
305
|
+
if (value === undefined)
|
|
306
|
+
return {};
|
|
280
307
|
if (value[0]) {
|
|
281
308
|
var _c = value[0], type = _c.type, expression = _c.expression, raw = _c.raw, start = _c.start, end = _c.end;
|
|
282
309
|
if (type === "Text") {
|
|
@@ -302,7 +329,7 @@ var ComponentParser = /** @class */ (function () {
|
|
|
302
329
|
}
|
|
303
330
|
return __assign(__assign({}, slot_props), (_b = {}, _b[name] = slot_prop_value, _b));
|
|
304
331
|
}, {});
|
|
305
|
-
var fallback = (
|
|
332
|
+
var fallback = (_l = node.children) === null || _l === void 0 ? void 0 : _l.map(function (_a) {
|
|
306
333
|
var start = _a.start, end = _a.end;
|
|
307
334
|
return _this.sourceAtPos(start, end);
|
|
308
335
|
}).join("").trim();
|
|
@@ -387,7 +414,8 @@ var ComponentParser = /** @class */ (function () {
|
|
|
387
414
|
events: ComponentParser.mapToArray(this.events),
|
|
388
415
|
typedefs: ComponentParser.mapToArray(this.typedefs),
|
|
389
416
|
rest_props: this.rest_props,
|
|
390
|
-
"extends": this["extends"]
|
|
417
|
+
"extends": this["extends"],
|
|
418
|
+
componentComment: this.componentComment
|
|
391
419
|
};
|
|
392
420
|
};
|
|
393
421
|
return ComponentParser;
|
package/lib/path.d.ts
ADDED
package/lib/path.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
exports.__esModule = true;
|
|
3
|
+
exports.normalizeSeparators = void 0;
|
|
4
|
+
var path_1 = require("path");
|
|
5
|
+
/**
|
|
6
|
+
* Normalize directory separators to always use `/`.
|
|
7
|
+
* @param filePath A file path.
|
|
8
|
+
* @returns Path with normalized separators.
|
|
9
|
+
*/
|
|
10
|
+
function normalizeSeparators(filePath) {
|
|
11
|
+
return path_1.sep === "/" ? filePath : filePath.split(path_1.sep).join("/");
|
|
12
|
+
}
|
|
13
|
+
exports.normalizeSeparators = normalizeSeparators;
|
package/lib/rollup-plugin.js
CHANGED
|
@@ -59,6 +59,7 @@ var get_svelte_entry_1 = require("./get-svelte-entry");
|
|
|
59
59
|
var parse_exports_1 = require("./parse-exports");
|
|
60
60
|
var compiler_1 = require("svelte/compiler");
|
|
61
61
|
var svelte_preprocess_1 = require("svelte-preprocess");
|
|
62
|
+
var path_1 = require("./path");
|
|
62
63
|
function pluginSveld(opts) {
|
|
63
64
|
var result;
|
|
64
65
|
var input;
|
|
@@ -101,10 +102,7 @@ function generateBundle(input, glob) {
|
|
|
101
102
|
if (glob) {
|
|
102
103
|
fg.sync([dir + "/**/*.svelte"]).forEach(function (file) {
|
|
103
104
|
var moduleName = path.parse(file).name.replace(/\-/g, "");
|
|
104
|
-
var source = "./" + path.relative(dir, file);
|
|
105
|
-
if (path.sep !== "/") {
|
|
106
|
-
source = source.split(path.sep).join("/");
|
|
107
|
-
}
|
|
105
|
+
var source = (0, path_1.normalizeSeparators)("./" + path.relative(dir, file));
|
|
108
106
|
if (exports[moduleName]) {
|
|
109
107
|
exports[moduleName].source = source;
|
|
110
108
|
}
|
|
@@ -48,6 +48,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
48
48
|
};
|
|
49
49
|
exports.__esModule = true;
|
|
50
50
|
var path = require("path");
|
|
51
|
+
var path_1 = require("../path");
|
|
51
52
|
var Writer_1 = require("./Writer");
|
|
52
53
|
function writeJson(components, options) {
|
|
53
54
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -59,7 +60,7 @@ function writeJson(components, options) {
|
|
|
59
60
|
total: components.size,
|
|
60
61
|
components: Array.from(components, function (_a) {
|
|
61
62
|
var moduleName = _a[0], component = _a[1];
|
|
62
|
-
return (__assign(__assign({}, component), { filePath: path.join(options.inputDir, path.normalize(component.filePath)) }));
|
|
63
|
+
return (__assign(__assign({}, component), { filePath: (0, path_1.normalizeSeparators)(path.join(options.inputDir, path.normalize(component.filePath))) }));
|
|
63
64
|
}).sort(function (a, b) {
|
|
64
65
|
if (a.moduleName < b.moduleName)
|
|
65
66
|
return -1;
|
|
@@ -148,15 +148,25 @@ function genImports(def) {
|
|
|
148
148
|
return "";
|
|
149
149
|
return "import { " + def["extends"].interface + " } from " + def["extends"]["import"] + ";";
|
|
150
150
|
}
|
|
151
|
+
function genComponentComment(def) {
|
|
152
|
+
if (!def.componentComment)
|
|
153
|
+
return "";
|
|
154
|
+
if (!/\n/.test(def.componentComment))
|
|
155
|
+
return "/** " + def.componentComment.trim() + " */";
|
|
156
|
+
return "/*" + def.componentComment
|
|
157
|
+
.split("\n")
|
|
158
|
+
.map(function (line) { return "* " + line; })
|
|
159
|
+
.join("\n") + "\n*/";
|
|
160
|
+
}
|
|
151
161
|
function writeTsDefinition(component) {
|
|
152
|
-
var moduleName = component.moduleName, typedefs = component.typedefs, props = component.props, slots = component.slots, events = component.events, rest_props = component.rest_props, _extends = component["extends"];
|
|
162
|
+
var moduleName = component.moduleName, typedefs = component.typedefs, props = component.props, slots = component.slots, events = component.events, rest_props = component.rest_props, _extends = component["extends"], componentComment = component.componentComment;
|
|
153
163
|
var _a = genPropDef({
|
|
154
164
|
moduleName: moduleName,
|
|
155
165
|
props: props,
|
|
156
166
|
rest_props: rest_props,
|
|
157
167
|
"extends": _extends
|
|
158
168
|
}), props_name = _a.props_name, prop_def = _a.prop_def;
|
|
159
|
-
return "\n /// <reference types=\"svelte\" />\n import { SvelteComponentTyped } from \"svelte\";\n " + genImports({ "extends": _extends }) + "\n " + getTypeDefs({ typedefs: typedefs }) + "\n " + prop_def + "\n\n export default class " + (moduleName === "default" ? "" : moduleName) + " extends SvelteComponentTyped<\n " + props_name + ",\n {" + genEventDef({ events: events }) + "},\n {" + genSlotDef({ slots: slots }) + "}\n > {\n " + genAccessors({ props: props }) + "\n }";
|
|
169
|
+
return "\n /// <reference types=\"svelte\" />\n import { SvelteComponentTyped } from \"svelte\";\n " + genImports({ "extends": _extends }) + "\n " + getTypeDefs({ typedefs: typedefs }) + "\n " + prop_def + "\n " + genComponentComment({ componentComment: componentComment }) + "\n export default class " + (moduleName === "default" ? "" : moduleName) + " extends SvelteComponentTyped<\n " + props_name + ",\n {" + genEventDef({ events: events }) + "},\n {" + genSlotDef({ slots: slots }) + "}\n > {\n " + genAccessors({ props: props }) + "\n }";
|
|
160
170
|
}
|
|
161
171
|
exports.writeTsDefinition = writeTsDefinition;
|
|
162
172
|
function writeTsDefinitions(components, options) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sveld",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Generate TypeScript definitions for your Svelte components.",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"test": "run-p test:*",
|
|
12
12
|
"test:unit": "tsnd node_modules/tape/bin/tape tests/*.test.ts",
|
|
13
13
|
"test:integration": "node tests/integration",
|
|
14
|
-
"format": "prettier --write
|
|
14
|
+
"format": "prettier --write \"{src,tests}/**/*.{ts,svelte}\"",
|
|
15
15
|
"prepack": "run-s build test"
|
|
16
16
|
},
|
|
17
17
|
"peerDependencies": {
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"@types/prettier": "^2.3.2",
|
|
37
37
|
"@types/tape": "^4.13.2",
|
|
38
38
|
"npm-run-all": "^4.1.5",
|
|
39
|
+
"prettier-plugin-svelte": "^2.4.0",
|
|
39
40
|
"tape": "^5.3.1",
|
|
40
41
|
"ts-node-dev": "^1.1.1"
|
|
41
42
|
},
|