svelte2tsx 0.7.7 → 0.7.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -2686,18 +2686,12 @@ function handleBinding(str, attr, parent, element, preserveBind, isSvelte5Plus)
2686
2686
  const value = isShorthand
2687
2687
  ? preserveBind && element instanceof Element
2688
2688
  ? [rangeWithTrailingPropertyAccess(str.original, attr.expression)]
2689
- : isSvelte5Plus
2690
- ? [
2691
- `__sveltets_2_binding(${str.original.substring(attr.expression.start, attr.expression.end)})`
2692
- ]
2693
- : undefined
2694
- : element instanceof Element || !isSvelte5Plus
2695
- ? [rangeWithTrailingPropertyAccess(str.original, attr.expression)]
2696
- : [
2697
- '__sveltets_2_binding(',
2698
- rangeWithTrailingPropertyAccess(str.original, attr.expression),
2699
- ')'
2700
- ];
2689
+ : undefined
2690
+ : [rangeWithTrailingPropertyAccess(str.original, attr.expression)];
2691
+ if (isSvelte5Plus && element instanceof InlineComponent) {
2692
+ // To check if property is actually bindable
2693
+ element.appendToStartEnd([`${element.name}.$$bindings = '${attr.name}';`]);
2694
+ }
2701
2695
  if (element instanceof Element) {
2702
2696
  element.addAttribute(name, value);
2703
2697
  }
@@ -3131,10 +3125,13 @@ function handleSnippet(str, snippetBlock, component) {
3131
3125
  let generic = '';
3132
3126
  if ((_e = snippetBlock.parameters) === null || _e === void 0 ? void 0 : _e.length) {
3133
3127
  generic = `<[${snippetBlock.parameters
3134
- .map((p) => p.typeAnnotation
3135
- ? str.original.slice(p.typeAnnotation.start + 1, p.typeAnnotation.end)
3136
- : // slap any on to it to silence "implicit any" errors; JSDoc people can't add types to snippets
3137
- 'any')
3128
+ .map((p) => {
3129
+ var _a;
3130
+ return ((_a = p.typeAnnotation) === null || _a === void 0 ? void 0 : _a.typeAnnotation)
3131
+ ? str.original.slice(p.typeAnnotation.typeAnnotation.start, p.typeAnnotation.typeAnnotation.end)
3132
+ : // slap any on to it to silence "implicit any" errors; JSDoc people can't add types to snippets
3133
+ 'any';
3134
+ })
3138
3135
  .join(', ')}]>`;
3139
3136
  }
3140
3137
  const typeAnnotation = surroundWithIgnoreComments(`: import('svelte').Snippet${generic}`);
@@ -4384,11 +4381,13 @@ function is$$PropsDeclaration(node) {
4384
4381
  return isInterfaceOrTypeDeclaration(node) && node.name.text === '$$Props';
4385
4382
  }
4386
4383
  class ExportedNames {
4387
- constructor(str, astOffset, basename, isTsFile) {
4384
+ constructor(str, astOffset, basename, isTsFile, isSvelte5Plus) {
4388
4385
  this.str = str;
4389
4386
  this.astOffset = astOffset;
4390
4387
  this.basename = basename;
4391
4388
  this.isTsFile = isTsFile;
4389
+ this.isSvelte5Plus = isSvelte5Plus;
4390
+ this.usesAccessors = false;
4392
4391
  /**
4393
4392
  * Uses the `$$Props` type
4394
4393
  */
@@ -4491,7 +4490,12 @@ class ExportedNames {
4491
4490
  ? element.propertyName.text
4492
4491
  : element.name.text;
4493
4492
  if (element.initializer) {
4494
- const call = element.initializer;
4493
+ let call = element.initializer;
4494
+ // if it's an as expression we need to check wether the as
4495
+ // expression expression is a call
4496
+ if (ts.isAsExpression(call)) {
4497
+ call = call.expression;
4498
+ }
4495
4499
  if (ts.isCallExpression(call) && ts.isIdentifier(call.expression)) {
4496
4500
  if (call.expression.text === '$bindable') {
4497
4501
  this.$props.bindings.push(name);
@@ -4514,7 +4518,9 @@ class ExportedNames {
4514
4518
  preprendStr(this.str, generic_arg.pos + this.astOffset, `;type ${this.$props.type} = `);
4515
4519
  this.str.appendLeft(generic_arg.end + this.astOffset, ';');
4516
4520
  this.str.move(generic_arg.pos + this.astOffset, generic_arg.end + this.astOffset, node.parent.pos + this.astOffset);
4517
- this.str.appendRight(generic_arg.end + this.astOffset, this.$props.type);
4521
+ this.str.appendRight(generic_arg.end + this.astOffset,
4522
+ // so that semantic tokens ignore it, preventing an overlap of tokens
4523
+ surroundWithIgnoreComments(this.$props.type));
4518
4524
  }
4519
4525
  }
4520
4526
  else {
@@ -4859,38 +4865,13 @@ class ExportedNames {
4859
4865
  */
4860
4866
  createPropsStr(uses$$propsOr$$restProps) {
4861
4867
  const names = Array.from(this.exports.entries());
4862
- if (this.$props.type) {
4863
- return ('{} as any as ' +
4864
- (this.$props.bindings.length
4865
- ? `__sveltets_2_Bindings<${this.$props.type}, ${this.$props.bindings.map((b) => `"${b}"`).join('|')}>`
4866
- : this.$props.type));
4867
- }
4868
- if (this.$props.comment) {
4869
- let result = this.$props.comment + '({})';
4870
- // Try our best to incorporate __sveltets_2_Bindings here
4871
- let idx = this.$props.comment.indexOf('@type');
4872
- if (idx !== -1 && /[\s{]/.test(this.$props.comment[idx + 5])) {
4873
- idx = this.$props.comment.indexOf('{', idx);
4874
- const end = this.$props.comment.lastIndexOf('}');
4875
- if (idx !== -1 && end !== -1 && idx < end) {
4876
- const has_bindings = this.$props.bindings.length;
4877
- if (has_bindings) {
4878
- idx++;
4879
- result =
4880
- this.$props.comment.slice(0, idx) +
4881
- (has_bindings ? '__sveltets_2_Bindings<' : '') +
4882
- this.$props.comment.slice(idx, end) +
4883
- (has_bindings
4884
- ? `, ${this.$props.bindings.map((b) => `"${b}"`).join('|')}>`
4885
- : '') +
4886
- this.$props.comment.slice(end) +
4887
- '({})';
4888
- }
4889
- }
4890
- }
4891
- return result;
4892
- }
4893
4868
  if (this.usesRunes()) {
4869
+ if (this.$props.type) {
4870
+ return '{} as any as ' + this.$props.type;
4871
+ }
4872
+ if (this.$props.comment) {
4873
+ return this.$props.comment + '({})';
4874
+ }
4894
4875
  // Necessary, because {} roughly equals to any
4895
4876
  return this.isTsFile
4896
4877
  ? '{} as Record<string, never>'
@@ -4931,22 +4912,48 @@ class ExportedNames {
4931
4912
  const returnElementsType = this.createReturnElementsType(names);
4932
4913
  return `{${returnElements.join(' , ')}} as {${returnElementsType.join(', ')}}`;
4933
4914
  }
4915
+ hasNoProps() {
4916
+ if (this.usesRunes()) {
4917
+ return !this.$props.type && !this.$props.comment;
4918
+ }
4919
+ const names = Array.from(this.exports.entries());
4920
+ return names.length === 0;
4921
+ }
4922
+ createBindingsStr() {
4923
+ if (this.usesRunes()) {
4924
+ // will be just the empty strings for zero bindings, which is impossible to create a binding for, so it works out fine
4925
+ return `__sveltets_$$bindings('${this.$props.bindings.join("', '")}')`;
4926
+ }
4927
+ else {
4928
+ return '""';
4929
+ }
4930
+ }
4934
4931
  /**
4935
4932
  * In runes mode, exports are no longer part of props because you cannot `bind:` to them,
4936
- * which is why we need a separate return type for them.
4933
+ * which is why we need a separate return type for them. In Svelte 5, the isomorphic component
4934
+ * needs them separate, too.
4937
4935
  */
4938
4936
  createExportsStr() {
4939
4937
  const names = Array.from(this.exports.entries());
4940
4938
  const others = names.filter(([, { isLet }]) => !isLet);
4941
- if (this.usesRunes() && others.length > 0) {
4942
- if (this.isTsFile) {
4943
- return (', exports: {} as any as { ' +
4944
- this.createReturnElementsType(others, undefined, true).join(',') +
4945
- ' }');
4939
+ const needsAccessors = this.usesAccessors && names.length > 0 && !this.usesRunes(); // runes mode doesn't support accessors
4940
+ if (this.isSvelte5Plus && (others.length > 0 || this.usesRunes() || needsAccessors)) {
4941
+ let str = '';
4942
+ if (others.length > 0 || needsAccessors) {
4943
+ if (this.isTsFile) {
4944
+ str +=
4945
+ ', exports: {} as any as { ' +
4946
+ this.createReturnElementsType(needsAccessors ? names : others, undefined, true).join(',') +
4947
+ ' }';
4948
+ }
4949
+ else {
4950
+ str += `, exports: /** @type {{${this.createReturnElementsType(needsAccessors ? names : others, false, true)}}} */ ({})`;
4951
+ }
4946
4952
  }
4947
- else {
4948
- return `, exports: /** @type {${this.createReturnElementsType(others, false, true)}} */ ({})`;
4953
+ if (this.usesRunes()) {
4954
+ str += `, bindings: ${this.createBindingsStr()}`;
4949
4955
  }
4956
+ return str;
4950
4957
  }
4951
4958
  return '';
4952
4959
  }
@@ -4978,12 +4985,17 @@ class ExportedNames {
4978
4985
  getExportsMap() {
4979
4986
  return this.exports;
4980
4987
  }
4988
+ hasExports() {
4989
+ const names = Array.from(this.exports.entries());
4990
+ return this.usesAccessors ? names.length > 0 : names.some(([, { isLet }]) => !isLet);
4991
+ }
4981
4992
  hasPropsRune() {
4982
- return this.$props.type || this.$props.comment;
4993
+ return this.isSvelte5Plus && (this.$props.type || this.$props.comment);
4983
4994
  }
4984
4995
  checkGlobalsForRunes(globals) {
4985
4996
  const runes = ['$state', '$derived', '$effect']; // no need to check for props, already handled through other means in here
4986
- this.hasRunesGlobals = globals.some((global) => runes.includes(global));
4997
+ this.hasRunesGlobals =
4998
+ this.isSvelte5Plus && globals.some((global) => runes.includes(global));
4987
4999
  }
4988
5000
  usesRunes() {
4989
5001
  return this.hasRunesGlobals || this.hasPropsRune();
@@ -5860,6 +5872,9 @@ class Generics {
5860
5872
  toReferencesString() {
5861
5873
  return this.references.length ? `<${this.references.join(',')}>` : '';
5862
5874
  }
5875
+ toReferencesAnyString() {
5876
+ return this.references.length ? `<${this.references.map(() => 'any').join(',')}>` : '';
5877
+ }
5863
5878
  has() {
5864
5879
  return this.definitions.length > 0;
5865
5880
  }
@@ -5940,12 +5955,12 @@ class InterfacesAndTypes {
5940
5955
  }
5941
5956
  }
5942
5957
 
5943
- function processInstanceScriptContent(str, script, events, implicitStoreValues, mode, hasModuleScript, isTSFile, basename) {
5958
+ function processInstanceScriptContent(str, script, events, implicitStoreValues, mode, hasModuleScript, isTSFile, basename, isSvelte5Plus) {
5944
5959
  const htmlx = str.original;
5945
5960
  const scriptContent = htmlx.substring(script.content.start, script.content.end);
5946
5961
  const tsAst = ts.createSourceFile('component.ts.svelte', scriptContent, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
5947
5962
  const astOffset = script.content.start;
5948
- const exportedNames = new ExportedNames(str, astOffset, basename, isTSFile);
5963
+ const exportedNames = new ExportedNames(str, astOffset, basename, isTSFile, isSvelte5Plus);
5949
5964
  const generics = new Generics(str, astOffset, script);
5950
5965
  const interfacesAndTypes = new InterfacesAndTypes();
5951
5966
  const implicitTopLevelNames = new ImplicitTopLevelNames(str, astOffset);
@@ -6254,7 +6269,7 @@ function addComponentExport(params) {
6254
6269
  addSimpleComponentExport(params);
6255
6270
  }
6256
6271
  }
6257
- function addGenericsComponentExport({ strictEvents, canHaveAnyProp, exportedNames, componentDocumentation, fileName, mode, usesAccessors, str, generics, noSvelteComponentTyped }) {
6272
+ function addGenericsComponentExport({ strictEvents, canHaveAnyProp, exportedNames, componentDocumentation, fileName, mode, usesAccessors, str, generics, usesSlots, isSvelte5, noSvelteComponentTyped }) {
6258
6273
  const genericsDef = generics.toDefinitionString();
6259
6274
  const genericsRef = generics.toReferencesString();
6260
6275
  const doc = componentDocumentation.getFormatted();
@@ -6273,7 +6288,11 @@ class __sveltets_Render${genericsDef} {
6273
6288
  slots() {
6274
6289
  return render${genericsRef}().slots;
6275
6290
  }
6276
- }
6291
+ ${isSvelte5
6292
+ ? ` bindings() { return ${exportedNames.createBindingsStr()}; }
6293
+ exports() { return ${exportedNames.hasExports() ? `render${genericsRef}().exports` : '{}'}; }
6294
+ }`
6295
+ : '}'}
6277
6296
  `;
6278
6297
  const svelteComponentClass = noSvelteComponentTyped
6279
6298
  ? 'SvelteComponent'
@@ -6281,21 +6300,28 @@ class __sveltets_Render${genericsDef} {
6281
6300
  const [PropsName] = addTypeExport(str, className, 'Props');
6282
6301
  const [EventsName] = addTypeExport(str, className, 'Events');
6283
6302
  const [SlotsName] = addTypeExport(str, className, 'Slots');
6284
- /**
6285
- * In Svelte 5 runes mode we add a custom constructor to override the default one which implicitly makes all properties bindable.
6286
- * Remove this once Svelte typings no longer do that (Svelte 6 or 7)
6287
- */
6288
- let customConstructor = '';
6289
- if (exportedNames.hasPropsRune()) {
6290
- customConstructor = `\n constructor(options: import('svelte').ComponentConstructorOptions<__sveltets_2_PropsWithChildren<${returnType('props')}, ${returnType('slots')}>>) { super(options); }`;
6291
- }
6292
- if (mode === 'dts') {
6303
+ if (isSvelte5) {
6304
+ // Don't add props/events/slots type exports in dts mode for now, maybe someone asks for it to be back,
6305
+ // but it's safer to not do it for now to have more flexibility in the future.
6306
+ const propsType = !canHaveAnyProp && exportedNames.hasNoProps()
6307
+ ? `{$$events?: ${returnType('events')}${usesSlots ? `, $$slots?: ${returnType('slots')}, children?: any` : ''}}`
6308
+ : `${returnType('props')} & {$$events?: ${returnType('events')}${usesSlots ? `, $$slots?: ${returnType('slots')}, children?: any` : ''}}`;
6309
+ statement +=
6310
+ `\ninterface $$IsomorphicComponent {\n` +
6311
+ ` 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` +
6312
+ ` ${genericsDef}(internal: unknown, props: ${propsType}): ${returnType('exports')};\n` +
6313
+ ` z_$$bindings?: ReturnType<__sveltets_Render${generics.toReferencesAnyString()}['bindings']>;\n` +
6314
+ `}\n` +
6315
+ `${doc}const ${className || '$$Component'}: $$IsomorphicComponent = null as any;\n` +
6316
+ surroundWithIgnoreComments(`type ${className || '$$Component'}${genericsDef} = InstanceType<typeof ${className || '$$Component'}${genericsRef}>;\n`) +
6317
+ `export default ${className || '$$Component'};`;
6318
+ }
6319
+ else if (mode === 'dts') {
6293
6320
  statement +=
6294
6321
  `export type ${PropsName}${genericsDef} = ${returnType('props')};\n` +
6295
6322
  `export type ${EventsName}${genericsDef} = ${returnType('events')};\n` +
6296
6323
  `export type ${SlotsName}${genericsDef} = ${returnType('slots')};\n` +
6297
6324
  `\n${doc}export default class${className ? ` ${className}` : ''}${genericsDef} extends ${svelteComponentClass}<${PropsName}${genericsRef}, ${EventsName}${genericsRef}, ${SlotsName}${genericsRef}> {` +
6298
- customConstructor +
6299
6325
  exportedNames.createClassGetters(genericsRef) +
6300
6326
  (usesAccessors ? exportedNames.createClassAccessors() : '') +
6301
6327
  '\n}';
@@ -6304,63 +6330,87 @@ class __sveltets_Render${genericsDef} {
6304
6330
  statement +=
6305
6331
  `\n\nimport { ${svelteComponentClass} as __SvelteComponentTyped__ } from "svelte" \n` +
6306
6332
  `${doc}export default class${className ? ` ${className}` : ''}${genericsDef} extends __SvelteComponentTyped__<${returnType('props')}, ${returnType('events')}, ${returnType('slots')}> {` +
6307
- customConstructor +
6308
6333
  exportedNames.createClassGetters(genericsRef) +
6309
6334
  (usesAccessors ? exportedNames.createClassAccessors() : '') +
6310
6335
  '\n}';
6311
6336
  }
6312
6337
  str.append(statement);
6313
6338
  }
6314
- function addSimpleComponentExport({ strictEvents, isTsFile, canHaveAnyProp, exportedNames, componentDocumentation, fileName, mode, usesAccessors, str, noSvelteComponentTyped }) {
6339
+ function addSimpleComponentExport({ strictEvents, isTsFile, canHaveAnyProp, exportedNames, componentDocumentation, fileName, mode, usesAccessors, str, usesSlots, noSvelteComponentTyped, isSvelte5 }) {
6315
6340
  const propDef = props(isTsFile, canHaveAnyProp, exportedNames, events(strictEvents, 'render()'));
6316
6341
  const doc = componentDocumentation.getFormatted();
6317
6342
  const className = fileName && classNameFromFilename(fileName, mode !== 'dts');
6318
- /**
6319
- * In Svelte 5 runes mode we add a custom constructor to override the default one which implicitly makes all properties bindable.
6320
- * Remove this once Svelte typings no longer do that (Svelte 6 or 7)
6321
- */
6322
- let customConstructor = '';
6323
- if (exportedNames.hasPropsRune()) {
6324
- customConstructor = `\n constructor(options = __sveltets_2_runes_constructor(${propDef})) { super(options); }`;
6325
- }
6326
6343
  let statement;
6327
- if (mode === 'dts' && isTsFile) {
6328
- const svelteComponentClass = noSvelteComponentTyped
6329
- ? 'SvelteComponent'
6330
- : 'SvelteComponentTyped';
6331
- const [PropsName, PropsExport] = addTypeExport(str, className, 'Props');
6332
- const [EventsName, EventsExport] = addTypeExport(str, className, 'Events');
6333
- const [SlotsName, SlotsExport] = addTypeExport(str, className, 'Slots');
6334
- statement =
6335
- `\nconst __propDef = ${propDef};\n` +
6336
- PropsExport +
6337
- EventsExport +
6338
- SlotsExport +
6339
- `\n${doc}export default class${className ? ` ${className}` : ''} extends ${svelteComponentClass}<${PropsName}, ${EventsName}, ${SlotsName}> {` +
6340
- customConstructor +
6341
- exportedNames.createClassGetters() +
6342
- (usesAccessors ? exportedNames.createClassAccessors() : '') +
6343
- '\n}';
6344
- }
6345
- else if (mode === 'dts' && !isTsFile) {
6346
- statement =
6347
- `\nconst __propDef = ${propDef};\n` +
6348
- `/** @typedef {typeof __propDef.props} ${className}Props */\n` +
6349
- `/** @typedef {typeof __propDef.events} ${className}Events */\n` +
6350
- `/** @typedef {typeof __propDef.slots} ${className}Slots */\n` +
6351
- `\n${doc}export default class${className ? ` ${className}` : ''} extends __sveltets_2_createSvelte2TsxComponent(${propDef}) {` +
6352
- customConstructor +
6353
- exportedNames.createClassGetters() +
6354
- (usesAccessors ? exportedNames.createClassAccessors() : '') +
6355
- '\n}';
6344
+ if (mode === 'dts') {
6345
+ if (isSvelte5) {
6346
+ // Inline definitions from Svelte shims; else dts files will reference the globals which will be unresolved
6347
+ statement =
6348
+ `\ninterface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
6349
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & { $$bindings?: Bindings } & Exports;
6350
+ (internal: unknown, props: ${!canHaveAnyProp && exportedNames.hasNoProps() ? '{$$events?: Events, $$slots?: Slots}' : 'Props & {$$events?: Events, $$slots?: Slots}'}): Exports;
6351
+ z_$$bindings?: Bindings;
6352
+ }\n` +
6353
+ (usesSlots
6354
+ ? `type $$__sveltets_2_PropsWithChildren<Props, Slots> = Props &
6355
+ (Slots extends { default: any }
6356
+ ? Props extends Record<string, never>
6357
+ ? any
6358
+ : { children?: any }
6359
+ : {});
6360
+ declare function $$__sveltets_2_isomorphic_component_slots<
6361
+ Props extends Record<string, any>, Events extends Record<string, any>, Slots extends Record<string, any>, Exports extends Record<string, any>, Bindings extends string
6362
+ >(klass: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }): $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWithChildren<Props, Slots>, Events, Slots, Exports, Bindings>;\n`
6363
+ : `
6364
+ declare function $$__sveltets_2_isomorphic_component<
6365
+ Props extends Record<string, any>, Events extends Record<string, any>, Slots extends Record<string, any>, Exports extends Record<string, any>, Bindings extends string
6366
+ >(klass: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }): $$__sveltets_2_IsomorphicComponent<Props, Events, Slots, Exports, Bindings>;\n`) +
6367
+ `${doc}const ${className || '$$Component'} = $$__sveltets_2_isomorphic_component${usesSlots ? '_slots' : ''}(${propDef});\n` +
6368
+ surroundWithIgnoreComments(`type ${className || '$$Component'} = InstanceType<typeof ${className || '$$Component'}>;\n`) +
6369
+ `export default ${className || '$$Component'};`;
6370
+ }
6371
+ else if (isTsFile) {
6372
+ const svelteComponentClass = noSvelteComponentTyped
6373
+ ? 'SvelteComponent'
6374
+ : 'SvelteComponentTyped';
6375
+ const [PropsName, PropsExport] = addTypeExport(str, className, 'Props');
6376
+ const [EventsName, EventsExport] = addTypeExport(str, className, 'Events');
6377
+ const [SlotsName, SlotsExport] = addTypeExport(str, className, 'Slots');
6378
+ statement =
6379
+ `\nconst __propDef = ${propDef};\n` +
6380
+ PropsExport +
6381
+ EventsExport +
6382
+ SlotsExport +
6383
+ `\n${doc}export default class${className ? ` ${className}` : ''} extends ${svelteComponentClass}<${PropsName}, ${EventsName}, ${SlotsName}> {` +
6384
+ exportedNames.createClassGetters() +
6385
+ (usesAccessors ? exportedNames.createClassAccessors() : '') +
6386
+ '\n}';
6387
+ }
6388
+ else {
6389
+ statement =
6390
+ `\nconst __propDef = ${propDef};\n` +
6391
+ `/** @typedef {typeof __propDef.props} ${className}Props */\n` +
6392
+ `/** @typedef {typeof __propDef.events} ${className}Events */\n` +
6393
+ `/** @typedef {typeof __propDef.slots} ${className}Slots */\n` +
6394
+ `\n${doc}export default class${className ? ` ${className}` : ''} extends __sveltets_2_createSvelte2TsxComponent(${propDef}) {` +
6395
+ exportedNames.createClassGetters() +
6396
+ (usesAccessors ? exportedNames.createClassAccessors() : '') +
6397
+ '\n}';
6398
+ }
6356
6399
  }
6357
6400
  else {
6358
- statement =
6359
- `\n\n${doc}export default class${className ? ` ${className}` : ''} extends __sveltets_2_createSvelte2TsxComponent(${propDef}) {` +
6360
- customConstructor +
6361
- exportedNames.createClassGetters() +
6362
- (usesAccessors ? exportedNames.createClassAccessors() : '') +
6363
- '\n}';
6401
+ if (isSvelte5) {
6402
+ statement =
6403
+ `\n${doc}const ${className || '$$Component'} = __sveltets_2_isomorphic_component${usesSlots ? '_slots' : ''}(${propDef});\n` +
6404
+ surroundWithIgnoreComments(`type ${className || '$$Component'} = InstanceType<typeof ${className || '$$Component'}>;\n`) +
6405
+ `export default ${className || '$$Component'};`;
6406
+ }
6407
+ else {
6408
+ statement =
6409
+ `\n\n${doc}export default class${className ? ` ${className}` : ''} extends __sveltets_2_createSvelte2TsxComponent(${propDef}) {` +
6410
+ exportedNames.createClassGetters() +
6411
+ (usesAccessors ? exportedNames.createClassAccessors() : '') +
6412
+ '\n}';
6413
+ }
6364
6414
  }
6365
6415
  str.append(statement);
6366
6416
  }
@@ -6396,7 +6446,10 @@ function events(strictEvents, renderStr) {
6396
6446
  return strictEvents ? renderStr : `__sveltets_2_with_any_event(${renderStr})`;
6397
6447
  }
6398
6448
  function props(isTsFile, canHaveAnyProp, exportedNames, renderStr) {
6399
- if (isTsFile) {
6449
+ if (exportedNames.usesRunes()) {
6450
+ return renderStr;
6451
+ }
6452
+ else if (isTsFile) {
6400
6453
  return canHaveAnyProp ? `__sveltets_2_with_any(${renderStr})` : renderStr;
6401
6454
  }
6402
6455
  else {
@@ -6757,7 +6810,7 @@ function svelte2tsx(svelte, options = { parse: compiler.parse }) {
6757
6810
  : instanceScriptTarget;
6758
6811
  const implicitStoreValues = new ImplicitStoreValues(resolvedStores, renderFunctionStart);
6759
6812
  //move the instance script and process the content
6760
- let exportedNames = new ExportedNames(str, 0, basename, options === null || options === void 0 ? void 0 : options.isTsFile);
6813
+ let exportedNames = new ExportedNames(str, 0, basename, options === null || options === void 0 ? void 0 : options.isTsFile, svelte5Plus);
6761
6814
  let generics = new Generics(str, 0, { attributes: [] });
6762
6815
  let uses$$SlotsInterface = false;
6763
6816
  if (scriptTag) {
@@ -6766,12 +6819,13 @@ function svelte2tsx(svelte, options = { parse: compiler.parse }) {
6766
6819
  str.move(scriptTag.start, scriptTag.end, instanceScriptTarget);
6767
6820
  }
6768
6821
  const res = processInstanceScriptContent(str, scriptTag, events, implicitStoreValues, options.mode,
6769
- /**hasModuleScripts */ !!moduleScriptTag, options === null || options === void 0 ? void 0 : options.isTsFile, basename);
6822
+ /**hasModuleScripts */ !!moduleScriptTag, options === null || options === void 0 ? void 0 : options.isTsFile, basename, svelte5Plus);
6770
6823
  uses$$props = uses$$props || res.uses$$props;
6771
6824
  uses$$restProps = uses$$restProps || res.uses$$restProps;
6772
6825
  uses$$slots = uses$$slots || res.uses$$slots;
6773
6826
  ({ exportedNames, events, generics, uses$$SlotsInterface } = res);
6774
6827
  }
6828
+ exportedNames.usesAccessors = usesAccessors;
6775
6829
  if (svelte5Plus) {
6776
6830
  exportedNames.checkGlobalsForRunes(implicitStoreValues.getGlobals());
6777
6831
  }
@@ -6799,14 +6853,16 @@ function svelte2tsx(svelte, options = { parse: compiler.parse }) {
6799
6853
  addComponentExport({
6800
6854
  str,
6801
6855
  canHaveAnyProp: !exportedNames.uses$$Props && (uses$$props || uses$$restProps),
6802
- strictEvents: events.hasStrictEvents(),
6856
+ strictEvents: events.hasStrictEvents(), // TODO in Svelte 6 we should also apply strictEvents in runes mode
6803
6857
  isTsFile: options === null || options === void 0 ? void 0 : options.isTsFile,
6804
6858
  exportedNames,
6805
6859
  usesAccessors,
6860
+ usesSlots: slots.size > 0,
6806
6861
  fileName: options === null || options === void 0 ? void 0 : options.filename,
6807
6862
  componentDocumentation,
6808
6863
  mode: options.mode,
6809
6864
  generics,
6865
+ isSvelte5: svelte5Plus,
6810
6866
  noSvelteComponentTyped: options.noSvelteComponentTyped
6811
6867
  });
6812
6868
  if (options.mode === 'dts') {
@@ -7024,6 +7080,11 @@ async function createTsCompilerHost(options, svelteMap) {
7024
7080
  */
7025
7081
  async function createSvelteMap(config) {
7026
7082
  const svelteFiles = new Map();
7083
+ // TODO detect Svelte version in here and set shimsPath accordingly if not given from above
7084
+ const noSvelteComponentTyped = config.svelteShimsPath
7085
+ .replace(/\\/g, '/')
7086
+ .endsWith('svelte2tsx/svelte-shims-v4.d.ts');
7087
+ const version = noSvelteComponentTyped ? undefined : '3.42.0';
7027
7088
  function add(path) {
7028
7089
  const code = ts.sys.readFile(path, 'utf-8');
7029
7090
  const isTsFile = /<script\s+[^>]*?lang=('|")(ts|typescript)('|")/.test(code);
@@ -7031,9 +7092,8 @@ async function createSvelteMap(config) {
7031
7092
  filename: path,
7032
7093
  isTsFile,
7033
7094
  mode: 'dts',
7034
- noSvelteComponentTyped: config.svelteShimsPath
7035
- .replace(/\\/g, '/')
7036
- .endsWith('svelte2tsx/svelte-shims-v4.d.ts')
7095
+ version,
7096
+ noSvelteComponentTyped: noSvelteComponentTyped
7037
7097
  }).code;
7038
7098
  svelteFiles.set(path, transformed);
7039
7099
  return isTsFile;
package/index.mjs CHANGED
@@ -2666,18 +2666,12 @@ function handleBinding(str, attr, parent, element, preserveBind, isSvelte5Plus)
2666
2666
  const value = isShorthand
2667
2667
  ? preserveBind && element instanceof Element
2668
2668
  ? [rangeWithTrailingPropertyAccess(str.original, attr.expression)]
2669
- : isSvelte5Plus
2670
- ? [
2671
- `__sveltets_2_binding(${str.original.substring(attr.expression.start, attr.expression.end)})`
2672
- ]
2673
- : undefined
2674
- : element instanceof Element || !isSvelte5Plus
2675
- ? [rangeWithTrailingPropertyAccess(str.original, attr.expression)]
2676
- : [
2677
- '__sveltets_2_binding(',
2678
- rangeWithTrailingPropertyAccess(str.original, attr.expression),
2679
- ')'
2680
- ];
2669
+ : undefined
2670
+ : [rangeWithTrailingPropertyAccess(str.original, attr.expression)];
2671
+ if (isSvelte5Plus && element instanceof InlineComponent) {
2672
+ // To check if property is actually bindable
2673
+ element.appendToStartEnd([`${element.name}.$$bindings = '${attr.name}';`]);
2674
+ }
2681
2675
  if (element instanceof Element) {
2682
2676
  element.addAttribute(name, value);
2683
2677
  }
@@ -3111,10 +3105,13 @@ function handleSnippet(str, snippetBlock, component) {
3111
3105
  let generic = '';
3112
3106
  if ((_e = snippetBlock.parameters) === null || _e === void 0 ? void 0 : _e.length) {
3113
3107
  generic = `<[${snippetBlock.parameters
3114
- .map((p) => p.typeAnnotation
3115
- ? str.original.slice(p.typeAnnotation.start + 1, p.typeAnnotation.end)
3116
- : // slap any on to it to silence "implicit any" errors; JSDoc people can't add types to snippets
3117
- 'any')
3108
+ .map((p) => {
3109
+ var _a;
3110
+ return ((_a = p.typeAnnotation) === null || _a === void 0 ? void 0 : _a.typeAnnotation)
3111
+ ? str.original.slice(p.typeAnnotation.typeAnnotation.start, p.typeAnnotation.typeAnnotation.end)
3112
+ : // slap any on to it to silence "implicit any" errors; JSDoc people can't add types to snippets
3113
+ 'any';
3114
+ })
3118
3115
  .join(', ')}]>`;
3119
3116
  }
3120
3117
  const typeAnnotation = surroundWithIgnoreComments(`: import('svelte').Snippet${generic}`);
@@ -4364,11 +4361,13 @@ function is$$PropsDeclaration(node) {
4364
4361
  return isInterfaceOrTypeDeclaration(node) && node.name.text === '$$Props';
4365
4362
  }
4366
4363
  class ExportedNames {
4367
- constructor(str, astOffset, basename, isTsFile) {
4364
+ constructor(str, astOffset, basename, isTsFile, isSvelte5Plus) {
4368
4365
  this.str = str;
4369
4366
  this.astOffset = astOffset;
4370
4367
  this.basename = basename;
4371
4368
  this.isTsFile = isTsFile;
4369
+ this.isSvelte5Plus = isSvelte5Plus;
4370
+ this.usesAccessors = false;
4372
4371
  /**
4373
4372
  * Uses the `$$Props` type
4374
4373
  */
@@ -4471,7 +4470,12 @@ class ExportedNames {
4471
4470
  ? element.propertyName.text
4472
4471
  : element.name.text;
4473
4472
  if (element.initializer) {
4474
- const call = element.initializer;
4473
+ let call = element.initializer;
4474
+ // if it's an as expression we need to check wether the as
4475
+ // expression expression is a call
4476
+ if (ts.isAsExpression(call)) {
4477
+ call = call.expression;
4478
+ }
4475
4479
  if (ts.isCallExpression(call) && ts.isIdentifier(call.expression)) {
4476
4480
  if (call.expression.text === '$bindable') {
4477
4481
  this.$props.bindings.push(name);
@@ -4494,7 +4498,9 @@ class ExportedNames {
4494
4498
  preprendStr(this.str, generic_arg.pos + this.astOffset, `;type ${this.$props.type} = `);
4495
4499
  this.str.appendLeft(generic_arg.end + this.astOffset, ';');
4496
4500
  this.str.move(generic_arg.pos + this.astOffset, generic_arg.end + this.astOffset, node.parent.pos + this.astOffset);
4497
- this.str.appendRight(generic_arg.end + this.astOffset, this.$props.type);
4501
+ this.str.appendRight(generic_arg.end + this.astOffset,
4502
+ // so that semantic tokens ignore it, preventing an overlap of tokens
4503
+ surroundWithIgnoreComments(this.$props.type));
4498
4504
  }
4499
4505
  }
4500
4506
  else {
@@ -4839,38 +4845,13 @@ class ExportedNames {
4839
4845
  */
4840
4846
  createPropsStr(uses$$propsOr$$restProps) {
4841
4847
  const names = Array.from(this.exports.entries());
4842
- if (this.$props.type) {
4843
- return ('{} as any as ' +
4844
- (this.$props.bindings.length
4845
- ? `__sveltets_2_Bindings<${this.$props.type}, ${this.$props.bindings.map((b) => `"${b}"`).join('|')}>`
4846
- : this.$props.type));
4847
- }
4848
- if (this.$props.comment) {
4849
- let result = this.$props.comment + '({})';
4850
- // Try our best to incorporate __sveltets_2_Bindings here
4851
- let idx = this.$props.comment.indexOf('@type');
4852
- if (idx !== -1 && /[\s{]/.test(this.$props.comment[idx + 5])) {
4853
- idx = this.$props.comment.indexOf('{', idx);
4854
- const end = this.$props.comment.lastIndexOf('}');
4855
- if (idx !== -1 && end !== -1 && idx < end) {
4856
- const has_bindings = this.$props.bindings.length;
4857
- if (has_bindings) {
4858
- idx++;
4859
- result =
4860
- this.$props.comment.slice(0, idx) +
4861
- (has_bindings ? '__sveltets_2_Bindings<' : '') +
4862
- this.$props.comment.slice(idx, end) +
4863
- (has_bindings
4864
- ? `, ${this.$props.bindings.map((b) => `"${b}"`).join('|')}>`
4865
- : '') +
4866
- this.$props.comment.slice(end) +
4867
- '({})';
4868
- }
4869
- }
4870
- }
4871
- return result;
4872
- }
4873
4848
  if (this.usesRunes()) {
4849
+ if (this.$props.type) {
4850
+ return '{} as any as ' + this.$props.type;
4851
+ }
4852
+ if (this.$props.comment) {
4853
+ return this.$props.comment + '({})';
4854
+ }
4874
4855
  // Necessary, because {} roughly equals to any
4875
4856
  return this.isTsFile
4876
4857
  ? '{} as Record<string, never>'
@@ -4911,22 +4892,48 @@ class ExportedNames {
4911
4892
  const returnElementsType = this.createReturnElementsType(names);
4912
4893
  return `{${returnElements.join(' , ')}} as {${returnElementsType.join(', ')}}`;
4913
4894
  }
4895
+ hasNoProps() {
4896
+ if (this.usesRunes()) {
4897
+ return !this.$props.type && !this.$props.comment;
4898
+ }
4899
+ const names = Array.from(this.exports.entries());
4900
+ return names.length === 0;
4901
+ }
4902
+ createBindingsStr() {
4903
+ if (this.usesRunes()) {
4904
+ // will be just the empty strings for zero bindings, which is impossible to create a binding for, so it works out fine
4905
+ return `__sveltets_$$bindings('${this.$props.bindings.join("', '")}')`;
4906
+ }
4907
+ else {
4908
+ return '""';
4909
+ }
4910
+ }
4914
4911
  /**
4915
4912
  * In runes mode, exports are no longer part of props because you cannot `bind:` to them,
4916
- * which is why we need a separate return type for them.
4913
+ * which is why we need a separate return type for them. In Svelte 5, the isomorphic component
4914
+ * needs them separate, too.
4917
4915
  */
4918
4916
  createExportsStr() {
4919
4917
  const names = Array.from(this.exports.entries());
4920
4918
  const others = names.filter(([, { isLet }]) => !isLet);
4921
- if (this.usesRunes() && others.length > 0) {
4922
- if (this.isTsFile) {
4923
- return (', exports: {} as any as { ' +
4924
- this.createReturnElementsType(others, undefined, true).join(',') +
4925
- ' }');
4919
+ const needsAccessors = this.usesAccessors && names.length > 0 && !this.usesRunes(); // runes mode doesn't support accessors
4920
+ if (this.isSvelte5Plus && (others.length > 0 || this.usesRunes() || needsAccessors)) {
4921
+ let str = '';
4922
+ if (others.length > 0 || needsAccessors) {
4923
+ if (this.isTsFile) {
4924
+ str +=
4925
+ ', exports: {} as any as { ' +
4926
+ this.createReturnElementsType(needsAccessors ? names : others, undefined, true).join(',') +
4927
+ ' }';
4928
+ }
4929
+ else {
4930
+ str += `, exports: /** @type {{${this.createReturnElementsType(needsAccessors ? names : others, false, true)}}} */ ({})`;
4931
+ }
4926
4932
  }
4927
- else {
4928
- return `, exports: /** @type {${this.createReturnElementsType(others, false, true)}} */ ({})`;
4933
+ if (this.usesRunes()) {
4934
+ str += `, bindings: ${this.createBindingsStr()}`;
4929
4935
  }
4936
+ return str;
4930
4937
  }
4931
4938
  return '';
4932
4939
  }
@@ -4958,12 +4965,17 @@ class ExportedNames {
4958
4965
  getExportsMap() {
4959
4966
  return this.exports;
4960
4967
  }
4968
+ hasExports() {
4969
+ const names = Array.from(this.exports.entries());
4970
+ return this.usesAccessors ? names.length > 0 : names.some(([, { isLet }]) => !isLet);
4971
+ }
4961
4972
  hasPropsRune() {
4962
- return this.$props.type || this.$props.comment;
4973
+ return this.isSvelte5Plus && (this.$props.type || this.$props.comment);
4963
4974
  }
4964
4975
  checkGlobalsForRunes(globals) {
4965
4976
  const runes = ['$state', '$derived', '$effect']; // no need to check for props, already handled through other means in here
4966
- this.hasRunesGlobals = globals.some((global) => runes.includes(global));
4977
+ this.hasRunesGlobals =
4978
+ this.isSvelte5Plus && globals.some((global) => runes.includes(global));
4967
4979
  }
4968
4980
  usesRunes() {
4969
4981
  return this.hasRunesGlobals || this.hasPropsRune();
@@ -5840,6 +5852,9 @@ class Generics {
5840
5852
  toReferencesString() {
5841
5853
  return this.references.length ? `<${this.references.join(',')}>` : '';
5842
5854
  }
5855
+ toReferencesAnyString() {
5856
+ return this.references.length ? `<${this.references.map(() => 'any').join(',')}>` : '';
5857
+ }
5843
5858
  has() {
5844
5859
  return this.definitions.length > 0;
5845
5860
  }
@@ -5920,12 +5935,12 @@ class InterfacesAndTypes {
5920
5935
  }
5921
5936
  }
5922
5937
 
5923
- function processInstanceScriptContent(str, script, events, implicitStoreValues, mode, hasModuleScript, isTSFile, basename) {
5938
+ function processInstanceScriptContent(str, script, events, implicitStoreValues, mode, hasModuleScript, isTSFile, basename, isSvelte5Plus) {
5924
5939
  const htmlx = str.original;
5925
5940
  const scriptContent = htmlx.substring(script.content.start, script.content.end);
5926
5941
  const tsAst = ts.createSourceFile('component.ts.svelte', scriptContent, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
5927
5942
  const astOffset = script.content.start;
5928
- const exportedNames = new ExportedNames(str, astOffset, basename, isTSFile);
5943
+ const exportedNames = new ExportedNames(str, astOffset, basename, isTSFile, isSvelte5Plus);
5929
5944
  const generics = new Generics(str, astOffset, script);
5930
5945
  const interfacesAndTypes = new InterfacesAndTypes();
5931
5946
  const implicitTopLevelNames = new ImplicitTopLevelNames(str, astOffset);
@@ -6234,7 +6249,7 @@ function addComponentExport(params) {
6234
6249
  addSimpleComponentExport(params);
6235
6250
  }
6236
6251
  }
6237
- function addGenericsComponentExport({ strictEvents, canHaveAnyProp, exportedNames, componentDocumentation, fileName, mode, usesAccessors, str, generics, noSvelteComponentTyped }) {
6252
+ function addGenericsComponentExport({ strictEvents, canHaveAnyProp, exportedNames, componentDocumentation, fileName, mode, usesAccessors, str, generics, usesSlots, isSvelte5, noSvelteComponentTyped }) {
6238
6253
  const genericsDef = generics.toDefinitionString();
6239
6254
  const genericsRef = generics.toReferencesString();
6240
6255
  const doc = componentDocumentation.getFormatted();
@@ -6253,7 +6268,11 @@ class __sveltets_Render${genericsDef} {
6253
6268
  slots() {
6254
6269
  return render${genericsRef}().slots;
6255
6270
  }
6256
- }
6271
+ ${isSvelte5
6272
+ ? ` bindings() { return ${exportedNames.createBindingsStr()}; }
6273
+ exports() { return ${exportedNames.hasExports() ? `render${genericsRef}().exports` : '{}'}; }
6274
+ }`
6275
+ : '}'}
6257
6276
  `;
6258
6277
  const svelteComponentClass = noSvelteComponentTyped
6259
6278
  ? 'SvelteComponent'
@@ -6261,21 +6280,28 @@ class __sveltets_Render${genericsDef} {
6261
6280
  const [PropsName] = addTypeExport(str, className, 'Props');
6262
6281
  const [EventsName] = addTypeExport(str, className, 'Events');
6263
6282
  const [SlotsName] = addTypeExport(str, className, 'Slots');
6264
- /**
6265
- * In Svelte 5 runes mode we add a custom constructor to override the default one which implicitly makes all properties bindable.
6266
- * Remove this once Svelte typings no longer do that (Svelte 6 or 7)
6267
- */
6268
- let customConstructor = '';
6269
- if (exportedNames.hasPropsRune()) {
6270
- customConstructor = `\n constructor(options: import('svelte').ComponentConstructorOptions<__sveltets_2_PropsWithChildren<${returnType('props')}, ${returnType('slots')}>>) { super(options); }`;
6271
- }
6272
- if (mode === 'dts') {
6283
+ if (isSvelte5) {
6284
+ // Don't add props/events/slots type exports in dts mode for now, maybe someone asks for it to be back,
6285
+ // but it's safer to not do it for now to have more flexibility in the future.
6286
+ const propsType = !canHaveAnyProp && exportedNames.hasNoProps()
6287
+ ? `{$$events?: ${returnType('events')}${usesSlots ? `, $$slots?: ${returnType('slots')}, children?: any` : ''}}`
6288
+ : `${returnType('props')} & {$$events?: ${returnType('events')}${usesSlots ? `, $$slots?: ${returnType('slots')}, children?: any` : ''}}`;
6289
+ statement +=
6290
+ `\ninterface $$IsomorphicComponent {\n` +
6291
+ ` 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` +
6292
+ ` ${genericsDef}(internal: unknown, props: ${propsType}): ${returnType('exports')};\n` +
6293
+ ` z_$$bindings?: ReturnType<__sveltets_Render${generics.toReferencesAnyString()}['bindings']>;\n` +
6294
+ `}\n` +
6295
+ `${doc}const ${className || '$$Component'}: $$IsomorphicComponent = null as any;\n` +
6296
+ surroundWithIgnoreComments(`type ${className || '$$Component'}${genericsDef} = InstanceType<typeof ${className || '$$Component'}${genericsRef}>;\n`) +
6297
+ `export default ${className || '$$Component'};`;
6298
+ }
6299
+ else if (mode === 'dts') {
6273
6300
  statement +=
6274
6301
  `export type ${PropsName}${genericsDef} = ${returnType('props')};\n` +
6275
6302
  `export type ${EventsName}${genericsDef} = ${returnType('events')};\n` +
6276
6303
  `export type ${SlotsName}${genericsDef} = ${returnType('slots')};\n` +
6277
6304
  `\n${doc}export default class${className ? ` ${className}` : ''}${genericsDef} extends ${svelteComponentClass}<${PropsName}${genericsRef}, ${EventsName}${genericsRef}, ${SlotsName}${genericsRef}> {` +
6278
- customConstructor +
6279
6305
  exportedNames.createClassGetters(genericsRef) +
6280
6306
  (usesAccessors ? exportedNames.createClassAccessors() : '') +
6281
6307
  '\n}';
@@ -6284,63 +6310,87 @@ class __sveltets_Render${genericsDef} {
6284
6310
  statement +=
6285
6311
  `\n\nimport { ${svelteComponentClass} as __SvelteComponentTyped__ } from "svelte" \n` +
6286
6312
  `${doc}export default class${className ? ` ${className}` : ''}${genericsDef} extends __SvelteComponentTyped__<${returnType('props')}, ${returnType('events')}, ${returnType('slots')}> {` +
6287
- customConstructor +
6288
6313
  exportedNames.createClassGetters(genericsRef) +
6289
6314
  (usesAccessors ? exportedNames.createClassAccessors() : '') +
6290
6315
  '\n}';
6291
6316
  }
6292
6317
  str.append(statement);
6293
6318
  }
6294
- function addSimpleComponentExport({ strictEvents, isTsFile, canHaveAnyProp, exportedNames, componentDocumentation, fileName, mode, usesAccessors, str, noSvelteComponentTyped }) {
6319
+ function addSimpleComponentExport({ strictEvents, isTsFile, canHaveAnyProp, exportedNames, componentDocumentation, fileName, mode, usesAccessors, str, usesSlots, noSvelteComponentTyped, isSvelte5 }) {
6295
6320
  const propDef = props(isTsFile, canHaveAnyProp, exportedNames, events(strictEvents, 'render()'));
6296
6321
  const doc = componentDocumentation.getFormatted();
6297
6322
  const className = fileName && classNameFromFilename(fileName, mode !== 'dts');
6298
- /**
6299
- * In Svelte 5 runes mode we add a custom constructor to override the default one which implicitly makes all properties bindable.
6300
- * Remove this once Svelte typings no longer do that (Svelte 6 or 7)
6301
- */
6302
- let customConstructor = '';
6303
- if (exportedNames.hasPropsRune()) {
6304
- customConstructor = `\n constructor(options = __sveltets_2_runes_constructor(${propDef})) { super(options); }`;
6305
- }
6306
6323
  let statement;
6307
- if (mode === 'dts' && isTsFile) {
6308
- const svelteComponentClass = noSvelteComponentTyped
6309
- ? 'SvelteComponent'
6310
- : 'SvelteComponentTyped';
6311
- const [PropsName, PropsExport] = addTypeExport(str, className, 'Props');
6312
- const [EventsName, EventsExport] = addTypeExport(str, className, 'Events');
6313
- const [SlotsName, SlotsExport] = addTypeExport(str, className, 'Slots');
6314
- statement =
6315
- `\nconst __propDef = ${propDef};\n` +
6316
- PropsExport +
6317
- EventsExport +
6318
- SlotsExport +
6319
- `\n${doc}export default class${className ? ` ${className}` : ''} extends ${svelteComponentClass}<${PropsName}, ${EventsName}, ${SlotsName}> {` +
6320
- customConstructor +
6321
- exportedNames.createClassGetters() +
6322
- (usesAccessors ? exportedNames.createClassAccessors() : '') +
6323
- '\n}';
6324
- }
6325
- else if (mode === 'dts' && !isTsFile) {
6326
- statement =
6327
- `\nconst __propDef = ${propDef};\n` +
6328
- `/** @typedef {typeof __propDef.props} ${className}Props */\n` +
6329
- `/** @typedef {typeof __propDef.events} ${className}Events */\n` +
6330
- `/** @typedef {typeof __propDef.slots} ${className}Slots */\n` +
6331
- `\n${doc}export default class${className ? ` ${className}` : ''} extends __sveltets_2_createSvelte2TsxComponent(${propDef}) {` +
6332
- customConstructor +
6333
- exportedNames.createClassGetters() +
6334
- (usesAccessors ? exportedNames.createClassAccessors() : '') +
6335
- '\n}';
6324
+ if (mode === 'dts') {
6325
+ if (isSvelte5) {
6326
+ // Inline definitions from Svelte shims; else dts files will reference the globals which will be unresolved
6327
+ statement =
6328
+ `\ninterface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
6329
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & { $$bindings?: Bindings } & Exports;
6330
+ (internal: unknown, props: ${!canHaveAnyProp && exportedNames.hasNoProps() ? '{$$events?: Events, $$slots?: Slots}' : 'Props & {$$events?: Events, $$slots?: Slots}'}): Exports;
6331
+ z_$$bindings?: Bindings;
6332
+ }\n` +
6333
+ (usesSlots
6334
+ ? `type $$__sveltets_2_PropsWithChildren<Props, Slots> = Props &
6335
+ (Slots extends { default: any }
6336
+ ? Props extends Record<string, never>
6337
+ ? any
6338
+ : { children?: any }
6339
+ : {});
6340
+ declare function $$__sveltets_2_isomorphic_component_slots<
6341
+ Props extends Record<string, any>, Events extends Record<string, any>, Slots extends Record<string, any>, Exports extends Record<string, any>, Bindings extends string
6342
+ >(klass: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }): $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWithChildren<Props, Slots>, Events, Slots, Exports, Bindings>;\n`
6343
+ : `
6344
+ declare function $$__sveltets_2_isomorphic_component<
6345
+ Props extends Record<string, any>, Events extends Record<string, any>, Slots extends Record<string, any>, Exports extends Record<string, any>, Bindings extends string
6346
+ >(klass: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }): $$__sveltets_2_IsomorphicComponent<Props, Events, Slots, Exports, Bindings>;\n`) +
6347
+ `${doc}const ${className || '$$Component'} = $$__sveltets_2_isomorphic_component${usesSlots ? '_slots' : ''}(${propDef});\n` +
6348
+ surroundWithIgnoreComments(`type ${className || '$$Component'} = InstanceType<typeof ${className || '$$Component'}>;\n`) +
6349
+ `export default ${className || '$$Component'};`;
6350
+ }
6351
+ else if (isTsFile) {
6352
+ const svelteComponentClass = noSvelteComponentTyped
6353
+ ? 'SvelteComponent'
6354
+ : 'SvelteComponentTyped';
6355
+ const [PropsName, PropsExport] = addTypeExport(str, className, 'Props');
6356
+ const [EventsName, EventsExport] = addTypeExport(str, className, 'Events');
6357
+ const [SlotsName, SlotsExport] = addTypeExport(str, className, 'Slots');
6358
+ statement =
6359
+ `\nconst __propDef = ${propDef};\n` +
6360
+ PropsExport +
6361
+ EventsExport +
6362
+ SlotsExport +
6363
+ `\n${doc}export default class${className ? ` ${className}` : ''} extends ${svelteComponentClass}<${PropsName}, ${EventsName}, ${SlotsName}> {` +
6364
+ exportedNames.createClassGetters() +
6365
+ (usesAccessors ? exportedNames.createClassAccessors() : '') +
6366
+ '\n}';
6367
+ }
6368
+ else {
6369
+ statement =
6370
+ `\nconst __propDef = ${propDef};\n` +
6371
+ `/** @typedef {typeof __propDef.props} ${className}Props */\n` +
6372
+ `/** @typedef {typeof __propDef.events} ${className}Events */\n` +
6373
+ `/** @typedef {typeof __propDef.slots} ${className}Slots */\n` +
6374
+ `\n${doc}export default class${className ? ` ${className}` : ''} extends __sveltets_2_createSvelte2TsxComponent(${propDef}) {` +
6375
+ exportedNames.createClassGetters() +
6376
+ (usesAccessors ? exportedNames.createClassAccessors() : '') +
6377
+ '\n}';
6378
+ }
6336
6379
  }
6337
6380
  else {
6338
- statement =
6339
- `\n\n${doc}export default class${className ? ` ${className}` : ''} extends __sveltets_2_createSvelte2TsxComponent(${propDef}) {` +
6340
- customConstructor +
6341
- exportedNames.createClassGetters() +
6342
- (usesAccessors ? exportedNames.createClassAccessors() : '') +
6343
- '\n}';
6381
+ if (isSvelte5) {
6382
+ statement =
6383
+ `\n${doc}const ${className || '$$Component'} = __sveltets_2_isomorphic_component${usesSlots ? '_slots' : ''}(${propDef});\n` +
6384
+ surroundWithIgnoreComments(`type ${className || '$$Component'} = InstanceType<typeof ${className || '$$Component'}>;\n`) +
6385
+ `export default ${className || '$$Component'};`;
6386
+ }
6387
+ else {
6388
+ statement =
6389
+ `\n\n${doc}export default class${className ? ` ${className}` : ''} extends __sveltets_2_createSvelte2TsxComponent(${propDef}) {` +
6390
+ exportedNames.createClassGetters() +
6391
+ (usesAccessors ? exportedNames.createClassAccessors() : '') +
6392
+ '\n}';
6393
+ }
6344
6394
  }
6345
6395
  str.append(statement);
6346
6396
  }
@@ -6376,7 +6426,10 @@ function events(strictEvents, renderStr) {
6376
6426
  return strictEvents ? renderStr : `__sveltets_2_with_any_event(${renderStr})`;
6377
6427
  }
6378
6428
  function props(isTsFile, canHaveAnyProp, exportedNames, renderStr) {
6379
- if (isTsFile) {
6429
+ if (exportedNames.usesRunes()) {
6430
+ return renderStr;
6431
+ }
6432
+ else if (isTsFile) {
6380
6433
  return canHaveAnyProp ? `__sveltets_2_with_any(${renderStr})` : renderStr;
6381
6434
  }
6382
6435
  else {
@@ -6737,7 +6790,7 @@ function svelte2tsx(svelte, options = { parse }) {
6737
6790
  : instanceScriptTarget;
6738
6791
  const implicitStoreValues = new ImplicitStoreValues(resolvedStores, renderFunctionStart);
6739
6792
  //move the instance script and process the content
6740
- let exportedNames = new ExportedNames(str, 0, basename, options === null || options === void 0 ? void 0 : options.isTsFile);
6793
+ let exportedNames = new ExportedNames(str, 0, basename, options === null || options === void 0 ? void 0 : options.isTsFile, svelte5Plus);
6741
6794
  let generics = new Generics(str, 0, { attributes: [] });
6742
6795
  let uses$$SlotsInterface = false;
6743
6796
  if (scriptTag) {
@@ -6746,12 +6799,13 @@ function svelte2tsx(svelte, options = { parse }) {
6746
6799
  str.move(scriptTag.start, scriptTag.end, instanceScriptTarget);
6747
6800
  }
6748
6801
  const res = processInstanceScriptContent(str, scriptTag, events, implicitStoreValues, options.mode,
6749
- /**hasModuleScripts */ !!moduleScriptTag, options === null || options === void 0 ? void 0 : options.isTsFile, basename);
6802
+ /**hasModuleScripts */ !!moduleScriptTag, options === null || options === void 0 ? void 0 : options.isTsFile, basename, svelte5Plus);
6750
6803
  uses$$props = uses$$props || res.uses$$props;
6751
6804
  uses$$restProps = uses$$restProps || res.uses$$restProps;
6752
6805
  uses$$slots = uses$$slots || res.uses$$slots;
6753
6806
  ({ exportedNames, events, generics, uses$$SlotsInterface } = res);
6754
6807
  }
6808
+ exportedNames.usesAccessors = usesAccessors;
6755
6809
  if (svelte5Plus) {
6756
6810
  exportedNames.checkGlobalsForRunes(implicitStoreValues.getGlobals());
6757
6811
  }
@@ -6779,14 +6833,16 @@ function svelte2tsx(svelte, options = { parse }) {
6779
6833
  addComponentExport({
6780
6834
  str,
6781
6835
  canHaveAnyProp: !exportedNames.uses$$Props && (uses$$props || uses$$restProps),
6782
- strictEvents: events.hasStrictEvents(),
6836
+ strictEvents: events.hasStrictEvents(), // TODO in Svelte 6 we should also apply strictEvents in runes mode
6783
6837
  isTsFile: options === null || options === void 0 ? void 0 : options.isTsFile,
6784
6838
  exportedNames,
6785
6839
  usesAccessors,
6840
+ usesSlots: slots.size > 0,
6786
6841
  fileName: options === null || options === void 0 ? void 0 : options.filename,
6787
6842
  componentDocumentation,
6788
6843
  mode: options.mode,
6789
6844
  generics,
6845
+ isSvelte5: svelte5Plus,
6790
6846
  noSvelteComponentTyped: options.noSvelteComponentTyped
6791
6847
  });
6792
6848
  if (options.mode === 'dts') {
@@ -7004,6 +7060,11 @@ async function createTsCompilerHost(options, svelteMap) {
7004
7060
  */
7005
7061
  async function createSvelteMap(config) {
7006
7062
  const svelteFiles = new Map();
7063
+ // TODO detect Svelte version in here and set shimsPath accordingly if not given from above
7064
+ const noSvelteComponentTyped = config.svelteShimsPath
7065
+ .replace(/\\/g, '/')
7066
+ .endsWith('svelte2tsx/svelte-shims-v4.d.ts');
7067
+ const version = noSvelteComponentTyped ? undefined : '3.42.0';
7007
7068
  function add(path) {
7008
7069
  const code = ts.sys.readFile(path, 'utf-8');
7009
7070
  const isTsFile = /<script\s+[^>]*?lang=('|")(ts|typescript)('|")/.test(code);
@@ -7011,9 +7072,8 @@ async function createSvelteMap(config) {
7011
7072
  filename: path,
7012
7073
  isTsFile,
7013
7074
  mode: 'dts',
7014
- noSvelteComponentTyped: config.svelteShimsPath
7015
- .replace(/\\/g, '/')
7016
- .endsWith('svelte2tsx/svelte-shims-v4.d.ts')
7075
+ version,
7076
+ noSvelteComponentTyped: noSvelteComponentTyped
7017
7077
  }).code;
7018
7078
  svelteFiles.set(path, transformed);
7019
7079
  return isTsFile;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte2tsx",
3
- "version": "0.7.7",
3
+ "version": "0.7.9",
4
4
  "description": "Convert Svelte components to TSX for type checking",
5
5
  "author": "David Pershouse",
6
6
  "license": "MIT",
@@ -70,30 +70,30 @@ declare function __sveltets_2_slotsType<Slots, Key extends keyof Slots>(slots: S
70
70
  // An empty array of optionalProps makes OptionalProps type any, which means we lose the prop typing.
71
71
  // optionalProps need to be first or its type cannot be infered correctly.
72
72
 
73
- declare function __sveltets_2_partial<Props = {}, Events = {}, Slots = {}>(
74
- render: {props: Props, events: Events, slots: Slots }
75
- ): {props: Expand<SveltePropsAnyFallback<Props>>, events: Events, slots: Expand<SvelteSlotsAnyFallback<Slots>> }
76
- declare function __sveltets_2_partial<Props = {}, Events = {}, Slots = {}, OptionalProps extends keyof Props = any>(
73
+ declare function __sveltets_2_partial<Props = {}, Events = {}, Slots = {}, Exports = {}, Bindings = string>(
74
+ render: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }
75
+ ): {props: Expand<SveltePropsAnyFallback<Props>>, events: Events, slots: Expand<SvelteSlotsAnyFallback<Slots>>, exports?: Exports, bindings?: Bindings }
76
+ declare function __sveltets_2_partial<Props = {}, Events = {}, Slots = {}, Exports = {}, Bindings = string, OptionalProps extends keyof Props = any>(
77
77
  optionalProps: OptionalProps[],
78
- render: {props: Props, events: Events, slots: Slots }
79
- ): {props: Expand<SvelteWithOptionalProps<SveltePropsAnyFallback<Props>, OptionalProps>>, events: Events, slots: Expand<SvelteSlotsAnyFallback<Slots>> }
78
+ render: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }
79
+ ): {props: Expand<SvelteWithOptionalProps<SveltePropsAnyFallback<Props>, OptionalProps>>, events: Events, slots: Expand<SvelteSlotsAnyFallback<Slots>>, exports?: Exports, bindings?: Bindings }
80
80
 
81
- declare function __sveltets_2_partial_with_any<Props = {}, Events = {}, Slots = {}>(
82
- render: {props: Props, events: Events, slots: Slots }
83
- ): {props: Expand<SveltePropsAnyFallback<Props> & SvelteAllProps>, events: Events, slots: Expand<SvelteSlotsAnyFallback<Slots>> }
84
- declare function __sveltets_2_partial_with_any<Props = {}, Events = {}, Slots = {}, OptionalProps extends keyof Props = any>(
81
+ declare function __sveltets_2_partial_with_any<Props = {}, Events = {}, Slots = {}, Exports = {}, Bindings = string>(
82
+ render: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }
83
+ ): {props: Expand<SveltePropsAnyFallback<Props> & SvelteAllProps>, events: Events, slots: Expand<SvelteSlotsAnyFallback<Slots>>, exports?: Exports, bindings?: Bindings }
84
+ declare function __sveltets_2_partial_with_any<Props = {}, Events = {}, Slots = {}, Exports = {}, Bindings = string, OptionalProps extends keyof Props = any>(
85
85
  optionalProps: OptionalProps[],
86
- render: {props: Props, events: Events, slots: Slots }
87
- ): {props: Expand<SvelteWithOptionalProps<SveltePropsAnyFallback<Props>, OptionalProps> & SvelteAllProps>, events: Events, slots: Expand<SvelteSlotsAnyFallback<Slots>> }
86
+ render: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }
87
+ ): {props: Expand<SvelteWithOptionalProps<SveltePropsAnyFallback<Props>, OptionalProps> & SvelteAllProps>, events: Events, slots: Expand<SvelteSlotsAnyFallback<Slots>>, exports?: Exports, bindings?: Bindings }
88
88
 
89
89
 
90
- declare function __sveltets_2_with_any<Props = {}, Events = {}, Slots = {}>(
91
- render: {props: Props, events: Events, slots: Slots }
92
- ): {props: Expand<Props & SvelteAllProps>, events: Events, slots: Slots }
90
+ declare function __sveltets_2_with_any<Props = {}, Events = {}, Slots = {}, Exports = {}, Bindings = string>(
91
+ render: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }
92
+ ): {props: Expand<Props & SvelteAllProps>, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }
93
93
 
94
- declare function __sveltets_2_with_any_event<Props = {}, Events = {}, Slots = {}>(
95
- render: {props: Props, events: Events, slots: Slots }
96
- ): {props: Expand<Props>, events: Events & {[evt: string]: CustomEvent<any>;}, slots: Slots }
94
+ declare function __sveltets_2_with_any_event<Props = {}, Events = {}, Slots = {}, Exports = {}, Bindings = string>(
95
+ render: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }
96
+ ): {props: Props, events: Events & {[evt: string]: CustomEvent<any>;}, slots: Slots, exports?: Exports, bindings?: Bindings }
97
97
 
98
98
  declare function __sveltets_2_store_get<T = any>(store: SvelteStore<T>): T
99
99
  declare function __sveltets_2_store_get<Store extends SvelteStore<any> | undefined | null>(store: Store): Store extends SvelteStore<infer T> ? T : Store;
@@ -225,20 +225,13 @@ declare type ATypedSvelteComponent = {
225
225
  * ```
226
226
  */
227
227
  declare type ConstructorOfATypedSvelteComponent = new (args: {target: any, props?: any}) => ATypedSvelteComponent
228
- declare function __sveltets_2_ensureComponent<T extends ConstructorOfATypedSvelteComponent | null | undefined>(type: T): NonNullable<T>;
229
-
228
+ declare function __sveltets_2_ensureComponent<
229
+ // @ts-ignore svelte.Component doesn't exist in Svelte 4
230
+ T extends ConstructorOfATypedSvelteComponent | (0 extends (1 & import('svelte').Component) ? never : import('svelte').Component<any, any, any>) | null | undefined
231
+ // @ts-ignore svelte.Component doesn't exist in Svelte 4
232
+ >(type: T): NonNullable<T extends ConstructorOfATypedSvelteComponent ? T : 0 extends (1 & import('svelte').Component) ? T : T extends import('svelte').Component<infer Props> ? typeof import('svelte').SvelteComponent<Props, Props['$$events'], Props['$$slots']> : T>;
230
233
  declare function __sveltets_2_ensureArray<T extends ArrayLike<unknown> | Iterable<unknown>>(array: T): T extends ArrayLike<infer U> ? U[] : T extends Iterable<infer U> ? Iterable<U> : any[];
231
234
 
232
- declare type __sveltets_2_Bindings<Props extends Record<string, any>, Bindings extends string> = {
233
- [K in keyof Props]: K extends Bindings ?
234
- // @ts-ignore not available in Svelte 4
235
- import('svelte').Bindable<Props[K]> :
236
- Props[K]
237
- };
238
- declare function __sveltets_2_binding<T>(prop: T):
239
- // @ts-ignore not available in Svelte 4
240
- import('svelte').Binding<T>;
241
-
242
235
  type __sveltets_2_PropsWithChildren<Props, Slots> = Props &
243
236
  (Slots extends { default: any }
244
237
  // This is unfortunate because it means "accepts no props" turns into "accepts any prop"
@@ -248,4 +241,20 @@ type __sveltets_2_PropsWithChildren<Props, Slots> = Props &
248
241
  ? any
249
242
  : { children?: any }
250
243
  : {});
251
- declare function __sveltets_2_runes_constructor<Props extends {}, Events extends {}, Slots extends {}>(render: {props: Props, events: Events, slots: Slots }): import("svelte").ComponentConstructorOptions<__sveltets_2_PropsWithChildren<Props, Slots>>;
244
+ declare function __sveltets_2_runes_constructor<Props extends {}>(render: {props: Props }): import("svelte").ComponentConstructorOptions<Props>;
245
+
246
+ declare function __sveltets_$$bindings<Bindings extends string[]>(...bindings: Bindings): Bindings[number];
247
+
248
+ interface __sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
249
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & { $$bindings?: Bindings } & Exports;
250
+ (internal: unknown, props: Props extends Record<string, never> ? {$$events?: Events, $$slots?: Slots} : Props & {$$events?: Events, $$slots?: Slots}): Exports;
251
+ z_$$bindings?: Bindings;
252
+ }
253
+
254
+ declare function __sveltets_2_isomorphic_component<
255
+ Props extends Record<string, any>, Events extends Record<string, any>, Slots extends Record<string, any>, Exports extends Record<string, any>, Bindings extends string
256
+ >(klass: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }): __sveltets_2_IsomorphicComponent<Props, Events, Slots, Exports, Bindings>;
257
+
258
+ declare function __sveltets_2_isomorphic_component_slots<
259
+ Props extends Record<string, any>, Events extends Record<string, any>, Slots extends Record<string, any>, Exports extends Record<string, any>, Bindings extends string
260
+ >(klass: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }): __sveltets_2_IsomorphicComponent<__sveltets_2_PropsWithChildren<Props, Slots>, Events, Slots, Exports, Bindings>;