svelte2tsx 0.5.21 → 0.5.23
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/index.js +132 -47
- package/index.mjs +132 -47
- package/package.json +1 -1
- package/svelte-html-do-not-use.d.ts +7 -7
- package/svelte-jsx.d.ts +8 -9
- package/svelte-shims.d.ts +9 -1
package/index.js
CHANGED
|
@@ -4932,6 +4932,49 @@ function getNamesFromLabeledStatement(node) {
|
|
|
4932
4932
|
// svelte won't let you create a variable with $ prefix (reserved for stores)
|
|
4933
4933
|
.filter((name) => !name.startsWith('$')));
|
|
4934
4934
|
}
|
|
4935
|
+
/**
|
|
4936
|
+
* move node to top of script so they appear outside our render function
|
|
4937
|
+
*/
|
|
4938
|
+
function moveNode(node, str, astOffset, scriptStart, sourceFile) {
|
|
4939
|
+
var _a;
|
|
4940
|
+
const scanner = ts__default['default'].createScanner(sourceFile.languageVersion,
|
|
4941
|
+
/*skipTrivia*/ false, sourceFile.languageVariant);
|
|
4942
|
+
const comments = (_a = ts__default['default'].getLeadingCommentRanges(node.getFullText(), 0)) !== null && _a !== void 0 ? _a : [];
|
|
4943
|
+
if (!comments.some((comment) => comment.hasTrailingNewLine) &&
|
|
4944
|
+
isNewGroup(sourceFile, node, scanner)) {
|
|
4945
|
+
str.appendRight(node.getStart() + astOffset, '\n');
|
|
4946
|
+
}
|
|
4947
|
+
for (const comment of comments) {
|
|
4948
|
+
const commentEnd = node.pos + comment.end + astOffset;
|
|
4949
|
+
str.move(node.pos + comment.pos + astOffset, commentEnd, scriptStart + 1);
|
|
4950
|
+
if (comment.hasTrailingNewLine) {
|
|
4951
|
+
str.overwrite(commentEnd - 1, commentEnd, str.original[commentEnd - 1] + '\n');
|
|
4952
|
+
}
|
|
4953
|
+
}
|
|
4954
|
+
str.move(node.getStart() + astOffset, node.end + astOffset, scriptStart + 1);
|
|
4955
|
+
//add in a \n
|
|
4956
|
+
const originalEndChar = str.original[node.end + astOffset - 1];
|
|
4957
|
+
str.overwrite(node.end + astOffset - 1, node.end + astOffset, originalEndChar + '\n');
|
|
4958
|
+
}
|
|
4959
|
+
/**
|
|
4960
|
+
* adopted from https://github.com/microsoft/TypeScript/blob/6e0447fdf165b1cec9fc80802abcc15bd23a268f/src/services/organizeImports.ts#L111
|
|
4961
|
+
*/
|
|
4962
|
+
function isNewGroup(sourceFile, topLevelImportDecl, scanner) {
|
|
4963
|
+
const startPos = topLevelImportDecl.getFullStart();
|
|
4964
|
+
const endPos = topLevelImportDecl.getStart();
|
|
4965
|
+
scanner.setText(sourceFile.text, startPos, endPos - startPos);
|
|
4966
|
+
let numberOfNewLines = 0;
|
|
4967
|
+
while (scanner.getTokenPos() < endPos) {
|
|
4968
|
+
const tokenKind = scanner.scan();
|
|
4969
|
+
if (tokenKind === ts__default['default'].SyntaxKind.NewLineTrivia) {
|
|
4970
|
+
numberOfNewLines++;
|
|
4971
|
+
if (numberOfNewLines >= 2) {
|
|
4972
|
+
return true;
|
|
4973
|
+
}
|
|
4974
|
+
}
|
|
4975
|
+
}
|
|
4976
|
+
return false;
|
|
4977
|
+
}
|
|
4935
4978
|
|
|
4936
4979
|
function is$$EventsDeclaration(node) {
|
|
4937
4980
|
return isInterfaceOrTypeDeclaration(node) && node.name.text === '$$Events';
|
|
@@ -5353,6 +5396,9 @@ class ExportedNames {
|
|
|
5353
5396
|
constructor(str, astOffset) {
|
|
5354
5397
|
this.str = str;
|
|
5355
5398
|
this.astOffset = astOffset;
|
|
5399
|
+
/**
|
|
5400
|
+
* Uses the $$Props type
|
|
5401
|
+
*/
|
|
5356
5402
|
this.uses$$Props = false;
|
|
5357
5403
|
this.exports = new Map();
|
|
5358
5404
|
this.possibleExports = new Map();
|
|
@@ -5488,7 +5534,11 @@ class ExportedNames {
|
|
|
5488
5534
|
}
|
|
5489
5535
|
createClassGetters() {
|
|
5490
5536
|
return Array.from(this.getters)
|
|
5491
|
-
.map((name) =>
|
|
5537
|
+
.map((name) =>
|
|
5538
|
+
// getters are const/classes/functions, which are always defined.
|
|
5539
|
+
// We have to remove the `| undefined` from the type here because it was necessary to
|
|
5540
|
+
// be added in a previous step so people are not expected to provide these as props.
|
|
5541
|
+
`\n get ${name}() { return __sveltets_2_nonNullable(this.$$prop_def.${name}) }`)
|
|
5492
5542
|
.join('');
|
|
5493
5543
|
}
|
|
5494
5544
|
createClassAccessors() {
|
|
@@ -5581,8 +5631,9 @@ class ExportedNames {
|
|
|
5581
5631
|
* Creates a string from the collected props
|
|
5582
5632
|
*
|
|
5583
5633
|
* @param isTsFile Whether this is a TypeScript file or not.
|
|
5634
|
+
* @param uses$$propsValue whether the file references the $$props variable
|
|
5584
5635
|
*/
|
|
5585
|
-
createPropsStr(isTsFile) {
|
|
5636
|
+
createPropsStr(isTsFile, uses$$propsValue) {
|
|
5586
5637
|
const names = Array.from(this.exports.entries());
|
|
5587
5638
|
if (this.uses$$Props) {
|
|
5588
5639
|
const lets = names.filter(([, { isLet }]) => isLet);
|
|
@@ -5608,7 +5659,7 @@ class ExportedNames {
|
|
|
5608
5659
|
this.createReturnElementsType(others).join(',') +
|
|
5609
5660
|
'}}');
|
|
5610
5661
|
}
|
|
5611
|
-
if (names.length === 0) {
|
|
5662
|
+
if (names.length === 0 && !uses$$propsValue) {
|
|
5612
5663
|
// Necessary, because {} roughly equals to any
|
|
5613
5664
|
return isTsFile
|
|
5614
5665
|
? '{} as Record<string, never>'
|
|
@@ -6332,6 +6383,7 @@ class Generics {
|
|
|
6332
6383
|
this.str = str;
|
|
6333
6384
|
this.astOffset = astOffset;
|
|
6334
6385
|
this.definitions = [];
|
|
6386
|
+
this.typeReferences = [];
|
|
6335
6387
|
this.references = [];
|
|
6336
6388
|
}
|
|
6337
6389
|
addIfIsGeneric(node) {
|
|
@@ -6341,10 +6393,12 @@ class Generics {
|
|
|
6341
6393
|
throw new Error('Invalid $$Generic declaration: Only one type argument allowed');
|
|
6342
6394
|
}
|
|
6343
6395
|
if (((_b = node.type.typeArguments) === null || _b === void 0 ? void 0 : _b.length) === 1) {
|
|
6344
|
-
|
|
6396
|
+
const typeReference = node.type.typeArguments[0].getText();
|
|
6397
|
+
this.typeReferences.push(typeReference);
|
|
6398
|
+
this.definitions.push(`${node.name.text} extends ${typeReference}`);
|
|
6345
6399
|
}
|
|
6346
6400
|
else {
|
|
6347
|
-
this.definitions.push(
|
|
6401
|
+
this.definitions.push(node.name.text);
|
|
6348
6402
|
}
|
|
6349
6403
|
this.references.push(node.name.text);
|
|
6350
6404
|
this.str.remove(this.astOffset + node.getStart(), this.astOffset + node.getEnd());
|
|
@@ -6360,6 +6414,9 @@ class Generics {
|
|
|
6360
6414
|
ts__default['default'].isIdentifier(node.typeName) &&
|
|
6361
6415
|
node.typeName.text === '$$Generic');
|
|
6362
6416
|
}
|
|
6417
|
+
getTypeReferences() {
|
|
6418
|
+
return this.typeReferences;
|
|
6419
|
+
}
|
|
6363
6420
|
toDefinitionString(addIgnore = false) {
|
|
6364
6421
|
const surround = addIgnore ? surroundWithIgnoreComments : (str) => str;
|
|
6365
6422
|
return this.definitions.length ? surround(`<${this.definitions.join(',')}>`) : '';
|
|
@@ -6376,44 +6433,7 @@ class Generics {
|
|
|
6376
6433
|
* move imports to top of script so they appear outside our render function
|
|
6377
6434
|
*/
|
|
6378
6435
|
function handleImportDeclaration(node, str, astOffset, scriptStart, sourceFile) {
|
|
6379
|
-
|
|
6380
|
-
const scanner = ts__default['default'].createScanner(sourceFile.languageVersion,
|
|
6381
|
-
/*skipTrivia*/ false, sourceFile.languageVariant);
|
|
6382
|
-
const comments = (_a = ts__default['default'].getLeadingCommentRanges(node.getFullText(), 0)) !== null && _a !== void 0 ? _a : [];
|
|
6383
|
-
if (!comments.some((comment) => comment.hasTrailingNewLine) &&
|
|
6384
|
-
isNewGroup(sourceFile, node, scanner)) {
|
|
6385
|
-
str.appendRight(node.getStart() + astOffset, '\n');
|
|
6386
|
-
}
|
|
6387
|
-
for (const comment of comments) {
|
|
6388
|
-
const commentEnd = node.pos + comment.end + astOffset;
|
|
6389
|
-
str.move(node.pos + comment.pos + astOffset, commentEnd, scriptStart + 1);
|
|
6390
|
-
if (comment.hasTrailingNewLine) {
|
|
6391
|
-
str.overwrite(commentEnd - 1, commentEnd, str.original[commentEnd - 1] + '\n');
|
|
6392
|
-
}
|
|
6393
|
-
}
|
|
6394
|
-
str.move(node.getStart() + astOffset, node.end + astOffset, scriptStart + 1);
|
|
6395
|
-
//add in a \n
|
|
6396
|
-
const originalEndChar = str.original[node.end + astOffset - 1];
|
|
6397
|
-
str.overwrite(node.end + astOffset - 1, node.end + astOffset, originalEndChar + '\n');
|
|
6398
|
-
}
|
|
6399
|
-
/**
|
|
6400
|
-
* adopted from https://github.com/microsoft/TypeScript/blob/6e0447fdf165b1cec9fc80802abcc15bd23a268f/src/services/organizeImports.ts#L111
|
|
6401
|
-
*/
|
|
6402
|
-
function isNewGroup(sourceFile, topLevelImportDecl, scanner) {
|
|
6403
|
-
const startPos = topLevelImportDecl.getFullStart();
|
|
6404
|
-
const endPos = topLevelImportDecl.getStart();
|
|
6405
|
-
scanner.setText(sourceFile.text, startPos, endPos - startPos);
|
|
6406
|
-
let numberOfNewLines = 0;
|
|
6407
|
-
while (scanner.getTokenPos() < endPos) {
|
|
6408
|
-
const tokenKind = scanner.scan();
|
|
6409
|
-
if (tokenKind === ts__default['default'].SyntaxKind.NewLineTrivia) {
|
|
6410
|
-
numberOfNewLines++;
|
|
6411
|
-
if (numberOfNewLines >= 2) {
|
|
6412
|
-
return true;
|
|
6413
|
-
}
|
|
6414
|
-
}
|
|
6415
|
-
}
|
|
6416
|
-
return false;
|
|
6436
|
+
return moveNode(node, str, astOffset, scriptStart, sourceFile);
|
|
6417
6437
|
}
|
|
6418
6438
|
/**
|
|
6419
6439
|
* ensure it's in a newline.
|
|
@@ -6434,6 +6454,56 @@ function handleFirstInstanceImport(tsAst, astOffset, hasModuleScript, str) {
|
|
|
6434
6454
|
str.appendRight(start + astOffset, '\n' + (hasModuleScript ? '\n' : ''));
|
|
6435
6455
|
}
|
|
6436
6456
|
|
|
6457
|
+
function flatten(arr) {
|
|
6458
|
+
return arr.reduce((acc, val) => acc.concat(val), []);
|
|
6459
|
+
}
|
|
6460
|
+
|
|
6461
|
+
class InterfacesAndTypes {
|
|
6462
|
+
constructor() {
|
|
6463
|
+
this.node = null;
|
|
6464
|
+
this.all = [];
|
|
6465
|
+
this.references = new Map();
|
|
6466
|
+
}
|
|
6467
|
+
add(node) {
|
|
6468
|
+
this.all.push(node);
|
|
6469
|
+
}
|
|
6470
|
+
getNodesWithNames(names) {
|
|
6471
|
+
return this.all.filter((node) => names.includes(node.name.text));
|
|
6472
|
+
}
|
|
6473
|
+
// The following could be used to create a informative error message in case
|
|
6474
|
+
// someone has an interface that both references a generic and is used by one:
|
|
6475
|
+
addReference(reference) {
|
|
6476
|
+
if (!this.node) {
|
|
6477
|
+
return;
|
|
6478
|
+
}
|
|
6479
|
+
const references = this.references.get(this.node) || [];
|
|
6480
|
+
references.push(reference);
|
|
6481
|
+
this.references.set(this.node, references);
|
|
6482
|
+
}
|
|
6483
|
+
getNodesThatReferenceType(name) {
|
|
6484
|
+
const nodes = [];
|
|
6485
|
+
for (const [node, references] of this.references) {
|
|
6486
|
+
if (references.some((r) => r.typeName.getText() === name)) {
|
|
6487
|
+
nodes.push(node);
|
|
6488
|
+
}
|
|
6489
|
+
}
|
|
6490
|
+
return nodes;
|
|
6491
|
+
}
|
|
6492
|
+
getNodesThatRecursivelyReferenceType(name) {
|
|
6493
|
+
let types = [name];
|
|
6494
|
+
const nodes = new Set();
|
|
6495
|
+
while (types.length !== 0) {
|
|
6496
|
+
const newTypes = flatten(types.map((type) => this.getNodesThatReferenceType(type))).filter((t) => !nodes.has(t));
|
|
6497
|
+
newTypes.forEach((t) => nodes.add(t));
|
|
6498
|
+
types = newTypes.map((t) => t.name.text);
|
|
6499
|
+
}
|
|
6500
|
+
return [...nodes.values()];
|
|
6501
|
+
}
|
|
6502
|
+
getNodesThatRecursivelyReferenceTypes(names) {
|
|
6503
|
+
return flatten(names.map((name) => this.getNodesThatRecursivelyReferenceType(name)));
|
|
6504
|
+
}
|
|
6505
|
+
}
|
|
6506
|
+
|
|
6437
6507
|
function processInstanceScriptContent(str, script, events, implicitStoreValues, mode, hasModuleScript) {
|
|
6438
6508
|
const htmlx = str.original;
|
|
6439
6509
|
const scriptContent = htmlx.substring(script.content.start, script.content.end);
|
|
@@ -6441,6 +6511,7 @@ function processInstanceScriptContent(str, script, events, implicitStoreValues,
|
|
|
6441
6511
|
const astOffset = script.content.start;
|
|
6442
6512
|
const exportedNames = new ExportedNames(str, astOffset);
|
|
6443
6513
|
const generics = new Generics(str, astOffset);
|
|
6514
|
+
const interfacesAndTypes = new InterfacesAndTypes();
|
|
6444
6515
|
const implicitTopLevelNames = new ImplicitTopLevelNames(str, astOffset);
|
|
6445
6516
|
let uses$$props = false;
|
|
6446
6517
|
let uses$$restProps = false;
|
|
@@ -6576,6 +6647,11 @@ function processInstanceScriptContent(str, script, events, implicitStoreValues,
|
|
|
6576
6647
|
if (ts__namespace.isImportSpecifier(node)) {
|
|
6577
6648
|
implicitStoreValues.addImportStatement(node);
|
|
6578
6649
|
}
|
|
6650
|
+
if (ts__namespace.isTypeAliasDeclaration(node) || ts__namespace.isInterfaceDeclaration(node)) {
|
|
6651
|
+
interfacesAndTypes.node = node;
|
|
6652
|
+
interfacesAndTypes.add(node);
|
|
6653
|
+
onLeaveCallbacks.push(() => (interfacesAndTypes.node = null));
|
|
6654
|
+
}
|
|
6579
6655
|
//handle stores etc
|
|
6580
6656
|
if (ts__namespace.isIdentifier(node)) {
|
|
6581
6657
|
handleIdentifier(node, parent);
|
|
@@ -6611,12 +6687,18 @@ function processInstanceScriptContent(str, script, events, implicitStoreValues,
|
|
|
6611
6687
|
implicitTopLevelNames.modifyCode(rootScope.declared);
|
|
6612
6688
|
implicitStoreValues.modifyCode(astOffset, str);
|
|
6613
6689
|
handleFirstInstanceImport(tsAst, astOffset, hasModuleScript, str);
|
|
6690
|
+
// move interfaces and types out of the render function if they are referenced
|
|
6691
|
+
// by a $$Generic, otherwise it will be used before being defined after the transformation
|
|
6692
|
+
const nodesToMove = interfacesAndTypes.getNodesWithNames(generics.getTypeReferences());
|
|
6693
|
+
for (const node of nodesToMove) {
|
|
6694
|
+
moveNode(node, str, astOffset, script.start, tsAst);
|
|
6695
|
+
}
|
|
6614
6696
|
if (mode === 'dts') {
|
|
6615
6697
|
// Transform interface declarations to type declarations because indirectly
|
|
6616
6698
|
// using interfaces inside the return type of a function is forbidden.
|
|
6617
6699
|
// This is not a problem for intellisense/type inference but it will
|
|
6618
6700
|
// break dts generation (file will not be generated).
|
|
6619
|
-
transformInterfacesToTypes(tsAst, str, astOffset);
|
|
6701
|
+
transformInterfacesToTypes(tsAst, str, astOffset, nodesToMove);
|
|
6620
6702
|
}
|
|
6621
6703
|
return {
|
|
6622
6704
|
exportedNames,
|
|
@@ -6628,8 +6710,11 @@ function processInstanceScriptContent(str, script, events, implicitStoreValues,
|
|
|
6628
6710
|
generics
|
|
6629
6711
|
};
|
|
6630
6712
|
}
|
|
6631
|
-
function transformInterfacesToTypes(tsAst, str, astOffset) {
|
|
6632
|
-
tsAst.statements
|
|
6713
|
+
function transformInterfacesToTypes(tsAst, str, astOffset, movedNodes) {
|
|
6714
|
+
tsAst.statements
|
|
6715
|
+
.filter(ts__namespace.isInterfaceDeclaration)
|
|
6716
|
+
.filter((i) => !movedNodes.includes(i))
|
|
6717
|
+
.forEach((node) => {
|
|
6633
6718
|
var _a;
|
|
6634
6719
|
str.overwrite(node.getStart() + astOffset, node.getStart() + astOffset + 'interface'.length, 'type');
|
|
6635
6720
|
if ((_a = node.heritageClauses) === null || _a === void 0 ? void 0 : _a.length) {
|
|
@@ -6904,7 +6989,7 @@ function createRenderFunction({ str, scriptTag, scriptDestination, slots, events
|
|
|
6904
6989
|
})
|
|
6905
6990
|
.join(', ') +
|
|
6906
6991
|
'}';
|
|
6907
|
-
const returnString = `\nreturn { props: ${exportedNames.createPropsStr(isTsFile)}` +
|
|
6992
|
+
const returnString = `\nreturn { props: ${exportedNames.createPropsStr(isTsFile, uses$$props)}` +
|
|
6908
6993
|
`, slots: ${slotsAsDef}` +
|
|
6909
6994
|
`, events: ${events.toDefString()} }}`;
|
|
6910
6995
|
// wrap template with callback
|
package/index.mjs
CHANGED
|
@@ -4902,6 +4902,49 @@ function getNamesFromLabeledStatement(node) {
|
|
|
4902
4902
|
// svelte won't let you create a variable with $ prefix (reserved for stores)
|
|
4903
4903
|
.filter((name) => !name.startsWith('$')));
|
|
4904
4904
|
}
|
|
4905
|
+
/**
|
|
4906
|
+
* move node to top of script so they appear outside our render function
|
|
4907
|
+
*/
|
|
4908
|
+
function moveNode(node, str, astOffset, scriptStart, sourceFile) {
|
|
4909
|
+
var _a;
|
|
4910
|
+
const scanner = ts__default.createScanner(sourceFile.languageVersion,
|
|
4911
|
+
/*skipTrivia*/ false, sourceFile.languageVariant);
|
|
4912
|
+
const comments = (_a = ts__default.getLeadingCommentRanges(node.getFullText(), 0)) !== null && _a !== void 0 ? _a : [];
|
|
4913
|
+
if (!comments.some((comment) => comment.hasTrailingNewLine) &&
|
|
4914
|
+
isNewGroup(sourceFile, node, scanner)) {
|
|
4915
|
+
str.appendRight(node.getStart() + astOffset, '\n');
|
|
4916
|
+
}
|
|
4917
|
+
for (const comment of comments) {
|
|
4918
|
+
const commentEnd = node.pos + comment.end + astOffset;
|
|
4919
|
+
str.move(node.pos + comment.pos + astOffset, commentEnd, scriptStart + 1);
|
|
4920
|
+
if (comment.hasTrailingNewLine) {
|
|
4921
|
+
str.overwrite(commentEnd - 1, commentEnd, str.original[commentEnd - 1] + '\n');
|
|
4922
|
+
}
|
|
4923
|
+
}
|
|
4924
|
+
str.move(node.getStart() + astOffset, node.end + astOffset, scriptStart + 1);
|
|
4925
|
+
//add in a \n
|
|
4926
|
+
const originalEndChar = str.original[node.end + astOffset - 1];
|
|
4927
|
+
str.overwrite(node.end + astOffset - 1, node.end + astOffset, originalEndChar + '\n');
|
|
4928
|
+
}
|
|
4929
|
+
/**
|
|
4930
|
+
* adopted from https://github.com/microsoft/TypeScript/blob/6e0447fdf165b1cec9fc80802abcc15bd23a268f/src/services/organizeImports.ts#L111
|
|
4931
|
+
*/
|
|
4932
|
+
function isNewGroup(sourceFile, topLevelImportDecl, scanner) {
|
|
4933
|
+
const startPos = topLevelImportDecl.getFullStart();
|
|
4934
|
+
const endPos = topLevelImportDecl.getStart();
|
|
4935
|
+
scanner.setText(sourceFile.text, startPos, endPos - startPos);
|
|
4936
|
+
let numberOfNewLines = 0;
|
|
4937
|
+
while (scanner.getTokenPos() < endPos) {
|
|
4938
|
+
const tokenKind = scanner.scan();
|
|
4939
|
+
if (tokenKind === ts__default.SyntaxKind.NewLineTrivia) {
|
|
4940
|
+
numberOfNewLines++;
|
|
4941
|
+
if (numberOfNewLines >= 2) {
|
|
4942
|
+
return true;
|
|
4943
|
+
}
|
|
4944
|
+
}
|
|
4945
|
+
}
|
|
4946
|
+
return false;
|
|
4947
|
+
}
|
|
4905
4948
|
|
|
4906
4949
|
function is$$EventsDeclaration(node) {
|
|
4907
4950
|
return isInterfaceOrTypeDeclaration(node) && node.name.text === '$$Events';
|
|
@@ -5323,6 +5366,9 @@ class ExportedNames {
|
|
|
5323
5366
|
constructor(str, astOffset) {
|
|
5324
5367
|
this.str = str;
|
|
5325
5368
|
this.astOffset = astOffset;
|
|
5369
|
+
/**
|
|
5370
|
+
* Uses the $$Props type
|
|
5371
|
+
*/
|
|
5326
5372
|
this.uses$$Props = false;
|
|
5327
5373
|
this.exports = new Map();
|
|
5328
5374
|
this.possibleExports = new Map();
|
|
@@ -5458,7 +5504,11 @@ class ExportedNames {
|
|
|
5458
5504
|
}
|
|
5459
5505
|
createClassGetters() {
|
|
5460
5506
|
return Array.from(this.getters)
|
|
5461
|
-
.map((name) =>
|
|
5507
|
+
.map((name) =>
|
|
5508
|
+
// getters are const/classes/functions, which are always defined.
|
|
5509
|
+
// We have to remove the `| undefined` from the type here because it was necessary to
|
|
5510
|
+
// be added in a previous step so people are not expected to provide these as props.
|
|
5511
|
+
`\n get ${name}() { return __sveltets_2_nonNullable(this.$$prop_def.${name}) }`)
|
|
5462
5512
|
.join('');
|
|
5463
5513
|
}
|
|
5464
5514
|
createClassAccessors() {
|
|
@@ -5551,8 +5601,9 @@ class ExportedNames {
|
|
|
5551
5601
|
* Creates a string from the collected props
|
|
5552
5602
|
*
|
|
5553
5603
|
* @param isTsFile Whether this is a TypeScript file or not.
|
|
5604
|
+
* @param uses$$propsValue whether the file references the $$props variable
|
|
5554
5605
|
*/
|
|
5555
|
-
createPropsStr(isTsFile) {
|
|
5606
|
+
createPropsStr(isTsFile, uses$$propsValue) {
|
|
5556
5607
|
const names = Array.from(this.exports.entries());
|
|
5557
5608
|
if (this.uses$$Props) {
|
|
5558
5609
|
const lets = names.filter(([, { isLet }]) => isLet);
|
|
@@ -5578,7 +5629,7 @@ class ExportedNames {
|
|
|
5578
5629
|
this.createReturnElementsType(others).join(',') +
|
|
5579
5630
|
'}}');
|
|
5580
5631
|
}
|
|
5581
|
-
if (names.length === 0) {
|
|
5632
|
+
if (names.length === 0 && !uses$$propsValue) {
|
|
5582
5633
|
// Necessary, because {} roughly equals to any
|
|
5583
5634
|
return isTsFile
|
|
5584
5635
|
? '{} as Record<string, never>'
|
|
@@ -6302,6 +6353,7 @@ class Generics {
|
|
|
6302
6353
|
this.str = str;
|
|
6303
6354
|
this.astOffset = astOffset;
|
|
6304
6355
|
this.definitions = [];
|
|
6356
|
+
this.typeReferences = [];
|
|
6305
6357
|
this.references = [];
|
|
6306
6358
|
}
|
|
6307
6359
|
addIfIsGeneric(node) {
|
|
@@ -6311,10 +6363,12 @@ class Generics {
|
|
|
6311
6363
|
throw new Error('Invalid $$Generic declaration: Only one type argument allowed');
|
|
6312
6364
|
}
|
|
6313
6365
|
if (((_b = node.type.typeArguments) === null || _b === void 0 ? void 0 : _b.length) === 1) {
|
|
6314
|
-
|
|
6366
|
+
const typeReference = node.type.typeArguments[0].getText();
|
|
6367
|
+
this.typeReferences.push(typeReference);
|
|
6368
|
+
this.definitions.push(`${node.name.text} extends ${typeReference}`);
|
|
6315
6369
|
}
|
|
6316
6370
|
else {
|
|
6317
|
-
this.definitions.push(
|
|
6371
|
+
this.definitions.push(node.name.text);
|
|
6318
6372
|
}
|
|
6319
6373
|
this.references.push(node.name.text);
|
|
6320
6374
|
this.str.remove(this.astOffset + node.getStart(), this.astOffset + node.getEnd());
|
|
@@ -6330,6 +6384,9 @@ class Generics {
|
|
|
6330
6384
|
ts__default.isIdentifier(node.typeName) &&
|
|
6331
6385
|
node.typeName.text === '$$Generic');
|
|
6332
6386
|
}
|
|
6387
|
+
getTypeReferences() {
|
|
6388
|
+
return this.typeReferences;
|
|
6389
|
+
}
|
|
6333
6390
|
toDefinitionString(addIgnore = false) {
|
|
6334
6391
|
const surround = addIgnore ? surroundWithIgnoreComments : (str) => str;
|
|
6335
6392
|
return this.definitions.length ? surround(`<${this.definitions.join(',')}>`) : '';
|
|
@@ -6346,44 +6403,7 @@ class Generics {
|
|
|
6346
6403
|
* move imports to top of script so they appear outside our render function
|
|
6347
6404
|
*/
|
|
6348
6405
|
function handleImportDeclaration(node, str, astOffset, scriptStart, sourceFile) {
|
|
6349
|
-
|
|
6350
|
-
const scanner = ts__default.createScanner(sourceFile.languageVersion,
|
|
6351
|
-
/*skipTrivia*/ false, sourceFile.languageVariant);
|
|
6352
|
-
const comments = (_a = ts__default.getLeadingCommentRanges(node.getFullText(), 0)) !== null && _a !== void 0 ? _a : [];
|
|
6353
|
-
if (!comments.some((comment) => comment.hasTrailingNewLine) &&
|
|
6354
|
-
isNewGroup(sourceFile, node, scanner)) {
|
|
6355
|
-
str.appendRight(node.getStart() + astOffset, '\n');
|
|
6356
|
-
}
|
|
6357
|
-
for (const comment of comments) {
|
|
6358
|
-
const commentEnd = node.pos + comment.end + astOffset;
|
|
6359
|
-
str.move(node.pos + comment.pos + astOffset, commentEnd, scriptStart + 1);
|
|
6360
|
-
if (comment.hasTrailingNewLine) {
|
|
6361
|
-
str.overwrite(commentEnd - 1, commentEnd, str.original[commentEnd - 1] + '\n');
|
|
6362
|
-
}
|
|
6363
|
-
}
|
|
6364
|
-
str.move(node.getStart() + astOffset, node.end + astOffset, scriptStart + 1);
|
|
6365
|
-
//add in a \n
|
|
6366
|
-
const originalEndChar = str.original[node.end + astOffset - 1];
|
|
6367
|
-
str.overwrite(node.end + astOffset - 1, node.end + astOffset, originalEndChar + '\n');
|
|
6368
|
-
}
|
|
6369
|
-
/**
|
|
6370
|
-
* adopted from https://github.com/microsoft/TypeScript/blob/6e0447fdf165b1cec9fc80802abcc15bd23a268f/src/services/organizeImports.ts#L111
|
|
6371
|
-
*/
|
|
6372
|
-
function isNewGroup(sourceFile, topLevelImportDecl, scanner) {
|
|
6373
|
-
const startPos = topLevelImportDecl.getFullStart();
|
|
6374
|
-
const endPos = topLevelImportDecl.getStart();
|
|
6375
|
-
scanner.setText(sourceFile.text, startPos, endPos - startPos);
|
|
6376
|
-
let numberOfNewLines = 0;
|
|
6377
|
-
while (scanner.getTokenPos() < endPos) {
|
|
6378
|
-
const tokenKind = scanner.scan();
|
|
6379
|
-
if (tokenKind === ts__default.SyntaxKind.NewLineTrivia) {
|
|
6380
|
-
numberOfNewLines++;
|
|
6381
|
-
if (numberOfNewLines >= 2) {
|
|
6382
|
-
return true;
|
|
6383
|
-
}
|
|
6384
|
-
}
|
|
6385
|
-
}
|
|
6386
|
-
return false;
|
|
6406
|
+
return moveNode(node, str, astOffset, scriptStart, sourceFile);
|
|
6387
6407
|
}
|
|
6388
6408
|
/**
|
|
6389
6409
|
* ensure it's in a newline.
|
|
@@ -6404,6 +6424,56 @@ function handleFirstInstanceImport(tsAst, astOffset, hasModuleScript, str) {
|
|
|
6404
6424
|
str.appendRight(start + astOffset, '\n' + (hasModuleScript ? '\n' : ''));
|
|
6405
6425
|
}
|
|
6406
6426
|
|
|
6427
|
+
function flatten(arr) {
|
|
6428
|
+
return arr.reduce((acc, val) => acc.concat(val), []);
|
|
6429
|
+
}
|
|
6430
|
+
|
|
6431
|
+
class InterfacesAndTypes {
|
|
6432
|
+
constructor() {
|
|
6433
|
+
this.node = null;
|
|
6434
|
+
this.all = [];
|
|
6435
|
+
this.references = new Map();
|
|
6436
|
+
}
|
|
6437
|
+
add(node) {
|
|
6438
|
+
this.all.push(node);
|
|
6439
|
+
}
|
|
6440
|
+
getNodesWithNames(names) {
|
|
6441
|
+
return this.all.filter((node) => names.includes(node.name.text));
|
|
6442
|
+
}
|
|
6443
|
+
// The following could be used to create a informative error message in case
|
|
6444
|
+
// someone has an interface that both references a generic and is used by one:
|
|
6445
|
+
addReference(reference) {
|
|
6446
|
+
if (!this.node) {
|
|
6447
|
+
return;
|
|
6448
|
+
}
|
|
6449
|
+
const references = this.references.get(this.node) || [];
|
|
6450
|
+
references.push(reference);
|
|
6451
|
+
this.references.set(this.node, references);
|
|
6452
|
+
}
|
|
6453
|
+
getNodesThatReferenceType(name) {
|
|
6454
|
+
const nodes = [];
|
|
6455
|
+
for (const [node, references] of this.references) {
|
|
6456
|
+
if (references.some((r) => r.typeName.getText() === name)) {
|
|
6457
|
+
nodes.push(node);
|
|
6458
|
+
}
|
|
6459
|
+
}
|
|
6460
|
+
return nodes;
|
|
6461
|
+
}
|
|
6462
|
+
getNodesThatRecursivelyReferenceType(name) {
|
|
6463
|
+
let types = [name];
|
|
6464
|
+
const nodes = new Set();
|
|
6465
|
+
while (types.length !== 0) {
|
|
6466
|
+
const newTypes = flatten(types.map((type) => this.getNodesThatReferenceType(type))).filter((t) => !nodes.has(t));
|
|
6467
|
+
newTypes.forEach((t) => nodes.add(t));
|
|
6468
|
+
types = newTypes.map((t) => t.name.text);
|
|
6469
|
+
}
|
|
6470
|
+
return [...nodes.values()];
|
|
6471
|
+
}
|
|
6472
|
+
getNodesThatRecursivelyReferenceTypes(names) {
|
|
6473
|
+
return flatten(names.map((name) => this.getNodesThatRecursivelyReferenceType(name)));
|
|
6474
|
+
}
|
|
6475
|
+
}
|
|
6476
|
+
|
|
6407
6477
|
function processInstanceScriptContent(str, script, events, implicitStoreValues, mode, hasModuleScript) {
|
|
6408
6478
|
const htmlx = str.original;
|
|
6409
6479
|
const scriptContent = htmlx.substring(script.content.start, script.content.end);
|
|
@@ -6411,6 +6481,7 @@ function processInstanceScriptContent(str, script, events, implicitStoreValues,
|
|
|
6411
6481
|
const astOffset = script.content.start;
|
|
6412
6482
|
const exportedNames = new ExportedNames(str, astOffset);
|
|
6413
6483
|
const generics = new Generics(str, astOffset);
|
|
6484
|
+
const interfacesAndTypes = new InterfacesAndTypes();
|
|
6414
6485
|
const implicitTopLevelNames = new ImplicitTopLevelNames(str, astOffset);
|
|
6415
6486
|
let uses$$props = false;
|
|
6416
6487
|
let uses$$restProps = false;
|
|
@@ -6546,6 +6617,11 @@ function processInstanceScriptContent(str, script, events, implicitStoreValues,
|
|
|
6546
6617
|
if (ts.isImportSpecifier(node)) {
|
|
6547
6618
|
implicitStoreValues.addImportStatement(node);
|
|
6548
6619
|
}
|
|
6620
|
+
if (ts.isTypeAliasDeclaration(node) || ts.isInterfaceDeclaration(node)) {
|
|
6621
|
+
interfacesAndTypes.node = node;
|
|
6622
|
+
interfacesAndTypes.add(node);
|
|
6623
|
+
onLeaveCallbacks.push(() => (interfacesAndTypes.node = null));
|
|
6624
|
+
}
|
|
6549
6625
|
//handle stores etc
|
|
6550
6626
|
if (ts.isIdentifier(node)) {
|
|
6551
6627
|
handleIdentifier(node, parent);
|
|
@@ -6581,12 +6657,18 @@ function processInstanceScriptContent(str, script, events, implicitStoreValues,
|
|
|
6581
6657
|
implicitTopLevelNames.modifyCode(rootScope.declared);
|
|
6582
6658
|
implicitStoreValues.modifyCode(astOffset, str);
|
|
6583
6659
|
handleFirstInstanceImport(tsAst, astOffset, hasModuleScript, str);
|
|
6660
|
+
// move interfaces and types out of the render function if they are referenced
|
|
6661
|
+
// by a $$Generic, otherwise it will be used before being defined after the transformation
|
|
6662
|
+
const nodesToMove = interfacesAndTypes.getNodesWithNames(generics.getTypeReferences());
|
|
6663
|
+
for (const node of nodesToMove) {
|
|
6664
|
+
moveNode(node, str, astOffset, script.start, tsAst);
|
|
6665
|
+
}
|
|
6584
6666
|
if (mode === 'dts') {
|
|
6585
6667
|
// Transform interface declarations to type declarations because indirectly
|
|
6586
6668
|
// using interfaces inside the return type of a function is forbidden.
|
|
6587
6669
|
// This is not a problem for intellisense/type inference but it will
|
|
6588
6670
|
// break dts generation (file will not be generated).
|
|
6589
|
-
transformInterfacesToTypes(tsAst, str, astOffset);
|
|
6671
|
+
transformInterfacesToTypes(tsAst, str, astOffset, nodesToMove);
|
|
6590
6672
|
}
|
|
6591
6673
|
return {
|
|
6592
6674
|
exportedNames,
|
|
@@ -6598,8 +6680,11 @@ function processInstanceScriptContent(str, script, events, implicitStoreValues,
|
|
|
6598
6680
|
generics
|
|
6599
6681
|
};
|
|
6600
6682
|
}
|
|
6601
|
-
function transformInterfacesToTypes(tsAst, str, astOffset) {
|
|
6602
|
-
tsAst.statements
|
|
6683
|
+
function transformInterfacesToTypes(tsAst, str, astOffset, movedNodes) {
|
|
6684
|
+
tsAst.statements
|
|
6685
|
+
.filter(ts.isInterfaceDeclaration)
|
|
6686
|
+
.filter((i) => !movedNodes.includes(i))
|
|
6687
|
+
.forEach((node) => {
|
|
6603
6688
|
var _a;
|
|
6604
6689
|
str.overwrite(node.getStart() + astOffset, node.getStart() + astOffset + 'interface'.length, 'type');
|
|
6605
6690
|
if ((_a = node.heritageClauses) === null || _a === void 0 ? void 0 : _a.length) {
|
|
@@ -6874,7 +6959,7 @@ function createRenderFunction({ str, scriptTag, scriptDestination, slots, events
|
|
|
6874
6959
|
})
|
|
6875
6960
|
.join(', ') +
|
|
6876
6961
|
'}';
|
|
6877
|
-
const returnString = `\nreturn { props: ${exportedNames.createPropsStr(isTsFile)}` +
|
|
6962
|
+
const returnString = `\nreturn { props: ${exportedNames.createPropsStr(isTsFile, uses$$props)}` +
|
|
6878
6963
|
`, slots: ${slotsAsDef}` +
|
|
6879
6964
|
`, events: ${events.toDefString()} }}`;
|
|
6880
6965
|
// wrap template with callback
|
package/package.json
CHANGED
|
@@ -87,7 +87,7 @@ export interface DOMAttributes<T extends EventTarget> {
|
|
|
87
87
|
'on:reset'?: FormEventHandler<T> | undefined | null;
|
|
88
88
|
'on:submit'?: EventHandler<Event, T> | undefined | null; // TODO make this SubmitEvent once we require TS>=4.4
|
|
89
89
|
'on:invalid'?: EventHandler<Event, T> | undefined | null;
|
|
90
|
-
|
|
90
|
+
'on:formdata'?: EventHandler<Event & { readonly formData: FormData; }, T> | undefined | null; // TODO make this FormDataEvent once we require TS>=4.4
|
|
91
91
|
|
|
92
92
|
// Image Events
|
|
93
93
|
'on:load'?: EventHandler | undefined | null;
|
|
@@ -538,6 +538,12 @@ export interface HTMLAttributes<T extends EventTarget> extends AriaAttributes, D
|
|
|
538
538
|
* Elements with the contenteditable attribute support innerHTML and textContent bindings.
|
|
539
539
|
*/
|
|
540
540
|
'bind:textContent'?: string | undefined | null;
|
|
541
|
+
|
|
542
|
+
// SvelteKit
|
|
543
|
+
'data-sveltekit-noscroll'?: true | '' | 'off' | undefined | null;
|
|
544
|
+
'data-sveltekit-preload-code'?: true | '' | 'eager' | 'viewport' | 'hover' | 'tap' | 'off' | undefined | null;
|
|
545
|
+
'data-sveltekit-preload-data'?: true | '' | 'hover' | 'tap' | 'off' | undefined | null;
|
|
546
|
+
'data-sveltekit-reload'?: true | '' | 'off' | undefined | null;
|
|
541
547
|
}
|
|
542
548
|
|
|
543
549
|
export type HTMLAttributeAnchorTarget =
|
|
@@ -558,12 +564,6 @@ export interface HTMLAnchorAttributes extends HTMLAttributes<HTMLAnchorElement>
|
|
|
558
564
|
type?: string | undefined | null;
|
|
559
565
|
referrerpolicy?: ReferrerPolicy | undefined | null;
|
|
560
566
|
|
|
561
|
-
// SvelteKit
|
|
562
|
-
'data-sveltekit-noscroll'?: true | undefined | null;
|
|
563
|
-
'data-sveltekit-preload-code'?: true | 'eager' | 'viewport' | 'hover' | 'tap' | 'off' | undefined | null;
|
|
564
|
-
'data-sveltekit-preload-data'?: true | 'hover' | 'tap' | 'off' | undefined | null;
|
|
565
|
-
'data-sveltekit-reload'?: true | undefined | null;
|
|
566
|
-
|
|
567
567
|
// Sapper
|
|
568
568
|
'sapper:noscroll'?: true | undefined | null;
|
|
569
569
|
'sapper:prefetch'?: true | undefined | null;
|
package/svelte-jsx.d.ts
CHANGED
|
@@ -348,6 +348,7 @@ declare namespace svelte.JSX {
|
|
|
348
348
|
onsubmit?: EventHandler<SubmitEvent, T> | undefined | null;
|
|
349
349
|
oninvalid?: EventHandler<Event, T> | undefined | null;
|
|
350
350
|
onbeforeinput?: EventHandler<InputEvent, T> | undefined | null;
|
|
351
|
+
'on:formdata'?: EventHandler<FormDataEvent, T> | undefined | null;
|
|
351
352
|
|
|
352
353
|
// Image Events
|
|
353
354
|
onload?: EventHandler | undefined | null;
|
|
@@ -838,6 +839,11 @@ declare namespace svelte.JSX {
|
|
|
838
839
|
results?: number | undefined | null;
|
|
839
840
|
security?: string | undefined | null;
|
|
840
841
|
unselectable?: boolean | undefined | null;
|
|
842
|
+
|
|
843
|
+
'data-sveltekit-noscroll'?: true | '' | 'off' | undefined | null;
|
|
844
|
+
'data-sveltekit-preload-code'?: true | '' | 'eager' | 'viewport' | 'hover' | 'tap' | 'off' | undefined | null;
|
|
845
|
+
'data-sveltekit-preload-data'?: true | '' | 'hover' | 'tap' | 'off' | undefined | null;
|
|
846
|
+
'data-sveltekit-reload'?: true | '' | 'off' | undefined | null;
|
|
841
847
|
}
|
|
842
848
|
|
|
843
849
|
// this list is "complete" in that it contains every SVG attribute
|
|
@@ -1175,13 +1181,6 @@ declare namespace svelte.JSX {
|
|
|
1175
1181
|
sapperPrefetch?: true | undefined | null;
|
|
1176
1182
|
}
|
|
1177
1183
|
|
|
1178
|
-
interface SvelteKitAnchorProps {
|
|
1179
|
-
'data-sveltekit-noscroll'?: true | undefined | null;
|
|
1180
|
-
'data-sveltekit-preload-code'?: true | 'eager' | 'viewport' | 'hover' | 'tap' | 'off' | undefined | null;
|
|
1181
|
-
'data-sveltekit-preload-data'?: true | 'hover' | 'tap' | 'off' | undefined | null;
|
|
1182
|
-
'data-sveltekit-reload'?: true | undefined | null;
|
|
1183
|
-
}
|
|
1184
|
-
|
|
1185
1184
|
interface SvelteMediaTimeRange {
|
|
1186
1185
|
start: number;
|
|
1187
1186
|
end: number;
|
|
@@ -1220,7 +1219,7 @@ declare namespace svelte.JSX {
|
|
|
1220
1219
|
|
|
1221
1220
|
interface IntrinsicElements {
|
|
1222
1221
|
// HTML
|
|
1223
|
-
a: HTMLProps<HTMLAnchorElement> & SapperAnchorProps
|
|
1222
|
+
a: HTMLProps<HTMLAnchorElement> & SapperAnchorProps;
|
|
1224
1223
|
abbr: HTMLProps<HTMLElement>;
|
|
1225
1224
|
address: HTMLProps<HTMLElement>;
|
|
1226
1225
|
area: HTMLProps<HTMLAreaElement>;
|
|
@@ -1397,7 +1396,7 @@ declare namespace svelte.JSX {
|
|
|
1397
1396
|
sveltefragment: { slot?: string; };
|
|
1398
1397
|
svelteoptions: { [name: string]: any };
|
|
1399
1398
|
sveltehead: { [name: string]: any };
|
|
1400
|
-
svelteelement: { 'this': string | undefined | null; } & HTMLProps<any> & SVGProps<any> & SapperAnchorProps
|
|
1399
|
+
svelteelement: { 'this': string | undefined | null; } & HTMLProps<any> & SVGProps<any> & SapperAnchorProps;
|
|
1401
1400
|
// Needed due to backwards compatibility type which hits these
|
|
1402
1401
|
'svelte:window': HTMLProps<Window> & SvelteWindowProps;
|
|
1403
1402
|
'svelte:body': HTMLProps<HTMLElement>;
|
package/svelte-shims.d.ts
CHANGED
|
@@ -231,6 +231,7 @@ declare function __sveltets_2_createComponentAny(props: Record<string, any>): _S
|
|
|
231
231
|
declare function __sveltets_2_any(...dummy: any[]): any;
|
|
232
232
|
declare function __sveltets_2_empty(...dummy: any[]): {};
|
|
233
233
|
declare function __sveltets_2_union<T1,T2,T3,T4,T5>(t1:T1,t2?:T2,t3?:T3,t4?:T4,t5?:T5): T1 & T2 & T3 & T4 & T5;
|
|
234
|
+
declare function __sveltets_2_nonNullable<T>(type: T): NonNullable<T>;
|
|
234
235
|
|
|
235
236
|
declare function __sveltets_2_cssProp(prop: Record<string, any>): {};
|
|
236
237
|
|
|
@@ -295,7 +296,14 @@ declare type ATypedSvelteComponent = {
|
|
|
295
296
|
$on(event: string, handler: ((e: any) => any) | null | undefined): () => void;
|
|
296
297
|
}
|
|
297
298
|
/**
|
|
298
|
-
* Ambient type only used for intellisense, DO NOT USE IN YOUR PROJECT
|
|
299
|
+
* Ambient type only used for intellisense, DO NOT USE IN YOUR PROJECT.
|
|
300
|
+
*
|
|
301
|
+
* If you're looking for the type of a Svelte Component, use `SvelteComponentTyped` and `ComponentType` instead:
|
|
302
|
+
*
|
|
303
|
+
* ```ts
|
|
304
|
+
* import type { ComponentType, SvelteComponentTyped } from "svelte";
|
|
305
|
+
* let myComponentConstructor: ComponentType<SvelteComponentTyped> = ..;
|
|
306
|
+
* ```
|
|
299
307
|
*/
|
|
300
308
|
declare type ConstructorOfATypedSvelteComponent = new (args: {target: any, props?: any}) => ATypedSvelteComponent
|
|
301
309
|
declare function __sveltets_2_ensureComponent<T extends ConstructorOfATypedSvelteComponent | null | undefined>(type: T): NonNullable<T>;
|