svelte2tsx 0.7.46 → 0.7.48
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 +6 -0
- package/index.js +170 -62
- package/index.mjs +170 -62
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -84,6 +84,12 @@ export function svelte2tsx(
|
|
|
84
84
|
* Transpiled output may vary between versions.
|
|
85
85
|
*/
|
|
86
86
|
version?: string;
|
|
87
|
+
/**
|
|
88
|
+
* If true, emits JSDoc annotations for types in JS files instead of TypeScript syntax.
|
|
89
|
+
* This is useful for svelte-check's incremental mode where the output needs to be
|
|
90
|
+
* valid JS that tsc can process without errors.
|
|
91
|
+
*/
|
|
92
|
+
emitJsDoc?: boolean;
|
|
87
93
|
}
|
|
88
94
|
): SvelteCompiledToTsx
|
|
89
95
|
|
package/index.js
CHANGED
|
@@ -2839,7 +2839,7 @@ const supportsBindThis = [
|
|
|
2839
2839
|
/**
|
|
2840
2840
|
* Transform bind:xxx into something that conforms to JS/TS
|
|
2841
2841
|
*/
|
|
2842
|
-
function handleBinding(str, attr, parent, element, preserveBind, isSvelte5Plus) {
|
|
2842
|
+
function handleBinding(str, attr, parent, element, preserveBind, isSvelte5Plus, emitJsDoc, isTsFile) {
|
|
2843
2843
|
const isGetSetBinding = attr.expression.type === 'SequenceExpression';
|
|
2844
2844
|
const [get, set] = isGetSetBinding ? attr.expression.expressions : [];
|
|
2845
2845
|
// bind this
|
|
@@ -2871,9 +2871,14 @@ function handleBinding(str, attr, parent, element, preserveBind, isSvelte5Plus)
|
|
|
2871
2871
|
}
|
|
2872
2872
|
// one way binding whose property is not on the element
|
|
2873
2873
|
if (oneWayBindingAttributesNotOnElement.has(attr.name) && element instanceof Element) {
|
|
2874
|
+
const useTypescriptSyntax = isTsFile || !emitJsDoc;
|
|
2875
|
+
const bindingType = oneWayBindingAttributesNotOnElement.get(attr.name);
|
|
2876
|
+
const bindingValue = useTypescriptSyntax
|
|
2877
|
+
? `null as ${bindingType}`
|
|
2878
|
+
: `/** @type {${bindingType}} */ (null)`;
|
|
2874
2879
|
element.appendToStartEnd([
|
|
2875
2880
|
[attr.expression.start, getEnd(attr.expression)],
|
|
2876
|
-
`= ${surroundWithIgnoreComments(
|
|
2881
|
+
`= ${surroundWithIgnoreComments(bindingValue)};`
|
|
2877
2882
|
]);
|
|
2878
2883
|
return;
|
|
2879
2884
|
}
|
|
@@ -3338,10 +3343,11 @@ function handleTransitionDirective(str, attr, element) {
|
|
|
3338
3343
|
* }
|
|
3339
3344
|
* ```
|
|
3340
3345
|
*/
|
|
3341
|
-
function handleSnippet(str, snippetBlock, component) {
|
|
3346
|
+
function handleSnippet(str, snippetBlock, component, emitJsDoc = false, isTsFile = false) {
|
|
3342
3347
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
3343
3348
|
const isImplicitProp = component !== undefined;
|
|
3344
3349
|
const endSnippet = str.original.lastIndexOf('{', snippetBlock.end - 1);
|
|
3350
|
+
const usTSSyntax = isTsFile || !emitJsDoc;
|
|
3345
3351
|
const afterSnippet = isImplicitProp
|
|
3346
3352
|
? `};return __sveltets_2_any(0)}`
|
|
3347
3353
|
: `};return __sveltets_2_any(0)};`;
|
|
@@ -3407,13 +3413,14 @@ function handleSnippet(str, snippetBlock, component) {
|
|
|
3407
3413
|
'const ',
|
|
3408
3414
|
[snippetBlock.expression.start, snippetBlock.expression.end],
|
|
3409
3415
|
IGNORE_POSITION_COMMENT,
|
|
3410
|
-
` = ${snippetBlock.typeParams ? `<${snippetBlock.typeParams}>` : ''}(`
|
|
3416
|
+
` = ${usTSSyntax ? '' : "/** @returns {ReturnType<import('svelte').Snippet>} */ "}${usTSSyntax && snippetBlock.typeParams ? `<${snippetBlock.typeParams}>` : ''}(`
|
|
3411
3417
|
];
|
|
3412
3418
|
if (parameters) {
|
|
3413
3419
|
transforms.push(parameters);
|
|
3414
3420
|
}
|
|
3415
|
-
transforms.push(')',
|
|
3416
|
-
|
|
3421
|
+
transforms.push(')', usTSSyntax
|
|
3422
|
+
? surroundWithIgnoreComments(`: ReturnType<import('svelte').Snippet>`) // shows up nicely preserved on hover, other alternatives don't
|
|
3423
|
+
: '', afterParameters);
|
|
3417
3424
|
transform(str, snippetBlock.start, startEnd, transforms);
|
|
3418
3425
|
}
|
|
3419
3426
|
}
|
|
@@ -4895,8 +4902,11 @@ function handleAttachTag(tag, element) {
|
|
|
4895
4902
|
* and converts it to JSX
|
|
4896
4903
|
*/
|
|
4897
4904
|
function convertHtmlxToJsx(str, ast, tags, options = { svelte5Plus: false }) {
|
|
4905
|
+
var _a, _b;
|
|
4898
4906
|
options.typingsNamespace = options.typingsNamespace || 'svelteHTML';
|
|
4899
4907
|
const preserveAttributeCase = options.namespace === 'foreign';
|
|
4908
|
+
const emitJsDoc = (_a = options.emitJsDoc) !== null && _a !== void 0 ? _a : false;
|
|
4909
|
+
const isTsFile = (_b = options.isTsFile) !== null && _b !== void 0 ? _b : false;
|
|
4900
4910
|
const rootSnippets = [];
|
|
4901
4911
|
let element;
|
|
4902
4912
|
const pendingSnippetHoistCheck = new Set();
|
|
@@ -5032,7 +5042,7 @@ function convertHtmlxToJsx(str, ast, tags, options = { svelte5Plus: false }) {
|
|
|
5032
5042
|
(element instanceof Element &&
|
|
5033
5043
|
element.tagName === 'svelte:boundary')
|
|
5034
5044
|
? element
|
|
5035
|
-
: undefined);
|
|
5045
|
+
: undefined, emitJsDoc, isTsFile);
|
|
5036
5046
|
if (parent === ast) {
|
|
5037
5047
|
// root snippet -> move to instance script or possibly even module script
|
|
5038
5048
|
const result = analyze({
|
|
@@ -5128,7 +5138,7 @@ function convertHtmlxToJsx(str, ast, tags, options = { svelte5Plus: false }) {
|
|
|
5128
5138
|
handleComment(str, node);
|
|
5129
5139
|
break;
|
|
5130
5140
|
case 'Binding':
|
|
5131
|
-
handleBinding(str, node, parent, element, options.typingsNamespace === 'svelteHTML', options.svelte5Plus);
|
|
5141
|
+
handleBinding(str, node, parent, element, options.typingsNamespace === 'svelteHTML', options.svelte5Plus, emitJsDoc, isTsFile);
|
|
5132
5142
|
break;
|
|
5133
5143
|
case 'Class':
|
|
5134
5144
|
handleClassDirective(str, node, element);
|
|
@@ -5711,21 +5721,33 @@ function addComponentExport(params) {
|
|
|
5711
5721
|
addSimpleComponentExport(params);
|
|
5712
5722
|
}
|
|
5713
5723
|
}
|
|
5714
|
-
function addGenericsComponentExport({ events, canHaveAnyProp, exportedNames, componentDocumentation, fileName, mode, usesAccessors, str, generics, usesSlots, isSvelte5, noSvelteComponentTyped, hasTopLevelAwait }) {
|
|
5724
|
+
function addGenericsComponentExport({ events, canHaveAnyProp, exportedNames, componentDocumentation, fileName, mode, usesAccessors, str, isTsFile, generics, usesSlots, isSvelte5, noSvelteComponentTyped, hasTopLevelAwait, emitJsDoc }) {
|
|
5715
5725
|
const genericsDef = generics.toDefinitionString();
|
|
5716
5726
|
const genericsRef = generics.toReferencesString();
|
|
5727
|
+
const useTSSyntax = isTsFile || !emitJsDoc;
|
|
5728
|
+
const templateNames = !useTSSyntax && genericsDef
|
|
5729
|
+
? genericsDef
|
|
5730
|
+
.slice(1, -1)
|
|
5731
|
+
.split(',')
|
|
5732
|
+
.map((part) => part.trim())
|
|
5733
|
+
.map((part) => part.split(/\s|=/)[0])
|
|
5734
|
+
.filter(Boolean)
|
|
5735
|
+
: [];
|
|
5736
|
+
const templateComment = templateNames.length
|
|
5737
|
+
? `/** @template ${templateNames.join(', ')} */\n`
|
|
5738
|
+
: '';
|
|
5717
5739
|
const doc = componentDocumentation.getFormatted();
|
|
5718
5740
|
const className = fileName && classNameFromFilename(fileName, mode !== 'dts');
|
|
5719
5741
|
function returnType(forPart) {
|
|
5720
5742
|
return `ReturnType<__sveltets_Render${genericsRef}['${forPart}']>`;
|
|
5721
5743
|
}
|
|
5722
5744
|
const renderCall = hasTopLevelAwait
|
|
5723
|
-
? `(await ${internalHelpers.renderName}${genericsRef}())`
|
|
5724
|
-
: `${internalHelpers.renderName}${genericsRef}()`;
|
|
5745
|
+
? `(await ${internalHelpers.renderName}${useTSSyntax ? genericsRef : ''}())`
|
|
5746
|
+
: `${internalHelpers.renderName}${useTSSyntax ? genericsRef : ''}()`;
|
|
5725
5747
|
// TODO once Svelte 4 compatibility is dropped, we can simplify this, because since TS 4.7 it is possible to use generics
|
|
5726
5748
|
// like this: `typeof render<T>` - which wasn't possibly before, hence the class + methods workaround.
|
|
5727
5749
|
let statement = `
|
|
5728
|
-
class __sveltets_Render${genericsDef} {
|
|
5750
|
+
${templateComment}class __sveltets_Render${useTSSyntax ? genericsDef : ''} {
|
|
5729
5751
|
props() {
|
|
5730
5752
|
return ${props(true, canHaveAnyProp, exportedNames, renderCall)}.props;
|
|
5731
5753
|
}
|
|
@@ -5741,12 +5763,25 @@ class __sveltets_Render${genericsDef} {
|
|
|
5741
5763
|
const renderType = hasTopLevelAwait
|
|
5742
5764
|
? `Awaited<ReturnType<typeof ${internalHelpers.renderName}${genericsRef}>>`
|
|
5743
5765
|
: `ReturnType<typeof ${internalHelpers.renderName}${genericsRef}>`;
|
|
5744
|
-
|
|
5766
|
+
if (useTSSyntax) {
|
|
5767
|
+
statement = `
|
|
5745
5768
|
class __sveltets_Render${genericsDef} {
|
|
5746
5769
|
props(): ${renderType}['props'] { return null as any; }
|
|
5747
5770
|
events(): ${renderType}['events'] { return null as any; }
|
|
5748
5771
|
slots(): ${renderType}['slots'] { return null as any; }
|
|
5749
5772
|
`;
|
|
5773
|
+
}
|
|
5774
|
+
else {
|
|
5775
|
+
statement = `
|
|
5776
|
+
${templateComment}class __sveltets_Render {
|
|
5777
|
+
/** @returns {${renderType}['props']} */
|
|
5778
|
+
props() { return /** @type {any} */ (null); }
|
|
5779
|
+
/** @returns {${renderType}['events']} */
|
|
5780
|
+
events() { return /** @type {any} */ (null); }
|
|
5781
|
+
/** @returns {${renderType}['slots']} */
|
|
5782
|
+
slots() { return /** @type {any} */ (null); }
|
|
5783
|
+
`;
|
|
5784
|
+
}
|
|
5750
5785
|
}
|
|
5751
5786
|
statement += isSvelte5
|
|
5752
5787
|
? ` bindings() { return ${exportedNames.createBindingsStr()}; }
|
|
@@ -5778,15 +5813,29 @@ class __sveltets_Render${genericsDef} {
|
|
|
5778
5813
|
// - Constraints: Need to support Svelte 4 class component types, therefore we need to use __sveltets_2_ensureComponent to transform function components to classes
|
|
5779
5814
|
// - Limitations: TypeScript is not able to preserve generics during said transformation (i.e. there's no way to express keeping the generic etc)
|
|
5780
5815
|
// TODO Svelte 6/7: Switch this around and not use new Component in svelte2tsx anymore, which means we can remove the legacy class component. We need something like _ensureFnComponent then.
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5816
|
+
if (useTSSyntax) {
|
|
5817
|
+
statement +=
|
|
5818
|
+
`\ninterface $$IsomorphicComponent {\n` +
|
|
5819
|
+
` new ${genericsDef}(options: import('svelte').ComponentConstructorOptions<${returnType('props') + (usesSlots ? '& {children?: any}' : '')}>): import('svelte').SvelteComponent<${returnType('props')}, ${returnType('events')}, ${returnType('slots')}> & { $$bindings?: ${returnType('bindings')} } & ${returnType('exports')};\n` +
|
|
5820
|
+
` ${genericsDef}(internal: unknown, props: ${propsType}): ${returnType('exports')};\n` +
|
|
5821
|
+
` z_$$bindings?: ${bindingsType};\n` +
|
|
5822
|
+
`}\n` +
|
|
5823
|
+
`${doc}const ${className || '$$Component'}: $$IsomorphicComponent = null as any;\n` +
|
|
5824
|
+
surroundWithIgnoreComments(`type ${className || '$$Component'}${genericsDef} = InstanceType<typeof ${className || '$$Component'}${genericsRef}>;\n`) +
|
|
5825
|
+
`export default ${className || '$$Component'};`;
|
|
5826
|
+
}
|
|
5827
|
+
else {
|
|
5828
|
+
const componentName = className || '$$Component';
|
|
5829
|
+
const componentType = `(new ${genericsDef}(options: import('svelte').ComponentConstructorOptions<${returnType('props') + (usesSlots ? '& {children?: any}' : '')}>) => import('svelte').SvelteComponent<${returnType('props')}, ${returnType('events')}, ${returnType('slots')}> & { $$bindings?: ${returnType('bindings')} } & ${returnType('exports')}) & ` +
|
|
5830
|
+
`(${genericsDef}(internal: unknown, props: ${propsType}) => ${returnType('exports')}) & ` +
|
|
5831
|
+
`{z_$$bindings?: ${bindingsType}}`;
|
|
5832
|
+
statement +=
|
|
5833
|
+
`\n${templateComment}` +
|
|
5834
|
+
`/** @typedef {${componentType}} $$IsomorphicComponent */\n` +
|
|
5835
|
+
`${doc}/** @type {$$IsomorphicComponent} */ export const ${componentName} = /** @type {any} */(null);\n` +
|
|
5836
|
+
`/** @typedef {InstanceType<typeof ${componentName}>} ${componentName} */\n` +
|
|
5837
|
+
`export default ${componentName};`;
|
|
5838
|
+
}
|
|
5790
5839
|
}
|
|
5791
5840
|
else if (mode === 'dts') {
|
|
5792
5841
|
statement +=
|
|
@@ -5799,16 +5848,30 @@ class __sveltets_Render${genericsDef} {
|
|
|
5799
5848
|
'\n}';
|
|
5800
5849
|
}
|
|
5801
5850
|
else {
|
|
5802
|
-
|
|
5803
|
-
|
|
5804
|
-
|
|
5805
|
-
|
|
5806
|
-
|
|
5807
|
-
|
|
5851
|
+
if (useTSSyntax) {
|
|
5852
|
+
statement +=
|
|
5853
|
+
`\n\nimport { ${svelteComponentClass} as __SvelteComponentTyped__ } from "svelte" \n` +
|
|
5854
|
+
`${doc}export default class${className ? ` ${className}` : ''}${genericsDef} extends __SvelteComponentTyped__<${returnType('props')}, ${returnType('events')}, ${returnType('slots')}> {` +
|
|
5855
|
+
exportedNames.createClassGetters(genericsRef) +
|
|
5856
|
+
(usesAccessors ? exportedNames.createClassAccessors() : '') +
|
|
5857
|
+
'\n}';
|
|
5858
|
+
}
|
|
5859
|
+
else {
|
|
5860
|
+
statement +=
|
|
5861
|
+
`\n\nimport { ${svelteComponentClass} as __SvelteComponentTyped__ } from "svelte" \n` +
|
|
5862
|
+
`/**` +
|
|
5863
|
+
templateNames.map((t) => ` * @template ${t}\n`).join('') +
|
|
5864
|
+
` * @extends {__SvelteComponentTyped__<${returnType('props')}, ${returnType('events')}, ${returnType('slots')}>}\n` +
|
|
5865
|
+
` */\n` +
|
|
5866
|
+
`export default class${className ? ` ${className}` : ''} extends __SvelteComponentTyped__ {` +
|
|
5867
|
+
exportedNames.createClassGetters(genericsRef) +
|
|
5868
|
+
(usesAccessors ? exportedNames.createClassAccessors() : '') +
|
|
5869
|
+
'\n}';
|
|
5870
|
+
}
|
|
5808
5871
|
}
|
|
5809
5872
|
str.append(statement);
|
|
5810
5873
|
}
|
|
5811
|
-
function addSimpleComponentExport({ events, isTsFile, canHaveAnyProp, exportedNames, componentDocumentation, fileName, mode, usesAccessors, str, usesSlots, noSvelteComponentTyped, isSvelte5, hasTopLevelAwait }) {
|
|
5874
|
+
function addSimpleComponentExport({ events, isTsFile, canHaveAnyProp, exportedNames, componentDocumentation, fileName, mode, usesAccessors, str, usesSlots, noSvelteComponentTyped, isSvelte5, hasTopLevelAwait, emitJsDoc }) {
|
|
5812
5875
|
const renderCall = hasTopLevelAwait
|
|
5813
5876
|
? `$${internalHelpers.renderName}`
|
|
5814
5877
|
: `${internalHelpers.renderName}()`;
|
|
@@ -5885,18 +5948,25 @@ declare function $$__sveltets_2_isomorphic_component<
|
|
|
5885
5948
|
}
|
|
5886
5949
|
else {
|
|
5887
5950
|
if (isSvelte5) {
|
|
5951
|
+
// When emitting JSDoc (JS files in incremental mode), we use @typedef instead of
|
|
5952
|
+
// TS type syntax, and must export the const so declaration-merging with @typedef works.
|
|
5953
|
+
const useTypeScriptSyntax = isTsFile || !emitJsDoc;
|
|
5888
5954
|
if (exportedNames.isRunesMode() && !usesSlots && !events.hasEvents()) {
|
|
5889
5955
|
statement =
|
|
5890
|
-
`\n${awaitDeclaration}${doc}const ${componentName} = __sveltets_2_fn_component(${renderCall});\n` +
|
|
5956
|
+
`\n${awaitDeclaration}${doc}${useTypeScriptSyntax ? '' : 'export '}const ${componentName} = __sveltets_2_fn_component(${renderCall});\n` +
|
|
5891
5957
|
// Surround the type with ignore comments so it is filtered out from go-to-definition etc,
|
|
5892
5958
|
// which for some editors can cause duplicates
|
|
5893
|
-
surroundWithIgnoreComments(
|
|
5959
|
+
surroundWithIgnoreComments(useTypeScriptSyntax
|
|
5960
|
+
? `type ${componentName} = ReturnType<typeof ${componentName}>;\n`
|
|
5961
|
+
: `/** @typedef {ReturnType<typeof ${componentName}>} ${componentName} */\n`) +
|
|
5894
5962
|
`export default ${componentName};`;
|
|
5895
5963
|
}
|
|
5896
5964
|
else {
|
|
5897
5965
|
statement =
|
|
5898
|
-
`\n${awaitDeclaration}${doc}const ${componentName} = __sveltets_2_isomorphic_component${usesSlots ? '_slots' : ''}(${propDef});\n` +
|
|
5899
|
-
surroundWithIgnoreComments(
|
|
5966
|
+
`\n${awaitDeclaration}${doc}${useTypeScriptSyntax ? '' : 'export '}const ${componentName} = __sveltets_2_isomorphic_component${usesSlots ? '_slots' : ''}(${propDef});\n` +
|
|
5967
|
+
surroundWithIgnoreComments(useTypeScriptSyntax
|
|
5968
|
+
? `type ${componentName} = InstanceType<typeof ${componentName}>;\n`
|
|
5969
|
+
: `/** @typedef {InstanceType<typeof ${componentName}>} ${componentName} */\n`) +
|
|
5900
5970
|
`export default ${componentName};`;
|
|
5901
5971
|
}
|
|
5902
5972
|
}
|
|
@@ -5987,9 +6057,14 @@ function classNameFromFilename(filename, appendSuffix) {
|
|
|
5987
6057
|
}
|
|
5988
6058
|
}
|
|
5989
6059
|
|
|
5990
|
-
function createRenderFunction({ str, scriptTag, scriptDestination, slots, events, exportedNames, uses$$props, uses$$restProps, uses$$slots, uses$$SlotsInterface, generics, hasTopLevelAwait, isTsFile, mode }) {
|
|
6060
|
+
function createRenderFunction({ str, scriptTag, scriptDestination, slots, events, exportedNames, uses$$props, uses$$restProps, uses$$slots, uses$$SlotsInterface, generics, hasTopLevelAwait, isTsFile, mode, emitJsDoc = false }) {
|
|
5991
6061
|
const htmlx = str.original;
|
|
5992
6062
|
let propsDecl = '';
|
|
6063
|
+
const useTypescriptSyntax = isTsFile || !emitJsDoc;
|
|
6064
|
+
const templateNames = useTypescriptSyntax ? [] : generics.getReferences();
|
|
6065
|
+
const templateComment = !useTypescriptSyntax && templateNames.length
|
|
6066
|
+
? `\n/** @template ${templateNames.join(', ')} */\n`
|
|
6067
|
+
: '';
|
|
5993
6068
|
if (uses$$props) {
|
|
5994
6069
|
propsDecl += ' let $$props = __sveltets_2_allPropsType();';
|
|
5995
6070
|
}
|
|
@@ -6004,12 +6079,11 @@ function createRenderFunction({ str, scriptTag, scriptDestination, slots, events
|
|
|
6004
6079
|
.join(', ') +
|
|
6005
6080
|
'});';
|
|
6006
6081
|
}
|
|
6007
|
-
const
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
|
|
6012
|
-
: '';
|
|
6082
|
+
const slotTypeReference = uses$$SlotsInterface ? '<$$Slots>' : '';
|
|
6083
|
+
const slotDeclaration = useTypescriptSyntax || !slotTypeReference
|
|
6084
|
+
? `;const __sveltets_createSlot = __sveltets_2_createCreateSlot${slotTypeReference}();`
|
|
6085
|
+
: `/** @type {ReturnType<typeof __sveltets_2_createCreateSlot${slotTypeReference}>} */ const __sveltets_createSlot = __sveltets_2_createCreateSlot();`;
|
|
6086
|
+
const slotsDeclaration = slots.size > 0 && mode !== 'dts' ? '\n' + surroundWithIgnoreComments(slotDeclaration) : '';
|
|
6013
6087
|
if (scriptTag) {
|
|
6014
6088
|
//I couldn't get magicstring to let me put the script before the <> we prepend during conversion of the template to jsx, so we just close it instead
|
|
6015
6089
|
const scriptTagEnd = htmlx.lastIndexOf('>', scriptTag.content.start) + 1;
|
|
@@ -6021,12 +6095,19 @@ function createRenderFunction({ str, scriptTag, scriptDestination, slots, events
|
|
|
6021
6095
|
start++;
|
|
6022
6096
|
end--;
|
|
6023
6097
|
}
|
|
6024
|
-
str.overwrite(scriptTag.start + 1, start - 1, `${hasTopLevelAwait ? 'async ' : ''}function ${internalHelpers.renderName}`);
|
|
6025
|
-
|
|
6026
|
-
|
|
6098
|
+
str.overwrite(scriptTag.start + 1, start - 1, `${templateComment}${hasTopLevelAwait ? 'async ' : ''}function ${internalHelpers.renderName}`);
|
|
6099
|
+
if (useTypescriptSyntax) {
|
|
6100
|
+
str.overwrite(start - 1, start, isTsFile ? '<' : `<${IGNORE_START_COMMENT}`); // if the generics are unused, only this char is colored opaque
|
|
6101
|
+
str.overwrite(end, scriptTagEnd, `>${isTsFile ? '' : IGNORE_END_COMMENT}() {${propsDecl}\n`);
|
|
6102
|
+
}
|
|
6103
|
+
else {
|
|
6104
|
+
str.overwrite(start - 1, start, '');
|
|
6105
|
+
str.overwrite(start, end, '');
|
|
6106
|
+
str.overwrite(end, scriptTagEnd, `() {${propsDecl}\n`);
|
|
6107
|
+
}
|
|
6027
6108
|
}
|
|
6028
6109
|
else {
|
|
6029
|
-
str.overwrite(scriptTag.start + 1, scriptTagEnd, `${hasTopLevelAwait ? 'async ' : ''}function ${internalHelpers.renderName}${generics.toDefinitionString(true)}() {${propsDecl}\n`);
|
|
6110
|
+
str.overwrite(scriptTag.start + 1, scriptTagEnd, `${templateComment}${hasTopLevelAwait ? 'async ' : ''}function ${internalHelpers.renderName}${useTypescriptSyntax ? generics.toDefinitionString(true) : ''}() {${propsDecl}\n`);
|
|
6030
6111
|
}
|
|
6031
6112
|
const scriptEndTagStart = htmlx.lastIndexOf('<', scriptTag.end - 1);
|
|
6032
6113
|
// wrap template with callback
|
|
@@ -6035,7 +6116,7 @@ function createRenderFunction({ str, scriptTag, scriptDestination, slots, events
|
|
|
6035
6116
|
});
|
|
6036
6117
|
}
|
|
6037
6118
|
else {
|
|
6038
|
-
str.prependRight(scriptDestination, `;${hasTopLevelAwait ? 'async ' : ''}function ${internalHelpers.renderName}() {` +
|
|
6119
|
+
str.prependRight(scriptDestination, `;${templateComment}${hasTopLevelAwait ? 'async ' : ''}function ${internalHelpers.renderName}${useTypescriptSyntax ? generics.toDefinitionString(true) : ''}() {` +
|
|
6039
6120
|
`${propsDecl}${slotsDeclaration}\nasync () => {`);
|
|
6040
6121
|
}
|
|
6041
6122
|
const slotsAsDef = uses$$SlotsInterface
|
|
@@ -6316,6 +6397,11 @@ class HoistableInterfaces {
|
|
|
6316
6397
|
}
|
|
6317
6398
|
}
|
|
6318
6399
|
}
|
|
6400
|
+
addDisallowed(names) {
|
|
6401
|
+
for (const name of names) {
|
|
6402
|
+
this.disallowed_values.add(name);
|
|
6403
|
+
}
|
|
6404
|
+
}
|
|
6319
6405
|
/**
|
|
6320
6406
|
* Traverses the AST to collect import statements and top-level interfaces,
|
|
6321
6407
|
* then determines which interfaces can be hoisted.
|
|
@@ -6455,13 +6541,14 @@ function is$$PropsDeclaration(node) {
|
|
|
6455
6541
|
return isInterfaceOrTypeDeclaration(node) && node.name.text === '$$Props';
|
|
6456
6542
|
}
|
|
6457
6543
|
class ExportedNames {
|
|
6458
|
-
constructor(str, astOffset, basename, isTsFile, isSvelte5Plus, isRunes) {
|
|
6544
|
+
constructor(str, astOffset, basename, isTsFile, isSvelte5Plus, isRunes, emitJsDoc) {
|
|
6459
6545
|
this.str = str;
|
|
6460
6546
|
this.astOffset = astOffset;
|
|
6461
6547
|
this.basename = basename;
|
|
6462
6548
|
this.isTsFile = isTsFile;
|
|
6463
6549
|
this.isSvelte5Plus = isSvelte5Plus;
|
|
6464
6550
|
this.isRunes = isRunes;
|
|
6551
|
+
this.emitJsDoc = emitJsDoc;
|
|
6465
6552
|
this.hoistableInterfaces = new HoistableInterfaces();
|
|
6466
6553
|
this.usesAccessors = false;
|
|
6467
6554
|
/**
|
|
@@ -6489,6 +6576,22 @@ class ExportedNames {
|
|
|
6489
6576
|
this.doneDeclarationTransformation = new Set();
|
|
6490
6577
|
this.getters = new Set();
|
|
6491
6578
|
}
|
|
6579
|
+
/**
|
|
6580
|
+
* Emits a Kit type annotation (e.g. `: import('./$types.js').PageData`) either as a
|
|
6581
|
+
* JSDoc @type comment (for JS files in emitJsDoc mode) or as a TS type annotation
|
|
6582
|
+
* wrapped in ignore comments.
|
|
6583
|
+
*/
|
|
6584
|
+
emitKitType(kitType, nameStart, nameEnd) {
|
|
6585
|
+
if (!kitType)
|
|
6586
|
+
return;
|
|
6587
|
+
if (this.emitJsDoc && !this.isTsFile) {
|
|
6588
|
+
const kitTypeRef = kitType.slice(2); // strip leading ": "
|
|
6589
|
+
preprendStr(this.str, nameStart, `/** @type {${kitTypeRef}} */ `);
|
|
6590
|
+
}
|
|
6591
|
+
else {
|
|
6592
|
+
preprendStr(this.str, nameEnd, surroundWithIgnoreComments(kitType));
|
|
6593
|
+
}
|
|
6594
|
+
}
|
|
6492
6595
|
handleVariableStatement(node, parent) {
|
|
6493
6596
|
const exportModifier = findExportKeyword(node);
|
|
6494
6597
|
if (exportModifier) {
|
|
@@ -6507,10 +6610,7 @@ class ExportedNames {
|
|
|
6507
6610
|
n.name.getText() === 'snapshot';
|
|
6508
6611
|
// TS types are not allowed in JS files, but TS will still pick it up and the ignore comment will filter out the error
|
|
6509
6612
|
const kitType = isKitExport && !type ? `: import('./$types.js').Snapshot` : '';
|
|
6510
|
-
|
|
6511
|
-
if (kitType) {
|
|
6512
|
-
preprendStr(this.str, nameEnd, surroundWithIgnoreComments(kitType));
|
|
6513
|
-
}
|
|
6613
|
+
this.emitKitType(kitType, n.name.getStart() + this.astOffset, n.name.end + this.astOffset);
|
|
6514
6614
|
}
|
|
6515
6615
|
});
|
|
6516
6616
|
}
|
|
@@ -6794,17 +6894,20 @@ class ExportedNames {
|
|
|
6794
6894
|
[ts.SyntaxKind.FalseKeyword, ts.SyntaxKind.TrueKeyword].includes(declaration.initializer.kind)))) {
|
|
6795
6895
|
const name = identifier.getText();
|
|
6796
6896
|
if (nameEnd === end) {
|
|
6797
|
-
|
|
6897
|
+
if (kitType && this.emitJsDoc && !this.isTsFile) {
|
|
6898
|
+
const kitTypeRef = kitType.slice(2);
|
|
6899
|
+
const nameStart = identifier.getStart() + this.astOffset;
|
|
6900
|
+
preprendStr(this.str, nameStart, `/** @type {${kitTypeRef}} */ `);
|
|
6901
|
+
}
|
|
6902
|
+
preprendStr(this.str, end, surroundWithIgnoreComments(`${(this.isTsFile || !this.emitJsDoc) && kitType ? kitType : ''};${name} = __sveltets_2_any(${name});`));
|
|
6798
6903
|
}
|
|
6799
6904
|
else {
|
|
6800
|
-
|
|
6801
|
-
preprendStr(this.str, nameEnd, surroundWithIgnoreComments(kitType));
|
|
6802
|
-
}
|
|
6905
|
+
this.emitKitType(kitType, identifier.getStart() + this.astOffset, nameEnd);
|
|
6803
6906
|
preprendStr(this.str, end, surroundWithIgnoreComments(`;${name} = __sveltets_2_any(${name});`));
|
|
6804
6907
|
}
|
|
6805
6908
|
}
|
|
6806
|
-
else
|
|
6807
|
-
|
|
6909
|
+
else {
|
|
6910
|
+
this.emitKitType(kitType, identifier.getStart() + this.astOffset, nameEnd);
|
|
6808
6911
|
}
|
|
6809
6912
|
};
|
|
6810
6913
|
const findComma = (target) => target.getChildren().filter((child) => child.kind === ts.SyntaxKind.CommaToken);
|
|
@@ -7583,12 +7686,12 @@ class InterfacesAndTypes {
|
|
|
7583
7686
|
}
|
|
7584
7687
|
}
|
|
7585
7688
|
|
|
7586
|
-
function processInstanceScriptContent(str, script, events, implicitStoreValues, mode, moduleAst, isTSFile, basename, isSvelte5Plus, isRunes) {
|
|
7689
|
+
function processInstanceScriptContent(str, script, events, implicitStoreValues, mode, moduleAst, isTSFile, basename, isSvelte5Plus, isRunes, emitJsDoc) {
|
|
7587
7690
|
const htmlx = str.original;
|
|
7588
7691
|
const scriptContent = htmlx.substring(script.content.start, script.content.end);
|
|
7589
7692
|
const tsAst = ts.createSourceFile('component.ts.svelte', scriptContent, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
7590
7693
|
const astOffset = script.content.start;
|
|
7591
|
-
const exportedNames = new ExportedNames(str, astOffset, basename, isTSFile, isSvelte5Plus, isRunes);
|
|
7694
|
+
const exportedNames = new ExportedNames(str, astOffset, basename, isTSFile, isSvelte5Plus, isRunes, emitJsDoc);
|
|
7592
7695
|
const generics = new Generics(str, astOffset, script);
|
|
7593
7696
|
const interfacesAndTypes = new InterfacesAndTypes();
|
|
7594
7697
|
if (moduleAst) {
|
|
@@ -7821,6 +7924,7 @@ function processInstanceScriptContent(str, script, events, implicitStoreValues,
|
|
|
7821
7924
|
for (const node of nodesToMove) {
|
|
7822
7925
|
moveNode(node, str, astOffset, script.start, tsAst);
|
|
7823
7926
|
}
|
|
7927
|
+
exportedNames.hoistableInterfaces.addDisallowed(implicitStoreValues.getAccessedStores());
|
|
7824
7928
|
const hoisted = exportedNames.hoistableInterfaces.moveHoistableInterfaces(str, astOffset, script.start + 1, // +1 because imports are also moved at that position, and we want to move interfaces after imports
|
|
7825
7929
|
generics.getReferences());
|
|
7826
7930
|
if (mode === 'dts') {
|
|
@@ -7944,12 +8048,14 @@ function processSvelteTemplate(str, parse, options) {
|
|
|
7944
8048
|
return convertHtmlxToJsx(str, htmlxAst, tags, options);
|
|
7945
8049
|
}
|
|
7946
8050
|
function svelte2tsx(svelte, options = { parse: compiler.parse }) {
|
|
8051
|
+
var _a;
|
|
7947
8052
|
options.mode = options.mode || 'ts';
|
|
7948
8053
|
options.version = options.version || compiler.VERSION;
|
|
7949
8054
|
const str = new MagicString(svelte);
|
|
7950
8055
|
const basename = path.basename(options.filename || '');
|
|
7951
8056
|
const svelte5Plus = Number(options.version[0]) > 4;
|
|
7952
8057
|
const isTsFile = options === null || options === void 0 ? void 0 : options.isTsFile;
|
|
8058
|
+
const emitJsDoc = (_a = options === null || options === void 0 ? void 0 : options.emitJsDoc) !== null && _a !== void 0 ? _a : false;
|
|
7953
8059
|
// process the htmlx as a svelte template
|
|
7954
8060
|
let { htmlAst, moduleScriptTag, scriptTag, rootSnippets, slots, uses$$props, uses$$slots, uses$$restProps, events, componentDocumentation, resolvedStores, usesAccessors, isRunes } = processSvelteTemplate(str, options.parse || compiler.parse, {
|
|
7955
8061
|
...options,
|
|
@@ -7978,7 +8084,7 @@ function svelte2tsx(svelte, options = { parse: compiler.parse }) {
|
|
|
7978
8084
|
: instanceScriptTarget;
|
|
7979
8085
|
const implicitStoreValues = new ImplicitStoreValues(resolvedStores, renderFunctionStart, svelte5Plus);
|
|
7980
8086
|
//move the instance script and process the content
|
|
7981
|
-
let exportedNames = new ExportedNames(str, 0, basename, isTsFile, svelte5Plus, isRunes);
|
|
8087
|
+
let exportedNames = new ExportedNames(str, 0, basename, isTsFile, svelte5Plus, isRunes, emitJsDoc);
|
|
7982
8088
|
let generics = new Generics(str, 0, { attributes: [] });
|
|
7983
8089
|
let uses$$SlotsInterface = false;
|
|
7984
8090
|
let hasTopLevelAwait = false;
|
|
@@ -7987,7 +8093,7 @@ function svelte2tsx(svelte, options = { parse: compiler.parse }) {
|
|
|
7987
8093
|
if (scriptTag.start != instanceScriptTarget) {
|
|
7988
8094
|
str.move(scriptTag.start, scriptTag.end, instanceScriptTarget);
|
|
7989
8095
|
}
|
|
7990
|
-
const res = processInstanceScriptContent(str, scriptTag, events, implicitStoreValues, options.mode, moduleAst, isTsFile, basename, svelte5Plus, isRunes);
|
|
8096
|
+
const res = processInstanceScriptContent(str, scriptTag, events, implicitStoreValues, options.mode, moduleAst, isTsFile, basename, svelte5Plus, isRunes, emitJsDoc);
|
|
7991
8097
|
uses$$props = uses$$props || res.uses$$props;
|
|
7992
8098
|
uses$$restProps = uses$$restProps || res.uses$$restProps;
|
|
7993
8099
|
uses$$slots = uses$$slots || res.uses$$slots;
|
|
@@ -8016,7 +8122,8 @@ function svelte2tsx(svelte, options = { parse: compiler.parse }) {
|
|
|
8016
8122
|
hasTopLevelAwait,
|
|
8017
8123
|
svelte5Plus,
|
|
8018
8124
|
isTsFile,
|
|
8019
|
-
mode: options.mode
|
|
8125
|
+
mode: options.mode,
|
|
8126
|
+
emitJsDoc
|
|
8020
8127
|
});
|
|
8021
8128
|
// we need to process the module script after the instance script has moved otherwise we get warnings about moving edited items
|
|
8022
8129
|
if (moduleScriptTag) {
|
|
@@ -8069,7 +8176,8 @@ function svelte2tsx(svelte, options = { parse: compiler.parse }) {
|
|
|
8069
8176
|
generics,
|
|
8070
8177
|
isSvelte5: svelte5Plus,
|
|
8071
8178
|
hasTopLevelAwait,
|
|
8072
|
-
noSvelteComponentTyped: options.noSvelteComponentTyped
|
|
8179
|
+
noSvelteComponentTyped: options.noSvelteComponentTyped,
|
|
8180
|
+
emitJsDoc
|
|
8073
8181
|
});
|
|
8074
8182
|
if (options.mode === 'dts') {
|
|
8075
8183
|
// Prepend the import which is used for TS files
|
package/index.mjs
CHANGED
|
@@ -2819,7 +2819,7 @@ const supportsBindThis = [
|
|
|
2819
2819
|
/**
|
|
2820
2820
|
* Transform bind:xxx into something that conforms to JS/TS
|
|
2821
2821
|
*/
|
|
2822
|
-
function handleBinding(str, attr, parent, element, preserveBind, isSvelte5Plus) {
|
|
2822
|
+
function handleBinding(str, attr, parent, element, preserveBind, isSvelte5Plus, emitJsDoc, isTsFile) {
|
|
2823
2823
|
const isGetSetBinding = attr.expression.type === 'SequenceExpression';
|
|
2824
2824
|
const [get, set] = isGetSetBinding ? attr.expression.expressions : [];
|
|
2825
2825
|
// bind this
|
|
@@ -2851,9 +2851,14 @@ function handleBinding(str, attr, parent, element, preserveBind, isSvelte5Plus)
|
|
|
2851
2851
|
}
|
|
2852
2852
|
// one way binding whose property is not on the element
|
|
2853
2853
|
if (oneWayBindingAttributesNotOnElement.has(attr.name) && element instanceof Element) {
|
|
2854
|
+
const useTypescriptSyntax = isTsFile || !emitJsDoc;
|
|
2855
|
+
const bindingType = oneWayBindingAttributesNotOnElement.get(attr.name);
|
|
2856
|
+
const bindingValue = useTypescriptSyntax
|
|
2857
|
+
? `null as ${bindingType}`
|
|
2858
|
+
: `/** @type {${bindingType}} */ (null)`;
|
|
2854
2859
|
element.appendToStartEnd([
|
|
2855
2860
|
[attr.expression.start, getEnd(attr.expression)],
|
|
2856
|
-
`= ${surroundWithIgnoreComments(
|
|
2861
|
+
`= ${surroundWithIgnoreComments(bindingValue)};`
|
|
2857
2862
|
]);
|
|
2858
2863
|
return;
|
|
2859
2864
|
}
|
|
@@ -3318,10 +3323,11 @@ function handleTransitionDirective(str, attr, element) {
|
|
|
3318
3323
|
* }
|
|
3319
3324
|
* ```
|
|
3320
3325
|
*/
|
|
3321
|
-
function handleSnippet(str, snippetBlock, component) {
|
|
3326
|
+
function handleSnippet(str, snippetBlock, component, emitJsDoc = false, isTsFile = false) {
|
|
3322
3327
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
3323
3328
|
const isImplicitProp = component !== undefined;
|
|
3324
3329
|
const endSnippet = str.original.lastIndexOf('{', snippetBlock.end - 1);
|
|
3330
|
+
const usTSSyntax = isTsFile || !emitJsDoc;
|
|
3325
3331
|
const afterSnippet = isImplicitProp
|
|
3326
3332
|
? `};return __sveltets_2_any(0)}`
|
|
3327
3333
|
: `};return __sveltets_2_any(0)};`;
|
|
@@ -3387,13 +3393,14 @@ function handleSnippet(str, snippetBlock, component) {
|
|
|
3387
3393
|
'const ',
|
|
3388
3394
|
[snippetBlock.expression.start, snippetBlock.expression.end],
|
|
3389
3395
|
IGNORE_POSITION_COMMENT,
|
|
3390
|
-
` = ${snippetBlock.typeParams ? `<${snippetBlock.typeParams}>` : ''}(`
|
|
3396
|
+
` = ${usTSSyntax ? '' : "/** @returns {ReturnType<import('svelte').Snippet>} */ "}${usTSSyntax && snippetBlock.typeParams ? `<${snippetBlock.typeParams}>` : ''}(`
|
|
3391
3397
|
];
|
|
3392
3398
|
if (parameters) {
|
|
3393
3399
|
transforms.push(parameters);
|
|
3394
3400
|
}
|
|
3395
|
-
transforms.push(')',
|
|
3396
|
-
|
|
3401
|
+
transforms.push(')', usTSSyntax
|
|
3402
|
+
? surroundWithIgnoreComments(`: ReturnType<import('svelte').Snippet>`) // shows up nicely preserved on hover, other alternatives don't
|
|
3403
|
+
: '', afterParameters);
|
|
3397
3404
|
transform(str, snippetBlock.start, startEnd, transforms);
|
|
3398
3405
|
}
|
|
3399
3406
|
}
|
|
@@ -4875,8 +4882,11 @@ function handleAttachTag(tag, element) {
|
|
|
4875
4882
|
* and converts it to JSX
|
|
4876
4883
|
*/
|
|
4877
4884
|
function convertHtmlxToJsx(str, ast, tags, options = { svelte5Plus: false }) {
|
|
4885
|
+
var _a, _b;
|
|
4878
4886
|
options.typingsNamespace = options.typingsNamespace || 'svelteHTML';
|
|
4879
4887
|
const preserveAttributeCase = options.namespace === 'foreign';
|
|
4888
|
+
const emitJsDoc = (_a = options.emitJsDoc) !== null && _a !== void 0 ? _a : false;
|
|
4889
|
+
const isTsFile = (_b = options.isTsFile) !== null && _b !== void 0 ? _b : false;
|
|
4880
4890
|
const rootSnippets = [];
|
|
4881
4891
|
let element;
|
|
4882
4892
|
const pendingSnippetHoistCheck = new Set();
|
|
@@ -5012,7 +5022,7 @@ function convertHtmlxToJsx(str, ast, tags, options = { svelte5Plus: false }) {
|
|
|
5012
5022
|
(element instanceof Element &&
|
|
5013
5023
|
element.tagName === 'svelte:boundary')
|
|
5014
5024
|
? element
|
|
5015
|
-
: undefined);
|
|
5025
|
+
: undefined, emitJsDoc, isTsFile);
|
|
5016
5026
|
if (parent === ast) {
|
|
5017
5027
|
// root snippet -> move to instance script or possibly even module script
|
|
5018
5028
|
const result = analyze({
|
|
@@ -5108,7 +5118,7 @@ function convertHtmlxToJsx(str, ast, tags, options = { svelte5Plus: false }) {
|
|
|
5108
5118
|
handleComment(str, node);
|
|
5109
5119
|
break;
|
|
5110
5120
|
case 'Binding':
|
|
5111
|
-
handleBinding(str, node, parent, element, options.typingsNamespace === 'svelteHTML', options.svelte5Plus);
|
|
5121
|
+
handleBinding(str, node, parent, element, options.typingsNamespace === 'svelteHTML', options.svelte5Plus, emitJsDoc, isTsFile);
|
|
5112
5122
|
break;
|
|
5113
5123
|
case 'Class':
|
|
5114
5124
|
handleClassDirective(str, node, element);
|
|
@@ -5691,21 +5701,33 @@ function addComponentExport(params) {
|
|
|
5691
5701
|
addSimpleComponentExport(params);
|
|
5692
5702
|
}
|
|
5693
5703
|
}
|
|
5694
|
-
function addGenericsComponentExport({ events, canHaveAnyProp, exportedNames, componentDocumentation, fileName, mode, usesAccessors, str, generics, usesSlots, isSvelte5, noSvelteComponentTyped, hasTopLevelAwait }) {
|
|
5704
|
+
function addGenericsComponentExport({ events, canHaveAnyProp, exportedNames, componentDocumentation, fileName, mode, usesAccessors, str, isTsFile, generics, usesSlots, isSvelte5, noSvelteComponentTyped, hasTopLevelAwait, emitJsDoc }) {
|
|
5695
5705
|
const genericsDef = generics.toDefinitionString();
|
|
5696
5706
|
const genericsRef = generics.toReferencesString();
|
|
5707
|
+
const useTSSyntax = isTsFile || !emitJsDoc;
|
|
5708
|
+
const templateNames = !useTSSyntax && genericsDef
|
|
5709
|
+
? genericsDef
|
|
5710
|
+
.slice(1, -1)
|
|
5711
|
+
.split(',')
|
|
5712
|
+
.map((part) => part.trim())
|
|
5713
|
+
.map((part) => part.split(/\s|=/)[0])
|
|
5714
|
+
.filter(Boolean)
|
|
5715
|
+
: [];
|
|
5716
|
+
const templateComment = templateNames.length
|
|
5717
|
+
? `/** @template ${templateNames.join(', ')} */\n`
|
|
5718
|
+
: '';
|
|
5697
5719
|
const doc = componentDocumentation.getFormatted();
|
|
5698
5720
|
const className = fileName && classNameFromFilename(fileName, mode !== 'dts');
|
|
5699
5721
|
function returnType(forPart) {
|
|
5700
5722
|
return `ReturnType<__sveltets_Render${genericsRef}['${forPart}']>`;
|
|
5701
5723
|
}
|
|
5702
5724
|
const renderCall = hasTopLevelAwait
|
|
5703
|
-
? `(await ${internalHelpers.renderName}${genericsRef}())`
|
|
5704
|
-
: `${internalHelpers.renderName}${genericsRef}()`;
|
|
5725
|
+
? `(await ${internalHelpers.renderName}${useTSSyntax ? genericsRef : ''}())`
|
|
5726
|
+
: `${internalHelpers.renderName}${useTSSyntax ? genericsRef : ''}()`;
|
|
5705
5727
|
// TODO once Svelte 4 compatibility is dropped, we can simplify this, because since TS 4.7 it is possible to use generics
|
|
5706
5728
|
// like this: `typeof render<T>` - which wasn't possibly before, hence the class + methods workaround.
|
|
5707
5729
|
let statement = `
|
|
5708
|
-
class __sveltets_Render${genericsDef} {
|
|
5730
|
+
${templateComment}class __sveltets_Render${useTSSyntax ? genericsDef : ''} {
|
|
5709
5731
|
props() {
|
|
5710
5732
|
return ${props(true, canHaveAnyProp, exportedNames, renderCall)}.props;
|
|
5711
5733
|
}
|
|
@@ -5721,12 +5743,25 @@ class __sveltets_Render${genericsDef} {
|
|
|
5721
5743
|
const renderType = hasTopLevelAwait
|
|
5722
5744
|
? `Awaited<ReturnType<typeof ${internalHelpers.renderName}${genericsRef}>>`
|
|
5723
5745
|
: `ReturnType<typeof ${internalHelpers.renderName}${genericsRef}>`;
|
|
5724
|
-
|
|
5746
|
+
if (useTSSyntax) {
|
|
5747
|
+
statement = `
|
|
5725
5748
|
class __sveltets_Render${genericsDef} {
|
|
5726
5749
|
props(): ${renderType}['props'] { return null as any; }
|
|
5727
5750
|
events(): ${renderType}['events'] { return null as any; }
|
|
5728
5751
|
slots(): ${renderType}['slots'] { return null as any; }
|
|
5729
5752
|
`;
|
|
5753
|
+
}
|
|
5754
|
+
else {
|
|
5755
|
+
statement = `
|
|
5756
|
+
${templateComment}class __sveltets_Render {
|
|
5757
|
+
/** @returns {${renderType}['props']} */
|
|
5758
|
+
props() { return /** @type {any} */ (null); }
|
|
5759
|
+
/** @returns {${renderType}['events']} */
|
|
5760
|
+
events() { return /** @type {any} */ (null); }
|
|
5761
|
+
/** @returns {${renderType}['slots']} */
|
|
5762
|
+
slots() { return /** @type {any} */ (null); }
|
|
5763
|
+
`;
|
|
5764
|
+
}
|
|
5730
5765
|
}
|
|
5731
5766
|
statement += isSvelte5
|
|
5732
5767
|
? ` bindings() { return ${exportedNames.createBindingsStr()}; }
|
|
@@ -5758,15 +5793,29 @@ class __sveltets_Render${genericsDef} {
|
|
|
5758
5793
|
// - Constraints: Need to support Svelte 4 class component types, therefore we need to use __sveltets_2_ensureComponent to transform function components to classes
|
|
5759
5794
|
// - Limitations: TypeScript is not able to preserve generics during said transformation (i.e. there's no way to express keeping the generic etc)
|
|
5760
5795
|
// TODO Svelte 6/7: Switch this around and not use new Component in svelte2tsx anymore, which means we can remove the legacy class component. We need something like _ensureFnComponent then.
|
|
5761
|
-
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
5769
|
-
|
|
5796
|
+
if (useTSSyntax) {
|
|
5797
|
+
statement +=
|
|
5798
|
+
`\ninterface $$IsomorphicComponent {\n` +
|
|
5799
|
+
` new ${genericsDef}(options: import('svelte').ComponentConstructorOptions<${returnType('props') + (usesSlots ? '& {children?: any}' : '')}>): import('svelte').SvelteComponent<${returnType('props')}, ${returnType('events')}, ${returnType('slots')}> & { $$bindings?: ${returnType('bindings')} } & ${returnType('exports')};\n` +
|
|
5800
|
+
` ${genericsDef}(internal: unknown, props: ${propsType}): ${returnType('exports')};\n` +
|
|
5801
|
+
` z_$$bindings?: ${bindingsType};\n` +
|
|
5802
|
+
`}\n` +
|
|
5803
|
+
`${doc}const ${className || '$$Component'}: $$IsomorphicComponent = null as any;\n` +
|
|
5804
|
+
surroundWithIgnoreComments(`type ${className || '$$Component'}${genericsDef} = InstanceType<typeof ${className || '$$Component'}${genericsRef}>;\n`) +
|
|
5805
|
+
`export default ${className || '$$Component'};`;
|
|
5806
|
+
}
|
|
5807
|
+
else {
|
|
5808
|
+
const componentName = className || '$$Component';
|
|
5809
|
+
const componentType = `(new ${genericsDef}(options: import('svelte').ComponentConstructorOptions<${returnType('props') + (usesSlots ? '& {children?: any}' : '')}>) => import('svelte').SvelteComponent<${returnType('props')}, ${returnType('events')}, ${returnType('slots')}> & { $$bindings?: ${returnType('bindings')} } & ${returnType('exports')}) & ` +
|
|
5810
|
+
`(${genericsDef}(internal: unknown, props: ${propsType}) => ${returnType('exports')}) & ` +
|
|
5811
|
+
`{z_$$bindings?: ${bindingsType}}`;
|
|
5812
|
+
statement +=
|
|
5813
|
+
`\n${templateComment}` +
|
|
5814
|
+
`/** @typedef {${componentType}} $$IsomorphicComponent */\n` +
|
|
5815
|
+
`${doc}/** @type {$$IsomorphicComponent} */ export const ${componentName} = /** @type {any} */(null);\n` +
|
|
5816
|
+
`/** @typedef {InstanceType<typeof ${componentName}>} ${componentName} */\n` +
|
|
5817
|
+
`export default ${componentName};`;
|
|
5818
|
+
}
|
|
5770
5819
|
}
|
|
5771
5820
|
else if (mode === 'dts') {
|
|
5772
5821
|
statement +=
|
|
@@ -5779,16 +5828,30 @@ class __sveltets_Render${genericsDef} {
|
|
|
5779
5828
|
'\n}';
|
|
5780
5829
|
}
|
|
5781
5830
|
else {
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5831
|
+
if (useTSSyntax) {
|
|
5832
|
+
statement +=
|
|
5833
|
+
`\n\nimport { ${svelteComponentClass} as __SvelteComponentTyped__ } from "svelte" \n` +
|
|
5834
|
+
`${doc}export default class${className ? ` ${className}` : ''}${genericsDef} extends __SvelteComponentTyped__<${returnType('props')}, ${returnType('events')}, ${returnType('slots')}> {` +
|
|
5835
|
+
exportedNames.createClassGetters(genericsRef) +
|
|
5836
|
+
(usesAccessors ? exportedNames.createClassAccessors() : '') +
|
|
5837
|
+
'\n}';
|
|
5838
|
+
}
|
|
5839
|
+
else {
|
|
5840
|
+
statement +=
|
|
5841
|
+
`\n\nimport { ${svelteComponentClass} as __SvelteComponentTyped__ } from "svelte" \n` +
|
|
5842
|
+
`/**` +
|
|
5843
|
+
templateNames.map((t) => ` * @template ${t}\n`).join('') +
|
|
5844
|
+
` * @extends {__SvelteComponentTyped__<${returnType('props')}, ${returnType('events')}, ${returnType('slots')}>}\n` +
|
|
5845
|
+
` */\n` +
|
|
5846
|
+
`export default class${className ? ` ${className}` : ''} extends __SvelteComponentTyped__ {` +
|
|
5847
|
+
exportedNames.createClassGetters(genericsRef) +
|
|
5848
|
+
(usesAccessors ? exportedNames.createClassAccessors() : '') +
|
|
5849
|
+
'\n}';
|
|
5850
|
+
}
|
|
5788
5851
|
}
|
|
5789
5852
|
str.append(statement);
|
|
5790
5853
|
}
|
|
5791
|
-
function addSimpleComponentExport({ events, isTsFile, canHaveAnyProp, exportedNames, componentDocumentation, fileName, mode, usesAccessors, str, usesSlots, noSvelteComponentTyped, isSvelte5, hasTopLevelAwait }) {
|
|
5854
|
+
function addSimpleComponentExport({ events, isTsFile, canHaveAnyProp, exportedNames, componentDocumentation, fileName, mode, usesAccessors, str, usesSlots, noSvelteComponentTyped, isSvelte5, hasTopLevelAwait, emitJsDoc }) {
|
|
5792
5855
|
const renderCall = hasTopLevelAwait
|
|
5793
5856
|
? `$${internalHelpers.renderName}`
|
|
5794
5857
|
: `${internalHelpers.renderName}()`;
|
|
@@ -5865,18 +5928,25 @@ declare function $$__sveltets_2_isomorphic_component<
|
|
|
5865
5928
|
}
|
|
5866
5929
|
else {
|
|
5867
5930
|
if (isSvelte5) {
|
|
5931
|
+
// When emitting JSDoc (JS files in incremental mode), we use @typedef instead of
|
|
5932
|
+
// TS type syntax, and must export the const so declaration-merging with @typedef works.
|
|
5933
|
+
const useTypeScriptSyntax = isTsFile || !emitJsDoc;
|
|
5868
5934
|
if (exportedNames.isRunesMode() && !usesSlots && !events.hasEvents()) {
|
|
5869
5935
|
statement =
|
|
5870
|
-
`\n${awaitDeclaration}${doc}const ${componentName} = __sveltets_2_fn_component(${renderCall});\n` +
|
|
5936
|
+
`\n${awaitDeclaration}${doc}${useTypeScriptSyntax ? '' : 'export '}const ${componentName} = __sveltets_2_fn_component(${renderCall});\n` +
|
|
5871
5937
|
// Surround the type with ignore comments so it is filtered out from go-to-definition etc,
|
|
5872
5938
|
// which for some editors can cause duplicates
|
|
5873
|
-
surroundWithIgnoreComments(
|
|
5939
|
+
surroundWithIgnoreComments(useTypeScriptSyntax
|
|
5940
|
+
? `type ${componentName} = ReturnType<typeof ${componentName}>;\n`
|
|
5941
|
+
: `/** @typedef {ReturnType<typeof ${componentName}>} ${componentName} */\n`) +
|
|
5874
5942
|
`export default ${componentName};`;
|
|
5875
5943
|
}
|
|
5876
5944
|
else {
|
|
5877
5945
|
statement =
|
|
5878
|
-
`\n${awaitDeclaration}${doc}const ${componentName} = __sveltets_2_isomorphic_component${usesSlots ? '_slots' : ''}(${propDef});\n` +
|
|
5879
|
-
surroundWithIgnoreComments(
|
|
5946
|
+
`\n${awaitDeclaration}${doc}${useTypeScriptSyntax ? '' : 'export '}const ${componentName} = __sveltets_2_isomorphic_component${usesSlots ? '_slots' : ''}(${propDef});\n` +
|
|
5947
|
+
surroundWithIgnoreComments(useTypeScriptSyntax
|
|
5948
|
+
? `type ${componentName} = InstanceType<typeof ${componentName}>;\n`
|
|
5949
|
+
: `/** @typedef {InstanceType<typeof ${componentName}>} ${componentName} */\n`) +
|
|
5880
5950
|
`export default ${componentName};`;
|
|
5881
5951
|
}
|
|
5882
5952
|
}
|
|
@@ -5967,9 +6037,14 @@ function classNameFromFilename(filename, appendSuffix) {
|
|
|
5967
6037
|
}
|
|
5968
6038
|
}
|
|
5969
6039
|
|
|
5970
|
-
function createRenderFunction({ str, scriptTag, scriptDestination, slots, events, exportedNames, uses$$props, uses$$restProps, uses$$slots, uses$$SlotsInterface, generics, hasTopLevelAwait, isTsFile, mode }) {
|
|
6040
|
+
function createRenderFunction({ str, scriptTag, scriptDestination, slots, events, exportedNames, uses$$props, uses$$restProps, uses$$slots, uses$$SlotsInterface, generics, hasTopLevelAwait, isTsFile, mode, emitJsDoc = false }) {
|
|
5971
6041
|
const htmlx = str.original;
|
|
5972
6042
|
let propsDecl = '';
|
|
6043
|
+
const useTypescriptSyntax = isTsFile || !emitJsDoc;
|
|
6044
|
+
const templateNames = useTypescriptSyntax ? [] : generics.getReferences();
|
|
6045
|
+
const templateComment = !useTypescriptSyntax && templateNames.length
|
|
6046
|
+
? `\n/** @template ${templateNames.join(', ')} */\n`
|
|
6047
|
+
: '';
|
|
5973
6048
|
if (uses$$props) {
|
|
5974
6049
|
propsDecl += ' let $$props = __sveltets_2_allPropsType();';
|
|
5975
6050
|
}
|
|
@@ -5984,12 +6059,11 @@ function createRenderFunction({ str, scriptTag, scriptDestination, slots, events
|
|
|
5984
6059
|
.join(', ') +
|
|
5985
6060
|
'});';
|
|
5986
6061
|
}
|
|
5987
|
-
const
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
: '';
|
|
6062
|
+
const slotTypeReference = uses$$SlotsInterface ? '<$$Slots>' : '';
|
|
6063
|
+
const slotDeclaration = useTypescriptSyntax || !slotTypeReference
|
|
6064
|
+
? `;const __sveltets_createSlot = __sveltets_2_createCreateSlot${slotTypeReference}();`
|
|
6065
|
+
: `/** @type {ReturnType<typeof __sveltets_2_createCreateSlot${slotTypeReference}>} */ const __sveltets_createSlot = __sveltets_2_createCreateSlot();`;
|
|
6066
|
+
const slotsDeclaration = slots.size > 0 && mode !== 'dts' ? '\n' + surroundWithIgnoreComments(slotDeclaration) : '';
|
|
5993
6067
|
if (scriptTag) {
|
|
5994
6068
|
//I couldn't get magicstring to let me put the script before the <> we prepend during conversion of the template to jsx, so we just close it instead
|
|
5995
6069
|
const scriptTagEnd = htmlx.lastIndexOf('>', scriptTag.content.start) + 1;
|
|
@@ -6001,12 +6075,19 @@ function createRenderFunction({ str, scriptTag, scriptDestination, slots, events
|
|
|
6001
6075
|
start++;
|
|
6002
6076
|
end--;
|
|
6003
6077
|
}
|
|
6004
|
-
str.overwrite(scriptTag.start + 1, start - 1, `${hasTopLevelAwait ? 'async ' : ''}function ${internalHelpers.renderName}`);
|
|
6005
|
-
|
|
6006
|
-
|
|
6078
|
+
str.overwrite(scriptTag.start + 1, start - 1, `${templateComment}${hasTopLevelAwait ? 'async ' : ''}function ${internalHelpers.renderName}`);
|
|
6079
|
+
if (useTypescriptSyntax) {
|
|
6080
|
+
str.overwrite(start - 1, start, isTsFile ? '<' : `<${IGNORE_START_COMMENT}`); // if the generics are unused, only this char is colored opaque
|
|
6081
|
+
str.overwrite(end, scriptTagEnd, `>${isTsFile ? '' : IGNORE_END_COMMENT}() {${propsDecl}\n`);
|
|
6082
|
+
}
|
|
6083
|
+
else {
|
|
6084
|
+
str.overwrite(start - 1, start, '');
|
|
6085
|
+
str.overwrite(start, end, '');
|
|
6086
|
+
str.overwrite(end, scriptTagEnd, `() {${propsDecl}\n`);
|
|
6087
|
+
}
|
|
6007
6088
|
}
|
|
6008
6089
|
else {
|
|
6009
|
-
str.overwrite(scriptTag.start + 1, scriptTagEnd, `${hasTopLevelAwait ? 'async ' : ''}function ${internalHelpers.renderName}${generics.toDefinitionString(true)}() {${propsDecl}\n`);
|
|
6090
|
+
str.overwrite(scriptTag.start + 1, scriptTagEnd, `${templateComment}${hasTopLevelAwait ? 'async ' : ''}function ${internalHelpers.renderName}${useTypescriptSyntax ? generics.toDefinitionString(true) : ''}() {${propsDecl}\n`);
|
|
6010
6091
|
}
|
|
6011
6092
|
const scriptEndTagStart = htmlx.lastIndexOf('<', scriptTag.end - 1);
|
|
6012
6093
|
// wrap template with callback
|
|
@@ -6015,7 +6096,7 @@ function createRenderFunction({ str, scriptTag, scriptDestination, slots, events
|
|
|
6015
6096
|
});
|
|
6016
6097
|
}
|
|
6017
6098
|
else {
|
|
6018
|
-
str.prependRight(scriptDestination, `;${hasTopLevelAwait ? 'async ' : ''}function ${internalHelpers.renderName}() {` +
|
|
6099
|
+
str.prependRight(scriptDestination, `;${templateComment}${hasTopLevelAwait ? 'async ' : ''}function ${internalHelpers.renderName}${useTypescriptSyntax ? generics.toDefinitionString(true) : ''}() {` +
|
|
6019
6100
|
`${propsDecl}${slotsDeclaration}\nasync () => {`);
|
|
6020
6101
|
}
|
|
6021
6102
|
const slotsAsDef = uses$$SlotsInterface
|
|
@@ -6296,6 +6377,11 @@ class HoistableInterfaces {
|
|
|
6296
6377
|
}
|
|
6297
6378
|
}
|
|
6298
6379
|
}
|
|
6380
|
+
addDisallowed(names) {
|
|
6381
|
+
for (const name of names) {
|
|
6382
|
+
this.disallowed_values.add(name);
|
|
6383
|
+
}
|
|
6384
|
+
}
|
|
6299
6385
|
/**
|
|
6300
6386
|
* Traverses the AST to collect import statements and top-level interfaces,
|
|
6301
6387
|
* then determines which interfaces can be hoisted.
|
|
@@ -6435,13 +6521,14 @@ function is$$PropsDeclaration(node) {
|
|
|
6435
6521
|
return isInterfaceOrTypeDeclaration(node) && node.name.text === '$$Props';
|
|
6436
6522
|
}
|
|
6437
6523
|
class ExportedNames {
|
|
6438
|
-
constructor(str, astOffset, basename, isTsFile, isSvelte5Plus, isRunes) {
|
|
6524
|
+
constructor(str, astOffset, basename, isTsFile, isSvelte5Plus, isRunes, emitJsDoc) {
|
|
6439
6525
|
this.str = str;
|
|
6440
6526
|
this.astOffset = astOffset;
|
|
6441
6527
|
this.basename = basename;
|
|
6442
6528
|
this.isTsFile = isTsFile;
|
|
6443
6529
|
this.isSvelte5Plus = isSvelte5Plus;
|
|
6444
6530
|
this.isRunes = isRunes;
|
|
6531
|
+
this.emitJsDoc = emitJsDoc;
|
|
6445
6532
|
this.hoistableInterfaces = new HoistableInterfaces();
|
|
6446
6533
|
this.usesAccessors = false;
|
|
6447
6534
|
/**
|
|
@@ -6469,6 +6556,22 @@ class ExportedNames {
|
|
|
6469
6556
|
this.doneDeclarationTransformation = new Set();
|
|
6470
6557
|
this.getters = new Set();
|
|
6471
6558
|
}
|
|
6559
|
+
/**
|
|
6560
|
+
* Emits a Kit type annotation (e.g. `: import('./$types.js').PageData`) either as a
|
|
6561
|
+
* JSDoc @type comment (for JS files in emitJsDoc mode) or as a TS type annotation
|
|
6562
|
+
* wrapped in ignore comments.
|
|
6563
|
+
*/
|
|
6564
|
+
emitKitType(kitType, nameStart, nameEnd) {
|
|
6565
|
+
if (!kitType)
|
|
6566
|
+
return;
|
|
6567
|
+
if (this.emitJsDoc && !this.isTsFile) {
|
|
6568
|
+
const kitTypeRef = kitType.slice(2); // strip leading ": "
|
|
6569
|
+
preprendStr(this.str, nameStart, `/** @type {${kitTypeRef}} */ `);
|
|
6570
|
+
}
|
|
6571
|
+
else {
|
|
6572
|
+
preprendStr(this.str, nameEnd, surroundWithIgnoreComments(kitType));
|
|
6573
|
+
}
|
|
6574
|
+
}
|
|
6472
6575
|
handleVariableStatement(node, parent) {
|
|
6473
6576
|
const exportModifier = findExportKeyword(node);
|
|
6474
6577
|
if (exportModifier) {
|
|
@@ -6487,10 +6590,7 @@ class ExportedNames {
|
|
|
6487
6590
|
n.name.getText() === 'snapshot';
|
|
6488
6591
|
// TS types are not allowed in JS files, but TS will still pick it up and the ignore comment will filter out the error
|
|
6489
6592
|
const kitType = isKitExport && !type ? `: import('./$types.js').Snapshot` : '';
|
|
6490
|
-
|
|
6491
|
-
if (kitType) {
|
|
6492
|
-
preprendStr(this.str, nameEnd, surroundWithIgnoreComments(kitType));
|
|
6493
|
-
}
|
|
6593
|
+
this.emitKitType(kitType, n.name.getStart() + this.astOffset, n.name.end + this.astOffset);
|
|
6494
6594
|
}
|
|
6495
6595
|
});
|
|
6496
6596
|
}
|
|
@@ -6774,17 +6874,20 @@ class ExportedNames {
|
|
|
6774
6874
|
[ts.SyntaxKind.FalseKeyword, ts.SyntaxKind.TrueKeyword].includes(declaration.initializer.kind)))) {
|
|
6775
6875
|
const name = identifier.getText();
|
|
6776
6876
|
if (nameEnd === end) {
|
|
6777
|
-
|
|
6877
|
+
if (kitType && this.emitJsDoc && !this.isTsFile) {
|
|
6878
|
+
const kitTypeRef = kitType.slice(2);
|
|
6879
|
+
const nameStart = identifier.getStart() + this.astOffset;
|
|
6880
|
+
preprendStr(this.str, nameStart, `/** @type {${kitTypeRef}} */ `);
|
|
6881
|
+
}
|
|
6882
|
+
preprendStr(this.str, end, surroundWithIgnoreComments(`${(this.isTsFile || !this.emitJsDoc) && kitType ? kitType : ''};${name} = __sveltets_2_any(${name});`));
|
|
6778
6883
|
}
|
|
6779
6884
|
else {
|
|
6780
|
-
|
|
6781
|
-
preprendStr(this.str, nameEnd, surroundWithIgnoreComments(kitType));
|
|
6782
|
-
}
|
|
6885
|
+
this.emitKitType(kitType, identifier.getStart() + this.astOffset, nameEnd);
|
|
6783
6886
|
preprendStr(this.str, end, surroundWithIgnoreComments(`;${name} = __sveltets_2_any(${name});`));
|
|
6784
6887
|
}
|
|
6785
6888
|
}
|
|
6786
|
-
else
|
|
6787
|
-
|
|
6889
|
+
else {
|
|
6890
|
+
this.emitKitType(kitType, identifier.getStart() + this.astOffset, nameEnd);
|
|
6788
6891
|
}
|
|
6789
6892
|
};
|
|
6790
6893
|
const findComma = (target) => target.getChildren().filter((child) => child.kind === ts.SyntaxKind.CommaToken);
|
|
@@ -7563,12 +7666,12 @@ class InterfacesAndTypes {
|
|
|
7563
7666
|
}
|
|
7564
7667
|
}
|
|
7565
7668
|
|
|
7566
|
-
function processInstanceScriptContent(str, script, events, implicitStoreValues, mode, moduleAst, isTSFile, basename, isSvelte5Plus, isRunes) {
|
|
7669
|
+
function processInstanceScriptContent(str, script, events, implicitStoreValues, mode, moduleAst, isTSFile, basename, isSvelte5Plus, isRunes, emitJsDoc) {
|
|
7567
7670
|
const htmlx = str.original;
|
|
7568
7671
|
const scriptContent = htmlx.substring(script.content.start, script.content.end);
|
|
7569
7672
|
const tsAst = ts.createSourceFile('component.ts.svelte', scriptContent, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
7570
7673
|
const astOffset = script.content.start;
|
|
7571
|
-
const exportedNames = new ExportedNames(str, astOffset, basename, isTSFile, isSvelte5Plus, isRunes);
|
|
7674
|
+
const exportedNames = new ExportedNames(str, astOffset, basename, isTSFile, isSvelte5Plus, isRunes, emitJsDoc);
|
|
7572
7675
|
const generics = new Generics(str, astOffset, script);
|
|
7573
7676
|
const interfacesAndTypes = new InterfacesAndTypes();
|
|
7574
7677
|
if (moduleAst) {
|
|
@@ -7801,6 +7904,7 @@ function processInstanceScriptContent(str, script, events, implicitStoreValues,
|
|
|
7801
7904
|
for (const node of nodesToMove) {
|
|
7802
7905
|
moveNode(node, str, astOffset, script.start, tsAst);
|
|
7803
7906
|
}
|
|
7907
|
+
exportedNames.hoistableInterfaces.addDisallowed(implicitStoreValues.getAccessedStores());
|
|
7804
7908
|
const hoisted = exportedNames.hoistableInterfaces.moveHoistableInterfaces(str, astOffset, script.start + 1, // +1 because imports are also moved at that position, and we want to move interfaces after imports
|
|
7805
7909
|
generics.getReferences());
|
|
7806
7910
|
if (mode === 'dts') {
|
|
@@ -7924,12 +8028,14 @@ function processSvelteTemplate(str, parse, options) {
|
|
|
7924
8028
|
return convertHtmlxToJsx(str, htmlxAst, tags, options);
|
|
7925
8029
|
}
|
|
7926
8030
|
function svelte2tsx(svelte, options = { parse }) {
|
|
8031
|
+
var _a;
|
|
7927
8032
|
options.mode = options.mode || 'ts';
|
|
7928
8033
|
options.version = options.version || VERSION;
|
|
7929
8034
|
const str = new MagicString(svelte);
|
|
7930
8035
|
const basename = path__default.basename(options.filename || '');
|
|
7931
8036
|
const svelte5Plus = Number(options.version[0]) > 4;
|
|
7932
8037
|
const isTsFile = options === null || options === void 0 ? void 0 : options.isTsFile;
|
|
8038
|
+
const emitJsDoc = (_a = options === null || options === void 0 ? void 0 : options.emitJsDoc) !== null && _a !== void 0 ? _a : false;
|
|
7933
8039
|
// process the htmlx as a svelte template
|
|
7934
8040
|
let { htmlAst, moduleScriptTag, scriptTag, rootSnippets, slots, uses$$props, uses$$slots, uses$$restProps, events, componentDocumentation, resolvedStores, usesAccessors, isRunes } = processSvelteTemplate(str, options.parse || parse, {
|
|
7935
8041
|
...options,
|
|
@@ -7958,7 +8064,7 @@ function svelte2tsx(svelte, options = { parse }) {
|
|
|
7958
8064
|
: instanceScriptTarget;
|
|
7959
8065
|
const implicitStoreValues = new ImplicitStoreValues(resolvedStores, renderFunctionStart, svelte5Plus);
|
|
7960
8066
|
//move the instance script and process the content
|
|
7961
|
-
let exportedNames = new ExportedNames(str, 0, basename, isTsFile, svelte5Plus, isRunes);
|
|
8067
|
+
let exportedNames = new ExportedNames(str, 0, basename, isTsFile, svelte5Plus, isRunes, emitJsDoc);
|
|
7962
8068
|
let generics = new Generics(str, 0, { attributes: [] });
|
|
7963
8069
|
let uses$$SlotsInterface = false;
|
|
7964
8070
|
let hasTopLevelAwait = false;
|
|
@@ -7967,7 +8073,7 @@ function svelte2tsx(svelte, options = { parse }) {
|
|
|
7967
8073
|
if (scriptTag.start != instanceScriptTarget) {
|
|
7968
8074
|
str.move(scriptTag.start, scriptTag.end, instanceScriptTarget);
|
|
7969
8075
|
}
|
|
7970
|
-
const res = processInstanceScriptContent(str, scriptTag, events, implicitStoreValues, options.mode, moduleAst, isTsFile, basename, svelte5Plus, isRunes);
|
|
8076
|
+
const res = processInstanceScriptContent(str, scriptTag, events, implicitStoreValues, options.mode, moduleAst, isTsFile, basename, svelte5Plus, isRunes, emitJsDoc);
|
|
7971
8077
|
uses$$props = uses$$props || res.uses$$props;
|
|
7972
8078
|
uses$$restProps = uses$$restProps || res.uses$$restProps;
|
|
7973
8079
|
uses$$slots = uses$$slots || res.uses$$slots;
|
|
@@ -7996,7 +8102,8 @@ function svelte2tsx(svelte, options = { parse }) {
|
|
|
7996
8102
|
hasTopLevelAwait,
|
|
7997
8103
|
svelte5Plus,
|
|
7998
8104
|
isTsFile,
|
|
7999
|
-
mode: options.mode
|
|
8105
|
+
mode: options.mode,
|
|
8106
|
+
emitJsDoc
|
|
8000
8107
|
});
|
|
8001
8108
|
// we need to process the module script after the instance script has moved otherwise we get warnings about moving edited items
|
|
8002
8109
|
if (moduleScriptTag) {
|
|
@@ -8049,7 +8156,8 @@ function svelte2tsx(svelte, options = { parse }) {
|
|
|
8049
8156
|
generics,
|
|
8050
8157
|
isSvelte5: svelte5Plus,
|
|
8051
8158
|
hasTopLevelAwait,
|
|
8052
|
-
noSvelteComponentTyped: options.noSvelteComponentTyped
|
|
8159
|
+
noSvelteComponentTyped: options.noSvelteComponentTyped,
|
|
8160
|
+
emitJsDoc
|
|
8053
8161
|
});
|
|
8054
8162
|
if (options.mode === 'dts') {
|
|
8055
8163
|
// Prepend the import which is used for TS files
|