Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/svelte2tsx/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export const internalHelpers: {
fileName: string,
options: InternalHelpers.KitFilesSettings
) => boolean;
isKitRouteFile: (fileName: string, basename: string) =>boolean,
isKitRouteFile: (basename: string) => boolean,
isClientHooksFile: (
fileName: string,
basename: string,
Expand Down
11 changes: 5 additions & 6 deletions packages/svelte2tsx/src/helpers/sveltekit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const kitPageFiles = new Set(['+page', '+layout', '+page.server', '+layout.serve
export function isKitFile(fileName: string, options: KitFilesSettings): boolean {
const basename = path.basename(fileName);
return (
isKitRouteFile(fileName, basename) ||
isKitRouteFile(basename) ||
isServerHooksFile(fileName, basename, options.serverHooksPath) ||
isClientHooksFile(fileName, basename, options.clientHooksPath) ||
isParamsFile(fileName, basename, options.paramsPath)
Expand All @@ -36,12 +36,12 @@ export function isKitFile(fileName: string, options: KitFilesSettings): boolean
/**
* Determines whether or not a given file is a SvelteKit-specific route file
*/
export function isKitRouteFile(fileName: string, basename: string): boolean {
export function isKitRouteFile(basename: string): boolean {
if (basename.includes('@')) {
// +page@foo -> +page
basename = basename.split('@')[0];
} else {
basename = basename.slice(0, -path.extname(fileName).length);
basename = basename.slice(0, -path.extname(basename).length);
}

return kitPageFiles.has(basename);
Expand Down Expand Up @@ -97,7 +97,7 @@ export function upsertKitFile(
): { text: string; addedCode: AddedCode[] } {
let basename = path.basename(fileName);
const result =
upserKitRouteFile(ts, fileName, basename, getSource, surround) ??
upserKitRouteFile(ts, basename, getSource, surround) ??
upserKitServerHooksFile(
ts,
fileName,
Expand Down Expand Up @@ -141,12 +141,11 @@ export function upsertKitFile(

function upserKitRouteFile(
ts: _ts,
fileName: string,
basename: string,
getSource: () => ts.SourceFile | undefined,
surround: (text: string) => string
) {
if (!isKitRouteFile(fileName, basename)) return;
if (!isKitRouteFile(basename)) return;

const source = getSource();
if (!source) return;
Expand Down
9 changes: 8 additions & 1 deletion packages/svelte2tsx/src/helpers/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,18 @@ export function findExports(ts: _ts, source: ts.SourceFile, isTsFile: boolean) {
(ts.isSatisfiesExpression(declaration.initializer) &&
ts.isParenthesizedExpression(declaration.initializer.expression) &&
(ts.isFunctionExpression(declaration.initializer.expression.expression) ||
ts.isArrowFunction(declaration.initializer.expression.expression))))
ts.isArrowFunction(declaration.initializer.expression.expression))) ||
(ts.isParenthesizedExpression(declaration.initializer) &&
(ts.isFunctionExpression(declaration.initializer.expression) ||
ts.isArrowFunction(declaration.initializer.expression))))
) {
const node = ts.isSatisfiesExpression(declaration.initializer)
? ((declaration.initializer.expression as ts.ParenthesizedExpression)
.expression as ts.FunctionExpression | ts.ArrowFunction)
: ts.isParenthesizedExpression(declaration.initializer)
? (declaration.initializer.expression as
| ts.FunctionExpression
| ts.ArrowFunction)
: declaration.initializer;
exports.set(declaration.name.getText(), {
type: 'function',
Expand Down
42 changes: 33 additions & 9 deletions packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import MagicString from 'magic-string';
import ts from 'typescript';
import { internalHelpers } from '../../helpers';
import { surroundWithIgnoreComments } from '../../utils/ignore';
import { preprendStr, overwriteStr } from '../../utils/magic-string';
import { findExportKeyword, getLastLeadingDoc, isInterfaceOrTypeDeclaration } from '../utils/tsAst';
Expand All @@ -18,8 +19,6 @@ interface ExportedName {
doc?: string;
}

const kitPageFiles = new Set(['+page.svelte', '+layout.svelte']);

export class ExportedNames {
/**
* Uses the $$Props type
Expand Down Expand Up @@ -52,6 +51,17 @@ export class ExportedNames {
node.declarationList.forEachChild((n) => {
if (ts.isVariableDeclaration(n) && ts.isIdentifier(n.name)) {
this.addGetter(n.name);

const type = n.type || ts.getJSDocType(n);
const isKitExport =
internalHelpers.isKitRouteFile(this.basename) &&
n.name.getText() === 'snapshot';
// TS types are not allowed in JS files, but TS will still pick it up and the ignore comment will filter out the error
const kitType = isKitExport && !type ? `: import('./$types').Snapshot` : '';
const nameEnd = n.name.end + this.astOffset;
if (kitType) {
preprendStr(this.str, nameEnd, surroundWithIgnoreComments(kitType));
}
}
});
}
Expand Down Expand Up @@ -117,7 +127,7 @@ export class ExportedNames {
const type = tsType || jsDocType;
const name = identifier.getText();
const isKitExport =
kitPageFiles.has(this.basename) &&
internalHelpers.isKitRouteFile(this.basename) &&
(name === 'data' || name === 'form' || name === 'snapshot');
// TS types are not allowed in JS files, but TS will still pick it up and the ignore comment will filter out the error
const kitType =
Expand All @@ -132,6 +142,7 @@ export class ExportedNames {
: 'Snapshot'
}`
: '';
const nameEnd = identifier.end + this.astOffset;
const end = declaration.end + this.astOffset;

if (
Expand All @@ -150,13 +161,26 @@ export class ExportedNames {
) {
const name = identifier.getText();

preprendStr(
this.str,
end,
surroundWithIgnoreComments(`${kitType};${name} = __sveltets_2_any(${name});`)
);
if (nameEnd === end) {
preprendStr(
this.str,
end,
surroundWithIgnoreComments(
`${kitType};${name} = __sveltets_2_any(${name});`
)
);
} else {
if (kitType) {
preprendStr(this.str, nameEnd, surroundWithIgnoreComments(kitType));
}
preprendStr(
this.str,
end,
surroundWithIgnoreComments(`;${name} = __sveltets_2_any(${name});`)
);
}
} else if (kitType) {
preprendStr(this.str, end, surroundWithIgnoreComments(`${kitType}`));
preprendStr(this.str, nameEnd, surroundWithIgnoreComments(kitType));
}
};

Expand Down
16 changes: 16 additions & 0 deletions packages/svelte2tsx/test/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,20 @@ describe('Internal Helpers - upsertKitFile', () => {
`export async function GET(e: import('./$types').RequestEvent) : Response | Promise<Response> {}`
);
});

it('upserts load const with paranthesis', () => {
upsert(
'+page.ts',
`export const load = (async (e) => {});`,
`export const load = (async (e: import('./$types').PageLoadEvent) => {});`
);
});

it('recognizes page@', () => {
upsert('+page@.ts', `export const ssr = true;`, `export const ssr : boolean = true;`);
});

it('recognizes layout@foo', () => {
upsert('+layout@foo.ts', `export const ssr = true;`, `export const ssr : boolean = true;`);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
export const snapshot = {};

export let nope;
export let form = {}
export let data: number;
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@

let data/*Ωignore_startΩ*/: import('./$types').PageData;data = __sveltets_2_any(data);/*Ωignore_endΩ*/;
let form/*Ωignore_startΩ*/: import('./$types').ActionData;form = __sveltets_2_any(form);/*Ωignore_endΩ*/;
const snapshot = {};
const snapshot/*Ωignore_startΩ*/: import('./$types').Snapshot/*Ωignore_endΩ*/ = {};

let nope/*Ωignore_startΩ*/;nope = __sveltets_2_any(nope);/*Ωignore_endΩ*/;
let form/*Ωignore_startΩ*/: import('./$types').ActionData/*Ωignore_endΩ*/ = {}
let data: number/*Ωignore_startΩ*/;data = __sveltets_2_any(data);/*Ωignore_endΩ*/;
;
async () => {};
return { props: {data: data , form: form , snapshot: snapshot , nope: nope}, slots: {}, events: {} }}

export default class Page__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(['snapshot'], __sveltets_2_with_any_event(render()))) {
export default class Page__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(['form','snapshot'], __sveltets_2_with_any_event(render()))) {
get snapshot() { return __sveltets_2_nonNullable(this.$$prop_def.snapshot) }
}