├── testdata
├── external.ts
├── error_with_bare_import.ts
├── subdir
│ ├── foo.js
│ ├── foo.ts
│ ├── foo2.ts
│ ├── print_hello.ts
│ ├── escape.json
│ ├── circular2.ts
│ ├── object.json
│ ├── app.jsx
│ ├── mod2.ts
│ └── more_decorators.ts
├── hello_world.ts
├── js_module.js
├── jsx
│ └── main.tsx
├── top_level_await.ts
├── import_map
│ ├── main.ts
│ └── import_map.json
├── jsx_import_from_ts.ts
├── json_import.ts
├── json_import_escape.ts
├── shebang.ts
├── circular1.ts
├── exports_with_alias.ts
├── mod1.ts
├── es_decorators.ts
└── ts_decorators.ts
├── tests
├── __snapshots__
│ ├── common
│ │ ├── external
│ │ │ ├── bundle.js
│ │ │ └── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── local
│ │ │ │ └── external.ts
│ │ │ │ └── modules.json
│ │ ├── hello_world
│ │ │ ├── bundle.js
│ │ │ └── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── local
│ │ │ │ └── hello_world.ts
│ │ │ │ └── modules.json
│ │ ├── js
│ │ │ ├── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── local
│ │ │ │ │ ├── subdir
│ │ │ │ │ │ └── foo.js
│ │ │ │ │ └── js_module.js
│ │ │ │ └── modules.json
│ │ │ └── bundle.js
│ │ ├── load_override
│ │ │ ├── bundle.js
│ │ │ └── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── local
│ │ │ │ └── src.ts
│ │ │ │ └── modules.json
│ │ ├── exports
│ │ │ ├── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── local
│ │ │ │ │ ├── subdir
│ │ │ │ │ │ ├── print_hello.ts
│ │ │ │ │ │ └── mod2.ts
│ │ │ │ │ └── mod1.ts
│ │ │ │ └── modules.json
│ │ │ └── bundle.js
│ │ ├── file_url_as_object
│ │ │ ├── bundle.js
│ │ │ └── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── local
│ │ │ │ └── hello_world.ts
│ │ │ │ └── modules.json
│ │ ├── file_url_as_string
│ │ │ ├── bundle.js
│ │ │ └── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── local
│ │ │ │ └── hello_world.ts
│ │ │ │ └── modules.json
│ │ ├── es_decorators
│ │ │ └── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── modules.json
│ │ │ │ └── local
│ │ │ │ └── subdir
│ │ │ │ └── more_decorators.ts
│ │ ├── ts_decorators
│ │ │ ├── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── modules.json
│ │ │ │ └── local
│ │ │ │ │ ├── subdir
│ │ │ │ │ └── more_decorators.ts
│ │ │ │ │ └── ts_decorators.ts
│ │ │ └── bundle.js
│ │ ├── hello_world_relative_path
│ │ │ ├── bundle.js
│ │ │ └── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── local
│ │ │ │ └── hello_world.ts
│ │ │ │ └── modules.json
│ │ ├── jsx_import_from_ts
│ │ │ ├── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── local
│ │ │ │ │ ├── jsx_import_from_ts.ts
│ │ │ │ │ └── subdir
│ │ │ │ │ │ └── app.jsx
│ │ │ │ └── modules.json
│ │ │ └── bundle.js
│ │ ├── top_level_await
│ │ │ ├── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── local
│ │ │ │ │ └── top_level_await.ts
│ │ │ │ └── modules.json
│ │ │ └── bundle.js
│ │ ├── export_specifier_with_alias
│ │ │ ├── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── local
│ │ │ │ │ ├── subdir
│ │ │ │ │ │ └── foo.ts
│ │ │ │ │ └── exports_with_alias.ts
│ │ │ │ └── modules.json
│ │ │ └── bundle.js
│ │ ├── remote_url_as_object
│ │ │ └── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── remote
│ │ │ │ └── NNRNTa3nQ9cRguYpg8Fa19sQDzU
│ │ │ │ │ └── std@0.140.0
│ │ │ │ │ ├── io
│ │ │ │ │ └── types.d.ts
│ │ │ │ │ ├── path
│ │ │ │ │ ├── _interface.ts
│ │ │ │ │ ├── separator.ts
│ │ │ │ │ ├── mod.ts
│ │ │ │ │ ├── common.ts
│ │ │ │ │ ├── _constants.ts
│ │ │ │ │ ├── _util.ts
│ │ │ │ │ └── glob.ts
│ │ │ │ │ ├── _util
│ │ │ │ │ ├── assert.ts
│ │ │ │ │ └── os.ts
│ │ │ │ │ ├── bytes
│ │ │ │ │ ├── equals.ts
│ │ │ │ │ ├── bytes_list.ts
│ │ │ │ │ └── mod.ts
│ │ │ │ │ └── examples
│ │ │ │ │ └── chat
│ │ │ │ │ └── server.ts
│ │ │ │ └── modules.json
│ │ └── remote_url_as_string
│ │ │ └── transpile
│ │ │ ├── deno.json
│ │ │ ├── remote
│ │ │ └── NNRNTa3nQ9cRguYpg8Fa19sQDzU
│ │ │ │ └── std@0.140.0
│ │ │ │ ├── io
│ │ │ │ └── types.d.ts
│ │ │ │ ├── path
│ │ │ │ ├── _interface.ts
│ │ │ │ ├── separator.ts
│ │ │ │ ├── mod.ts
│ │ │ │ ├── common.ts
│ │ │ │ ├── _constants.ts
│ │ │ │ ├── _util.ts
│ │ │ │ └── glob.ts
│ │ │ │ ├── _util
│ │ │ │ ├── assert.ts
│ │ │ │ └── os.ts
│ │ │ │ ├── bytes
│ │ │ │ ├── equals.ts
│ │ │ │ ├── bytes_list.ts
│ │ │ │ └── mod.ts
│ │ │ │ └── examples
│ │ │ │ └── chat
│ │ │ │ └── server.ts
│ │ │ └── modules.json
│ ├── jsx
│ │ ├── jsx_type_preserve
│ │ │ ├── deno.json
│ │ │ ├── bundle.js
│ │ │ ├── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── local
│ │ │ │ │ └── jsx
│ │ │ │ │ │ └── main.tsx
│ │ │ │ └── modules.json
│ │ │ ├── local
│ │ │ │ └── jsx
│ │ │ │ │ └── main.tsx
│ │ │ └── modules.json
│ │ ├── jsx_type_reactjsx
│ │ │ ├── deno.json
│ │ │ ├── modules.json
│ │ │ └── local
│ │ │ │ └── jsx
│ │ │ │ └── main.tsx
│ │ ├── jsx_default
│ │ │ ├── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── modules.json
│ │ │ │ └── local
│ │ │ │ │ └── jsx
│ │ │ │ │ └── main.tsx
│ │ │ └── bundle.js
│ │ ├── jsx_type_precompile
│ │ │ ├── deno.json
│ │ │ ├── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── modules.json
│ │ │ │ └── local
│ │ │ │ │ └── jsx
│ │ │ │ │ └── main.tsx
│ │ │ ├── modules.json
│ │ │ └── local
│ │ │ │ └── jsx
│ │ │ │ └── main.tsx
│ │ ├── jsx_type_reactnative
│ │ │ ├── bundle.js
│ │ │ └── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── local
│ │ │ │ └── jsx
│ │ │ │ │ └── main.tsx
│ │ │ │ └── modules.json
│ │ ├── jsx_type_react
│ │ │ ├── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── modules.json
│ │ │ │ └── local
│ │ │ │ │ └── jsx
│ │ │ │ │ └── main.tsx
│ │ │ └── bundle.js
│ │ └── jsx_type_reactjsx_with_custom_import_source
│ │ │ ├── deno.json
│ │ │ ├── modules.json
│ │ │ └── local
│ │ │ └── jsx
│ │ │ └── main.tsx
│ ├── import_map
│ │ ├── embedded
│ │ │ ├── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── local
│ │ │ │ │ ├── subdir
│ │ │ │ │ │ └── foo.ts
│ │ │ │ │ └── import_map
│ │ │ │ │ │ └── main.ts
│ │ │ │ └── modules.json
│ │ │ └── bundle.js
│ │ ├── empty_import_map
│ │ │ ├── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── local
│ │ │ │ │ ├── subdir
│ │ │ │ │ │ ├── print_hello.ts
│ │ │ │ │ │ └── mod2.ts
│ │ │ │ │ └── mod1.ts
│ │ │ │ └── modules.json
│ │ │ └── bundle.js
│ │ ├── embedded_with_specific_base_url
│ │ │ ├── bundle.js
│ │ │ └── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── local
│ │ │ │ ├── subdir
│ │ │ │ │ └── foo.ts
│ │ │ │ └── import_map
│ │ │ │ │ └── main.ts
│ │ │ │ └── modules.json
│ │ ├── local_file_set_as_absolute_path
│ │ │ ├── bundle.js
│ │ │ └── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── local
│ │ │ │ ├── subdir
│ │ │ │ │ └── foo.ts
│ │ │ │ └── import_map
│ │ │ │ │ └── main.ts
│ │ │ │ └── modules.json
│ │ ├── local_file_set_as_file_url_object
│ │ │ ├── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── local
│ │ │ │ │ ├── subdir
│ │ │ │ │ │ └── foo.ts
│ │ │ │ │ └── import_map
│ │ │ │ │ │ └── main.ts
│ │ │ │ └── modules.json
│ │ │ └── bundle.js
│ │ ├── local_file_set_as_file_url_string
│ │ │ ├── transpile
│ │ │ │ ├── deno.json
│ │ │ │ ├── local
│ │ │ │ │ ├── subdir
│ │ │ │ │ │ └── foo.ts
│ │ │ │ │ └── import_map
│ │ │ │ │ │ └── main.ts
│ │ │ │ └── modules.json
│ │ │ └── bundle.js
│ │ └── local_file_set_as_relative_path
│ │ │ ├── bundle.js
│ │ │ └── transpile
│ │ │ ├── deno.json
│ │ │ ├── local
│ │ │ ├── subdir
│ │ │ │ └── foo.ts
│ │ │ └── import_map
│ │ │ │ └── main.ts
│ │ │ └── modules.json
│ └── bundle
│ │ ├── circular.js
│ │ ├── json_import_escape.js
│ │ ├── minified_json_import.js
│ │ └── json_import.js
├── jsx_test.ts
├── bundle_test.ts
├── import_map_test.ts
├── common_test.ts
└── source_map_test.ts
├── rust-toolchain.toml
├── .gitattributes
├── .gitignore
├── .rustfmt.toml
├── js
├── deno.json
├── README.md
├── _utils.ts
├── emit.generated.d.ts
└── mod.ts
├── deno.jsonc
├── Cargo.toml
├── rs-lib
├── Cargo.toml
└── src
│ ├── bundle_hook.rs
│ ├── text.rs
│ └── lib.rs
├── wasm
├── Cargo.toml
└── src
│ └── lib.rs
├── README.md
├── .github
└── workflows
│ ├── release.yml
│ └── ci.yml
└── LICENSE
/testdata/external.ts:
--------------------------------------------------------------------------------
1 | import "node:fs";
2 |
--------------------------------------------------------------------------------
/testdata/error_with_bare_import.ts:
--------------------------------------------------------------------------------
1 | import "foo";
2 |
--------------------------------------------------------------------------------
/testdata/subdir/foo.js:
--------------------------------------------------------------------------------
1 | export const foo = "foo";
2 |
--------------------------------------------------------------------------------
/testdata/hello_world.ts:
--------------------------------------------------------------------------------
1 | console.log("Hello world!");
2 |
--------------------------------------------------------------------------------
/testdata/subdir/foo.ts:
--------------------------------------------------------------------------------
1 | export const foo: string = "foo";
2 |
--------------------------------------------------------------------------------
/testdata/subdir/foo2.ts:
--------------------------------------------------------------------------------
1 | export const foo: string = "foo2";
2 |
--------------------------------------------------------------------------------
/testdata/js_module.js:
--------------------------------------------------------------------------------
1 | export { foo } from "./subdir/foo.js";
2 |
--------------------------------------------------------------------------------
/testdata/jsx/main.tsx:
--------------------------------------------------------------------------------
1 | const helloWorld =
;
--------------------------------------------------------------------------------
/tests/__snapshots__/common/external/bundle.js:
--------------------------------------------------------------------------------
1 | import "node:fs";
2 |
--------------------------------------------------------------------------------
/testdata/top_level_await.ts:
--------------------------------------------------------------------------------
1 | export const tla = await Promise.resolve("Hello");
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/hello_world/bundle.js:
--------------------------------------------------------------------------------
1 | console.log("Hello world!");
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/js/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/load_override/bundle.js:
--------------------------------------------------------------------------------
1 | console.log("Hello world!");
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_preserve/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_reactjsx/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/testdata/import_map/main.ts:
--------------------------------------------------------------------------------
1 | import { foo } from "foo";
2 |
3 | console.log(foo);
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/exports/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/external/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/external/transpile/local/external.ts:
--------------------------------------------------------------------------------
1 | import "node:fs";
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/file_url_as_object/bundle.js:
--------------------------------------------------------------------------------
1 | console.log("Hello world!");
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/file_url_as_string/bundle.js:
--------------------------------------------------------------------------------
1 | console.log("Hello world!");
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_default/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_precompile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_preserve/bundle.js:
--------------------------------------------------------------------------------
1 | ;
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_reactnative/bundle.js:
--------------------------------------------------------------------------------
1 | ;
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/es_decorators/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/hello_world/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/js/bundle.js:
--------------------------------------------------------------------------------
1 | const foo = "foo";
2 | export { foo as foo };
3 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/js/transpile/local/subdir/foo.js:
--------------------------------------------------------------------------------
1 | export const foo = "foo";
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/load_override/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/ts_decorators/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/embedded/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_preserve/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_react/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/rust-toolchain.toml:
--------------------------------------------------------------------------------
1 | [toolchain]
2 | channel = "1.80.0"
3 | components = [ "clippy", "rustfmt" ]
--------------------------------------------------------------------------------
/testdata/jsx_import_from_ts.ts:
--------------------------------------------------------------------------------
1 | import app from "./subdir/app.jsx";
2 |
3 | console.log(app);
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/file_url_as_object/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/file_url_as_string/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/hello_world_relative_path/bundle.js:
--------------------------------------------------------------------------------
1 | console.log("Hello world!");
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/jsx_import_from_ts/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/load_override/transpile/local/src.ts:
--------------------------------------------------------------------------------
1 | console.log("Hello world!");
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/top_level_await/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/embedded/bundle.js:
--------------------------------------------------------------------------------
1 | const foo = "foo";
2 | console.log(foo);
3 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_precompile/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_reactnative/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 | /tests/__snapshots__/** text eol=lf
3 | /testdata/** text eol=lf
4 |
--------------------------------------------------------------------------------
/testdata/subdir/print_hello.ts:
--------------------------------------------------------------------------------
1 | export function printHello() {
2 | console.log("Hello");
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/hello_world/transpile/local/hello_world.ts:
--------------------------------------------------------------------------------
1 | console.log("Hello world!");
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/js/transpile/local/js_module.js:
--------------------------------------------------------------------------------
1 | export { foo } from "./subdir/foo.js";
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/embedded/transpile/local/subdir/foo.ts:
--------------------------------------------------------------------------------
1 | export const foo = "foo";
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/empty_import_map/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/testdata/import_map/import_map.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {
3 | "foo": "../subdir/foo.ts"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/export_specifier_with_alias/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/hello_world_relative_path/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/file_url_as_object/transpile/local/hello_world.ts:
--------------------------------------------------------------------------------
1 | console.log("Hello world!");
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/file_url_as_string/transpile/local/hello_world.ts:
--------------------------------------------------------------------------------
1 | console.log("Hello world!");
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_default/bundle.js:
--------------------------------------------------------------------------------
1 | React.createElement("div", {
2 | id: "helloWorld"
3 | });
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_preserve/local/jsx/main.tsx:
--------------------------------------------------------------------------------
1 | const helloWorld = ;
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_reactjsx_with_custom_import_source/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/export_specifier_with_alias/transpile/local/subdir/foo.ts:
--------------------------------------------------------------------------------
1 | export const foo = "foo";
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/hello_world_relative_path/transpile/local/hello_world.ts:
--------------------------------------------------------------------------------
1 | console.log("Hello world!");
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/load_override/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///src.ts": "local/src.ts"
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/embedded_with_specific_base_url/bundle.js:
--------------------------------------------------------------------------------
1 | const foo = "foo";
2 | console.log(foo);
3 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/embedded_with_specific_base_url/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/local_file_set_as_absolute_path/bundle.js:
--------------------------------------------------------------------------------
1 | const foo = "foo";
2 | console.log(foo);
3 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/local_file_set_as_absolute_path/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/local_file_set_as_file_url_object/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/local_file_set_as_file_url_string/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/local_file_set_as_relative_path/bundle.js:
--------------------------------------------------------------------------------
1 | const foo = "foo";
2 | console.log(foo);
3 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/local_file_set_as_relative_path/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {}
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_preserve/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///jsx/main.tsx": "local/jsx/main.tsx"
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_react/bundle.js:
--------------------------------------------------------------------------------
1 | React.createElement("div", {
2 | id: "helloWorld"
3 | });
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_reactjsx/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///jsx/main.tsx": "local/jsx/main.tsx"
3 | }
4 |
--------------------------------------------------------------------------------
/testdata/json_import.ts:
--------------------------------------------------------------------------------
1 | import json from "./subdir/object.json" assert { type: "json" };
2 |
3 | console.log(json);
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/external/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///external.ts": "local/external.ts"
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/embedded_with_specific_base_url/transpile/local/subdir/foo.ts:
--------------------------------------------------------------------------------
1 | export const foo = "foo";
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/local_file_set_as_absolute_path/transpile/local/subdir/foo.ts:
--------------------------------------------------------------------------------
1 | export const foo = "foo";
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/local_file_set_as_file_url_object/bundle.js:
--------------------------------------------------------------------------------
1 | const foo = "foo";
2 | console.log(foo);
3 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/local_file_set_as_file_url_string/bundle.js:
--------------------------------------------------------------------------------
1 | const foo = "foo";
2 | console.log(foo);
3 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/local_file_set_as_relative_path/transpile/local/subdir/foo.ts:
--------------------------------------------------------------------------------
1 | export const foo = "foo";
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_default/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///jsx/main.tsx": "local/jsx/main.tsx"
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_precompile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///jsx/main.tsx": "local/jsx/main.tsx"
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_preserve/transpile/local/jsx/main.tsx:
--------------------------------------------------------------------------------
1 | const helloWorld = ;
2 |
--------------------------------------------------------------------------------
/testdata/json_import_escape.ts:
--------------------------------------------------------------------------------
1 | import json from "./subdir/escape.json" assert { type: "json" };
2 |
3 | console.log(json);
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/hello_world/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///hello_world.ts": "local/hello_world.ts"
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/top_level_await/bundle.js:
--------------------------------------------------------------------------------
1 | const tla = await Promise.resolve("Hello");
2 | export { tla as tla };
3 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/embedded/transpile/local/import_map/main.ts:
--------------------------------------------------------------------------------
1 | import { foo } from "foo";
2 | console.log(foo);
3 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/local_file_set_as_file_url_object/transpile/local/subdir/foo.ts:
--------------------------------------------------------------------------------
1 | export const foo = "foo";
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/local_file_set_as_file_url_string/transpile/local/subdir/foo.ts:
--------------------------------------------------------------------------------
1 | export const foo = "foo";
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_preserve/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///jsx/main.tsx": "local/jsx/main.tsx"
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_react/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///jsx/main.tsx": "local/jsx/main.tsx"
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_reactnative/transpile/local/jsx/main.tsx:
--------------------------------------------------------------------------------
1 | const helloWorld = ;
2 |
--------------------------------------------------------------------------------
/testdata/subdir/escape.json:
--------------------------------------------------------------------------------
1 | "a value with newline\n, \"double quotes\", 'single quotes', ${jsInterpolation} and `string literal`"
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/top_level_await/transpile/local/top_level_await.ts:
--------------------------------------------------------------------------------
1 | export const tla = await Promise.resolve("Hello");
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_precompile/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///jsx/main.tsx": "local/jsx/main.tsx"
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_reactnative/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///jsx/main.tsx": "local/jsx/main.tsx"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /rs-lib/target
3 | /wasm/target
4 | .vscode/
5 | /js/LICENSE
6 | /js/emit_bg.wasm
7 | /js/emit.generated.js
8 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/file_url_as_object/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///hello_world.ts": "local/hello_world.ts"
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/file_url_as_string/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///hello_world.ts": "local/hello_world.ts"
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/exports/transpile/local/subdir/print_hello.ts:
--------------------------------------------------------------------------------
1 | export function printHello() {
2 | console.log("Hello");
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/hello_world_relative_path/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///hello_world.ts": "local/hello_world.ts"
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/top_level_await/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///top_level_await.ts": "local/top_level_await.ts"
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_reactjsx_with_custom_import_source/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///jsx/main.tsx": "local/jsx/main.tsx"
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/jsx_import_from_ts/transpile/local/jsx_import_from_ts.ts:
--------------------------------------------------------------------------------
1 | import app from "./subdir/app.jsx";
2 | console.log(app);
3 |
--------------------------------------------------------------------------------
/.rustfmt.toml:
--------------------------------------------------------------------------------
1 | # Copyright 2020-2021 the Deno authors. All rights reserved. MIT license.
2 | max_width = 80
3 | tab_spaces = 2
4 | edition = "2018"
5 |
--------------------------------------------------------------------------------
/testdata/shebang.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env -S deno run --allow-read
2 |
3 | for (const item of Deno.readDirSync(".")) {
4 | console.log(item.name);
5 | }
6 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/embedded_with_specific_base_url/transpile/local/import_map/main.ts:
--------------------------------------------------------------------------------
1 | import { foo } from "foo";
2 | console.log(foo);
3 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/local_file_set_as_absolute_path/transpile/local/import_map/main.ts:
--------------------------------------------------------------------------------
1 | import { foo } from "foo";
2 | console.log(foo);
3 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/local_file_set_as_file_url_object/transpile/local/import_map/main.ts:
--------------------------------------------------------------------------------
1 | import { foo } from "foo";
2 | console.log(foo);
3 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/local_file_set_as_file_url_string/transpile/local/import_map/main.ts:
--------------------------------------------------------------------------------
1 | import { foo } from "foo";
2 | console.log(foo);
3 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/local_file_set_as_relative_path/transpile/local/import_map/main.ts:
--------------------------------------------------------------------------------
1 | import { foo } from "foo";
2 | console.log(foo);
3 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/empty_import_map/transpile/local/subdir/print_hello.ts:
--------------------------------------------------------------------------------
1 | export function printHello() {
2 | console.log("Hello");
3 | }
4 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_default/transpile/local/jsx/main.tsx:
--------------------------------------------------------------------------------
1 | const helloWorld = /*#__PURE__*/ React.createElement("div", {
2 | id: "helloWorld"
3 | });
4 |
--------------------------------------------------------------------------------
/testdata/circular1.ts:
--------------------------------------------------------------------------------
1 | import * as circular2 from "./subdir/circular2.ts";
2 |
3 | export function f1() {
4 | console.log("f1");
5 | }
6 |
7 | circular2.f2();
8 |
--------------------------------------------------------------------------------
/testdata/subdir/circular2.ts:
--------------------------------------------------------------------------------
1 | import * as circular1 from "../circular1.ts";
2 |
3 | export function f2() {
4 | console.log("f2");
5 | }
6 |
7 | circular1.f1();
8 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/export_specifier_with_alias/bundle.js:
--------------------------------------------------------------------------------
1 | const foo = "foo";
2 | export { foo as test1 };
3 | export { foo as test2 };
4 | console.log(foo);
5 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_react/transpile/local/jsx/main.tsx:
--------------------------------------------------------------------------------
1 | const helloWorld = /*#__PURE__*/ React.createElement("div", {
2 | id: "helloWorld"
3 | });
4 |
--------------------------------------------------------------------------------
/testdata/subdir/object.json:
--------------------------------------------------------------------------------
1 | {
2 | "$var": { "a": 123, "b": [1, 2, 3], "c": null },
3 | "with space": "invalid variable name",
4 | "function": "reserved word"
5 | }
6 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/js/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///js_module.js": "local/js_module.js",
3 | "file:///subdir/foo.js": "local/subdir/foo.js"
4 | }
5 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_object/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {
3 | "https://deno.land": "./remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_string/transpile/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {
3 | "https://deno.land": "./remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/embedded/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///import_map/main.ts": "local/import_map/main.ts",
3 | "file:///subdir/foo.ts": "local/subdir/foo.ts"
4 | }
5 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_reactjsx/local/jsx/main.tsx:
--------------------------------------------------------------------------------
1 | import { jsx as _jsx } from "/jsx-runtime";
2 | const helloWorld = /*#__PURE__*/ _jsx("div", {
3 | id: "helloWorld"
4 | });
5 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_object/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/io/types.d.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_string/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/io/types.d.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 |
--------------------------------------------------------------------------------
/tests/__snapshots__/bundle/circular.js:
--------------------------------------------------------------------------------
1 | function f1() {
2 | console.log("f1");
3 | }
4 | function f2() {
5 | console.log("f2");
6 | }
7 | f2();
8 | f1();
9 | export { f1 as f1 };
10 |
--------------------------------------------------------------------------------
/testdata/exports_with_alias.ts:
--------------------------------------------------------------------------------
1 | export { foo as test1 } from "./subdir/foo.ts";
2 | export { foo as test2 } from "./subdir/foo.ts";
3 | import { foo } from "./subdir/foo.ts";
4 |
5 | console.log(foo);
6 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/jsx_import_from_ts/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///jsx_import_from_ts.ts": "local/jsx_import_from_ts.ts",
3 | "file:///subdir/app.jsx": "local/subdir/app.jsx"
4 | }
5 |
--------------------------------------------------------------------------------
/testdata/subdir/app.jsx:
--------------------------------------------------------------------------------
1 | const React = {
2 | createElement() {},
3 | };
4 |
5 | export default function app() {
6 | return (
7 |
8 |
asdf
9 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/es_decorators/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///es_decorators.ts": "local/es_decorators.ts",
3 | "file:///subdir/more_decorators.ts": "local/subdir/more_decorators.ts"
4 | }
5 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/export_specifier_with_alias/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///exports_with_alias.ts": "local/exports_with_alias.ts",
3 | "file:///subdir/foo.ts": "local/subdir/foo.ts"
4 | }
5 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/ts_decorators/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///subdir/more_decorators.ts": "local/subdir/more_decorators.ts",
3 | "file:///ts_decorators.ts": "local/ts_decorators.ts"
4 | }
5 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/embedded_with_specific_base_url/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///import_map/main.ts": "local/import_map/main.ts",
3 | "file:///subdir/foo.ts": "local/subdir/foo.ts"
4 | }
5 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/local_file_set_as_absolute_path/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///import_map/main.ts": "local/import_map/main.ts",
3 | "file:///subdir/foo.ts": "local/subdir/foo.ts"
4 | }
5 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/local_file_set_as_file_url_object/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///import_map/main.ts": "local/import_map/main.ts",
3 | "file:///subdir/foo.ts": "local/subdir/foo.ts"
4 | }
5 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/local_file_set_as_file_url_string/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///import_map/main.ts": "local/import_map/main.ts",
3 | "file:///subdir/foo.ts": "local/subdir/foo.ts"
4 | }
5 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/local_file_set_as_relative_path/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///import_map/main.ts": "local/import_map/main.ts",
3 | "file:///subdir/foo.ts": "local/subdir/foo.ts"
4 | }
5 |
--------------------------------------------------------------------------------
/tests/__snapshots__/bundle/json_import_escape.js:
--------------------------------------------------------------------------------
1 | const __default = JSON.parse("\"a value with newline\\n, \\\"double quotes\\\", 'single quotes', ${jsInterpolation} and `string literal`\"");
2 | console.log(__default);
3 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_reactjsx_with_custom_import_source/local/jsx/main.tsx:
--------------------------------------------------------------------------------
1 | import { jsx as _jsx } from "example/jsx-runtime";
2 | const helloWorld = /*#__PURE__*/ _jsx("div", {
3 | id: "helloWorld"
4 | });
5 |
--------------------------------------------------------------------------------
/testdata/subdir/mod2.ts:
--------------------------------------------------------------------------------
1 | import { printHello } from "./print_hello.ts";
2 |
3 | export function returnsFoo(): string {
4 | return "Foo";
5 | }
6 |
7 | export function printHello2() {
8 | printHello();
9 | }
10 |
--------------------------------------------------------------------------------
/tests/__snapshots__/bundle/minified_json_import.js:
--------------------------------------------------------------------------------
1 | const __default=JSON.parse('{\n "$var": { "a": 123, "b": [1, 2, 3], "c": null },\n "with space": "invalid variable name",\n "function": "reserved word"\n}');console.log(__default);
--------------------------------------------------------------------------------
/tests/__snapshots__/common/exports/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///mod1.ts": "local/mod1.ts",
3 | "file:///subdir/mod2.ts": "local/subdir/mod2.ts",
4 | "file:///subdir/print_hello.ts": "local/subdir/print_hello.ts"
5 | }
6 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/exports/transpile/local/subdir/mod2.ts:
--------------------------------------------------------------------------------
1 | import { printHello } from "./print_hello.ts";
2 | export function returnsFoo() {
3 | return "Foo";
4 | }
5 | export function printHello2() {
6 | printHello();
7 | }
8 |
--------------------------------------------------------------------------------
/tests/__snapshots__/bundle/json_import.js:
--------------------------------------------------------------------------------
1 | const __default = JSON.parse("{\n \"$var\": { \"a\": 123, \"b\": [1, 2, 3], \"c\": null },\n \"with space\": \"invalid variable name\",\n \"function\": \"reserved word\"\n}");
2 | console.log(__default);
3 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/jsx_import_from_ts/bundle.js:
--------------------------------------------------------------------------------
1 | const React = {
2 | createElement () {}
3 | };
4 | function app() {
5 | return React.createElement("div", null, React.createElement("h2", null, "asdf"));
6 | }
7 | console.log(app);
8 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/empty_import_map/transpile/local/subdir/mod2.ts:
--------------------------------------------------------------------------------
1 | import { printHello } from "./print_hello.ts";
2 | export function returnsFoo() {
3 | return "Foo";
4 | }
5 | export function printHello2() {
6 | printHello();
7 | }
8 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/empty_import_map/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "file:///mod1.ts": "local/mod1.ts",
3 | "file:///subdir/mod2.ts": "local/subdir/mod2.ts",
4 | "file:///subdir/print_hello.ts": "local/subdir/print_hello.ts"
5 | }
6 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_precompile/local/jsx/main.tsx:
--------------------------------------------------------------------------------
1 | import { jsxTemplate as _jsxTemplate } from "jsx-precompile/jsx-runtime";
2 | const $$_tpl_1 = [
3 | ''
4 | ];
5 | const helloWorld = _jsxTemplate($$_tpl_1);
6 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/export_specifier_with_alias/transpile/local/exports_with_alias.ts:
--------------------------------------------------------------------------------
1 | export { foo as test1 } from "./subdir/foo.ts";
2 | export { foo as test2 } from "./subdir/foo.ts";
3 | import { foo } from "./subdir/foo.ts";
4 | console.log(foo);
5 |
--------------------------------------------------------------------------------
/tests/__snapshots__/jsx/jsx_type_precompile/transpile/local/jsx/main.tsx:
--------------------------------------------------------------------------------
1 | import { jsxTemplate as _jsxTemplate } from "jsx-precompile/jsx-runtime";
2 | const $$_tpl_1 = [
3 | ''
4 | ];
5 | const helloWorld = _jsxTemplate($$_tpl_1);
6 |
--------------------------------------------------------------------------------
/js/deno.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@deno/emit",
3 | "version": "0.0.0",
4 | "exports": "./mod.ts",
5 | "publish": {
6 | "exclude": [
7 | "!**"
8 | ]
9 | },
10 | "imports": {
11 | "@std/path": "jsr:@std/path@^0.223.0"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/jsx_import_from_ts/transpile/local/subdir/app.jsx:
--------------------------------------------------------------------------------
1 | const React = {
2 | createElement () {}
3 | };
4 | export default function app() {
5 | return /*#__PURE__*/ React.createElement("div", null, /*#__PURE__*/ React.createElement("h2", null, "asdf"));
6 | }
7 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_object/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/_interface.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | // This module is browser compatible.
3 | /**
4 | * A parsed path object generated by path.parse() or consumed by path.format().
5 | */
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_string/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/_interface.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | // This module is browser compatible.
3 | /**
4 | * A parsed path object generated by path.parse() or consumed by path.format().
5 | */
--------------------------------------------------------------------------------
/testdata/subdir/more_decorators.ts:
--------------------------------------------------------------------------------
1 | function a() {
2 | console.log("a(): evaluated");
3 | return (
4 | _target: any,
5 | _propertyKey: string,
6 | _descriptor: PropertyDescriptor,
7 | ) => {
8 | console.log("a(): called");
9 | };
10 | }
11 |
12 | export class B {
13 | @a()
14 | method() {
15 | console.log("method");
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_object/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/separator.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | // This module is browser compatible.
3 | import { isWindows } from "../_util/os.ts";
4 | export const SEP = isWindows ? "\\" : "/";
5 | export const SEP_PATTERN = isWindows ? /[\\/]+/ : /\/+/;
6 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_string/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/separator.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | // This module is browser compatible.
3 | import { isWindows } from "../_util/os.ts";
4 | export const SEP = isWindows ? "\\" : "/";
5 | export const SEP_PATTERN = isWindows ? /[\\/]+/ : /\/+/;
6 |
--------------------------------------------------------------------------------
/testdata/mod1.ts:
--------------------------------------------------------------------------------
1 | import { printHello2, returnsFoo } from "./subdir/mod2.ts";
2 |
3 | export function returnsHi(): string {
4 | return "Hi";
5 | }
6 |
7 | export function returnsFoo2(): string {
8 | return returnsFoo();
9 | }
10 |
11 | export function printHello3() {
12 | printHello2();
13 | }
14 |
15 | export function throwsError() {
16 | throw Error("exception from mod1");
17 | }
18 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/exports/transpile/local/mod1.ts:
--------------------------------------------------------------------------------
1 | import { printHello2, returnsFoo } from "./subdir/mod2.ts";
2 | export function returnsHi() {
3 | return "Hi";
4 | }
5 | export function returnsFoo2() {
6 | return returnsFoo();
7 | }
8 | export function printHello3() {
9 | printHello2();
10 | }
11 | export function throwsError() {
12 | throw Error("exception from mod1");
13 | }
14 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/empty_import_map/transpile/local/mod1.ts:
--------------------------------------------------------------------------------
1 | import { printHello2, returnsFoo } from "./subdir/mod2.ts";
2 | export function returnsHi() {
3 | return "Hi";
4 | }
5 | export function returnsFoo2() {
6 | return returnsFoo();
7 | }
8 | export function printHello3() {
9 | printHello2();
10 | }
11 | export function throwsError() {
12 | throw Error("exception from mod1");
13 | }
14 |
--------------------------------------------------------------------------------
/deno.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "lock": false,
3 | "tasks": {
4 | "test": "deno test -A",
5 | "update-snapshots": "deno test -A -- --update",
6 | "build": "cp LICENSE js/LICENSE && deno run -A jsr:@deno/wasmbuild@0.17.1 --out js"
7 | },
8 | "exclude": [
9 | "lib",
10 | "static",
11 | "testdata",
12 | "target",
13 | "tests/__snapshots__"
14 | ],
15 | "imports": {
16 | "@std/path": "jsr:@std/path@^0.223.0"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 | resolver = "2"
3 | members = [
4 | "rs-lib",
5 | "wasm"
6 | ]
7 |
8 | [workspace.dependencies]
9 | anyhow = "1.0.44"
10 | base64 = "0.21.5"
11 | deno_graph = { version = "0.82.0", default-features = false }
12 | deno_ast = { version = "0.42.0", features = ["bundler", "codegen", "proposal", "react", "sourcemap", "transforms", "typescript", "visit", "transpiling"] }
13 | url = { version = "2.3.1" }
14 |
15 | [profile.release]
16 | codegen-units = 1
17 | incremental = true
18 | lto = true
19 | opt-level = "z"
20 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_object/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/_util/assert.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | // This module is browser compatible.
3 | export class DenoStdInternalError extends Error {
4 | constructor(message){
5 | super(message);
6 | this.name = "DenoStdInternalError";
7 | }
8 | }
9 | /** Make an assertion, if not `true`, then throw. */ export function assert(expr, msg = "") {
10 | if (!expr) {
11 | throw new DenoStdInternalError(msg);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_string/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/_util/assert.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | // This module is browser compatible.
3 | export class DenoStdInternalError extends Error {
4 | constructor(message){
5 | super(message);
6 | this.name = "DenoStdInternalError";
7 | }
8 | }
9 | /** Make an assertion, if not `true`, then throw. */ export function assert(expr, msg = "") {
10 | if (!expr) {
11 | throw new DenoStdInternalError(msg);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/testdata/es_decorators.ts:
--------------------------------------------------------------------------------
1 | import { B } from "./subdir/more_decorators.ts";
2 |
3 | function Decorator() {
4 | return function (
5 | target: Record,
6 | propertyKey: string,
7 | descriptor: TypedPropertyDescriptor,
8 | ) {
9 | const originalFn: Function = descriptor.value as Function;
10 | descriptor.value = async function (...args: any[]) {
11 | return await originalFn.apply(this, args);
12 | };
13 | return descriptor;
14 | };
15 | }
16 |
17 | class SomeClass {
18 | @Decorator()
19 | async test() {}
20 | }
21 |
22 | new SomeClass().test();
23 | new B().method();
24 |
--------------------------------------------------------------------------------
/testdata/ts_decorators.ts:
--------------------------------------------------------------------------------
1 | import { B } from "./subdir/more_decorators.ts";
2 |
3 | function Decorator() {
4 | return function (
5 | target: Record,
6 | propertyKey: string,
7 | descriptor: TypedPropertyDescriptor,
8 | ) {
9 | const originalFn: Function = descriptor.value as Function;
10 | descriptor.value = async function (...args: any[]) {
11 | return await originalFn.apply(this, args);
12 | };
13 | return descriptor;
14 | };
15 | }
16 |
17 | class SomeClass {
18 | @Decorator()
19 | async test() {}
20 | }
21 |
22 | new SomeClass().test();
23 | new B().method();
24 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/exports/bundle.js:
--------------------------------------------------------------------------------
1 | function printHello() {
2 | console.log("Hello");
3 | }
4 | function returnsFoo() {
5 | return "Foo";
6 | }
7 | function printHello2() {
8 | printHello();
9 | }
10 | function returnsHi() {
11 | return "Hi";
12 | }
13 | function returnsFoo2() {
14 | return returnsFoo();
15 | }
16 | function printHello3() {
17 | printHello2();
18 | }
19 | function throwsError() {
20 | throw Error("exception from mod1");
21 | }
22 | export { returnsHi as returnsHi };
23 | export { returnsFoo2 as returnsFoo2 };
24 | export { printHello3 as printHello3 };
25 | export { throwsError as throwsError };
26 |
--------------------------------------------------------------------------------
/tests/__snapshots__/import_map/empty_import_map/bundle.js:
--------------------------------------------------------------------------------
1 | function printHello() {
2 | console.log("Hello");
3 | }
4 | function returnsFoo() {
5 | return "Foo";
6 | }
7 | function printHello2() {
8 | printHello();
9 | }
10 | function returnsHi() {
11 | return "Hi";
12 | }
13 | function returnsFoo2() {
14 | return returnsFoo();
15 | }
16 | function printHello3() {
17 | printHello2();
18 | }
19 | function throwsError() {
20 | throw Error("exception from mod1");
21 | }
22 | export { returnsHi as returnsHi };
23 | export { returnsFoo2 as returnsFoo2 };
24 | export { printHello3 as printHello3 };
25 | export { throwsError as throwsError };
26 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_object/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/_util/os.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | // This module is browser compatible.
3 | export const osType = (()=>{
4 | // deno-lint-ignore no-explicit-any
5 | const { Deno } = globalThis;
6 | if (typeof Deno?.build?.os === "string") {
7 | return Deno.build.os;
8 | }
9 | // deno-lint-ignore no-explicit-any
10 | const { navigator } = globalThis;
11 | if (navigator?.appVersion?.includes?.("Win")) {
12 | return "windows";
13 | }
14 | return "linux";
15 | })();
16 | export const isWindows = osType === "windows";
17 | export const isLinux = osType === "linux";
18 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_string/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/_util/os.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | // This module is browser compatible.
3 | export const osType = (()=>{
4 | // deno-lint-ignore no-explicit-any
5 | const { Deno } = globalThis;
6 | if (typeof Deno?.build?.os === "string") {
7 | return Deno.build.os;
8 | }
9 | // deno-lint-ignore no-explicit-any
10 | const { navigator } = globalThis;
11 | if (navigator?.appVersion?.includes?.("Win")) {
12 | return "windows";
13 | }
14 | return "linux";
15 | })();
16 | export const isWindows = osType === "windows";
17 | export const isLinux = osType === "linux";
18 |
--------------------------------------------------------------------------------
/rs-lib/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "deno_emit"
3 | version = "0.46.0"
4 | edition = "2021"
5 | description = "module transpiling and emitting for deno"
6 | homepage = "https://deno.land/"
7 | repository = "https://github.com/denoland/deno_emit"
8 | authors = ["the Deno authors"]
9 | license = "MIT"
10 |
11 | [dependencies]
12 | anyhow = { workspace = true }
13 | base64 = { workspace = true }
14 | deno_ast = { workspace = true }
15 | deno_graph = { workspace = true }
16 | escape8259 = "0.5.2"
17 | futures = "0.3.17"
18 | import_map = "0.20.0"
19 | parking_lot = { version = "0.11.2" }
20 | url = { workspace = true }
21 |
22 | [dev-dependencies]
23 | pretty_assertions = "1.0.0"
24 | tokio = { version = "1.11.0", features = ["full"] }
25 |
--------------------------------------------------------------------------------
/wasm/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "deno_emit_wasm"
3 | version = "0.0.0"
4 | edition = "2021"
5 | description = "module transpiling and emitting for deno"
6 | homepage = "https://deno.land/"
7 | repository = "https://github.com/denoland/deno_emit"
8 | authors = ["the Deno authors"]
9 | license = "MIT"
10 |
11 | [lib]
12 | crate-type = ["cdylib", "rlib"]
13 | name = "emit"
14 |
15 | [dependencies]
16 | anyhow = { workspace = true }
17 | base64 = { workspace = true }
18 | console_error_panic_hook = "0.1.7"
19 | deno_emit = { path = "../rs-lib" }
20 | deno_graph = { workspace = true }
21 | getrandom = { version = "*", features = ["js"] }
22 | js-sys = { version = "=0.3.69" }
23 | serde = { version = "1.0.130", features = ["derive", "rc"] }
24 | url = { workspace = true }
25 | wasm-bindgen = { version = "=0.2.92" }
26 | wasm-bindgen-futures = { version = "=0.4.42" }
27 | serde-wasm-bindgen = "0.5.0"
28 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/ts_decorators/transpile/local/subdir/more_decorators.ts:
--------------------------------------------------------------------------------
1 | function _ts_decorate(decorators, target, key, desc) {
2 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4 | else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5 | return c > 3 && r && Object.defineProperty(target, key, r), r;
6 | }
7 | function a() {
8 | console.log("a(): evaluated");
9 | return (_target, _propertyKey, _descriptor)=>{
10 | console.log("a(): called");
11 | };
12 | }
13 | export class B {
14 | method() {
15 | console.log("method");
16 | }
17 | }
18 | _ts_decorate([
19 | a()
20 | ], B.prototype, "method", null);
21 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_object/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/mod.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | // Copyright the Browserify authors. MIT License.
3 | /**
4 | * Ported mostly from https://github.com/browserify/path-browserify/
5 | * This module is browser compatible.
6 | * @module
7 | */ import { isWindows } from "../_util/os.ts";
8 | import * as _win32 from "./win32.ts";
9 | import * as _posix from "./posix.ts";
10 | const path = isWindows ? _win32 : _posix;
11 | export const win32 = _win32;
12 | export const posix = _posix;
13 | export const { basename, delimiter, dirname, extname, format, fromFileUrl, isAbsolute, join, normalize, parse, relative, resolve, sep, toFileUrl, toNamespacedPath } = path;
14 | export * from "./common.ts";
15 | export { SEP, SEP_PATTERN } from "./separator.ts";
16 | export * from "./_interface.ts";
17 | export * from "./glob.ts";
18 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_string/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/mod.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | // Copyright the Browserify authors. MIT License.
3 | /**
4 | * Ported mostly from https://github.com/browserify/path-browserify/
5 | * This module is browser compatible.
6 | * @module
7 | */ import { isWindows } from "../_util/os.ts";
8 | import * as _win32 from "./win32.ts";
9 | import * as _posix from "./posix.ts";
10 | const path = isWindows ? _win32 : _posix;
11 | export const win32 = _win32;
12 | export const posix = _posix;
13 | export const { basename, delimiter, dirname, extname, format, fromFileUrl, isAbsolute, join, normalize, parse, relative, resolve, sep, toFileUrl, toNamespacedPath } = path;
14 | export * from "./common.ts";
15 | export { SEP, SEP_PATTERN } from "./separator.ts";
16 | export * from "./_interface.ts";
17 | export * from "./glob.ts";
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # deno_emit
2 |
3 | [](https://jsr.io/@deno/emit)
4 |
5 | > [!WARNING]
6 | > `deno emit` is deprecated and not recommended anymore. See
7 | > [this issue](https://github.com/denoland/deno_emit/issues/200) for better
8 | > alternatives.
9 |
10 | Transpile and bundle JavaScript and TypeScript in Deno and Deno Deploy.
11 |
12 | > This is an unstable module, where the API is likely to change over time.
13 |
14 | ## JS API
15 |
16 | See [js/README.md](js/README.md).
17 |
18 | ---
19 |
20 | Copyright 2018-2024 the Deno authors. All rights reserved. MIT License.
21 |
22 | [Build Status - Cirrus]: https://github.com/denoland/deno_emit/workflows/ci/badge.svg?branch=main&event=push
23 | [Build status]: https://github.com/denoland/deno_emit/actions
24 | [Twitter badge]: https://twitter.com/intent/follow?screen_name=deno_land
25 | [Twitter handle]: https://img.shields.io/twitter/follow/deno_land.svg?style=social&label=Follow
26 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/ts_decorators/transpile/local/ts_decorators.ts:
--------------------------------------------------------------------------------
1 | function _ts_decorate(decorators, target, key, desc) {
2 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4 | else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5 | return c > 3 && r && Object.defineProperty(target, key, r), r;
6 | }
7 | import { B } from "./subdir/more_decorators.ts";
8 | function Decorator() {
9 | return function(target, propertyKey, descriptor) {
10 | const originalFn = descriptor.value;
11 | descriptor.value = async function(...args) {
12 | return await originalFn.apply(this, args);
13 | };
14 | return descriptor;
15 | };
16 | }
17 | class SomeClass {
18 | async test() {}
19 | }
20 | _ts_decorate([
21 | Decorator()
22 | ], SomeClass.prototype, "test", null);
23 | new SomeClass().test();
24 | new B().method();
25 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: release
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | releaseKind:
7 | description: "Kind of release"
8 | default: "minor"
9 | type: choice
10 | options:
11 | - patch
12 | - minor
13 | required: true
14 |
15 | jobs:
16 | rust:
17 | name: release
18 | runs-on: ubuntu-latest
19 | timeout-minutes: 30
20 |
21 | steps:
22 | - name: Clone repository
23 | uses: actions/checkout@v4
24 | with:
25 | token: ${{ secrets.DENOBOT_PAT }}
26 |
27 | - uses: denoland/setup-deno@v2
28 | - uses: dsherret/rust-toolchain-file@v1
29 |
30 | - name: Tag and release
31 | env:
32 | GITHUB_TOKEN: ${{ secrets.DENOBOT_PAT }}
33 | GH_WORKFLOW_ACTOR: ${{ github.actor }}
34 | run: |
35 | git config user.email "denobot@users.noreply.github.com"
36 | git config user.name "denobot"
37 | deno run -A https://raw.githubusercontent.com/denoland/automation/0.14.1/tasks/publish_release.ts --${{github.event.inputs.releaseKind}} deno_emit
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018-2024 the Deno authors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/js/README.md:
--------------------------------------------------------------------------------
1 | # emit
2 |
3 | [](https://jsr.io/@deno/emit)
4 |
5 | Transpile and bundle JavaScript and TypeScript in Deno and Deno Deploy.
6 |
7 | > This is an unstable module, where the API is likely to change over time.
8 |
9 | ## Transpiling
10 |
11 | Take individual modules that are JavaScript or TypeScript and emit them in a
12 | transpiled fashion. An example of taking some TypeScript and transpiling to
13 | JavaScript:
14 |
15 | ```ts
16 | import { transpile } from "jsr:@deno/emit";
17 |
18 | const url = new URL("./testdata/mod.ts", import.meta.url);
19 | const result = await transpile(url);
20 |
21 | const code = result.get(url.href);
22 | console.log(code?.includes("export default function hello()"));
23 | ```
24 |
25 | ## Bundle
26 |
27 | Take a root module and all its dependencies and emit a single JavaScript bundle.
28 | This is similar to the functionality provided by `deno bundle` on the Deno
29 | command line. An example:
30 |
31 | ```ts
32 | import { bundle } from "jsr:@deno/emit";
33 | const result = await bundle(
34 | new URL("https://deno.land/std@0.140.0/examples/chat/server.ts"),
35 | );
36 |
37 | const { code } = result;
38 | console.log(code);
39 | ```
40 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_object/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/common.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | // This module is browser compatible.
3 | import { SEP } from "./separator.ts";
4 | /** Determines the common path from a set of paths, using an optional separator,
5 | * which defaults to the OS default separator.
6 | *
7 | * ```ts
8 | * import { common } from "https://deno.land/std@$STD_VERSION/path/mod.ts";
9 | * const p = common([
10 | * "./deno/std/path/mod.ts",
11 | * "./deno/std/fs/mod.ts",
12 | * ]);
13 | * console.log(p); // "./deno/std/"
14 | * ```
15 | */ export function common(paths, sep = SEP) {
16 | const [first = "", ...remaining] = paths;
17 | if (first === "" || remaining.length === 0) {
18 | return first.substring(0, first.lastIndexOf(sep) + 1);
19 | }
20 | const parts = first.split(sep);
21 | let endOfPrefix = parts.length;
22 | for (const path of remaining){
23 | const compare = path.split(sep);
24 | for(let i = 0; i < endOfPrefix; i++){
25 | if (compare[i] !== parts[i]) {
26 | endOfPrefix = i;
27 | }
28 | }
29 | if (endOfPrefix === 0) {
30 | return "";
31 | }
32 | }
33 | const prefix = parts.slice(0, endOfPrefix).join(sep);
34 | return prefix.endsWith(sep) ? prefix : `${prefix}${sep}`;
35 | }
36 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_string/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/common.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | // This module is browser compatible.
3 | import { SEP } from "./separator.ts";
4 | /** Determines the common path from a set of paths, using an optional separator,
5 | * which defaults to the OS default separator.
6 | *
7 | * ```ts
8 | * import { common } from "https://deno.land/std@$STD_VERSION/path/mod.ts";
9 | * const p = common([
10 | * "./deno/std/path/mod.ts",
11 | * "./deno/std/fs/mod.ts",
12 | * ]);
13 | * console.log(p); // "./deno/std/"
14 | * ```
15 | */ export function common(paths, sep = SEP) {
16 | const [first = "", ...remaining] = paths;
17 | if (first === "" || remaining.length === 0) {
18 | return first.substring(0, first.lastIndexOf(sep) + 1);
19 | }
20 | const parts = first.split(sep);
21 | let endOfPrefix = parts.length;
22 | for (const path of remaining){
23 | const compare = path.split(sep);
24 | for(let i = 0; i < endOfPrefix; i++){
25 | if (compare[i] !== parts[i]) {
26 | endOfPrefix = i;
27 | }
28 | }
29 | if (endOfPrefix === 0) {
30 | return "";
31 | }
32 | }
33 | const prefix = parts.slice(0, endOfPrefix).join(sep);
34 | return prefix.endsWith(sep) ? prefix : `${prefix}${sep}`;
35 | }
36 |
--------------------------------------------------------------------------------
/rs-lib/src/bundle_hook.rs:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
2 |
3 | use anyhow::Result;
4 | use deno_ast::swc::ast;
5 | use deno_ast::swc::bundler::Hook;
6 | use deno_ast::swc::bundler::ModuleRecord;
7 | use deno_ast::swc::common::Span;
8 |
9 | /// This contains the logic for Deno to rewrite the `import.meta` when bundling.
10 | pub struct BundleHook;
11 |
12 | impl Hook for BundleHook {
13 | fn get_import_meta_props(
14 | &self,
15 | span: Span,
16 | module_record: &ModuleRecord,
17 | ) -> Result> {
18 | Ok(vec![
19 | ast::KeyValueProp {
20 | key: ast::PropName::Ident(ast::IdentName::new("url".into(), span)),
21 | value: Box::new(ast::Expr::Lit(ast::Lit::Str(ast::Str {
22 | span,
23 | value: module_record.file_name.to_string().into(),
24 | raw: None,
25 | }))),
26 | },
27 | ast::KeyValueProp {
28 | key: ast::PropName::Ident(ast::IdentName::new("main".into(), span)),
29 | value: Box::new(if module_record.is_entry {
30 | ast::Expr::Member(ast::MemberExpr {
31 | span,
32 | obj: Box::new(ast::Expr::MetaProp(ast::MetaPropExpr {
33 | span,
34 | kind: ast::MetaPropKind::ImportMeta,
35 | })),
36 | prop: ast::MemberProp::Ident(ast::IdentName::new(
37 | "main".into(),
38 | span,
39 | )),
40 | })
41 | } else {
42 | ast::Expr::Lit(ast::Lit::Bool(ast::Bool { span, value: false }))
43 | }),
44 | },
45 | ])
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_object/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/bytes/equals.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | // This module is browser compatible.
3 | /** Check whether binary arrays are equal to each other using 8-bit comparisons.
4 | * @private
5 | * @param a first array to check equality
6 | * @param b second array to check equality
7 | */ export function equalsNaive(a, b) {
8 | if (a.length !== b.length) return false;
9 | for(let i = 0; i < b.length; i++){
10 | if (a[i] !== b[i]) return false;
11 | }
12 | return true;
13 | }
14 | /** Check whether binary arrays are equal to each other using 32-bit comparisons.
15 | * @private
16 | * @param a first array to check equality
17 | * @param b second array to check equality
18 | */ export function equalsSimd(a, b) {
19 | if (a.length !== b.length) return false;
20 | const len = a.length;
21 | const compressable = Math.floor(len / 4);
22 | const compressedA = new Uint32Array(a.buffer, 0, compressable);
23 | const compressedB = new Uint32Array(b.buffer, 0, compressable);
24 | for(let i = compressable * 4; i < len; i++){
25 | if (a[i] !== b[i]) return false;
26 | }
27 | for(let i = 0; i < compressedA.length; i++){
28 | if (compressedA[i] !== compressedB[i]) return false;
29 | }
30 | return true;
31 | }
32 | /** Check whether binary arrays are equal to each other.
33 | * @param a first array to check equality
34 | * @param b second array to check equality
35 | */ export function equals(a, b) {
36 | if (a.length < 1000) return equalsNaive(a, b);
37 | return equalsSimd(a, b);
38 | }
39 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_string/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/bytes/equals.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | // This module is browser compatible.
3 | /** Check whether binary arrays are equal to each other using 8-bit comparisons.
4 | * @private
5 | * @param a first array to check equality
6 | * @param b second array to check equality
7 | */ export function equalsNaive(a, b) {
8 | if (a.length !== b.length) return false;
9 | for(let i = 0; i < b.length; i++){
10 | if (a[i] !== b[i]) return false;
11 | }
12 | return true;
13 | }
14 | /** Check whether binary arrays are equal to each other using 32-bit comparisons.
15 | * @private
16 | * @param a first array to check equality
17 | * @param b second array to check equality
18 | */ export function equalsSimd(a, b) {
19 | if (a.length !== b.length) return false;
20 | const len = a.length;
21 | const compressable = Math.floor(len / 4);
22 | const compressedA = new Uint32Array(a.buffer, 0, compressable);
23 | const compressedB = new Uint32Array(b.buffer, 0, compressable);
24 | for(let i = compressable * 4; i < len; i++){
25 | if (a[i] !== b[i]) return false;
26 | }
27 | for(let i = 0; i < compressedA.length; i++){
28 | if (compressedA[i] !== compressedB[i]) return false;
29 | }
30 | return true;
31 | }
32 | /** Check whether binary arrays are equal to each other.
33 | * @param a first array to check equality
34 | * @param b second array to check equality
35 | */ export function equals(a, b) {
36 | if (a.length < 1000) return equalsNaive(a, b);
37 | return equalsSimd(a, b);
38 | }
39 |
--------------------------------------------------------------------------------
/js/_utils.ts:
--------------------------------------------------------------------------------
1 | import { isAbsolute, resolve, toFileUrl } from "@std/path";
2 |
3 | /**
4 | * Resolves a location to its canonical URL object.
5 | * @description
6 | * The JS API is pretty liberal in what it accepts as a file location.
7 | * It can be a URL or a path. The URL can be a URL object or a string, and can
8 | * locate a local file or a remote file. The path can be relative or absolute,
9 | * and can be represented as a POSIX path or a Win32 path, depending on the
10 | * system.
11 | * The Rust API, on the other hand, always expects well-formed URLs, and nothing
12 | * else.
13 | * @param location a URL object, a URL string, an absolute file path or a
14 | * relative file path
15 | * @returns a URL object that matches the location
16 | */
17 | export function locationToUrl(location: URL | string): URL {
18 | if (location instanceof URL) {
19 | // We don't return it directly to ensure that the caller can then safely
20 | // mutate without affecting the original.
21 | return new URL(location);
22 | }
23 | // We attempt to build a URL from the location; if it succeeds, it's great!
24 | // If it does not, we assume that it was probably a file path instead.
25 | try {
26 | // Absolute file paths on Windows can be successfully parsed as URLs, so we
27 | // exclude that case first.
28 | if (!isAbsolute(location)) {
29 | return new URL(location);
30 | }
31 | } catch (error) {
32 | // Rethrowing errors that have nothing to do with failing to parse the URL.
33 | if (
34 | !(error instanceof TypeError &&
35 | error.message.startsWith("Invalid URL"))
36 | ) {
37 | throw error;
38 | }
39 | }
40 | return toFileUrl(resolve(location));
41 | }
42 |
--------------------------------------------------------------------------------
/tests/jsx_test.ts:
--------------------------------------------------------------------------------
1 | import {
2 | resolveFixture,
3 | testTranspile,
4 | testTranspileAndBundle,
5 | } from "./utils.ts";
6 |
7 | Deno.test({
8 | name: "jsx default",
9 | fn: testTranspileAndBundle(
10 | resolveFixture("jsx/main.tsx"),
11 | ),
12 | });
13 |
14 | Deno.test({
15 | name: "jsx type react",
16 | fn: testTranspileAndBundle(
17 | resolveFixture("jsx/main.tsx"),
18 | {
19 | compilerOptions: {
20 | jsx: "react",
21 | },
22 | },
23 | ),
24 | });
25 |
26 | Deno.test({
27 | name: "jsx type react-native",
28 | fn: testTranspileAndBundle(
29 | resolveFixture("jsx/main.tsx"),
30 | {
31 | compilerOptions: {
32 | jsx: "react-native",
33 | },
34 | },
35 | ),
36 | });
37 |
38 | Deno.test({
39 | name: "jsx type precompile",
40 | fn: testTranspile(
41 | resolveFixture("jsx/main.tsx"),
42 | {
43 | compilerOptions: {
44 | jsx: "precompile",
45 | jsxImportSource: "jsx-precompile",
46 | },
47 | },
48 | ),
49 | });
50 |
51 | Deno.test({
52 | name: "jsx type preserve",
53 | fn: testTranspileAndBundle(
54 | resolveFixture("jsx/main.tsx"),
55 | {
56 | compilerOptions: {
57 | jsx: "preserve",
58 | },
59 | },
60 | ),
61 | });
62 |
63 | Deno.test({
64 | name: "jsx type react-jsx",
65 | fn: testTranspile(
66 | resolveFixture("jsx/main.tsx"),
67 | {
68 | compilerOptions: {
69 | jsx: "react-jsx",
70 | },
71 | },
72 | ),
73 | });
74 |
75 | Deno.test({
76 | name: "jsx type react-jsx with custom import source",
77 | fn: testTranspile(
78 | resolveFixture("jsx/main.tsx"),
79 | {
80 | compilerOptions: {
81 | jsx: "react-jsx",
82 | jsxImportSource: "example",
83 | },
84 | },
85 | ),
86 | });
87 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/ts_decorators/bundle.js:
--------------------------------------------------------------------------------
1 | function _ts_decorate(decorators, target, key, desc) {
2 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4 | else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5 | return c > 3 && r && Object.defineProperty(target, key, r), r;
6 | }
7 | function a() {
8 | console.log("a(): evaluated");
9 | return (_target, _propertyKey, _descriptor)=>{
10 | console.log("a(): called");
11 | };
12 | }
13 | class B {
14 | method() {
15 | console.log("method");
16 | }
17 | }
18 | _ts_decorate([
19 | a()
20 | ], B.prototype, "method", null);
21 | function _ts_decorate1(decorators, target, key, desc) {
22 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
23 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
24 | else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
25 | return c > 3 && r && Object.defineProperty(target, key, r), r;
26 | }
27 | function Decorator() {
28 | return function(target, propertyKey, descriptor) {
29 | const originalFn = descriptor.value;
30 | descriptor.value = async function(...args) {
31 | return await originalFn.apply(this, args);
32 | };
33 | return descriptor;
34 | };
35 | }
36 | class SomeClass {
37 | async test() {}
38 | }
39 | _ts_decorate1([
40 | Decorator()
41 | ], SomeClass.prototype, "test", null);
42 | new SomeClass().test();
43 | new B().method();
44 |
--------------------------------------------------------------------------------
/js/emit.generated.d.ts:
--------------------------------------------------------------------------------
1 | // deno-lint-ignore-file
2 | // deno-fmt-ignore-file
3 |
4 | export interface InstantiateResult {
5 | instance: WebAssembly.Instance;
6 | exports: {
7 | bundle: typeof bundle;
8 | transpile: typeof transpile
9 | };
10 | }
11 |
12 | /** Gets if the Wasm module has been instantiated. */
13 | export function isInstantiated(): boolean;
14 |
15 | /** Options for instantiating a Wasm instance. */
16 | export interface InstantiateOptions {
17 | /** Optional url to the Wasm file to instantiate. */
18 | url?: URL;
19 | /** Callback to decompress the raw Wasm file bytes before instantiating. */
20 | decompress?: (bytes: Uint8Array) => Uint8Array;
21 | }
22 |
23 | /** Instantiates an instance of the Wasm module returning its functions.
24 | * @remarks It is safe to call this multiple times and once successfully
25 | * loaded it will always return a reference to the same object. */
26 | export function instantiate(opts?: InstantiateOptions): Promise;
27 |
28 | /** Instantiates an instance of the Wasm module along with its exports.
29 | * @remarks It is safe to call this multiple times and once successfully
30 | * loaded it will always return a reference to the same object. */
31 | export function instantiateWithInstance(opts?: InstantiateOptions): Promise;
32 |
33 | /**
34 | * @param {string} root
35 | * @param {Function} load
36 | * @param {string | undefined} maybe_bundle_type
37 | * @param {any} maybe_import_map
38 | * @param {any} maybe_compiler_options
39 | * @param {boolean} minify
40 | * @returns {Promise}
41 | */
42 | export function bundle(root: string, load: Function, maybe_bundle_type: string | undefined, maybe_import_map: any, maybe_compiler_options: any, minify: boolean): Promise;
43 | /**
44 | * @param {string} root
45 | * @param {Function} load
46 | * @param {any} maybe_import_map
47 | * @param {any} maybe_compiler_options
48 | * @returns {Promise}
49 | */
50 | export function transpile(root: string, load: Function, maybe_import_map: any, maybe_compiler_options: any): Promise;
51 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_object/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "https://deno.land/std@0.140.0/_util/assert.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/_util/assert.ts",
3 | "https://deno.land/std@0.140.0/_util/os.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/_util/os.ts",
4 | "https://deno.land/std@0.140.0/bytes/bytes_list.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/bytes/bytes_list.ts",
5 | "https://deno.land/std@0.140.0/bytes/equals.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/bytes/equals.ts",
6 | "https://deno.land/std@0.140.0/bytes/mod.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/bytes/mod.ts",
7 | "https://deno.land/std@0.140.0/examples/chat/server.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/examples/chat/server.ts",
8 | "https://deno.land/std@0.140.0/io/buffer.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/io/buffer.ts",
9 | "https://deno.land/std@0.140.0/path/_constants.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/_constants.ts",
10 | "https://deno.land/std@0.140.0/path/_interface.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/_interface.ts",
11 | "https://deno.land/std@0.140.0/path/_util.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/_util.ts",
12 | "https://deno.land/std@0.140.0/path/common.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/common.ts",
13 | "https://deno.land/std@0.140.0/path/glob.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/glob.ts",
14 | "https://deno.land/std@0.140.0/path/mod.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/mod.ts",
15 | "https://deno.land/std@0.140.0/path/posix.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/posix.ts",
16 | "https://deno.land/std@0.140.0/path/separator.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/separator.ts",
17 | "https://deno.land/std@0.140.0/path/win32.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/win32.ts",
18 | "https://deno.land/std@0.140.0/streams/conversion.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/streams/conversion.ts"
19 | }
20 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_string/transpile/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "https://deno.land/std@0.140.0/_util/assert.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/_util/assert.ts",
3 | "https://deno.land/std@0.140.0/_util/os.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/_util/os.ts",
4 | "https://deno.land/std@0.140.0/bytes/bytes_list.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/bytes/bytes_list.ts",
5 | "https://deno.land/std@0.140.0/bytes/equals.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/bytes/equals.ts",
6 | "https://deno.land/std@0.140.0/bytes/mod.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/bytes/mod.ts",
7 | "https://deno.land/std@0.140.0/examples/chat/server.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/examples/chat/server.ts",
8 | "https://deno.land/std@0.140.0/io/buffer.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/io/buffer.ts",
9 | "https://deno.land/std@0.140.0/path/_constants.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/_constants.ts",
10 | "https://deno.land/std@0.140.0/path/_interface.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/_interface.ts",
11 | "https://deno.land/std@0.140.0/path/_util.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/_util.ts",
12 | "https://deno.land/std@0.140.0/path/common.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/common.ts",
13 | "https://deno.land/std@0.140.0/path/glob.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/glob.ts",
14 | "https://deno.land/std@0.140.0/path/mod.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/mod.ts",
15 | "https://deno.land/std@0.140.0/path/posix.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/posix.ts",
16 | "https://deno.land/std@0.140.0/path/separator.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/separator.ts",
17 | "https://deno.land/std@0.140.0/path/win32.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/win32.ts",
18 | "https://deno.land/std@0.140.0/streams/conversion.ts": "remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/streams/conversion.ts"
19 | }
20 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: ci
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | rust:
7 | name: deno_emit-${{ matrix.os }}
8 | if: |
9 | github.event_name == 'push' ||
10 | !startsWith(github.event.pull_request.head.label, 'denoland:')
11 | runs-on: ${{ matrix.os }}
12 | timeout-minutes: 30
13 | strategy:
14 | matrix:
15 | os: [macOS-latest, ubuntu-latest, windows-latest]
16 |
17 | env:
18 | CARGO_INCREMENTAL: 0
19 | GH_ACTIONS: 1
20 | RUST_BACKTRACE: full
21 | RUSTFLAGS: -D warnings
22 |
23 | permissions:
24 | contents: read
25 | id-token: write
26 |
27 | steps:
28 | - name: Clone repository
29 | uses: actions/checkout@v4
30 |
31 | - name: Install rust
32 | uses: dsherret/rust-toolchain-file@v1
33 |
34 | - uses: Swatinem/rust-cache@v2
35 | with:
36 | save-if: ${{ github.ref == 'refs/heads/main' }}
37 |
38 | - name: Install up Deno
39 | uses: denoland/setup-deno@v2
40 |
41 | - name: Format
42 | if: contains(matrix.os, 'ubuntu')
43 | run: |
44 | cargo fmt -- --check
45 | deno fmt --check
46 |
47 | - name: Lint
48 | if: contains(matrix.os, 'ubuntu')
49 | run: |
50 | cargo clippy --locked --release --all-features --all-targets -- -D clippy::all
51 | deno lint
52 |
53 | - name: Build
54 | run: deno task build
55 |
56 | - name: Test
57 | run: |
58 | cargo test --locked --release --all-features --all-targets
59 | deno task test
60 |
61 | - name: Cargo publish
62 | if: |
63 | contains(matrix.os, 'ubuntu') &&
64 | github.repository == 'denoland/deno_emit' &&
65 | startsWith(github.ref, 'refs/tags/')
66 | env:
67 | CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
68 | run: |
69 | cargo publish -p deno_emit
70 |
71 | - name: Publish to JSR
72 | if: contains(matrix.os, 'ubuntu')
73 | run: cd js && deno run -A jsr:@david/publish-on-tag@0.1.3
74 |
--------------------------------------------------------------------------------
/rs-lib/src/text.rs:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
2 |
3 | const BOM_CHAR: char = '\u{FEFF}';
4 |
5 | /// Strips the byte order mark from the provided text if it exists.
6 | pub fn strip_bom(text: &str) -> &str {
7 | if text.starts_with(BOM_CHAR) {
8 | &text[BOM_CHAR.len_utf8()..]
9 | } else {
10 | text
11 | }
12 | }
13 |
14 | pub fn transform_json_source(source: &str) -> String {
15 | // Make sure to trim all redundant training newlines,
16 | // and escape all reserved characters per JSON RFC,
17 | // https://www.rfc-editor.org/rfc/rfc8259
18 | let escaped = escape8259::escape(source.trim_end());
19 | format!(r#"export default JSON.parse("{escaped}");"#)
20 | }
21 |
22 | #[cfg(test)]
23 | mod test {
24 | use super::*;
25 |
26 | #[test]
27 | fn strip_bom_with_bom() {
28 | let text = format!("{BOM_CHAR}text");
29 | assert_eq!(strip_bom(&text), "text");
30 | }
31 |
32 | #[test]
33 | fn strip_bom_without_bom() {
34 | let text = "text";
35 | assert_eq!(strip_bom(text), "text");
36 | }
37 |
38 | #[test]
39 | fn transform_json_source_simple() {
40 | let text = r#"{"foo": "bar"}"#;
41 | assert_eq!(
42 | transform_json_source(text),
43 | r#"export default JSON.parse("{\"foo\": \"bar\"}");"#
44 | );
45 | }
46 |
47 | #[test]
48 | fn transform_json_source_escape_newline() {
49 | let text = r#"{"foo": "bar\nbaz"}"#;
50 | assert_eq!(
51 | transform_json_source(text),
52 | r#"export default JSON.parse("{\"foo\": \"bar\\nbaz\"}");"#
53 | );
54 | }
55 |
56 | #[test]
57 | fn transform_json_source_escape_quotes() {
58 | let text = r#"{"foo": "bar \"baz\" 'qux' `quaz`"}"#;
59 | assert_eq!(
60 | transform_json_source(text),
61 | r#"export default JSON.parse("{\"foo\": \"bar \\\"baz\\\" 'qux' `quaz`\"}");"#
62 | );
63 | }
64 |
65 | #[test]
66 | fn transform_json_source_not_escape_string_interpolation() {
67 | let text = r#"{"foo": "bar ${baz}"}"#;
68 | assert_eq!(
69 | transform_json_source(text),
70 | r#"export default JSON.parse("{\"foo\": \"bar ${baz}\"}");"#
71 | );
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/tests/bundle_test.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
2 | import {
3 | assertEquals,
4 | assertStringIncludes,
5 | } from "https://deno.land/std@0.182.0/testing/asserts.ts";
6 | import { resolveFixture, runModule, testBundle } from "./utils.ts";
7 |
8 | Deno.test({
9 | name: "json import",
10 | fn: testBundle(
11 | resolveFixture("json_import.ts"),
12 | undefined,
13 | async ({ outputFileUrl }) => {
14 | const output = await runModule(outputFileUrl);
15 | assertStringIncludes(output, "with space");
16 | },
17 | ),
18 | });
19 |
20 | Deno.test({
21 | name: "json import escape",
22 | fn: testBundle(
23 | resolveFixture("json_import_escape.ts"),
24 | undefined,
25 | async ({ outputFileUrl, result }) => {
26 | const output = await runModule(outputFileUrl);
27 | assertStringIncludes(
28 | output,
29 | "a value with newline\n, \"double quotes\", 'single quotes', ${jsInterpolation} and `string literal`",
30 | );
31 |
32 | // This is done on purpose, as `String.raw` still performs a string interpolation,
33 | // and we want a literal value as is, without any modifications.
34 | // We should not need to escape $, { nor ` as they are JSON-safe characters.
35 | const jsInterpolation = "${jsInterpolation} and `string literal`";
36 | assertStringIncludes(
37 | result.code,
38 | String
39 | .raw`const __default = JSON.parse("\"a value with newline\\n, \\\"double quotes\\\", 'single quotes', ${jsInterpolation}\"");`,
40 | );
41 | },
42 | ),
43 | });
44 |
45 | Deno.test({
46 | name: "minified json import",
47 | fn: testBundle(
48 | resolveFixture("json_import.ts"),
49 | { minify: true },
50 | async ({ outputFileUrl }) => {
51 | const output = await runModule(outputFileUrl);
52 | assertStringIncludes(output, "with space");
53 | },
54 | ),
55 | });
56 |
57 | Deno.test({
58 | name: "circular",
59 | fn: testBundle(
60 | resolveFixture("circular1.ts"),
61 | undefined,
62 | async ({ outputFileUrl }) => {
63 | const output = await runModule(outputFileUrl);
64 | assertEquals(output, "f2\nf1\n");
65 | },
66 | ),
67 | });
68 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_object/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/_constants.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | // Copyright the Browserify authors. MIT License.
3 | // Ported from https://github.com/browserify/path-browserify/
4 | // This module is browser compatible.
5 | // Alphabet chars.
6 | export const CHAR_UPPERCASE_A = 65; /* A */
7 | export const CHAR_LOWERCASE_A = 97; /* a */
8 | export const CHAR_UPPERCASE_Z = 90; /* Z */
9 | export const CHAR_LOWERCASE_Z = 122; /* z */
10 | // Non-alphabetic chars.
11 | export const CHAR_DOT = 46; /* . */
12 | export const CHAR_FORWARD_SLASH = 47; /* / */
13 | export const CHAR_BACKWARD_SLASH = 92; /* \ */
14 | export const CHAR_VERTICAL_LINE = 124; /* | */
15 | export const CHAR_COLON = 58; /* : */
16 | export const CHAR_QUESTION_MARK = 63; /* ? */
17 | export const CHAR_UNDERSCORE = 95; /* _ */
18 | export const CHAR_LINE_FEED = 10; /* \n */
19 | export const CHAR_CARRIAGE_RETURN = 13; /* \r */
20 | export const CHAR_TAB = 9; /* \t */
21 | export const CHAR_FORM_FEED = 12; /* \f */
22 | export const CHAR_EXCLAMATION_MARK = 33; /* ! */
23 | export const CHAR_HASH = 35; /* # */
24 | export const CHAR_SPACE = 32; /* */
25 | export const CHAR_NO_BREAK_SPACE = 160; /* \u00A0 */
26 | export const CHAR_ZERO_WIDTH_NOBREAK_SPACE = 65279; /* \uFEFF */
27 | export const CHAR_LEFT_SQUARE_BRACKET = 91; /* [ */
28 | export const CHAR_RIGHT_SQUARE_BRACKET = 93; /* ] */
29 | export const CHAR_LEFT_ANGLE_BRACKET = 60; /* < */
30 | export const CHAR_RIGHT_ANGLE_BRACKET = 62; /* > */
31 | export const CHAR_LEFT_CURLY_BRACKET = 123; /* { */
32 | export const CHAR_RIGHT_CURLY_BRACKET = 125; /* } */
33 | export const CHAR_HYPHEN_MINUS = 45; /* - */
34 | export const CHAR_PLUS = 43; /* + */
35 | export const CHAR_DOUBLE_QUOTE = 34; /* " */
36 | export const CHAR_SINGLE_QUOTE = 39; /* ' */
37 | export const CHAR_PERCENT = 37; /* % */
38 | export const CHAR_SEMICOLON = 59; /* ; */
39 | export const CHAR_CIRCUMFLEX_ACCENT = 94; /* ^ */
40 | export const CHAR_GRAVE_ACCENT = 96; /* ` */
41 | export const CHAR_AT = 64; /* @ */
42 | export const CHAR_AMPERSAND = 38; /* & */
43 | export const CHAR_EQUAL = 61; /* = */
44 | // Digits
45 | export const CHAR_0 = 48; /* 0 */
46 | export const CHAR_9 = 57; /* 9 */
47 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_string/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/_constants.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | // Copyright the Browserify authors. MIT License.
3 | // Ported from https://github.com/browserify/path-browserify/
4 | // This module is browser compatible.
5 | // Alphabet chars.
6 | export const CHAR_UPPERCASE_A = 65; /* A */
7 | export const CHAR_LOWERCASE_A = 97; /* a */
8 | export const CHAR_UPPERCASE_Z = 90; /* Z */
9 | export const CHAR_LOWERCASE_Z = 122; /* z */
10 | // Non-alphabetic chars.
11 | export const CHAR_DOT = 46; /* . */
12 | export const CHAR_FORWARD_SLASH = 47; /* / */
13 | export const CHAR_BACKWARD_SLASH = 92; /* \ */
14 | export const CHAR_VERTICAL_LINE = 124; /* | */
15 | export const CHAR_COLON = 58; /* : */
16 | export const CHAR_QUESTION_MARK = 63; /* ? */
17 | export const CHAR_UNDERSCORE = 95; /* _ */
18 | export const CHAR_LINE_FEED = 10; /* \n */
19 | export const CHAR_CARRIAGE_RETURN = 13; /* \r */
20 | export const CHAR_TAB = 9; /* \t */
21 | export const CHAR_FORM_FEED = 12; /* \f */
22 | export const CHAR_EXCLAMATION_MARK = 33; /* ! */
23 | export const CHAR_HASH = 35; /* # */
24 | export const CHAR_SPACE = 32; /* */
25 | export const CHAR_NO_BREAK_SPACE = 160; /* \u00A0 */
26 | export const CHAR_ZERO_WIDTH_NOBREAK_SPACE = 65279; /* \uFEFF */
27 | export const CHAR_LEFT_SQUARE_BRACKET = 91; /* [ */
28 | export const CHAR_RIGHT_SQUARE_BRACKET = 93; /* ] */
29 | export const CHAR_LEFT_ANGLE_BRACKET = 60; /* < */
30 | export const CHAR_RIGHT_ANGLE_BRACKET = 62; /* > */
31 | export const CHAR_LEFT_CURLY_BRACKET = 123; /* { */
32 | export const CHAR_RIGHT_CURLY_BRACKET = 125; /* } */
33 | export const CHAR_HYPHEN_MINUS = 45; /* - */
34 | export const CHAR_PLUS = 43; /* + */
35 | export const CHAR_DOUBLE_QUOTE = 34; /* " */
36 | export const CHAR_SINGLE_QUOTE = 39; /* ' */
37 | export const CHAR_PERCENT = 37; /* % */
38 | export const CHAR_SEMICOLON = 59; /* ; */
39 | export const CHAR_CIRCUMFLEX_ACCENT = 94; /* ^ */
40 | export const CHAR_GRAVE_ACCENT = 96; /* ` */
41 | export const CHAR_AT = 64; /* @ */
42 | export const CHAR_AMPERSAND = 38; /* & */
43 | export const CHAR_EQUAL = 61; /* = */
44 | // Digits
45 | export const CHAR_0 = 48; /* 0 */
46 | export const CHAR_9 = 57; /* 9 */
47 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_object/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/examples/chat/server.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | import { fromFileUrl } from "../../path/mod.ts";
3 | import { readableStreamFromReader } from "../../streams/conversion.ts";
4 | const clients = new Map();
5 | let clientId = 0;
6 | function dispatch(msg) {
7 | for (const client of clients.values()){
8 | client.send(msg);
9 | }
10 | }
11 | function wsHandler(ws) {
12 | const id = ++clientId;
13 | clients.set(id, ws);
14 | ws.onopen = ()=>{
15 | dispatch(`Connected: [${id}]`);
16 | };
17 | ws.onmessage = (e)=>{
18 | console.log(`msg:${id}`, e.data);
19 | dispatch(`[${id}]: ${e.data}`);
20 | };
21 | ws.onclose = ()=>{
22 | clients.delete(id);
23 | dispatch(`Closed: [${id}]`);
24 | };
25 | }
26 | async function requestHandler(req) {
27 | const pathname = new URL(req.request.url).pathname;
28 | if (req.request.method === "GET" && pathname === "/") {
29 | //Serve with hack
30 | const u = new URL("./index.html", import.meta.url);
31 | if (u.protocol.startsWith("http")) {
32 | // server launched by deno run http(s)://.../server.ts,
33 | fetch(u.href).then(async (resp)=>{
34 | const body = new Uint8Array(await resp.arrayBuffer());
35 | req.respondWith(new Response(body, {
36 | status: resp.status,
37 | headers: {
38 | "content-type": "text/html"
39 | }
40 | }));
41 | });
42 | } else {
43 | // server launched by deno run ./server.ts
44 | const file = await Deno.open(fromFileUrl(u));
45 | req.respondWith(new Response(readableStreamFromReader(file), {
46 | status: 200,
47 | headers: {
48 | "content-type": "text/html"
49 | }
50 | }));
51 | }
52 | } else if (req.request.method === "GET" && pathname === "/favicon.ico") {
53 | req.respondWith(Response.redirect("https://deno.land/favicon.ico", 302));
54 | } else if (req.request.method === "GET" && pathname === "/ws") {
55 | const { socket, response } = Deno.upgradeWebSocket(req.request);
56 | wsHandler(socket);
57 | req.respondWith(response);
58 | }
59 | }
60 | const server = Deno.listen({
61 | port: 8080
62 | });
63 | console.log("chat server starting on :8080....");
64 | for await (const conn of server){
65 | (async ()=>{
66 | const httpConn = Deno.serveHttp(conn);
67 | for await (const requestEvent of httpConn){
68 | requestHandler(requestEvent);
69 | }
70 | })();
71 | }
72 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_string/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/examples/chat/server.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | import { fromFileUrl } from "../../path/mod.ts";
3 | import { readableStreamFromReader } from "../../streams/conversion.ts";
4 | const clients = new Map();
5 | let clientId = 0;
6 | function dispatch(msg) {
7 | for (const client of clients.values()){
8 | client.send(msg);
9 | }
10 | }
11 | function wsHandler(ws) {
12 | const id = ++clientId;
13 | clients.set(id, ws);
14 | ws.onopen = ()=>{
15 | dispatch(`Connected: [${id}]`);
16 | };
17 | ws.onmessage = (e)=>{
18 | console.log(`msg:${id}`, e.data);
19 | dispatch(`[${id}]: ${e.data}`);
20 | };
21 | ws.onclose = ()=>{
22 | clients.delete(id);
23 | dispatch(`Closed: [${id}]`);
24 | };
25 | }
26 | async function requestHandler(req) {
27 | const pathname = new URL(req.request.url).pathname;
28 | if (req.request.method === "GET" && pathname === "/") {
29 | //Serve with hack
30 | const u = new URL("./index.html", import.meta.url);
31 | if (u.protocol.startsWith("http")) {
32 | // server launched by deno run http(s)://.../server.ts,
33 | fetch(u.href).then(async (resp)=>{
34 | const body = new Uint8Array(await resp.arrayBuffer());
35 | req.respondWith(new Response(body, {
36 | status: resp.status,
37 | headers: {
38 | "content-type": "text/html"
39 | }
40 | }));
41 | });
42 | } else {
43 | // server launched by deno run ./server.ts
44 | const file = await Deno.open(fromFileUrl(u));
45 | req.respondWith(new Response(readableStreamFromReader(file), {
46 | status: 200,
47 | headers: {
48 | "content-type": "text/html"
49 | }
50 | }));
51 | }
52 | } else if (req.request.method === "GET" && pathname === "/favicon.ico") {
53 | req.respondWith(Response.redirect("https://deno.land/favicon.ico", 302));
54 | } else if (req.request.method === "GET" && pathname === "/ws") {
55 | const { socket, response } = Deno.upgradeWebSocket(req.request);
56 | wsHandler(socket);
57 | req.respondWith(response);
58 | }
59 | }
60 | const server = Deno.listen({
61 | port: 8080
62 | });
63 | console.log("chat server starting on :8080....");
64 | for await (const conn of server){
65 | (async ()=>{
66 | const httpConn = Deno.serveHttp(conn);
67 | for await (const requestEvent of httpConn){
68 | requestHandler(requestEvent);
69 | }
70 | })();
71 | }
72 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_object/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/_util.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | // Copyright the Browserify authors. MIT License.
3 | // Ported from https://github.com/browserify/path-browserify/
4 | // This module is browser compatible.
5 | import { CHAR_BACKWARD_SLASH, CHAR_DOT, CHAR_FORWARD_SLASH, CHAR_LOWERCASE_A, CHAR_LOWERCASE_Z, CHAR_UPPERCASE_A, CHAR_UPPERCASE_Z } from "./_constants.ts";
6 | export function assertPath(path) {
7 | if (typeof path !== "string") {
8 | throw new TypeError(`Path must be a string. Received ${JSON.stringify(path)}`);
9 | }
10 | }
11 | export function isPosixPathSeparator(code) {
12 | return code === CHAR_FORWARD_SLASH;
13 | }
14 | export function isPathSeparator(code) {
15 | return isPosixPathSeparator(code) || code === CHAR_BACKWARD_SLASH;
16 | }
17 | export function isWindowsDeviceRoot(code) {
18 | return code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z || code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z;
19 | }
20 | // Resolves . and .. elements in a path with directory names
21 | export function normalizeString(path, allowAboveRoot, separator, isPathSeparator) {
22 | let res = "";
23 | let lastSegmentLength = 0;
24 | let lastSlash = -1;
25 | let dots = 0;
26 | let code;
27 | for(let i = 0, len = path.length; i <= len; ++i){
28 | if (i < len) code = path.charCodeAt(i);
29 | else if (isPathSeparator(code)) break;
30 | else code = CHAR_FORWARD_SLASH;
31 | if (isPathSeparator(code)) {
32 | if (lastSlash === i - 1 || dots === 1) {
33 | // NOOP
34 | } else if (lastSlash !== i - 1 && dots === 2) {
35 | if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== CHAR_DOT || res.charCodeAt(res.length - 2) !== CHAR_DOT) {
36 | if (res.length > 2) {
37 | const lastSlashIndex = res.lastIndexOf(separator);
38 | if (lastSlashIndex === -1) {
39 | res = "";
40 | lastSegmentLength = 0;
41 | } else {
42 | res = res.slice(0, lastSlashIndex);
43 | lastSegmentLength = res.length - 1 - res.lastIndexOf(separator);
44 | }
45 | lastSlash = i;
46 | dots = 0;
47 | continue;
48 | } else if (res.length === 2 || res.length === 1) {
49 | res = "";
50 | lastSegmentLength = 0;
51 | lastSlash = i;
52 | dots = 0;
53 | continue;
54 | }
55 | }
56 | if (allowAboveRoot) {
57 | if (res.length > 0) res += `${separator}..`;
58 | else res = "..";
59 | lastSegmentLength = 2;
60 | }
61 | } else {
62 | if (res.length > 0) res += separator + path.slice(lastSlash + 1, i);
63 | else res = path.slice(lastSlash + 1, i);
64 | lastSegmentLength = i - lastSlash - 1;
65 | }
66 | lastSlash = i;
67 | dots = 0;
68 | } else if (code === CHAR_DOT && dots !== -1) {
69 | ++dots;
70 | } else {
71 | dots = -1;
72 | }
73 | }
74 | return res;
75 | }
76 | export function _format(sep, pathObject) {
77 | const dir = pathObject.dir || pathObject.root;
78 | const base = pathObject.base || (pathObject.name || "") + (pathObject.ext || "");
79 | if (!dir) return base;
80 | if (dir === pathObject.root) return dir + base;
81 | return dir + sep + base;
82 | }
83 | const WHITESPACE_ENCODINGS = {
84 | "\u0009": "%09",
85 | "\u000A": "%0A",
86 | "\u000B": "%0B",
87 | "\u000C": "%0C",
88 | "\u000D": "%0D",
89 | "\u0020": "%20"
90 | };
91 | export function encodeWhitespace(string) {
92 | return string.replaceAll(/[\s]/g, (c)=>{
93 | return WHITESPACE_ENCODINGS[c] ?? c;
94 | });
95 | }
96 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_string/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/path/_util.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | // Copyright the Browserify authors. MIT License.
3 | // Ported from https://github.com/browserify/path-browserify/
4 | // This module is browser compatible.
5 | import { CHAR_BACKWARD_SLASH, CHAR_DOT, CHAR_FORWARD_SLASH, CHAR_LOWERCASE_A, CHAR_LOWERCASE_Z, CHAR_UPPERCASE_A, CHAR_UPPERCASE_Z } from "./_constants.ts";
6 | export function assertPath(path) {
7 | if (typeof path !== "string") {
8 | throw new TypeError(`Path must be a string. Received ${JSON.stringify(path)}`);
9 | }
10 | }
11 | export function isPosixPathSeparator(code) {
12 | return code === CHAR_FORWARD_SLASH;
13 | }
14 | export function isPathSeparator(code) {
15 | return isPosixPathSeparator(code) || code === CHAR_BACKWARD_SLASH;
16 | }
17 | export function isWindowsDeviceRoot(code) {
18 | return code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z || code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z;
19 | }
20 | // Resolves . and .. elements in a path with directory names
21 | export function normalizeString(path, allowAboveRoot, separator, isPathSeparator) {
22 | let res = "";
23 | let lastSegmentLength = 0;
24 | let lastSlash = -1;
25 | let dots = 0;
26 | let code;
27 | for(let i = 0, len = path.length; i <= len; ++i){
28 | if (i < len) code = path.charCodeAt(i);
29 | else if (isPathSeparator(code)) break;
30 | else code = CHAR_FORWARD_SLASH;
31 | if (isPathSeparator(code)) {
32 | if (lastSlash === i - 1 || dots === 1) {
33 | // NOOP
34 | } else if (lastSlash !== i - 1 && dots === 2) {
35 | if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== CHAR_DOT || res.charCodeAt(res.length - 2) !== CHAR_DOT) {
36 | if (res.length > 2) {
37 | const lastSlashIndex = res.lastIndexOf(separator);
38 | if (lastSlashIndex === -1) {
39 | res = "";
40 | lastSegmentLength = 0;
41 | } else {
42 | res = res.slice(0, lastSlashIndex);
43 | lastSegmentLength = res.length - 1 - res.lastIndexOf(separator);
44 | }
45 | lastSlash = i;
46 | dots = 0;
47 | continue;
48 | } else if (res.length === 2 || res.length === 1) {
49 | res = "";
50 | lastSegmentLength = 0;
51 | lastSlash = i;
52 | dots = 0;
53 | continue;
54 | }
55 | }
56 | if (allowAboveRoot) {
57 | if (res.length > 0) res += `${separator}..`;
58 | else res = "..";
59 | lastSegmentLength = 2;
60 | }
61 | } else {
62 | if (res.length > 0) res += separator + path.slice(lastSlash + 1, i);
63 | else res = path.slice(lastSlash + 1, i);
64 | lastSegmentLength = i - lastSlash - 1;
65 | }
66 | lastSlash = i;
67 | dots = 0;
68 | } else if (code === CHAR_DOT && dots !== -1) {
69 | ++dots;
70 | } else {
71 | dots = -1;
72 | }
73 | }
74 | return res;
75 | }
76 | export function _format(sep, pathObject) {
77 | const dir = pathObject.dir || pathObject.root;
78 | const base = pathObject.base || (pathObject.name || "") + (pathObject.ext || "");
79 | if (!dir) return base;
80 | if (dir === pathObject.root) return dir + base;
81 | return dir + sep + base;
82 | }
83 | const WHITESPACE_ENCODINGS = {
84 | "\u0009": "%09",
85 | "\u000A": "%0A",
86 | "\u000B": "%0B",
87 | "\u000C": "%0C",
88 | "\u000D": "%0D",
89 | "\u0020": "%20"
90 | };
91 | export function encodeWhitespace(string) {
92 | return string.replaceAll(/[\s]/g, (c)=>{
93 | return WHITESPACE_ENCODINGS[c] ?? c;
94 | });
95 | }
96 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_object/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/bytes/bytes_list.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | // This module is browser compatible.
3 | /**
4 | * An abstraction of multiple Uint8Arrays
5 | */ export class BytesList {
6 | len = 0;
7 | chunks = [];
8 | constructor(){}
9 | /**
10 | * Total size of bytes
11 | */ size() {
12 | return this.len;
13 | }
14 | /**
15 | * Push bytes with given offset infos
16 | */ add(value, start = 0, end = value.byteLength) {
17 | if (value.byteLength === 0 || end - start === 0) {
18 | return;
19 | }
20 | checkRange(start, end, value.byteLength);
21 | this.chunks.push({
22 | value,
23 | end,
24 | start,
25 | offset: this.len
26 | });
27 | this.len += end - start;
28 | }
29 | /**
30 | * Drop head `n` bytes.
31 | */ shift(n) {
32 | if (n === 0) {
33 | return;
34 | }
35 | if (this.len <= n) {
36 | this.chunks = [];
37 | this.len = 0;
38 | return;
39 | }
40 | const idx = this.getChunkIndex(n);
41 | this.chunks.splice(0, idx);
42 | const [chunk] = this.chunks;
43 | if (chunk) {
44 | const diff = n - chunk.offset;
45 | chunk.start += diff;
46 | }
47 | let offset = 0;
48 | for (const chunk of this.chunks){
49 | chunk.offset = offset;
50 | offset += chunk.end - chunk.start;
51 | }
52 | this.len = offset;
53 | }
54 | /**
55 | * Find chunk index in which `pos` locates by binary-search
56 | * returns -1 if out of range
57 | */ getChunkIndex(pos) {
58 | let max = this.chunks.length;
59 | let min = 0;
60 | while(true){
61 | const i = min + Math.floor((max - min) / 2);
62 | if (i < 0 || this.chunks.length <= i) {
63 | return -1;
64 | }
65 | const { offset, start, end } = this.chunks[i];
66 | const len = end - start;
67 | if (offset <= pos && pos < offset + len) {
68 | return i;
69 | } else if (offset + len <= pos) {
70 | min = i + 1;
71 | } else {
72 | max = i - 1;
73 | }
74 | }
75 | }
76 | /**
77 | * Get indexed byte from chunks
78 | */ get(i) {
79 | if (i < 0 || this.len <= i) {
80 | throw new Error("out of range");
81 | }
82 | const idx = this.getChunkIndex(i);
83 | const { value, offset, start } = this.chunks[idx];
84 | return value[start + i - offset];
85 | }
86 | /**
87 | * Iterator of bytes from given position
88 | */ *iterator(start = 0) {
89 | const startIdx = this.getChunkIndex(start);
90 | if (startIdx < 0) return;
91 | const first = this.chunks[startIdx];
92 | let firstOffset = start - first.offset;
93 | for(let i = startIdx; i < this.chunks.length; i++){
94 | const chunk = this.chunks[i];
95 | for(let j = chunk.start + firstOffset; j < chunk.end; j++){
96 | yield chunk.value[j];
97 | }
98 | firstOffset = 0;
99 | }
100 | }
101 | /**
102 | * Returns subset of bytes copied
103 | */ slice(start, end = this.len) {
104 | if (end === start) {
105 | return new Uint8Array();
106 | }
107 | checkRange(start, end, this.len);
108 | const result = new Uint8Array(end - start);
109 | const startIdx = this.getChunkIndex(start);
110 | const endIdx = this.getChunkIndex(end - 1);
111 | let written = 0;
112 | for(let i = startIdx; i < endIdx; i++){
113 | const chunk = this.chunks[i];
114 | const len = chunk.end - chunk.start;
115 | result.set(chunk.value.subarray(chunk.start, chunk.end), written);
116 | written += len;
117 | }
118 | const last = this.chunks[endIdx];
119 | const rest = end - start - written;
120 | result.set(last.value.subarray(last.start, last.start + rest), written);
121 | return result;
122 | }
123 | /**
124 | * Concatenate chunks into single Uint8Array copied.
125 | */ concat() {
126 | const result = new Uint8Array(this.len);
127 | let sum = 0;
128 | for (const { value, start, end } of this.chunks){
129 | result.set(value.subarray(start, end), sum);
130 | sum += end - start;
131 | }
132 | return result;
133 | }
134 | }
135 | function checkRange(start, end, len) {
136 | if (start < 0 || len < start || end < 0 || len < end || end < start) {
137 | throw new Error("invalid range");
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/tests/__snapshots__/common/remote_url_as_string/transpile/remote/NNRNTa3nQ9cRguYpg8Fa19sQDzU/std@0.140.0/bytes/bytes_list.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
2 | // This module is browser compatible.
3 | /**
4 | * An abstraction of multiple Uint8Arrays
5 | */ export class BytesList {
6 | len = 0;
7 | chunks = [];
8 | constructor(){}
9 | /**
10 | * Total size of bytes
11 | */ size() {
12 | return this.len;
13 | }
14 | /**
15 | * Push bytes with given offset infos
16 | */ add(value, start = 0, end = value.byteLength) {
17 | if (value.byteLength === 0 || end - start === 0) {
18 | return;
19 | }
20 | checkRange(start, end, value.byteLength);
21 | this.chunks.push({
22 | value,
23 | end,
24 | start,
25 | offset: this.len
26 | });
27 | this.len += end - start;
28 | }
29 | /**
30 | * Drop head `n` bytes.
31 | */ shift(n) {
32 | if (n === 0) {
33 | return;
34 | }
35 | if (this.len <= n) {
36 | this.chunks = [];
37 | this.len = 0;
38 | return;
39 | }
40 | const idx = this.getChunkIndex(n);
41 | this.chunks.splice(0, idx);
42 | const [chunk] = this.chunks;
43 | if (chunk) {
44 | const diff = n - chunk.offset;
45 | chunk.start += diff;
46 | }
47 | let offset = 0;
48 | for (const chunk of this.chunks){
49 | chunk.offset = offset;
50 | offset += chunk.end - chunk.start;
51 | }
52 | this.len = offset;
53 | }
54 | /**
55 | * Find chunk index in which `pos` locates by binary-search
56 | * returns -1 if out of range
57 | */ getChunkIndex(pos) {
58 | let max = this.chunks.length;
59 | let min = 0;
60 | while(true){
61 | const i = min + Math.floor((max - min) / 2);
62 | if (i < 0 || this.chunks.length <= i) {
63 | return -1;
64 | }
65 | const { offset, start, end } = this.chunks[i];
66 | const len = end - start;
67 | if (offset <= pos && pos < offset + len) {
68 | return i;
69 | } else if (offset + len <= pos) {
70 | min = i + 1;
71 | } else {
72 | max = i - 1;
73 | }
74 | }
75 | }
76 | /**
77 | * Get indexed byte from chunks
78 | */ get(i) {
79 | if (i < 0 || this.len <= i) {
80 | throw new Error("out of range");
81 | }
82 | const idx = this.getChunkIndex(i);
83 | const { value, offset, start } = this.chunks[idx];
84 | return value[start + i - offset];
85 | }
86 | /**
87 | * Iterator of bytes from given position
88 | */ *iterator(start = 0) {
89 | const startIdx = this.getChunkIndex(start);
90 | if (startIdx < 0) return;
91 | const first = this.chunks[startIdx];
92 | let firstOffset = start - first.offset;
93 | for(let i = startIdx; i < this.chunks.length; i++){
94 | const chunk = this.chunks[i];
95 | for(let j = chunk.start + firstOffset; j < chunk.end; j++){
96 | yield chunk.value[j];
97 | }
98 | firstOffset = 0;
99 | }
100 | }
101 | /**
102 | * Returns subset of bytes copied
103 | */ slice(start, end = this.len) {
104 | if (end === start) {
105 | return new Uint8Array();
106 | }
107 | checkRange(start, end, this.len);
108 | const result = new Uint8Array(end - start);
109 | const startIdx = this.getChunkIndex(start);
110 | const endIdx = this.getChunkIndex(end - 1);
111 | let written = 0;
112 | for(let i = startIdx; i < endIdx; i++){
113 | const chunk = this.chunks[i];
114 | const len = chunk.end - chunk.start;
115 | result.set(chunk.value.subarray(chunk.start, chunk.end), written);
116 | written += len;
117 | }
118 | const last = this.chunks[endIdx];
119 | const rest = end - start - written;
120 | result.set(last.value.subarray(last.start, last.start + rest), written);
121 | return result;
122 | }
123 | /**
124 | * Concatenate chunks into single Uint8Array copied.
125 | */ concat() {
126 | const result = new Uint8Array(this.len);
127 | let sum = 0;
128 | for (const { value, start, end } of this.chunks){
129 | result.set(value.subarray(start, end), sum);
130 | sum += end - start;
131 | }
132 | return result;
133 | }
134 | }
135 | function checkRange(start, end, len) {
136 | if (start < 0 || len < start || end < 0 || len < end || end < start) {
137 | throw new Error("invalid range");
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/tests/import_map_test.ts:
--------------------------------------------------------------------------------
1 | import { join, toFileUrl } from "https://deno.land/std@0.182.0/path/mod.ts";
2 | import { assertEquals } from "https://deno.land/std@0.182.0/testing/asserts.ts";
3 | import { resolveFixture, runModule, testTranspileAndBundle } from "./utils.ts";
4 |
5 | Deno.test({
6 | name: "embedded",
7 | fn: testTranspileAndBundle(
8 | resolveFixture("import_map/main.ts"),
9 | {
10 | importMap: {
11 | imports: {
12 | "foo": "./testdata/subdir/foo.ts",
13 | },
14 | },
15 | },
16 | async ({ outputFileUrl, denoConfigPath, functionCalled }) => {
17 | if (functionCalled === "bundle") {
18 | const output = await runModule(outputFileUrl, denoConfigPath);
19 | assertEquals(output, "foo\n");
20 | }
21 | },
22 | ),
23 | });
24 |
25 | Deno.test({
26 | name: "embedded with specific base url",
27 | fn: testTranspileAndBundle(
28 | resolveFixture("import_map/main.ts"),
29 | {
30 | importMap: {
31 | baseUrl: toFileUrl(resolveFixture(".")),
32 | imports: {
33 | "foo": "./subdir/foo.ts",
34 | },
35 | },
36 | },
37 | async ({ outputFileUrl, denoConfigPath, functionCalled }) => {
38 | if (functionCalled === "bundle") {
39 | const output = await runModule(outputFileUrl, denoConfigPath);
40 | assertEquals(output, "foo\n");
41 | }
42 | },
43 | ),
44 | });
45 |
46 | Deno.test({
47 | name: "local file set as relative path",
48 | fn: testTranspileAndBundle(
49 | resolveFixture("import_map/main.ts"),
50 | {
51 | importMap: join("testdata", "import_map", "import_map.json"),
52 | },
53 | async ({ outputFileUrl, denoConfigPath, functionCalled }) => {
54 | if (functionCalled === "bundle") {
55 | const output = await runModule(outputFileUrl, denoConfigPath);
56 | assertEquals(output, "foo\n");
57 | }
58 | },
59 | ),
60 | });
61 |
62 | Deno.test({
63 | name: "local file set as absolute path",
64 | fn: testTranspileAndBundle(
65 | resolveFixture("import_map/main.ts"),
66 | {
67 | importMap: resolveFixture("import_map/import_map.json"),
68 | },
69 | async ({ outputFileUrl, denoConfigPath, functionCalled }) => {
70 | if (functionCalled === "bundle") {
71 | const output = await runModule(outputFileUrl, denoConfigPath);
72 | assertEquals(output, "foo\n");
73 | }
74 | },
75 | ),
76 | });
77 |
78 | Deno.test({
79 | name: "local file set as file url string",
80 | fn: testTranspileAndBundle(
81 | resolveFixture("import_map/main.ts"),
82 | {
83 | importMap: toFileUrl(resolveFixture("import_map/import_map.json"))
84 | .toString(),
85 | },
86 | async ({ outputFileUrl, denoConfigPath, functionCalled }) => {
87 | if (functionCalled === "bundle") {
88 | const output = await runModule(outputFileUrl, denoConfigPath);
89 | assertEquals(output, "foo\n");
90 | }
91 | },
92 | ),
93 | });
94 |
95 | Deno.test({
96 | name: "local file set as file url object",
97 | fn: testTranspileAndBundle(
98 | resolveFixture("import_map/main.ts"),
99 | {
100 | importMap: toFileUrl(resolveFixture("import_map/import_map.json")),
101 | },
102 | async ({ outputFileUrl, denoConfigPath, functionCalled }) => {
103 | if (functionCalled === "bundle") {
104 | const output = await runModule(outputFileUrl, denoConfigPath);
105 | assertEquals(output, "foo\n");
106 | }
107 | },
108 | ),
109 | });
110 |
111 | Deno.test({
112 | name: "remote url string",
113 | fn: testTranspileAndBundle(
114 | resolveFixture("import_map/main.ts"),
115 | {
116 | importMap: "http://localhost:8000/import_map/import_map.json",
117 | },
118 | async ({ outputFileUrl, denoConfigPath, functionCalled }) => {
119 | if (functionCalled === "bundle") {
120 | const output = await runModule(outputFileUrl, denoConfigPath);
121 | assertEquals(output, "foo\n");
122 | }
123 | },
124 | ),
125 | // TODO: Run a local server to be able to test this.
126 | ignore: true,
127 | });
128 |
129 | Deno.test({
130 | name: "remote url object",
131 | fn: testTranspileAndBundle(
132 | resolveFixture("import_map/main.ts"),
133 | {
134 | importMap: new URL("http://localhost:8000/import_map/import_map.json"),
135 | },
136 | async ({ outputFileUrl, denoConfigPath, functionCalled }) => {
137 | if (functionCalled === "bundle") {
138 | const output = await runModule(outputFileUrl, denoConfigPath);
139 | assertEquals(output, "foo\n");
140 | }
141 | },
142 | ),
143 | // TODO: Run a local server to be able to test this.
144 | ignore: true,
145 | });
146 |
147 | Deno.test({
148 | name: "empty import map",
149 | fn: testTranspileAndBundle(
150 | resolveFixture("mod1.ts"),
151 | { importMap: {} },
152 | ),
153 | });
154 |
--------------------------------------------------------------------------------
/rs-lib/src/lib.rs:
--------------------------------------------------------------------------------
1 | // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
2 |
3 | #![deny(clippy::print_stderr)]
4 | #![deny(clippy::print_stdout)]
5 |
6 | mod bundle_hook;
7 | mod emit;
8 | mod text;
9 |
10 | use anyhow::Result;
11 | use deno_graph::source::ResolveError;
12 | use deno_graph::BuildOptions;
13 | use deno_graph::CapturingModuleAnalyzer;
14 | use deno_graph::GraphKind;
15 | use deno_graph::ModuleGraph;
16 | use deno_graph::ParsedSourceStore;
17 | use deno_graph::Range;
18 | use import_map::ImportMap;
19 | use import_map::ImportMapOptions;
20 | use std::collections::HashMap;
21 | use url::Url;
22 |
23 | pub use emit::bundle_graph;
24 | pub use emit::BundleEmit;
25 | pub use emit::BundleOptions;
26 | pub use emit::BundleType;
27 |
28 | pub use deno_ast::EmitOptions;
29 | pub use deno_ast::ImportsNotUsedAsValues;
30 | pub use deno_ast::ModuleSpecifier;
31 | pub use deno_ast::SourceMapOption;
32 | pub use deno_ast::TranspileOptions;
33 | pub use deno_graph::source::CacheSetting;
34 | pub use deno_graph::source::LoadFuture;
35 | pub use deno_graph::source::LoadOptions;
36 | pub use deno_graph::source::Loader;
37 | pub use deno_graph::source::LoaderChecksum;
38 |
39 | pub async fn bundle(
40 | root: ModuleSpecifier,
41 | loader: &mut dyn Loader,
42 | maybe_import_map: Option,
43 | options: BundleOptions,
44 | ) -> Result {
45 | let maybe_import_map = get_import_map_from_input(maybe_import_map)?;
46 | let import_map_resolver = ImportMapResolver(maybe_import_map);
47 | let mut graph = ModuleGraph::new(GraphKind::CodeOnly);
48 | graph
49 | .build(
50 | vec![root],
51 | loader,
52 | BuildOptions {
53 | resolver: Some(import_map_resolver.as_resolver()),
54 | ..Default::default()
55 | },
56 | )
57 | .await;
58 |
59 | bundle_graph(&graph, options)
60 | }
61 |
62 | pub async fn transpile(
63 | root: ModuleSpecifier,
64 | loader: &mut dyn Loader,
65 | maybe_import_map: Option,
66 | transpile_options: &TranspileOptions,
67 | emit_options: &EmitOptions,
68 | ) -> Result>> {
69 | let analyzer = CapturingModuleAnalyzer::default();
70 | let maybe_import_map = get_import_map_from_input(maybe_import_map)?;
71 | let import_map_resolver = ImportMapResolver(maybe_import_map);
72 | let mut graph = ModuleGraph::new(GraphKind::CodeOnly);
73 | graph
74 | .build(
75 | vec![root],
76 | loader,
77 | BuildOptions {
78 | module_analyzer: &analyzer,
79 | resolver: Some(import_map_resolver.as_resolver()),
80 | ..Default::default()
81 | },
82 | )
83 | .await;
84 |
85 | graph.valid()?;
86 |
87 | let mut map = HashMap::new();
88 |
89 | for module in graph.modules().filter_map(|m| m.js()) {
90 | if let Some(parsed_source) =
91 | analyzer.remove_parsed_source(&module.specifier)
92 | {
93 | let transpiled_source = parsed_source
94 | .transpile(transpile_options, emit_options)?
95 | .into_source();
96 |
97 | map.insert(module.specifier.to_string(), transpiled_source.source);
98 |
99 | if let Some(source_map) = transpiled_source.source_map {
100 | map.insert(format!("{}.map", module.specifier.as_str()), source_map);
101 | }
102 | }
103 | }
104 |
105 | Ok(map)
106 | }
107 |
108 | #[derive(Debug)]
109 | pub struct ImportMapInput {
110 | pub base_url: Url,
111 | pub json_string: String,
112 | }
113 |
114 | fn get_import_map_from_input(
115 | maybe_input: Option,
116 | ) -> Result