svelte2tsx 0.7.36 → 0.7.37

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.
Files changed (3) hide show
  1. package/index.js +78 -21
  2. package/index.mjs +78 -21
  3. package/package.json +1 -1
package/index.js CHANGED
@@ -2037,7 +2037,7 @@ class Element {
2037
2037
  this.isSelfclosing = this.computeIsSelfclosing();
2038
2038
  this.startTagStart = this.node.start;
2039
2039
  this.startTagEnd = this.computeStartTagEnd();
2040
- const tagEnd = this.startTagStart + this.node.name.length + 1;
2040
+ const tagEnd = (this.tagNameEnd = this.startTagStart + this.node.name.length + 1);
2041
2041
  // Ensure deleted characters are mapped to the attributes object so we
2042
2042
  // get autocompletion when triggering it on a whitespace.
2043
2043
  if (/\s/.test(str.original.charAt(tagEnd))) {
@@ -2143,7 +2143,16 @@ class Element {
2143
2143
  this.endTransformation.push('}');
2144
2144
  }
2145
2145
  if (this.isSelfclosing) {
2146
- transform(this.str, this.startTagStart, this.startTagEnd, [
2146
+ // The transformation is the whole start tag + <, ex: <span
2147
+ // To avoid the end tag transform being moved to before the tag name,
2148
+ // manually remove the first character and let the `transform` function skip removing unused
2149
+ let transformEnd = this.startTagEnd;
2150
+ if (this.str.original[transformEnd - 1] !== '>' &&
2151
+ (transformEnd === this.tagNameEnd || transformEnd === this.tagNameEnd + 1)) {
2152
+ transformEnd = this.startTagStart;
2153
+ this.str.remove(this.startTagStart, this.startTagStart + 1);
2154
+ }
2155
+ transform(this.str, this.startTagStart, transformEnd, [
2147
2156
  // Named slot transformations go first inside a outer block scope because
2148
2157
  // <div let:xx {x} /> means "use the x of let:x", and without a separate
2149
2158
  // block scope this would give a "used before defined" error
@@ -2227,7 +2236,7 @@ class Element {
2227
2236
  default: {
2228
2237
  createElementStatement = [
2229
2238
  `${createElement}("`,
2230
- [this.node.start + 1, this.node.start + 1 + this.node.name.length],
2239
+ [this.node.start + 1, this.tagNameEnd],
2231
2240
  `"${addActions()}, {`
2232
2241
  ];
2233
2242
  break;
@@ -2314,7 +2323,7 @@ class InlineComponent {
2314
2323
  this.isSelfclosing = this.computeIsSelfclosing();
2315
2324
  this.startTagStart = this.node.start;
2316
2325
  this.startTagEnd = this.computeStartTagEnd();
2317
- const tagEnd = this.startTagStart + this.node.name.length + 1;
2326
+ const tagEnd = (this.tagNameEnd = this.startTagStart + this.node.name.length + 1);
2318
2327
  // Ensure deleted characters are mapped to the attributes object so we
2319
2328
  // get autocompletion when triggering it on a whitespace.
2320
2329
  if (/\s/.test(str.original.charAt(tagEnd))) {
@@ -2449,7 +2458,7 @@ class InlineComponent {
2449
2458
  if (endStart === -1) {
2450
2459
  // Can happen in loose parsing mode when there's no closing tag
2451
2460
  endStart = this.node.end;
2452
- this.startTagEnd = this.node.end - 1;
2461
+ this.startTagEnd = Math.max(this.node.end - 1, this.tagNameEnd);
2453
2462
  }
2454
2463
  else {
2455
2464
  endStart += this.node.start;
@@ -2459,7 +2468,15 @@ class InlineComponent {
2459
2468
  this.endTransformation.push([endStart + 2, endStart + this.node.name.length + 2]);
2460
2469
  }
2461
2470
  this.endTransformation.push('}');
2462
- transform(this.str, this.startTagStart, this.startTagEnd, [
2471
+ let transformationEnd = this.startTagEnd;
2472
+ // The transformation is the whole start tag + <, ex: <Comp
2473
+ // To avoid the "cannot move inside itself" error,
2474
+ // manually remove the first character and let the transform function skip removing unused
2475
+ if (transformationEnd === this.tagNameEnd) {
2476
+ transformationEnd = this.startTagStart;
2477
+ this.str.remove(this.startTagStart, this.startTagStart + 1);
2478
+ }
2479
+ transform(this.str, this.startTagStart, transformationEnd, [
2463
2480
  // See comment above why this goes first
2464
2481
  ...namedSlotLetTransformation,
2465
2482
  ...this.startTransformation,
@@ -3828,6 +3845,9 @@ function isNewGroup(sourceFile, topLevelImportDecl, scanner) {
3828
3845
  }
3829
3846
  return false;
3830
3847
  }
3848
+ function getTopLevelImports(sourceFile) {
3849
+ return sourceFile.statements.filter(ts.isImportDeclaration).sort((a, b) => a.end - b.end);
3850
+ }
3831
3851
 
3832
3852
  /**
3833
3853
  * Get the constructor type of a component node
@@ -6082,9 +6102,15 @@ class HoistableInterfaces {
6082
6102
  if (ts.isInterfaceDeclaration(node)) {
6083
6103
  this.module_types.add(node.name.text);
6084
6104
  }
6105
+ if (ts.isEnumDeclaration(node)) {
6106
+ this.module_types.add(node.name.text);
6107
+ }
6108
+ if (ts.isModuleDeclaration(node) && ts.isIdentifier(node.name)) {
6109
+ this.module_types.add(node.name.text);
6110
+ }
6085
6111
  }
6086
6112
  analyzeInstanceScriptNode(node) {
6087
- var _a, _b, _c, _d;
6113
+ var _a, _b, _c, _d, _e;
6088
6114
  // Handle Import Declarations
6089
6115
  if (ts.isImportDeclaration(node) && node.importClause) {
6090
6116
  const is_type_only = node.importClause.isTypeOnly;
@@ -6130,6 +6156,17 @@ class HoistableInterfaces {
6130
6156
  });
6131
6157
  }
6132
6158
  });
6159
+ (_c = node.heritageClauses) === null || _c === void 0 ? void 0 : _c.forEach((clause) => {
6160
+ clause.types.forEach((type) => {
6161
+ if (ts.isIdentifier(type.expression)) {
6162
+ const type_name = type.expression.text;
6163
+ if (!generics.includes(type_name)) {
6164
+ type_dependencies.add(type_name);
6165
+ }
6166
+ }
6167
+ this.collectTypeDependencies(type, type_dependencies, value_dependencies, generics);
6168
+ });
6169
+ });
6133
6170
  if (this.module_types.has(interface_name)) {
6134
6171
  // shadowed; we can't hoist
6135
6172
  this.disallowed_types.add(interface_name);
@@ -6147,7 +6184,7 @@ class HoistableInterfaces {
6147
6184
  const alias_name = node.name.text;
6148
6185
  const type_dependencies = new Set();
6149
6186
  const value_dependencies = new Set();
6150
- const generics = (_d = (_c = node.typeParameters) === null || _c === void 0 ? void 0 : _c.map((param) => param.name.text)) !== null && _d !== void 0 ? _d : [];
6187
+ const generics = (_e = (_d = node.typeParameters) === null || _d === void 0 ? void 0 : _d.map((param) => param.name.text)) !== null && _e !== void 0 ? _e : [];
6151
6188
  this.collectTypeDependencies(node.type, type_dependencies, value_dependencies, generics);
6152
6189
  if (this.module_types.has(alias_name)) {
6153
6190
  // shadowed; we can't hoist
@@ -6189,13 +6226,20 @@ class HoistableInterfaces {
6189
6226
  if (ts.isEnumDeclaration(node)) {
6190
6227
  this.disallowed_values.add(node.name.text);
6191
6228
  }
6229
+ // namespace declaration should not be in the instance script.
6230
+ // Only adding the top-level name to the disallowed list,
6231
+ // so that at least there won't a confusing error message of "can't find namespace Foo"
6232
+ if (ts.isModuleDeclaration(node) && ts.isIdentifier(node.name)) {
6233
+ this.disallowed_types.add(node.name.text);
6234
+ this.disallowed_values.add(node.name.text);
6235
+ }
6192
6236
  }
6193
6237
  analyze$propsRune(node) {
6194
6238
  var _a, _b;
6195
6239
  if (((_a = node.initializer.typeArguments) === null || _a === void 0 ? void 0 : _a.length) > 0 || node.type) {
6196
6240
  const generic_arg = ((_b = node.initializer.typeArguments) === null || _b === void 0 ? void 0 : _b[0]) || node.type;
6197
6241
  if (ts.isTypeReferenceNode(generic_arg)) {
6198
- const name = this.getEntityNameText(generic_arg.typeName);
6242
+ const name = this.getEntityNameRoot(generic_arg.typeName);
6199
6243
  const interface_node = this.interface_map.get(name);
6200
6244
  if (interface_node) {
6201
6245
  this.props_interface.name = name;
@@ -6316,30 +6360,31 @@ class HoistableInterfaces {
6316
6360
  collectTypeDependencies(type_node, type_dependencies, value_dependencies, generics) {
6317
6361
  const walk = (node) => {
6318
6362
  if (ts.isTypeReferenceNode(node)) {
6319
- const type_name = this.getEntityNameText(node.typeName);
6363
+ const type_name = this.getEntityNameRoot(node.typeName);
6320
6364
  if (!generics.includes(type_name)) {
6321
6365
  type_dependencies.add(type_name);
6322
6366
  }
6323
6367
  }
6324
6368
  else if (ts.isTypeQueryNode(node)) {
6325
6369
  // Handle 'typeof' expressions: e.g., foo: typeof bar
6326
- value_dependencies.add(this.getEntityNameText(node.exprName));
6370
+ value_dependencies.add(this.getEntityNameRoot(node.exprName));
6327
6371
  }
6328
6372
  ts.forEachChild(node, walk);
6329
6373
  };
6330
6374
  walk(type_node);
6331
6375
  }
6332
6376
  /**
6333
- * Retrieves the full text of an EntityName (handles nested names).
6377
+ * Retrieves the top-level variable/namespace of an EntityName (handles nested names).
6378
+ * ex: `foo.bar.baz` -> `foo`
6334
6379
  * @param entity_name The EntityName to extract text from.
6335
- * @returns The full name as a string.
6380
+ * @returns The top-level name as a string.
6336
6381
  */
6337
- getEntityNameText(entity_name) {
6382
+ getEntityNameRoot(entity_name) {
6338
6383
  if (ts.isIdentifier(entity_name)) {
6339
6384
  return entity_name.text;
6340
6385
  }
6341
6386
  else {
6342
- return this.getEntityNameText(entity_name.left) + '.' + entity_name.right.text;
6387
+ return this.getEntityNameRoot(entity_name.left);
6343
6388
  }
6344
6389
  }
6345
6390
  }
@@ -6960,10 +7005,10 @@ class ExportedNames {
6960
7005
  }
6961
7006
  return '';
6962
7007
  }
6963
- createReturnElements(names, dontAddTypeDef, omitTyped = false) {
7008
+ createReturnElements(names, dontAddTypeDef, onlyTyped = false) {
6964
7009
  return names
6965
7010
  .map(([key, value]) => {
6966
- if (omitTyped && value.type)
7011
+ if (onlyTyped && !value.type)
6967
7012
  return;
6968
7013
  // Important to not use shorthand props for rename functionality
6969
7014
  return `${dontAddTypeDef && value.doc ? `\n${value.doc}` : ''}${value.identifierText || key}: ${key}`;
@@ -7383,7 +7428,7 @@ function handleImportDeclaration(node, str, astOffset, scriptStart, sourceFile)
7383
7428
  */
7384
7429
  function handleFirstInstanceImport(tsAst, astOffset, hasModuleScript, str) {
7385
7430
  var _a;
7386
- const imports = tsAst.statements.filter(ts.isImportDeclaration).sort((a, b) => a.end - b.end);
7431
+ const imports = getTopLevelImports(tsAst);
7387
7432
  const firstImport = imports[0];
7388
7433
  if (!firstImport) {
7389
7434
  return;
@@ -7887,14 +7932,26 @@ function svelte2tsx(svelte, options = { parse: compiler.parse }) {
7887
7932
  exportedNames.hoistableInterfaces.analyzeSnippets(rootSnippets);
7888
7933
  }
7889
7934
  if (moduleScriptTag || scriptTag) {
7935
+ let snippetHoistTargetForModule = 0;
7936
+ if (rootSnippets.length) {
7937
+ if (scriptTag) {
7938
+ snippetHoistTargetForModule = scriptTag.start + 1; // +1 because imports are also moved at that position, and we want to move interfaces after imports
7939
+ }
7940
+ else {
7941
+ const imports = getTopLevelImports(moduleAst.tsAst);
7942
+ const lastImport = imports[imports.length - 1];
7943
+ snippetHoistTargetForModule = lastImport
7944
+ ? lastImport.end + moduleAst.astOffset
7945
+ : moduleAst.astOffset;
7946
+ str.appendLeft(snippetHoistTargetForModule, '\n');
7947
+ }
7948
+ }
7890
7949
  for (const [start, end, globals] of rootSnippets) {
7891
7950
  const hoist_to_module = moduleScriptTag &&
7892
7951
  (globals.size === 0 ||
7893
7952
  [...globals.keys()].every((id) => exportedNames.hoistableInterfaces.isAllowedReference(id)));
7894
7953
  if (hoist_to_module) {
7895
- str.move(start, end, scriptTag
7896
- ? scriptTag.start + 1 // +1 because imports are also moved at that position, and we want to move interfaces after imports
7897
- : instanceScriptTarget);
7954
+ str.move(start, end, snippetHoistTargetForModule);
7898
7955
  }
7899
7956
  else if (scriptTag) {
7900
7957
  str.move(start, end, renderFunctionStart);
package/index.mjs CHANGED
@@ -2017,7 +2017,7 @@ class Element {
2017
2017
  this.isSelfclosing = this.computeIsSelfclosing();
2018
2018
  this.startTagStart = this.node.start;
2019
2019
  this.startTagEnd = this.computeStartTagEnd();
2020
- const tagEnd = this.startTagStart + this.node.name.length + 1;
2020
+ const tagEnd = (this.tagNameEnd = this.startTagStart + this.node.name.length + 1);
2021
2021
  // Ensure deleted characters are mapped to the attributes object so we
2022
2022
  // get autocompletion when triggering it on a whitespace.
2023
2023
  if (/\s/.test(str.original.charAt(tagEnd))) {
@@ -2123,7 +2123,16 @@ class Element {
2123
2123
  this.endTransformation.push('}');
2124
2124
  }
2125
2125
  if (this.isSelfclosing) {
2126
- transform(this.str, this.startTagStart, this.startTagEnd, [
2126
+ // The transformation is the whole start tag + <, ex: <span
2127
+ // To avoid the end tag transform being moved to before the tag name,
2128
+ // manually remove the first character and let the `transform` function skip removing unused
2129
+ let transformEnd = this.startTagEnd;
2130
+ if (this.str.original[transformEnd - 1] !== '>' &&
2131
+ (transformEnd === this.tagNameEnd || transformEnd === this.tagNameEnd + 1)) {
2132
+ transformEnd = this.startTagStart;
2133
+ this.str.remove(this.startTagStart, this.startTagStart + 1);
2134
+ }
2135
+ transform(this.str, this.startTagStart, transformEnd, [
2127
2136
  // Named slot transformations go first inside a outer block scope because
2128
2137
  // <div let:xx {x} /> means "use the x of let:x", and without a separate
2129
2138
  // block scope this would give a "used before defined" error
@@ -2207,7 +2216,7 @@ class Element {
2207
2216
  default: {
2208
2217
  createElementStatement = [
2209
2218
  `${createElement}("`,
2210
- [this.node.start + 1, this.node.start + 1 + this.node.name.length],
2219
+ [this.node.start + 1, this.tagNameEnd],
2211
2220
  `"${addActions()}, {`
2212
2221
  ];
2213
2222
  break;
@@ -2294,7 +2303,7 @@ class InlineComponent {
2294
2303
  this.isSelfclosing = this.computeIsSelfclosing();
2295
2304
  this.startTagStart = this.node.start;
2296
2305
  this.startTagEnd = this.computeStartTagEnd();
2297
- const tagEnd = this.startTagStart + this.node.name.length + 1;
2306
+ const tagEnd = (this.tagNameEnd = this.startTagStart + this.node.name.length + 1);
2298
2307
  // Ensure deleted characters are mapped to the attributes object so we
2299
2308
  // get autocompletion when triggering it on a whitespace.
2300
2309
  if (/\s/.test(str.original.charAt(tagEnd))) {
@@ -2429,7 +2438,7 @@ class InlineComponent {
2429
2438
  if (endStart === -1) {
2430
2439
  // Can happen in loose parsing mode when there's no closing tag
2431
2440
  endStart = this.node.end;
2432
- this.startTagEnd = this.node.end - 1;
2441
+ this.startTagEnd = Math.max(this.node.end - 1, this.tagNameEnd);
2433
2442
  }
2434
2443
  else {
2435
2444
  endStart += this.node.start;
@@ -2439,7 +2448,15 @@ class InlineComponent {
2439
2448
  this.endTransformation.push([endStart + 2, endStart + this.node.name.length + 2]);
2440
2449
  }
2441
2450
  this.endTransformation.push('}');
2442
- transform(this.str, this.startTagStart, this.startTagEnd, [
2451
+ let transformationEnd = this.startTagEnd;
2452
+ // The transformation is the whole start tag + <, ex: <Comp
2453
+ // To avoid the "cannot move inside itself" error,
2454
+ // manually remove the first character and let the transform function skip removing unused
2455
+ if (transformationEnd === this.tagNameEnd) {
2456
+ transformationEnd = this.startTagStart;
2457
+ this.str.remove(this.startTagStart, this.startTagStart + 1);
2458
+ }
2459
+ transform(this.str, this.startTagStart, transformationEnd, [
2443
2460
  // See comment above why this goes first
2444
2461
  ...namedSlotLetTransformation,
2445
2462
  ...this.startTransformation,
@@ -3808,6 +3825,9 @@ function isNewGroup(sourceFile, topLevelImportDecl, scanner) {
3808
3825
  }
3809
3826
  return false;
3810
3827
  }
3828
+ function getTopLevelImports(sourceFile) {
3829
+ return sourceFile.statements.filter(ts.isImportDeclaration).sort((a, b) => a.end - b.end);
3830
+ }
3811
3831
 
3812
3832
  /**
3813
3833
  * Get the constructor type of a component node
@@ -6062,9 +6082,15 @@ class HoistableInterfaces {
6062
6082
  if (ts.isInterfaceDeclaration(node)) {
6063
6083
  this.module_types.add(node.name.text);
6064
6084
  }
6085
+ if (ts.isEnumDeclaration(node)) {
6086
+ this.module_types.add(node.name.text);
6087
+ }
6088
+ if (ts.isModuleDeclaration(node) && ts.isIdentifier(node.name)) {
6089
+ this.module_types.add(node.name.text);
6090
+ }
6065
6091
  }
6066
6092
  analyzeInstanceScriptNode(node) {
6067
- var _a, _b, _c, _d;
6093
+ var _a, _b, _c, _d, _e;
6068
6094
  // Handle Import Declarations
6069
6095
  if (ts.isImportDeclaration(node) && node.importClause) {
6070
6096
  const is_type_only = node.importClause.isTypeOnly;
@@ -6110,6 +6136,17 @@ class HoistableInterfaces {
6110
6136
  });
6111
6137
  }
6112
6138
  });
6139
+ (_c = node.heritageClauses) === null || _c === void 0 ? void 0 : _c.forEach((clause) => {
6140
+ clause.types.forEach((type) => {
6141
+ if (ts.isIdentifier(type.expression)) {
6142
+ const type_name = type.expression.text;
6143
+ if (!generics.includes(type_name)) {
6144
+ type_dependencies.add(type_name);
6145
+ }
6146
+ }
6147
+ this.collectTypeDependencies(type, type_dependencies, value_dependencies, generics);
6148
+ });
6149
+ });
6113
6150
  if (this.module_types.has(interface_name)) {
6114
6151
  // shadowed; we can't hoist
6115
6152
  this.disallowed_types.add(interface_name);
@@ -6127,7 +6164,7 @@ class HoistableInterfaces {
6127
6164
  const alias_name = node.name.text;
6128
6165
  const type_dependencies = new Set();
6129
6166
  const value_dependencies = new Set();
6130
- const generics = (_d = (_c = node.typeParameters) === null || _c === void 0 ? void 0 : _c.map((param) => param.name.text)) !== null && _d !== void 0 ? _d : [];
6167
+ const generics = (_e = (_d = node.typeParameters) === null || _d === void 0 ? void 0 : _d.map((param) => param.name.text)) !== null && _e !== void 0 ? _e : [];
6131
6168
  this.collectTypeDependencies(node.type, type_dependencies, value_dependencies, generics);
6132
6169
  if (this.module_types.has(alias_name)) {
6133
6170
  // shadowed; we can't hoist
@@ -6169,13 +6206,20 @@ class HoistableInterfaces {
6169
6206
  if (ts.isEnumDeclaration(node)) {
6170
6207
  this.disallowed_values.add(node.name.text);
6171
6208
  }
6209
+ // namespace declaration should not be in the instance script.
6210
+ // Only adding the top-level name to the disallowed list,
6211
+ // so that at least there won't a confusing error message of "can't find namespace Foo"
6212
+ if (ts.isModuleDeclaration(node) && ts.isIdentifier(node.name)) {
6213
+ this.disallowed_types.add(node.name.text);
6214
+ this.disallowed_values.add(node.name.text);
6215
+ }
6172
6216
  }
6173
6217
  analyze$propsRune(node) {
6174
6218
  var _a, _b;
6175
6219
  if (((_a = node.initializer.typeArguments) === null || _a === void 0 ? void 0 : _a.length) > 0 || node.type) {
6176
6220
  const generic_arg = ((_b = node.initializer.typeArguments) === null || _b === void 0 ? void 0 : _b[0]) || node.type;
6177
6221
  if (ts.isTypeReferenceNode(generic_arg)) {
6178
- const name = this.getEntityNameText(generic_arg.typeName);
6222
+ const name = this.getEntityNameRoot(generic_arg.typeName);
6179
6223
  const interface_node = this.interface_map.get(name);
6180
6224
  if (interface_node) {
6181
6225
  this.props_interface.name = name;
@@ -6296,30 +6340,31 @@ class HoistableInterfaces {
6296
6340
  collectTypeDependencies(type_node, type_dependencies, value_dependencies, generics) {
6297
6341
  const walk = (node) => {
6298
6342
  if (ts.isTypeReferenceNode(node)) {
6299
- const type_name = this.getEntityNameText(node.typeName);
6343
+ const type_name = this.getEntityNameRoot(node.typeName);
6300
6344
  if (!generics.includes(type_name)) {
6301
6345
  type_dependencies.add(type_name);
6302
6346
  }
6303
6347
  }
6304
6348
  else if (ts.isTypeQueryNode(node)) {
6305
6349
  // Handle 'typeof' expressions: e.g., foo: typeof bar
6306
- value_dependencies.add(this.getEntityNameText(node.exprName));
6350
+ value_dependencies.add(this.getEntityNameRoot(node.exprName));
6307
6351
  }
6308
6352
  ts.forEachChild(node, walk);
6309
6353
  };
6310
6354
  walk(type_node);
6311
6355
  }
6312
6356
  /**
6313
- * Retrieves the full text of an EntityName (handles nested names).
6357
+ * Retrieves the top-level variable/namespace of an EntityName (handles nested names).
6358
+ * ex: `foo.bar.baz` -> `foo`
6314
6359
  * @param entity_name The EntityName to extract text from.
6315
- * @returns The full name as a string.
6360
+ * @returns The top-level name as a string.
6316
6361
  */
6317
- getEntityNameText(entity_name) {
6362
+ getEntityNameRoot(entity_name) {
6318
6363
  if (ts.isIdentifier(entity_name)) {
6319
6364
  return entity_name.text;
6320
6365
  }
6321
6366
  else {
6322
- return this.getEntityNameText(entity_name.left) + '.' + entity_name.right.text;
6367
+ return this.getEntityNameRoot(entity_name.left);
6323
6368
  }
6324
6369
  }
6325
6370
  }
@@ -6940,10 +6985,10 @@ class ExportedNames {
6940
6985
  }
6941
6986
  return '';
6942
6987
  }
6943
- createReturnElements(names, dontAddTypeDef, omitTyped = false) {
6988
+ createReturnElements(names, dontAddTypeDef, onlyTyped = false) {
6944
6989
  return names
6945
6990
  .map(([key, value]) => {
6946
- if (omitTyped && value.type)
6991
+ if (onlyTyped && !value.type)
6947
6992
  return;
6948
6993
  // Important to not use shorthand props for rename functionality
6949
6994
  return `${dontAddTypeDef && value.doc ? `\n${value.doc}` : ''}${value.identifierText || key}: ${key}`;
@@ -7363,7 +7408,7 @@ function handleImportDeclaration(node, str, astOffset, scriptStart, sourceFile)
7363
7408
  */
7364
7409
  function handleFirstInstanceImport(tsAst, astOffset, hasModuleScript, str) {
7365
7410
  var _a;
7366
- const imports = tsAst.statements.filter(ts.isImportDeclaration).sort((a, b) => a.end - b.end);
7411
+ const imports = getTopLevelImports(tsAst);
7367
7412
  const firstImport = imports[0];
7368
7413
  if (!firstImport) {
7369
7414
  return;
@@ -7867,14 +7912,26 @@ function svelte2tsx(svelte, options = { parse }) {
7867
7912
  exportedNames.hoistableInterfaces.analyzeSnippets(rootSnippets);
7868
7913
  }
7869
7914
  if (moduleScriptTag || scriptTag) {
7915
+ let snippetHoistTargetForModule = 0;
7916
+ if (rootSnippets.length) {
7917
+ if (scriptTag) {
7918
+ snippetHoistTargetForModule = scriptTag.start + 1; // +1 because imports are also moved at that position, and we want to move interfaces after imports
7919
+ }
7920
+ else {
7921
+ const imports = getTopLevelImports(moduleAst.tsAst);
7922
+ const lastImport = imports[imports.length - 1];
7923
+ snippetHoistTargetForModule = lastImport
7924
+ ? lastImport.end + moduleAst.astOffset
7925
+ : moduleAst.astOffset;
7926
+ str.appendLeft(snippetHoistTargetForModule, '\n');
7927
+ }
7928
+ }
7870
7929
  for (const [start, end, globals] of rootSnippets) {
7871
7930
  const hoist_to_module = moduleScriptTag &&
7872
7931
  (globals.size === 0 ||
7873
7932
  [...globals.keys()].every((id) => exportedNames.hoistableInterfaces.isAllowedReference(id)));
7874
7933
  if (hoist_to_module) {
7875
- str.move(start, end, scriptTag
7876
- ? scriptTag.start + 1 // +1 because imports are also moved at that position, and we want to move interfaces after imports
7877
- : instanceScriptTarget);
7934
+ str.move(start, end, snippetHoistTargetForModule);
7878
7935
  }
7879
7936
  else if (scriptTag) {
7880
7937
  str.move(start, end, renderFunctionStart);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte2tsx",
3
- "version": "0.7.36",
3
+ "version": "0.7.37",
4
4
  "description": "Convert Svelte components to TSX for type checking",
5
5
  "author": "The Svelte Community",
6
6
  "license": "MIT",