Skip to content
Closed
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
4 changes: 2 additions & 2 deletions packages/create-svelte/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export async function create(cwd, options) {

/**
* @param {string} template
* @param {boolean} typescript
* @param {false | "checkjs" | "typescript"} types
* @param {string} name
* @param {string} cwd
*/
Expand All @@ -40,7 +40,7 @@ function write_template_files(template, types, name, cwd) {
}

/**
build*
*
* @param {string} cwd
* @param {import('./types/internal').Options} options
* @param {string} name
Expand Down
32 changes: 15 additions & 17 deletions packages/create-svelte/scripts/build-templates.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,7 @@ import prettier from 'prettier';
import { transform } from 'sucrase';
import glob from 'tiny-glob/sync.js';
import { mkdirp, rimraf } from '../utils.js';

/** @param {string} typescript */
function convert_typescript(typescript) {
const transformed = transform(typescript, {
transforms: ['typescript']
});

return prettier.format(transformed.code, {
parser: 'babel',
useTabs: true,
singleQuote: true,
trailingComma: 'none',
printWidth: 100
});
}
import { transpile, extract_types } from '../transformers.js';

/** @param {Set<string>} shared */
async function generate_templates(shared) {
Expand Down Expand Up @@ -88,7 +74,7 @@ async function generate_templates(shared) {
} else if (file.name.endsWith('.ts')) {
js.push({
name: file.name.replace(/\.ts$/, '.js'),
contents: convert_typescript(file.contents)
contents: transpile(file.contents)
});
} else if (file.name.endsWith('.svelte')) {
// we jump through some hoops, rather than just using svelte.preprocess,
Expand Down Expand Up @@ -143,6 +129,18 @@ async function generate_templates(shared) {
}
}

JSON.parse(fs.readFileSync(meta_file, 'utf-8')).generateDeclarationsFor?.forEach(
(/** @type string */ name) => {
if (!name.endsWith('.ts')) throw new Error(`${name} is not a .ts file`);

const filepath = path.join(cwd, name);
js.push({
name: path.normalize(name.replace(/.ts$/, '.d.ts')),
contents: extract_types(filepath)
});
}
);

fs.copyFileSync(meta_file, `${dir}/meta.json`);
fs.writeFileSync(`${dir}/files.ts.json`, JSON.stringify(ts, null, '\t'));
fs.writeFileSync(`${dir}/files.js.json`, JSON.stringify(js, null, '\t'));
Expand Down Expand Up @@ -190,7 +188,7 @@ async function generate_shared() {
name: js_name,
include: [...include],
exclude: [...exclude, 'typescript'],
contents: convert_typescript(contents)
contents: transpile(contents)
});

include.push('typescript');
Expand Down
3 changes: 2 additions & 1 deletion packages/create-svelte/templates/default/.meta.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"description": "SvelteKit demo app"
"description": "SvelteKit demo app",
"generateDeclarationsFor": ["src/lib/form.ts"]
}
47 changes: 47 additions & 0 deletions packages/create-svelte/transformers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { transform } from 'sucrase';
import ts from 'typescript';
import prettier from 'prettier';

/**
* Transpile a TypeScript source string to JavaScript.
* @param {string} typescript
*/
export function transpile(typescript) {
const transformed = transform(typescript, { transforms: ['typescript'] });

return prettier.format(transformed.code, {
parser: 'babel',
useTabs: true,
singleQuote: true,
trailingComma: 'none',
printWidth: 100
});
}

/**
* Extract type declarations from a TypeScript file.
* @param {string} filepath the path to the file to extract types from
* @returns {string}
*/
export function extract_types(filepath) {
// Create a Program with an in-memory emit
const host = ts.createCompilerHost({
declaration: true,
emitDeclarationOnly: true
});
let declaration;
host.writeFile = (_, contents) => (declaration = contents);

// Prepare and emit the d.ts files
const program = ts.createProgram(
[filepath],
{
declaration: true,
emitDeclarationOnly: true
},
host
);
program.emit();

return declaration;
}