mirror of
https://github.com/denoland/deno.git
synced 2024-12-23 23:59:59 -05:00
BREAKING: Remove unstable Deno.emit and Deno.formatDiagnostics APIs (#14463)
This commit is contained in:
parent
9766399a3f
commit
f57aac77ff
32 changed files with 7 additions and 1957 deletions
105
cli/cache.rs
105
cli/cache.rs
|
@ -5,7 +5,6 @@ use crate::errors::get_error_class_name;
|
|||
use crate::file_fetcher::FileFetcher;
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::future;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::serde::Deserialize;
|
||||
use deno_core::serde::Serialize;
|
||||
|
@ -16,7 +15,6 @@ use deno_graph::source::LoadFuture;
|
|||
use deno_graph::source::LoadResponse;
|
||||
use deno_graph::source::Loader;
|
||||
use deno_runtime::permissions::Permissions;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
|
@ -248,106 +246,3 @@ impl CacherLoader for FetchCacher {
|
|||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// An in memory cache that is used by the runtime `Deno.emit()` API to provide
|
||||
/// the same behavior as the disk cache when sources are provided.
|
||||
#[derive(Debug)]
|
||||
pub struct MemoryCacher {
|
||||
sources: HashMap<String, Arc<String>>,
|
||||
declarations: HashMap<ModuleSpecifier, String>,
|
||||
emits: HashMap<ModuleSpecifier, String>,
|
||||
maps: HashMap<ModuleSpecifier, String>,
|
||||
build_infos: HashMap<ModuleSpecifier, String>,
|
||||
versions: HashMap<ModuleSpecifier, String>,
|
||||
}
|
||||
|
||||
impl MemoryCacher {
|
||||
pub fn new(sources: HashMap<String, Arc<String>>) -> Self {
|
||||
Self {
|
||||
sources,
|
||||
declarations: HashMap::default(),
|
||||
emits: HashMap::default(),
|
||||
maps: HashMap::default(),
|
||||
build_infos: HashMap::default(),
|
||||
versions: HashMap::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Loader for MemoryCacher {
|
||||
fn load(
|
||||
&mut self,
|
||||
specifier: &ModuleSpecifier,
|
||||
_is_dynamic: bool,
|
||||
) -> LoadFuture {
|
||||
let mut specifier_str = specifier.to_string();
|
||||
if !self.sources.contains_key(&specifier_str) {
|
||||
specifier_str = specifier_str.replace("file:///", "/");
|
||||
if !self.sources.contains_key(&specifier_str) {
|
||||
specifier_str = specifier_str[3..].to_string();
|
||||
}
|
||||
}
|
||||
let response =
|
||||
self
|
||||
.sources
|
||||
.get(&specifier_str)
|
||||
.map(|c| LoadResponse::Module {
|
||||
specifier: specifier.clone(),
|
||||
maybe_headers: None,
|
||||
content: c.to_owned(),
|
||||
});
|
||||
Box::pin(future::ready(Ok(response)))
|
||||
}
|
||||
}
|
||||
|
||||
impl Cacher for MemoryCacher {
|
||||
fn get(
|
||||
&self,
|
||||
cache_type: CacheType,
|
||||
specifier: &ModuleSpecifier,
|
||||
) -> Option<String> {
|
||||
match cache_type {
|
||||
CacheType::Declaration => self.declarations.get(specifier).cloned(),
|
||||
CacheType::Emit => self.emits.get(specifier).cloned(),
|
||||
CacheType::SourceMap => self.maps.get(specifier).cloned(),
|
||||
CacheType::TypeScriptBuildInfo => {
|
||||
self.build_infos.get(specifier).cloned()
|
||||
}
|
||||
CacheType::Version => self.versions.get(specifier).cloned(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set(
|
||||
&mut self,
|
||||
cache_type: CacheType,
|
||||
specifier: &ModuleSpecifier,
|
||||
value: String,
|
||||
) -> Result<(), AnyError> {
|
||||
match cache_type {
|
||||
CacheType::Declaration => {
|
||||
self.declarations.insert(specifier.clone(), value)
|
||||
}
|
||||
CacheType::Emit => self.emits.insert(specifier.clone(), value),
|
||||
CacheType::SourceMap => self.maps.insert(specifier.clone(), value),
|
||||
CacheType::TypeScriptBuildInfo => {
|
||||
self.build_infos.insert(specifier.clone(), value)
|
||||
}
|
||||
CacheType::Version => self.versions.insert(specifier.clone(), value),
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl CacherLoader for MemoryCacher {
|
||||
fn as_cacher(&self) -> &dyn Cacher {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_mut_loader(&mut self) -> &mut dyn Loader {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_mut_cacher(&mut self) -> &mut dyn Cacher {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ use deno_core::serde::Deserialize;
|
|||
use deno_core::serde::Deserializer;
|
||||
use deno_core::serde::Serialize;
|
||||
use deno_core::serde::Serializer;
|
||||
use deno_graph::ModuleGraphError;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use std::error::Error;
|
||||
|
@ -16,7 +15,6 @@ const MAX_SOURCE_LINE_LENGTH: usize = 150;
|
|||
|
||||
const UNSTABLE_DENO_PROPS: &[&str] = &[
|
||||
"BenchDefinition",
|
||||
"CompilerOptions",
|
||||
"CreateHttpClientOptions",
|
||||
"DatagramConn",
|
||||
"Diagnostic",
|
||||
|
@ -40,8 +38,6 @@ const UNSTABLE_DENO_PROPS: &[&str] = &[
|
|||
"connect",
|
||||
"consoleSize",
|
||||
"createHttpClient",
|
||||
"emit",
|
||||
"formatDiagnostics",
|
||||
"futime",
|
||||
"futimeSync",
|
||||
"hostname",
|
||||
|
@ -357,21 +353,6 @@ impl Diagnostics {
|
|||
Diagnostics(diagnostics)
|
||||
}
|
||||
|
||||
pub fn extend_graph_errors(&mut self, errors: Vec<ModuleGraphError>) {
|
||||
self.0.extend(errors.into_iter().map(|err| Diagnostic {
|
||||
category: DiagnosticCategory::Error,
|
||||
code: 900001,
|
||||
start: None,
|
||||
end: None,
|
||||
message_text: Some(err.to_string()),
|
||||
message_chain: None,
|
||||
source: None,
|
||||
source_line: None,
|
||||
file_name: Some(err.specifier().to_string()),
|
||||
related_information: None,
|
||||
}));
|
||||
}
|
||||
|
||||
/// Return a set of diagnostics where only the values where the predicate
|
||||
/// returns `true` are included.
|
||||
pub fn filter<P>(&self, predicate: P) -> Self
|
||||
|
|
342
cli/dts/lib.deno.unstable.d.ts
vendored
342
cli/dts/lib.deno.unstable.d.ts
vendored
|
@ -553,348 +553,6 @@ declare namespace Deno {
|
|||
code: number;
|
||||
}
|
||||
|
||||
/** **UNSTABLE**: new API, yet to be vetted.
|
||||
*
|
||||
* Format an array of diagnostic items and return them as a single string in a
|
||||
* user friendly format. If there are no diagnostics then it will return an
|
||||
* empty string.
|
||||
*
|
||||
* ```ts
|
||||
* const { diagnostics } = await Deno.emit("file_with_compile_issues.ts");
|
||||
* console.table(diagnostics); // Prints raw diagnostic data
|
||||
* console.log(Deno.formatDiagnostics(diagnostics)); // User friendly output of diagnostics
|
||||
* console.log(Deno.formatDiagnostics([])); // An empty string
|
||||
* ```
|
||||
*
|
||||
* @param diagnostics An array of diagnostic items to format
|
||||
*/
|
||||
export function formatDiagnostics(diagnostics: Diagnostic[]): string;
|
||||
|
||||
/** **UNSTABLE**: new API, yet to be vetted.
|
||||
*
|
||||
* A specific subset TypeScript compiler options that can be supported by the
|
||||
* Deno TypeScript compiler. */
|
||||
export interface CompilerOptions {
|
||||
/** Allow JavaScript files to be compiled. Defaults to `true`. */
|
||||
allowJs?: boolean;
|
||||
/** Allow default imports from modules with no default export. This does not
|
||||
* affect code emit, just typechecking. Defaults to `false`. */
|
||||
allowSyntheticDefaultImports?: boolean;
|
||||
/** Allow accessing UMD globals from modules. Defaults to `false`. */
|
||||
allowUmdGlobalAccess?: boolean;
|
||||
/** Do not report errors on unreachable code. Defaults to `false`. */
|
||||
allowUnreachableCode?: boolean;
|
||||
/** Do not report errors on unused labels. Defaults to `false` */
|
||||
allowUnusedLabels?: boolean;
|
||||
/** Parse in strict mode and emit `"use strict"` for each source file.
|
||||
* Defaults to `true`. */
|
||||
alwaysStrict?: boolean;
|
||||
/** Base directory to resolve non-relative module names. Defaults to
|
||||
* `undefined`. */
|
||||
baseUrl?: string;
|
||||
/** The character set of the input files. Defaults to `"utf8"`. */
|
||||
charset?: string;
|
||||
/** Report errors in `.js` files. Use in conjunction with `allowJs`. Defaults
|
||||
* to `false`. */
|
||||
checkJs?: boolean;
|
||||
/** Generates corresponding `.d.ts` file. Defaults to `false`. */
|
||||
declaration?: boolean;
|
||||
/** Output directory for generated declaration files. */
|
||||
declarationDir?: string;
|
||||
/** Generates a source map for each corresponding `.d.ts` file. Defaults to
|
||||
* `false`. */
|
||||
declarationMap?: boolean;
|
||||
/** Provide full support for iterables in `for..of`, spread and
|
||||
* destructuring when targeting ES5 or ES3. Defaults to `false`. */
|
||||
downlevelIteration?: boolean;
|
||||
/** Only emit `.d.ts` declaration files. Defaults to `false`. */
|
||||
emitDeclarationOnly?: boolean;
|
||||
/** Emit design-type metadata for decorated declarations in source. See issue
|
||||
* [microsoft/TypeScript#2577](https://github.com/Microsoft/TypeScript/issues/2577)
|
||||
* for details. Defaults to `false`. */
|
||||
emitDecoratorMetadata?: boolean;
|
||||
/** Emit `__importStar` and `__importDefault` helpers for runtime babel
|
||||
* ecosystem compatibility and enable `allowSyntheticDefaultImports` for type
|
||||
* system compatibility. Defaults to `true`. */
|
||||
esModuleInterop?: boolean;
|
||||
/** Enables experimental support for ES decorators. Defaults to `true`. */
|
||||
experimentalDecorators?: boolean;
|
||||
/** Import emit helpers (e.g. `__extends`, `__rest`, etc..) from
|
||||
* [tslib](https://www.npmjs.com/package/tslib). */
|
||||
importHelpers?: boolean;
|
||||
/** This flag controls how `import` works, there are 3 different options:
|
||||
*
|
||||
* - `remove`: The default behavior of dropping import statements which only
|
||||
* reference types.
|
||||
* - `preserve`: Preserves all `import` statements whose values or types are
|
||||
* never used. This can cause imports/side-effects to be preserved.
|
||||
* - `error`: This preserves all imports (the same as the preserve option),
|
||||
* but will error when a value import is only used as a type. This might
|
||||
* be useful if you want to ensure no values are being accidentally
|
||||
* imported, but still make side-effect imports explicit.
|
||||
*
|
||||
* This flag works because you can use `import type` to explicitly create an
|
||||
* `import` statement which should never be emitted into JavaScript. */
|
||||
importsNotUsedAsValues?: "remove" | "preserve" | "error";
|
||||
/** Emit a single file with source maps instead of having a separate file.
|
||||
* Defaults to `false`. */
|
||||
inlineSourceMap?: boolean;
|
||||
/** Emit the source alongside the source maps within a single file; requires
|
||||
* `inlineSourceMap` or `sourceMap` to be set. Defaults to `false`. */
|
||||
inlineSources?: boolean;
|
||||
/** Support JSX in `.tsx` files: `"react"`, `"preserve"`, `"react-native"`,
|
||||
* `"react-jsx", `"react-jsxdev"`.
|
||||
* Defaults to `"react"`. */
|
||||
jsx?: "react" | "preserve" | "react-native" | "react-jsx" | "react-jsx-dev";
|
||||
/** Specify the JSX factory function to use when targeting react JSX emit,
|
||||
* e.g. `React.createElement` or `h`. Defaults to `React.createElement`. */
|
||||
jsxFactory?: string;
|
||||
/** Specify the JSX fragment factory function to use when targeting react
|
||||
* JSX emit, e.g. `Fragment`. Defaults to `React.Fragment`. */
|
||||
jsxFragmentFactory?: string;
|
||||
/** Declares the module specifier to be used for importing the `jsx` and
|
||||
* `jsxs` factory functions when using jsx as `"react-jsx"` or
|
||||
* `"react-jsxdev"`. Defaults to `"react"`. */
|
||||
jsxImportSource?: string;
|
||||
/** Resolve keyof to string valued property names only (no numbers or
|
||||
* symbols). Defaults to `false`. */
|
||||
keyofStringsOnly?: string;
|
||||
/** List of library files to be included in the compilation. If omitted,
|
||||
* then the Deno main runtime libs are used. */
|
||||
lib?: string[];
|
||||
/** The locale to use to show error messages. */
|
||||
locale?: string;
|
||||
/** Specifies the location where debugger should locate map files instead of
|
||||
* generated locations. Use this flag if the `.map` files will be located at
|
||||
* run-time in a different location than the `.js` files. The location
|
||||
* specified will be embedded in the source map to direct the debugger where
|
||||
* the map files will be located. Defaults to `undefined`. */
|
||||
mapRoot?: string;
|
||||
/** Specify the module format for the emitted code. Defaults to
|
||||
* `"esnext"`. */
|
||||
module?:
|
||||
| "none"
|
||||
| "commonjs"
|
||||
| "amd"
|
||||
| "system"
|
||||
| "umd"
|
||||
| "es6"
|
||||
| "es2015"
|
||||
| "es2020"
|
||||
| "esnext";
|
||||
/** Do not generate custom helper functions like `__extends` in compiled
|
||||
* output. Defaults to `false`. */
|
||||
noEmitHelpers?: boolean;
|
||||
/** Report errors for fallthrough cases in switch statement. Defaults to
|
||||
* `false`. */
|
||||
noFallthroughCasesInSwitch?: boolean;
|
||||
/** Raise error on expressions and declarations with an implied any type.
|
||||
* Defaults to `true`. */
|
||||
noImplicitAny?: boolean;
|
||||
/** Report an error when not all code paths in function return a value.
|
||||
* Defaults to `false`. */
|
||||
noImplicitReturns?: boolean;
|
||||
/** Raise error on `this` expressions with an implied `any` type. Defaults to
|
||||
* `true`. */
|
||||
noImplicitThis?: boolean;
|
||||
/** Do not emit `"use strict"` directives in module output. Defaults to
|
||||
* `false`. */
|
||||
noImplicitUseStrict?: boolean;
|
||||
/** Do not include the default library file (`lib.d.ts`). Defaults to
|
||||
* `false`. */
|
||||
noLib?: boolean;
|
||||
/** Do not add triple-slash references or module import targets to the list of
|
||||
* compiled files. Defaults to `false`. */
|
||||
noResolve?: boolean;
|
||||
/** Disable strict checking of generic signatures in function types. Defaults
|
||||
* to `false`. */
|
||||
noStrictGenericChecks?: boolean;
|
||||
/** Include 'undefined' in index signature results. Defaults to `false`. */
|
||||
noUncheckedIndexedAccess?: boolean;
|
||||
/** Report errors on unused locals. Defaults to `false`. */
|
||||
noUnusedLocals?: boolean;
|
||||
/** Report errors on unused parameters. Defaults to `false`. */
|
||||
noUnusedParameters?: boolean;
|
||||
/** List of path mapping entries for module names to locations relative to the
|
||||
* `baseUrl`. Defaults to `undefined`. */
|
||||
paths?: Record<string, string[]>;
|
||||
/** Do not erase const enum declarations in generated code. Defaults to
|
||||
* `false`. */
|
||||
preserveConstEnums?: boolean;
|
||||
/** Remove all comments except copy-right header comments beginning with
|
||||
* `/*!`. Defaults to `true`. */
|
||||
removeComments?: boolean;
|
||||
/** Specifies the root directory of input files. Only use to control the
|
||||
* output directory structure with `outDir`. Defaults to `undefined`. */
|
||||
rootDir?: string;
|
||||
/** List of _root_ folders whose combined content represent the structure of
|
||||
* the project at runtime. Defaults to `undefined`. */
|
||||
rootDirs?: string[];
|
||||
/** Generates corresponding `.map` file. Defaults to `false`. */
|
||||
sourceMap?: boolean;
|
||||
/** Specifies the location where debugger should locate TypeScript files
|
||||
* instead of source locations. Use this flag if the sources will be located
|
||||
* at run-time in a different location than that at design-time. The location
|
||||
* specified will be embedded in the sourceMap to direct the debugger where
|
||||
* the source files will be located. Defaults to `undefined`. */
|
||||
sourceRoot?: string;
|
||||
/** Skip type checking of all declaration files (`*.d.ts`). */
|
||||
skipLibCheck?: boolean;
|
||||
/** Enable all strict type checking options. Enabling `strict` enables
|
||||
* `noImplicitAny`, `noImplicitThis`, `alwaysStrict`, `strictBindCallApply`,
|
||||
* `strictNullChecks`, `strictFunctionTypes` and
|
||||
* `strictPropertyInitialization`. Defaults to `true`. */
|
||||
strict?: boolean;
|
||||
/** Enable stricter checking of the `bind`, `call`, and `apply` methods on
|
||||
* functions. Defaults to `true`. */
|
||||
strictBindCallApply?: boolean;
|
||||
/** Disable bivariant parameter checking for function types. Defaults to
|
||||
* `true`. */
|
||||
strictFunctionTypes?: boolean;
|
||||
/** Ensure non-undefined class properties are initialized in the constructor.
|
||||
* This option requires `strictNullChecks` be enabled in order to take effect.
|
||||
* Defaults to `true`. */
|
||||
strictPropertyInitialization?: boolean;
|
||||
/** In strict null checking mode, the `null` and `undefined` values are not in
|
||||
* the domain of every type and are only assignable to themselves and `any`
|
||||
* (the one exception being that `undefined` is also assignable to `void`). */
|
||||
strictNullChecks?: boolean;
|
||||
/** Suppress excess property checks for object literals. Defaults to
|
||||
* `false`. */
|
||||
suppressExcessPropertyErrors?: boolean;
|
||||
/** Suppress `noImplicitAny` errors for indexing objects lacking index
|
||||
* signatures. */
|
||||
suppressImplicitAnyIndexErrors?: boolean;
|
||||
/** Specify ECMAScript target version. Defaults to `esnext`. */
|
||||
target?:
|
||||
| "es3"
|
||||
| "es5"
|
||||
| "es6"
|
||||
| "es2015"
|
||||
| "es2016"
|
||||
| "es2017"
|
||||
| "es2018"
|
||||
| "es2019"
|
||||
| "es2020"
|
||||
| "esnext";
|
||||
/** List of names of type definitions to include when type checking.
|
||||
* Defaults to `undefined`.
|
||||
*
|
||||
* The type definitions are resolved according to the normal Deno resolution
|
||||
* irrespective of if sources are provided on the call. In addition, unlike
|
||||
* passing the `--config` option on startup, there is no base to resolve
|
||||
* relative specifiers, so the specifiers here have to be fully qualified
|
||||
* URLs or paths. For example:
|
||||
*
|
||||
* ```ts
|
||||
* Deno.emit("./a.ts", {
|
||||
* compilerOptions: {
|
||||
* types: [
|
||||
* "https://deno.land/x/pkg/types.d.ts",
|
||||
* "/Users/me/pkg/types.d.ts",
|
||||
* ]
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
types?: string[];
|
||||
/** Emit class fields with ECMAScript-standard semantics. Defaults to
|
||||
* `false`. */
|
||||
useDefineForClassFields?: boolean;
|
||||
}
|
||||
|
||||
interface ImportMap {
|
||||
imports: Record<string, string>;
|
||||
scopes?: Record<string, Record<string, string>>;
|
||||
}
|
||||
|
||||
/**
|
||||
* **UNSTABLE**: new API, yet to be vetted.
|
||||
*
|
||||
* The options for `Deno.emit()` API.
|
||||
*/
|
||||
export interface EmitOptions {
|
||||
/** Indicate that the source code should be emitted to a single file
|
||||
* JavaScript bundle that is a single ES module (`"module"`) or a single
|
||||
* file self contained script executed in an immediately invoked function
|
||||
* when loaded (`"classic"`). */
|
||||
bundle?: "module" | "classic";
|
||||
/** If `true` then the sources will be typed checked, returning any
|
||||
* diagnostic errors in the result. If `false` type checking will be
|
||||
* skipped. Defaults to `true`.
|
||||
*
|
||||
* *Note* by default, only TypeScript will be type checked, just like on
|
||||
* the command line. Use the `compilerOptions` options of `checkJs` to
|
||||
* enable type checking of JavaScript. */
|
||||
check?: boolean;
|
||||
/** A set of options that are aligned to TypeScript compiler options that
|
||||
* are supported by Deno. */
|
||||
compilerOptions?: CompilerOptions;
|
||||
/** An [import-map](https://deno.land/manual/linking_to_external_code/import_maps#import-maps)
|
||||
* which will be applied to the imports. */
|
||||
importMap?: ImportMap;
|
||||
/** An absolute path to an [import-map](https://deno.land/manual/linking_to_external_code/import_maps#import-maps).
|
||||
* Required to be specified if an `importMap` is specified to be able to
|
||||
* determine resolution of relative paths. If a `importMap` is not
|
||||
* specified, then it will assumed the file path points to an import map on
|
||||
* disk and will be attempted to be loaded based on current runtime
|
||||
* permissions.
|
||||
*/
|
||||
importMapPath?: string;
|
||||
/** A record of sources to use when doing the emit. If provided, Deno will
|
||||
* use these sources instead of trying to resolve the modules externally. */
|
||||
sources?: Record<string, string>;
|
||||
}
|
||||
|
||||
/**
|
||||
* **UNSTABLE**: new API, yet to be vetted.
|
||||
*
|
||||
* The result of `Deno.emit()` API.
|
||||
*/
|
||||
export interface EmitResult {
|
||||
/** Diagnostic messages returned from the type checker (`tsc`).
|
||||
*
|
||||
* Can be used with `Deno.formatDiagnostics` to display a user
|
||||
* friendly string. */
|
||||
diagnostics: Diagnostic[];
|
||||
/** Any emitted files. If bundled, then the JavaScript will have the
|
||||
* key of `deno:///bundle.js` with an optional map (based on
|
||||
* `compilerOptions`) in `deno:///bundle.js.map`. */
|
||||
files: Record<string, string>;
|
||||
/** An optional array of any compiler options that were ignored by Deno. */
|
||||
ignoredOptions?: string[];
|
||||
/** An array of internal statistics related to the emit, for diagnostic
|
||||
* purposes. */
|
||||
stats: Array<[string, number]>;
|
||||
}
|
||||
|
||||
/**
|
||||
* **UNSTABLE**: new API, yet to be vetted.
|
||||
*
|
||||
* Similar to the command line functionality of `deno run` or `deno cache`,
|
||||
* `Deno.emit()` provides a way to provide Deno arbitrary JavaScript
|
||||
* or TypeScript and have it return JavaScript based on the options and
|
||||
* settings provided. The source code can either be provided or the modules
|
||||
* can be fetched and resolved in line with the behavior of the command line.
|
||||
*
|
||||
* Requires `allow-read` and/or `allow-net` if sources are not provided.
|
||||
*
|
||||
* @param rootSpecifier The specifier that will be used as the entry point.
|
||||
* If no sources are provided, then the specifier would
|
||||
* be the same as if you typed it on the command line for
|
||||
* `deno run`. If sources are provided, it should match
|
||||
* one of the names of the sources.
|
||||
* @param options A set of options to be used with the emit.
|
||||
*
|
||||
* @returns The result of the emit. If diagnostics are found, they can be used
|
||||
* with `Deno.formatDiagnostics` to construct a user friendly string, which
|
||||
* has the same format as CLI diagnostics.
|
||||
*/
|
||||
export function emit(
|
||||
rootSpecifier: string | URL,
|
||||
options?: EmitOptions,
|
||||
): Promise<EmitResult>;
|
||||
|
||||
export type SetRawOptions = {
|
||||
cbreak: boolean;
|
||||
};
|
||||
|
|
81
cli/emit.rs
81
cli/emit.rs
|
@ -146,8 +146,6 @@ pub enum ConfigType {
|
|||
Check { lib: TypeLib, tsc_emit: bool },
|
||||
/// Return a configuration to use swc to emit single module files.
|
||||
Emit,
|
||||
/// Return a configuration as a base for the runtime `Deno.emit()` API.
|
||||
RuntimeEmit { tsc_emit: bool },
|
||||
}
|
||||
|
||||
/// For a given configuration type and optionally a configuration file, return a
|
||||
|
@ -216,44 +214,6 @@ pub fn get_ts_config(
|
|||
"jsxFragmentFactory": "React.Fragment",
|
||||
"resolveJsonModule": true,
|
||||
})),
|
||||
ConfigType::RuntimeEmit { tsc_emit } => {
|
||||
let mut ts_config = TsConfig::new(json!({
|
||||
"allowJs": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"checkJs": false,
|
||||
"emitDecoratorMetadata": false,
|
||||
"experimentalDecorators": true,
|
||||
"importsNotUsedAsValues": "remove",
|
||||
"incremental": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "react",
|
||||
"jsxFactory": "React.createElement",
|
||||
"jsxFragmentFactory": "React.Fragment",
|
||||
"lib": TypeLib::DenoWindow,
|
||||
"module": "esnext",
|
||||
"removeComments": true,
|
||||
"inlineSourceMap": false,
|
||||
"inlineSources": false,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"target": "esnext",
|
||||
"tsBuildInfoFile": "deno:///.tsbuildinfo",
|
||||
"useDefineForClassFields": true,
|
||||
// TODO(@kitsonk) remove for Deno 2.0
|
||||
"useUnknownInCatchVariables": false,
|
||||
}));
|
||||
if tsc_emit {
|
||||
ts_config.merge(&json!({
|
||||
"importsNotUsedAsValues": "remove",
|
||||
"outDir": "deno://",
|
||||
}));
|
||||
} else {
|
||||
ts_config.merge(&json!({
|
||||
"noEmit": true,
|
||||
}));
|
||||
}
|
||||
ts_config
|
||||
}
|
||||
};
|
||||
let maybe_ignored_options = if let Some(user_options) = maybe_user_config {
|
||||
ts_config.merge_user_config(user_options)?
|
||||
|
@ -946,47 +906,6 @@ impl fmt::Display for GraphError {
|
|||
}
|
||||
}
|
||||
|
||||
/// Convert a module graph to a map of "files", which are used by the runtime
|
||||
/// emit to be passed back to the caller.
|
||||
pub fn to_file_map(
|
||||
graph: &ModuleGraph,
|
||||
cache: &dyn Cacher,
|
||||
) -> HashMap<String, String> {
|
||||
let mut files = HashMap::new();
|
||||
for (_, result) in graph.specifiers().into_iter() {
|
||||
if let Ok((specifier, _, media_type)) = result {
|
||||
if let Some(emit) = cache.get(CacheType::Emit, &specifier) {
|
||||
files.insert(format!("{}.js", specifier), emit);
|
||||
if let Some(map) = cache.get(CacheType::SourceMap, &specifier) {
|
||||
files.insert(format!("{}.js.map", specifier), map);
|
||||
}
|
||||
} else if matches!(
|
||||
media_type,
|
||||
MediaType::JavaScript
|
||||
| MediaType::Mjs
|
||||
| MediaType::Cjs
|
||||
| MediaType::Json
|
||||
| MediaType::Unknown
|
||||
) {
|
||||
if let Some(module) = graph.get(&specifier) {
|
||||
files.insert(
|
||||
specifier.to_string(),
|
||||
module
|
||||
.maybe_source
|
||||
.as_ref()
|
||||
.map(|s| s.to_string())
|
||||
.unwrap_or_else(|| "".to_string()),
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Some(declaration) = cache.get(CacheType::Declaration, &specifier) {
|
||||
files.insert(format!("{}.d.ts", specifier), declaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
files
|
||||
}
|
||||
|
||||
/// This contains the logic for Deno to rewrite the `import.meta` when bundling.
|
||||
pub struct BundleHook;
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@ pub fn format_location(frame: &JsStackFrame) -> String {
|
|||
result
|
||||
}
|
||||
|
||||
// Keep in sync with `runtime/js/40_error_stack.js`.
|
||||
fn format_frame(frame: &JsStackFrame) -> String {
|
||||
let _internal = frame
|
||||
.file_name
|
||||
|
|
|
@ -139,7 +139,7 @@ fn create_web_worker_callback(
|
|||
let preload_module_cb =
|
||||
create_web_worker_preload_module_callback(ps.clone());
|
||||
|
||||
let extensions = ops::cli_exts(ps.clone(), args.use_deno_namespace);
|
||||
let extensions = ops::cli_exts(ps.clone());
|
||||
|
||||
let options = WebWorkerOptions {
|
||||
bootstrap: BootstrapOptions {
|
||||
|
@ -237,7 +237,7 @@ pub fn create_main_worker(
|
|||
.join(checksum::gen(&[key.as_bytes()]))
|
||||
});
|
||||
|
||||
let mut extensions = ops::cli_exts(ps.clone(), true);
|
||||
let mut extensions = ops::cli_exts(ps.clone());
|
||||
extensions.append(&mut custom_extensions);
|
||||
|
||||
let options = WorkerOptions {
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::diagnostics::Diagnostics;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::serde_json::Value;
|
||||
use deno_core::Extension;
|
||||
|
||||
pub fn init() -> Extension {
|
||||
Extension::builder()
|
||||
.ops(vec![op_format_diagnostic::decl()])
|
||||
.build()
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_format_diagnostic(args: Value) -> Result<Value, AnyError> {
|
||||
let diagnostic: Diagnostics = serde_json::from_value(args)?;
|
||||
Ok(json!(diagnostic.to_string()))
|
||||
}
|
|
@ -4,20 +4,10 @@ use crate::proc_state::ProcState;
|
|||
use deno_core::Extension;
|
||||
|
||||
pub mod bench;
|
||||
mod errors;
|
||||
mod runtime_compiler;
|
||||
pub mod testing;
|
||||
|
||||
pub fn cli_exts(ps: ProcState, enable_compiler: bool) -> Vec<Extension> {
|
||||
if enable_compiler {
|
||||
vec![
|
||||
init_proc_state(ps),
|
||||
errors::init(),
|
||||
runtime_compiler::init(),
|
||||
]
|
||||
} else {
|
||||
vec![init_proc_state(ps), errors::init()]
|
||||
}
|
||||
pub fn cli_exts(ps: ProcState) -> Vec<Extension> {
|
||||
vec![init_proc_state(ps)]
|
||||
}
|
||||
|
||||
fn init_proc_state(ps: ProcState) -> Extension {
|
||||
|
|
|
@ -1,328 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::cache;
|
||||
use crate::config_file::IgnoredCompilerOptions;
|
||||
use crate::diagnostics::Diagnostics;
|
||||
use crate::emit;
|
||||
use crate::errors::get_error_class_name;
|
||||
use crate::flags;
|
||||
use crate::graph_util::graph_valid;
|
||||
use crate::proc_state::import_map_from_text;
|
||||
use crate::proc_state::ProcState;
|
||||
use crate::resolver::ImportMapResolver;
|
||||
use crate::resolver::JsxResolver;
|
||||
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::custom_error;
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::AnyError;
|
||||
|
||||
use deno_core::op;
|
||||
use deno_core::parking_lot::RwLock;
|
||||
use deno_core::resolve_url_or_path;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::Value;
|
||||
use deno_core::Extension;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::OpState;
|
||||
use deno_graph::ModuleKind;
|
||||
use deno_runtime::permissions::Permissions;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub fn init() -> Extension {
|
||||
Extension::builder().ops(vec![op_emit::decl()]).build()
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
enum RuntimeBundleType {
|
||||
#[serde(rename = "module")]
|
||||
Module,
|
||||
#[serde(rename = "classic")]
|
||||
Classic,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a RuntimeBundleType> for emit::BundleType {
|
||||
fn from(bundle_type: &'a RuntimeBundleType) -> Self {
|
||||
match bundle_type {
|
||||
RuntimeBundleType::Classic => Self::Classic,
|
||||
RuntimeBundleType::Module => Self::Module,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct EmitArgs {
|
||||
bundle: Option<RuntimeBundleType>,
|
||||
check: Option<bool>,
|
||||
compiler_options: Option<HashMap<String, Value>>,
|
||||
import_map: Option<Value>,
|
||||
import_map_path: Option<String>,
|
||||
root_specifier: String,
|
||||
sources: Option<HashMap<String, Arc<String>>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct EmitResult {
|
||||
diagnostics: Diagnostics,
|
||||
files: HashMap<String, String>,
|
||||
#[serde(rename = "ignoredOptions")]
|
||||
maybe_ignored_options: Option<IgnoredCompilerOptions>,
|
||||
stats: emit::Stats,
|
||||
}
|
||||
|
||||
/// Provides inferred imported modules from configuration options, like the
|
||||
/// `"types"` and `"jsxImportSource"` imports.
|
||||
fn to_maybe_imports(
|
||||
referrer: &ModuleSpecifier,
|
||||
maybe_options: Option<&HashMap<String, Value>>,
|
||||
) -> Option<Vec<(ModuleSpecifier, Vec<String>)>> {
|
||||
let options = maybe_options?;
|
||||
let mut imports = Vec::new();
|
||||
if let Some(types_value) = options.get("types") {
|
||||
if let Ok(types) =
|
||||
serde_json::from_value::<Vec<String>>(types_value.clone())
|
||||
{
|
||||
imports.extend(types);
|
||||
}
|
||||
}
|
||||
if let Some(jsx_value) = options.get("jsx") {
|
||||
if let Ok(jsx) = serde_json::from_value::<String>(jsx_value.clone()) {
|
||||
let jsx_import_source =
|
||||
if let Some(jsx_import_source_value) = options.get("jsxImportSource") {
|
||||
if let Ok(jsx_import_source) =
|
||||
serde_json::from_value::<String>(jsx_import_source_value.clone())
|
||||
{
|
||||
jsx_import_source
|
||||
} else {
|
||||
"react".to_string()
|
||||
}
|
||||
} else {
|
||||
"react".to_string()
|
||||
};
|
||||
match jsx.as_str() {
|
||||
"react-jsx" => {
|
||||
imports.push(format!("{}/jsx-runtime", jsx_import_source));
|
||||
}
|
||||
"react-jsxdev" => {
|
||||
imports.push(format!("{}/jsx-dev-runtime", jsx_import_source));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
if !imports.is_empty() {
|
||||
Some(vec![(referrer.clone(), imports)])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts the compiler options to the JSX import source module that will be
|
||||
/// loaded when transpiling JSX.
|
||||
fn to_maybe_jsx_import_source_module(
|
||||
maybe_options: Option<&HashMap<String, Value>>,
|
||||
) -> Option<String> {
|
||||
let options = maybe_options?;
|
||||
let jsx_value = options.get("jsx")?;
|
||||
let jsx: String = serde_json::from_value(jsx_value.clone()).ok()?;
|
||||
match jsx.as_str() {
|
||||
"react-jsx" => Some("jsx-runtime".to_string()),
|
||||
"react-jsxdev" => Some("jsx-dev-runtime".to_string()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_emit(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: EmitArgs,
|
||||
) -> Result<EmitResult, AnyError> {
|
||||
deno_runtime::ops::check_unstable2(&state, "Deno.emit");
|
||||
let root_specifier = args.root_specifier;
|
||||
let ps = {
|
||||
let state = state.borrow();
|
||||
state.borrow::<ProcState>().clone()
|
||||
};
|
||||
let mut runtime_permissions = {
|
||||
let state = state.borrow();
|
||||
state.borrow::<Permissions>().clone()
|
||||
};
|
||||
|
||||
let mut cache: Box<dyn cache::CacherLoader> =
|
||||
if let Some(sources) = &args.sources {
|
||||
Box::new(cache::MemoryCacher::new(sources.clone()))
|
||||
} else {
|
||||
Box::new(cache::FetchCacher::new(
|
||||
ps.dir.gen_cache.clone(),
|
||||
ps.file_fetcher.clone(),
|
||||
runtime_permissions.clone(),
|
||||
runtime_permissions.clone(),
|
||||
))
|
||||
};
|
||||
let maybe_import_map_resolver = if let Some(import_map_str) =
|
||||
args.import_map_path
|
||||
{
|
||||
let import_map_specifier = resolve_url_or_path(&import_map_str)
|
||||
.with_context(|| {
|
||||
format!("Bad URL (\"{}\") for import map.", import_map_str)
|
||||
})?;
|
||||
let import_map_source = if let Some(value) = args.import_map {
|
||||
Arc::new(value.to_string())
|
||||
} else {
|
||||
let file = ps
|
||||
.file_fetcher
|
||||
.fetch(&import_map_specifier, &mut runtime_permissions)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
generic_error(format!(
|
||||
"Unable to load '{}' import map: {}",
|
||||
import_map_specifier, e
|
||||
))
|
||||
})?;
|
||||
file.source
|
||||
};
|
||||
let import_map =
|
||||
import_map_from_text(&import_map_specifier, &import_map_source)?;
|
||||
Some(ImportMapResolver::new(Arc::new(import_map)))
|
||||
} else if args.import_map.is_some() {
|
||||
return Err(generic_error("An importMap was specified, but no importMapPath was provided, which is required."));
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let maybe_jsx_resolver =
|
||||
to_maybe_jsx_import_source_module(args.compiler_options.as_ref())
|
||||
.map(|im| JsxResolver::new(im, maybe_import_map_resolver.clone()));
|
||||
let maybe_resolver = if maybe_jsx_resolver.is_some() {
|
||||
maybe_jsx_resolver.as_ref().map(|jr| jr.as_resolver())
|
||||
} else {
|
||||
maybe_import_map_resolver
|
||||
.as_ref()
|
||||
.map(|imr| imr.as_resolver())
|
||||
};
|
||||
let roots = vec![(resolve_url_or_path(&root_specifier)?, ModuleKind::Esm)];
|
||||
let maybe_imports =
|
||||
to_maybe_imports(&roots[0].0, args.compiler_options.as_ref());
|
||||
let graph = Arc::new(
|
||||
deno_graph::create_graph(
|
||||
roots,
|
||||
true,
|
||||
maybe_imports,
|
||||
cache.as_mut_loader(),
|
||||
maybe_resolver,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await,
|
||||
);
|
||||
let check = args.check.unwrap_or(true);
|
||||
// There are certain graph errors that we want to return as an error of an op,
|
||||
// versus something that gets returned as a diagnostic of the op, this is
|
||||
// handled here.
|
||||
if let Err(err) = graph_valid(&graph, check, true) {
|
||||
if get_error_class_name(&err) == "PermissionDenied" {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
let debug = ps.flags.log_level == Some(log::Level::Debug);
|
||||
let tsc_emit = check && args.bundle.is_none();
|
||||
let (ts_config, maybe_ignored_options) = emit::get_ts_config(
|
||||
emit::ConfigType::RuntimeEmit { tsc_emit },
|
||||
None,
|
||||
args.compiler_options.as_ref(),
|
||||
)?;
|
||||
let (files, mut diagnostics, stats) = if check && args.bundle.is_none() {
|
||||
let emit_result = emit::check_and_maybe_emit(
|
||||
&graph.roots,
|
||||
Arc::new(RwLock::new(graph.as_ref().into())),
|
||||
cache.as_mut_cacher(),
|
||||
emit::CheckOptions {
|
||||
type_check_mode: flags::TypeCheckMode::All,
|
||||
debug,
|
||||
emit_with_diagnostics: true,
|
||||
maybe_config_specifier: None,
|
||||
ts_config,
|
||||
log_checks: false,
|
||||
reload: ps.flags.reload || args.sources.is_some(),
|
||||
// TODO(nayeemrmn): Determine reload exclusions.
|
||||
reload_exclusions: Default::default(),
|
||||
},
|
||||
)?;
|
||||
let files = emit::to_file_map(graph.as_ref(), cache.as_mut_cacher());
|
||||
(files, emit_result.diagnostics, emit_result.stats)
|
||||
} else if let Some(bundle) = &args.bundle {
|
||||
let (diagnostics, stats) = if check {
|
||||
if ts_config.get_declaration() {
|
||||
return Err(custom_error("TypeError", "The bundle option is set, but the compiler option of `declaration` is true which is not currently supported."));
|
||||
}
|
||||
let emit_result = emit::check_and_maybe_emit(
|
||||
&graph.roots,
|
||||
Arc::new(RwLock::new(graph.as_ref().into())),
|
||||
cache.as_mut_cacher(),
|
||||
emit::CheckOptions {
|
||||
type_check_mode: flags::TypeCheckMode::All,
|
||||
debug,
|
||||
emit_with_diagnostics: true,
|
||||
maybe_config_specifier: None,
|
||||
ts_config: ts_config.clone(),
|
||||
log_checks: false,
|
||||
reload: ps.flags.reload || args.sources.is_some(),
|
||||
// TODO(nayeemrmn): Determine reload exclusions.
|
||||
reload_exclusions: Default::default(),
|
||||
},
|
||||
)?;
|
||||
(emit_result.diagnostics, emit_result.stats)
|
||||
} else {
|
||||
(Diagnostics::default(), Default::default())
|
||||
};
|
||||
let (emit, maybe_map) = emit::bundle(
|
||||
graph.as_ref(),
|
||||
emit::BundleOptions {
|
||||
bundle_type: bundle.into(),
|
||||
ts_config,
|
||||
emit_ignore_directives: true,
|
||||
},
|
||||
)?;
|
||||
let mut files = HashMap::new();
|
||||
files.insert("deno:///bundle.js".to_string(), emit);
|
||||
if let Some(map) = maybe_map {
|
||||
files.insert("deno:///bundle.js.map".to_string(), map);
|
||||
}
|
||||
(files, diagnostics, stats)
|
||||
} else {
|
||||
if ts_config.get_declaration() {
|
||||
return Err(custom_error("TypeError", "The option of `check` is false, but the compiler option of `declaration` is true which is not currently supported."));
|
||||
}
|
||||
let emit_result = emit::emit(
|
||||
graph.as_ref(),
|
||||
cache.as_mut_cacher(),
|
||||
emit::EmitOptions {
|
||||
ts_config,
|
||||
reload: ps.flags.reload || args.sources.is_some(),
|
||||
// TODO(nayeemrmn): Determine reload exclusions.
|
||||
reload_exclusions: HashSet::default(),
|
||||
},
|
||||
)?;
|
||||
let files = emit::to_file_map(graph.as_ref(), cache.as_mut_cacher());
|
||||
(files, emit_result.diagnostics, emit_result.stats)
|
||||
};
|
||||
|
||||
// we want to add any errors that were returned as an `Err` earlier by adding
|
||||
// them to the diagnostics.
|
||||
diagnostics.extend_graph_errors(graph.errors());
|
||||
|
||||
Ok(EmitResult {
|
||||
diagnostics,
|
||||
files,
|
||||
maybe_ignored_options,
|
||||
stats,
|
||||
})
|
||||
}
|
|
@ -288,7 +288,7 @@ pub async fn run(
|
|||
unstable: metadata.unstable,
|
||||
user_agent: version::get_user_agent(),
|
||||
},
|
||||
extensions: ops::cli_exts(ps.clone(), true),
|
||||
extensions: ops::cli_exts(ps.clone()),
|
||||
unsafely_ignore_certificate_errors: metadata
|
||||
.unsafely_ignore_certificate_errors,
|
||||
root_cert_store: Some(root_cert_store),
|
||||
|
|
|
@ -225,76 +225,6 @@ fn standalone_follow_redirects() {
|
|||
assert_eq!(output.stdout, b"Hello\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn standalone_compiler_ops() {
|
||||
let dir = TempDir::new();
|
||||
let exe = if cfg!(windows) {
|
||||
dir.path().join("standalone_compiler_ops.exe")
|
||||
} else {
|
||||
dir.path().join("standalone_compiler_ops")
|
||||
};
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&exe)
|
||||
.arg("./standalone_compiler_ops.ts")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let output = Command::new(exe)
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, b"Hello, Compiler API!\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compile_with_directory_output_flag() {
|
||||
let dir = TempDir::new();
|
||||
let output_path = if cfg!(windows) {
|
||||
dir.path().join(r"args\random\")
|
||||
} else {
|
||||
dir.path().join("args/random/")
|
||||
};
|
||||
let output = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("compile")
|
||||
.arg("--unstable")
|
||||
.arg("--output")
|
||||
.arg(&output_path)
|
||||
.arg("./standalone_compiler_ops.ts")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
let exe = if cfg!(windows) {
|
||||
output_path.join("standalone_compiler_ops.exe")
|
||||
} else {
|
||||
output_path.join("standalone_compiler_ops")
|
||||
};
|
||||
assert!(&exe.exists());
|
||||
let output = Command::new(exe)
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, b"Hello, Compiler API!\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compile_with_file_exists_error() {
|
||||
let dir = TempDir::new();
|
||||
|
|
|
@ -443,22 +443,6 @@ console.log("finish");
|
|||
assert!(end - start < Duration::new(10, 0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compiler_api() {
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("test")
|
||||
.arg("--unstable")
|
||||
.arg("--reload")
|
||||
.arg("--allow-read")
|
||||
.arg("compiler_api_test.ts")
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn broken_stdout() {
|
||||
let (reader, writer) = os_pipe::pipe().unwrap();
|
||||
|
|
|
@ -450,12 +450,6 @@ itest!(_079_location_authentication {
|
|||
output: "079_location_authentication.ts.out",
|
||||
});
|
||||
|
||||
itest!(_080_deno_emit_permissions {
|
||||
args: "run --unstable 080_deno_emit_permissions.ts",
|
||||
output: "080_deno_emit_permissions.ts.out",
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(_081_location_relative_fetch_redirect {
|
||||
args: "run --location http://127.0.0.1:4546/ --allow-net 081_location_relative_fetch_redirect.ts",
|
||||
output: "081_location_relative_fetch_redirect.ts.out",
|
||||
|
@ -986,26 +980,6 @@ itest!(runtime_decorators {
|
|||
output: "runtime_decorators.ts.out",
|
||||
});
|
||||
|
||||
itest!(lib_dom_asynciterable {
|
||||
args: "run --quiet --unstable --reload lib_dom_asynciterable.ts",
|
||||
output: "lib_dom_asynciterable.ts.out",
|
||||
});
|
||||
|
||||
itest!(lib_dom_extras {
|
||||
args: "run --quiet --unstable --reload lib_dom_extras.ts",
|
||||
output: "lib_dom_extras.ts.out",
|
||||
});
|
||||
|
||||
itest!(lib_ref {
|
||||
args: "run --quiet --unstable --reload lib_ref.ts",
|
||||
output: "lib_ref.ts.out",
|
||||
});
|
||||
|
||||
itest!(lib_runtime_api {
|
||||
args: "run --quiet --unstable --reload lib_runtime_api.ts",
|
||||
output: "lib_runtime_api.ts.out",
|
||||
});
|
||||
|
||||
itest!(seed_random {
|
||||
args: "run --seed=100 seed_random.js",
|
||||
output: "seed_random.js.out",
|
||||
|
@ -2417,24 +2391,6 @@ itest!(eval_context_throw_dom_exception {
|
|||
envs: vec![("DENO_FUTURE_CHECK".to_string(), "1".to_string())],
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn issue12453() {
|
||||
let _g = util::http_server();
|
||||
let deno_dir = util::new_deno_dir();
|
||||
let mut deno_cmd = util::deno_cmd_with_deno_dir(&deno_dir);
|
||||
let status = deno_cmd
|
||||
.current_dir(util::testdata_path())
|
||||
.arg("run")
|
||||
.arg("--unstable")
|
||||
.arg("--allow-net")
|
||||
.arg("issue12453.js")
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
/// Regression test for https://github.com/denoland/deno/issues/12740.
|
||||
#[test]
|
||||
fn issue12740() {
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
await Deno.emit(new URL("001_hello.js", import.meta.url).href);
|
|
@ -1,2 +0,0 @@
|
|||
[WILDCARD]error: Uncaught (in promise) PermissionDenied: Requires read access to "[WILDCARD]001_hello.js", run again with the --allow-read flag
|
||||
[WILDCARD]
|
664
cli/tests/testdata/compiler_api_test.ts
vendored
664
cli/tests/testdata/compiler_api_test.ts
vendored
|
@ -1,664 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
import {
|
||||
assert,
|
||||
assertEquals,
|
||||
assertRejects,
|
||||
assertStringIncludes,
|
||||
} from "../../../test_util/std/testing/asserts.ts";
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - sources provided",
|
||||
async fn() {
|
||||
const { diagnostics, files, ignoredOptions, stats } = await Deno.emit(
|
||||
"/foo.ts",
|
||||
{
|
||||
sources: {
|
||||
"/foo.ts": `import * as bar from "./bar.ts";\n\nconsole.log(bar);\n`,
|
||||
"/bar.ts": `export const bar = "bar";\n`,
|
||||
},
|
||||
},
|
||||
);
|
||||
assertEquals(diagnostics.length, 0);
|
||||
assert(!ignoredOptions);
|
||||
assertEquals(stats.length, 12);
|
||||
const keys = Object.keys(files).sort();
|
||||
assert(keys[0].endsWith("/bar.ts.js"));
|
||||
assert(keys[1].endsWith("/bar.ts.js.map"));
|
||||
assert(keys[2].endsWith("/foo.ts.js"));
|
||||
assert(keys[3].endsWith("/foo.ts.js.map"));
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - no sources provided",
|
||||
async fn() {
|
||||
const { diagnostics, files, ignoredOptions, stats } = await Deno.emit(
|
||||
"./subdir/mod1.ts",
|
||||
);
|
||||
assertEquals(diagnostics.length, 0);
|
||||
assert(!ignoredOptions);
|
||||
assertEquals(stats.length, 12);
|
||||
const keys = Object.keys(files).sort();
|
||||
assertEquals(keys.length, 6);
|
||||
assert(keys[0].endsWith("subdir/mod1.ts.js"));
|
||||
assert(keys[1].endsWith("subdir/mod1.ts.js.map"));
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - data url",
|
||||
async fn() {
|
||||
const data =
|
||||
"data:application/javascript;base64,Y29uc29sZS5sb2coImhlbGxvIHdvcmxkIik7";
|
||||
const { diagnostics, files, ignoredOptions, stats } = await Deno.emit(data);
|
||||
assertEquals(diagnostics.length, 0);
|
||||
assert(!ignoredOptions);
|
||||
assertEquals(stats.length, 0);
|
||||
const keys = Object.keys(files);
|
||||
assertEquals(keys.length, 1);
|
||||
assertEquals(keys[0], data);
|
||||
assertStringIncludes(files[keys[0]], 'console.log("hello world");');
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - compiler options effects emit",
|
||||
async fn() {
|
||||
const { diagnostics, files, ignoredOptions, stats } = await Deno.emit(
|
||||
"/foo.ts",
|
||||
{
|
||||
compilerOptions: {
|
||||
module: "amd",
|
||||
sourceMap: false,
|
||||
},
|
||||
sources: { "/foo.ts": `export const foo = "foo";` },
|
||||
},
|
||||
);
|
||||
assertEquals(diagnostics.length, 0);
|
||||
assert(!ignoredOptions);
|
||||
assertEquals(stats.length, 12);
|
||||
const keys = Object.keys(files);
|
||||
assertEquals(keys.length, 1);
|
||||
const key = keys[0];
|
||||
assert(key.endsWith("/foo.ts.js"));
|
||||
assert(files[key].startsWith("define("));
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - pass lib in compiler options",
|
||||
async fn() {
|
||||
const { diagnostics, files, ignoredOptions, stats } = await Deno.emit(
|
||||
"file:///foo.ts",
|
||||
{
|
||||
compilerOptions: {
|
||||
lib: ["dom", "es2018", "deno.ns"],
|
||||
},
|
||||
sources: {
|
||||
"file:///foo.ts": `console.log(document.getElementById("foo"));
|
||||
console.log(Deno.args);`,
|
||||
},
|
||||
},
|
||||
);
|
||||
assertEquals(diagnostics.length, 0);
|
||||
assert(!ignoredOptions);
|
||||
assertEquals(stats.length, 12);
|
||||
const keys = Object.keys(files).sort();
|
||||
assertEquals(keys, ["file:///foo.ts.js", "file:///foo.ts.js.map"]);
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - type references can be loaded",
|
||||
async fn() {
|
||||
const { diagnostics, files, ignoredOptions, stats } = await Deno.emit(
|
||||
"file:///a.ts",
|
||||
{
|
||||
sources: {
|
||||
"file:///a.ts": `/// <reference types="./b.d.ts" />
|
||||
const b = new B();
|
||||
console.log(b.b);`,
|
||||
"file:///b.d.ts": `declare class B {
|
||||
b: string;
|
||||
}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
assertEquals(diagnostics.length, 0);
|
||||
assert(!ignoredOptions);
|
||||
assertEquals(stats.length, 12);
|
||||
const keys = Object.keys(files).sort();
|
||||
assertEquals(keys, ["file:///a.ts.js", "file:///a.ts.js.map"]);
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - compilerOptions.types",
|
||||
async fn() {
|
||||
const { diagnostics, files, ignoredOptions, stats } = await Deno.emit(
|
||||
"file:///a.ts",
|
||||
{
|
||||
compilerOptions: {
|
||||
types: ["file:///b.d.ts"],
|
||||
},
|
||||
sources: {
|
||||
"file:///a.ts": `const b = new B();
|
||||
console.log(b.b);`,
|
||||
"file:///b.d.ts": `declare class B {
|
||||
b: string;
|
||||
}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
assertEquals(diagnostics.length, 0);
|
||||
assert(!ignoredOptions);
|
||||
assertEquals(stats.length, 12);
|
||||
const keys = Object.keys(files).sort();
|
||||
assertEquals(keys, ["file:///a.ts.js", "file:///a.ts.js.map"]);
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - import maps",
|
||||
async fn() {
|
||||
const { diagnostics, files, ignoredOptions, stats } = await Deno.emit(
|
||||
"file:///a.ts",
|
||||
{
|
||||
importMap: {
|
||||
imports: {
|
||||
"b": "./b.ts",
|
||||
},
|
||||
},
|
||||
importMapPath: "file:///import-map.json",
|
||||
sources: {
|
||||
"file:///a.ts": `import * as b from "b"
|
||||
console.log(b);`,
|
||||
"file:///b.ts": `export const b = "b";`,
|
||||
},
|
||||
},
|
||||
);
|
||||
assertEquals(diagnostics.length, 0);
|
||||
assert(!ignoredOptions);
|
||||
assertEquals(stats.length, 12);
|
||||
const keys = Object.keys(files).sort();
|
||||
assertEquals(
|
||||
keys,
|
||||
[
|
||||
"file:///a.ts.js",
|
||||
"file:///a.ts.js.map",
|
||||
"file:///b.ts.js",
|
||||
"file:///b.ts.js.map",
|
||||
],
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - allowSyntheticDefaultImports true by default",
|
||||
async fn() {
|
||||
const { diagnostics, files, ignoredOptions } = await Deno.emit(
|
||||
"file:///a.ts",
|
||||
{
|
||||
sources: {
|
||||
"file:///a.ts": `import b from "./b.js";\n`,
|
||||
"file:///b.js":
|
||||
`/// <reference types="./b.d.ts";\n\nconst b = "b";\n\nexport default b;\n`,
|
||||
"file:///b.d.ts": `declare const b: "b";\nexport = b;\n`,
|
||||
},
|
||||
},
|
||||
);
|
||||
assertEquals(diagnostics.length, 0);
|
||||
assert(!ignoredOptions);
|
||||
const keys = Object.keys(files).sort();
|
||||
assertEquals(keys, [
|
||||
"file:///a.ts.js",
|
||||
"file:///a.ts.js.map",
|
||||
"file:///b.js",
|
||||
]);
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - no check",
|
||||
async fn() {
|
||||
const { diagnostics, files, ignoredOptions, stats } = await Deno.emit(
|
||||
"/foo.ts",
|
||||
{
|
||||
check: false,
|
||||
sources: {
|
||||
"/foo.ts": `export enum Foo { Foo, Bar, Baz };\n`,
|
||||
},
|
||||
},
|
||||
);
|
||||
assertEquals(diagnostics.length, 0);
|
||||
assert(!ignoredOptions);
|
||||
assertEquals(stats.length, 3);
|
||||
const keys = Object.keys(files).sort();
|
||||
assert(keys[0].endsWith("/foo.ts.js"));
|
||||
assert(keys[1].endsWith("/foo.ts.js.map"));
|
||||
assert(files[keys[0]].startsWith("export var Foo;"));
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - no check - config effects emit",
|
||||
async fn() {
|
||||
const { diagnostics, files, ignoredOptions, stats } = await Deno.emit(
|
||||
"/foo.ts",
|
||||
{
|
||||
check: false,
|
||||
compilerOptions: { removeComments: true },
|
||||
sources: {
|
||||
"/foo.ts":
|
||||
`/** This is JSDoc */\nexport enum Foo { Foo, Bar, Baz };\n`,
|
||||
},
|
||||
},
|
||||
);
|
||||
assertEquals(diagnostics.length, 0);
|
||||
assert(!ignoredOptions);
|
||||
assertEquals(stats.length, 3);
|
||||
const keys = Object.keys(files).sort();
|
||||
assert(keys[0].endsWith("/foo.ts.js"));
|
||||
assert(keys[1].endsWith("/foo.ts.js.map"));
|
||||
assert(!files[keys[0]].includes("This is JSDoc"));
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - bundle as module script - with sources",
|
||||
async fn() {
|
||||
const { diagnostics, files, ignoredOptions, stats } = await Deno.emit(
|
||||
"/foo.ts",
|
||||
{
|
||||
bundle: "module",
|
||||
sources: {
|
||||
"/foo.ts": `export * from "./bar.ts";\n`,
|
||||
"/bar.ts": `export const bar = "bar";\n`,
|
||||
},
|
||||
},
|
||||
);
|
||||
assertEquals(diagnostics.length, 0);
|
||||
assert(!ignoredOptions);
|
||||
assertEquals(stats.length, 12);
|
||||
assertEquals(
|
||||
Object.keys(files).sort(),
|
||||
["deno:///bundle.js", "deno:///bundle.js.map"].sort(),
|
||||
);
|
||||
assert(files["deno:///bundle.js"].includes(`const bar = "bar"`));
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - bundle as module script - no sources",
|
||||
async fn() {
|
||||
const { diagnostics, files, ignoredOptions, stats } = await Deno.emit(
|
||||
"./subdir/mod1.ts",
|
||||
{
|
||||
bundle: "module",
|
||||
},
|
||||
);
|
||||
assertEquals(diagnostics.length, 0);
|
||||
assert(!ignoredOptions);
|
||||
assertEquals(stats.length, 12);
|
||||
assertEquals(
|
||||
Object.keys(files).sort(),
|
||||
["deno:///bundle.js", "deno:///bundle.js.map"].sort(),
|
||||
);
|
||||
assert(files["deno:///bundle.js"].length);
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - bundle as module script - include js modules",
|
||||
async fn() {
|
||||
const { diagnostics, files, ignoredOptions, stats } = await Deno.emit(
|
||||
"/foo.js",
|
||||
{
|
||||
bundle: "module",
|
||||
sources: {
|
||||
"/foo.js": `export * from "./bar.js";\n`,
|
||||
"/bar.js": `export const bar = "bar";\n`,
|
||||
},
|
||||
},
|
||||
);
|
||||
assertEquals(diagnostics.length, 0);
|
||||
assert(!ignoredOptions);
|
||||
assertEquals(stats.length, 0);
|
||||
assertEquals(
|
||||
Object.keys(files).sort(),
|
||||
["deno:///bundle.js.map", "deno:///bundle.js"].sort(),
|
||||
);
|
||||
assert(files["deno:///bundle.js"].includes(`const bar = "bar"`));
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - generates diagnostics",
|
||||
async fn() {
|
||||
const { diagnostics, files } = await Deno.emit(
|
||||
"/foo.ts",
|
||||
{
|
||||
sources: {
|
||||
"/foo.ts": `document.getElementById("foo");`,
|
||||
},
|
||||
},
|
||||
);
|
||||
assertEquals(diagnostics.length, 1);
|
||||
const keys = Object.keys(files).sort();
|
||||
assert(keys[0].endsWith("/foo.ts.js"));
|
||||
assert(keys[1].endsWith("/foo.ts.js.map"));
|
||||
},
|
||||
});
|
||||
|
||||
// See https://github.com/denoland/deno/issues/6908
|
||||
Deno.test({
|
||||
name: "Deno.emit() - invalid syntax does not panic",
|
||||
async fn() {
|
||||
const { diagnostics } = await Deno.emit("/main.js", {
|
||||
sources: {
|
||||
"/main.js": `
|
||||
export class Foo {
|
||||
constructor() {
|
||||
console.log("foo");
|
||||
}
|
||||
export get() {
|
||||
console.log("bar");
|
||||
}
|
||||
}`,
|
||||
},
|
||||
});
|
||||
assertEquals(diagnostics.length, 1);
|
||||
assert(
|
||||
diagnostics[0].messageText!.startsWith(
|
||||
"The module's source code could not be parsed: Unexpected token `get`. Expected * for generator, private key, identifier or async at file:",
|
||||
),
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: 'Deno.emit() - allows setting of "importsNotUsedAsValues"',
|
||||
async fn() {
|
||||
const { diagnostics } = await Deno.emit("/a.ts", {
|
||||
sources: {
|
||||
"/a.ts": `import { B } from "./b.ts";
|
||||
const b: B = { b: "b" };`,
|
||||
"/b.ts": `export interface B {
|
||||
b:string;
|
||||
};`,
|
||||
},
|
||||
compilerOptions: {
|
||||
importsNotUsedAsValues: "error",
|
||||
},
|
||||
});
|
||||
assert(diagnostics);
|
||||
assertEquals(diagnostics.length, 1);
|
||||
assert(diagnostics[0].messageText);
|
||||
assert(diagnostics[0].messageText.includes("This import is never used"));
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - Unknown media type does not panic",
|
||||
async fn() {
|
||||
await Deno.emit("https://example.com/foo", {
|
||||
sources: {
|
||||
"https://example.com/foo": `let foo: string = "foo";`,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - non-normalized specifier and source can compile",
|
||||
async fn() {
|
||||
const specifier = "https://example.com/foo//bar.ts";
|
||||
const { files } = await Deno.emit(specifier, {
|
||||
sources: {
|
||||
[specifier]: `export let foo: string = "foo";`,
|
||||
},
|
||||
});
|
||||
assertEquals(files[`${specifier}.js`], 'export let foo = "foo";\n');
|
||||
assert(typeof files[`${specifier}.js.map`] === "string");
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: `Deno.emit() - bundle as classic script iife`,
|
||||
async fn() {
|
||||
const { diagnostics, files } = await Deno.emit("/a.ts", {
|
||||
bundle: "classic",
|
||||
sources: {
|
||||
"/a.ts": `import { b } from "./b.ts";
|
||||
console.log(b);`,
|
||||
"/b.ts": `export const b = "b";`,
|
||||
},
|
||||
});
|
||||
const ignoreDirecives = [
|
||||
"// deno-fmt-ignore-file",
|
||||
"// deno-lint-ignore-file",
|
||||
"// This code was bundled using `deno bundle` and it's not recommended to edit it manually",
|
||||
"",
|
||||
"",
|
||||
].join("\n");
|
||||
assert(diagnostics);
|
||||
assertEquals(diagnostics.length, 0);
|
||||
assertEquals(Object.keys(files).length, 2);
|
||||
assert(
|
||||
files["deno:///bundle.js"].startsWith(
|
||||
ignoreDirecives + "(function() {\n",
|
||||
),
|
||||
);
|
||||
assert(files["deno:///bundle.js"].endsWith("})();\n"));
|
||||
assert(files["deno:///bundle.js.map"]);
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: `Deno.emit() - throws descriptive error when unable to load import map`,
|
||||
async fn() {
|
||||
await assertRejects(
|
||||
async () => {
|
||||
await Deno.emit("/a.ts", {
|
||||
bundle: "classic",
|
||||
sources: {
|
||||
"/a.ts": `console.log("hello");`,
|
||||
},
|
||||
importMapPath: "file:///import_map_does_not_exist.json",
|
||||
});
|
||||
},
|
||||
Error,
|
||||
"Unable to load 'file:///import_map_does_not_exist.json' import map",
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: `Deno.emit() - support source maps with bundle option`,
|
||||
async fn() {
|
||||
{
|
||||
const { diagnostics, files } = await Deno.emit("/a.ts", {
|
||||
bundle: "classic",
|
||||
sources: {
|
||||
"/a.ts": `import { b } from "./b.ts";
|
||||
console.log(b);`,
|
||||
"/b.ts": `export const b = "b";`,
|
||||
},
|
||||
compilerOptions: {
|
||||
inlineSourceMap: true,
|
||||
sourceMap: false,
|
||||
},
|
||||
});
|
||||
assert(diagnostics);
|
||||
assertEquals(diagnostics.length, 0);
|
||||
assertEquals(Object.keys(files).length, 1);
|
||||
assertStringIncludes(files["deno:///bundle.js"], "sourceMappingURL");
|
||||
}
|
||||
|
||||
const { diagnostics, files } = await Deno.emit("/a.ts", {
|
||||
bundle: "classic",
|
||||
sources: {
|
||||
"/a.ts": `import { b } from "./b.ts";
|
||||
console.log(b);`,
|
||||
"/b.ts": `export const b = "b";`,
|
||||
},
|
||||
});
|
||||
assert(diagnostics);
|
||||
assertEquals(diagnostics.length, 0);
|
||||
assertEquals(Object.keys(files).length, 2);
|
||||
assert(files["deno:///bundle.js"]);
|
||||
assert(files["deno:///bundle.js.map"]);
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: `Deno.emit() - graph errors as diagnostics`,
|
||||
ignore: Deno.build.os === "windows",
|
||||
async fn() {
|
||||
const { diagnostics } = await Deno.emit("/a.ts", {
|
||||
sources: {
|
||||
"/a.ts": `import { b } from "./b.ts";
|
||||
console.log(b);`,
|
||||
},
|
||||
});
|
||||
assert(diagnostics);
|
||||
assertEquals(diagnostics, [
|
||||
{
|
||||
category: 1,
|
||||
code: 2305,
|
||||
start: { line: 0, character: 9 },
|
||||
end: { line: 0, character: 10 },
|
||||
messageText:
|
||||
`Module '"deno:///missing_dependency.d.ts"' has no exported member 'b'.`,
|
||||
messageChain: null,
|
||||
source: null,
|
||||
sourceLine: 'import { b } from "./b.ts";',
|
||||
fileName: "file:///a.ts",
|
||||
relatedInformation: null,
|
||||
},
|
||||
{
|
||||
category: 1,
|
||||
code: 900001,
|
||||
start: null,
|
||||
end: null,
|
||||
messageText: 'Module not found "file:///b.ts".',
|
||||
messageChain: null,
|
||||
source: null,
|
||||
sourceLine: null,
|
||||
fileName: "file:///b.ts",
|
||||
relatedInformation: null,
|
||||
},
|
||||
]);
|
||||
assert(
|
||||
Deno.formatDiagnostics(diagnostics).includes(
|
||||
'Module not found "file:///b.ts".',
|
||||
),
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - no check respects inlineSources compiler option",
|
||||
async fn() {
|
||||
const { files } = await Deno.emit(
|
||||
"file:///a.ts",
|
||||
{
|
||||
check: false,
|
||||
compilerOptions: {
|
||||
types: ["file:///b.d.ts"],
|
||||
inlineSources: true,
|
||||
},
|
||||
sources: {
|
||||
"file:///a.ts": `const b = new B();
|
||||
console.log(b.b);`,
|
||||
"file:///b.d.ts": `declare class B {
|
||||
b: string;
|
||||
}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
const sourceMap: { sourcesContent?: string[] } = JSON.parse(
|
||||
files["file:///a.ts.js.map"],
|
||||
);
|
||||
assert(sourceMap.sourcesContent);
|
||||
assertEquals(sourceMap.sourcesContent.length, 1);
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - JSX import source pragma",
|
||||
async fn() {
|
||||
const { files } = await Deno.emit(
|
||||
"file:///a.tsx",
|
||||
{
|
||||
sources: {
|
||||
"file:///a.tsx": `/** @jsxImportSource https://example.com/jsx */
|
||||
|
||||
export function App() {
|
||||
return (
|
||||
<div><></></div>
|
||||
);
|
||||
}`,
|
||||
"https://example.com/jsx/jsx-runtime": `export function jsx(
|
||||
_type,
|
||||
_props,
|
||||
_key,
|
||||
_source,
|
||||
_self,
|
||||
) {}
|
||||
export const jsxs = jsx;
|
||||
export const jsxDEV = jsx;
|
||||
export const Fragment = Symbol("Fragment");
|
||||
console.log("imported", import.meta.url);
|
||||
`,
|
||||
},
|
||||
},
|
||||
);
|
||||
assert(files["file:///a.tsx.js"]);
|
||||
assert(
|
||||
files["file:///a.tsx.js"].startsWith(
|
||||
`import { Fragment as _Fragment, jsx as _jsx } from "https://example.com/jsx/jsx-runtime";\n`,
|
||||
),
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - JSX import source no pragma",
|
||||
async fn() {
|
||||
const { files } = await Deno.emit(
|
||||
"file:///a.tsx",
|
||||
{
|
||||
compilerOptions: {
|
||||
jsx: "react-jsx",
|
||||
jsxImportSource: "https://example.com/jsx",
|
||||
},
|
||||
sources: {
|
||||
"file:///a.tsx": `export function App() {
|
||||
return (
|
||||
<div><></></div>
|
||||
);
|
||||
}`,
|
||||
"https://example.com/jsx/jsx-runtime": `export function jsx(
|
||||
_type,
|
||||
_props,
|
||||
_key,
|
||||
_source,
|
||||
_self,
|
||||
) {}
|
||||
export const jsxs = jsx;
|
||||
export const jsxDEV = jsx;
|
||||
export const Fragment = Symbol("Fragment");
|
||||
console.log("imported", import.meta.url);
|
||||
`,
|
||||
},
|
||||
},
|
||||
);
|
||||
assert(files["file:///a.tsx.js"]);
|
||||
assert(
|
||||
files["file:///a.tsx.js"].startsWith(
|
||||
`import { Fragment as _Fragment, jsx as _jsx } from "https://example.com/jsx/jsx-runtime";\n`,
|
||||
),
|
||||
);
|
||||
},
|
||||
});
|
4
cli/tests/testdata/issue12453.js
vendored
4
cli/tests/testdata/issue12453.js
vendored
|
@ -1,4 +0,0 @@
|
|||
const i = setInterval(() => {
|
||||
Deno.emit("http://localhost:4545/subdir/mt_text_typescript.t1.ts");
|
||||
clearInterval(i);
|
||||
}, 1);
|
23
cli/tests/testdata/lib_dom_asynciterable.ts
vendored
23
cli/tests/testdata/lib_dom_asynciterable.ts
vendored
|
@ -1,23 +0,0 @@
|
|||
const { diagnostics, files } = await Deno.emit("/main.ts", {
|
||||
compilerOptions: {
|
||||
target: "esnext",
|
||||
lib: ["esnext", "dom", "dom.iterable", "dom.asynciterable"],
|
||||
},
|
||||
sources: {
|
||||
"/main.ts": `const rs = new ReadableStream<string>({
|
||||
start(c) {
|
||||
c.enqueue("hello");
|
||||
c.enqueue("deno");
|
||||
c.close();
|
||||
}
|
||||
});
|
||||
|
||||
for await (const s of rs) {
|
||||
console.log("s");
|
||||
}
|
||||
`,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(diagnostics);
|
||||
console.log(Object.keys(files).sort());
|
|
@ -1,2 +0,0 @@
|
|||
[]
|
||||
[ "[WILDCARD]/main.ts.js", "[WILDCARD]/main.ts.js.map" ]
|
17
cli/tests/testdata/lib_dom_extras.ts
vendored
17
cli/tests/testdata/lib_dom_extras.ts
vendored
|
@ -1,17 +0,0 @@
|
|||
const { diagnostics, files } = await Deno.emit("/main.ts", {
|
||||
compilerOptions: {
|
||||
target: "esnext",
|
||||
lib: ["esnext", "dom"],
|
||||
},
|
||||
sources: {
|
||||
"/main.ts": `const as = new AbortSignal();
|
||||
console.log(as.reason);
|
||||
|
||||
const up = new URLPattern("https://example.com/books/:id");
|
||||
console.log(up);
|
||||
`,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(diagnostics);
|
||||
console.log(Object.keys(files).sort());
|
2
cli/tests/testdata/lib_dom_extras.ts.out
vendored
2
cli/tests/testdata/lib_dom_extras.ts.out
vendored
|
@ -1,2 +0,0 @@
|
|||
[]
|
||||
[ "[WILDCARD]/main.ts.js", "[WILDCARD]/main.ts.js.map" ]
|
16
cli/tests/testdata/lib_ref.ts
vendored
16
cli/tests/testdata/lib_ref.ts
vendored
|
@ -1,16 +0,0 @@
|
|||
const { diagnostics, files } = await Deno.emit(
|
||||
"/main.ts",
|
||||
{
|
||||
sources: {
|
||||
"/main.ts":
|
||||
`/// <reference lib="dom" />\n\ndocument.getElementById("foo");\nDeno.args;`,
|
||||
},
|
||||
compilerOptions: {
|
||||
target: "es2018",
|
||||
lib: ["es2018", "deno.ns"],
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
console.log(diagnostics);
|
||||
console.log(Object.keys(files).sort());
|
2
cli/tests/testdata/lib_ref.ts.out
vendored
2
cli/tests/testdata/lib_ref.ts.out
vendored
|
@ -1,2 +0,0 @@
|
|||
[]
|
||||
[ "file:///[WILDCARD]main.ts.js", "file:///[WILDCARD]main.ts.js.map" ]
|
14
cli/tests/testdata/lib_runtime_api.ts
vendored
14
cli/tests/testdata/lib_runtime_api.ts
vendored
|
@ -1,14 +0,0 @@
|
|||
const { diagnostics, files } = await Deno.emit(
|
||||
"/main.ts",
|
||||
{
|
||||
sources: {
|
||||
"/main.ts": `document.getElementById("foo");`,
|
||||
},
|
||||
compilerOptions: {
|
||||
lib: ["dom", "esnext"],
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
console.log(diagnostics);
|
||||
console.log(Object.keys(files).sort());
|
2
cli/tests/testdata/lib_runtime_api.ts.out
vendored
2
cli/tests/testdata/lib_runtime_api.ts.out
vendored
|
@ -1,2 +0,0 @@
|
|||
[]
|
||||
[ "file:///[WILDCARD]main.ts.js", "file:///[WILDCARD]main.ts.js.map" ]
|
12
cli/tests/testdata/standalone_compiler_ops.ts
vendored
12
cli/tests/testdata/standalone_compiler_ops.ts
vendored
|
@ -1,12 +0,0 @@
|
|||
const { files } = await Deno.emit("/mod.ts", {
|
||||
bundle: "classic",
|
||||
sources: {
|
||||
"/mod.ts": `import { hello } from "/hello.ts"; console.log(hello);`,
|
||||
"/hello.ts": `export const hello: string = "Hello, Compiler API!"`,
|
||||
},
|
||||
compilerOptions: {
|
||||
sourceMap: false,
|
||||
},
|
||||
});
|
||||
|
||||
eval(files["deno:///bundle.js"]);
|
2
cli/tests/testdata/unstable_worker.ts.out
vendored
2
cli/tests/testdata/unstable_worker.ts.out
vendored
|
@ -1,2 +1,2 @@
|
|||
[Function: query]
|
||||
[Function: emit]
|
||||
[Function: setRaw]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
console.log(Deno.permissions.query);
|
||||
console.log(Deno.emit);
|
||||
console.log(Deno.setRaw);
|
||||
self.onmessage = () => {
|
||||
self.close();
|
||||
};
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
import { assert } from "./test_util.ts";
|
||||
|
||||
Deno.test(function formatDiagnosticBasic() {
|
||||
const fixture: Deno.Diagnostic[] = [
|
||||
{
|
||||
start: {
|
||||
line: 0,
|
||||
character: 0,
|
||||
},
|
||||
end: {
|
||||
line: 0,
|
||||
character: 7,
|
||||
},
|
||||
fileName: "test.ts",
|
||||
messageText:
|
||||
"Cannot find name 'console'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.",
|
||||
sourceLine: `console.log("a");`,
|
||||
category: 1,
|
||||
code: 2584,
|
||||
},
|
||||
];
|
||||
const out = Deno.formatDiagnostics(fixture);
|
||||
assert(out.includes("Cannot find name"));
|
||||
assert(out.includes("test.ts"));
|
||||
});
|
||||
|
||||
Deno.test(function formatDiagnosticError() {
|
||||
let thrown = false;
|
||||
// deno-lint-ignore no-explicit-any
|
||||
const bad = ([{ hello: 123 }] as any) as Deno.Diagnostic[];
|
||||
try {
|
||||
Deno.formatDiagnostics(bad);
|
||||
} catch (e) {
|
||||
assert(e instanceof Deno.errors.InvalidData);
|
||||
thrown = true;
|
||||
}
|
||||
assert(thrown);
|
||||
});
|
|
@ -1,97 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
// @ts-check
|
||||
|
||||
// This file contains the runtime APIs which will dispatch work to the internal
|
||||
// compiler within Deno.
|
||||
"use strict";
|
||||
((window) => {
|
||||
const core = window.Deno.core;
|
||||
const util = window.__bootstrap.util;
|
||||
const {
|
||||
StringPrototypeMatch,
|
||||
PromiseReject,
|
||||
TypeError,
|
||||
} = window.__bootstrap.primordials;
|
||||
|
||||
/**
|
||||
* @typedef {object} ImportMap
|
||||
* @property {Record<string, string>} imports
|
||||
* @property {Record<string, Record<string, string>>=} scopes
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {object} OpEmitRequest
|
||||
* @property {"module" | "classic"=} bundle
|
||||
* @property {boolean=} check
|
||||
* @property {Record<string, any>=} compilerOptions
|
||||
* @property {ImportMap=} importMap
|
||||
* @property {string=} importMapPath
|
||||
* @property {string} rootSpecifier
|
||||
* @property {Record<string, string>=} sources
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef OpEmitResponse
|
||||
* @property {any[]} diagnostics
|
||||
* @property {Record<string, string>} files
|
||||
* @property {string[]=} ignoredOptions
|
||||
* @property {Array<[string, number]>} stats
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {OpEmitRequest} request
|
||||
* @returns {Promise<OpEmitResponse>}
|
||||
*/
|
||||
function opEmit(request) {
|
||||
return core.opAsync("op_emit", request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} specifier
|
||||
* @returns {string}
|
||||
*/
|
||||
function checkRelative(specifier) {
|
||||
return StringPrototypeMatch(
|
||||
specifier,
|
||||
/^([\.\/\\]|https?:\/{2}|file:\/{2}|data:)/,
|
||||
)
|
||||
? specifier
|
||||
: `./${specifier}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} EmitOptions
|
||||
* @property {"module" | "classic"=} bundle
|
||||
* @property {boolean=} check
|
||||
* @property {Record<string, any>=} compilerOptions
|
||||
* @property {ImportMap=} importMap
|
||||
* @property {string=} importMapPath
|
||||
* @property {Record<string, string>=} sources
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {string | URL} rootSpecifier
|
||||
* @param {EmitOptions=} options
|
||||
* @returns {Promise<OpEmitResponse>}
|
||||
*/
|
||||
function emit(rootSpecifier, options = {}) {
|
||||
util.log(`Deno.emit`, { rootSpecifier });
|
||||
if (!rootSpecifier) {
|
||||
return PromiseReject(
|
||||
new TypeError("A root specifier must be supplied."),
|
||||
);
|
||||
}
|
||||
if (!(typeof rootSpecifier === "string")) {
|
||||
rootSpecifier = rootSpecifier.toString();
|
||||
}
|
||||
if (!options.sources) {
|
||||
rootSpecifier = checkRelative(rootSpecifier);
|
||||
}
|
||||
return opEmit({ rootSpecifier, ...options });
|
||||
}
|
||||
|
||||
window.__bootstrap.compilerApi = {
|
||||
emit,
|
||||
};
|
||||
})(this);
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
"use strict";
|
||||
|
||||
((window) => {
|
||||
const core = window.Deno.core;
|
||||
|
||||
function opFormatDiagnostics(diagnostics) {
|
||||
return core.opSync("op_format_diagnostic", diagnostics);
|
||||
}
|
||||
|
||||
window.__bootstrap.errorStack = {
|
||||
opFormatDiagnostics,
|
||||
};
|
||||
})(this);
|
|
@ -116,7 +116,6 @@
|
|||
};
|
||||
|
||||
__bootstrap.denoNsUnstable = {
|
||||
emit: __bootstrap.compilerApi.emit,
|
||||
setRaw: __bootstrap.tty.setRaw,
|
||||
consoleSize: __bootstrap.tty.consoleSize,
|
||||
DiagnosticCategory: __bootstrap.diagnostics.DiagnosticCategory,
|
||||
|
@ -126,7 +125,6 @@
|
|||
systemMemoryInfo: __bootstrap.os.systemMemoryInfo,
|
||||
networkInterfaces: __bootstrap.os.networkInterfaces,
|
||||
getUid: __bootstrap.os.getUid,
|
||||
formatDiagnostics: __bootstrap.errorStack.opFormatDiagnostics,
|
||||
sleepSync: __bootstrap.timers.sleepSync,
|
||||
listen: __bootstrap.netUnstable.listen,
|
||||
connect: __bootstrap.netUnstable.connect,
|
||||
|
|
Loading…
Reference in a new issue