svelte2tsx 0.7.21 → 0.7.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.d.ts +7 -0
- package/index.js +109 -27
- package/index.mjs +110 -28
- package/package.json +2 -2
package/index.d.ts
CHANGED
|
@@ -134,6 +134,13 @@ export function emitDts(config: EmitDtsConfig): Promise<void>;
|
|
|
134
134
|
* static top level `ts` namespace, it must be passed as a parameter.
|
|
135
135
|
*/
|
|
136
136
|
export const internalHelpers: {
|
|
137
|
+
get_global_types: (
|
|
138
|
+
tsSystem: ts.System,
|
|
139
|
+
isSvelte3: boolean,
|
|
140
|
+
sveltePath: string,
|
|
141
|
+
typesPath: string,
|
|
142
|
+
hiddenFolderPath?: string,
|
|
143
|
+
) => string[],
|
|
137
144
|
isKitFile: (
|
|
138
145
|
fileName: string,
|
|
139
146
|
options: InternalHelpers.KitFilesSettings
|
package/index.js
CHANGED
|
@@ -4161,6 +4161,65 @@ function eventMapEntryToString([eventName, expression]) {
|
|
|
4161
4161
|
return `'${eventName}':${Array.isArray(expression) ? `__sveltets_2_unionType(${expression.join(',')})` : expression}`;
|
|
4162
4162
|
}
|
|
4163
4163
|
|
|
4164
|
+
/**
|
|
4165
|
+
* Returns the path to the global svelte2tsx files that should be included in the project.
|
|
4166
|
+
* Creates a hidden folder in the user's node_modules if `hiddenFolderPath` is provided.
|
|
4167
|
+
*/
|
|
4168
|
+
function get_global_types(tsSystem, isSvelte3, sveltePath, typesPath, hiddenFolderPath) {
|
|
4169
|
+
const svelteHtmlPath = isSvelte3 ? undefined : path.join(sveltePath, 'svelte-html.d.ts');
|
|
4170
|
+
const svelteHtmlPathExists = svelteHtmlPath && tsSystem.fileExists(svelteHtmlPath);
|
|
4171
|
+
const svelteHtmlFile = svelteHtmlPathExists ? svelteHtmlPath : './svelte-jsx-v4.d.ts';
|
|
4172
|
+
let svelteTsxFiles;
|
|
4173
|
+
if (isSvelte3) {
|
|
4174
|
+
svelteTsxFiles = ['./svelte-shims.d.ts', './svelte-jsx.d.ts', './svelte-native-jsx.d.ts'];
|
|
4175
|
+
}
|
|
4176
|
+
else {
|
|
4177
|
+
svelteTsxFiles = ['./svelte-shims-v4.d.ts', './svelte-native-jsx.d.ts'];
|
|
4178
|
+
if (!svelteHtmlPathExists) {
|
|
4179
|
+
svelteTsxFiles.push(svelteHtmlPath);
|
|
4180
|
+
}
|
|
4181
|
+
}
|
|
4182
|
+
svelteTsxFiles = svelteTsxFiles.map((f) => tsSystem.resolvePath(path.resolve(typesPath, f)));
|
|
4183
|
+
if (hiddenFolderPath) {
|
|
4184
|
+
try {
|
|
4185
|
+
// IDE context - the `import('svelte')` statements inside the d.ts files will load the Svelte version of
|
|
4186
|
+
// the extension, which can cause all sorts of problems. Therefore put the files into a hidden folder in
|
|
4187
|
+
// the user's node_modules, preferably next to the Svelte package.
|
|
4188
|
+
let path$1 = path.dirname(sveltePath);
|
|
4189
|
+
if (!tsSystem.directoryExists(path.resolve(path$1, 'node_modules'))) {
|
|
4190
|
+
path$1 = hiddenFolderPath;
|
|
4191
|
+
while (path$1 && !tsSystem.directoryExists(path.resolve(path$1, 'node_modules'))) {
|
|
4192
|
+
const parent = path.dirname(path$1);
|
|
4193
|
+
if (path$1 === parent) {
|
|
4194
|
+
path$1 = '';
|
|
4195
|
+
break;
|
|
4196
|
+
}
|
|
4197
|
+
path$1 = parent;
|
|
4198
|
+
}
|
|
4199
|
+
}
|
|
4200
|
+
if (path$1) {
|
|
4201
|
+
const hiddenPath = path.resolve(path$1, 'node_modules/.svelte2tsx-language-server-files');
|
|
4202
|
+
const newFiles = [];
|
|
4203
|
+
for (const f of svelteTsxFiles) {
|
|
4204
|
+
const hiddenFile = path.resolve(hiddenPath, path.basename(f));
|
|
4205
|
+
const existing = tsSystem.readFile(hiddenFile);
|
|
4206
|
+
const toWrite = tsSystem.readFile(f) || '';
|
|
4207
|
+
if (existing !== toWrite) {
|
|
4208
|
+
tsSystem.writeFile(hiddenFile, toWrite);
|
|
4209
|
+
}
|
|
4210
|
+
newFiles.push(hiddenFile);
|
|
4211
|
+
}
|
|
4212
|
+
svelteTsxFiles = newFiles;
|
|
4213
|
+
}
|
|
4214
|
+
}
|
|
4215
|
+
catch (e) { }
|
|
4216
|
+
}
|
|
4217
|
+
if (svelteHtmlPathExists) {
|
|
4218
|
+
svelteTsxFiles.push(tsSystem.resolvePath(path.resolve(typesPath, svelteHtmlFile)));
|
|
4219
|
+
}
|
|
4220
|
+
return svelteTsxFiles;
|
|
4221
|
+
}
|
|
4222
|
+
|
|
4164
4223
|
/**
|
|
4165
4224
|
* Finds the top level const/let/function exports of a source file.
|
|
4166
4225
|
*/
|
|
@@ -4209,7 +4268,8 @@ function findExports(ts, source, isTsFile) {
|
|
|
4209
4268
|
hasTypeDefinition: hasTypeDefinition || hasTypedParameter(ts, node, isTsFile)
|
|
4210
4269
|
});
|
|
4211
4270
|
}
|
|
4212
|
-
else {
|
|
4271
|
+
else if (ts.isIdentifier(declaration.name)) {
|
|
4272
|
+
// TODO support `export const { x, y } = ...` ?
|
|
4213
4273
|
exports.set(declaration.name.getText(), {
|
|
4214
4274
|
type: 'var',
|
|
4215
4275
|
node: declaration,
|
|
@@ -4306,6 +4366,12 @@ function upsertKitRouteFile(ts, basename, getSource, surround) {
|
|
|
4306
4366
|
const inserted = surround(`: import('./$types.js').${basename.includes('layout') ? 'Layout' : 'Page'}${basename.includes('server') ? 'Server' : ''}LoadEvent`);
|
|
4307
4367
|
insert(pos, inserted);
|
|
4308
4368
|
}
|
|
4369
|
+
else if ((load === null || load === void 0 ? void 0 : load.type) === 'var' && !load.hasTypeDefinition) {
|
|
4370
|
+
// "const load = ..." will be transformed into
|
|
4371
|
+
// "const load = (...) satisfies PageLoad"
|
|
4372
|
+
insert(load.node.initializer.getStart(), surround('('));
|
|
4373
|
+
insert(load.node.initializer.getEnd(), surround(`) satisfies import('./$types.js').${basename.includes('layout') ? 'Layout' : 'Page'}${basename.includes('server') ? 'Server' : ''}Load`));
|
|
4374
|
+
}
|
|
4309
4375
|
// add type to entries function if not explicitly typed
|
|
4310
4376
|
const entries = exports.get('entries');
|
|
4311
4377
|
if ((entries === null || entries === void 0 ? void 0 : entries.type) === 'function' &&
|
|
@@ -4507,7 +4573,8 @@ const internalHelpers = {
|
|
|
4507
4573
|
upsertKitFile,
|
|
4508
4574
|
toVirtualPos,
|
|
4509
4575
|
toOriginalPos,
|
|
4510
|
-
findExports
|
|
4576
|
+
findExports,
|
|
4577
|
+
get_global_types
|
|
4511
4578
|
};
|
|
4512
4579
|
|
|
4513
4580
|
/**
|
|
@@ -4549,12 +4616,13 @@ function is$$PropsDeclaration(node) {
|
|
|
4549
4616
|
return isInterfaceOrTypeDeclaration(node) && node.name.text === '$$Props';
|
|
4550
4617
|
}
|
|
4551
4618
|
class ExportedNames {
|
|
4552
|
-
constructor(str, astOffset, basename, isTsFile, isSvelte5Plus) {
|
|
4619
|
+
constructor(str, astOffset, basename, isTsFile, isSvelte5Plus, isRunes) {
|
|
4553
4620
|
this.str = str;
|
|
4554
4621
|
this.astOffset = astOffset;
|
|
4555
4622
|
this.basename = basename;
|
|
4556
4623
|
this.isTsFile = isTsFile;
|
|
4557
4624
|
this.isSvelte5Plus = isSvelte5Plus;
|
|
4625
|
+
this.isRunes = isRunes;
|
|
4558
4626
|
this.usesAccessors = false;
|
|
4559
4627
|
/**
|
|
4560
4628
|
* Uses the `$$Props` type
|
|
@@ -4636,10 +4704,10 @@ class ExportedNames {
|
|
|
4636
4704
|
if (ts.isNamedExports(exportClause)) {
|
|
4637
4705
|
for (const ne of exportClause.elements) {
|
|
4638
4706
|
if (ne.propertyName) {
|
|
4639
|
-
this.addExport(ne.propertyName, false, ne.name);
|
|
4707
|
+
this.addExport(ne.propertyName, false, ne.name, undefined, undefined, true);
|
|
4640
4708
|
}
|
|
4641
4709
|
else {
|
|
4642
|
-
this.addExport(ne.name, false);
|
|
4710
|
+
this.addExport(ne.name, false, undefined, undefined, undefined, true);
|
|
4643
4711
|
}
|
|
4644
4712
|
}
|
|
4645
4713
|
//we can remove entire statement
|
|
@@ -4772,7 +4840,11 @@ class ExportedNames {
|
|
|
4772
4840
|
? 'boolean'
|
|
4773
4841
|
: ts.isIdentifier(element.initializer)
|
|
4774
4842
|
? `typeof ${element.initializer.text}`
|
|
4775
|
-
:
|
|
4843
|
+
: ts.isObjectLiteralExpression(element.initializer)
|
|
4844
|
+
? 'Record<string, unknown>'
|
|
4845
|
+
: ts.isArrayLiteralExpression(element.initializer)
|
|
4846
|
+
? 'unknown[]'
|
|
4847
|
+
: 'unknown';
|
|
4776
4848
|
props.push(`${name}?: ${type}`);
|
|
4777
4849
|
}
|
|
4778
4850
|
else {
|
|
@@ -4976,7 +5048,7 @@ class ExportedNames {
|
|
|
4976
5048
|
/**
|
|
4977
5049
|
* Adds export to map
|
|
4978
5050
|
*/
|
|
4979
|
-
addExport(name, isLet, target = null, type = null, required = false) {
|
|
5051
|
+
addExport(name, isLet, target = null, type = null, required = false, isNamedExport = false) {
|
|
4980
5052
|
const existingDeclaration = this.possibleExports.get(name.text);
|
|
4981
5053
|
if (target) {
|
|
4982
5054
|
this.exports.set(name.text, {
|
|
@@ -4984,7 +5056,8 @@ class ExportedNames {
|
|
|
4984
5056
|
type: (type === null || type === void 0 ? void 0 : type.getText()) || (existingDeclaration === null || existingDeclaration === void 0 ? void 0 : existingDeclaration.type),
|
|
4985
5057
|
identifierText: target.text,
|
|
4986
5058
|
required: required || (existingDeclaration === null || existingDeclaration === void 0 ? void 0 : existingDeclaration.required),
|
|
4987
|
-
doc: this.getDoc(target) || (existingDeclaration === null || existingDeclaration === void 0 ? void 0 : existingDeclaration.doc)
|
|
5059
|
+
doc: this.getDoc(target) || (existingDeclaration === null || existingDeclaration === void 0 ? void 0 : existingDeclaration.doc),
|
|
5060
|
+
isNamedExport
|
|
4988
5061
|
});
|
|
4989
5062
|
}
|
|
4990
5063
|
else {
|
|
@@ -4992,7 +5065,8 @@ class ExportedNames {
|
|
|
4992
5065
|
isLet: isLet || (existingDeclaration === null || existingDeclaration === void 0 ? void 0 : existingDeclaration.isLet),
|
|
4993
5066
|
type: existingDeclaration === null || existingDeclaration === void 0 ? void 0 : existingDeclaration.type,
|
|
4994
5067
|
required: existingDeclaration === null || existingDeclaration === void 0 ? void 0 : existingDeclaration.required,
|
|
4995
|
-
doc: existingDeclaration === null || existingDeclaration === void 0 ? void 0 : existingDeclaration.doc
|
|
5068
|
+
doc: existingDeclaration === null || existingDeclaration === void 0 ? void 0 : existingDeclaration.doc,
|
|
5069
|
+
isNamedExport
|
|
4996
5070
|
});
|
|
4997
5071
|
}
|
|
4998
5072
|
if (existingDeclaration === null || existingDeclaration === void 0 ? void 0 : existingDeclaration.isLet) {
|
|
@@ -5103,7 +5177,7 @@ class ExportedNames {
|
|
|
5103
5177
|
*/
|
|
5104
5178
|
createExportsStr() {
|
|
5105
5179
|
const names = Array.from(this.exports.entries());
|
|
5106
|
-
const others = names.filter(([, { isLet }]) => !isLet);
|
|
5180
|
+
const others = names.filter(([, { isLet, isNamedExport }]) => !isLet || (this.usesRunes() && isNamedExport));
|
|
5107
5181
|
const needsAccessors = this.usesAccessors && names.length > 0 && !this.usesRunes(); // runes mode doesn't support accessors
|
|
5108
5182
|
if (this.isSvelte5Plus) {
|
|
5109
5183
|
let str = '';
|
|
@@ -5175,7 +5249,7 @@ class ExportedNames {
|
|
|
5175
5249
|
this.isSvelte5Plus && globals.some((global) => runes.includes(global));
|
|
5176
5250
|
}
|
|
5177
5251
|
usesRunes() {
|
|
5178
|
-
return this.hasRunesGlobals || this.hasPropsRune();
|
|
5252
|
+
return this.hasRunesGlobals || this.hasPropsRune() || this.isRunes;
|
|
5179
5253
|
}
|
|
5180
5254
|
}
|
|
5181
5255
|
|
|
@@ -6135,12 +6209,12 @@ class InterfacesAndTypes {
|
|
|
6135
6209
|
}
|
|
6136
6210
|
}
|
|
6137
6211
|
|
|
6138
|
-
function processInstanceScriptContent(str, script, events, implicitStoreValues, mode, hasModuleScript, isTSFile, basename, isSvelte5Plus) {
|
|
6212
|
+
function processInstanceScriptContent(str, script, events, implicitStoreValues, mode, hasModuleScript, isTSFile, basename, isSvelte5Plus, isRunes) {
|
|
6139
6213
|
const htmlx = str.original;
|
|
6140
6214
|
const scriptContent = htmlx.substring(script.content.start, script.content.end);
|
|
6141
6215
|
const tsAst = ts.createSourceFile('component.ts.svelte', scriptContent, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
6142
6216
|
const astOffset = script.content.start;
|
|
6143
|
-
const exportedNames = new ExportedNames(str, astOffset, basename, isTSFile, isSvelte5Plus);
|
|
6217
|
+
const exportedNames = new ExportedNames(str, astOffset, basename, isTSFile, isSvelte5Plus, isRunes);
|
|
6144
6218
|
const generics = new Generics(str, astOffset, script);
|
|
6145
6219
|
const interfacesAndTypes = new InterfacesAndTypes();
|
|
6146
6220
|
const implicitTopLevelNames = new ImplicitTopLevelNames(str, astOffset);
|
|
@@ -6536,12 +6610,14 @@ function addSimpleComponentExport({ events, isTsFile, canHaveAnyProp, exportedNa
|
|
|
6536
6610
|
const propDef = props(isTsFile, canHaveAnyProp, exportedNames, _events(events.hasStrictEvents(), 'render()'));
|
|
6537
6611
|
const doc = componentDocumentation.getFormatted();
|
|
6538
6612
|
const className = fileName && classNameFromFilename(fileName, mode !== 'dts');
|
|
6613
|
+
const componentName = className || '$$Component';
|
|
6539
6614
|
let statement;
|
|
6540
6615
|
if (mode === 'dts') {
|
|
6541
6616
|
if (isSvelte5 && exportedNames.usesRunes() && !usesSlots && !events.hasEvents()) {
|
|
6542
6617
|
statement =
|
|
6543
|
-
`\n${doc}const ${
|
|
6544
|
-
`
|
|
6618
|
+
`\n${doc}const ${componentName} = __sveltets_2_fn_component(render());\n` +
|
|
6619
|
+
`type ${componentName} = ReturnType<typeof ${componentName}>;\n` +
|
|
6620
|
+
`export default ${componentName};`;
|
|
6545
6621
|
}
|
|
6546
6622
|
else if (isSvelte5) {
|
|
6547
6623
|
// Inline definitions from Svelte shims; else dts files will reference the globals which will be unresolved
|
|
@@ -6565,9 +6641,9 @@ function addSimpleComponentExport({ events, isTsFile, canHaveAnyProp, exportedNa
|
|
|
6565
6641
|
declare function $$__sveltets_2_isomorphic_component<
|
|
6566
6642
|
Props extends Record<string, any>, Events extends Record<string, any>, Slots extends Record<string, any>, Exports extends Record<string, any>, Bindings extends string
|
|
6567
6643
|
>(klass: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }): $$__sveltets_2_IsomorphicComponent<Props, Events, Slots, Exports, Bindings>;\n`) +
|
|
6568
|
-
`${doc}const ${
|
|
6569
|
-
surroundWithIgnoreComments(`type ${
|
|
6570
|
-
`export default ${
|
|
6644
|
+
`${doc}const ${componentName} = $$__sveltets_2_isomorphic_component${usesSlots ? '_slots' : ''}(${propDef});\n` +
|
|
6645
|
+
surroundWithIgnoreComments(`type ${componentName} = InstanceType<typeof ${componentName}>;\n`) +
|
|
6646
|
+
`export default ${componentName};`;
|
|
6571
6647
|
}
|
|
6572
6648
|
else if (isTsFile) {
|
|
6573
6649
|
const svelteComponentClass = noSvelteComponentTyped
|
|
@@ -6602,14 +6678,15 @@ declare function $$__sveltets_2_isomorphic_component<
|
|
|
6602
6678
|
if (isSvelte5) {
|
|
6603
6679
|
if (exportedNames.usesRunes() && !usesSlots && !events.hasEvents()) {
|
|
6604
6680
|
statement =
|
|
6605
|
-
`\n${doc}const ${
|
|
6606
|
-
`
|
|
6681
|
+
`\n${doc}const ${componentName} = __sveltets_2_fn_component(render());\n` +
|
|
6682
|
+
`type ${componentName} = ReturnType<typeof ${componentName}>;\n` +
|
|
6683
|
+
`export default ${componentName};`;
|
|
6607
6684
|
}
|
|
6608
6685
|
else {
|
|
6609
6686
|
statement =
|
|
6610
|
-
`\n${doc}const ${
|
|
6611
|
-
surroundWithIgnoreComments(`type ${
|
|
6612
|
-
`export default ${
|
|
6687
|
+
`\n${doc}const ${componentName} = __sveltets_2_isomorphic_component${usesSlots ? '_slots' : ''}(${propDef});\n` +
|
|
6688
|
+
surroundWithIgnoreComments(`type ${componentName} = InstanceType<typeof ${componentName}>;\n`) +
|
|
6689
|
+
`export default ${componentName};`;
|
|
6613
6690
|
}
|
|
6614
6691
|
}
|
|
6615
6692
|
else {
|
|
@@ -6781,6 +6858,7 @@ function processSvelteTemplate(str, parse, options) {
|
|
|
6781
6858
|
let uses$$restProps = false;
|
|
6782
6859
|
let uses$$slots = false;
|
|
6783
6860
|
let usesAccessors = !!options.accessors;
|
|
6861
|
+
let isRunes = false;
|
|
6784
6862
|
const componentDocumentation = new ComponentDocumentation();
|
|
6785
6863
|
//track if we are in a declaration scope
|
|
6786
6864
|
const isDeclaration = { value: false };
|
|
@@ -6804,6 +6882,9 @@ function processSvelteTemplate(str, parse, options) {
|
|
|
6804
6882
|
usesAccessors = true;
|
|
6805
6883
|
}
|
|
6806
6884
|
break;
|
|
6885
|
+
case 'runes':
|
|
6886
|
+
isRunes = true;
|
|
6887
|
+
break;
|
|
6807
6888
|
}
|
|
6808
6889
|
}
|
|
6809
6890
|
};
|
|
@@ -6983,7 +7064,8 @@ function processSvelteTemplate(str, parse, options) {
|
|
|
6983
7064
|
uses$$slots,
|
|
6984
7065
|
componentDocumentation,
|
|
6985
7066
|
resolvedStores,
|
|
6986
|
-
usesAccessors
|
|
7067
|
+
usesAccessors,
|
|
7068
|
+
isRunes
|
|
6987
7069
|
};
|
|
6988
7070
|
}
|
|
6989
7071
|
function svelte2tsx(svelte, options = { parse: compiler.parse }) {
|
|
@@ -6993,7 +7075,7 @@ function svelte2tsx(svelte, options = { parse: compiler.parse }) {
|
|
|
6993
7075
|
const basename = path.basename(options.filename || '');
|
|
6994
7076
|
const svelte5Plus = Number(options.version[0]) > 4;
|
|
6995
7077
|
// process the htmlx as a svelte template
|
|
6996
|
-
let { htmlAst, moduleScriptTag, scriptTag, rootSnippets, slots, uses$$props, uses$$slots, uses$$restProps, events, componentDocumentation, resolvedStores, usesAccessors } = processSvelteTemplate(str, options.parse || compiler.parse, {
|
|
7078
|
+
let { htmlAst, moduleScriptTag, scriptTag, rootSnippets, slots, uses$$props, uses$$slots, uses$$restProps, events, componentDocumentation, resolvedStores, usesAccessors, isRunes } = processSvelteTemplate(str, options.parse || compiler.parse, {
|
|
6997
7079
|
...options,
|
|
6998
7080
|
svelte5Plus
|
|
6999
7081
|
});
|
|
@@ -7018,7 +7100,7 @@ function svelte2tsx(svelte, options = { parse: compiler.parse }) {
|
|
|
7018
7100
|
: instanceScriptTarget;
|
|
7019
7101
|
const implicitStoreValues = new ImplicitStoreValues(resolvedStores, renderFunctionStart);
|
|
7020
7102
|
//move the instance script and process the content
|
|
7021
|
-
let exportedNames = new ExportedNames(str, 0, basename, options === null || options === void 0 ? void 0 : options.isTsFile, svelte5Plus);
|
|
7103
|
+
let exportedNames = new ExportedNames(str, 0, basename, options === null || options === void 0 ? void 0 : options.isTsFile, svelte5Plus, isRunes);
|
|
7022
7104
|
let generics = new Generics(str, 0, { attributes: [] });
|
|
7023
7105
|
let uses$$SlotsInterface = false;
|
|
7024
7106
|
if (scriptTag) {
|
|
@@ -7027,7 +7109,7 @@ function svelte2tsx(svelte, options = { parse: compiler.parse }) {
|
|
|
7027
7109
|
str.move(scriptTag.start, scriptTag.end, instanceScriptTarget);
|
|
7028
7110
|
}
|
|
7029
7111
|
const res = processInstanceScriptContent(str, scriptTag, events, implicitStoreValues, options.mode,
|
|
7030
|
-
/**hasModuleScripts */ !!moduleScriptTag, options === null || options === void 0 ? void 0 : options.isTsFile, basename, svelte5Plus);
|
|
7112
|
+
/**hasModuleScripts */ !!moduleScriptTag, options === null || options === void 0 ? void 0 : options.isTsFile, basename, svelte5Plus, isRunes);
|
|
7031
7113
|
uses$$props = uses$$props || res.uses$$props;
|
|
7032
7114
|
uses$$restProps = uses$$restProps || res.uses$$restProps;
|
|
7033
7115
|
uses$$slots = uses$$slots || res.uses$$slots;
|
package/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import dedent from 'dedent-js';
|
|
2
2
|
import ts from 'typescript';
|
|
3
3
|
import * as path from 'path';
|
|
4
|
-
import path__default from 'path';
|
|
4
|
+
import path__default, { join, resolve, dirname, basename } from 'path';
|
|
5
5
|
import { pascalCase } from 'pascal-case';
|
|
6
6
|
import { VERSION, parse } from 'svelte/compiler';
|
|
7
7
|
|
|
@@ -4141,6 +4141,65 @@ function eventMapEntryToString([eventName, expression]) {
|
|
|
4141
4141
|
return `'${eventName}':${Array.isArray(expression) ? `__sveltets_2_unionType(${expression.join(',')})` : expression}`;
|
|
4142
4142
|
}
|
|
4143
4143
|
|
|
4144
|
+
/**
|
|
4145
|
+
* Returns the path to the global svelte2tsx files that should be included in the project.
|
|
4146
|
+
* Creates a hidden folder in the user's node_modules if `hiddenFolderPath` is provided.
|
|
4147
|
+
*/
|
|
4148
|
+
function get_global_types(tsSystem, isSvelte3, sveltePath, typesPath, hiddenFolderPath) {
|
|
4149
|
+
const svelteHtmlPath = isSvelte3 ? undefined : join(sveltePath, 'svelte-html.d.ts');
|
|
4150
|
+
const svelteHtmlPathExists = svelteHtmlPath && tsSystem.fileExists(svelteHtmlPath);
|
|
4151
|
+
const svelteHtmlFile = svelteHtmlPathExists ? svelteHtmlPath : './svelte-jsx-v4.d.ts';
|
|
4152
|
+
let svelteTsxFiles;
|
|
4153
|
+
if (isSvelte3) {
|
|
4154
|
+
svelteTsxFiles = ['./svelte-shims.d.ts', './svelte-jsx.d.ts', './svelte-native-jsx.d.ts'];
|
|
4155
|
+
}
|
|
4156
|
+
else {
|
|
4157
|
+
svelteTsxFiles = ['./svelte-shims-v4.d.ts', './svelte-native-jsx.d.ts'];
|
|
4158
|
+
if (!svelteHtmlPathExists) {
|
|
4159
|
+
svelteTsxFiles.push(svelteHtmlPath);
|
|
4160
|
+
}
|
|
4161
|
+
}
|
|
4162
|
+
svelteTsxFiles = svelteTsxFiles.map((f) => tsSystem.resolvePath(resolve(typesPath, f)));
|
|
4163
|
+
if (hiddenFolderPath) {
|
|
4164
|
+
try {
|
|
4165
|
+
// IDE context - the `import('svelte')` statements inside the d.ts files will load the Svelte version of
|
|
4166
|
+
// the extension, which can cause all sorts of problems. Therefore put the files into a hidden folder in
|
|
4167
|
+
// the user's node_modules, preferably next to the Svelte package.
|
|
4168
|
+
let path = dirname(sveltePath);
|
|
4169
|
+
if (!tsSystem.directoryExists(resolve(path, 'node_modules'))) {
|
|
4170
|
+
path = hiddenFolderPath;
|
|
4171
|
+
while (path && !tsSystem.directoryExists(resolve(path, 'node_modules'))) {
|
|
4172
|
+
const parent = dirname(path);
|
|
4173
|
+
if (path === parent) {
|
|
4174
|
+
path = '';
|
|
4175
|
+
break;
|
|
4176
|
+
}
|
|
4177
|
+
path = parent;
|
|
4178
|
+
}
|
|
4179
|
+
}
|
|
4180
|
+
if (path) {
|
|
4181
|
+
const hiddenPath = resolve(path, 'node_modules/.svelte2tsx-language-server-files');
|
|
4182
|
+
const newFiles = [];
|
|
4183
|
+
for (const f of svelteTsxFiles) {
|
|
4184
|
+
const hiddenFile = resolve(hiddenPath, basename(f));
|
|
4185
|
+
const existing = tsSystem.readFile(hiddenFile);
|
|
4186
|
+
const toWrite = tsSystem.readFile(f) || '';
|
|
4187
|
+
if (existing !== toWrite) {
|
|
4188
|
+
tsSystem.writeFile(hiddenFile, toWrite);
|
|
4189
|
+
}
|
|
4190
|
+
newFiles.push(hiddenFile);
|
|
4191
|
+
}
|
|
4192
|
+
svelteTsxFiles = newFiles;
|
|
4193
|
+
}
|
|
4194
|
+
}
|
|
4195
|
+
catch (e) { }
|
|
4196
|
+
}
|
|
4197
|
+
if (svelteHtmlPathExists) {
|
|
4198
|
+
svelteTsxFiles.push(tsSystem.resolvePath(resolve(typesPath, svelteHtmlFile)));
|
|
4199
|
+
}
|
|
4200
|
+
return svelteTsxFiles;
|
|
4201
|
+
}
|
|
4202
|
+
|
|
4144
4203
|
/**
|
|
4145
4204
|
* Finds the top level const/let/function exports of a source file.
|
|
4146
4205
|
*/
|
|
@@ -4189,7 +4248,8 @@ function findExports(ts, source, isTsFile) {
|
|
|
4189
4248
|
hasTypeDefinition: hasTypeDefinition || hasTypedParameter(ts, node, isTsFile)
|
|
4190
4249
|
});
|
|
4191
4250
|
}
|
|
4192
|
-
else {
|
|
4251
|
+
else if (ts.isIdentifier(declaration.name)) {
|
|
4252
|
+
// TODO support `export const { x, y } = ...` ?
|
|
4193
4253
|
exports.set(declaration.name.getText(), {
|
|
4194
4254
|
type: 'var',
|
|
4195
4255
|
node: declaration,
|
|
@@ -4286,6 +4346,12 @@ function upsertKitRouteFile(ts, basename, getSource, surround) {
|
|
|
4286
4346
|
const inserted = surround(`: import('./$types.js').${basename.includes('layout') ? 'Layout' : 'Page'}${basename.includes('server') ? 'Server' : ''}LoadEvent`);
|
|
4287
4347
|
insert(pos, inserted);
|
|
4288
4348
|
}
|
|
4349
|
+
else if ((load === null || load === void 0 ? void 0 : load.type) === 'var' && !load.hasTypeDefinition) {
|
|
4350
|
+
// "const load = ..." will be transformed into
|
|
4351
|
+
// "const load = (...) satisfies PageLoad"
|
|
4352
|
+
insert(load.node.initializer.getStart(), surround('('));
|
|
4353
|
+
insert(load.node.initializer.getEnd(), surround(`) satisfies import('./$types.js').${basename.includes('layout') ? 'Layout' : 'Page'}${basename.includes('server') ? 'Server' : ''}Load`));
|
|
4354
|
+
}
|
|
4289
4355
|
// add type to entries function if not explicitly typed
|
|
4290
4356
|
const entries = exports.get('entries');
|
|
4291
4357
|
if ((entries === null || entries === void 0 ? void 0 : entries.type) === 'function' &&
|
|
@@ -4487,7 +4553,8 @@ const internalHelpers = {
|
|
|
4487
4553
|
upsertKitFile,
|
|
4488
4554
|
toVirtualPos,
|
|
4489
4555
|
toOriginalPos,
|
|
4490
|
-
findExports
|
|
4556
|
+
findExports,
|
|
4557
|
+
get_global_types
|
|
4491
4558
|
};
|
|
4492
4559
|
|
|
4493
4560
|
/**
|
|
@@ -4529,12 +4596,13 @@ function is$$PropsDeclaration(node) {
|
|
|
4529
4596
|
return isInterfaceOrTypeDeclaration(node) && node.name.text === '$$Props';
|
|
4530
4597
|
}
|
|
4531
4598
|
class ExportedNames {
|
|
4532
|
-
constructor(str, astOffset, basename, isTsFile, isSvelte5Plus) {
|
|
4599
|
+
constructor(str, astOffset, basename, isTsFile, isSvelte5Plus, isRunes) {
|
|
4533
4600
|
this.str = str;
|
|
4534
4601
|
this.astOffset = astOffset;
|
|
4535
4602
|
this.basename = basename;
|
|
4536
4603
|
this.isTsFile = isTsFile;
|
|
4537
4604
|
this.isSvelte5Plus = isSvelte5Plus;
|
|
4605
|
+
this.isRunes = isRunes;
|
|
4538
4606
|
this.usesAccessors = false;
|
|
4539
4607
|
/**
|
|
4540
4608
|
* Uses the `$$Props` type
|
|
@@ -4616,10 +4684,10 @@ class ExportedNames {
|
|
|
4616
4684
|
if (ts.isNamedExports(exportClause)) {
|
|
4617
4685
|
for (const ne of exportClause.elements) {
|
|
4618
4686
|
if (ne.propertyName) {
|
|
4619
|
-
this.addExport(ne.propertyName, false, ne.name);
|
|
4687
|
+
this.addExport(ne.propertyName, false, ne.name, undefined, undefined, true);
|
|
4620
4688
|
}
|
|
4621
4689
|
else {
|
|
4622
|
-
this.addExport(ne.name, false);
|
|
4690
|
+
this.addExport(ne.name, false, undefined, undefined, undefined, true);
|
|
4623
4691
|
}
|
|
4624
4692
|
}
|
|
4625
4693
|
//we can remove entire statement
|
|
@@ -4752,7 +4820,11 @@ class ExportedNames {
|
|
|
4752
4820
|
? 'boolean'
|
|
4753
4821
|
: ts.isIdentifier(element.initializer)
|
|
4754
4822
|
? `typeof ${element.initializer.text}`
|
|
4755
|
-
:
|
|
4823
|
+
: ts.isObjectLiteralExpression(element.initializer)
|
|
4824
|
+
? 'Record<string, unknown>'
|
|
4825
|
+
: ts.isArrayLiteralExpression(element.initializer)
|
|
4826
|
+
? 'unknown[]'
|
|
4827
|
+
: 'unknown';
|
|
4756
4828
|
props.push(`${name}?: ${type}`);
|
|
4757
4829
|
}
|
|
4758
4830
|
else {
|
|
@@ -4956,7 +5028,7 @@ class ExportedNames {
|
|
|
4956
5028
|
/**
|
|
4957
5029
|
* Adds export to map
|
|
4958
5030
|
*/
|
|
4959
|
-
addExport(name, isLet, target = null, type = null, required = false) {
|
|
5031
|
+
addExport(name, isLet, target = null, type = null, required = false, isNamedExport = false) {
|
|
4960
5032
|
const existingDeclaration = this.possibleExports.get(name.text);
|
|
4961
5033
|
if (target) {
|
|
4962
5034
|
this.exports.set(name.text, {
|
|
@@ -4964,7 +5036,8 @@ class ExportedNames {
|
|
|
4964
5036
|
type: (type === null || type === void 0 ? void 0 : type.getText()) || (existingDeclaration === null || existingDeclaration === void 0 ? void 0 : existingDeclaration.type),
|
|
4965
5037
|
identifierText: target.text,
|
|
4966
5038
|
required: required || (existingDeclaration === null || existingDeclaration === void 0 ? void 0 : existingDeclaration.required),
|
|
4967
|
-
doc: this.getDoc(target) || (existingDeclaration === null || existingDeclaration === void 0 ? void 0 : existingDeclaration.doc)
|
|
5039
|
+
doc: this.getDoc(target) || (existingDeclaration === null || existingDeclaration === void 0 ? void 0 : existingDeclaration.doc),
|
|
5040
|
+
isNamedExport
|
|
4968
5041
|
});
|
|
4969
5042
|
}
|
|
4970
5043
|
else {
|
|
@@ -4972,7 +5045,8 @@ class ExportedNames {
|
|
|
4972
5045
|
isLet: isLet || (existingDeclaration === null || existingDeclaration === void 0 ? void 0 : existingDeclaration.isLet),
|
|
4973
5046
|
type: existingDeclaration === null || existingDeclaration === void 0 ? void 0 : existingDeclaration.type,
|
|
4974
5047
|
required: existingDeclaration === null || existingDeclaration === void 0 ? void 0 : existingDeclaration.required,
|
|
4975
|
-
doc: existingDeclaration === null || existingDeclaration === void 0 ? void 0 : existingDeclaration.doc
|
|
5048
|
+
doc: existingDeclaration === null || existingDeclaration === void 0 ? void 0 : existingDeclaration.doc,
|
|
5049
|
+
isNamedExport
|
|
4976
5050
|
});
|
|
4977
5051
|
}
|
|
4978
5052
|
if (existingDeclaration === null || existingDeclaration === void 0 ? void 0 : existingDeclaration.isLet) {
|
|
@@ -5083,7 +5157,7 @@ class ExportedNames {
|
|
|
5083
5157
|
*/
|
|
5084
5158
|
createExportsStr() {
|
|
5085
5159
|
const names = Array.from(this.exports.entries());
|
|
5086
|
-
const others = names.filter(([, { isLet }]) => !isLet);
|
|
5160
|
+
const others = names.filter(([, { isLet, isNamedExport }]) => !isLet || (this.usesRunes() && isNamedExport));
|
|
5087
5161
|
const needsAccessors = this.usesAccessors && names.length > 0 && !this.usesRunes(); // runes mode doesn't support accessors
|
|
5088
5162
|
if (this.isSvelte5Plus) {
|
|
5089
5163
|
let str = '';
|
|
@@ -5155,7 +5229,7 @@ class ExportedNames {
|
|
|
5155
5229
|
this.isSvelte5Plus && globals.some((global) => runes.includes(global));
|
|
5156
5230
|
}
|
|
5157
5231
|
usesRunes() {
|
|
5158
|
-
return this.hasRunesGlobals || this.hasPropsRune();
|
|
5232
|
+
return this.hasRunesGlobals || this.hasPropsRune() || this.isRunes;
|
|
5159
5233
|
}
|
|
5160
5234
|
}
|
|
5161
5235
|
|
|
@@ -6115,12 +6189,12 @@ class InterfacesAndTypes {
|
|
|
6115
6189
|
}
|
|
6116
6190
|
}
|
|
6117
6191
|
|
|
6118
|
-
function processInstanceScriptContent(str, script, events, implicitStoreValues, mode, hasModuleScript, isTSFile, basename, isSvelte5Plus) {
|
|
6192
|
+
function processInstanceScriptContent(str, script, events, implicitStoreValues, mode, hasModuleScript, isTSFile, basename, isSvelte5Plus, isRunes) {
|
|
6119
6193
|
const htmlx = str.original;
|
|
6120
6194
|
const scriptContent = htmlx.substring(script.content.start, script.content.end);
|
|
6121
6195
|
const tsAst = ts.createSourceFile('component.ts.svelte', scriptContent, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
6122
6196
|
const astOffset = script.content.start;
|
|
6123
|
-
const exportedNames = new ExportedNames(str, astOffset, basename, isTSFile, isSvelte5Plus);
|
|
6197
|
+
const exportedNames = new ExportedNames(str, astOffset, basename, isTSFile, isSvelte5Plus, isRunes);
|
|
6124
6198
|
const generics = new Generics(str, astOffset, script);
|
|
6125
6199
|
const interfacesAndTypes = new InterfacesAndTypes();
|
|
6126
6200
|
const implicitTopLevelNames = new ImplicitTopLevelNames(str, astOffset);
|
|
@@ -6516,12 +6590,14 @@ function addSimpleComponentExport({ events, isTsFile, canHaveAnyProp, exportedNa
|
|
|
6516
6590
|
const propDef = props(isTsFile, canHaveAnyProp, exportedNames, _events(events.hasStrictEvents(), 'render()'));
|
|
6517
6591
|
const doc = componentDocumentation.getFormatted();
|
|
6518
6592
|
const className = fileName && classNameFromFilename(fileName, mode !== 'dts');
|
|
6593
|
+
const componentName = className || '$$Component';
|
|
6519
6594
|
let statement;
|
|
6520
6595
|
if (mode === 'dts') {
|
|
6521
6596
|
if (isSvelte5 && exportedNames.usesRunes() && !usesSlots && !events.hasEvents()) {
|
|
6522
6597
|
statement =
|
|
6523
|
-
`\n${doc}const ${
|
|
6524
|
-
`
|
|
6598
|
+
`\n${doc}const ${componentName} = __sveltets_2_fn_component(render());\n` +
|
|
6599
|
+
`type ${componentName} = ReturnType<typeof ${componentName}>;\n` +
|
|
6600
|
+
`export default ${componentName};`;
|
|
6525
6601
|
}
|
|
6526
6602
|
else if (isSvelte5) {
|
|
6527
6603
|
// Inline definitions from Svelte shims; else dts files will reference the globals which will be unresolved
|
|
@@ -6545,9 +6621,9 @@ function addSimpleComponentExport({ events, isTsFile, canHaveAnyProp, exportedNa
|
|
|
6545
6621
|
declare function $$__sveltets_2_isomorphic_component<
|
|
6546
6622
|
Props extends Record<string, any>, Events extends Record<string, any>, Slots extends Record<string, any>, Exports extends Record<string, any>, Bindings extends string
|
|
6547
6623
|
>(klass: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }): $$__sveltets_2_IsomorphicComponent<Props, Events, Slots, Exports, Bindings>;\n`) +
|
|
6548
|
-
`${doc}const ${
|
|
6549
|
-
surroundWithIgnoreComments(`type ${
|
|
6550
|
-
`export default ${
|
|
6624
|
+
`${doc}const ${componentName} = $$__sveltets_2_isomorphic_component${usesSlots ? '_slots' : ''}(${propDef});\n` +
|
|
6625
|
+
surroundWithIgnoreComments(`type ${componentName} = InstanceType<typeof ${componentName}>;\n`) +
|
|
6626
|
+
`export default ${componentName};`;
|
|
6551
6627
|
}
|
|
6552
6628
|
else if (isTsFile) {
|
|
6553
6629
|
const svelteComponentClass = noSvelteComponentTyped
|
|
@@ -6582,14 +6658,15 @@ declare function $$__sveltets_2_isomorphic_component<
|
|
|
6582
6658
|
if (isSvelte5) {
|
|
6583
6659
|
if (exportedNames.usesRunes() && !usesSlots && !events.hasEvents()) {
|
|
6584
6660
|
statement =
|
|
6585
|
-
`\n${doc}const ${
|
|
6586
|
-
`
|
|
6661
|
+
`\n${doc}const ${componentName} = __sveltets_2_fn_component(render());\n` +
|
|
6662
|
+
`type ${componentName} = ReturnType<typeof ${componentName}>;\n` +
|
|
6663
|
+
`export default ${componentName};`;
|
|
6587
6664
|
}
|
|
6588
6665
|
else {
|
|
6589
6666
|
statement =
|
|
6590
|
-
`\n${doc}const ${
|
|
6591
|
-
surroundWithIgnoreComments(`type ${
|
|
6592
|
-
`export default ${
|
|
6667
|
+
`\n${doc}const ${componentName} = __sveltets_2_isomorphic_component${usesSlots ? '_slots' : ''}(${propDef});\n` +
|
|
6668
|
+
surroundWithIgnoreComments(`type ${componentName} = InstanceType<typeof ${componentName}>;\n`) +
|
|
6669
|
+
`export default ${componentName};`;
|
|
6593
6670
|
}
|
|
6594
6671
|
}
|
|
6595
6672
|
else {
|
|
@@ -6761,6 +6838,7 @@ function processSvelteTemplate(str, parse, options) {
|
|
|
6761
6838
|
let uses$$restProps = false;
|
|
6762
6839
|
let uses$$slots = false;
|
|
6763
6840
|
let usesAccessors = !!options.accessors;
|
|
6841
|
+
let isRunes = false;
|
|
6764
6842
|
const componentDocumentation = new ComponentDocumentation();
|
|
6765
6843
|
//track if we are in a declaration scope
|
|
6766
6844
|
const isDeclaration = { value: false };
|
|
@@ -6784,6 +6862,9 @@ function processSvelteTemplate(str, parse, options) {
|
|
|
6784
6862
|
usesAccessors = true;
|
|
6785
6863
|
}
|
|
6786
6864
|
break;
|
|
6865
|
+
case 'runes':
|
|
6866
|
+
isRunes = true;
|
|
6867
|
+
break;
|
|
6787
6868
|
}
|
|
6788
6869
|
}
|
|
6789
6870
|
};
|
|
@@ -6963,7 +7044,8 @@ function processSvelteTemplate(str, parse, options) {
|
|
|
6963
7044
|
uses$$slots,
|
|
6964
7045
|
componentDocumentation,
|
|
6965
7046
|
resolvedStores,
|
|
6966
|
-
usesAccessors
|
|
7047
|
+
usesAccessors,
|
|
7048
|
+
isRunes
|
|
6967
7049
|
};
|
|
6968
7050
|
}
|
|
6969
7051
|
function svelte2tsx(svelte, options = { parse }) {
|
|
@@ -6973,7 +7055,7 @@ function svelte2tsx(svelte, options = { parse }) {
|
|
|
6973
7055
|
const basename = path__default.basename(options.filename || '');
|
|
6974
7056
|
const svelte5Plus = Number(options.version[0]) > 4;
|
|
6975
7057
|
// process the htmlx as a svelte template
|
|
6976
|
-
let { htmlAst, moduleScriptTag, scriptTag, rootSnippets, slots, uses$$props, uses$$slots, uses$$restProps, events, componentDocumentation, resolvedStores, usesAccessors } = processSvelteTemplate(str, options.parse || parse, {
|
|
7058
|
+
let { htmlAst, moduleScriptTag, scriptTag, rootSnippets, slots, uses$$props, uses$$slots, uses$$restProps, events, componentDocumentation, resolvedStores, usesAccessors, isRunes } = processSvelteTemplate(str, options.parse || parse, {
|
|
6977
7059
|
...options,
|
|
6978
7060
|
svelte5Plus
|
|
6979
7061
|
});
|
|
@@ -6998,7 +7080,7 @@ function svelte2tsx(svelte, options = { parse }) {
|
|
|
6998
7080
|
: instanceScriptTarget;
|
|
6999
7081
|
const implicitStoreValues = new ImplicitStoreValues(resolvedStores, renderFunctionStart);
|
|
7000
7082
|
//move the instance script and process the content
|
|
7001
|
-
let exportedNames = new ExportedNames(str, 0, basename, options === null || options === void 0 ? void 0 : options.isTsFile, svelte5Plus);
|
|
7083
|
+
let exportedNames = new ExportedNames(str, 0, basename, options === null || options === void 0 ? void 0 : options.isTsFile, svelte5Plus, isRunes);
|
|
7002
7084
|
let generics = new Generics(str, 0, { attributes: [] });
|
|
7003
7085
|
let uses$$SlotsInterface = false;
|
|
7004
7086
|
if (scriptTag) {
|
|
@@ -7007,7 +7089,7 @@ function svelte2tsx(svelte, options = { parse }) {
|
|
|
7007
7089
|
str.move(scriptTag.start, scriptTag.end, instanceScriptTarget);
|
|
7008
7090
|
}
|
|
7009
7091
|
const res = processInstanceScriptContent(str, scriptTag, events, implicitStoreValues, options.mode,
|
|
7010
|
-
/**hasModuleScripts */ !!moduleScriptTag, options === null || options === void 0 ? void 0 : options.isTsFile, basename, svelte5Plus);
|
|
7092
|
+
/**hasModuleScripts */ !!moduleScriptTag, options === null || options === void 0 ? void 0 : options.isTsFile, basename, svelte5Plus, isRunes);
|
|
7011
7093
|
uses$$props = uses$$props || res.uses$$props;
|
|
7012
7094
|
uses$$restProps = uses$$restProps || res.uses$$restProps;
|
|
7013
7095
|
uses$$slots = uses$$slots || res.uses$$slots;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte2tsx",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.23",
|
|
4
4
|
"description": "Convert Svelte components to TSX for type checking",
|
|
5
5
|
"author": "David Pershouse",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"svelte": "~4.2.19",
|
|
41
41
|
"tiny-glob": "^0.2.6",
|
|
42
42
|
"tslib": "^2.4.0",
|
|
43
|
-
"typescript": "^5.
|
|
43
|
+
"typescript": "^5.6.3"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"svelte": "^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0",
|