diff options
Diffstat (limited to 'cli')
36 files changed, 496 insertions, 145 deletions
diff --git a/cli/flags.rs b/cli/flags.rs index 4cacb01e4..eb98c6032 100644 --- a/cli/flags.rs +++ b/cli/flags.rs @@ -106,6 +106,7 @@ pub struct Flags { pub lock_write: bool, pub log_level: Option<Level>, pub net_allowlist: Vec<String>, + pub no_check: bool, pub no_prompts: bool, pub no_remote: bool, pub read_allowlist: Vec<PathBuf>, @@ -453,6 +454,7 @@ fn eval_parse(flags: &mut Flags, matches: &clap::ArgMatches) { fn info_parse(flags: &mut Flags, matches: &clap::ArgMatches) { ca_file_arg_parse(flags, matches); unstable_arg_parse(flags, matches); + no_check_arg_parse(flags, matches); flags.subcommand = DenoSubcommand::Info { file: matches.value_of("file").map(|f| f.to_string()), @@ -464,6 +466,7 @@ fn cache_parse(flags: &mut Flags, matches: &clap::ArgMatches) { lock_args_parse(flags, matches); importmap_arg_parse(flags, matches); config_arg_parse(flags, matches); + no_check_arg_parse(flags, matches); no_remote_arg_parse(flags, matches); ca_file_arg_parse(flags, matches); unstable_arg_parse(flags, matches); @@ -492,6 +495,7 @@ fn run_test_args_parse(flags: &mut Flags, matches: &clap::ArgMatches) { importmap_arg_parse(flags, matches); config_arg_parse(flags, matches); v8_flags_arg_parse(flags, matches); + no_check_arg_parse(flags, matches); no_remote_arg_parse(flags, matches); permission_args_parse(flags, matches); ca_file_arg_parse(flags, matches); @@ -818,6 +822,7 @@ TypeScript compiler cache: Subdirectory containing TS compiler output.", ) .arg(Arg::with_name("file").takes_value(true).required(false)) .arg(ca_file_arg()) + .arg(no_check_arg()) .arg(unstable_arg()) } @@ -829,6 +834,7 @@ fn cache_subcommand<'a, 'b>() -> App<'a, 'b> { .arg(importmap_arg()) .arg(unstable_arg()) .arg(config_arg()) + .arg(no_check_arg()) .arg(no_remote_arg()) .arg( Arg::with_name("file") @@ -1040,6 +1046,7 @@ fn run_test_args<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> { .arg(config_arg()) .arg(lock_arg()) .arg(lock_write_arg()) + .arg(no_check_arg()) .arg(no_remote_arg()) .arg(v8_flags_arg()) .arg(ca_file_arg()) @@ -1314,6 +1321,18 @@ fn v8_flags_arg_parse(flags: &mut Flags, matches: &ArgMatches) { } } +fn no_check_arg<'a, 'b>() -> Arg<'a, 'b> { + Arg::with_name("no-check") + .long("no-check") + .help("Skip type checking modules") +} + +fn no_check_arg_parse(flags: &mut Flags, matches: &clap::ArgMatches) { + if matches.is_present("no-check") { + flags.no_check = true; + } +} + fn no_remote_arg<'a, 'b>() -> Arg<'a, 'b> { Arg::with_name("no-remote") .long("no-remote") @@ -2442,6 +2461,22 @@ mod tests { */ #[test] + fn no_check() { + let r = + flags_from_vec_safe(svec!["deno", "run", "--no-check", "script.ts"]); + assert_eq!( + r.unwrap(), + Flags { + subcommand: DenoSubcommand::Run { + script: "script.ts".to_string(), + }, + no_check: true, + ..Flags::default() + } + ); + } + + #[test] fn no_remote() { let r = flags_from_vec_safe(svec!["deno", "run", "--no-remote", "script.ts"]); diff --git a/cli/global_state.rs b/cli/global_state.rs index cd04d03e6..e9988f4b5 100644 --- a/cli/global_state.rs +++ b/cli/global_state.rs @@ -170,17 +170,24 @@ impl GlobalState { let allow_js = should_allow_js(&module_graph_files); if should_compile { - self - .ts_compiler - .compile( - self.clone(), - &out, - target_lib, - permissions, - module_graph, - allow_js, - ) - .await?; + if self.flags.no_check { + self + .ts_compiler + .transpile(self.clone(), permissions, module_graph) + .await?; + } else { + self + .ts_compiler + .compile( + self.clone(), + &out, + target_lib, + permissions, + module_graph, + allow_js, + ) + .await?; + } } if let Some(ref lockfile) = self.lockfile { diff --git a/cli/js/buffer.ts b/cli/js/buffer.ts index 6a5105908..5c304c127 100644 --- a/cli/js/buffer.ts +++ b/cli/js/buffer.ts @@ -4,7 +4,7 @@ // Copyright 2009 The Go Authors. All rights reserved. BSD license. // https://github.com/golang/go/blob/master/LICENSE -import { Reader, Writer, ReaderSync, WriterSync } from "./io.ts"; +import type { Reader, Writer, ReaderSync, WriterSync } from "./io.ts"; import { assert } from "./util.ts"; // MIN_READ is the minimum ArrayBuffer size passed to a read call by diff --git a/cli/js/compiler.ts b/cli/js/compiler.ts index 500716a64..fc75a7c10 100644 --- a/cli/js/compiler.ts +++ b/cli/js/compiler.ts @@ -14,10 +14,10 @@ import "./ts_global.d.ts"; import { bold, cyan, yellow } from "./colors.ts"; -import { CompilerOptions } from "./compiler_options.ts"; -import { Diagnostic, DiagnosticItem } from "./diagnostics.ts"; +import type { CompilerOptions } from "./compiler_options.ts"; +import type { Diagnostic, DiagnosticItem } from "./diagnostics.ts"; import { fromTypeScriptDiagnostic } from "./diagnostics_util.ts"; -import { TranspileOnlyResult } from "./ops/runtime_compiler.ts"; +import type { TranspileOnlyResult } from "./ops/runtime_compiler.ts"; import { bootstrapWorkerRuntime } from "./runtime_worker.ts"; import { assert, log, notImplemented } from "./util.ts"; import { core } from "./core.ts"; @@ -47,6 +47,8 @@ const TS_BUILD_INFO = "cache:///tsbuildinfo.json"; // TODO(Bartlomieju): this check should be done in Rust const IGNORED_COMPILER_OPTIONS: readonly string[] = [ "allowSyntheticDefaultImports", + "allowUmdGlobalAccess", + "assumeChangesOnlyAffectDirectDependencies", "baseUrl", "build", "composite", @@ -60,13 +62,13 @@ const IGNORED_COMPILER_OPTIONS: readonly string[] = [ "esModuleInterop", "extendedDiagnostics", "forceConsistentCasingInFileNames", + "generateCpuProfile", "help", "importHelpers", "incremental", "inlineSourceMap", "inlineSources", "init", - "isolatedModules", "listEmittedFiles", "listFiles", "mapRoot", @@ -139,10 +141,18 @@ const DEFAULT_COMPILE_OPTIONS: ts.CompilerOptions = { jsx: ts.JsxEmit.React, module: ts.ModuleKind.ESNext, outDir: OUT_DIR, - resolveJsonModule: true, sourceMap: true, strict: true, - stripComments: true, + removeComments: true, + target: ts.ScriptTarget.ESNext, +}; + +const DEFAULT_TRANSPILE_OPTIONS: ts.CompilerOptions = { + esModuleInterop: true, + inlineSourceMap: true, + jsx: ts.JsxEmit.React, + module: ts.ModuleKind.ESNext, + removeComments: true, target: ts.ScriptTarget.ESNext, }; @@ -172,16 +182,23 @@ interface CompilerHostOptions { incremental?: boolean; } -interface IncrementalCompilerHostOptions extends CompilerHostOptions { +type IncrementalCompilerHostOptions = Omit< + CompilerHostOptions, + "incremental" +> & { rootNames?: string[]; buildInfo?: string; -} +}; -interface ConfigureResponse { +interface HostConfigureResponse { ignoredOptions?: string[]; diagnostics?: ts.Diagnostic[]; } +interface ConfigureResponse extends HostConfigureResponse { + options: ts.CompilerOptions; +} + // Warning! The values in this enum are duplicated in `cli/msg.rs` // Update carefully! enum MediaType { @@ -238,6 +255,37 @@ const SOURCE_FILE_CACHE: Map<string, SourceFile> = new Map(); */ const RESOLVED_SPECIFIER_CACHE: Map<string, Map<string, string>> = new Map(); +function configure( + defaultOptions: ts.CompilerOptions, + source: string, + path: string, + cwd: string +): ConfigureResponse { + const { config, error } = ts.parseConfigFileTextToJson(path, source); + if (error) { + return { diagnostics: [error], options: defaultOptions }; + } + const { options, errors } = ts.convertCompilerOptionsFromJson( + config.compilerOptions, + cwd + ); + const ignoredOptions: string[] = []; + for (const key of Object.keys(options)) { + if ( + IGNORED_COMPILER_OPTIONS.includes(key) && + (!(key in defaultOptions) || options[key] !== defaultOptions[key]) + ) { + ignoredOptions.push(key); + delete options[key]; + } + } + return { + options: Object.assign({}, defaultOptions, options), + ignoredOptions: ignoredOptions.length ? ignoredOptions : undefined, + diagnostics: errors.length ? errors : undefined, + }; +} + class SourceFile { extension!: ts.Extension; filename!: string; @@ -314,7 +362,7 @@ function getAssetInternal(filename: string): SourceFile { } class Host implements ts.CompilerHost { - protected _options = DEFAULT_COMPILE_OPTIONS; + #options = DEFAULT_COMPILE_OPTIONS; readonly #target: CompilerHostTarget; readonly #writeFile: WriteFileCallback; /* Deno specific APIs */ @@ -330,12 +378,12 @@ class Host implements ts.CompilerHost { this.#writeFile = writeFile; if (bundle) { // options we need to change when we are generating a bundle - Object.assign(this._options, DEFAULT_BUNDLER_OPTIONS); + Object.assign(this.#options, DEFAULT_BUNDLER_OPTIONS); } else if (incremental) { - Object.assign(this._options, DEFAULT_INCREMENTAL_COMPILE_OPTIONS); + Object.assign(this.#options, DEFAULT_INCREMENTAL_COMPILE_OPTIONS); } if (unstable) { - this._options.lib = [ + this.#options.lib = [ target === CompilerHostTarget.Worker ? "lib.deno.worker.d.ts" : "lib.deno.window.d.ts", @@ -345,47 +393,28 @@ class Host implements ts.CompilerHost { } get options(): ts.CompilerOptions { - return this._options; + return this.#options; } configure( cwd: string, path: string, configurationText: string - ): ConfigureResponse { + ): HostConfigureResponse { log("compiler::host.configure", path); - assert(configurationText); - const { config, error } = ts.parseConfigFileTextToJson( + const { options, ...result } = configure( + this.#options, + configurationText, path, - configurationText - ); - if (error) { - return { diagnostics: [error] }; - } - const { options, errors } = ts.convertCompilerOptionsFromJson( - config.compilerOptions, cwd ); - const ignoredOptions: string[] = []; - for (const key of Object.keys(options)) { - if ( - IGNORED_COMPILER_OPTIONS.includes(key) && - (!(key in this._options) || options[key] !== this._options[key]) - ) { - ignoredOptions.push(key); - delete options[key]; - } - } - Object.assign(this._options, options); - return { - ignoredOptions: ignoredOptions.length ? ignoredOptions : undefined, - diagnostics: errors.length ? errors : undefined, - }; + this.#options = options; + return result; } mergeOptions(...options: ts.CompilerOptions[]): ts.CompilerOptions { - Object.assign(this._options, ...options); - return Object.assign({}, this._options); + Object.assign(this.#options, ...options); + return Object.assign({}, this.#options); } /* TypeScript CompilerHost APIs */ @@ -400,7 +429,7 @@ class Host implements ts.CompilerHost { getCompilationSettings(): ts.CompilerOptions { log("compiler::host.getCompilationSettings()"); - return this._options; + return this.#options; } getCurrentDirectory(): string { @@ -522,7 +551,7 @@ class IncrementalCompileHost extends Host { readonly #buildInfo?: string; constructor(options: IncrementalCompilerHostOptions) { - super(options); + super({ ...options, incremental: true }); const { buildInfo } = options; if (buildInfo) { this.#buildInfo = buildInfo; @@ -735,10 +764,11 @@ interface BundleWriteFileState { // Update carefully! enum CompilerRequestType { Compile = 0, - Bundle = 1, - RuntimeCompile = 2, - RuntimeBundle = 3, - RuntimeTranspile = 4, + Transpile = 1, + Bundle = 2, + RuntimeCompile = 3, + RuntimeBundle = 4, + RuntimeTranspile = 5, } function createBundleWriteFile(state: BundleWriteFileState): WriteFileCallback { @@ -943,16 +973,29 @@ function performanceStart(): void { ts.performance.enable(); } -function performanceProgram(program: ts.Program | ts.BuilderProgram): void { - if ("getProgram" in program) { - program = program.getProgram(); +function performanceProgram({ + program, + fileCount, +}: { + program?: ts.Program | ts.BuilderProgram; + fileCount?: number; +}): void { + if (program) { + if ("getProgram" in program) { + program = program.getProgram(); + } + stats.push({ key: "Files", value: program.getSourceFiles().length }); + stats.push({ key: "Nodes", value: program.getNodeCount() }); + stats.push({ key: "Identifiers", value: program.getIdentifierCount() }); + stats.push({ key: "Symbols", value: program.getSymbolCount() }); + stats.push({ key: "Types", value: program.getTypeCount() }); + stats.push({ + key: "Instantiations", + value: program.getInstantiationCount(), + }); + } else if (fileCount != null) { + stats.push({ key: "Files", value: fileCount }); } - stats.push({ key: "Files", value: program.getSourceFiles().length }); - stats.push({ key: "Nodes", value: program.getNodeCount() }); - stats.push({ key: "Identifiers", value: program.getIdentifierCount() }); - stats.push({ key: "Symbols", value: program.getSymbolCount() }); - stats.push({ key: "Types", value: program.getTypeCount() }); - stats.push({ key: "Instantiations", value: program.getInstantiationCount() }); const programTime = ts.performance.getDuration("Program"); const bindTime = ts.performance.getDuration("Bind"); const checkTime = ts.performance.getDuration("Check"); @@ -976,7 +1019,7 @@ function performanceEnd(): Stats { // TODO(Bartlomieju): this check should be done in Rust; there should be no function processConfigureResponse( - configResult: ConfigureResponse, + configResult: HostConfigureResponse, configPath: string ): ts.Diagnostic[] | undefined { const { ignoredOptions, diagnostics } = configResult; @@ -1209,6 +1252,20 @@ interface CompileRequest { buildInfo?: string; } +interface TranspileRequest { + type: CompilerRequestType.Transpile; + config?: string; + configPath?: string; + cwd?: string; + performance: boolean; + sourceFiles: TranspileSourceFile[]; +} + +interface TranspileSourceFile { + sourceCode: string; + fileName: string; +} + /** Used when "deno bundle" is invoked */ interface BundleRequest { type: CompilerRequestType.Bundle; @@ -1252,6 +1309,7 @@ interface RuntimeTranspileRequest { type CompilerRequest = | CompileRequest + | TranspileRequest | BundleRequest | RuntimeCompileRequest | RuntimeBundleRequest @@ -1264,6 +1322,12 @@ interface CompileResponse { stats?: Stats; } +interface TranspileResponse { + emitMap: Record<string, EmittedSource>; + diagnostics: Diagnostic; + stats?: Stats; +} + interface BundleResponse { bundleOutput?: string; diagnostics: Diagnostic; @@ -1310,7 +1374,6 @@ function compile({ bundle: false, target, unstable, - incremental: true, writeFile: createCompileWriteFile(state), rootNames, buildInfo, @@ -1364,7 +1427,7 @@ function compile({ // without casting. diagnostics = emitResult.diagnostics; } - performanceProgram(program); + performanceProgram({ program }); } log("<<< compile end", { rootNames, type: CompilerRequestType[type] }); @@ -1378,21 +1441,81 @@ function compile({ }; } +function transpile({ + config: configText, + configPath, + cwd, + performance, + sourceFiles, +}: TranspileRequest): TranspileResponse { + if (performance) { + performanceStart(); + } + log(">>> transpile start"); + let compilerOptions: ts.CompilerOptions; + if (configText && configPath && cwd) { + const { options, ...response } = configure( + DEFAULT_TRANSPILE_OPTIONS, + configText, + configPath, + cwd + ); + const diagnostics = processConfigureResponse(response, configPath); + if (diagnostics && diagnostics.length) { + return { + diagnostics: fromTypeScriptDiagnostic(diagnostics), + emitMap: {}, + }; + } + compilerOptions = options; + } else { + compilerOptions = Object.assign({}, DEFAULT_TRANSPILE_OPTIONS); + } + const emitMap: Record<string, EmittedSource> = {}; + let diagnostics: ts.Diagnostic[] = []; + for (const { sourceCode, fileName } of sourceFiles) { + const { + outputText, + sourceMapText, + diagnostics: diags, + } = ts.transpileModule(sourceCode, { + fileName, + compilerOptions, + reportDiagnostics: true, + }); + if (diags) { + diagnostics = diagnostics.concat(...diags); + } + emitMap[`${fileName}.js`] = { filename: fileName, contents: outputText }; + // currently we inline source maps, but this is good logic to have if this + // ever changes + if (sourceMapText) { + emitMap[`${fileName}.map`] = { + filename: fileName, + contents: sourceMapText, + }; + } + } + performanceProgram({ fileCount: sourceFiles.length }); + const stats = performance ? performanceEnd() : undefined; + log("<<< transpile end"); + return { diagnostics: fromTypeScriptDiagnostic(diagnostics), emitMap, stats }; +} + function bundle({ - type, config, configPath, rootNames, target, unstable, - performance, cwd, sourceFileMap, + type, }: BundleRequest): BundleResponse { if (performance) { performanceStart(); } - log(">>> start start", { + log(">>> bundle start", { rootNames, type: CompilerRequestType[type], }); @@ -1447,7 +1570,7 @@ function bundle({ diagnostics = emitResult.diagnostics; } if (performance) { - performanceProgram(program); + performanceProgram({ program }); } } @@ -1655,6 +1778,11 @@ async function tsCompilerOnMessage({ globalThis.postMessage(result); break; } + case CompilerRequestType.Transpile: { + const result = transpile(request); + globalThis.postMessage(result); + break; + } case CompilerRequestType.Bundle: { const result = bundle(request); globalThis.postMessage(result); diff --git a/cli/js/compiler_api.ts b/cli/js/compiler_api.ts index 0f4aec887..8a50e0b3d 100644 --- a/cli/js/compiler_api.ts +++ b/cli/js/compiler_api.ts @@ -3,11 +3,11 @@ // This file contains the runtime APIs which will dispatch work to the internal // compiler within Deno. -import { DiagnosticItem } from "./diagnostics.ts"; +import type { DiagnosticItem } from "./diagnostics.ts"; import * as util from "./util.ts"; import * as runtimeCompilerOps from "./ops/runtime_compiler.ts"; -import { TranspileOnlyResult } from "./ops/runtime_compiler.ts"; -import { CompilerOptions } from "./compiler_options.ts"; +import type { TranspileOnlyResult } from "./ops/runtime_compiler.ts"; +import type { CompilerOptions } from "./compiler_options.ts"; function checkRelative(specifier: string): string { return specifier.match(/^([\.\/\\]|https?:\/{2}|file:\/{2})/) diff --git a/cli/js/deno.ts b/cli/js/deno.ts index 6570042af..878df8fb4 100644 --- a/cli/js/deno.ts +++ b/cli/js/deno.ts @@ -27,16 +27,15 @@ export { stderr, seek, seekSync, - OpenOptions, } from "./files.ts"; +export type { OpenOptions } from "./files.ts"; export { read, readSync, write, writeSync } from "./ops/io.ts"; -export { FsEvent, watchFs } from "./ops/fs_events.ts"; +export { watchFs } from "./ops/fs_events.ts"; +export type { FsEvent } from "./ops/fs_events.ts"; export { internalSymbol as internal } from "./internals.ts"; -export { - copy, - iter, - iterSync, - SeekMode, +export { copy, iter, iterSync } from "./io.ts"; +export { SeekMode } from "./io.ts"; +export type { Reader, ReaderSync, Writer, @@ -49,30 +48,39 @@ export { makeTempDir, makeTempFileSync, makeTempFile, - MakeTempOptions, } from "./ops/fs/make_temp.ts"; -export { metrics, Metrics } from "./ops/runtime.ts"; -export { mkdirSync, mkdir, MkdirOptions } from "./ops/fs/mkdir.ts"; -export { connect, listen, Listener, Conn } from "./net.ts"; +export type { MakeTempOptions } from "./ops/fs/make_temp.ts"; +export { metrics } from "./ops/runtime.ts"; +export type { Metrics } from "./ops/runtime.ts"; +export { mkdirSync, mkdir } from "./ops/fs/mkdir.ts"; +export type { MkdirOptions } from "./ops/fs/mkdir.ts"; +export { connect, listen } from "./net.ts"; +export type { Listener, Conn } from "./net.ts"; export { env, exit, execPath } from "./ops/os.ts"; -export { run, RunOptions, Process, ProcessStatus } from "./process.ts"; -export { DirEntry, readDirSync, readDir } from "./ops/fs/read_dir.ts"; +export { Process, run } from "./process.ts"; +export type { RunOptions, ProcessStatus } from "./process.ts"; +export { readDirSync, readDir } from "./ops/fs/read_dir.ts"; +export type { DirEntry } from "./ops/fs/read_dir.ts"; export { readFileSync, readFile } from "./read_file.ts"; export { readTextFileSync, readTextFile } from "./read_text_file.ts"; export { readLinkSync, readLink } from "./ops/fs/read_link.ts"; export { realPathSync, realPath } from "./ops/fs/real_path.ts"; -export { removeSync, remove, RemoveOptions } from "./ops/fs/remove.ts"; +export { removeSync, remove } from "./ops/fs/remove.ts"; +export type { RemoveOptions } from "./ops/fs/remove.ts"; export { renameSync, rename } from "./ops/fs/rename.ts"; export { resources, close } from "./ops/resources.ts"; -export { FileInfo, statSync, lstatSync, stat, lstat } from "./ops/fs/stat.ts"; +export { statSync, lstatSync, stat, lstat } from "./ops/fs/stat.ts"; +export type { FileInfo } from "./ops/fs/stat.ts"; export { connectTls, listenTls } from "./tls.ts"; export { truncateSync, truncate } from "./ops/fs/truncate.ts"; export { isatty } from "./ops/tty.ts"; export { version } from "./version.ts"; -export { writeFileSync, writeFile, WriteFileOptions } from "./write_file.ts"; +export { writeFileSync, writeFile } from "./write_file.ts"; +export type { WriteFileOptions } from "./write_file.ts"; export { writeTextFileSync, writeTextFile } from "./write_text_file.ts"; export const args: string[] = []; -export { TestDefinition, test } from "./testing.ts"; +export { test } from "./testing.ts"; +export type { TestDefinition } from "./testing.ts"; // These are internal Deno APIs. We are marking them as internal so they do not // appear in the runtime type library. diff --git a/cli/js/deno_unstable.ts b/cli/js/deno_unstable.ts index e7a0510be..8744abba4 100644 --- a/cli/js/deno_unstable.ts +++ b/cli/js/deno_unstable.ts @@ -15,20 +15,16 @@ export { signal, signals, Signal, SignalStream } from "./signals.ts"; export { setRaw } from "./ops/tty.ts"; export { utimeSync, utime } from "./ops/fs/utime.ts"; export { ftruncateSync, ftruncate } from "./ops/fs/truncate.ts"; -export { ShutdownMode, shutdown } from "./net.ts"; +export { shutdown, ShutdownMode } from "./net.ts"; export { listen, listenDatagram, connect } from "./net_unstable.ts"; export { startTls } from "./tls.ts"; export { kill } from "./ops/process.ts"; -export { - permissions, - PermissionName, - PermissionState, - PermissionStatus, - Permissions, -} from "./permissions.ts"; -export { +export { permissions, Permissions } from "./permissions.ts"; +export { PermissionStatus } from "./permissions.ts"; +export type { PermissionName, PermissionState } from "./permissions.ts"; +export { DiagnosticCategory } from "./diagnostics.ts"; +export type { Diagnostic, - DiagnosticCategory, DiagnosticItem, DiagnosticMessageChain, } from "./diagnostics.ts"; diff --git a/cli/js/files.ts b/cli/js/files.ts index 3dc48420d..3afcb4878 100644 --- a/cli/js/files.ts +++ b/cli/js/files.ts @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { +import type { Reader, Writer, Seeker, @@ -19,7 +19,7 @@ import { openSync as opOpenSync, OpenOptions, } from "./ops/fs/open.ts"; -export { OpenOptions } from "./ops/fs/open.ts"; +export type { OpenOptions } from "./ops/fs/open.ts"; export function openSync( path: string | URL, diff --git a/cli/js/globals.ts b/cli/js/globals.ts index 5746b224f..c73a2a6ab 100644 --- a/cli/js/globals.ts +++ b/cli/js/globals.ts @@ -7,7 +7,7 @@ import * as abortSignal from "./web/abort_signal.ts"; import * as blob from "./web/blob.ts"; import * as consoleTypes from "./web/console.ts"; import * as csprng from "./ops/get_random_values.ts"; -import * as promiseTypes from "./web/promise.ts"; +import type * as promiseTypes from "./web/promise.ts"; import * as customEvent from "./web/custom_event.ts"; import * as domException from "./web/dom_exception.ts"; import * as domFile from "./web/dom_file.ts"; diff --git a/cli/js/net.ts b/cli/js/net.ts index e5e6af7bd..a4aad0254 100644 --- a/cli/js/net.ts +++ b/cli/js/net.ts @@ -1,12 +1,13 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { errors } from "./errors.ts"; -import { Reader, Writer, Closer } from "./io.ts"; +import type { Reader, Writer, Closer } from "./io.ts"; import { read, write } from "./ops/io.ts"; import { close } from "./ops/resources.ts"; import * as netOps from "./ops/net.ts"; -import { Addr } from "./ops/net.ts"; -export { ShutdownMode, shutdown, NetAddr, UnixAddr } from "./ops/net.ts"; +import type { Addr } from "./ops/net.ts"; +export type { ShutdownMode, NetAddr, UnixAddr } from "./ops/net.ts"; +export { shutdown } from "./ops/net.ts"; export interface DatagramConn extends AsyncIterable<[Uint8Array, Addr]> { receive(p?: Uint8Array): Promise<[Uint8Array, Addr]>; diff --git a/cli/js/ops/errors.ts b/cli/js/ops/errors.ts index c6c26b8ba..002ca699e 100644 --- a/cli/js/ops/errors.ts +++ b/cli/js/ops/errors.ts @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { DiagnosticItem } from "../diagnostics.ts"; +import type { DiagnosticItem } from "../diagnostics.ts"; import { sendSync } from "./dispatch_json.ts"; export function formatDiagnostics(items: DiagnosticItem[]): string { diff --git a/cli/js/ops/fs/seek.ts b/cli/js/ops/fs/seek.ts index 2e23e084b..8fd3964fd 100644 --- a/cli/js/ops/fs/seek.ts +++ b/cli/js/ops/fs/seek.ts @@ -1,7 +1,7 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync, sendAsync } from "../dispatch_json.ts"; -import { SeekMode } from "../../io.ts"; +import type { SeekMode } from "../../io.ts"; export function seekSync( rid: number, diff --git a/cli/js/ops/permissions.ts b/cli/js/ops/permissions.ts index dfe8c4834..74b9ba0f0 100644 --- a/cli/js/ops/permissions.ts +++ b/cli/js/ops/permissions.ts @@ -1,7 +1,7 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync } from "./dispatch_json.ts"; -import { PermissionState } from "../permissions.ts"; +import type { PermissionState } from "../permissions.ts"; interface PermissionRequest { name: string; diff --git a/cli/js/ops/runtime_compiler.ts b/cli/js/ops/runtime_compiler.ts index 5a89983ee..671585118 100644 --- a/cli/js/ops/runtime_compiler.ts +++ b/cli/js/ops/runtime_compiler.ts @@ -1,7 +1,7 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendAsync } from "./dispatch_json.ts"; -import { DiagnosticItem } from "../diagnostics.ts"; +import type { DiagnosticItem } from "../diagnostics.ts"; interface CompileRequest { rootName: string; diff --git a/cli/js/process.ts b/cli/js/process.ts index 6f45081dc..ee32eac3d 100644 --- a/cli/js/process.ts +++ b/cli/js/process.ts @@ -2,7 +2,7 @@ import { File } from "./files.ts"; import { close } from "./ops/resources.ts"; -import { Closer, Reader, Writer } from "./io.ts"; +import type { Closer, Reader, Writer } from "./io.ts"; import { readAll } from "./buffer.ts"; import { kill, runStatus as runStatusOp, run as runOp } from "./ops/process.ts"; diff --git a/cli/js/web/body.ts b/cli/js/web/body.ts index 3bcda0634..69aca459f 100644 --- a/cli/js/web/body.ts +++ b/cli/js/web/body.ts @@ -2,7 +2,7 @@ import * as blob from "./blob.ts"; import * as encoding from "./text_encoding.ts"; -import * as domTypes from "./dom_types.d.ts"; +import type * as domTypes from "./dom_types.d.ts"; import { ReadableStreamImpl } from "./streams/readable_stream.ts"; import { isReadableStreamDisturbed } from "./streams/internals.ts"; import { Buffer } from "../buffer.ts"; diff --git a/cli/js/web/event.ts b/cli/js/web/event.ts index b57c0f901..556d403a6 100644 --- a/cli/js/web/event.ts +++ b/cli/js/web/event.ts @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import * as domTypes from "./dom_types.d.ts"; +import type * as domTypes from "./dom_types.d.ts"; import { defineEnumerableProps, requiredArguments } from "./util.ts"; import { assert } from "../util.ts"; diff --git a/cli/js/web/event_target.ts b/cli/js/web/event_target.ts index 1a560dfbe..6f6897425 100644 --- a/cli/js/web/event_target.ts +++ b/cli/js/web/event_target.ts @@ -6,7 +6,7 @@ // and impossible logic branches based on what Deno currently supports. import { DOMExceptionImpl as DOMException } from "./dom_exception.ts"; -import * as domTypes from "./dom_types.d.ts"; +import type * as domTypes from "./dom_types.d.ts"; import { EventImpl as Event, EventPath, diff --git a/cli/js/web/fetch.ts b/cli/js/web/fetch.ts index 33cf12069..543560c8d 100644 --- a/cli/js/web/fetch.ts +++ b/cli/js/web/fetch.ts @@ -2,12 +2,13 @@ import { notImplemented } from "../util.ts"; import { isTypedArray } from "./util.ts"; -import * as domTypes from "./dom_types.d.ts"; +import type * as domTypes from "./dom_types.d.ts"; import { TextEncoder } from "./text_encoding.ts"; import { DenoBlob, bytesSymbol as blobBytesSymbol } from "./blob.ts"; import { read } from "../ops/io.ts"; import { close } from "../ops/resources.ts"; -import { fetch as opFetch, FetchResponse } from "../ops/fetch.ts"; +import { fetch as opFetch } from "../ops/fetch.ts"; +import type { FetchResponse } from "../ops/fetch.ts"; import * as Body from "./body.ts"; import { getHeaderValueParams } from "./util.ts"; import { ReadableStreamImpl } from "./streams/readable_stream.ts"; diff --git a/cli/js/web/request.ts b/cli/js/web/request.ts index 7ea6a9ecd..f65b6a363 100644 --- a/cli/js/web/request.ts +++ b/cli/js/web/request.ts @@ -1,7 +1,7 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import * as body from "./body.ts"; -import * as domTypes from "./dom_types.d.ts"; +import type * as domTypes from "./dom_types.d.ts"; import { ReadableStreamImpl } from "./streams/readable_stream.ts"; function byteUpperCase(s: string): string { diff --git a/cli/js/web/streams/internals.ts b/cli/js/web/streams/internals.ts index 3fbfb7735..f6b20ccaf 100644 --- a/cli/js/web/streams/internals.ts +++ b/cli/js/web/streams/internals.ts @@ -12,7 +12,7 @@ import { ReadableStreamDefaultControllerImpl } from "./readable_stream_default_c import { ReadableStreamDefaultReaderImpl } from "./readable_stream_default_reader.ts"; import { ReadableStreamImpl } from "./readable_stream.ts"; import * as sym from "./symbols.ts"; -import { TransformStreamImpl } from "./transform_stream.ts"; +import type { TransformStreamImpl } from "./transform_stream.ts"; import { TransformStreamDefaultControllerImpl } from "./transform_stream_default_controller.ts"; import { WritableStreamDefaultControllerImpl } from "./writable_stream_default_controller.ts"; import { WritableStreamDefaultWriterImpl } from "./writable_stream_default_writer.ts"; diff --git a/cli/js/web/streams/readable_byte_stream_controller.ts b/cli/js/web/streams/readable_byte_stream_controller.ts index cbef64357..65409dc1e 100644 --- a/cli/js/web/streams/readable_byte_stream_controller.ts +++ b/cli/js/web/streams/readable_byte_stream_controller.ts @@ -20,7 +20,7 @@ import { readableStreamCreateReadResult, setFunctionName, } from "./internals.ts"; -import { ReadableStreamImpl } from "./readable_stream.ts"; +import type { ReadableStreamImpl } from "./readable_stream.ts"; import * as sym from "./symbols.ts"; import { assert } from "../../util.ts"; import { customInspect } from "../console.ts"; diff --git a/cli/js/web/streams/readable_stream.ts b/cli/js/web/streams/readable_stream.ts index 27a733d9d..3191c0859 100644 --- a/cli/js/web/streams/readable_stream.ts +++ b/cli/js/web/streams/readable_stream.ts @@ -19,9 +19,9 @@ import { setUpReadableStreamDefaultControllerFromUnderlyingSource, validateAndNormalizeHighWaterMark, } from "./internals.ts"; -import { ReadableByteStreamControllerImpl } from "./readable_byte_stream_controller.ts"; +import type { ReadableByteStreamControllerImpl } from "./readable_byte_stream_controller.ts"; import { ReadableStreamAsyncIteratorPrototype } from "./readable_stream_async_iterator.ts"; -import { ReadableStreamDefaultControllerImpl } from "./readable_stream_default_controller.ts"; +import type { ReadableStreamDefaultControllerImpl } from "./readable_stream_default_controller.ts"; import * as sym from "./symbols.ts"; import { customInspect } from "../console.ts"; import { AbortSignalImpl } from "../abort_signal.ts"; diff --git a/cli/js/web/streams/readable_stream_default_controller.ts b/cli/js/web/streams/readable_stream_default_controller.ts index 0755e7765..47cb719c7 100644 --- a/cli/js/web/streams/readable_stream_default_controller.ts +++ b/cli/js/web/streams/readable_stream_default_controller.ts @@ -20,7 +20,7 @@ import { SizeAlgorithm, setFunctionName, } from "./internals.ts"; -import { ReadableStreamImpl } from "./readable_stream.ts"; +import type { ReadableStreamImpl } from "./readable_stream.ts"; import * as sym from "./symbols.ts"; import { customInspect } from "../console.ts"; diff --git a/cli/js/web/streams/readable_stream_default_reader.ts b/cli/js/web/streams/readable_stream_default_reader.ts index a0d5901dc..01b679cd3 100644 --- a/cli/js/web/streams/readable_stream_default_reader.ts +++ b/cli/js/web/streams/readable_stream_default_reader.ts @@ -11,7 +11,7 @@ import { readableStreamReaderGenericRelease, setFunctionName, } from "./internals.ts"; -import { ReadableStreamImpl } from "./readable_stream.ts"; +import type { ReadableStreamImpl } from "./readable_stream.ts"; import * as sym from "./symbols.ts"; import { customInspect } from "../console.ts"; diff --git a/cli/js/web/streams/transform_stream.ts b/cli/js/web/streams/transform_stream.ts index ac08fea3f..548a20b38 100644 --- a/cli/js/web/streams/transform_stream.ts +++ b/cli/js/web/streams/transform_stream.ts @@ -11,10 +11,10 @@ import { setUpTransformStreamDefaultControllerFromTransformer, validateAndNormalizeHighWaterMark, } from "./internals.ts"; -import { ReadableStreamImpl } from "./readable_stream.ts"; +import type { ReadableStreamImpl } from "./readable_stream.ts"; import * as sym from "./symbols.ts"; -import { TransformStreamDefaultControllerImpl } from "./transform_stream_default_controller.ts"; -import { WritableStreamImpl } from "./writable_stream.ts"; +import type { TransformStreamDefaultControllerImpl } from "./transform_stream_default_controller.ts"; +import type { WritableStreamImpl } from "./writable_stream.ts"; import { customInspect, inspect } from "../console.ts"; // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/cli/js/web/streams/transform_stream_default_controller.ts b/cli/js/web/streams/transform_stream_default_controller.ts index 2fc8d2160..78beaf879 100644 --- a/cli/js/web/streams/transform_stream_default_controller.ts +++ b/cli/js/web/streams/transform_stream_default_controller.ts @@ -10,9 +10,9 @@ import { transformStreamDefaultControllerError, transformStreamDefaultControllerTerminate, } from "./internals.ts"; -import { ReadableStreamDefaultControllerImpl } from "./readable_stream_default_controller.ts"; +import type { ReadableStreamDefaultControllerImpl } from "./readable_stream_default_controller.ts"; import * as sym from "./symbols.ts"; -import { TransformStreamImpl } from "./transform_stream.ts"; +import type { TransformStreamImpl } from "./transform_stream.ts"; import { customInspect } from "../console.ts"; // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/cli/js/web/streams/writable_stream.ts b/cli/js/web/streams/writable_stream.ts index 4bbf339da..8a31f512d 100644 --- a/cli/js/web/streams/writable_stream.ts +++ b/cli/js/web/streams/writable_stream.ts @@ -16,8 +16,8 @@ import { validateAndNormalizeHighWaterMark, } from "./internals.ts"; import * as sym from "./symbols.ts"; -import { WritableStreamDefaultControllerImpl } from "./writable_stream_default_controller.ts"; -import { WritableStreamDefaultWriterImpl } from "./writable_stream_default_writer.ts"; +import type { WritableStreamDefaultControllerImpl } from "./writable_stream_default_controller.ts"; +import type { WritableStreamDefaultWriterImpl } from "./writable_stream_default_writer.ts"; import { customInspect } from "../console.ts"; // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/cli/js/web/streams/writable_stream_default_controller.ts b/cli/js/web/streams/writable_stream_default_controller.ts index 040d0eefc..b957c2c8f 100644 --- a/cli/js/web/streams/writable_stream_default_controller.ts +++ b/cli/js/web/streams/writable_stream_default_controller.ts @@ -13,7 +13,7 @@ import { writableStreamDefaultControllerError, } from "./internals.ts"; import * as sym from "./symbols.ts"; -import { WritableStreamImpl } from "./writable_stream.ts"; +import type { WritableStreamImpl } from "./writable_stream.ts"; import { customInspect } from "../console.ts"; export class WritableStreamDefaultControllerImpl<W> diff --git a/cli/js/web/streams/writable_stream_default_writer.ts b/cli/js/web/streams/writable_stream_default_writer.ts index 444a77aa9..09b47c69f 100644 --- a/cli/js/web/streams/writable_stream_default_writer.ts +++ b/cli/js/web/streams/writable_stream_default_writer.ts @@ -16,7 +16,7 @@ import { writableStreamDefaultWriterWrite, } from "./internals.ts"; import * as sym from "./symbols.ts"; -import { WritableStreamImpl } from "./writable_stream.ts"; +import type { WritableStreamImpl } from "./writable_stream.ts"; import { customInspect } from "../console.ts"; import { assert } from "../../util.ts"; diff --git a/cli/msg.rs b/cli/msg.rs index 3e5000296..5c50c96ab 100644 --- a/cli/msg.rs +++ b/cli/msg.rs @@ -55,10 +55,11 @@ pub fn enum_name_media_type(mt: MediaType) -> &'static str { #[derive(Clone, Copy, PartialEq, Debug)] pub enum CompilerRequestType { Compile = 0, - Bundle = 1, - RuntimeCompile = 2, - RuntimeBundle = 3, - RuntimeTranspile = 4, + Transpile = 1, + Bundle = 2, + RuntimeCompile = 3, + RuntimeBundle = 4, + RuntimeTranspile = 5, } impl Serialize for CompilerRequestType { @@ -68,10 +69,11 @@ impl Serialize for CompilerRequestType { { let value: i32 = match self { CompilerRequestType::Compile => 0 as i32, - CompilerRequestType::Bundle => 1 as i32, - CompilerRequestType::RuntimeCompile => 2 as i32, - CompilerRequestType::RuntimeBundle => 3 as i32, - CompilerRequestType::RuntimeTranspile => 4 as i32, + CompilerRequestType::Transpile => 1 as i32, + CompilerRequestType::Bundle => 2 as i32, + CompilerRequestType::RuntimeCompile => 3 as i32, + CompilerRequestType::RuntimeBundle => 4 as i32, + CompilerRequestType::RuntimeTranspile => 5 as i32, }; Serialize::serialize(&value, serializer) } diff --git a/cli/tests/error_no_check.ts b/cli/tests/error_no_check.ts new file mode 100644 index 000000000..db9257a1d --- /dev/null +++ b/cli/tests/error_no_check.ts @@ -0,0 +1 @@ +export { AnInterface, isAnInterface } from "./subdir/type_and_code.ts"; diff --git a/cli/tests/error_no_check.ts.out b/cli/tests/error_no_check.ts.out new file mode 100644 index 000000000..5890d1db8 --- /dev/null +++ b/cli/tests/error_no_check.ts.out @@ -0,0 +1 @@ +error: Uncaught SyntaxError: The requested module './subdir/type_and_code.ts' does not provide an export named 'AnInterface' diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs index 562c25de2..9acb4ed3f 100644 --- a/cli/tests/integration_tests.rs +++ b/cli/tests/integration_tests.rs @@ -16,6 +16,7 @@ use tempfile::TempDir; fn std_tests() { let dir = TempDir::new().expect("tempdir fail"); let std_path = util::root_path().join("std"); + let std_config = std_path.join("tsconfig_test.json"); let status = util::deno_cmd() .env("DENO_DIR", dir.path()) .current_dir(std_path) // TODO(ry) change this to root_path @@ -23,6 +24,8 @@ fn std_tests() { .arg("--unstable") .arg("--seed=86") // Some tests rely on specific random numbers. .arg("-A") + .arg("--config") + .arg(std_config.to_str().unwrap()) // .arg("-Ldebug") .spawn() .unwrap() @@ -1832,6 +1835,12 @@ itest!(error_025_tab_indent { exit_code: 1, }); +itest!(error_no_check { + args: "run --reload --no-check error_no_check.ts", + output: "error_no_check.ts.out", + exit_code: 1, +}); + itest!(error_syntax { args: "run --reload error_syntax.js", exit_code: 1, @@ -1890,6 +1899,12 @@ itest!(main_module { output: "main_module.ts.out", }); +itest!(no_check { + args: "run --quiet --reload --no-check 006_url_imports.ts", + output: "006_url_imports.ts.out", + http_server: true, +}); + itest!(lib_ref { args: "run --quiet --unstable --reload lib_ref.ts", output: "lib_ref.ts.out", diff --git a/cli/tests/subdir/type_and_code.ts b/cli/tests/subdir/type_and_code.ts new file mode 100644 index 000000000..b14713419 --- /dev/null +++ b/cli/tests/subdir/type_and_code.ts @@ -0,0 +1,7 @@ +export interface AnInterface { + a: string; +} + +export function isAnInterface(value: unknown): value is AnInterface { + return value && typeof value === "object" && "a" in value; +} diff --git a/cli/tsc.rs b/cli/tsc.rs index 9f8216e52..2a1307432 100644 --- a/cli/tsc.rs +++ b/cli/tsc.rs @@ -302,6 +302,13 @@ impl CompiledFileMetadata { } } +#[derive(Serialize, Debug)] +#[serde(rename_all = "camelCase")] +struct TranspileSourceFile { + pub source_code: String, + pub file_name: String, +} + /// Emit a SHA256 hash based on source code, deno version and TS config. /// Used to check if a recompilation for source code is needed. fn source_code_version_hash( @@ -376,6 +383,13 @@ struct CompileResponse { build_info: Option<String>, stats: Option<Vec<Stat>>, } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct TranspileResponse { + diagnostics: Diagnostic, + emit_map: HashMap<String, EmittedSource>, + stats: Option<Vec<Stat>>, +} // TODO(bartlomieju): possible deduplicate once TS refactor is stabilized #[derive(Deserialize)] @@ -704,6 +718,72 @@ impl TsCompiler { Ok(output) } + pub async fn transpile( + &self, + global_state: GlobalState, + permissions: Permissions, + module_graph: ModuleGraph, + ) -> Result<(), ErrBox> { + let mut source_files: Vec<TranspileSourceFile> = Vec::new(); + for (_, value) in module_graph.iter() { + let url = Url::parse(&value.url).expect("Filename is not a valid url"); + if !value.url.ends_with(".d.ts") + && (!self.use_disk_cache || !self.has_compiled_source(&url)) + { + source_files.push(TranspileSourceFile { + source_code: value.source_code.clone(), + file_name: value.url.clone(), + }); + } + } + if source_files.is_empty() { + return Ok(()); + } + + let source_files_json = + serde_json::to_value(source_files).expect("Filed to serialize data"); + let compiler_config = self.config.clone(); + let cwd = std::env::current_dir().unwrap(); + let performance = match global_state.flags.log_level { + Some(Level::Debug) => true, + _ => false, + }; + let j = match (compiler_config.path, compiler_config.content) { + (Some(config_path), Some(config_data)) => json!({ + "config": str::from_utf8(&config_data).unwrap(), + "configPath": config_path, + "cwd": cwd, + "performance": performance, + "sourceFiles": source_files_json, + "type": msg::CompilerRequestType::Transpile, + }), + _ => json!({ + "performance": performance, + "sourceFiles": source_files_json, + "type": msg::CompilerRequestType::Transpile, + }), + }; + + let req_msg = j.to_string().into_boxed_str().into_boxed_bytes(); + + let msg = + execute_in_same_thread(global_state.clone(), permissions, req_msg) + .await?; + + let json_str = std::str::from_utf8(&msg).unwrap(); + + let transpile_response: TranspileResponse = serde_json::from_str(json_str)?; + + if !transpile_response.diagnostics.items.is_empty() { + return Err(ErrBox::from(transpile_response.diagnostics)); + } + + maybe_log_stats(transpile_response.stats); + + self.cache_emitted_files(transpile_response.emit_map)?; + Ok(()) + } + /// Get associated `CompiledFileMetadata` for given module if it exists. fn get_metadata(&self, url: &Url) -> Option<CompiledFileMetadata> { // Try to load cached version: @@ -1575,6 +1655,75 @@ mod tests { } #[tokio::test] + async fn test_transpile() { + let p = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .parent() + .unwrap() + .join("cli/tests/002_hello.ts"); + let specifier = + ModuleSpecifier::resolve_url_or_path(p.to_str().unwrap()).unwrap(); + let out = SourceFile { + url: specifier.as_url().clone(), + filename: PathBuf::from(p.to_str().unwrap().to_string()), + media_type: msg::MediaType::TypeScript, + source_code: include_bytes!("./tests/002_hello.ts").to_vec(), + types_header: None, + }; + let dir = + deno_dir::DenoDir::new(Some(test_util::new_deno_dir().path().to_owned())) + .unwrap(); + let http_cache = http_cache::HttpCache::new(&dir.root.join("deps")); + let mock_state = GlobalState::mock( + vec![String::from("deno"), String::from("hello.ts")], + None, + ); + let file_fetcher = SourceFileFetcher::new( + http_cache, + true, + mock_state.flags.cache_blocklist.clone(), + false, + false, + None, + ) + .unwrap(); + + let mut module_graph_loader = ModuleGraphLoader::new( + file_fetcher.clone(), + None, + Permissions::allow_all(), + false, + false, + ); + module_graph_loader + .add_to_graph(&specifier, None) + .await + .expect("Failed to create graph"); + let module_graph = module_graph_loader.get_graph(); + + let ts_compiler = TsCompiler::new( + file_fetcher, + mock_state.flags.clone(), + dir.gen_cache.clone(), + ) + .unwrap(); + + let result = ts_compiler + .transpile(mock_state.clone(), Permissions::allow_all(), module_graph) + .await; + assert!(result.is_ok()); + let compiled_file = ts_compiler.get_compiled_module(&out.url).unwrap(); + let source_code = compiled_file.code; + assert!(source_code + .as_bytes() + .starts_with(b"console.log(\"Hello World\");")); + let mut lines: Vec<String> = + source_code.split('\n').map(|s| s.to_string()).collect(); + let last_line = lines.pop().unwrap(); + assert!(last_line + .starts_with("//# sourceMappingURL=data:application/json;base64")); + } + + #[tokio::test] async fn test_bundle() { let p = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) .parent() |