svelte2tsx 0.5.22 → 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 +127 -46
- package/index.mjs +127 -46
- package/package.json +1 -1
- package/svelte-html-do-not-use.d.ts +6 -6
- package/svelte-jsx.d.ts +7 -9
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();
|
|
@@ -5585,8 +5631,9 @@ class ExportedNames {
|
|
|
5585
5631
|
* Creates a string from the collected props
|
|
5586
5632
|
*
|
|
5587
5633
|
* @param isTsFile Whether this is a TypeScript file or not.
|
|
5634
|
+
* @param uses$$propsValue whether the file references the $$props variable
|
|
5588
5635
|
*/
|
|
5589
|
-
createPropsStr(isTsFile) {
|
|
5636
|
+
createPropsStr(isTsFile, uses$$propsValue) {
|
|
5590
5637
|
const names = Array.from(this.exports.entries());
|
|
5591
5638
|
if (this.uses$$Props) {
|
|
5592
5639
|
const lets = names.filter(([, { isLet }]) => isLet);
|
|
@@ -5612,7 +5659,7 @@ class ExportedNames {
|
|
|
5612
5659
|
this.createReturnElementsType(others).join(',') +
|
|
5613
5660
|
'}}');
|
|
5614
5661
|
}
|
|
5615
|
-
if (names.length === 0) {
|
|
5662
|
+
if (names.length === 0 && !uses$$propsValue) {
|
|
5616
5663
|
// Necessary, because {} roughly equals to any
|
|
5617
5664
|
return isTsFile
|
|
5618
5665
|
? '{} as Record<string, never>'
|
|
@@ -6336,6 +6383,7 @@ class Generics {
|
|
|
6336
6383
|
this.str = str;
|
|
6337
6384
|
this.astOffset = astOffset;
|
|
6338
6385
|
this.definitions = [];
|
|
6386
|
+
this.typeReferences = [];
|
|
6339
6387
|
this.references = [];
|
|
6340
6388
|
}
|
|
6341
6389
|
addIfIsGeneric(node) {
|
|
@@ -6345,10 +6393,12 @@ class Generics {
|
|
|
6345
6393
|
throw new Error('Invalid $$Generic declaration: Only one type argument allowed');
|
|
6346
6394
|
}
|
|
6347
6395
|
if (((_b = node.type.typeArguments) === null || _b === void 0 ? void 0 : _b.length) === 1) {
|
|
6348
|
-
|
|
6396
|
+
const typeReference = node.type.typeArguments[0].getText();
|
|
6397
|
+
this.typeReferences.push(typeReference);
|
|
6398
|
+
this.definitions.push(`${node.name.text} extends ${typeReference}`);
|
|
6349
6399
|
}
|
|
6350
6400
|
else {
|
|
6351
|
-
this.definitions.push(
|
|
6401
|
+
this.definitions.push(node.name.text);
|
|
6352
6402
|
}
|
|
6353
6403
|
this.references.push(node.name.text);
|
|
6354
6404
|
this.str.remove(this.astOffset + node.getStart(), this.astOffset + node.getEnd());
|
|
@@ -6364,6 +6414,9 @@ class Generics {
|
|
|
6364
6414
|
ts__default['default'].isIdentifier(node.typeName) &&
|
|
6365
6415
|
node.typeName.text === '$$Generic');
|
|
6366
6416
|
}
|
|
6417
|
+
getTypeReferences() {
|
|
6418
|
+
return this.typeReferences;
|
|
6419
|
+
}
|
|
6367
6420
|
toDefinitionString(addIgnore = false) {
|
|
6368
6421
|
const surround = addIgnore ? surroundWithIgnoreComments : (str) => str;
|
|
6369
6422
|
return this.definitions.length ? surround(`<${this.definitions.join(',')}>`) : '';
|
|
@@ -6380,44 +6433,7 @@ class Generics {
|
|
|
6380
6433
|
* move imports to top of script so they appear outside our render function
|
|
6381
6434
|
*/
|
|
6382
6435
|
function handleImportDeclaration(node, str, astOffset, scriptStart, sourceFile) {
|
|
6383
|
-
|
|
6384
|
-
const scanner = ts__default['default'].createScanner(sourceFile.languageVersion,
|
|
6385
|
-
/*skipTrivia*/ false, sourceFile.languageVariant);
|
|
6386
|
-
const comments = (_a = ts__default['default'].getLeadingCommentRanges(node.getFullText(), 0)) !== null && _a !== void 0 ? _a : [];
|
|
6387
|
-
if (!comments.some((comment) => comment.hasTrailingNewLine) &&
|
|
6388
|
-
isNewGroup(sourceFile, node, scanner)) {
|
|
6389
|
-
str.appendRight(node.getStart() + astOffset, '\n');
|
|
6390
|
-
}
|
|
6391
|
-
for (const comment of comments) {
|
|
6392
|
-
const commentEnd = node.pos + comment.end + astOffset;
|
|
6393
|
-
str.move(node.pos + comment.pos + astOffset, commentEnd, scriptStart + 1);
|
|
6394
|
-
if (comment.hasTrailingNewLine) {
|
|
6395
|
-
str.overwrite(commentEnd - 1, commentEnd, str.original[commentEnd - 1] + '\n');
|
|
6396
|
-
}
|
|
6397
|
-
}
|
|
6398
|
-
str.move(node.getStart() + astOffset, node.end + astOffset, scriptStart + 1);
|
|
6399
|
-
//add in a \n
|
|
6400
|
-
const originalEndChar = str.original[node.end + astOffset - 1];
|
|
6401
|
-
str.overwrite(node.end + astOffset - 1, node.end + astOffset, originalEndChar + '\n');
|
|
6402
|
-
}
|
|
6403
|
-
/**
|
|
6404
|
-
* adopted from https://github.com/microsoft/TypeScript/blob/6e0447fdf165b1cec9fc80802abcc15bd23a268f/src/services/organizeImports.ts#L111
|
|
6405
|
-
*/
|
|
6406
|
-
function isNewGroup(sourceFile, topLevelImportDecl, scanner) {
|
|
6407
|
-
const startPos = topLevelImportDecl.getFullStart();
|
|
6408
|
-
const endPos = topLevelImportDecl.getStart();
|
|
6409
|
-
scanner.setText(sourceFile.text, startPos, endPos - startPos);
|
|
6410
|
-
let numberOfNewLines = 0;
|
|
6411
|
-
while (scanner.getTokenPos() < endPos) {
|
|
6412
|
-
const tokenKind = scanner.scan();
|
|
6413
|
-
if (tokenKind === ts__default['default'].SyntaxKind.NewLineTrivia) {
|
|
6414
|
-
numberOfNewLines++;
|
|
6415
|
-
if (numberOfNewLines >= 2) {
|
|
6416
|
-
return true;
|
|
6417
|
-
}
|
|
6418
|
-
}
|
|
6419
|
-
}
|
|
6420
|
-
return false;
|
|
6436
|
+
return moveNode(node, str, astOffset, scriptStart, sourceFile);
|
|
6421
6437
|
}
|
|
6422
6438
|
/**
|
|
6423
6439
|
* ensure it's in a newline.
|
|
@@ -6438,6 +6454,56 @@ function handleFirstInstanceImport(tsAst, astOffset, hasModuleScript, str) {
|
|
|
6438
6454
|
str.appendRight(start + astOffset, '\n' + (hasModuleScript ? '\n' : ''));
|
|
6439
6455
|
}
|
|
6440
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
|
+
|
|
6441
6507
|
function processInstanceScriptContent(str, script, events, implicitStoreValues, mode, hasModuleScript) {
|
|
6442
6508
|
const htmlx = str.original;
|
|
6443
6509
|
const scriptContent = htmlx.substring(script.content.start, script.content.end);
|
|
@@ -6445,6 +6511,7 @@ function processInstanceScriptContent(str, script, events, implicitStoreValues,
|
|
|
6445
6511
|
const astOffset = script.content.start;
|
|
6446
6512
|
const exportedNames = new ExportedNames(str, astOffset);
|
|
6447
6513
|
const generics = new Generics(str, astOffset);
|
|
6514
|
+
const interfacesAndTypes = new InterfacesAndTypes();
|
|
6448
6515
|
const implicitTopLevelNames = new ImplicitTopLevelNames(str, astOffset);
|
|
6449
6516
|
let uses$$props = false;
|
|
6450
6517
|
let uses$$restProps = false;
|
|
@@ -6580,6 +6647,11 @@ function processInstanceScriptContent(str, script, events, implicitStoreValues,
|
|
|
6580
6647
|
if (ts__namespace.isImportSpecifier(node)) {
|
|
6581
6648
|
implicitStoreValues.addImportStatement(node);
|
|
6582
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
|
+
}
|
|
6583
6655
|
//handle stores etc
|
|
6584
6656
|
if (ts__namespace.isIdentifier(node)) {
|
|
6585
6657
|
handleIdentifier(node, parent);
|
|
@@ -6615,12 +6687,18 @@ function processInstanceScriptContent(str, script, events, implicitStoreValues,
|
|
|
6615
6687
|
implicitTopLevelNames.modifyCode(rootScope.declared);
|
|
6616
6688
|
implicitStoreValues.modifyCode(astOffset, str);
|
|
6617
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
|
+
}
|
|
6618
6696
|
if (mode === 'dts') {
|
|
6619
6697
|
// Transform interface declarations to type declarations because indirectly
|
|
6620
6698
|
// using interfaces inside the return type of a function is forbidden.
|
|
6621
6699
|
// This is not a problem for intellisense/type inference but it will
|
|
6622
6700
|
// break dts generation (file will not be generated).
|
|
6623
|
-
transformInterfacesToTypes(tsAst, str, astOffset);
|
|
6701
|
+
transformInterfacesToTypes(tsAst, str, astOffset, nodesToMove);
|
|
6624
6702
|
}
|
|
6625
6703
|
return {
|
|
6626
6704
|
exportedNames,
|
|
@@ -6632,8 +6710,11 @@ function processInstanceScriptContent(str, script, events, implicitStoreValues,
|
|
|
6632
6710
|
generics
|
|
6633
6711
|
};
|
|
6634
6712
|
}
|
|
6635
|
-
function transformInterfacesToTypes(tsAst, str, astOffset) {
|
|
6636
|
-
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) => {
|
|
6637
6718
|
var _a;
|
|
6638
6719
|
str.overwrite(node.getStart() + astOffset, node.getStart() + astOffset + 'interface'.length, 'type');
|
|
6639
6720
|
if ((_a = node.heritageClauses) === null || _a === void 0 ? void 0 : _a.length) {
|
|
@@ -6908,7 +6989,7 @@ function createRenderFunction({ str, scriptTag, scriptDestination, slots, events
|
|
|
6908
6989
|
})
|
|
6909
6990
|
.join(', ') +
|
|
6910
6991
|
'}';
|
|
6911
|
-
const returnString = `\nreturn { props: ${exportedNames.createPropsStr(isTsFile)}` +
|
|
6992
|
+
const returnString = `\nreturn { props: ${exportedNames.createPropsStr(isTsFile, uses$$props)}` +
|
|
6912
6993
|
`, slots: ${slotsAsDef}` +
|
|
6913
6994
|
`, events: ${events.toDefString()} }}`;
|
|
6914
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();
|
|
@@ -5555,8 +5601,9 @@ class ExportedNames {
|
|
|
5555
5601
|
* Creates a string from the collected props
|
|
5556
5602
|
*
|
|
5557
5603
|
* @param isTsFile Whether this is a TypeScript file or not.
|
|
5604
|
+
* @param uses$$propsValue whether the file references the $$props variable
|
|
5558
5605
|
*/
|
|
5559
|
-
createPropsStr(isTsFile) {
|
|
5606
|
+
createPropsStr(isTsFile, uses$$propsValue) {
|
|
5560
5607
|
const names = Array.from(this.exports.entries());
|
|
5561
5608
|
if (this.uses$$Props) {
|
|
5562
5609
|
const lets = names.filter(([, { isLet }]) => isLet);
|
|
@@ -5582,7 +5629,7 @@ class ExportedNames {
|
|
|
5582
5629
|
this.createReturnElementsType(others).join(',') +
|
|
5583
5630
|
'}}');
|
|
5584
5631
|
}
|
|
5585
|
-
if (names.length === 0) {
|
|
5632
|
+
if (names.length === 0 && !uses$$propsValue) {
|
|
5586
5633
|
// Necessary, because {} roughly equals to any
|
|
5587
5634
|
return isTsFile
|
|
5588
5635
|
? '{} as Record<string, never>'
|
|
@@ -6306,6 +6353,7 @@ class Generics {
|
|
|
6306
6353
|
this.str = str;
|
|
6307
6354
|
this.astOffset = astOffset;
|
|
6308
6355
|
this.definitions = [];
|
|
6356
|
+
this.typeReferences = [];
|
|
6309
6357
|
this.references = [];
|
|
6310
6358
|
}
|
|
6311
6359
|
addIfIsGeneric(node) {
|
|
@@ -6315,10 +6363,12 @@ class Generics {
|
|
|
6315
6363
|
throw new Error('Invalid $$Generic declaration: Only one type argument allowed');
|
|
6316
6364
|
}
|
|
6317
6365
|
if (((_b = node.type.typeArguments) === null || _b === void 0 ? void 0 : _b.length) === 1) {
|
|
6318
|
-
|
|
6366
|
+
const typeReference = node.type.typeArguments[0].getText();
|
|
6367
|
+
this.typeReferences.push(typeReference);
|
|
6368
|
+
this.definitions.push(`${node.name.text} extends ${typeReference}`);
|
|
6319
6369
|
}
|
|
6320
6370
|
else {
|
|
6321
|
-
this.definitions.push(
|
|
6371
|
+
this.definitions.push(node.name.text);
|
|
6322
6372
|
}
|
|
6323
6373
|
this.references.push(node.name.text);
|
|
6324
6374
|
this.str.remove(this.astOffset + node.getStart(), this.astOffset + node.getEnd());
|
|
@@ -6334,6 +6384,9 @@ class Generics {
|
|
|
6334
6384
|
ts__default.isIdentifier(node.typeName) &&
|
|
6335
6385
|
node.typeName.text === '$$Generic');
|
|
6336
6386
|
}
|
|
6387
|
+
getTypeReferences() {
|
|
6388
|
+
return this.typeReferences;
|
|
6389
|
+
}
|
|
6337
6390
|
toDefinitionString(addIgnore = false) {
|
|
6338
6391
|
const surround = addIgnore ? surroundWithIgnoreComments : (str) => str;
|
|
6339
6392
|
return this.definitions.length ? surround(`<${this.definitions.join(',')}>`) : '';
|
|
@@ -6350,44 +6403,7 @@ class Generics {
|
|
|
6350
6403
|
* move imports to top of script so they appear outside our render function
|
|
6351
6404
|
*/
|
|
6352
6405
|
function handleImportDeclaration(node, str, astOffset, scriptStart, sourceFile) {
|
|
6353
|
-
|
|
6354
|
-
const scanner = ts__default.createScanner(sourceFile.languageVersion,
|
|
6355
|
-
/*skipTrivia*/ false, sourceFile.languageVariant);
|
|
6356
|
-
const comments = (_a = ts__default.getLeadingCommentRanges(node.getFullText(), 0)) !== null && _a !== void 0 ? _a : [];
|
|
6357
|
-
if (!comments.some((comment) => comment.hasTrailingNewLine) &&
|
|
6358
|
-
isNewGroup(sourceFile, node, scanner)) {
|
|
6359
|
-
str.appendRight(node.getStart() + astOffset, '\n');
|
|
6360
|
-
}
|
|
6361
|
-
for (const comment of comments) {
|
|
6362
|
-
const commentEnd = node.pos + comment.end + astOffset;
|
|
6363
|
-
str.move(node.pos + comment.pos + astOffset, commentEnd, scriptStart + 1);
|
|
6364
|
-
if (comment.hasTrailingNewLine) {
|
|
6365
|
-
str.overwrite(commentEnd - 1, commentEnd, str.original[commentEnd - 1] + '\n');
|
|
6366
|
-
}
|
|
6367
|
-
}
|
|
6368
|
-
str.move(node.getStart() + astOffset, node.end + astOffset, scriptStart + 1);
|
|
6369
|
-
//add in a \n
|
|
6370
|
-
const originalEndChar = str.original[node.end + astOffset - 1];
|
|
6371
|
-
str.overwrite(node.end + astOffset - 1, node.end + astOffset, originalEndChar + '\n');
|
|
6372
|
-
}
|
|
6373
|
-
/**
|
|
6374
|
-
* adopted from https://github.com/microsoft/TypeScript/blob/6e0447fdf165b1cec9fc80802abcc15bd23a268f/src/services/organizeImports.ts#L111
|
|
6375
|
-
*/
|
|
6376
|
-
function isNewGroup(sourceFile, topLevelImportDecl, scanner) {
|
|
6377
|
-
const startPos = topLevelImportDecl.getFullStart();
|
|
6378
|
-
const endPos = topLevelImportDecl.getStart();
|
|
6379
|
-
scanner.setText(sourceFile.text, startPos, endPos - startPos);
|
|
6380
|
-
let numberOfNewLines = 0;
|
|
6381
|
-
while (scanner.getTokenPos() < endPos) {
|
|
6382
|
-
const tokenKind = scanner.scan();
|
|
6383
|
-
if (tokenKind === ts__default.SyntaxKind.NewLineTrivia) {
|
|
6384
|
-
numberOfNewLines++;
|
|
6385
|
-
if (numberOfNewLines >= 2) {
|
|
6386
|
-
return true;
|
|
6387
|
-
}
|
|
6388
|
-
}
|
|
6389
|
-
}
|
|
6390
|
-
return false;
|
|
6406
|
+
return moveNode(node, str, astOffset, scriptStart, sourceFile);
|
|
6391
6407
|
}
|
|
6392
6408
|
/**
|
|
6393
6409
|
* ensure it's in a newline.
|
|
@@ -6408,6 +6424,56 @@ function handleFirstInstanceImport(tsAst, astOffset, hasModuleScript, str) {
|
|
|
6408
6424
|
str.appendRight(start + astOffset, '\n' + (hasModuleScript ? '\n' : ''));
|
|
6409
6425
|
}
|
|
6410
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
|
+
|
|
6411
6477
|
function processInstanceScriptContent(str, script, events, implicitStoreValues, mode, hasModuleScript) {
|
|
6412
6478
|
const htmlx = str.original;
|
|
6413
6479
|
const scriptContent = htmlx.substring(script.content.start, script.content.end);
|
|
@@ -6415,6 +6481,7 @@ function processInstanceScriptContent(str, script, events, implicitStoreValues,
|
|
|
6415
6481
|
const astOffset = script.content.start;
|
|
6416
6482
|
const exportedNames = new ExportedNames(str, astOffset);
|
|
6417
6483
|
const generics = new Generics(str, astOffset);
|
|
6484
|
+
const interfacesAndTypes = new InterfacesAndTypes();
|
|
6418
6485
|
const implicitTopLevelNames = new ImplicitTopLevelNames(str, astOffset);
|
|
6419
6486
|
let uses$$props = false;
|
|
6420
6487
|
let uses$$restProps = false;
|
|
@@ -6550,6 +6617,11 @@ function processInstanceScriptContent(str, script, events, implicitStoreValues,
|
|
|
6550
6617
|
if (ts.isImportSpecifier(node)) {
|
|
6551
6618
|
implicitStoreValues.addImportStatement(node);
|
|
6552
6619
|
}
|
|
6620
|
+
if (ts.isTypeAliasDeclaration(node) || ts.isInterfaceDeclaration(node)) {
|
|
6621
|
+
interfacesAndTypes.node = node;
|
|
6622
|
+
interfacesAndTypes.add(node);
|
|
6623
|
+
onLeaveCallbacks.push(() => (interfacesAndTypes.node = null));
|
|
6624
|
+
}
|
|
6553
6625
|
//handle stores etc
|
|
6554
6626
|
if (ts.isIdentifier(node)) {
|
|
6555
6627
|
handleIdentifier(node, parent);
|
|
@@ -6585,12 +6657,18 @@ function processInstanceScriptContent(str, script, events, implicitStoreValues,
|
|
|
6585
6657
|
implicitTopLevelNames.modifyCode(rootScope.declared);
|
|
6586
6658
|
implicitStoreValues.modifyCode(astOffset, str);
|
|
6587
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
|
+
}
|
|
6588
6666
|
if (mode === 'dts') {
|
|
6589
6667
|
// Transform interface declarations to type declarations because indirectly
|
|
6590
6668
|
// using interfaces inside the return type of a function is forbidden.
|
|
6591
6669
|
// This is not a problem for intellisense/type inference but it will
|
|
6592
6670
|
// break dts generation (file will not be generated).
|
|
6593
|
-
transformInterfacesToTypes(tsAst, str, astOffset);
|
|
6671
|
+
transformInterfacesToTypes(tsAst, str, astOffset, nodesToMove);
|
|
6594
6672
|
}
|
|
6595
6673
|
return {
|
|
6596
6674
|
exportedNames,
|
|
@@ -6602,8 +6680,11 @@ function processInstanceScriptContent(str, script, events, implicitStoreValues,
|
|
|
6602
6680
|
generics
|
|
6603
6681
|
};
|
|
6604
6682
|
}
|
|
6605
|
-
function transformInterfacesToTypes(tsAst, str, astOffset) {
|
|
6606
|
-
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) => {
|
|
6607
6688
|
var _a;
|
|
6608
6689
|
str.overwrite(node.getStart() + astOffset, node.getStart() + astOffset + 'interface'.length, 'type');
|
|
6609
6690
|
if ((_a = node.heritageClauses) === null || _a === void 0 ? void 0 : _a.length) {
|
|
@@ -6878,7 +6959,7 @@ function createRenderFunction({ str, scriptTag, scriptDestination, slots, events
|
|
|
6878
6959
|
})
|
|
6879
6960
|
.join(', ') +
|
|
6880
6961
|
'}';
|
|
6881
|
-
const returnString = `\nreturn { props: ${exportedNames.createPropsStr(isTsFile)}` +
|
|
6962
|
+
const returnString = `\nreturn { props: ${exportedNames.createPropsStr(isTsFile, uses$$props)}` +
|
|
6882
6963
|
`, slots: ${slotsAsDef}` +
|
|
6883
6964
|
`, events: ${events.toDefString()} }}`;
|
|
6884
6965
|
// wrap template with callback
|
package/package.json
CHANGED
|
@@ -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 | '' | 'off' | 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 | '' | 'off' | 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
|
@@ -839,6 +839,11 @@ declare namespace svelte.JSX {
|
|
|
839
839
|
results?: number | undefined | null;
|
|
840
840
|
security?: string | undefined | null;
|
|
841
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;
|
|
842
847
|
}
|
|
843
848
|
|
|
844
849
|
// this list is "complete" in that it contains every SVG attribute
|
|
@@ -1176,13 +1181,6 @@ declare namespace svelte.JSX {
|
|
|
1176
1181
|
sapperPrefetch?: true | undefined | null;
|
|
1177
1182
|
}
|
|
1178
1183
|
|
|
1179
|
-
interface SvelteKitAnchorProps {
|
|
1180
|
-
'data-sveltekit-noscroll'?: true | '' | 'off' | undefined | null;
|
|
1181
|
-
'data-sveltekit-preload-code'?: true | '' | 'eager' | 'viewport' | 'hover' | 'tap' | 'off' | undefined | null;
|
|
1182
|
-
'data-sveltekit-preload-data'?: true | '' | 'hover' | 'tap' | 'off' | undefined | null;
|
|
1183
|
-
'data-sveltekit-reload'?: true | '' | 'off' | undefined | null;
|
|
1184
|
-
}
|
|
1185
|
-
|
|
1186
1184
|
interface SvelteMediaTimeRange {
|
|
1187
1185
|
start: number;
|
|
1188
1186
|
end: number;
|
|
@@ -1221,7 +1219,7 @@ declare namespace svelte.JSX {
|
|
|
1221
1219
|
|
|
1222
1220
|
interface IntrinsicElements {
|
|
1223
1221
|
// HTML
|
|
1224
|
-
a: HTMLProps<HTMLAnchorElement> & SapperAnchorProps
|
|
1222
|
+
a: HTMLProps<HTMLAnchorElement> & SapperAnchorProps;
|
|
1225
1223
|
abbr: HTMLProps<HTMLElement>;
|
|
1226
1224
|
address: HTMLProps<HTMLElement>;
|
|
1227
1225
|
area: HTMLProps<HTMLAreaElement>;
|
|
@@ -1398,7 +1396,7 @@ declare namespace svelte.JSX {
|
|
|
1398
1396
|
sveltefragment: { slot?: string; };
|
|
1399
1397
|
svelteoptions: { [name: string]: any };
|
|
1400
1398
|
sveltehead: { [name: string]: any };
|
|
1401
|
-
svelteelement: { 'this': string | undefined | null; } & HTMLProps<any> & SVGProps<any> & SapperAnchorProps
|
|
1399
|
+
svelteelement: { 'this': string | undefined | null; } & HTMLProps<any> & SVGProps<any> & SapperAnchorProps;
|
|
1402
1400
|
// Needed due to backwards compatibility type which hits these
|
|
1403
1401
|
'svelte:window': HTMLProps<Window> & SvelteWindowProps;
|
|
1404
1402
|
'svelte:body': HTMLProps<HTMLElement>;
|