Best JavaScript code snippet using cypress
js-api-tests.js
Source:js-api-tests.js
1const { installForTests, removeRecursiveSync, writeFileAtomic } = require('./esbuild')2const { SourceMapConsumer } = require('source-map')3const assert = require('assert')4const path = require('path')5const http = require('http')6const fs = require('fs')7const vm = require('vm')8const readFileAsync = fs.promises.readFile9const writeFileAsync = fs.promises.writeFile10const mkdirAsync = fs.promises.mkdir11const repoDir = path.dirname(__dirname)12const rootTestDir = path.join(repoDir, 'scripts', '.js-api-tests')13let buildTests = {14 async errorIfEntryPointsNotArray({ esbuild }) {15 try {16 await esbuild.build({17 entryPoints: 'this is not an array',18 logLevel: 'silent',19 })20 throw new Error('Expected build failure');21 } catch (e) {22 if (!e.errors || !e.errors[0] || e.errors[0].text !== '"entryPoints" must be an array or an object') {23 throw e;24 }25 }26 },27 async errorIfBadWorkingDirectory({ esbuild }) {28 try {29 await esbuild.build({30 absWorkingDir: 'what is this? certainly not an absolute path',31 logLevel: 'silent',32 write: false,33 })34 throw new Error('Expected build failure');35 } catch (e) {36 if (e.message !== 'Build failed with 1 error:\nerror: The working directory ' +37 '"what is this? certainly not an absolute path" is not an absolute path') {38 throw e;39 }40 }41 },42 async errorIfGlob({ esbuild }) {43 try {44 await esbuild.build({45 entryPoints: ['./src/*.js'],46 logLevel: 'silent',47 write: false,48 })49 throw new Error('Expected build failure');50 } catch (e) {51 if (!e.errors || !e.errors[0] || e.errors[0].text !== 'Could not resolve "./src/*.js" ' +52 '(glob syntax must be expanded first before passing the paths to esbuild)') {53 throw e;54 }55 }56 },57 async windowsBackslashPathTest({ esbuild, testDir }) {58 let entry = path.join(testDir, 'entry.js');59 let nested = path.join(testDir, 'nested.js');60 let outfile = path.join(testDir, 'out.js');61 // On Windows, backslash and forward slash should be treated the same62 fs.writeFileSync(entry, `63 import ${JSON.stringify(nested)}64 import ${JSON.stringify(nested.split(path.sep).join('/'))}65 `);66 fs.writeFileSync(nested, `console.log('once')`);67 const result = await esbuild.build({68 entryPoints: [entry],69 outfile,70 bundle: true,71 write: false,72 minify: true,73 format: 'esm',74 })75 assert.strictEqual(result.outputFiles[0].text, 'console.log("once");\n')76 },77 async workingDirTest({ esbuild, testDir }) {78 let aDir = path.join(testDir, 'a');79 let bDir = path.join(testDir, 'b');80 let aFile = path.join(aDir, 'a-in.js');81 let bFile = path.join(bDir, 'b-in.js');82 let aOut = path.join(aDir, 'a-out.js');83 let bOut = path.join(bDir, 'b-out.js');84 fs.mkdirSync(aDir, { recursive: true });85 fs.mkdirSync(bDir, { recursive: true });86 fs.writeFileSync(aFile, 'exports.x = true');87 fs.writeFileSync(bFile, 'exports.y = true');88 await Promise.all([89 esbuild.build({90 entryPoints: [path.basename(aFile)],91 outfile: path.basename(aOut),92 absWorkingDir: aDir,93 }),94 esbuild.build({95 entryPoints: [path.basename(bFile)],96 outfile: path.basename(bOut),97 absWorkingDir: bDir,98 }),99 ]);100 assert.strictEqual(require(aOut).x, true)101 assert.strictEqual(require(bOut).y, true)102 },103 async pathResolverEACCS({ esbuild, testDir }) {104 let outerDir = path.join(testDir, 'outer');105 let innerDir = path.join(outerDir, 'inner');106 let pkgDir = path.join(testDir, 'node_modules', 'pkg');107 let entry = path.join(innerDir, 'entry.js');108 let sibling = path.join(innerDir, 'sibling.js');109 let index = path.join(pkgDir, 'index.js');110 let outfile = path.join(innerDir, 'out.js');111 fs.mkdirSync(pkgDir, { recursive: true });112 fs.mkdirSync(innerDir, { recursive: true });113 fs.writeFileSync(entry, `114 import a from "./sibling.js"115 import b from "pkg"116 export default {a, b}117 `);118 fs.writeFileSync(sibling, `export default 'sibling'`);119 fs.writeFileSync(index, `export default 'pkg'`);120 fs.chmodSync(outerDir, 0o111);121 try {122 await esbuild.build({123 entryPoints: [entry],124 bundle: true,125 outfile,126 format: 'cjs',127 });128 const result = require(outfile);129 assert.deepStrictEqual(result.default, { a: 'sibling', b: 'pkg' });130 }131 finally {132 // Restore permission when the test ends so test cleanup works133 fs.chmodSync(outerDir, 0o755);134 }135 },136 async nodePathsTest({ esbuild, testDir }) {137 let srcDir = path.join(testDir, 'src');138 let pkgDir = path.join(testDir, 'pkg');139 let outfile = path.join(testDir, 'out.js');140 let entry = path.join(srcDir, 'entry.js');141 let other = path.join(pkgDir, 'other.js');142 fs.mkdirSync(srcDir, { recursive: true });143 fs.mkdirSync(pkgDir, { recursive: true });144 fs.writeFileSync(entry, `export {x} from 'other'`);145 fs.writeFileSync(other, `export let x = 123`);146 await esbuild.build({147 entryPoints: [entry],148 outfile,149 bundle: true,150 nodePaths: [pkgDir],151 format: 'cjs',152 })153 assert.strictEqual(require(outfile).x, 123)154 },155 // A local "node_modules" path should be preferred over "NODE_PATH".156 // See: https://github.com/evanw/esbuild/issues/1117157 async nodePathsLocalPreferredTestIssue1117({ esbuild, testDir }) {158 let srcDir = path.join(testDir, 'src');159 let srcOtherDir = path.join(testDir, 'src', 'node_modules', 'other');160 let pkgDir = path.join(testDir, 'pkg');161 let outfile = path.join(testDir, 'out.js');162 let entry = path.join(srcDir, 'entry.js');163 let srcOther = path.join(srcOtherDir, 'index.js');164 let pkgOther = path.join(pkgDir, 'other.js');165 fs.mkdirSync(srcDir, { recursive: true });166 fs.mkdirSync(srcOtherDir, { recursive: true });167 fs.mkdirSync(pkgDir, { recursive: true });168 fs.writeFileSync(entry, `export {x} from 'other'`);169 fs.writeFileSync(srcOther, `export let x = 234`);170 fs.writeFileSync(pkgOther, `export let x = 123`);171 await esbuild.build({172 entryPoints: [entry],173 outfile,174 bundle: true,175 nodePaths: [pkgDir],176 format: 'cjs',177 })178 assert.strictEqual(require(outfile).x, 234)179 },180 async es6_to_cjs({ esbuild, testDir }) {181 const input = path.join(testDir, 'in.js')182 const output = path.join(testDir, 'out.js')183 await writeFileAsync(input, 'export default 123')184 const value = await esbuild.build({185 entryPoints: [input],186 bundle: true,187 outfile: output,188 format: 'cjs',189 })190 assert.strictEqual(value.outputFiles, void 0)191 const result = require(output)192 assert.strictEqual(result.default, 123)193 assert.strictEqual(result.__esModule, true)194 },195 // Test recursive directory creation196 async recursiveMkdir({ esbuild, testDir }) {197 const input = path.join(testDir, 'in.js')198 const output = path.join(testDir, 'a/b/c/d/out.js')199 await writeFileAsync(input, 'export default 123')200 await esbuild.build({201 entryPoints: [input],202 bundle: true,203 outfile: output,204 format: 'cjs',205 })206 const result = require(output)207 assert.strictEqual(result.default, 123)208 assert.strictEqual(result.__esModule, true)209 },210 async outExtensionJS({ esbuild, testDir }) {211 const input = path.join(testDir, 'in.js')212 const output = path.join(testDir, 'in.mjs')213 await writeFileAsync(input, 'console.log("test")')214 await esbuild.build({215 entryPoints: [input],216 outdir: testDir,217 outExtension: { '.js': '.mjs' },218 })219 const mjs = await readFileAsync(output, 'utf8')220 assert.strictEqual(mjs, 'console.log("test");\n')221 },222 async outExtensionCSS({ esbuild, testDir }) {223 const input = path.join(testDir, 'in.css')224 const output = path.join(testDir, 'in.notcss')225 await writeFileAsync(input, 'body {}')226 await esbuild.build({227 entryPoints: [input],228 outdir: testDir,229 outExtension: { '.css': '.notcss' },230 })231 const notcss = await readFileAsync(output, 'utf8')232 assert.strictEqual(notcss, 'body {\n}\n')233 },234 async sourceMap({ esbuild, testDir }) {235 const input = path.join(testDir, 'in.js')236 const output = path.join(testDir, 'out.js')237 const content = 'exports.foo = 123'238 await writeFileAsync(input, content)239 await esbuild.build({240 entryPoints: [input],241 outfile: output,242 sourcemap: true,243 })244 const result = require(output)245 assert.strictEqual(result.foo, 123)246 const outputFile = await readFileAsync(output, 'utf8')247 const match = /\/\/# sourceMappingURL=(.*)/.exec(outputFile)248 assert.strictEqual(match[1], 'out.js.map')249 const resultMap = await readFileAsync(output + '.map', 'utf8')250 const json = JSON.parse(resultMap)251 assert.strictEqual(json.version, 3)252 assert.strictEqual(json.sources[0], path.basename(input))253 assert.strictEqual(json.sourcesContent[0], content)254 },255 async sourceMapExternal({ esbuild, testDir }) {256 const input = path.join(testDir, 'in.js')257 const output = path.join(testDir, 'out.js')258 const content = 'exports.foo = 123'259 await writeFileAsync(input, content)260 await esbuild.build({261 entryPoints: [input],262 outfile: output,263 sourcemap: 'external',264 })265 const result = require(output)266 assert.strictEqual(result.foo, 123)267 const outputFile = await readFileAsync(output, 'utf8')268 const match = /\/\/# sourceMappingURL=(.*)/.exec(outputFile)269 assert.strictEqual(match, null)270 const resultMap = await readFileAsync(output + '.map', 'utf8')271 const json = JSON.parse(resultMap)272 assert.strictEqual(json.version, 3)273 assert.strictEqual(json.sources[0], path.basename(input))274 assert.strictEqual(json.sourcesContent[0], content)275 },276 async sourceMapInline({ esbuild, testDir }) {277 const input = path.join(testDir, 'in.js')278 const output = path.join(testDir, 'out.js')279 const content = 'exports.foo = 123'280 await writeFileAsync(input, content)281 await esbuild.build({282 entryPoints: [input],283 outfile: output,284 sourcemap: 'inline',285 })286 const result = require(output)287 assert.strictEqual(result.foo, 123)288 const outputFile = await readFileAsync(output, 'utf8')289 const match = /\/\/# sourceMappingURL=data:application\/json;base64,(.*)/.exec(outputFile)290 const json = JSON.parse(Buffer.from(match[1], 'base64').toString())291 assert.strictEqual(json.version, 3)292 assert.strictEqual(json.sources[0], path.basename(input))293 assert.strictEqual(json.sourcesContent[0], content)294 },295 async sourceMapBoth({ esbuild, testDir }) {296 const input = path.join(testDir, 'in.js')297 const output = path.join(testDir, 'out.js')298 const content = 'exports.foo = 123'299 await writeFileAsync(input, content)300 await esbuild.build({301 entryPoints: [input],302 outfile: output,303 sourcemap: 'both',304 })305 const result = require(output)306 assert.strictEqual(result.foo, 123)307 const outputFile = await readFileAsync(output, 'utf8')308 const match = /\/\/# sourceMappingURL=data:application\/json;base64,(.*)/.exec(outputFile)309 const json = JSON.parse(Buffer.from(match[1], 'base64').toString())310 assert.strictEqual(json.version, 3)311 assert.strictEqual(json.sources[0], path.basename(input))312 assert.strictEqual(json.sourcesContent[0], content)313 const outputFileMap = await readFileAsync(output + '.map', 'utf8')314 assert.strictEqual(Buffer.from(match[1], 'base64').toString(), outputFileMap)315 },316 async sourceMapIncludeSourcesContent({ esbuild, testDir }) {317 const input = path.join(testDir, 'in.js')318 const output = path.join(testDir, 'out.js')319 const content = 'exports.foo = 123'320 await writeFileAsync(input, content)321 await esbuild.build({322 entryPoints: [input],323 outfile: output,324 sourcemap: true,325 sourcesContent: true,326 })327 const result = require(output)328 assert.strictEqual(result.foo, 123)329 const outputFile = await readFileAsync(output, 'utf8')330 const match = /\/\/# sourceMappingURL=(.*)/.exec(outputFile)331 assert.strictEqual(match[1], 'out.js.map')332 const resultMap = await readFileAsync(output + '.map', 'utf8')333 const json = JSON.parse(resultMap)334 assert.strictEqual(json.version, 3)335 assert.strictEqual(json.sources[0], path.basename(input))336 assert.strictEqual(json.sourcesContent[0], content)337 },338 async sourceMapExcludeSourcesContent({ esbuild, testDir }) {339 const input = path.join(testDir, 'in.js')340 const output = path.join(testDir, 'out.js')341 const content = 'exports.foo = 123'342 await writeFileAsync(input, content)343 await esbuild.build({344 entryPoints: [input],345 outfile: output,346 sourcemap: true,347 sourcesContent: false,348 })349 const result = require(output)350 assert.strictEqual(result.foo, 123)351 const outputFile = await readFileAsync(output, 'utf8')352 const match = /\/\/# sourceMappingURL=(.*)/.exec(outputFile)353 assert.strictEqual(match[1], 'out.js.map')354 const resultMap = await readFileAsync(output + '.map', 'utf8')355 const json = JSON.parse(resultMap)356 assert.strictEqual(json.version, 3)357 assert.strictEqual(json.sources[0], path.basename(input))358 assert.strictEqual(json.sourcesContent, void 0)359 },360 async sourceMapSourceRoot({ esbuild, testDir }) {361 const input = path.join(testDir, 'in.js')362 const output = path.join(testDir, 'out.js')363 const content = 'exports.foo = 123'364 await writeFileAsync(input, content)365 await esbuild.build({366 entryPoints: [input],367 outfile: output,368 sourcemap: true,369 sourceRoot: 'https://example.com/'370 })371 const result = require(output)372 assert.strictEqual(result.foo, 123)373 const outputFile = await readFileAsync(output, 'utf8')374 const match = /\/\/# sourceMappingURL=(.*)/.exec(outputFile)375 assert.strictEqual(match[1], 'out.js.map')376 const resultMap = await readFileAsync(output + '.map', 'utf8')377 const json = JSON.parse(resultMap)378 assert.strictEqual(json.version, 3)379 assert.strictEqual(json.sources[0], path.basename(input))380 assert.strictEqual(json.sourceRoot, 'https://example.com/')381 },382 async sourceMapWithDisabledFile({ esbuild, testDir }) {383 const input = path.join(testDir, 'in.js')384 const disabled = path.join(testDir, 'disabled.js')385 const packageJSON = path.join(testDir, 'package.json')386 const output = path.join(testDir, 'out.js')387 const content = 'exports.foo = require("./disabled")'388 await writeFileAsync(input, content)389 await writeFileAsync(disabled, 'module.exports = 123')390 await writeFileAsync(packageJSON, `{"browser": {"./disabled.js": false}}`)391 await esbuild.build({392 entryPoints: [input],393 outfile: output,394 sourcemap: true,395 bundle: true,396 })397 const result = require(output)398 assert.strictEqual(result.foo, void 0)399 const resultMap = await readFileAsync(output + '.map', 'utf8')400 const json = JSON.parse(resultMap)401 assert.strictEqual(json.version, 3)402 assert.strictEqual(json.sources[0], 'disabled')403 assert.strictEqual(json.sources[1], path.basename(input))404 assert.strictEqual(json.sourcesContent[0], '')405 assert.strictEqual(json.sourcesContent[1], content)406 },407 async sourceMapWithDisabledModule({ esbuild, testDir }) {408 const input = path.join(testDir, 'in.js')409 const disabled = path.join(testDir, 'node_modules', 'disabled', 'index.js')410 const packageJSON = path.join(testDir, 'package.json')411 const output = path.join(testDir, 'out.js')412 const content = 'exports.foo = require("disabled")'413 await mkdirAsync(path.dirname(disabled), { recursive: true })414 await writeFileAsync(input, content)415 await writeFileAsync(disabled, 'module.exports = 123')416 await writeFileAsync(packageJSON, `{"browser": {"disabled": false}}`)417 await esbuild.build({418 entryPoints: [input],419 outfile: output,420 sourcemap: true,421 bundle: true,422 })423 const result = require(output)424 assert.strictEqual(result.foo, void 0)425 const resultMap = await readFileAsync(output + '.map', 'utf8')426 const json = JSON.parse(resultMap)427 assert.strictEqual(json.version, 3)428 assert.strictEqual(json.sources[0], path.relative(testDir, disabled).split(path.sep).join('/'))429 assert.strictEqual(json.sources[1], path.basename(input))430 assert.strictEqual(json.sourcesContent[0], '')431 assert.strictEqual(json.sourcesContent[1], content)432 },433 async resolveExtensionOrder({ esbuild, testDir }) {434 const input = path.join(testDir, 'in.js');435 const inputBare = path.join(testDir, 'module.js')436 const inputSomething = path.join(testDir, 'module.something.js')437 const output = path.join(testDir, 'out.js')438 await writeFileAsync(input, 'exports.result = require("./module").foo')439 await writeFileAsync(inputBare, 'exports.foo = 321')440 await writeFileAsync(inputSomething, 'exports.foo = 123')441 await esbuild.build({442 entryPoints: [input],443 outfile: output,444 format: 'cjs',445 bundle: true,446 resolveExtensions: ['.something.js', '.js'],447 })448 assert.strictEqual(require(output).result, 123)449 },450 async defineObject({ esbuild, testDir }) {451 const input = path.join(testDir, 'in.js');452 const output = path.join(testDir, 'out.js')453 await writeFileAsync(input, 'export default {abc, xyz}')454 await esbuild.build({455 entryPoints: [input],456 outfile: output,457 format: 'cjs',458 bundle: true,459 define: {460 abc: '["a", "b", "c"]',461 xyz: '{"x": 1, "y": 2, "z": 3}',462 },463 })464 assert.deepStrictEqual(require(output).default, {465 abc: ['a', 'b', 'c'],466 xyz: { x: 1, y: 2, z: 3 },467 })468 },469 async inject({ esbuild, testDir }) {470 const input = path.join(testDir, 'in.js');471 const inject = path.join(testDir, 'inject.js')472 const output = path.join(testDir, 'out.js')473 await writeFileAsync(input, 'export default foo * 10 + 4')474 await writeFileAsync(inject, 'export let foo = 123')475 await esbuild.build({476 entryPoints: [input],477 outfile: output,478 format: 'cjs',479 bundle: true,480 inject: [inject],481 })482 assert.strictEqual(require(output).default, 1234)483 },484 async mainFields({ esbuild, testDir }) {485 const input = path.join(testDir, 'in.js')486 const output = path.join(testDir, 'out.js')487 const mainFieldsDir = path.join(testDir, 'node_modules', 'main-fields-test')488 const mainFieldsA = path.join(mainFieldsDir, 'a.js')489 const mainFieldsB = path.join(mainFieldsDir, 'b.js')490 const mainFieldsPackage = path.join(mainFieldsDir, 'package.json')491 await mkdirAsync(mainFieldsDir, { recursive: true })492 await writeFileAsync(input, 'export * from "main-fields-test"')493 await writeFileAsync(mainFieldsA, 'export let foo = "a"')494 await writeFileAsync(mainFieldsB, 'export let foo = "b"')495 await writeFileAsync(mainFieldsPackage, '{ "a": "./a.js", "b": "./b.js", "c": "./c.js" }')496 await esbuild.build({497 entryPoints: [input],498 outfile: output,499 bundle: true,500 format: 'cjs',501 mainFields: ['c', 'b', 'a'],502 })503 const result = require(output)504 assert.strictEqual(result.foo, 'b')505 },506 async requireAbsolutePath({ esbuild, testDir }) {507 const input = path.join(testDir, 'in.js')508 const dependency = path.join(testDir, 'dep.js')509 const output = path.join(testDir, 'out.js')510 await writeFileAsync(input, `import value from ${JSON.stringify(dependency)}; export default value`)511 await writeFileAsync(dependency, `export default 123`)512 const value = await esbuild.build({513 entryPoints: [input],514 bundle: true,515 outfile: output,516 format: 'cjs',517 })518 assert.strictEqual(value.outputFiles, void 0)519 const result = require(output)520 assert.strictEqual(result.default, 123)521 assert.strictEqual(result.__esModule, true)522 },523 async fileLoader({ esbuild, testDir }) {524 const input = path.join(testDir, 'in.js')525 const data = path.join(testDir, 'data.bin')526 const output = path.join(testDir, 'out.js')527 await writeFileAsync(input, `export {default as value} from ${JSON.stringify(data)}`)528 await writeFileAsync(data, `stuff`)529 const value = await esbuild.build({530 entryPoints: [input],531 bundle: true,532 outfile: output,533 format: 'cjs',534 loader: { '.bin': 'file' },535 })536 assert.strictEqual(value.outputFiles, void 0)537 const result = require(output)538 assert.strictEqual(result.value, './data-BYATPJRB.bin')539 assert.strictEqual(result.__esModule, true)540 },541 async splittingPublicPath({ esbuild, testDir }) {542 const input1 = path.join(testDir, 'a', 'in1.js')543 const input2 = path.join(testDir, 'b', 'in2.js')544 const shared = path.join(testDir, 'c', 'shared.js')545 const outdir = path.join(testDir, 'out')546 await mkdirAsync(path.dirname(input1), { recursive: true })547 await mkdirAsync(path.dirname(input2), { recursive: true })548 await mkdirAsync(path.dirname(shared), { recursive: true })549 await writeFileAsync(input1, `export {default as input1} from ${JSON.stringify(shared)}`)550 await writeFileAsync(input2, `export {default as input2} from ${JSON.stringify(shared)}`)551 await writeFileAsync(shared, `export default function foo() { return 123 }`)552 const value = await esbuild.build({553 entryPoints: [input1, input2],554 bundle: true,555 outdir,556 format: 'esm',557 splitting: true,558 publicPath: 'https://www.example.com/assets',559 write: false,560 })561 assert.deepStrictEqual(value.outputFiles.length, 3)562 assert.deepStrictEqual(value.outputFiles[0].path, path.join(outdir, 'a', 'in1.js'))563 assert.deepStrictEqual(value.outputFiles[1].path, path.join(outdir, 'b', 'in2.js'))564 assert.deepStrictEqual(value.outputFiles[2].path, path.join(outdir, 'chunk-22JQAFLY.js'))565 assert.deepStrictEqual(value.outputFiles[0].text, `import {566 foo567} from "https://www.example.com/assets/chunk-22JQAFLY.js";568export {569 foo as input1570};571`)572 assert.deepStrictEqual(value.outputFiles[1].text, `import {573 foo574} from "https://www.example.com/assets/chunk-22JQAFLY.js";575export {576 foo as input2577};578`)579 assert.deepStrictEqual(value.outputFiles[2].text, `// scripts/.js-api-tests/splittingPublicPath/c/shared.js580function foo() {581 return 123;582}583export {584 foo585};586`)587 },588 async fileLoaderPublicPath({ esbuild, testDir }) {589 const input = path.join(testDir, 'in.js')590 const data = path.join(testDir, 'data.bin')591 const output = path.join(testDir, 'out.js')592 await writeFileAsync(input, `export {default as value} from ${JSON.stringify(data)}`)593 await writeFileAsync(data, `stuff`)594 const value = await esbuild.build({595 entryPoints: [input],596 bundle: true,597 outfile: output,598 format: 'cjs',599 loader: { '.bin': 'file' },600 publicPath: 'https://www.example.com/assets',601 })602 assert.strictEqual(value.outputFiles, void 0)603 const result = require(output)604 assert.strictEqual(result.value, 'https://www.example.com/assets/data-BYATPJRB.bin')605 assert.strictEqual(result.__esModule, true)606 },607 async fileLoaderCSS({ esbuild, testDir }) {608 const input = path.join(testDir, 'in.css')609 const data = path.join(testDir, 'data.bin')610 const output = path.join(testDir, 'out.css')611 await writeFileAsync(input, `body { background: url(${JSON.stringify(data)}) }`)612 await writeFileAsync(data, `stuff`)613 const value = await esbuild.build({614 entryPoints: [input],615 bundle: true,616 outfile: output,617 loader: { '.bin': 'file' },618 publicPath: 'https://www.example.com/assets',619 })620 assert.strictEqual(value.outputFiles, void 0)621 assert.strictEqual(await readFileAsync(output, 'utf8'), `/* scripts/.js-api-tests/fileLoaderCSS/in.css */622body {623 background: url(https://www.example.com/assets/data-BYATPJRB.bin);624}625`)626 },627 async fileLoaderWithAssetPath({ esbuild, testDir }) {628 const input = path.join(testDir, 'in.js')629 const data = path.join(testDir, 'data.bin')630 const outdir = path.join(testDir, 'out')631 await writeFileAsync(input, `export {default as value} from ${JSON.stringify(data)}`)632 await writeFileAsync(data, `stuff`)633 const value = await esbuild.build({634 entryPoints: [input],635 bundle: true,636 outdir,637 format: 'cjs',638 loader: { '.bin': 'file' },639 assetNames: 'assets/name=[name]/hash=[hash]',640 })641 assert.strictEqual(value.outputFiles, void 0)642 const result = require(path.join(outdir, path.basename(input)))643 assert.strictEqual(result.value, './assets/name=data/hash=BYATPJRB.bin')644 assert.strictEqual(result.__esModule, true)645 const stuff = fs.readFileSync(path.join(outdir, result.value), 'utf8')646 assert.strictEqual(stuff, 'stuff')647 },648 async fileLoaderWithAssetPathAndPublicPath({ esbuild, testDir }) {649 const input = path.join(testDir, 'in.js')650 const data = path.join(testDir, 'data.bin')651 const outdir = path.join(testDir, 'out')652 await writeFileAsync(input, `export {default as value} from ${JSON.stringify(data)}`)653 await writeFileAsync(data, `stuff`)654 const value = await esbuild.build({655 entryPoints: [input],656 bundle: true,657 outdir,658 format: 'cjs',659 loader: { '.bin': 'file' },660 assetNames: 'assets/name=[name]/hash=[hash]',661 publicPath: 'https://www.example.com',662 })663 assert.strictEqual(value.outputFiles, void 0)664 const result = require(path.join(outdir, path.basename(input)))665 assert.strictEqual(result.value, 'https://www.example.com/assets/name=data/hash=BYATPJRB.bin')666 assert.strictEqual(result.__esModule, true)667 const stuff = fs.readFileSync(path.join(outdir, 'assets', 'name=data', 'hash=BYATPJRB.bin'), 'utf8')668 assert.strictEqual(stuff, 'stuff')669 },670 async fileLoaderBinaryVsText({ esbuild, testDir }) {671 const input = path.join(testDir, 'in.js')672 const valid = path.join(testDir, 'valid.bin')673 const invalid = path.join(testDir, 'invalid.bin')674 const output = path.join(testDir, 'out.js')675 await writeFileAsync(input, `676 import valid from ${JSON.stringify(valid)}677 import invalid from ${JSON.stringify(invalid)}678 console.log(valid, invalid)679 `)680 await writeFileAsync(valid, Buffer.from([0xCF, 0x80]))681 await writeFileAsync(invalid, Buffer.from([0x80, 0xCF]))682 const value = await esbuild.build({683 entryPoints: [input],684 bundle: true,685 outfile: output,686 format: 'cjs',687 loader: { '.bin': 'file' },688 write: false,689 })690 assert.strictEqual(value.outputFiles.length, 3)691 // Valid UTF-8 should decode correctly692 assert.deepEqual(value.outputFiles[0].contents, new Uint8Array([207, 128]))693 assert.strictEqual(value.outputFiles[0].text, 'Ï')694 // Invalid UTF-8 should be preserved as bytes but should be replaced by the U+FFFD replacement character when decoded695 assert.deepEqual(value.outputFiles[1].contents, new Uint8Array([128, 207]))696 assert.strictEqual(value.outputFiles[1].text, '\uFFFD\uFFFD')697 },698 async metafile({ esbuild, testDir }) {699 const entry = path.join(testDir, 'entry.js')700 const imported = path.join(testDir, 'imported.js')701 const text = path.join(testDir, 'text.txt')702 const css = path.join(testDir, 'example.css')703 const outputJS = path.join(testDir, 'out.js')704 const outputCSS = path.join(testDir, 'out.css')705 await writeFileAsync(entry, `706 import x from "./imported"707 const y = require("./text.txt")708 import * as z from "./example.css"709 console.log(x, y, z)710 `)711 await writeFileAsync(imported, 'export default 123')712 await writeFileAsync(text, 'some text')713 await writeFileAsync(css, 'body { some: css; }')714 const result = await esbuild.build({715 entryPoints: [entry],716 bundle: true,717 outfile: outputJS,718 metafile: true,719 sourcemap: true,720 loader: { '.txt': 'file' },721 })722 const json = result.metafile723 assert.strictEqual(Object.keys(json.inputs).length, 4)724 assert.strictEqual(Object.keys(json.outputs).length, 5)725 const cwd = process.cwd()726 const makePath = absPath => path.relative(cwd, absPath).split(path.sep).join('/')727 // Check inputs728 assert.deepStrictEqual(json.inputs[makePath(entry)].bytes, 144)729 assert.deepStrictEqual(json.inputs[makePath(entry)].imports, [730 { path: makePath(imported), kind: 'import-statement' },731 { path: makePath(css), kind: 'import-statement' },732 { path: makePath(text), kind: 'require-call' },733 ])734 assert.deepStrictEqual(json.inputs[makePath(imported)].bytes, 18)735 assert.deepStrictEqual(json.inputs[makePath(imported)].imports, [])736 assert.deepStrictEqual(json.inputs[makePath(text)].bytes, 9)737 assert.deepStrictEqual(json.inputs[makePath(text)].imports, [])738 assert.deepStrictEqual(json.inputs[makePath(css)].bytes, 19)739 assert.deepStrictEqual(json.inputs[makePath(css)].imports, [])740 // Check outputs741 assert.strictEqual(typeof json.outputs[makePath(outputJS)].bytes, 'number')742 assert.strictEqual(typeof json.outputs[makePath(outputCSS)].bytes, 'number')743 assert.strictEqual(typeof json.outputs[makePath(outputJS) + '.map'].bytes, 'number')744 assert.strictEqual(typeof json.outputs[makePath(outputCSS) + '.map'].bytes, 'number')745 assert.strictEqual(json.outputs[makePath(outputJS)].entryPoint, makePath(entry))746 assert.strictEqual(json.outputs[makePath(outputCSS)].entryPoint, undefined) // This is deliberately undefined747 assert.deepStrictEqual(json.outputs[makePath(outputJS) + '.map'].imports, [])748 assert.deepStrictEqual(json.outputs[makePath(outputJS) + '.map'].exports, [])749 assert.deepStrictEqual(json.outputs[makePath(outputJS) + '.map'].inputs, {})750 assert.deepStrictEqual(json.outputs[makePath(outputCSS) + '.map'].imports, [])751 assert.deepStrictEqual(json.outputs[makePath(outputCSS) + '.map'].exports, [])752 assert.deepStrictEqual(json.outputs[makePath(outputCSS) + '.map'].inputs, {})753 // Check inputs for main output754 const outputInputs = json.outputs[makePath(outputJS)].inputs755 assert.strictEqual(Object.keys(outputInputs).length, 4)756 assert.strictEqual(typeof outputInputs[makePath(entry)].bytesInOutput, 'number')757 assert.strictEqual(typeof outputInputs[makePath(imported)].bytesInOutput, 'number')758 assert.strictEqual(typeof outputInputs[makePath(text)].bytesInOutput, 'number')759 assert.strictEqual(typeof outputInputs[makePath(css)].bytesInOutput, 'number')760 },761 async metafileSplitting({ esbuild, testDir }) {762 const entry1 = path.join(testDir, 'entry1.js')763 const entry2 = path.join(testDir, 'entry2.js')764 const imported = path.join(testDir, 'imported.js')765 const outdir = path.join(testDir, 'out')766 await writeFileAsync(entry1, `767 import x, {f1} from "./${path.basename(imported)}"768 console.log(1, x, f1())769 export {x}770 `)771 await writeFileAsync(entry2, `772 import x, {f2} from "./${path.basename(imported)}"773 console.log('entry 2', x, f2())774 export {x as y}775 `)776 await writeFileAsync(imported, `777 export default 123778 export function f1() {}779 export function f2() {}780 console.log('shared')781 `)782 const result = await esbuild.build({783 entryPoints: [entry1, entry2],784 bundle: true,785 outdir,786 metafile: true,787 splitting: true,788 format: 'esm',789 })790 const json = result.metafile791 assert.strictEqual(Object.keys(json.inputs).length, 3)792 assert.strictEqual(Object.keys(json.outputs).length, 3)793 const cwd = process.cwd()794 const makeOutPath = basename => path.relative(cwd, path.join(outdir, basename)).split(path.sep).join('/')795 const makeInPath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')796 // Check metafile797 const inEntry1 = makeInPath(entry1);798 const inEntry2 = makeInPath(entry2);799 const inImported = makeInPath(imported);800 const chunk = 'chunk-YNV25ITT.js';801 const outEntry1 = makeOutPath(path.basename(entry1));802 const outEntry2 = makeOutPath(path.basename(entry2));803 const outChunk = makeOutPath(chunk);804 assert.deepStrictEqual(json.inputs[inEntry1], { bytes: 94, imports: [{ path: inImported, kind: 'import-statement' }] })805 assert.deepStrictEqual(json.inputs[inEntry2], { bytes: 107, imports: [{ path: inImported, kind: 'import-statement' }] })806 assert.deepStrictEqual(json.inputs[inImported], { bytes: 118, imports: [] })807 assert.deepStrictEqual(json.outputs[outEntry1].imports, [{ path: makeOutPath(chunk), kind: 'import-statement' }])808 assert.deepStrictEqual(json.outputs[outEntry2].imports, [{ path: makeOutPath(chunk), kind: 'import-statement' }])809 assert.deepStrictEqual(json.outputs[outChunk].imports, [])810 assert.deepStrictEqual(json.outputs[outEntry1].exports, ['x'])811 assert.deepStrictEqual(json.outputs[outEntry2].exports, ['y'])812 assert.deepStrictEqual(json.outputs[outChunk].exports, ['f1', 'f2', 'imported_default'])813 assert.deepStrictEqual(json.outputs[outEntry1].inputs, { [inEntry1]: { bytesInOutput: 40 } })814 assert.deepStrictEqual(json.outputs[outEntry2].inputs, { [inEntry2]: { bytesInOutput: 48 } })815 assert.deepStrictEqual(json.outputs[outChunk].inputs, { [inImported]: { bytesInOutput: 87 } })816 },817 async metafileSplittingPublicPath({ esbuild, testDir }) {818 const entry1 = path.join(testDir, 'entry1.js')819 const entry2 = path.join(testDir, 'entry2.js')820 const imported = path.join(testDir, 'imported.js')821 const outdir = path.join(testDir, 'out')822 await writeFileAsync(entry1, `823 import x, {f1} from "./${path.basename(imported)}"824 console.log(1, x, f1())825 export {x}826 `)827 await writeFileAsync(entry2, `828 import x, {f2} from "./${path.basename(imported)}"829 console.log('entry 2', x, f2())830 export {x as y}831 `)832 await writeFileAsync(imported, `833 export default 123834 export function f1() {}835 export function f2() {}836 console.log('shared')837 `)838 const result = await esbuild.build({839 entryPoints: [entry1, entry2],840 bundle: true,841 outdir,842 metafile: true,843 splitting: true,844 format: 'esm',845 publicPath: 'public',846 })847 const json = result.metafile848 assert.strictEqual(Object.keys(json.inputs).length, 3)849 assert.strictEqual(Object.keys(json.outputs).length, 3)850 const cwd = process.cwd()851 const makeOutPath = basename => path.relative(cwd, path.join(outdir, basename)).split(path.sep).join('/')852 const makeInPath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')853 // Check metafile854 const inEntry1 = makeInPath(entry1);855 const inEntry2 = makeInPath(entry2);856 const inImported = makeInPath(imported);857 const chunk = 'chunk-MDV3DDWZ.js';858 const outEntry1 = makeOutPath(path.basename(entry1));859 const outEntry2 = makeOutPath(path.basename(entry2));860 const outChunk = makeOutPath(chunk);861 assert.deepStrictEqual(json.inputs[inEntry1], { bytes: 94, imports: [{ path: inImported, kind: 'import-statement' }] })862 assert.deepStrictEqual(json.inputs[inEntry2], { bytes: 107, imports: [{ path: inImported, kind: 'import-statement' }] })863 assert.deepStrictEqual(json.inputs[inImported], { bytes: 118, imports: [] })864 assert.deepStrictEqual(json.outputs[outEntry1].imports, [{ path: makeOutPath(chunk), kind: 'import-statement' }])865 assert.deepStrictEqual(json.outputs[outEntry2].imports, [{ path: makeOutPath(chunk), kind: 'import-statement' }])866 assert.deepStrictEqual(json.outputs[outChunk].imports, [])867 assert.deepStrictEqual(json.outputs[outEntry1].exports, ['x'])868 assert.deepStrictEqual(json.outputs[outEntry2].exports, ['y'])869 assert.deepStrictEqual(json.outputs[outChunk].exports, ['f1', 'f2', 'imported_default'])870 assert.deepStrictEqual(json.outputs[outEntry1].inputs, { [inEntry1]: { bytesInOutput: 40 } })871 assert.deepStrictEqual(json.outputs[outEntry2].inputs, { [inEntry2]: { bytesInOutput: 48 } })872 assert.deepStrictEqual(json.outputs[outChunk].inputs, { [inImported]: { bytesInOutput: 87 } })873 },874 async metafileSplittingDoubleDynamicImport({ esbuild, testDir }) {875 const entry = path.join(testDir, 'entry.js')876 const importDir = path.join(testDir, 'import-dir')877 const import1 = path.join(importDir, 'import1.js')878 const import2 = path.join(importDir, 'import2.js')879 const shared = path.join(testDir, 'shared.js')880 const outdir = path.join(testDir, 'out')881 const makeImportPath = (importing, imported) => JSON.stringify('./' + path.relative(path.dirname(importing), imported).split(path.sep).join('/'))882 await mkdirAsync(importDir)883 await writeFileAsync(entry, `884 import ${makeImportPath(entry, shared)}885 import(${makeImportPath(entry, import1)})886 import(${makeImportPath(entry, import2)})887 `)888 await writeFileAsync(import1, `889 import ${makeImportPath(import1, shared)}890 `)891 await writeFileAsync(import2, `892 import ${makeImportPath(import2, shared)}893 `)894 await writeFileAsync(shared, `895 console.log('side effect')896 `)897 const result = await esbuild.build({898 entryPoints: [entry],899 bundle: true,900 outdir,901 metafile: true,902 splitting: true,903 format: 'esm',904 })905 const json = result.metafile906 assert.strictEqual(Object.keys(json.inputs).length, 4)907 assert.strictEqual(Object.keys(json.outputs).length, 4)908 const cwd = process.cwd()909 const makeOutPath = basename => path.relative(cwd, path.join(outdir, basename)).split(path.sep).join('/')910 const makeInPath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')911 // Check metafile912 const inEntry = makeInPath(entry);913 const inImport1 = makeInPath(import1);914 const inImport2 = makeInPath(import2);915 const inShared = makeInPath(shared);916 const chunk = 'chunk-3GRHLZ7X.js';917 const outEntry = makeOutPath(path.relative(testDir, entry));918 const outImport1 = makeOutPath('import1-SELM3ZIG.js');919 const outImport2 = makeOutPath('import2-3GSTEHBF.js');920 const outChunk = makeOutPath(chunk);921 assert.deepStrictEqual(json.inputs[inEntry], {922 bytes: 112,923 imports: [924 { path: inShared, kind: 'import-statement' },925 { path: inImport1, kind: 'dynamic-import' },926 { path: inImport2, kind: 'dynamic-import' },927 ]928 })929 assert.deepStrictEqual(json.inputs[inImport1], {930 bytes: 35,931 imports: [932 { path: inShared, kind: 'import-statement' },933 ]934 })935 assert.deepStrictEqual(json.inputs[inImport2], {936 bytes: 35,937 imports: [938 { path: inShared, kind: 'import-statement' },939 ]940 })941 assert.deepStrictEqual(json.inputs[inShared], { bytes: 38, imports: [] })942 assert.deepStrictEqual(Object.keys(json.outputs), [943 outEntry,944 outImport1,945 outImport2,946 outChunk,947 ])948 assert.deepStrictEqual(json.outputs[outEntry].imports, [949 { path: outImport1, kind: 'dynamic-import' },950 { path: outImport2, kind: 'dynamic-import' },951 { path: outChunk, kind: 'import-statement' },952 ])953 assert.deepStrictEqual(json.outputs[outImport1].imports, [{ path: outChunk, kind: 'import-statement' }])954 assert.deepStrictEqual(json.outputs[outImport2].imports, [{ path: outChunk, kind: 'import-statement' }])955 assert.deepStrictEqual(json.outputs[outChunk].imports, [])956 assert.deepStrictEqual(json.outputs[outEntry].exports, [])957 assert.deepStrictEqual(json.outputs[outImport1].exports, [])958 assert.deepStrictEqual(json.outputs[outImport2].exports, [])959 assert.deepStrictEqual(json.outputs[outChunk].exports, [])960 assert.deepStrictEqual(json.outputs[outEntry].inputs, { [inEntry]: { bytesInOutput: 74 } })961 assert.deepStrictEqual(json.outputs[outImport1].inputs, { [inImport1]: { bytesInOutput: 0 } })962 assert.deepStrictEqual(json.outputs[outImport2].inputs, { [inImport2]: { bytesInOutput: 0 } })963 assert.deepStrictEqual(json.outputs[outChunk].inputs, { [inShared]: { bytesInOutput: 28 } })964 },965 async metafileCJSInFormatIIFE({ esbuild, testDir }) {966 const entry = path.join(testDir, 'entry.js')967 const outfile = path.join(testDir, 'out.js')968 await writeFileAsync(entry, `module.exports = {}`)969 const result = await esbuild.build({970 entryPoints: [entry],971 outfile,972 metafile: true,973 format: 'iife',974 })975 const cwd = process.cwd()976 const makePath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')977 const json = result.metafile978 assert.deepStrictEqual(json.inputs[makePath(entry)].imports, [])979 assert.deepStrictEqual(json.outputs[makePath(outfile)].imports, [])980 assert.deepStrictEqual(json.outputs[makePath(outfile)].exports, [])981 },982 async metafileCJSInFormatCJS({ esbuild, testDir }) {983 const entry = path.join(testDir, 'entry.js')984 const outfile = path.join(testDir, 'out.js')985 await writeFileAsync(entry, `module.exports = {}`)986 const result = await esbuild.build({987 entryPoints: [entry],988 outfile,989 metafile: true,990 format: 'cjs',991 })992 const cwd = process.cwd()993 const makePath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')994 const json = result.metafile995 assert.deepStrictEqual(json.inputs[makePath(entry)].imports, [])996 assert.deepStrictEqual(json.outputs[makePath(outfile)].imports, [])997 assert.deepStrictEqual(json.outputs[makePath(outfile)].exports, [])998 assert.deepStrictEqual(json.outputs[makePath(outfile)].entryPoint, makePath(entry))999 },1000 async metafileCJSInFormatESM({ esbuild, testDir }) {1001 const entry = path.join(testDir, 'entry.js')1002 const outfile = path.join(testDir, 'out.js')1003 await writeFileAsync(entry, `module.exports = {}`)1004 const result = await esbuild.build({1005 entryPoints: [entry],1006 outfile,1007 metafile: true,1008 format: 'esm',1009 })1010 const cwd = process.cwd()1011 const makePath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')1012 const json = result.metafile1013 assert.deepStrictEqual(json.inputs[makePath(entry)].imports, [])1014 assert.deepStrictEqual(json.outputs[makePath(outfile)].imports, [])1015 assert.deepStrictEqual(json.outputs[makePath(outfile)].exports, ['default'])1016 },1017 async metafileESMInFormatIIFE({ esbuild, testDir }) {1018 const entry = path.join(testDir, 'entry.js')1019 const outfile = path.join(testDir, 'out.js')1020 await writeFileAsync(entry, `export let a = 1, b = 2`)1021 const result = await esbuild.build({1022 entryPoints: [entry],1023 outfile,1024 metafile: true,1025 format: 'iife',1026 })1027 const cwd = process.cwd()1028 const makePath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')1029 const json = result.metafile1030 assert.deepStrictEqual(json.inputs[makePath(entry)].imports, [])1031 assert.deepStrictEqual(json.outputs[makePath(outfile)].imports, [])1032 assert.deepStrictEqual(json.outputs[makePath(outfile)].exports, [])1033 },1034 async metafileESMInFormatCJS({ esbuild, testDir }) {1035 const entry = path.join(testDir, 'entry.js')1036 const outfile = path.join(testDir, 'out.js')1037 await writeFileAsync(entry, `export let a = 1, b = 2`)1038 const result = await esbuild.build({1039 entryPoints: [entry],1040 outfile,1041 metafile: true,1042 format: 'cjs',1043 })1044 const cwd = process.cwd()1045 const makePath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')1046 const json = result.metafile1047 assert.deepStrictEqual(json.inputs[makePath(entry)].imports, [])1048 assert.deepStrictEqual(json.outputs[makePath(outfile)].imports, [])1049 assert.deepStrictEqual(json.outputs[makePath(outfile)].exports, [])1050 },1051 async metafileESMInFormatESM({ esbuild, testDir }) {1052 const entry = path.join(testDir, 'entry.js')1053 const outfile = path.join(testDir, 'out.js')1054 await writeFileAsync(entry, `export let a = 1, b = 2`)1055 const result = await esbuild.build({1056 entryPoints: [entry],1057 outfile,1058 metafile: true,1059 format: 'esm',1060 })1061 const cwd = process.cwd()1062 const makePath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')1063 const json = result.metafile1064 assert.deepStrictEqual(json.inputs[makePath(entry)].imports, [])1065 assert.deepStrictEqual(json.outputs[makePath(outfile)].imports, [])1066 assert.deepStrictEqual(json.outputs[makePath(outfile)].exports, ['a', 'b'])1067 },1068 async metafileNestedExportNames({ esbuild, testDir }) {1069 const entry = path.join(testDir, 'entry.js')1070 const nested1 = path.join(testDir, 'nested1.js')1071 const nested2 = path.join(testDir, 'nested2.js')1072 const nested3 = path.join(testDir, 'nested3.js')1073 const outfile = path.join(testDir, 'out.js')1074 await writeFileAsync(entry, `1075 export {nested1} from ${JSON.stringify(nested1)}1076 export * from ${JSON.stringify(nested2)}1077 export let topLevel = 01078 `)1079 await writeFileAsync(nested1, `1080 import {nested3} from ${JSON.stringify(nested3)}1081 export default 11082 export let nested1 = nested31083 `)1084 await writeFileAsync(nested2, `1085 export default 'nested2'1086 export let nested2 = 21087 `)1088 await writeFileAsync(nested3, `1089 export let nested3 = 31090 `)1091 const result = await esbuild.build({1092 entryPoints: [entry],1093 bundle: true,1094 outfile,1095 metafile: true,1096 format: 'esm',1097 })1098 const cwd = process.cwd()1099 const makePath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')1100 const json = result.metafile1101 assert.deepStrictEqual(json.inputs[makePath(entry)].imports, [1102 { path: makePath(nested1), kind: 'import-statement' },1103 { path: makePath(nested2), kind: 'import-statement' },1104 ])1105 assert.deepStrictEqual(json.inputs[makePath(nested1)].imports, [1106 { path: makePath(nested3), kind: 'import-statement' },1107 ])1108 assert.deepStrictEqual(json.inputs[makePath(nested2)].imports, [])1109 assert.deepStrictEqual(json.inputs[makePath(nested3)].imports, [])1110 assert.deepStrictEqual(json.outputs[makePath(outfile)].imports, [])1111 assert.deepStrictEqual(json.outputs[makePath(outfile)].exports, ['nested1', 'nested2', 'topLevel'])1112 assert.deepStrictEqual(json.outputs[makePath(outfile)].entryPoint, makePath(entry))1113 },1114 async metafileCSS({ esbuild, testDir }) {1115 const entry = path.join(testDir, 'entry.css')1116 const imported = path.join(testDir, 'imported.css')1117 const image = path.join(testDir, 'example.png')1118 const output = path.join(testDir, 'out.css')1119 await writeFileAsync(entry, `1120 @import "./imported";1121 body { background: url(https://example.com/external.png) }1122 `)1123 await writeFileAsync(imported, `1124 a { background: url(./example.png) }1125 `)1126 await writeFileAsync(image, 'an image')1127 const result = await esbuild.build({1128 entryPoints: [entry],1129 bundle: true,1130 outfile: output,1131 metafile: true,1132 sourcemap: true,1133 loader: { '.png': 'dataurl' },1134 })1135 const json = result.metafile1136 assert.strictEqual(Object.keys(json.inputs).length, 3)1137 assert.strictEqual(Object.keys(json.outputs).length, 2)1138 const cwd = process.cwd()1139 const makePath = absPath => path.relative(cwd, absPath).split(path.sep).join('/')1140 // Check inputs1141 assert.deepStrictEqual(json, {1142 inputs: {1143 [makePath(entry)]: { bytes: 98, imports: [{ path: makePath(imported), kind: 'import-rule' }] },1144 [makePath(image)]: { bytes: 8, imports: [] },1145 [makePath(imported)]: { bytes: 48, imports: [{ path: makePath(image), kind: 'url-token' }] },1146 },1147 outputs: {1148 [makePath(output)]: {1149 bytes: 263,1150 entryPoint: makePath(entry),1151 imports: [],1152 inputs: {1153 [makePath(entry)]: { bytesInOutput: 62 },1154 [makePath(imported)]: { bytesInOutput: 61 },1155 },1156 },1157 [makePath(output + '.map')]: {1158 bytes: 312,1159 exports: [],1160 imports: [],1161 inputs: {},1162 },1163 },1164 })1165 },1166 async metafileLoaderFileMultipleEntry({ esbuild, testDir }) {1167 const entry1 = path.join(testDir, 'entry1.js')1168 const entry2 = path.join(testDir, 'entry2.js')1169 const file = path.join(testDir, 'x.file')1170 const outdir = path.join(testDir, 'out')1171 await writeFileAsync(entry1, `1172 export {default} from './x.file'1173 `)1174 await writeFileAsync(entry2, `1175 import z from './x.file'1176 console.log(z)1177 `)1178 await writeFileAsync(file, `This is a file`)1179 const result = await esbuild.build({1180 entryPoints: [entry1, entry2],1181 bundle: true,1182 loader: { '.file': 'file' },1183 outdir,1184 metafile: true,1185 format: 'cjs',1186 })1187 const json = result.metafile1188 const cwd = process.cwd()1189 const makePath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')1190 const fileName = require(path.join(outdir, 'entry1.js')).default1191 const fileKey = makePath(path.join(outdir, fileName))1192 assert.deepStrictEqual(json.outputs[fileKey].imports, [])1193 assert.deepStrictEqual(json.outputs[fileKey].exports, [])1194 assert.deepStrictEqual(json.outputs[fileKey].inputs, { [makePath(file)]: { bytesInOutput: 14 } })1195 },1196 // Test in-memory output files1197 async writeFalse({ esbuild, testDir }) {1198 const input = path.join(testDir, 'in.js')1199 const output = path.join(testDir, 'out.js')1200 const inputCode = 'console.log()'1201 await writeFileAsync(input, inputCode)1202 const value = await esbuild.build({1203 entryPoints: [input],1204 bundle: true,1205 outfile: output,1206 sourcemap: true,1207 format: 'esm',1208 metafile: true,1209 write: false,1210 })1211 assert.strictEqual(fs.existsSync(output), false)1212 assert.notStrictEqual(value.outputFiles, void 0)1213 assert.strictEqual(value.outputFiles.length, 2)1214 assert.strictEqual(value.outputFiles[0].path, output + '.map')1215 assert.strictEqual(value.outputFiles[0].contents.constructor, Uint8Array)1216 assert.strictEqual(value.outputFiles[1].path, output)1217 assert.strictEqual(value.outputFiles[1].contents.constructor, Uint8Array)1218 const sourceMap = JSON.parse(Buffer.from(value.outputFiles[0].contents).toString())1219 const js = Buffer.from(value.outputFiles[1].contents).toString()1220 assert.strictEqual(sourceMap.version, 3)1221 assert.strictEqual(js, `// scripts/.js-api-tests/writeFalse/in.js\nconsole.log();\n//# sourceMappingURL=out.js.map\n`)1222 const cwd = process.cwd()1223 const makePath = file => path.relative(cwd, file).split(path.sep).join('/')1224 const meta = value.metafile1225 assert.strictEqual(meta.inputs[makePath(input)].bytes, inputCode.length)1226 assert.strictEqual(meta.outputs[makePath(output)].bytes, js.length)1227 assert.strictEqual(meta.outputs[makePath(output + '.map')].bytes, value.outputFiles[0].contents.length)1228 },1229 async allowOverwrite({ esbuild, testDir }) {1230 const input = path.join(testDir, 'in.mjs')1231 await writeFileAsync(input, `export default FOO`)1232 // Fail without "allowOverwrite"1233 try {1234 await esbuild.build({1235 entryPoints: [input],1236 outfile: input,1237 logLevel: 'silent',1238 })1239 throw new Error('Expected build failure');1240 } catch (e) {1241 if (!e || !e.errors || !e.errors.length || !e.errors[0].text.includes('Refusing to overwrite input file'))1242 throw e1243 }1244 // Succeed with "allowOverwrite"1245 await esbuild.build({1246 entryPoints: [input],1247 outfile: input,1248 allowOverwrite: true,1249 define: { FOO: '123' },1250 })1251 // This needs to use relative paths to avoid breaking on Windows.1252 // Importing by absolute path doesn't work on Windows in node.1253 const result = await import('./' + path.relative(__dirname, input))1254 assert.strictEqual(result.default, 123)1255 },1256 async splittingRelativeSameDir({ esbuild, testDir }) {1257 const inputA = path.join(testDir, 'a.js')1258 const inputB = path.join(testDir, 'b.js')1259 const inputCommon = path.join(testDir, 'common.js')1260 await writeFileAsync(inputA, `1261 import x from "./${path.basename(inputCommon)}"1262 console.log('a' + x)1263 `)1264 await writeFileAsync(inputB, `1265 import x from "./${path.basename(inputCommon)}"1266 console.log('b' + x)1267 `)1268 await writeFileAsync(inputCommon, `1269 export default 'common'1270 `)1271 const outdir = path.join(testDir, 'out')1272 const value = await esbuild.build({1273 entryPoints: [inputA, inputB],1274 bundle: true,1275 outdir,1276 format: 'esm',1277 splitting: true,1278 write: false,1279 })1280 assert.strictEqual(value.outputFiles.length, 3)1281 // These should all use forward slashes, even on Windows1282 const chunk = 'chunk-P3NHLAOZ.js'1283 assert.strictEqual(Buffer.from(value.outputFiles[0].contents).toString(), `import {1284 common_default1285} from "./${chunk}";1286// scripts/.js-api-tests/splittingRelativeSameDir/a.js1287console.log("a" + common_default);1288`)1289 assert.strictEqual(Buffer.from(value.outputFiles[1].contents).toString(), `import {1290 common_default1291} from "./${chunk}";1292// scripts/.js-api-tests/splittingRelativeSameDir/b.js1293console.log("b" + common_default);1294`)1295 assert.strictEqual(Buffer.from(value.outputFiles[2].contents).toString(), `// scripts/.js-api-tests/splittingRelativeSameDir/common.js1296var common_default = "common";1297export {1298 common_default1299};1300`)1301 assert.strictEqual(value.outputFiles[0].path, path.join(outdir, path.basename(inputA)))1302 assert.strictEqual(value.outputFiles[1].path, path.join(outdir, path.basename(inputB)))1303 assert.strictEqual(value.outputFiles[2].path, path.join(outdir, chunk))1304 },1305 async splittingRelativeNestedDir({ esbuild, testDir }) {1306 const inputA = path.join(testDir, 'a/demo.js')1307 const inputB = path.join(testDir, 'b/demo.js')1308 const inputCommon = path.join(testDir, 'common.js')1309 await mkdirAsync(path.dirname(inputA)).catch(x => x)1310 await mkdirAsync(path.dirname(inputB)).catch(x => x)1311 await writeFileAsync(inputA, `1312 import x from "../${path.basename(inputCommon)}"1313 console.log('a' + x)1314 `)1315 await writeFileAsync(inputB, `1316 import x from "../${path.basename(inputCommon)}"1317 console.log('b' + x)1318 `)1319 await writeFileAsync(inputCommon, `1320 export default 'common'1321 `)1322 const outdir = path.join(testDir, 'out')1323 const value = await esbuild.build({1324 entryPoints: [inputA, inputB],1325 bundle: true,1326 outdir,1327 format: 'esm',1328 splitting: true,1329 write: false,1330 })1331 assert.strictEqual(value.outputFiles.length, 3)1332 // These should all use forward slashes, even on Windows1333 const chunk = 'chunk-BPDO6GL2.js'1334 assert.strictEqual(Buffer.from(value.outputFiles[0].contents).toString(), `import {1335 common_default1336} from "../${chunk}";1337// scripts/.js-api-tests/splittingRelativeNestedDir/a/demo.js1338console.log("a" + common_default);1339`)1340 assert.strictEqual(Buffer.from(value.outputFiles[1].contents).toString(), `import {1341 common_default1342} from "../${chunk}";1343// scripts/.js-api-tests/splittingRelativeNestedDir/b/demo.js1344console.log("b" + common_default);1345`)1346 assert.strictEqual(Buffer.from(value.outputFiles[2].contents).toString(), `// scripts/.js-api-tests/splittingRelativeNestedDir/common.js1347var common_default = "common";1348export {1349 common_default1350};1351`)1352 assert.strictEqual(value.outputFiles[0].path, path.join(outdir, path.relative(testDir, inputA)))1353 assert.strictEqual(value.outputFiles[1].path, path.join(outdir, path.relative(testDir, inputB)))1354 assert.strictEqual(value.outputFiles[2].path, path.join(outdir, chunk))1355 },1356 async splittingWithChunkPath({ esbuild, testDir }) {1357 const inputA = path.join(testDir, 'a/demo.js')1358 const inputB = path.join(testDir, 'b/demo.js')1359 const inputCommon = path.join(testDir, 'common.js')1360 await mkdirAsync(path.dirname(inputA)).catch(x => x)1361 await mkdirAsync(path.dirname(inputB)).catch(x => x)1362 await writeFileAsync(inputA, `1363 import x from "../${path.basename(inputCommon)}"1364 console.log('a' + x)1365 `)1366 await writeFileAsync(inputB, `1367 import x from "../${path.basename(inputCommon)}"1368 console.log('b' + x)1369 `)1370 await writeFileAsync(inputCommon, `1371 export default 'common'1372 `)1373 const outdir = path.join(testDir, 'out')1374 const value = await esbuild.build({1375 entryPoints: [inputA, inputB],1376 bundle: true,1377 outdir,1378 format: 'esm',1379 splitting: true,1380 write: false,1381 chunkNames: 'chunks/name=[name]/hash=[hash]',1382 })1383 assert.strictEqual(value.outputFiles.length, 3)1384 // These should all use forward slashes, even on Windows1385 const chunk = 'chunks/name=chunk/hash=7RIY4OCQ.js'1386 assert.strictEqual(value.outputFiles[0].text, `import {1387 common_default1388} from "../${chunk}";1389// scripts/.js-api-tests/splittingWithChunkPath/a/demo.js1390console.log("a" + common_default);1391`)1392 assert.strictEqual(value.outputFiles[1].text, `import {1393 common_default1394} from "../${chunk}";1395// scripts/.js-api-tests/splittingWithChunkPath/b/demo.js1396console.log("b" + common_default);1397`)1398 assert.strictEqual(value.outputFiles[2].text, `// scripts/.js-api-tests/splittingWithChunkPath/common.js1399var common_default = "common";1400export {1401 common_default1402};1403`)1404 assert.strictEqual(value.outputFiles[0].path, path.join(outdir, path.relative(testDir, inputA)))1405 assert.strictEqual(value.outputFiles[1].path, path.join(outdir, path.relative(testDir, inputB)))1406 assert.strictEqual(value.outputFiles[2].path, path.join(outdir, chunk))1407 },1408 async splittingWithEntryHashes({ esbuild, testDir }) {1409 const inputA = path.join(testDir, 'a/demo.js')1410 const inputB = path.join(testDir, 'b/demo.js')1411 const inputCommon = path.join(testDir, 'common.js')1412 await mkdirAsync(path.dirname(inputA)).catch(x => x)1413 await mkdirAsync(path.dirname(inputB)).catch(x => x)1414 await writeFileAsync(inputA, `1415 import x from "../${path.basename(inputCommon)}"1416 console.log('a' + x.name)1417 `)1418 await writeFileAsync(inputB, `1419 import x from "../${path.basename(inputCommon)}"1420 console.log('b' + x.name)1421 `)1422 await writeFileAsync(inputCommon, `1423 export default { name: 'common' }1424 `)1425 const outdir = path.join(testDir, 'out')1426 const value = await esbuild.build({1427 entryPoints: [inputA, inputB],1428 bundle: true,1429 outdir,1430 format: 'esm',1431 splitting: true,1432 write: false,1433 entryNames: 'entry/name=[name]/hash=[hash]',1434 chunkNames: 'chunks/name=[name]/hash=[hash]',1435 })1436 assert.strictEqual(value.outputFiles.length, 3)1437 // These should all use forward slashes, even on Windows1438 const chunk = 'chunks/name=chunk/hash=6VLJRT45.js'1439 assert.strictEqual(value.outputFiles[0].text, `import {1440 common_default1441} from "../../${chunk}";1442// scripts/.js-api-tests/splittingWithEntryHashes/a/demo.js1443console.log("a" + common_default.name);1444`)1445 assert.strictEqual(value.outputFiles[1].text, `import {1446 common_default1447} from "../../${chunk}";1448// scripts/.js-api-tests/splittingWithEntryHashes/b/demo.js1449console.log("b" + common_default.name);1450`)1451 assert.strictEqual(value.outputFiles[2].text, `// scripts/.js-api-tests/splittingWithEntryHashes/common.js1452var common_default = { name: "common" };1453export {1454 common_default1455};1456`)1457 const outputA = 'entry/name=demo/hash=ZKX5HN4L.js'1458 const outputB = 'entry/name=demo/hash=TYTZIN4P.js'1459 assert.strictEqual(value.outputFiles[0].path, path.join(outdir, outputA))1460 assert.strictEqual(value.outputFiles[1].path, path.join(outdir, outputB))1461 assert.strictEqual(value.outputFiles[2].path, path.join(outdir, chunk))1462 },1463 async splittingWithChunkPathAndCrossChunkImportsIssue899({ esbuild, testDir }) {1464 const entry1 = path.join(testDir, 'src', 'entry1.js')1465 const entry2 = path.join(testDir, 'src', 'entry2.js')1466 const entry3 = path.join(testDir, 'src', 'entry3.js')1467 const shared1 = path.join(testDir, 'src', 'shared1.js')1468 const shared2 = path.join(testDir, 'src', 'shared2.js')1469 const shared3 = path.join(testDir, 'src', 'shared3.js')1470 await mkdirAsync(path.join(testDir, 'src')).catch(x => x)1471 await writeFileAsync(entry1, `1472 import { shared1 } from './shared1';1473 import { shared2 } from './shared2';1474 export default async function() {1475 return shared1() + shared2();1476 }1477 `)1478 await writeFileAsync(entry2, `1479 import { shared2 } from './shared2';1480 import { shared3 } from './shared3';1481 export default async function() {1482 return shared2() + shared3();1483 }1484 `)1485 await writeFileAsync(entry3, `1486 import { shared3 } from './shared3';1487 import { shared1 } from './shared1';1488 export default async function() {1489 return shared3() + shared1();1490 }1491 `)1492 await writeFileAsync(shared1, `1493 import { shared2 } from './shared2';1494 export function shared1() {1495 return shared2().replace('2', '1');1496 }1497 `)1498 await writeFileAsync(shared2, `1499 import { shared3 } from './shared3'1500 export function shared2() {1501 return 'shared2';1502 }1503 `)1504 await writeFileAsync(shared3, `1505 export function shared3() {1506 return 'shared3';1507 }1508 `)1509 const outdir = path.join(testDir, 'out')1510 await esbuild.build({1511 entryPoints: [entry1, entry2, entry3],1512 bundle: true,1513 outdir,1514 format: 'esm',1515 splitting: true,1516 outExtension: { '.js': '.mjs' },1517 chunkNames: 'chunks/[hash]/[name]',1518 })1519 // This needs to use relative paths to avoid breaking on Windows.1520 // Importing by absolute path doesn't work on Windows in node.1521 const result1 = await import('./' + path.relative(__dirname, path.join(outdir, 'entry1.mjs')))1522 const result2 = await import('./' + path.relative(__dirname, path.join(outdir, 'entry2.mjs')))1523 const result3 = await import('./' + path.relative(__dirname, path.join(outdir, 'entry3.mjs')))1524 assert.strictEqual(await result1.default(), 'shared1shared2');1525 assert.strictEqual(await result2.default(), 'shared2shared3');1526 assert.strictEqual(await result3.default(), 'shared3shared1');1527 },1528 async splittingStaticImportHashChange({ esbuild, testDir }) {1529 const input1 = path.join(testDir, 'a', 'in1.js')1530 const input2 = path.join(testDir, 'b', 'in2.js')1531 const outdir = path.join(testDir, 'out')1532 await mkdirAsync(path.dirname(input1), { recursive: true })1533 await mkdirAsync(path.dirname(input2), { recursive: true })1534 await writeFileAsync(input1, `import ${JSON.stringify(input2)}`)1535 await writeFileAsync(input2, `console.log(123)`)1536 const result1 = await esbuild.build({1537 entryPoints: [input1, input2],1538 bundle: true,1539 outdir,1540 format: 'esm',1541 splitting: true,1542 write: false,1543 entryNames: '[name]-[hash]',1544 })1545 await writeFileAsync(input2, `console.log(321)`)1546 const result2 = await esbuild.build({1547 entryPoints: [input1, input2],1548 bundle: true,1549 outdir,1550 format: 'esm',1551 splitting: true,1552 write: false,1553 entryNames: '[name]-[hash]',1554 })1555 assert.strictEqual(result1.outputFiles.length, 3)1556 assert.strictEqual(result2.outputFiles.length, 3)1557 // The hashes of both output files must change. Previously there was a bug1558 // where hash changes worked for static imports but not for dynamic imports.1559 for (const { path: oldPath } of result1.outputFiles)1560 for (const { path: newPath } of result2.outputFiles)1561 assert.notStrictEqual(oldPath, newPath)1562 },1563 async splittingDynamicImportHashChangeIssue1076({ esbuild, testDir }) {1564 const input1 = path.join(testDir, 'a', 'in1.js')1565 const input2 = path.join(testDir, 'b', 'in2.js')1566 const outdir = path.join(testDir, 'out')1567 await mkdirAsync(path.dirname(input1), { recursive: true })1568 await mkdirAsync(path.dirname(input2), { recursive: true })1569 await writeFileAsync(input1, `import(${JSON.stringify(input2)})`)1570 await writeFileAsync(input2, `console.log(123)`)1571 const result1 = await esbuild.build({1572 entryPoints: [input1],1573 bundle: true,1574 outdir,1575 format: 'esm',1576 splitting: true,1577 write: false,1578 entryNames: '[name]-[hash]',1579 })1580 await writeFileAsync(input2, `console.log(321)`)1581 const result2 = await esbuild.build({1582 entryPoints: [input1],1583 bundle: true,1584 outdir,1585 format: 'esm',1586 splitting: true,1587 write: false,1588 entryNames: '[name]-[hash]',1589 })1590 assert.strictEqual(result1.outputFiles.length, 2)1591 assert.strictEqual(result2.outputFiles.length, 2)1592 // The hashes of both output files must change. Previously there was a bug1593 // where hash changes worked for static imports but not for dynamic imports.1594 for (const { path: oldPath } of result1.outputFiles)1595 for (const { path: newPath } of result2.outputFiles)1596 assert.notStrictEqual(oldPath, newPath)1597 },1598 async stdinStdoutBundle({ esbuild, testDir }) {1599 const auxiliary = path.join(testDir, 'auxiliary.js')1600 await writeFileAsync(auxiliary, 'export default 123')1601 const value = await esbuild.build({1602 stdin: {1603 contents: `1604 import x from './auxiliary.js'1605 console.log(x)1606 `,1607 resolveDir: testDir,1608 },1609 bundle: true,1610 write: false,1611 })1612 assert.strictEqual(value.outputFiles.length, 1)1613 assert.strictEqual(value.outputFiles[0].path, '<stdout>')1614 assert.strictEqual(Buffer.from(value.outputFiles[0].contents).toString(), `(() => {1615 // scripts/.js-api-tests/stdinStdoutBundle/auxiliary.js1616 var auxiliary_default = 123;1617 // <stdin>1618 console.log(auxiliary_default);1619})();1620`)1621 },1622 async stdinOutfileBundle({ esbuild, testDir }) {1623 const auxiliary = path.join(testDir, 'auxiliary.js')1624 const outfile = path.join(testDir, 'out.js')1625 await writeFileAsync(auxiliary, 'export default 123')1626 const value = await esbuild.build({1627 stdin: {1628 contents: `1629 import x from './auxiliary.js'1630 export {x as fromStdin}1631 `,1632 resolveDir: testDir,1633 },1634 bundle: true,1635 outfile,1636 format: 'cjs',1637 })1638 assert.strictEqual(value.outputFiles, void 0)1639 const result = require(outfile)1640 assert.strictEqual(result.fromStdin, 123)1641 },1642 async stdinAndEntryBundle({ esbuild, testDir }) {1643 const srcDir = path.join(testDir, 'src')1644 const entry = path.join(srcDir, 'entry.js')1645 const auxiliary = path.join(srcDir, 'auxiliary.js')1646 const outdir = path.join(testDir, 'out')1647 await mkdirAsync(srcDir)1648 await writeFileAsync(auxiliary, 'export default 123')1649 await writeFileAsync(entry, `1650 import x from './auxiliary.js'1651 export let fromEntry = x1652 `)1653 const value = await esbuild.build({1654 entryPoints: [entry],1655 stdin: {1656 contents: `1657 import x from './src/auxiliary.js'1658 export {x as fromStdin}1659 `,1660 resolveDir: testDir,1661 },1662 bundle: true,1663 outdir,1664 format: 'cjs',1665 })1666 assert.strictEqual(value.outputFiles, void 0)1667 const entryResult = require(path.join(outdir, path.basename(entry)))1668 assert.strictEqual(entryResult.fromEntry, 123)1669 const stdinResult = require(path.join(outdir, path.basename('stdin.js')))1670 assert.strictEqual(stdinResult.fromStdin, 123)1671 },1672 async forceTsConfig({ esbuild, testDir }) {1673 // ./tsconfig.json1674 // ./a/forced-config.json1675 // ./a/b/test-impl.js1676 // ./a/b/c/in.js1677 const aDir = path.join(testDir, 'a')1678 const bDir = path.join(aDir, 'b')1679 const cDir = path.join(bDir, 'c')1680 await mkdirAsync(aDir).catch(x => x)1681 await mkdirAsync(bDir).catch(x => x)1682 await mkdirAsync(cDir).catch(x => x)1683 const input = path.join(cDir, 'in.js')1684 const forced = path.join(bDir, 'test-impl.js')1685 const tsconfigIgnore = path.join(testDir, 'tsconfig.json')1686 const tsconfigForced = path.join(aDir, 'forced-config.json')1687 const output = path.join(testDir, 'out.js')1688 await writeFileAsync(input, 'import "test"')1689 await writeFileAsync(forced, 'console.log("success")')1690 await writeFileAsync(tsconfigIgnore, '{"compilerOptions": {"baseUrl": "./a", "paths": {"test": ["./ignore.js"]}}}')1691 await writeFileAsync(tsconfigForced, '{"compilerOptions": {"baseUrl": "./b", "paths": {"test": ["./test-impl.js"]}}}')1692 await esbuild.build({1693 entryPoints: [input],1694 bundle: true,1695 outfile: output,1696 tsconfig: tsconfigForced,1697 format: 'esm',1698 })1699 const result = await readFileAsync(output, 'utf8')1700 assert.strictEqual(result, `// scripts/.js-api-tests/forceTsConfig/a/b/test-impl.js1701console.log("success");1702`)1703 },1704 async es5({ esbuild, testDir }) {1705 const input = path.join(testDir, 'in.js')1706 const cjs = path.join(testDir, 'cjs.js')1707 const esm = path.join(testDir, 'esm.js')1708 const output = path.join(testDir, 'out.js')1709 await writeFileAsync(input, `1710 export {foo} from "./cjs"1711 export * as bar from "./esm"1712 `)1713 await writeFileAsync(cjs, 'exports.foo = 123')1714 await writeFileAsync(esm, 'export var foo = 123')1715 const value = await esbuild.build({1716 entryPoints: [input],1717 bundle: true,1718 outfile: output,1719 format: 'cjs',1720 target: 'es5',1721 })1722 assert.strictEqual(value.outputFiles, void 0)1723 const result = require(output)1724 assert.strictEqual(result.foo, 123)1725 assert.strictEqual(result.bar.foo, 123)1726 assert.strictEqual(result.__esModule, true)1727 const contents = await readFileAsync(output, 'utf8')1728 assert.strictEqual(contents.indexOf('=>'), -1)1729 assert.strictEqual(contents.indexOf('const'), -1)1730 },1731 async outbaseImplicit({ esbuild, testDir }) {1732 const outbase = path.join(testDir, 'pages', 'a')1733 const b = path.join(outbase, 'b', 'index.js')1734 const c = path.join(outbase, 'c', 'index.js')1735 const outdir = path.join(testDir, 'outdir')1736 await mkdirAsync(path.dirname(b), { recursive: true })1737 await mkdirAsync(path.dirname(c), { recursive: true })1738 await writeFileAsync(b, 'module.exports = "b"')1739 await writeFileAsync(c, 'module.exports = "c"')1740 await esbuild.build({1741 entryPoints: [1742 path.relative(process.cwd(), b),1743 path.relative(process.cwd(), c),1744 ],1745 outdir,1746 format: 'cjs',1747 })1748 const outB = path.join(outdir, path.relative(outbase, b))1749 const outC = path.join(outdir, path.relative(outbase, c))1750 assert.strictEqual(require(outB), 'b')1751 assert.strictEqual(require(outC), 'c')1752 },1753 async outbaseRelPath({ esbuild, testDir }) {1754 const outbase = path.join(testDir, 'pages')1755 const b = path.join(outbase, 'a', 'b', 'index.js')1756 const c = path.join(outbase, 'a', 'c', 'index.js')1757 const outdir = path.join(testDir, 'outdir')1758 await mkdirAsync(path.dirname(b), { recursive: true })1759 await mkdirAsync(path.dirname(c), { recursive: true })1760 await writeFileAsync(b, 'module.exports = "b"')1761 await writeFileAsync(c, 'module.exports = "c"')1762 await esbuild.build({1763 entryPoints: [1764 path.relative(process.cwd(), b),1765 path.relative(process.cwd(), c),1766 ],1767 outdir,1768 outbase,1769 format: 'cjs',1770 })1771 const outB = path.join(outdir, path.relative(outbase, b))1772 const outC = path.join(outdir, path.relative(outbase, c))1773 assert.strictEqual(require(outB), 'b')1774 assert.strictEqual(require(outC), 'c')1775 },1776 async outbaseAbsPath({ esbuild, testDir }) {1777 const outbase = path.join(testDir, 'pages')1778 const b = path.join(outbase, 'a', 'b', 'index.js')1779 const c = path.join(outbase, 'a', 'c', 'index.js')1780 const outdir = path.join(testDir, 'outdir')1781 await mkdirAsync(path.dirname(b), { recursive: true })1782 await mkdirAsync(path.dirname(c), { recursive: true })1783 await writeFileAsync(b, 'module.exports = "b"')1784 await writeFileAsync(c, 'module.exports = "c"')1785 await esbuild.build({1786 entryPoints: [b, c],1787 outdir,1788 outbase,1789 format: 'cjs',1790 })1791 const outB = path.join(outdir, path.relative(outbase, b))1792 const outC = path.join(outdir, path.relative(outbase, c))1793 assert.strictEqual(require(outB), 'b')1794 assert.strictEqual(require(outC), 'c')1795 },1796 async bundleTreeShakingDefault({ esbuild }) {1797 const { outputFiles } = await esbuild.build({1798 stdin: {1799 contents: `1800 let removeMe1 = /* @__PURE__ */ fn();1801 let removeMe2 = <div/>;1802 `,1803 loader: 'jsx',1804 },1805 write: false,1806 bundle: true,1807 })1808 assert.strictEqual(outputFiles[0].text, `(() => {\n})();\n`)1809 },1810 async bundleTreeShakingTrue({ esbuild }) {1811 const { outputFiles } = await esbuild.build({1812 stdin: {1813 contents: `1814 let removeMe1 = /* @__PURE__ */ fn();1815 let removeMe2 = <div/>;1816 `,1817 loader: 'jsx',1818 },1819 write: false,1820 bundle: true,1821 treeShaking: true,1822 })1823 assert.strictEqual(outputFiles[0].text, `(() => {\n})();\n`)1824 },1825 async bundleTreeShakingIgnoreAnnotations({ esbuild }) {1826 const { outputFiles } = await esbuild.build({1827 stdin: {1828 contents: `1829 let keepMe1 = /* @__PURE__ */ fn();1830 let keepMe2 = <div/>;1831 `,1832 loader: 'jsx',1833 },1834 write: false,1835 bundle: true,1836 ignoreAnnotations: true,1837 })1838 assert.strictEqual(outputFiles[0].text, `(() => {1839 // <stdin>1840 var keepMe1 = fn();1841 var keepMe2 = React.createElement("div", null);1842})();1843`)1844 },1845 async externalWithWildcard({ esbuild }) {1846 const { outputFiles } = await esbuild.build({1847 stdin: {1848 contents: `require('/assets/file.png')`,1849 },1850 write: false,1851 bundle: true,1852 external: ['/assets/*.png'],1853 platform: 'node',1854 })1855 assert.strictEqual(outputFiles[0].text, `// <stdin>1856require("/assets/file.png");1857`)1858 },1859 async errorInvalidExternalWithTwoWildcards({ esbuild }) {1860 try {1861 await esbuild.build({1862 entryPoints: ['in.js'],1863 external: ['a*b*c'],1864 write: false,1865 logLevel: 'silent',1866 })1867 throw new Error('Expected build failure');1868 } catch (e) {1869 if (e.message !== 'Build failed with 1 error:\nerror: External path "a*b*c" cannot have more than one "*" wildcard') {1870 throw e;1871 }1872 }1873 },1874 async jsBannerBuild({ esbuild, testDir }) {1875 const input = path.join(testDir, 'in.js')1876 const outfile = path.join(testDir, 'out.js')1877 await writeFileAsync(input, `if (!bannerDefined) throw 'fail'`)1878 await esbuild.build({1879 entryPoints: [input],1880 outfile,1881 banner: { js: 'const bannerDefined = true' },1882 })1883 require(outfile)1884 },1885 async jsFooterBuild({ esbuild, testDir }) {1886 const input = path.join(testDir, 'in.js')1887 const outfile = path.join(testDir, 'out.js')1888 await writeFileAsync(input, `footer()`)1889 await esbuild.build({1890 entryPoints: [input],1891 outfile,1892 footer: { js: 'function footer() {}' },1893 })1894 require(outfile)1895 },1896 async jsBannerFooterBuild({ esbuild, testDir }) {1897 const aPath = path.join(testDir, 'a.js')1898 const bPath = path.join(testDir, 'b.js')1899 const outdir = path.join(testDir, 'out')1900 await writeFileAsync(aPath, `module.exports = { banner: bannerDefined, footer };`)1901 await writeFileAsync(bPath, `module.exports = { banner: bannerDefined, footer };`)1902 await esbuild.build({1903 entryPoints: [aPath, bPath],1904 outdir,1905 banner: { js: 'const bannerDefined = true' },1906 footer: { js: 'function footer() {}' },1907 })1908 const a = require(path.join(outdir, path.basename(aPath)))1909 const b = require(path.join(outdir, path.basename(bPath)))1910 if (!a.banner || !b.banner) throw 'fail'1911 a.footer()1912 b.footer()1913 },1914 async cssBannerFooterBuild({ esbuild, testDir }) {1915 const input = path.join(testDir, 'in.css')1916 const outfile = path.join(testDir, 'out.css')1917 await writeFileAsync(input, `div { color: red }`)1918 await esbuild.build({1919 entryPoints: [input],1920 outfile,1921 banner: { css: '/* banner */' },1922 footer: { css: '/* footer */' },1923 })1924 const code = await readFileAsync(outfile, 'utf8')1925 assert.strictEqual(code, `/* banner */\ndiv {\n color: red;\n}\n/* footer */\n`)1926 },1927 async buildRelativeIssue693({ esbuild }) {1928 const result = await esbuild.build({1929 stdin: {1930 contents: `const x=1`,1931 },1932 write: false,1933 outfile: 'esbuild.js',1934 });1935 assert.strictEqual(result.outputFiles.length, 1)1936 assert.strictEqual(result.outputFiles[0].path, path.join(process.cwd(), 'esbuild.js'))1937 assert.strictEqual(result.outputFiles[0].text, 'const x = 1;\n')1938 },1939 async noRebuild({ esbuild, testDir }) {1940 const input = path.join(testDir, 'in.js')1941 const output = path.join(testDir, 'out.js')1942 await writeFileAsync(input, `console.log('abc')`)1943 const result1 = await esbuild.build({1944 entryPoints: [input],1945 outfile: output,1946 format: 'esm',1947 incremental: false,1948 })1949 assert.strictEqual(result1.outputFiles, void 0)1950 assert.strictEqual(await readFileAsync(output, 'utf8'), `console.log("abc");\n`)1951 assert.strictEqual(result1.rebuild, void 0)1952 },1953 async rebuildBasic({ esbuild, testDir }) {1954 const input = path.join(testDir, 'in.js')1955 const output = path.join(testDir, 'out.js')1956 // Build 11957 await writeFileAsync(input, `console.log('abc')`)1958 const result1 = await esbuild.build({1959 entryPoints: [input],1960 outfile: output,1961 format: 'esm',1962 incremental: true,1963 })1964 assert.strictEqual(result1.outputFiles, void 0)1965 assert.strictEqual(await readFileAsync(output, 'utf8'), `console.log("abc");\n`)1966 // Build 21967 await writeFileAsync(input, `console.log('xyz')`)1968 const result2 = await result1.rebuild();1969 assert.strictEqual(result2.rebuild, result1.rebuild)1970 assert.strictEqual(result2.outputFiles, void 0)1971 assert.strictEqual(await readFileAsync(output, 'utf8'), `console.log("xyz");\n`)1972 // Build 31973 await writeFileAsync(input, `console.log(123)`)1974 const result3 = await result1.rebuild();1975 assert.strictEqual(result3.rebuild, result1.rebuild)1976 assert.strictEqual(result3.outputFiles, void 0)1977 assert.strictEqual(await readFileAsync(output, 'utf8'), `console.log(123);\n`)1978 // Further rebuilds should not be possible after a dispose1979 result1.rebuild.dispose()1980 try {1981 await result1.rebuild()1982 throw new Error('Expected an error to be thrown')1983 } catch (e) {1984 assert.strictEqual(e.message, 'Cannot rebuild')1985 }1986 },1987 async rebuildIndependent({ esbuild, testDir }) {1988 const inputA = path.join(testDir, 'in-a.js')1989 const inputB = path.join(testDir, 'in-b.js')1990 const outputA = path.join(testDir, 'out-a.js')1991 const outputB = path.join(testDir, 'out-b.js')1992 // Build 11993 await writeFileAsync(inputA, `console.log('a')`)1994 await writeFileAsync(inputB, `console.log('b')`)1995 const resultA1 = await esbuild.build({1996 entryPoints: [inputA],1997 outfile: outputA,1998 format: 'esm',1999 incremental: true,2000 })2001 const resultB1 = await esbuild.build({2002 entryPoints: [inputB],2003 outfile: outputB,2004 format: 'esm',2005 incremental: true,2006 })2007 assert.notStrictEqual(resultA1.rebuild, resultB1.rebuild)2008 assert.strictEqual(resultA1.outputFiles, void 0)2009 assert.strictEqual(resultB1.outputFiles, void 0)2010 assert.strictEqual(await readFileAsync(outputA, 'utf8'), `console.log("a");\n`)2011 assert.strictEqual(await readFileAsync(outputB, 'utf8'), `console.log("b");\n`)2012 // Build 22013 await writeFileAsync(inputA, `console.log(1)`)2014 await writeFileAsync(inputB, `console.log(2)`)2015 const promiseA = resultA1.rebuild();2016 const promiseB = resultB1.rebuild();2017 const resultA2 = await promiseA;2018 const resultB2 = await promiseB;2019 assert.strictEqual(resultA2.rebuild, resultA1.rebuild)2020 assert.strictEqual(resultB2.rebuild, resultB1.rebuild)2021 assert.strictEqual(resultA2.outputFiles, void 0)2022 assert.strictEqual(resultB2.outputFiles, void 0)2023 assert.strictEqual(await readFileAsync(outputA, 'utf8'), `console.log(1);\n`)2024 assert.strictEqual(await readFileAsync(outputB, 'utf8'), `console.log(2);\n`)2025 // Further rebuilds should not be possible after a dispose2026 resultA1.rebuild.dispose()2027 try {2028 await resultA1.rebuild()2029 throw new Error('Expected an error to be thrown')2030 } catch (e) {2031 assert.strictEqual(e.message, 'Cannot rebuild')2032 }2033 // Build 32034 await writeFileAsync(inputB, `console.log(3)`)2035 const resultB3 = await resultB1.rebuild()2036 assert.strictEqual(resultB3.rebuild, resultB1.rebuild)2037 assert.strictEqual(resultB3.outputFiles, void 0)2038 assert.strictEqual(await readFileAsync(outputB, 'utf8'), `console.log(3);\n`)2039 // Further rebuilds should not be possible after a dispose2040 resultB1.rebuild.dispose()2041 try {2042 await resultB1.rebuild()2043 throw new Error('Expected an error to be thrown')2044 } catch (e) {2045 assert.strictEqual(e.message, 'Cannot rebuild')2046 }2047 },2048 async rebuildParallel({ esbuild, testDir }) {2049 const input = path.join(testDir, 'in.js')2050 const output = path.join(testDir, 'out.js')2051 // Build 12052 await writeFileAsync(input, `console.log('abc')`)2053 const result1 = await esbuild.build({2054 entryPoints: [input],2055 outfile: output,2056 format: 'esm',2057 incremental: true,2058 })2059 assert.strictEqual(result1.outputFiles, void 0)2060 assert.strictEqual(await readFileAsync(output, 'utf8'), `console.log("abc");\n`)2061 // Build 22062 await writeFileAsync(input, `console.log('xyz')`)2063 const promise2A = result1.rebuild();2064 const promise2B = result1.rebuild();2065 const result2A = await promise2A;2066 const result2B = await promise2B;2067 assert.strictEqual(result2A.rebuild, result1.rebuild)2068 assert.strictEqual(result2B.rebuild, result1.rebuild)2069 assert.strictEqual(result2A.outputFiles, void 0)2070 assert.strictEqual(result2B.outputFiles, void 0)2071 assert.strictEqual(await readFileAsync(output, 'utf8'), `console.log("xyz");\n`)2072 // Build 32073 await writeFileAsync(input, `console.log(123)`)2074 const promise3A = result1.rebuild();2075 const promise3B = result1.rebuild();2076 const result3A = await promise3A;2077 const result3B = await promise3B;2078 assert.strictEqual(result3A.rebuild, result1.rebuild)2079 assert.strictEqual(result3B.rebuild, result1.rebuild)2080 assert.strictEqual(result3A.outputFiles, void 0)2081 assert.strictEqual(result3B.outputFiles, void 0)2082 assert.strictEqual(await readFileAsync(output, 'utf8'), `console.log(123);\n`)2083 // Further rebuilds should not be possible after a dispose2084 result1.rebuild.dispose()2085 try {2086 await result1.rebuild()2087 throw new Error('Expected an error to be thrown')2088 } catch (e) {2089 assert.strictEqual(e.message, 'Cannot rebuild')2090 }2091 },2092 async bundleAvoidTDZ({ esbuild }) {2093 var { outputFiles } = await esbuild.build({2094 stdin: {2095 contents: `2096 class Foo {2097 // The above line will be transformed into "var". However, the2098 // symbol "Foo" must still be defined before the class body ends.2099 static foo = new Foo2100 }2101 if (!(Foo.foo instanceof Foo))2102 throw 'fail'2103 `,2104 },2105 bundle: true,2106 write: false,2107 })2108 assert.strictEqual(outputFiles.length, 1)2109 new Function(outputFiles[0].text)()2110 },2111 async bundleTSAvoidTDZ({ esbuild }) {2112 var { outputFiles } = await esbuild.build({2113 stdin: {2114 contents: `2115 class Foo {2116 // The above line will be transformed into "var". However, the2117 // symbol "Foo" must still be defined before the class body ends.2118 static foo = new Foo2119 }2120 if (!(Foo.foo instanceof Foo))2121 throw 'fail'2122 `,2123 loader: 'ts',2124 },2125 bundle: true,2126 write: false,2127 })2128 assert.strictEqual(outputFiles.length, 1)2129 new Function(outputFiles[0].text)()2130 },2131 async bundleTSDecoratorAvoidTDZ({ esbuild }) {2132 var { outputFiles } = await esbuild.build({2133 stdin: {2134 contents: `2135 class Bar {}2136 var oldFoo2137 function swap(target) {2138 oldFoo = target2139 return Bar2140 }2141 @swap2142 class Foo {2143 bar() { return new Foo }2144 static foo = new Foo2145 }2146 if (!(oldFoo.foo instanceof oldFoo))2147 throw 'fail: foo'2148 if (!(oldFoo.foo.bar() instanceof Bar))2149 throw 'fail: bar'2150 `,2151 loader: 'ts',2152 },2153 bundle: true,2154 write: false,2155 })2156 assert.strictEqual(outputFiles.length, 1)2157 new Function(outputFiles[0].text)()2158 },2159 async automaticEntryPointOutputPathsWithDot({ esbuild, testDir }) {2160 const input = path.join(testDir, 'in.file.ts')2161 const css = path.join(testDir, 'file.css')2162 await writeFileAsync(input, `import './file.css'; console.log('test')`)2163 await writeFileAsync(css, `body { color: red }`)2164 var { outputFiles } = await esbuild.build({2165 entryPoints: [input],2166 outdir: testDir,2167 bundle: true,2168 write: false,2169 })2170 assert.strictEqual(outputFiles.length, 2)2171 assert.strictEqual(outputFiles[0].path, path.join(testDir, 'in.file.js'))2172 assert.strictEqual(outputFiles[1].path, path.join(testDir, 'in.file.css'))2173 },2174 async customEntryPointOutputPathsWithDot({ esbuild, testDir }) {2175 const input = path.join(testDir, 'in.file.ts')2176 const css = path.join(testDir, 'file.css')2177 await writeFileAsync(input, `import './file.css'; console.log('test')`)2178 await writeFileAsync(css, `body { color: red }`)2179 var { outputFiles } = await esbuild.build({2180 entryPoints: {2181 'out.test': input,2182 },2183 outdir: testDir,2184 bundle: true,2185 write: false,2186 })2187 assert.strictEqual(outputFiles.length, 2)2188 assert.strictEqual(outputFiles[0].path, path.join(testDir, 'out.test.js'))2189 assert.strictEqual(outputFiles[1].path, path.join(testDir, 'out.test.css'))2190 },2191 async customEntryPointOutputPathsRel({ esbuild, testDir }) {2192 const input1 = path.join(testDir, 'in1.js')2193 const input2 = path.join(testDir, 'in2.js')2194 const output1 = 'out/1.cjs'2195 const output2 = 'out/2.mjs'2196 await writeFileAsync(input1, `console.log('in1')`)2197 await writeFileAsync(input2, `console.log('in2')`)2198 var { outputFiles } = await esbuild.build({2199 entryPoints: {2200 [output1]: input1,2201 [output2]: input2,2202 },2203 entryNames: 'entry/[dir]/[hash]-[name]',2204 outdir: testDir,2205 write: false,2206 })2207 assert.strictEqual(outputFiles.length, 2)2208 assert.strictEqual(outputFiles[0].path, path.join(testDir, 'entry', 'out', 'CXHWNMAN-1.cjs.js'))2209 assert.strictEqual(outputFiles[1].path, path.join(testDir, 'entry', 'out', 'EYSNILNO-2.mjs.js'))2210 },2211 async customEntryPointOutputPathsAbs({ esbuild, testDir }) {2212 const input1 = path.join(testDir, 'in1.js')2213 const input2 = path.join(testDir, 'in2.js')2214 const output1 = path.join(testDir, 'out/1')2215 const output2 = path.join(testDir, 'out/2')2216 await writeFileAsync(input1, `console.log('in1')`)2217 await writeFileAsync(input2, `console.log('in2')`)2218 var { outputFiles } = await esbuild.build({2219 entryPoints: {2220 [output1]: input1,2221 [output2]: input2,2222 },2223 entryNames: 'entry/[dir]/[hash]-[name]',2224 outdir: testDir,2225 write: false,2226 })2227 assert.strictEqual(outputFiles.length, 2)2228 assert.strictEqual(outputFiles[0].path, path.join(testDir, 'entry', 'out', 'TIORPBNU-1.js'))2229 assert.strictEqual(outputFiles[1].path, path.join(testDir, 'entry', 'out', '3KY7NOSR-2.js'))2230 },2231}2232function fetch(host, port, path, headers) {2233 return new Promise((resolve, reject) => {2234 http.get({ host, port, path, headers }, res => {2235 const chunks = []2236 res.on('data', chunk => chunks.push(chunk))2237 res.on('end', () => {2238 const content = Buffer.concat(chunks)2239 if (res.statusCode < 200 || res.statusCode > 299)2240 reject(new Error(`${res.statusCode} when fetching ${path}: ${content}`))2241 else {2242 content.headers = res.headers2243 resolve(content)2244 }2245 })2246 }).on('error', reject)2247 })2248}2249let watchTests = {2250 async watchEditSession({ esbuild, testDir }) {2251 const srcDir = path.join(testDir, 'src')2252 const outfile = path.join(testDir, 'out.js')2253 const input = path.join(srcDir, 'in.js')2254 await mkdirAsync(srcDir, { recursive: true })2255 await writeFileAsync(input, `throw 1`)2256 let onRebuild = () => { }2257 const result = await esbuild.build({2258 entryPoints: [input],2259 outfile,2260 format: 'esm',2261 logLevel: 'silent',2262 watch: {2263 onRebuild: (...args) => onRebuild(args),2264 },2265 })2266 const rebuildUntil = (mutator, condition) => {2267 let timeout2268 return new Promise((resolve, reject) => {2269 timeout = setTimeout(() => reject(new Error('Timeout after 30 seconds')), 30 * 1000)2270 onRebuild = args => {2271 try { if (condition(...args)) clearTimeout(timeout), resolve(args) }2272 catch (e) { clearTimeout(timeout), reject(e) }2273 }2274 mutator()2275 })2276 }2277 try {2278 assert.strictEqual(result.outputFiles, void 0)2279 assert.strictEqual(typeof result.stop, 'function')2280 assert.strictEqual(await readFileAsync(outfile, 'utf8'), 'throw 1;\n')2281 // First rebuild: edit2282 {2283 const [error2, result2] = await rebuildUntil(2284 () => writeFileAtomic(input, `throw 2`),2285 () => fs.readFileSync(outfile, 'utf8') === 'throw 2;\n',2286 )2287 assert.strictEqual(error2, null)2288 assert.strictEqual(result2.outputFiles, void 0)2289 assert.strictEqual(result2.stop, result.stop)2290 }2291 // Second rebuild: edit2292 {2293 const [error2, result2] = await rebuildUntil(2294 () => writeFileAtomic(input, `throw 3`),2295 () => fs.readFileSync(outfile, 'utf8') === 'throw 3;\n',2296 )2297 assert.strictEqual(error2, null)2298 assert.strictEqual(result2.outputFiles, void 0)2299 assert.strictEqual(result2.stop, result.stop)2300 }2301 // Third rebuild: syntax error2302 {2303 const [error2, result2] = await rebuildUntil(2304 () => writeFileAtomic(input, `throw 1 2`),2305 err => err,2306 )2307 assert.notStrictEqual(error2, null)2308 assert(error2.message.startsWith('Build failed with 1 error'))2309 assert.strictEqual(error2.errors.length, 1)2310 assert.strictEqual(error2.errors[0].text, 'Expected ";" but found "2"')2311 assert.strictEqual(result2, null)2312 assert.strictEqual(await readFileAsync(outfile, 'utf8'), 'throw 3;\n')2313 }2314 // Fourth rebuild: edit2315 {2316 const [error2, result2] = await rebuildUntil(2317 () => writeFileAtomic(input, `throw 4`),2318 () => fs.readFileSync(outfile, 'utf8') === 'throw 4;\n',2319 )2320 assert.strictEqual(error2, null)2321 assert.strictEqual(result2.outputFiles, void 0)2322 assert.strictEqual(result2.stop, result.stop)2323 }2324 // Fifth rebuild: delete2325 {2326 const [error2, result2] = await rebuildUntil(2327 () => fs.promises.unlink(input),2328 err => err,2329 )2330 assert.notStrictEqual(error2, null)2331 assert(error2.message.startsWith('Build failed with 1 error'))2332 assert.strictEqual(error2.errors.length, 1)2333 assert.strictEqual(result2, null)2334 assert.strictEqual(await readFileAsync(outfile, 'utf8'), 'throw 4;\n')2335 }2336 // Sixth rebuild: restore2337 {2338 const [error2, result2] = await rebuildUntil(2339 () => writeFileAtomic(input, `throw 5`),2340 () => fs.readFileSync(outfile, 'utf8') === 'throw 5;\n',2341 )2342 assert.strictEqual(error2, null)2343 assert.strictEqual(result2.outputFiles, void 0)2344 assert.strictEqual(result2.stop, result.stop)2345 assert.strictEqual(await readFileAsync(outfile, 'utf8'), 'throw 5;\n')2346 }2347 } finally {2348 result.stop()2349 }2350 },2351 async watchWriteFalse({ esbuild, testDir }) {2352 const srcDir = path.join(testDir, 'src')2353 const outdir = path.join(testDir, 'out')2354 const input = path.join(srcDir, 'in.js')2355 const output = path.join(outdir, 'in.js')2356 await mkdirAsync(srcDir, { recursive: true })2357 await writeFileAsync(input, `throw 1`)2358 let onRebuild = () => { }2359 const result = await esbuild.build({2360 entryPoints: [input],2361 outdir,2362 format: 'esm',2363 logLevel: 'silent',2364 write: false,2365 watch: {2366 onRebuild: (...args) => onRebuild(args),2367 },2368 })2369 const rebuildUntil = (mutator, condition) => {2370 let timeout2371 return new Promise((resolve, reject) => {2372 timeout = setTimeout(() => reject(new Error('Timeout after 30 seconds')), 30 * 1000)2373 onRebuild = args => {2374 try { if (condition(...args)) clearTimeout(timeout), resolve(args) }2375 catch (e) { clearTimeout(timeout), reject(e) }2376 }2377 mutator()2378 })2379 }2380 try {2381 assert.strictEqual(result.outputFiles.length, 1)2382 assert.strictEqual(result.outputFiles[0].text, 'throw 1;\n')2383 assert.strictEqual(typeof result.stop, 'function')2384 assert.strictEqual(fs.existsSync(output), false)2385 // First rebuild: edit2386 {2387 const [error2, result2] = await rebuildUntil(2388 () => writeFileAtomic(input, `throw 2`),2389 (err, res) => res.outputFiles[0].text === 'throw 2;\n',2390 )2391 assert.strictEqual(error2, null)2392 assert.strictEqual(result2.stop, result.stop)2393 assert.strictEqual(fs.existsSync(output), false)2394 }2395 // Second rebuild: edit2396 {2397 const [error2, result2] = await rebuildUntil(2398 () => writeFileAtomic(input, `throw 3`),2399 (err, res) => res.outputFiles[0].text === 'throw 3;\n',2400 )2401 assert.strictEqual(error2, null)2402 assert.strictEqual(result2.stop, result.stop)2403 assert.strictEqual(fs.existsSync(output), false)2404 }2405 } finally {2406 result.stop()2407 }2408 },2409}2410let serveTests = {2411 async serveBasic({ esbuild, testDir }) {2412 const input = path.join(testDir, 'in.js')2413 await writeFileAsync(input, `console.log(123)`)2414 let onRequest;2415 let singleRequestPromise = new Promise(resolve => {2416 onRequest = resolve;2417 });2418 const result = await esbuild.serve({2419 host: '127.0.0.1',2420 onRequest,2421 }, {2422 entryPoints: [input],2423 format: 'esm',2424 })2425 assert.strictEqual(result.host, '127.0.0.1');2426 assert.strictEqual(typeof result.port, 'number');2427 const buffer = await fetch(result.host, result.port, '/in.js')2428 assert.strictEqual(buffer.toString(), `console.log(123);\n`);2429 let singleRequest = await singleRequestPromise;2430 assert.strictEqual(singleRequest.method, 'GET');2431 assert.strictEqual(singleRequest.path, '/in.js');2432 assert.strictEqual(singleRequest.status, 200);2433 assert.strictEqual(typeof singleRequest.remoteAddress, 'string');2434 assert.strictEqual(typeof singleRequest.timeInMS, 'number');2435 result.stop();2436 await result.wait;2437 },2438 async serveOutfile({ esbuild, testDir }) {2439 const input = path.join(testDir, 'in.js')2440 await writeFileAsync(input, `console.log(123)`)2441 let onRequest;2442 let singleRequestPromise = new Promise(resolve => {2443 onRequest = resolve;2444 });2445 const result = await esbuild.serve({2446 host: '127.0.0.1',2447 onRequest,2448 }, {2449 entryPoints: [input],2450 format: 'esm',2451 outfile: 'out.js',2452 })2453 assert.strictEqual(result.host, '127.0.0.1');2454 assert.strictEqual(typeof result.port, 'number');2455 const buffer = await fetch(result.host, result.port, '/out.js')2456 assert.strictEqual(buffer.toString(), `console.log(123);\n`);2457 let singleRequest = await singleRequestPromise;2458 assert.strictEqual(singleRequest.method, 'GET');2459 assert.strictEqual(singleRequest.path, '/out.js');2460 assert.strictEqual(singleRequest.status, 200);2461 assert.strictEqual(typeof singleRequest.remoteAddress, 'string');2462 assert.strictEqual(typeof singleRequest.timeInMS, 'number');2463 try {2464 await fetch(result.host, result.port, '/in.js')2465 throw new Error('Expected a 404 error for "/in.js"')2466 } catch (err) {2467 if (err.message !== '404 when fetching /in.js: 404 - Not Found')2468 throw err2469 }2470 result.stop();2471 await result.wait;2472 },2473 async serveWithFallbackDir({ esbuild, testDir }) {2474 const input = path.join(testDir, 'in.js')2475 const wwwDir = path.join(testDir, 'www')2476 const index = path.join(wwwDir, 'index.html')2477 await mkdirAsync(wwwDir, { recursive: true })2478 await writeFileAsync(input, `console.log(123)`)2479 await writeFileAsync(index, `<!doctype html>`)2480 let onRequest;2481 let nextRequestPromise;2482 (function generateNewPromise() {2483 nextRequestPromise = new Promise(resolve => {2484 onRequest = args => {2485 generateNewPromise();2486 resolve(args);2487 };2488 });2489 })();2490 const result = await esbuild.serve({2491 host: '127.0.0.1',2492 onRequest: args => onRequest(args),2493 servedir: wwwDir,2494 }, {2495 entryPoints: [input],2496 format: 'esm',2497 })2498 assert.strictEqual(result.host, '127.0.0.1');2499 assert.strictEqual(typeof result.port, 'number');2500 let promise, buffer, req;2501 promise = nextRequestPromise;2502 buffer = await fetch(result.host, result.port, '/in.js')2503 assert.strictEqual(buffer.toString(), `console.log(123);\n`);2504 req = await promise;2505 assert.strictEqual(req.method, 'GET');2506 assert.strictEqual(req.path, '/in.js');2507 assert.strictEqual(req.status, 200);2508 assert.strictEqual(typeof req.remoteAddress, 'string');2509 assert.strictEqual(typeof req.timeInMS, 'number');2510 promise = nextRequestPromise;2511 buffer = await fetch(result.host, result.port, '/')2512 assert.strictEqual(buffer.toString(), `<!doctype html>`);2513 req = await promise;2514 assert.strictEqual(req.method, 'GET');2515 assert.strictEqual(req.path, '/');2516 assert.strictEqual(req.status, 200);2517 assert.strictEqual(typeof req.remoteAddress, 'string');2518 assert.strictEqual(typeof req.timeInMS, 'number');2519 result.stop();2520 await result.wait;2521 },2522 async serveWithFallbackDirAndSiblingOutputDir({ esbuild, testDir }) {2523 try {2524 const result = await esbuild.serve({2525 servedir: 'www',2526 }, {2527 entryPoints: [path.join(testDir, 'in.js')],2528 outdir: 'out',2529 })2530 result.stop()2531 throw new Error('Expected an error to be thrown')2532 } catch (e) {2533 assert.strictEqual(e + '', `Error: Output directory "out" must be contained in serve directory "www"`)2534 }2535 },2536 async serveWithFallbackDirAndParentOutputDir({ esbuild, testDir }) {2537 try {2538 const result = await esbuild.serve({2539 servedir: path.join(testDir, 'www'),2540 }, {2541 entryPoints: [path.join(testDir, 'in.js')],2542 outdir: testDir,2543 absWorkingDir: testDir,2544 })2545 result.stop()2546 throw new Error('Expected an error to be thrown')2547 } catch (e) {2548 assert.strictEqual(e + '', `Error: Output directory "." must be contained in serve directory "www"`)2549 }2550 },2551 async serveWithFallbackDirAndOutputDir({ esbuild, testDir }) {2552 const input = path.join(testDir, 'in.js')2553 const outputDir = path.join(testDir, 'www/out')2554 const wwwDir = path.join(testDir, 'www')2555 const index = path.join(wwwDir, 'index.html')2556 await mkdirAsync(wwwDir, { recursive: true })2557 await writeFileAsync(input, `console.log(123)`)2558 await writeFileAsync(index, `<!doctype html>`)2559 let onRequest;2560 let nextRequestPromise;2561 (function generateNewPromise() {2562 nextRequestPromise = new Promise(resolve => {2563 onRequest = args => {2564 generateNewPromise();2565 resolve(args);2566 };2567 });2568 })();2569 const result = await esbuild.serve({2570 host: '127.0.0.1',2571 onRequest: args => onRequest(args),2572 servedir: wwwDir,2573 }, {2574 entryPoints: [input],2575 format: 'esm',2576 outdir: outputDir,2577 })2578 assert.strictEqual(result.host, '127.0.0.1');2579 assert.strictEqual(typeof result.port, 'number');2580 let promise, buffer, req;2581 promise = nextRequestPromise;2582 buffer = await fetch(result.host, result.port, '/out/in.js')2583 assert.strictEqual(buffer.toString(), `console.log(123);\n`);2584 req = await promise;2585 assert.strictEqual(req.method, 'GET');2586 assert.strictEqual(req.path, '/out/in.js');2587 assert.strictEqual(req.status, 200);2588 assert.strictEqual(typeof req.remoteAddress, 'string');2589 assert.strictEqual(typeof req.timeInMS, 'number');2590 promise = nextRequestPromise;2591 buffer = await fetch(result.host, result.port, '/')2592 assert.strictEqual(buffer.toString(), `<!doctype html>`);2593 req = await promise;2594 assert.strictEqual(req.method, 'GET');2595 assert.strictEqual(req.path, '/');2596 assert.strictEqual(req.status, 200);2597 assert.strictEqual(typeof req.remoteAddress, 'string');2598 assert.strictEqual(typeof req.timeInMS, 'number');2599 result.stop();2600 await result.wait;2601 },2602 async serveWithFallbackDirNoEntryPoints({ esbuild, testDir }) {2603 const index = path.join(testDir, 'index.html')2604 await writeFileAsync(index, `<!doctype html>`)2605 let onRequest;2606 let nextRequestPromise;2607 (function generateNewPromise() {2608 nextRequestPromise = new Promise(resolve => {2609 onRequest = args => {2610 generateNewPromise();2611 resolve(args);2612 };2613 });2614 })();2615 const result = await esbuild.serve({2616 host: '127.0.0.1',2617 onRequest: args => onRequest(args),2618 servedir: testDir,2619 }, {2620 })2621 assert.strictEqual(result.host, '127.0.0.1');2622 assert.strictEqual(typeof result.port, 'number');2623 let promise, buffer, req;2624 promise = nextRequestPromise;2625 buffer = await fetch(result.host, result.port, '/')2626 assert.strictEqual(buffer.toString(), `<!doctype html>`);2627 req = await promise;2628 assert.strictEqual(req.method, 'GET');2629 assert.strictEqual(req.path, '/');2630 assert.strictEqual(req.status, 200);2631 assert.strictEqual(typeof req.remoteAddress, 'string');2632 assert.strictEqual(typeof req.timeInMS, 'number');2633 // Check that removing the file removes it from the directory listing (i.e. the2634 // "fs.FS" object in Go does not cache the result of calling "ReadDirectory")2635 await fs.promises.unlink(index)2636 promise = nextRequestPromise;2637 buffer = await fetch(result.host, result.port, '/')2638 assert.strictEqual(buffer.toString(), `<!doctype html><meta charset="utf8"><title>Directory: /</title><h1>Directory: /</h1><ul></ul>`);2639 req = await promise;2640 assert.strictEqual(req.method, 'GET');2641 assert.strictEqual(req.path, '/');2642 assert.strictEqual(req.status, 200);2643 assert.strictEqual(typeof req.remoteAddress, 'string');2644 assert.strictEqual(typeof req.timeInMS, 'number');2645 result.stop();2646 await result.wait;2647 },2648 async serveRange({ esbuild, testDir }) {2649 const big = path.join(testDir, 'big.txt')2650 const byteCount = 16 * 1024 * 10242651 const buffer = require('crypto').randomBytes(byteCount)2652 await writeFileAsync(big, buffer)2653 const result = await esbuild.serve({2654 host: '127.0.0.1',2655 servedir: testDir,2656 }, {})2657 // Test small to big ranges2658 const minLength = 12659 const maxLength = buffer.length2660 for (let i = 0, n = 16; i < n; i++) {2661 const length = Math.round(minLength + (maxLength - minLength) * i / (n - 1))2662 const start = Math.floor(Math.random() * (buffer.length - length))2663 const fetched = await fetch(result.host, result.port, '/big.txt', {2664 // Subtract 1 because range headers are inclusive on both ends2665 Range: `bytes=${start}-${start + length - 1}`,2666 })2667 delete fetched.headers.date2668 const expected = buffer.slice(start, start + length)2669 expected.headers = {2670 'access-control-allow-origin': '*',2671 'content-length': `${length}`,2672 'content-range': `bytes ${start}-${start + length - 1}/${byteCount}`,2673 'content-type': 'application/octet-stream',2674 'connection': 'close',2675 }2676 assert.deepStrictEqual(fetched, expected)2677 }2678 result.stop();2679 await result.wait;2680 },2681}2682async function futureSyntax(esbuild, js, targetBelow, targetAbove) {2683 failure: {2684 try { await esbuild.transform(js, { target: targetBelow }) }2685 catch { break failure }2686 throw new Error(`Expected failure for ${targetBelow}: ${js}`)2687 }2688 try { await esbuild.transform(js, { target: targetAbove }) }2689 catch (e) { throw new Error(`Expected success for ${targetAbove}: ${js}\n${e}`) }2690}2691let transformTests = {2692 async transformWithNonString({ esbuild }) {2693 try {2694 await esbuild.transform(Buffer.from(`1+2`))2695 throw new Error('Expected an error to be thrown');2696 } catch (e) {2697 assert.strictEqual(e.errors[0].text, 'The input to "transform" must be a string')2698 }2699 },2700 async version({ esbuild }) {2701 const version = fs.readFileSync(path.join(repoDir, 'version.txt'), 'utf8').trim()2702 assert.strictEqual(esbuild.version, version);2703 },2704 async ignoreUndefinedOptions({ esbuild }) {2705 // This should not throw2706 await esbuild.transform(``, { jsxFactory: void 0 })2707 },2708 async throwOnBadOptions({ esbuild }) {2709 // This should throw2710 try {2711 await esbuild.transform(``, { jsxFactory: ['React', 'createElement'] })2712 throw new Error('Expected transform failure');2713 } catch (e) {2714 if (!e.errors || !e.errors[0] || e.errors[0].text !== '"jsxFactory" must be a string') {2715 throw e;2716 }2717 }2718 },2719 async avoidTDZ({ esbuild }) {2720 var { code } = await esbuild.transform(`2721 class Foo {2722 // The above line will be transformed into "var". However, the2723 // symbol "Foo" must still be defined before the class body ends.2724 static foo = new Foo2725 }2726 if (!(Foo.foo instanceof Foo))2727 throw 'fail'2728 `)2729 new Function(code)()2730 },2731 async tsAvoidTDZ({ esbuild }) {2732 var { code } = await esbuild.transform(`2733 class Foo {2734 // The above line will be transformed into "var". However, the2735 // symbol "Foo" must still be defined before the class body ends.2736 static foo = new Foo2737 }2738 if (!(Foo.foo instanceof Foo))2739 throw 'fail'2740 `, {2741 loader: 'ts',2742 })2743 new Function(code)()2744 },2745 // Note: The TypeScript compiler's transformer doesn't handle this case.2746 // Using "this" like this is a syntax error instead. However, we can handle2747 // it without too much trouble so we handle it here. This is defensive in2748 // case the TypeScript compiler team fixes this in the future.2749 async tsAvoidTDZThis({ esbuild }) {2750 var { code } = await esbuild.transform(`2751 class Foo {2752 static foo = 1232753 static bar = this.foo // "this" must be rewritten when the property is relocated2754 }2755 if (Foo.bar !== 123) throw 'fail'2756 `, {2757 loader: 'ts',2758 tsconfigRaw: {2759 compilerOptions: {2760 useDefineForClassFields: false,2761 },2762 },2763 })2764 new Function(code)()2765 },2766 async tsDecoratorAvoidTDZ({ esbuild }) {2767 var { code } = await esbuild.transform(`2768 class Bar {}2769 var oldFoo2770 function swap(target) {2771 oldFoo = target2772 return Bar2773 }2774 @swap2775 class Foo {2776 bar() { return new Foo }2777 static foo = new Foo2778 }2779 if (!(oldFoo.foo instanceof oldFoo))2780 throw 'fail: foo'2781 if (!(oldFoo.foo.bar() instanceof Bar))2782 throw 'fail: bar'2783 `, {2784 loader: 'ts',2785 })2786 new Function(code)()2787 },2788 async jsBannerTransform({ esbuild }) {2789 var { code } = await esbuild.transform(`2790 if (!bannerDefined) throw 'fail'2791 `, {2792 banner: 'const bannerDefined = true',2793 })2794 new Function(code)()2795 },2796 async jsFooterTransform({ esbuild }) {2797 var { code } = await esbuild.transform(`2798 footer()2799 `, {2800 footer: 'function footer() {}',2801 })2802 new Function(code)()2803 new Function(code)()2804 },2805 async jsBannerFooterTransform({ esbuild }) {2806 var { code } = await esbuild.transform(`2807 return { banner: bannerDefined, footer };2808 `, {2809 banner: 'const bannerDefined = true',2810 footer: 'function footer() {}',2811 })2812 const result = new Function(code)()2813 if (!result.banner) throw 'fail'2814 result.footer()2815 },2816 async cssBannerFooterTransform({ esbuild }) {2817 var { code } = await esbuild.transform(`2818 div { color: red }2819 `, {2820 loader: 'css',2821 banner: '/* banner */',2822 footer: '/* footer */',2823 })2824 assert.strictEqual(code, `/* banner */\ndiv {\n color: red;\n}\n/* footer */\n`)2825 },2826 async transformDirectEval({ esbuild }) {2827 var { code } = await esbuild.transform(`2828 export let abc = 1232829 eval('console.log(abc)')2830 `, {2831 minify: true,2832 })2833 assert.strictEqual(code, `export let abc=123;eval("console.log(abc)");\n`)2834 },2835 async tsconfigRawRemoveUnusedImportsDefault({ esbuild }) {2836 const { code } = await esbuild.transform(`import {T} from 'path'`, {2837 tsconfigRaw: {2838 compilerOptions: {},2839 },2840 loader: 'ts',2841 })2842 assert.strictEqual(code, ``)2843 },2844 async tsconfigRawRemoveUnusedImports({ esbuild }) {2845 const { code } = await esbuild.transform(`import {T} from 'path'`, {2846 tsconfigRaw: {2847 compilerOptions: {2848 importsNotUsedAsValues: 'remove',2849 },2850 },2851 loader: 'ts',2852 })2853 assert.strictEqual(code, ``)2854 },2855 async tsconfigRawPreserveUnusedImports({ esbuild }) {2856 const { code } = await esbuild.transform(`import {T} from 'path'`, {2857 tsconfigRaw: {2858 compilerOptions: {2859 importsNotUsedAsValues: 'preserve',2860 },2861 },2862 loader: 'ts',2863 })2864 assert.strictEqual(code, `import { T } from "path";\n`)2865 },2866 async tsconfigRawPreserveUnusedImportsMinifyIdentifiers({ esbuild }) {2867 const { code } = await esbuild.transform(`import {T} from 'path'`, {2868 tsconfigRaw: {2869 compilerOptions: {2870 importsNotUsedAsValues: 'preserve',2871 },2872 },2873 loader: 'ts',2874 minifyIdentifiers: true,2875 })2876 assert.strictEqual(code, `import "path";\n`)2877 },2878 async tsconfigRawPreserveUnusedImportsJS({ esbuild }) {2879 const { code } = await esbuild.transform(`import {T} from 'path'`, {2880 tsconfigRaw: {2881 compilerOptions: {2882 importsNotUsedAsValues: 'preserve',2883 },2884 },2885 loader: 'js',2886 })2887 assert.strictEqual(code, `import { T } from "path";\n`)2888 },2889 async tsconfigRawCommentsInJSON({ esbuild }) {2890 // Can use a string, which allows weird TypeScript pseudo-JSON with comments and trailing commas2891 const { code: code5 } = await esbuild.transform(`import {T} from 'path'`, {2892 tsconfigRaw: `{2893 "compilerOptions": {2894 "importsNotUsedAsValues": "preserve", // there is a trailing comment here2895 },2896 }`,2897 loader: 'ts',2898 })2899 assert.strictEqual(code5, `import { T } from "path";\n`)2900 },2901 async tsconfigRawImportsNotUsedAsValues({ esbuild }) {2902 const { code: code1 } = await esbuild.transform(`class Foo { foo }`, {2903 tsconfigRaw: {2904 compilerOptions: {2905 useDefineForClassFields: false,2906 },2907 },2908 loader: 'ts',2909 })2910 assert.strictEqual(code1, `class Foo {\n}\n`)2911 const { code: code2 } = await esbuild.transform(`class Foo { foo }`, {2912 tsconfigRaw: {2913 compilerOptions: {2914 useDefineForClassFields: true,2915 },2916 },2917 loader: 'ts',2918 })2919 assert.strictEqual(code2, `class Foo {\n foo;\n}\n`)2920 },2921 async tsconfigRawJSX({ esbuild }) {2922 const { code: code1 } = await esbuild.transform(`<><div/></>`, {2923 tsconfigRaw: {2924 compilerOptions: {2925 },2926 },2927 loader: 'jsx',2928 })2929 assert.strictEqual(code1, `/* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", null));\n`)2930 const { code: code2 } = await esbuild.transform(`<><div/></>`, {2931 tsconfigRaw: {2932 compilerOptions: {2933 jsxFactory: 'factory',2934 jsxFragmentFactory: 'fragment',2935 },2936 },2937 loader: 'jsx',2938 })2939 assert.strictEqual(code2, `/* @__PURE__ */ factory(fragment, null, /* @__PURE__ */ factory("div", null));\n`)2940 },2941 // Note: tree shaking is disabled when the output format isn't IIFE2942 async treeShakingDefault({ esbuild }) {2943 const { code } = await esbuild.transform(`2944 var unused = 1232945 var used = 2342946 export { used }2947 `, {2948 loader: 'jsx',2949 format: 'esm',2950 treeShaking: undefined,2951 })2952 assert.strictEqual(code, `var unused = 123;\nvar used = 234;\nexport {\n used\n};\n`)2953 },2954 async treeShakingFalse({ esbuild }) {2955 const { code } = await esbuild.transform(`2956 var unused = 1232957 var used = 2342958 export { used }2959 `, {2960 loader: 'jsx',2961 format: 'esm',2962 treeShaking: false,2963 })2964 assert.strictEqual(code, `var unused = 123;\nvar used = 234;\nexport {\n used\n};\n`)2965 },2966 async treeShakingTrue({ esbuild }) {2967 const { code } = await esbuild.transform(`2968 var unused = 1232969 var used = 2342970 export { used }2971 `, {2972 loader: 'jsx',2973 format: 'esm',2974 treeShaking: true,2975 })2976 assert.strictEqual(code, `var used = 234;\nexport {\n used\n};\n`)2977 },2978 // Note: tree shaking is enabled when the output format is IIFE2979 async treeShakingDefaultIIFE({ esbuild }) {2980 const { code } = await esbuild.transform(`var unused = 123`, {2981 loader: 'jsx',2982 format: 'iife',2983 treeShaking: undefined,2984 })2985 assert.strictEqual(code, `(() => {\n})();\n`)2986 },2987 async treeShakingFalseIIFE({ esbuild }) {2988 const { code } = await esbuild.transform(`var unused = 123`, {2989 loader: 'jsx',2990 format: 'iife',2991 treeShaking: false,2992 })2993 assert.strictEqual(code, `(() => {\n var unused = 123;\n})();\n`)2994 },2995 async treeShakingTrueIIFE({ esbuild }) {2996 const { code } = await esbuild.transform(`var unused = 123`, {2997 loader: 'jsx',2998 format: 'iife',2999 treeShaking: true,3000 })3001 assert.strictEqual(code, `(() => {\n})();\n`)3002 },3003 async ignoreAnnotationsDefault({ esbuild }) {3004 const { code } = await esbuild.transform(`/* @__PURE__ */ fn(); <div/>`, {3005 loader: 'jsx',3006 minifySyntax: true,3007 })3008 assert.strictEqual(code, ``)3009 },3010 async ignoreAnnotationsFalse({ esbuild }) {3011 const { code } = await esbuild.transform(`/* @__PURE__ */ fn(); <div/>`, {3012 loader: 'jsx',3013 minifySyntax: true,3014 ignoreAnnotations: false,3015 })3016 assert.strictEqual(code, ``)3017 },3018 async ignoreAnnotationsTrue({ esbuild }) {3019 const { code } = await esbuild.transform(`/* @__PURE__ */ fn(); <div/>`, {3020 loader: 'jsx',3021 minifySyntax: true,3022 ignoreAnnotations: true,3023 })3024 assert.strictEqual(code, `fn(), React.createElement("div", null);\n`)3025 },3026 async jsCharsetDefault({ esbuild }) {3027 const { code } = await esbuild.transform(`let Ï = 'Ï'`, {})3028 assert.strictEqual(code, `let \\u03C0 = "\\u03C0";\n`)3029 },3030 async jsCharsetASCII({ esbuild }) {3031 const { code } = await esbuild.transform(`let Ï = 'Ï'`, { charset: 'ascii' })3032 assert.strictEqual(code, `let \\u03C0 = "\\u03C0";\n`)3033 },3034 async jsCharsetUTF8({ esbuild }) {3035 const { code } = await esbuild.transform(`let Ï = 'Ï'`, { charset: 'utf8' })3036 assert.strictEqual(code, `let Ï = "Ï";\n`)3037 },3038 async cssCharsetDefault({ esbuild }) {3039 const { code } = await esbuild.transform(`.Ï:after { content: 'Ï' }`, { loader: 'css' })3040 assert.strictEqual(code, `.\\3c0:after {\n content: "\\3c0";\n}\n`)3041 },3042 async cssCharsetASCII({ esbuild }) {3043 const { code } = await esbuild.transform(`.Ï:after { content: 'Ï' }`, { loader: 'css', charset: 'ascii' })3044 assert.strictEqual(code, `.\\3c0:after {\n content: "\\3c0";\n}\n`)3045 },3046 async cssCharsetUTF8({ esbuild }) {3047 const { code } = await esbuild.transform(`.Ï:after { content: 'Ï' }`, { loader: 'css', charset: 'utf8' })3048 assert.strictEqual(code, `.Ï:after {\n content: "Ï";\n}\n`)3049 },3050 async cssMinify({ esbuild }) {3051 const { code } = await esbuild.transform(`div { color: #abcd }`, { loader: 'css', minify: true })3052 assert.strictEqual(code, `div{color:#abcd}\n`)3053 },3054 // Using an "es" target shouldn't affect CSS3055 async cssMinifyTargetES6({ esbuild }) {3056 const { code } = await esbuild.transform(`div { color: #abcd }`, { loader: 'css', minify: true, target: 'es6' })3057 assert.strictEqual(code, `div{color:#abcd}\n`)3058 },3059 // Using a "node" target shouldn't affect CSS3060 async cssMinifyTargetNode({ esbuild }) {3061 const { code } = await esbuild.transform(`div { color: #abcd }`, { loader: 'css', minify: true, target: 'node8' })3062 assert.strictEqual(code, `div{color:#abcd}\n`)3063 },3064 // Using an older browser target should affect CSS3065 async cssMinifyTargetChrome8({ esbuild }) {3066 const { code } = await esbuild.transform(`div { color: #abcd }`, { loader: 'css', minify: true, target: 'chrome8' })3067 assert.strictEqual(code, `div{color:rgba(170,187,204,.867)}\n`)3068 },3069 // Using a newer browser target shouldn't affect CSS3070 async cssMinifyTargetChrome80({ esbuild }) {3071 const { code } = await esbuild.transform(`div { color: #abcd }`, { loader: 'css', minify: true, target: 'chrome80' })3072 assert.strictEqual(code, `div{color:#abcd}\n`)3073 },3074 async cjs_require({ esbuild }) {3075 const { code } = await esbuild.transform(`const {foo} = require('path')`, {})3076 assert.strictEqual(code, `const { foo } = require("path");\n`)3077 },3078 async cjs_exports({ esbuild }) {3079 const { code } = await esbuild.transform(`exports.foo = 123`, {})3080 assert.strictEqual(code, `exports.foo = 123;\n`)3081 },3082 async es6_import({ esbuild }) {3083 const { code } = await esbuild.transform(`import {foo} from 'path'`, {})3084 assert.strictEqual(code, `import { foo } from "path";\n`)3085 },3086 async es6_export({ esbuild }) {3087 const { code } = await esbuild.transform(`export const foo = 123`, {})3088 assert.strictEqual(code, `export const foo = 123;\n`)3089 },3090 async es6_import_to_iife({ esbuild }) {3091 const { code } = await esbuild.transform(`import {exists} from "fs"; if (!exists) throw 'fail'`, { format: 'iife' })3092 new Function('require', code)(require)3093 },3094 async es6_import_star_to_iife({ esbuild }) {3095 const { code } = await esbuild.transform(`import * as fs from "fs"; if (!fs.exists) throw 'fail'`, { format: 'iife' })3096 new Function('require', code)(require)3097 },3098 async es6_export_to_iife({ esbuild }) {3099 const { code } = await esbuild.transform(`export {exists} from "fs"`, { format: 'iife', globalName: 'out' })3100 const out = new Function('require', code + ';return out')(require)3101 if (out.exists !== fs.exists) throw 'fail'3102 },3103 async es6_export_star_to_iife({ esbuild }) {3104 const { code } = await esbuild.transform(`export * from "fs"`, { format: 'iife', globalName: 'out' })3105 const out = new Function('require', code + ';return out')(require)3106 if (out.exists !== fs.exists) throw 'fail'3107 },3108 async es6_export_star_as_to_iife({ esbuild }) {3109 const { code } = await esbuild.transform(`export * as fs from "fs"`, { format: 'iife', globalName: 'out' })3110 const out = new Function('require', code + ';return out')(require)3111 if (out.fs.exists !== fs.exists) throw 'fail'3112 },3113 async es6_import_to_cjs({ esbuild }) {3114 const { code } = await esbuild.transform(`import {exists} from "fs"; if (!exists) throw 'fail'`, { format: 'cjs' })3115 new Function('require', code)(require)3116 },3117 async es6_import_star_to_cjs({ esbuild }) {3118 const { code } = await esbuild.transform(`import * as fs from "fs"; if (!fs.exists) throw 'fail'`, { format: 'cjs' })3119 new Function('require', code)(require)3120 },3121 async es6_export_to_cjs({ esbuild }) {3122 const { code } = await esbuild.transform(`export {exists} from "fs"`, { format: 'cjs' })3123 const exports = {}3124 new Function('require', 'exports', code)(require, exports)3125 if (exports.exists !== fs.exists) throw 'fail'3126 },3127 async es6_export_star_to_cjs({ esbuild }) {3128 const { code } = await esbuild.transform(`export * from "fs"`, { format: 'cjs' })3129 const exports = {}3130 new Function('require', 'exports', code)(require, exports)3131 if (exports.exists !== fs.exists) throw 'fail'3132 },3133 async es6_export_star_as_to_cjs({ esbuild }) {3134 const { code } = await esbuild.transform(`export * as fs from "fs"`, { format: 'cjs' })3135 const exports = {}3136 new Function('require', 'exports', code)(require, exports)3137 if (exports.fs.exists !== fs.exists) throw 'fail'3138 },3139 async es6_import_to_esm({ esbuild }) {3140 const { code } = await esbuild.transform(`import {exists} from "fs"; if (!exists) throw 'fail'`, { format: 'esm' })3141 assert.strictEqual(code, `import { exists } from "fs";\nif (!exists)\n throw "fail";\n`)3142 },3143 async es6_import_star_to_esm({ esbuild }) {3144 const { code } = await esbuild.transform(`import * as fs from "fs"; if (!fs.exists) throw 'fail'`, { format: 'esm' })3145 assert.strictEqual(code, `import * as fs from "fs";\nif (!fs.exists)\n throw "fail";\n`)3146 },3147 async es6_export_to_esm({ esbuild }) {3148 const { code } = await esbuild.transform(`export {exists} from "fs"`, { format: 'esm' })3149 assert.strictEqual(code, `import { exists } from "fs";\nexport {\n exists\n};\n`)3150 },3151 async es6_export_star_to_esm({ esbuild }) {3152 const { code } = await esbuild.transform(`export * from "fs"`, { format: 'esm' })3153 assert.strictEqual(code, `export * from "fs";\n`)3154 },3155 async es6_export_star_as_to_esm({ esbuild }) {3156 const { code } = await esbuild.transform(`export * as fs from "fs"`, { format: 'esm' })3157 assert.strictEqual(code, `import * as fs from "fs";\nexport {\n fs\n};\n`)3158 },3159 async iifeGlobalName({ esbuild }) {3160 const { code } = await esbuild.transform(`export default 123`, { format: 'iife', globalName: 'testName' })3161 const globals = {}3162 vm.createContext(globals)3163 vm.runInContext(code, globals)3164 assert.strictEqual(globals.testName.default, 123)3165 },3166 async iifeGlobalNameCompound({ esbuild }) {3167 const { code } = await esbuild.transform(`export default 123`, { format: 'iife', globalName: 'test.name' })3168 const globals = {}3169 vm.createContext(globals)3170 vm.runInContext(code, globals)3171 assert.strictEqual(globals.test.name.default, 123)3172 },3173 async iifeGlobalNameString({ esbuild }) {3174 const { code } = await esbuild.transform(`export default 123`, { format: 'iife', globalName: 'test["some text"]' })3175 const globals = {}3176 vm.createContext(globals)3177 vm.runInContext(code, globals)3178 assert.strictEqual(globals.test['some text'].default, 123)3179 },3180 async iifeGlobalNameUnicodeEscape({ esbuild }) {3181 const { code } = await esbuild.transform(`export default 123`, { format: 'iife', globalName: 'Ï["Ï ð"].ð["ð Ï"]' })3182 const globals = {}3183 vm.createContext(globals)3184 vm.runInContext(code, globals)3185 assert.strictEqual(globals.Ï["Ï ð"].ð["ð Ï"].default, 123)3186 assert.strictEqual(code.slice(0, code.indexOf('(() => {\n')), `var \\u03C0 = \\u03C0 || {};3187\\u03C0["\\u03C0 \\uD800\\uDC00"] = \\u03C0["\\u03C0 \\uD800\\uDC00"] || {};3188\\u03C0["\\u03C0 \\uD800\\uDC00"]["\\uD800\\uDC00"] = \\u03C0["\\u03C0 \\uD800\\uDC00"]["\\uD800\\uDC00"] || {};3189\\u03C0["\\u03C0 \\uD800\\uDC00"]["\\uD800\\uDC00"]["\\uD800\\uDC00 \\u03C0"] = `)3190 },3191 async iifeGlobalNameUnicodeNoEscape({ esbuild }) {3192 const { code } = await esbuild.transform(`export default 123`, { format: 'iife', globalName: 'Ï["Ï ð"].ð["ð Ï"]', charset: 'utf8' })3193 const globals = {}3194 vm.createContext(globals)3195 vm.runInContext(code, globals)3196 assert.strictEqual(globals.Ï["Ï ð"].ð["ð Ï"].default, 123)3197 assert.strictEqual(code.slice(0, code.indexOf('(() => {\n')),3198 `var Ï = Ï || {};3199Ï["Ï ð"] = Ï["Ï ð"] || {};3200Ï["Ï ð"]["ð"] = Ï["Ï ð"]["ð"] || {};3201Ï["Ï ð"]["ð"]["ð Ï"] = `)3202 },3203 async jsx({ esbuild }) {3204 const { code } = await esbuild.transform(`console.log(<div/>)`, { loader: 'jsx' })3205 assert.strictEqual(code, `console.log(/* @__PURE__ */ React.createElement("div", null));\n`)3206 },3207 async jsxTransform({ esbuild }) {3208 const { code } = await esbuild.transform(`console.log(<div/>)`, { loader: 'jsx', jsx: 'transform' })3209 assert.strictEqual(code, `console.log(/* @__PURE__ */ React.createElement("div", null));\n`)3210 },3211 async jsxPreserve({ esbuild }) {3212 const { code } = await esbuild.transform(`console.log(<div/>)`, { loader: 'jsx', jsx: 'preserve' })3213 assert.strictEqual(code, `console.log(<div />);\n`)3214 },3215 async ts({ esbuild }) {3216 const { code } = await esbuild.transform(`enum Foo { FOO }`, { loader: 'ts' })3217 assert.strictEqual(code, `var Foo;\n(function(Foo2) {\n Foo2[Foo2["FOO"] = 0] = "FOO";\n})(Foo || (Foo = {}));\n`)3218 },3219 async tsx({ esbuild }) {3220 const { code } = await esbuild.transform(`console.log(<Foo<T>/>)`, { loader: 'tsx' })3221 assert.strictEqual(code, `console.log(/* @__PURE__ */ React.createElement(Foo, null));\n`)3222 },3223 async minify({ esbuild }) {3224 const { code } = await esbuild.transform(`console.log("a" + "b" + c)`, { minify: true })3225 assert.strictEqual(code, `console.log("ab"+c);\n`)3226 },3227 async define({ esbuild }) {3228 const define = { 'process.env.NODE_ENV': '"production"' }3229 const { code } = await esbuild.transform(`console.log(process.env.NODE_ENV)`, { define })3230 assert.strictEqual(code, `console.log("production");\n`)3231 },3232 async defineArray({ esbuild }) {3233 const define = { 'process.env.NODE_ENV': '[1,2,3]', 'something.else': '[2,3,4]' }3234 const { code } = await esbuild.transform(`console.log(process.env.NODE_ENV)`, { define })3235 assert.strictEqual(code, `var define_process_env_NODE_ENV_default = [1, 2, 3];\nconsole.log(define_process_env_NODE_ENV_default);\n`)3236 },3237 async json({ esbuild }) {3238 const { code } = await esbuild.transform(`{ "x": "y" }`, { loader: 'json' })3239 assert.strictEqual(code, `module.exports = { x: "y" };\n`)3240 },3241 async jsonMinified({ esbuild }) {3242 const { code } = await esbuild.transform(`{ "x": "y" }`, { loader: 'json', minify: true })3243 const module = {}3244 new Function('module', code)(module)3245 assert.deepStrictEqual(module.exports, { x: 'y' })3246 },3247 async jsonESM({ esbuild }) {3248 const { code } = await esbuild.transform(`{ "x": "y" }`, { loader: 'json', format: 'esm' })3249 assert.strictEqual(code, `var x = "y";\nvar stdin_default = { x };\nexport {\n stdin_default as default,\n x\n};\n`)3250 },3251 async jsonInvalidIdentifierStart({ esbuild }) {3252 // This character is a valid "ID_Continue" but not a valid "ID_Start" so it must be quoted3253 const { code } = await esbuild.transform(`{ "\\uD835\\uDFCE": "y" }`, { loader: 'json' })3254 assert.strictEqual(code, `module.exports = { "\\u{1D7CE}": "y" };\n`)3255 },3256 async text({ esbuild }) {3257 const { code } = await esbuild.transform(`This is some text`, { loader: 'text' })3258 assert.strictEqual(code, `module.exports = "This is some text";\n`)3259 },3260 async textESM({ esbuild }) {3261 const { code } = await esbuild.transform(`This is some text`, { loader: 'text', format: 'esm' })3262 assert.strictEqual(code, `var stdin_default = "This is some text";\nexport {\n stdin_default as default\n};\n`)3263 },3264 async base64({ esbuild }) {3265 const { code } = await esbuild.transform(`\x00\x01\x02`, { loader: 'base64' })3266 assert.strictEqual(code, `module.exports = "AAEC";\n`)3267 },3268 async dataurl({ esbuild }) {3269 const { code } = await esbuild.transform(`\x00\x01\x02`, { loader: 'dataurl' })3270 assert.strictEqual(code, `module.exports = "data:application/octet-stream;base64,AAEC";\n`)3271 },3272 async sourceMapWithName({ esbuild }) {3273 const { code, map } = await esbuild.transform(`let x`, { sourcemap: true, sourcefile: 'afile.js' })3274 assert.strictEqual(code, `let x;\n`)3275 await assertSourceMap(map, 'afile.js')3276 },3277 async sourceMapExternalWithName({ esbuild }) {3278 const { code, map } = await esbuild.transform(`let x`, { sourcemap: 'external', sourcefile: 'afile.js' })3279 assert.strictEqual(code, `let x;\n`)3280 await assertSourceMap(map, 'afile.js')3281 },3282 async sourceMapInlineWithName({ esbuild }) {3283 const { code, map } = await esbuild.transform(`let x`, { sourcemap: 'inline', sourcefile: 'afile.js' })3284 assert(code.startsWith(`let x;\n//# sourceMappingURL=`))3285 assert.strictEqual(map, '')3286 const base64 = code.slice(code.indexOf('base64,') + 'base64,'.length)3287 await assertSourceMap(Buffer.from(base64.trim(), 'base64').toString(), 'afile.js')3288 },3289 async sourceMapBothWithName({ esbuild }) {3290 const { code, map } = await esbuild.transform(`let x`, { sourcemap: 'both', sourcefile: 'afile.js' })3291 assert(code.startsWith(`let x;\n//# sourceMappingURL=`))3292 await assertSourceMap(map, 'afile.js')3293 const base64 = code.slice(code.indexOf('base64,') + 'base64,'.length)3294 await assertSourceMap(Buffer.from(base64.trim(), 'base64').toString(), 'afile.js')3295 },3296 async sourceMapRoot({ esbuild }) {3297 const { code, map } = await esbuild.transform(`let x`, { sourcemap: true, sourcefile: 'afile.js', sourceRoot: "https://example.com/" })3298 assert.strictEqual(code, `let x;\n`)3299 assert.strictEqual(JSON.parse(map).sourceRoot, 'https://example.com/');3300 },3301 async numericLiteralPrinting({ esbuild }) {3302 async function checkLiteral(text) {3303 const { code } = await esbuild.transform(`return ${text}`, { minify: true })3304 assert.strictEqual(+text, new Function(code)())3305 }3306 const promises = []3307 for (let i = 0; i < 10; i++) {3308 for (let j = 0; j < 10; j++) {3309 promises.push(checkLiteral(`0.${'0'.repeat(i)}${'123456789'.slice(0, j)}`))3310 promises.push(checkLiteral(`1${'0'.repeat(i)}.${'123456789'.slice(0, j)}`))3311 promises.push(checkLiteral(`1${'123456789'.slice(0, j)}${'0'.repeat(i)}`))3312 }3313 }3314 await Promise.all(promises)3315 },3316 async tryCatchScopeMerge({ esbuild }) {3317 const code = `3318 var x = 13319 if (x !== 1) throw 'fail'3320 try {3321 throw 23322 } catch (x) {3323 if (x !== 2) throw 'fail'3324 {3325 if (x !== 2) throw 'fail'3326 var x = 33327 if (x !== 3) throw 'fail'3328 }3329 if (x !== 3) throw 'fail'3330 }3331 if (x !== 1) throw 'fail'3332 `;3333 new Function(code)(); // Verify that the code itself is correct3334 new Function((await esbuild.transform(code)).code)();3335 },3336 async nestedFunctionHoist({ esbuild }) {3337 const code = `3338 if (x !== void 0) throw 'fail'3339 {3340 if (x !== void 0) throw 'fail'3341 {3342 x()3343 function x() {}3344 x()3345 }3346 x()3347 }3348 x()3349 `;3350 new Function(code)(); // Verify that the code itself is correct3351 new Function((await esbuild.transform(code)).code)();3352 },3353 async nestedFunctionHoistBefore({ esbuild }) {3354 const code = `3355 var x = 13356 if (x !== 1) throw 'fail'3357 {3358 if (x !== 1) throw 'fail'3359 {3360 x()3361 function x() {}3362 x()3363 }3364 x()3365 }3366 x()3367 `;3368 new Function(code)(); // Verify that the code itself is correct3369 new Function((await esbuild.transform(code)).code)();3370 },3371 async nestedFunctionHoistAfter({ esbuild }) {3372 const code = `3373 if (x !== void 0) throw 'fail'3374 {3375 if (x !== void 0) throw 'fail'3376 {3377 x()3378 function x() {}3379 x()3380 }3381 x()3382 }3383 x()3384 var x = 13385 `;3386 new Function(code)(); // Verify that the code itself is correct3387 new Function((await esbuild.transform(code)).code)();3388 },3389 async nestedFunctionShadowBefore({ esbuild }) {3390 const code = `3391 let x = 13392 if (x !== 1) throw 'fail'3393 {3394 if (x !== 1) throw 'fail'3395 {3396 x()3397 function x() {}3398 x()3399 }3400 if (x !== 1) throw 'fail'3401 }3402 if (x !== 1) throw 'fail'3403 `;3404 new Function(code)(); // Verify that the code itself is correct3405 new Function((await esbuild.transform(code)).code)();3406 },3407 async nestedFunctionShadowAfter({ esbuild }) {3408 const code = `3409 try { x; throw 'fail' } catch (e) { if (!(e instanceof ReferenceError)) throw e }3410 {3411 try { x; throw 'fail' } catch (e) { if (!(e instanceof ReferenceError)) throw e }3412 {3413 x()3414 function x() {}3415 x()3416 }3417 try { x; throw 'fail' } catch (e) { if (!(e instanceof ReferenceError)) throw e }3418 }3419 try { x; throw 'fail' } catch (e) { if (!(e instanceof ReferenceError)) throw e }3420 let x = 13421 `;3422 new Function(code)(); // Verify that the code itself is correct3423 new Function((await esbuild.transform(code)).code)();3424 },3425 async sourceMapControlCharacterEscapes({ esbuild }) {3426 let chars = ''3427 for (let i = 0; i < 32; i++) chars += String.fromCharCode(i);3428 const input = `return \`${chars}\``;3429 const { code, map } = await esbuild.transform(input, { sourcemap: true, sourcefile: 'afile.code' })3430 const fn = new Function(code)3431 assert.strictEqual(fn(), chars.replace('\r', '\n'))3432 const json = JSON.parse(map)3433 assert.strictEqual(json.version, 3)3434 assert.strictEqual(json.sourcesContent.length, 1)3435 assert.strictEqual(json.sourcesContent[0], input)3436 },3437 async transformLegalCommentsJS({ esbuild }) {3438 assert.strictEqual((await esbuild.transform(`//!x\ny()`, { legalComments: 'none' })).code, `y();\n`)3439 assert.strictEqual((await esbuild.transform(`//!x\ny()`, { legalComments: 'inline' })).code, `//!x\ny();\n`)3440 assert.strictEqual((await esbuild.transform(`//!x\ny()`, { legalComments: 'eof' })).code, `y();\n//!x\n`)3441 try {3442 await esbuild.transform(``, { legalComments: 'linked' })3443 throw new Error('Expected a transform failure')3444 } catch (e) {3445 if (!e || !e.errors || !e.errors[0] || e.errors[0].text !== 'Cannot transform with linked or external legal comments')3446 throw e3447 }3448 try {3449 await esbuild.transform(``, { legalComments: 'external' })3450 throw new Error('Expected a transform failure')3451 } catch (e) {3452 if (!e || !e.errors || !e.errors[0] || e.errors[0].text !== 'Cannot transform with linked or external legal comments')3453 throw e3454 }3455 },3456 async transformLegalCommentsCSS({ esbuild }) {3457 assert.strictEqual((await esbuild.transform(`/*!x*/\ny{}`, { loader: 'css', legalComments: 'none' })).code, `y {\n}\n`)3458 assert.strictEqual((await esbuild.transform(`/*!x*/\ny{}`, { loader: 'css', legalComments: 'inline' })).code, `/*!x*/\ny {\n}\n`)3459 assert.strictEqual((await esbuild.transform(`/*!x*/\ny{}`, { loader: 'css', legalComments: 'eof' })).code, `y {\n}\n/*!x*/\n`)3460 try {3461 await esbuild.transform(``, { legalComments: 'linked' })3462 throw new Error('Expected a transform failure')3463 } catch (e) {3464 if (!e || !e.errors || !e.errors[0] || e.errors[0].text !== 'Cannot transform with linked or external legal comments')3465 throw e3466 }3467 try {3468 await esbuild.transform(``, { legalComments: 'external' })3469 throw new Error('Expected a transform failure')3470 } catch (e) {3471 if (!e || !e.errors || !e.errors[0] || e.errors[0].text !== 'Cannot transform with linked or external legal comments')3472 throw e3473 }3474 },3475 async tsDecorators({ esbuild }) {3476 const { code } = await esbuild.transform(`3477 let observed = [];3478 let on = key => (...args) => {3479 observed.push({ key, args });3480 };3481 @on('class')3482 class Foo {3483 @on('field') field;3484 @on('method') method() { }3485 @on('staticField') static staticField;3486 @on('staticMethod') static staticMethod() { }3487 fn(@on('param') x) { }3488 static staticFn(@on('staticParam') x) { }3489 }3490 // This is what the TypeScript compiler itself generates3491 let expected = [3492 { key: 'field', args: [Foo.prototype, 'field', undefined] },3493 { key: 'method', args: [Foo.prototype, 'method', { value: Foo.prototype.method, writable: true, enumerable: false, configurable: true }] },3494 { key: 'param', args: [Foo.prototype, 'fn', 0] },3495 { key: 'staticField', args: [Foo, 'staticField', undefined] },3496 { key: 'staticMethod', args: [Foo, 'staticMethod', { value: Foo.staticMethod, writable: true, enumerable: false, configurable: true }] },3497 { key: 'staticParam', args: [Foo, 'staticFn', 0] },3498 { key: 'class', args: [Foo] }3499 ];3500 return {observed, expected};3501 `, { loader: 'ts' });3502 const { observed, expected } = new Function(code)();3503 assert.deepStrictEqual(observed, expected);3504 },3505 async pureCallPrint({ esbuild }) {3506 const { code: code1 } = await esbuild.transform(`print(123, foo)`, { minifySyntax: true, pure: [] })3507 assert.strictEqual(code1, `print(123, foo);\n`)3508 const { code: code2 } = await esbuild.transform(`print(123, foo)`, { minifySyntax: true, pure: ['print'] })3509 assert.strictEqual(code2, `foo;\n`)3510 },3511 async pureCallConsoleLog({ esbuild }) {3512 const { code: code1 } = await esbuild.transform(`console.log(123, foo)`, { minifySyntax: true, pure: [] })3513 assert.strictEqual(code1, `console.log(123, foo);\n`)3514 const { code: code2 } = await esbuild.transform(`console.log(123, foo)`, { minifySyntax: true, pure: ['console.log'] })3515 assert.strictEqual(code2, `foo;\n`)3516 },3517 async nameCollisionEvalRename({ esbuild }) {3518 const { code } = await esbuild.transform(`3519 // "arg" must not be renamed to "arg2"3520 return function(arg2) {3521 function foo(arg) {3522 return arg + arg2;3523 }3524 // "eval" prevents "arg2" from being renamed3525 // "arg" below causes "arg" above to be renamed3526 return eval(foo(1)) + arg3527 }(2);3528 `)3529 const result = new Function('arg', code)(10)3530 assert.strictEqual(result, 13)3531 },3532 async nameCollisionEvalMinify({ esbuild }) {3533 const { code } = await esbuild.transform(`3534 // "arg" must not be renamed to "$"3535 return function($) {3536 function foo(arg) {3537 return arg + $;3538 }3539 // "eval" prevents "$" from being renamed3540 // Repeated "$" puts "$" at the top of the character frequency histogram3541 return eval(foo($$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$))3542 }(2);3543 `, { minifyIdentifiers: true })3544 const result = new Function('$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$', code)(1)3545 assert.strictEqual(result, 3)3546 },3547 async dynamicImportString({ esbuild }) {3548 const { code } = await esbuild.transform(`import('foo')`, { target: 'chrome63' })3549 assert.strictEqual(code, `import("foo");\n`)3550 },3551 async dynamicImportStringES6({ esbuild }) {3552 const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve'))3553 const { code } = await esbuild.transform(`import('foo')`, { target: 'chrome62' })3554 assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(() => __toModule(require("foo")));\n`)3555 },3556 async dynamicImportStringES5({ esbuild }) {3557 const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve'))3558 const { code } = await esbuild.transform(`import('foo')`, { target: 'chrome48' })3559 assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(function() {\n return __toModule(require("foo"));\n});\n`)3560 },3561 async dynamicImportStringES5Minify({ esbuild }) {3562 const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve'))3563 const { code } = await esbuild.transform(`import('foo')`, { target: 'chrome48', minifyWhitespace: true })3564 assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(function(){return __toModule(require("foo"))});\n`)3565 },3566 async dynamicImportStringNode12_19({ esbuild }) {3567 const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve'))3568 const { code } = await esbuild.transform(`import('foo')`, { target: 'node12.19' })3569 assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(() => __toModule(require("foo")));\n`)3570 },3571 async dynamicImportStringNode12_20({ esbuild }) {3572 const { code } = await esbuild.transform(`import('foo')`, { target: 'node12.20' })3573 assert.strictEqual(code, `import("foo");\n`)3574 },3575 async dynamicImportStringNode13({ esbuild }) {3576 const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve'))3577 const { code } = await esbuild.transform(`import('foo')`, { target: 'node13' })3578 assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(() => __toModule(require("foo")));\n`)3579 },3580 async dynamicImportStringNode13_1({ esbuild }) {3581 const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve'))3582 const { code } = await esbuild.transform(`import('foo')`, { target: 'node13.1' })3583 assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(() => __toModule(require("foo")));\n`)3584 },3585 async dynamicImportStringNode13_2({ esbuild }) {3586 const { code } = await esbuild.transform(`import('foo')`, { target: 'node13.2' })3587 assert.strictEqual(code, `import("foo");\n`)3588 },3589 async dynamicImportExpression({ esbuild }) {3590 const { code } = await esbuild.transform(`import(foo)`, { target: 'chrome63' })3591 assert.strictEqual(code, `import(foo);\n`)3592 },3593 async dynamicImportExpressionES6({ esbuild }) {3594 const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve'))3595 const { code: code2 } = await esbuild.transform(`import(foo)`, { target: 'chrome62' })3596 assert.strictEqual(fromPromiseResolve(code2), `Promise.resolve().then(() => __toModule(require(foo)));\n`)3597 },3598 async dynamicImportExpressionES5({ esbuild }) {3599 const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve'))3600 const { code: code3 } = await esbuild.transform(`import(foo)`, { target: 'chrome48' })3601 assert.strictEqual(fromPromiseResolve(code3), `Promise.resolve().then(function() {\n return __toModule(require(foo));\n});\n`)3602 },3603 async dynamicImportExpressionES5Minify({ esbuild }) {3604 const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve'))3605 const { code: code4 } = await esbuild.transform(`import(foo)`, { target: 'chrome48', minifyWhitespace: true })3606 assert.strictEqual(fromPromiseResolve(code4), `Promise.resolve().then(function(){return __toModule(require(foo))});\n`)3607 },3608 async caseInsensitiveTarget({ esbuild }) {3609 assert.strictEqual((await esbuild.transform(`a ||= b`, { target: 'eS5' })).code, `a || (a = b);\n`)3610 assert.strictEqual((await esbuild.transform(`a ||= b`, { target: 'eSnExT' })).code, `a ||= b;\n`)3611 },3612 async multipleEngineTargets({ esbuild }) {3613 const check = async (target, expected) =>3614 assert.strictEqual((await esbuild.transform(`foo(a ?? b)`, { target })).code, expected)3615 await Promise.all([3616 check('es2020', `foo(a ?? b);\n`),3617 check('es2019', `foo(a != null ? a : b);\n`),3618 check('chrome80', `foo(a ?? b);\n`),3619 check('chrome79', `foo(a != null ? a : b);\n`),3620 check(['es2020', 'chrome80'], `foo(a ?? b);\n`),3621 check(['es2020', 'chrome79'], `foo(a != null ? a : b);\n`),3622 check(['es2019', 'chrome80'], `foo(a != null ? a : b);\n`),3623 ])3624 },3625 async multipleEngineTargetsNotSupported({ esbuild }) {3626 try {3627 await esbuild.transform(`0n`, { target: ['es5', 'chrome1', 'safari2', 'firefox3'] })3628 throw new Error('Expected an error to be thrown')3629 } catch (e) {3630 assert.strictEqual(e.errors[0].text,3631 'Big integer literals are not available in the configured target environment ("chrome1", "es5", "firefox3", "safari2")')3632 }3633 },3634 // Future syntax3635 forAwait: ({ esbuild }) => futureSyntax(esbuild, 'async function foo() { for await (let x of y) {} }', 'es2017', 'es2018'),3636 bigInt: ({ esbuild }) => futureSyntax(esbuild, '123n', 'es2019', 'es2020'),3637 bigIntKey: ({ esbuild }) => futureSyntax(esbuild, '({123n: 0})', 'es2019', 'es2020'),3638 bigIntPattern: ({ esbuild }) => futureSyntax(esbuild, 'let {123n: x} = y', 'es2019', 'es2020'),3639 nonIdArrayRest: ({ esbuild }) => futureSyntax(esbuild, 'let [...[x]] = y', 'es2015', 'es2016'),3640 topLevelAwait: ({ esbuild }) => futureSyntax(esbuild, 'await foo', 'es2020', 'esnext'),3641 topLevelForAwait: ({ esbuild }) => futureSyntax(esbuild, 'for await (foo of bar) ;', 'es2020', 'esnext'),3642 // Future syntax: async generator functions3643 asyncGenFnStmt: ({ esbuild }) => futureSyntax(esbuild, 'async function* foo() {}', 'es2017', 'es2018'),3644 asyncGenFnExpr: ({ esbuild }) => futureSyntax(esbuild, '(async function*() {})', 'es2017', 'es2018'),3645 asyncGenObjFn: ({ esbuild }) => futureSyntax(esbuild, '({ async* foo() {} })', 'es2017', 'es2018'),3646 asyncGenClassStmtFn: ({ esbuild }) => futureSyntax(esbuild, 'class Foo { async* foo() {} }', 'es2017', 'es2018'),3647 asyncGenClassExprFn: ({ esbuild }) => futureSyntax(esbuild, '(class { async* foo() {} })', 'es2017', 'es2018'),3648}3649function registerClassPrivateTests(target) {3650 let contents = `3651 class Field { #foo = 123; bar = this.#foo }3652 if (new Field().bar !== 123) throw 'fail: field'3653 class Method { bar = this.#foo(); #foo() { return 123 } }3654 if (new Method().bar !== 123) throw 'fail: method'3655 class Accessor { bar = this.#foo; get #foo() { return 123 } }3656 if (new Accessor().bar !== 123) throw 'fail: accessor'3657 class StaticField { static #foo = 123; static bar = StaticField.#foo }3658 if (StaticField.bar !== 123) throw 'fail: static field'3659 class StaticMethod { static bar = StaticMethod.#foo(); static #foo() { return 123 } }3660 if (StaticMethod.bar !== 123) throw 'fail: static method'3661 class StaticAccessor { static bar = StaticAccessor.#foo; static get #foo() { return 123 } }3662 if (StaticAccessor.bar !== 123) throw 'fail: static accessor'3663 class StaticFieldThis { static #foo = 123; static bar = this.#foo }3664 if (StaticFieldThis.bar !== 123) throw 'fail: static field'3665 class StaticMethodThis { static bar = this.#foo(); static #foo() { return 123 } }3666 if (StaticMethodThis.bar !== 123) throw 'fail: static method'3667 class StaticAccessorThis { static bar = this.#foo; static get #foo() { return 123 } }3668 if (StaticAccessorThis.bar !== 123) throw 'fail: static accessor'3669 class FieldFromStatic { #foo = 123; static bar = new FieldFromStatic().#foo }3670 if (FieldFromStatic.bar !== 123) throw 'fail: field from static'3671 class MethodFromStatic { static bar = new MethodFromStatic().#foo(); #foo() { return 123 } }3672 if (MethodFromStatic.bar !== 123) throw 'fail: method from static'3673 class AccessorFromStatic { static bar = new AccessorFromStatic().#foo; get #foo() { return 123 } }3674 if (AccessorFromStatic.bar !== 123) throw 'fail: accessor from static'3675 `3676 // Test this code as JavaScript3677 let buildOptions = {3678 stdin: { contents },3679 bundle: true,3680 write: false,3681 target,3682 }3683 transformTests[`transformClassPrivate_${target[0]}`] = async ({ esbuild }) =>3684 new Function((await esbuild.transform(contents, { target })).code)()3685 buildTests[`buildClassPrivate_${target[0]}`] = async ({ esbuild }) =>3686 new Function((await esbuild.build(buildOptions)).outputFiles[0].text)()3687 // Test this code as TypeScript3688 let buildOptionsTS = {3689 stdin: { contents, loader: 'ts' },3690 bundle: true,3691 write: false,3692 }3693 transformTests[`tsTransformClassPrivate_${target[0]}`] = async ({ esbuild }) =>3694 new Function((await esbuild.transform(contents, { target, loader: 'ts' })).code)()3695 buildTests[`tsBuildClassPrivate_${target[0]}`] = async ({ esbuild }) =>3696 new Function((await esbuild.build(buildOptionsTS)).outputFiles[0].text)()3697}3698for (let es of ['es2015', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'esnext'])3699 registerClassPrivateTests([es])3700for (let chrome = 49; chrome < 100; chrome++)3701 registerClassPrivateTests([`chrome${chrome}`])3702for (let firefox = 45; firefox < 100; firefox++)3703 registerClassPrivateTests([`firefox${firefox}`])3704for (let edge = 13; edge < 100; edge++)3705 registerClassPrivateTests([`edge${edge}`])3706for (let safari = 10; safari < 20; safari++)3707 registerClassPrivateTests([`safari${safari}`])3708let formatTests = {3709 async formatMessages({ esbuild }) {3710 const messages = await esbuild.formatMessages([3711 { text: 'This is an error' },3712 { text: 'Another error', location: { file: 'file.js' } },3713 ], {3714 kind: 'error',3715 })3716 assert.strictEqual(messages.length, 2)3717 assert.strictEqual(messages[0], ` > error: This is an error\n\n`)3718 assert.strictEqual(messages[1], ` > file.js:0:0: error: Another error\n 0 â \n âµ ^\n\n`)3719 },3720}3721let analyzeTests = {3722 async analyzeMetafile({ esbuild }) {3723 const metafile = {3724 "inputs": {3725 "entry.js": {3726 "bytes": 50,3727 "imports": [3728 {3729 "path": "lib.js",3730 "kind": "import-statement"3731 }3732 ]3733 },3734 "lib.js": {3735 "bytes": 200,3736 "imports": []3737 }3738 },3739 "outputs": {3740 "out.js": {3741 "imports": [],3742 "exports": [],3743 "entryPoint": "entry.js",3744 "inputs": {3745 "entry.js": {3746 "bytesInOutput": 253747 },3748 "lib.js": {3749 "bytesInOutput": 503750 }3751 },3752 "bytes": 1003753 }3754 }3755 }3756 assert.strictEqual(await esbuild.analyzeMetafile(metafile), `3757 out.js 100b 100.0%3758 â lib.js 50b 50.0%3759 â entry.js 25b 25.0%3760`)3761 assert.strictEqual(await esbuild.analyzeMetafile(metafile, { verbose: true }), `3762 out.js ââââââ 100b ââ 100.0%3763 â lib.js ââââ 50b âââ 50.0%3764 â â entry.js3765 â entry.js ââ 25b âââ 25.0%3766`)3767 },3768}3769let functionScopeCases = [3770 'function x() {} { var x }',3771 'function* x() {} { var x }',3772 'async function x() {} { var x }',3773 'async function* x() {} { var x }',3774 '{ var x } function x() {}',3775 '{ var x } function* x() {}',3776 '{ var x } async function x() {}',3777 '{ var x } async function* x() {}',3778 '{ function x() {} { var x } }',3779 '{ function* x() {} { var x } }',3780 '{ async function x() {} { var x } }',3781 '{ async function* x() {} { var x } }',3782 '{ { var x } function x() {} }',3783 '{ { var x } function* x() {} }',3784 '{ { var x } async function x() {} }',3785 '{ { var x } async function* x() {} }',3786 'function f() { function x() {} { var x } }',3787 'function f() { function* x() {} { var x } }',3788 'function f() { async function x() {} { var x } }',3789 'function f() { async function* x() {} { var x } }',3790 'function f() { { var x } function x() {} }',3791 'function f() { { var x } function* x() {} }',3792 'function f() { { var x } async function x() {} }',3793 'function f() { { var x } async function* x() {} }',3794 'function f() { { function x() {} { var x } }}',3795 'function f() { { function* x() {} { var x } }}',3796 'function f() { { async function x() {} { var x } }}',3797 'function f() { { async function* x() {} { var x } }}',3798 'function f() { { { var x } function x() {} }}',3799 'function f() { { { var x } function* x() {} }}',3800 'function f() { { { var x } async function x() {} }}',3801 'function f() { { { var x } async function* x() {} }}',3802];3803{3804 let counter = 0;3805 for (let kind of ['var', 'let', 'const']) {3806 for (let code of functionScopeCases) {3807 code = code.replace('var', kind)3808 transformTests['functionScope' + counter++] = async ({ esbuild }) => {3809 let esbuildError3810 let nodeError3811 try { await esbuild.transform(code) } catch (e) { esbuildError = e }3812 try { new Function(code)() } catch (e) { nodeError = e }3813 if (!esbuildError !== !nodeError) {3814 throw new Error(`3815 code: ${code}3816 esbuild: ${esbuildError}3817 node: ${nodeError}3818 `)3819 }3820 }3821 }3822 }3823}3824let syncTests = {3825 async buildSync({ esbuild, testDir }) {3826 const input = path.join(testDir, 'in.js')3827 const output = path.join(testDir, 'out.js')3828 await writeFileAsync(input, 'export default 123')3829 esbuild.buildSync({ entryPoints: [input], bundle: true, outfile: output, format: 'cjs' })3830 const result = require(output)3831 assert.strictEqual(result.default, 123)3832 assert.strictEqual(result.__esModule, true)3833 },3834 async buildSyncOutputFiles({ esbuild, testDir }) {3835 const input = path.join(testDir, 'in.js')3836 const output = path.join(testDir, 'out.js')3837 await writeFileAsync(input, 'module.exports = 123')3838 let prettyPath = path.relative(process.cwd(), input).replace(/\\/g, '/')3839 let text = `// ${prettyPath}\nmodule.exports = 123;\n`3840 let result = esbuild.buildSync({ entryPoints: [input], bundle: true, outfile: output, format: 'cjs', write: false })3841 assert.strictEqual(result.outputFiles.length, 1)3842 assert.strictEqual(result.outputFiles[0].path, output)3843 assert.strictEqual(result.outputFiles[0].text, text)3844 assert.deepStrictEqual(result.outputFiles[0].contents, new Uint8Array(Buffer.from(text)))3845 },3846 async transformSyncJSMap({ esbuild }) {3847 const { code, map } = esbuild.transformSync(`1+2`, { sourcemap: true })3848 assert.strictEqual(code, `1 + 2;\n`)3849 assert.strictEqual(map, `{3850 "version": 3,3851 "sources": ["<stdin>"],3852 "sourcesContent": ["1+2"],3853 "mappings": "AAAA,IAAE;",3854 "names": []3855}3856`)3857 },3858 async transformSyncJSMapNoContent({ esbuild }) {3859 const { code, map } = esbuild.transformSync(`1+2`, { sourcemap: true, sourcesContent: false })3860 assert.strictEqual(code, `1 + 2;\n`)3861 assert.strictEqual(map, `{3862 "version": 3,3863 "sources": ["<stdin>"],3864 "mappings": "AAAA,IAAE;",3865 "names": []3866}3867`)3868 },3869 async transformSyncCSS({ esbuild }) {3870 const { code, map } = esbuild.transformSync(`a{b:c}`, { loader: 'css' })3871 assert.strictEqual(code, `a {\n b: c;\n}\n`)3872 assert.strictEqual(map, '')3873 },3874 async transformSyncWithNonString({ esbuild }) {3875 try {3876 esbuild.transformSync(Buffer.from(`1+2`))3877 throw new Error('Expected an error to be thrown');3878 } catch (e) {3879 assert.strictEqual(e.errors[0].text, 'The input to "transform" must be a string')3880 }3881 },3882 async transformSync100x({ esbuild }) {3883 for (let i = 0; i < 100; i++) {3884 const { code } = esbuild.transformSync(`console.log(1+${i})`, {})3885 assert.strictEqual(code, `console.log(1 + ${i});\n`)3886 }3887 },3888 async buildSyncThrow({ esbuild, testDir }) {3889 const input = path.join(testDir, 'in.js')3890 try {3891 const output = path.join(testDir, 'out.js')3892 await writeFileAsync(input, '1+')3893 esbuild.buildSync({ entryPoints: [input], bundle: true, outfile: output, format: 'cjs', logLevel: 'silent' })3894 const result = require(output)3895 assert.strictEqual(result.default, 123)3896 assert.strictEqual(result.__esModule, true)3897 throw new Error('Expected an error to be thrown');3898 } catch (error) {3899 assert(error instanceof Error, 'Must be an Error object');3900 assert.strictEqual(error.message, `Build failed with 1 error:3901${path.relative(process.cwd(), input).replace(/\\/g, '/')}:1:2: error: Unexpected end of file`);3902 assert.strictEqual(error.errors.length, 1);3903 assert.strictEqual(error.warnings.length, 0);3904 }3905 },3906 async buildSyncIncrementalThrow({ esbuild, testDir }) {3907 try {3908 const input = path.join(testDir, 'in.js')3909 const output = path.join(testDir, 'out.js')3910 await writeFileAsync(input, '1+')3911 esbuild.buildSync({ entryPoints: [input], bundle: true, outfile: output, format: 'cjs', logLevel: 'silent', incremental: true })3912 const result = require(output)3913 assert.strictEqual(result.default, 123)3914 assert.strictEqual(result.__esModule, true)3915 throw new Error('Expected an error to be thrown');3916 } catch (error) {3917 assert(error instanceof Error, 'Must be an Error object');3918 assert.strictEqual(error.message, `Build failed with 1 error:\nerror: Cannot use "incremental" with a synchronous build`);3919 assert.strictEqual(error.errors.length, 1);3920 assert.strictEqual(error.warnings.length, 0);3921 }3922 },3923 async buildSyncWatchThrow({ esbuild, testDir }) {3924 try {3925 const input = path.join(testDir, 'in.js')3926 const output = path.join(testDir, 'out.js')3927 await writeFileAsync(input, '1+')3928 esbuild.buildSync({ entryPoints: [input], bundle: true, outfile: output, format: 'cjs', logLevel: 'silent', watch: true })3929 const result = require(output)3930 assert.strictEqual(result.default, 123)3931 assert.strictEqual(result.__esModule, true)3932 throw new Error('Expected an error to be thrown');3933 } catch (error) {3934 assert(error instanceof Error, 'Must be an Error object');3935 assert.strictEqual(error.message, `Build failed with 1 error:\nerror: Cannot use "watch" with a synchronous build`);3936 assert.strictEqual(error.errors.length, 1);3937 assert.strictEqual(error.warnings.length, 0);3938 }3939 },3940 async transformThrow({ esbuild }) {3941 try {3942 await esbuild.transform(`1+`, {})3943 throw new Error('Expected an error to be thrown');3944 } catch (error) {3945 assert(error instanceof Error, 'Must be an Error object');3946 assert.strictEqual(error.message, `Transform failed with 1 error:\n<stdin>:1:2: error: Unexpected end of file`);3947 assert.strictEqual(error.errors.length, 1);3948 assert.strictEqual(error.warnings.length, 0);3949 }3950 },3951 async formatMessagesSync({ esbuild }) {3952 const messages = esbuild.formatMessagesSync([3953 { text: 'This is an error' },3954 { text: 'Another error', location: { file: 'file.js' } },3955 ], {3956 kind: 'error',3957 })3958 assert.strictEqual(messages.length, 2)3959 assert.strictEqual(messages[0], ` > error: This is an error\n\n`)3960 assert.strictEqual(messages[1], ` > file.js:0:0: error: Another error\n 0 â \n âµ ^\n\n`)3961 },3962 async analyzeMetafileSync({ esbuild }) {3963 const metafile = {3964 "inputs": {3965 "entry.js": {3966 "bytes": 50,3967 "imports": [3968 {3969 "path": "lib.js",3970 "kind": "import-statement"3971 }3972 ]3973 },3974 "lib.js": {3975 "bytes": 200,3976 "imports": []3977 }3978 },3979 "outputs": {3980 "out.js": {3981 "imports": [],3982 "exports": [],3983 "entryPoint": "entry.js",3984 "inputs": {3985 "entry.js": {3986 "bytesInOutput": 253987 },3988 "lib.js": {3989 "bytesInOutput": 503990 }3991 },3992 "bytes": 1003993 }3994 }3995 }3996 assert.strictEqual(esbuild.analyzeMetafileSync(metafile), `3997 out.js 100b 100.0%3998 â lib.js 50b 50.0%3999 â entry.js 25b 25.0%4000`)4001 assert.strictEqual(esbuild.analyzeMetafileSync(metafile, { verbose: true }), `4002 out.js ââââââ 100b ââ 100.0%4003 â lib.js ââââ 50b âââ 50.0%4004 â â entry.js4005 â entry.js ââ 25b âââ 25.0%4006`)4007 },4008}4009async function assertSourceMap(jsSourceMap, source) {4010 const map = await new SourceMapConsumer(jsSourceMap)4011 const original = map.originalPositionFor({ line: 1, column: 4 })4012 assert.strictEqual(original.source, source)4013 assert.strictEqual(original.line, 1)4014 assert.strictEqual(original.column, 10)4015}4016async function main() {4017 const esbuild = installForTests()4018 // Create a fresh test directory4019 removeRecursiveSync(rootTestDir)4020 fs.mkdirSync(rootTestDir)4021 // Time out these tests after 5 minutes. This exists to help debug test hangs in CI.4022 let minutes = 54023 let timeout = setTimeout(() => {4024 console.error(`â js api tests timed out after ${minutes} minutes, exiting...`)4025 process.exit(1)4026 }, minutes * 60 * 1000)4027 // Run all tests concurrently4028 const runTest = async ([name, fn]) => {4029 let testDir = path.join(rootTestDir, name)4030 try {4031 await mkdirAsync(testDir)4032 await fn({ esbuild, testDir })4033 removeRecursiveSync(testDir)4034 return true4035 } catch (e) {4036 console.error(`â ${name}: ${e && e.message || e}`)4037 return false4038 }4039 }4040 const tests = [4041 ...Object.entries(buildTests),4042 ...Object.entries(watchTests),4043 ...Object.entries(serveTests),4044 ...Object.entries(transformTests),4045 ...Object.entries(formatTests),4046 ...Object.entries(analyzeTests),4047 ...Object.entries(syncTests),4048 ]4049 let allTestsPassed = (await Promise.all(tests.map(runTest))).every(success => success)4050 if (!allTestsPassed) {4051 console.error(`â js api tests failed`)4052 process.exit(1)4053 } else {4054 console.log(`â js api tests passed`)4055 removeRecursiveSync(rootTestDir)4056 }4057 clearTimeout(timeout);4058}...
Functions.js
Source:Functions.js
1// jPak 1808-- 2// jPak 1901-- added password option ==> pwdProtected:'true' <==3function jPak(a) {4 if (a.leavePopUpOpen === undefined) a.leavePopUpOpen = 'false';5 if (a.returnAction === undefined) a.returnAction = "refreshAll"; /*noReturn , onlyAppend, refreshAll, myFunction*/6 if (a.refreshArea === undefined) a.refreshArea = "div1";7 if (a.ctrlAction === undefined) a.ctrlAction = "GetData";8 if (a.confirm === undefined) a.confirm = "false";9 if (a.event === undefined) a.event = "show"; /*update | insert | remove | show */10 if (a.edid === undefined) a.edid = 0;11 if (a.ctrl === undefined) a.ctrl = window.location.pathname.split('/')[1];12 //if (a.func === undefined) a.func = null;13 if (a.closefunc === undefined) a.closefunc = function (r) { };14 if (a.title === undefined) a.title = "Edit Area";15 if (a.tsk === undefined) a.tsk = "lst"; /*//lst //frm // dsp // rem // ref //*/16 if (a.popUp === undefined) a.popUp = "false";17 if (a.showLoader === 'true') { LoaderAppend(a.refreshArea); }18 if (a.popUpStyle === undefined) a.popUpStyle = "";19 if (a.popUpSize === undefined) a.popUpSize = "lg";20 if (a.divId === undefined) a.divId = a.refreshArea + "-" + a.edid;21 if (a.showMsg === undefined) a.showMsg = 'true';22 if (a.ctrl.length === 0) a.ctrl = "Home";23 var f = new FormData();24 if (a.tsk !== undefined) f.append("sect", a.tsk);25 if (a.refreshArea !== undefined) f.append("refreshArea", a.refreshArea);26 if (a.returnAction !== undefined) f.append("returnAction", a.returnAction);27 f.append("edid", a.edid);28 if (a.frmName !== undefined) {29 $('input[type=file]').each(function () {30 var inputfile = $(this);31 var files = inputfile[0].files;32 for (var fi = 0; fi < files.length; fi++) {33 f.append(inputfile[0].name, files[fi], files[fi].name);34 }35 });36 var elements = document.forms[a.frmName].elements;37 for (var i = 0; i < elements.length; i++) {38 if (elements[i].name.length !== 0) {39 if (elements[i].type === "radio" || elements[i].type === "checkbox") {40 if (elements[i].checked === true)41 f.append(elements[i].name, elements[i].value);42 } else f.append(elements[i].name, elements[i].value);43 }44 }45 }46 if (a.frmValues !== undefined) {47 var attrib = a.frmValues;48 Object.keys(attrib).forEach(function (key) { f.append(key, attrib[key]); });49 }50 if (a.leavePopUpOpen === 'false') KillPopUp();51 52 if (a.confirm === 'true') {53 if (a.confirmArr === undefined) a.confirmArr = {};54 if (a.confirmArr.title === undefined) a.confirmArr.title = "Are you sure?";55 if (a.confirmArr.text === undefined) a.confirmArr.text = " ";56 if (a.confirmArr.type === undefined) a.confirmArr.type = "warning";57 if (a.confirmArr.confirmButtonClass === undefined) a.confirmArr.confirmButtonClass = "btn-danger";58 if (a.confirmArr.confirmButtonText === undefined) a.confirmArr.confirmButtonText = "Yes, I am!";59 if (a.confirmArr.showCancelButton === undefined) a.confirmArr.showCancelButton = 'true';60 if (a.confirmArr.closeOnConfirm === undefined) a.confirmArr.closeOnConfirm = 'true';61 swal({62 type: "warning",63 confirmButtonClass: "btn-danger",64 title: a.confirmArr.title,65 text: a.confirmArr.text,66 confirmButtonText: a.confirmArr.confirmButtonText,67 showCancelButton: true,68 closeOnConfirm: true69 /*,showLoaderOnConfirm: true*/70 },71 function (isConfirm) {72 if (isConfirm) {73 window.onkeydown = null;74 window.onfocus = null;75 jPakAJx("/" + a.ctrl + "/" + a.ctrlAction, f, function (r) {76 jPakSuccessFunc(a, r);77 if (a.func !== undefined) {78 a.func(r);79 }80 return true;81 });82 } else {83 swal("Cancelled", "You are safe :)", "info");84 }85 });86 } else {87 if (a.pwdProtected === 'true') {88 swal({89 title: "Provide Password!",90 text: "Password:",91 type: "input",92 inputType: "password",93 showCancelButton: true,94 closeOnConfirm: false,95 showLoaderOnConfirm: true,96 inputPlaceholder: "Password"97 }, function (inputValue) {98 if (inputValue === false) return false;99 if (inputValue === "") { swal.showInputError("Can not be empty.!"); return false }100 f.append("code", inputValue);101 if (a.popUp === 'true') {102 jPakCrtMdl({ modalHeader: a.title, divId: a.divId, style: a.popUpStyle, sizeModal: a.popUpSize });103 $(document).on('click', "#swalClose1", function (r) { a.closefunc(r); });104 $(document).on('click', "#swalClose2", function (r) { a.closefunc(r); });105 a.refreshArea = a.divId;106 }107 jPakAJx("/" + a.ctrl + "/" + a.ctrlAction, f, function (r) { jPakSuccessFunc(a, r); if (a.func !== undefined) a.func(r); });108 swal.close();109 });110 die();111 }112 if (a.popUp === 'true') {113 jPakCrtMdl({ modalHeader: a.title, divId: a.divId, style: a.popUpStyle, sizeModal: a.popUpSize });114 $(document).on('click', "#swalClose1", function (r) { a.closefunc(r); });115 $(document).on('click', "#swalClose2", function (r) { a.closefunc(r); });116 a.refreshArea = a.divId;117 }118 jPakAJx("/" + a.ctrl + "/" + a.ctrlAction, f, function (r) { jPakSuccessFunc(a, r); if (a.func !== undefined) a.func(r); });119 }120 return false;121}122function jPakCrtMdl(a) {123 var divId = "PopUp";124 var sizeModal = "lg";125 var modalHeader = "General Information";126 var style = 'style="width:75%;"';127 if (a.divId !== undefined) divId = a.divId;128 if (a.sizeModal !== undefined) sizeModal = a.sizeModal;129 if (a.style !== undefined) style = a.style;130 if (a.modalHeader !== undefined) modalHeader = a.modalHeader;131 if (document.getElementById(divId) === null) {132 var div = '<div class="modal fade" id="' + divId + '">';133 var sizeModeldiv = '<div class="modal-dialog modal-' + sizeModal + '" style="' + style + '" >';134 var container = '<div class="modal-content">';135 var header = '<div class="modal-header"><button type="button" id="swalClose1" class="close swalClose" data-dismiss="modal" style="color: #000;">×</button><h4 class="modal-title">' + modalHeader + '</h4></div>';136 var body = '<div class="modal-body" id="modal-body" ></div>';137 var footer = '<div class="modal-footer"><button type="button" id="swalClose2" class="btn swalClose btn-default" data-dismiss="modal">Close</button></div>';138 container = container + header + body + footer + '</div>';139 sizeModeldiv = sizeModeldiv + container + '</div>';140 div = div + sizeModeldiv + '</div>';141 $('body').prepend(div);142 $('.modal-body').append('<div class="Preloader" id="Preloader" style="display:none"></div>');143 LoaderAppend("Preloader");144 ProgressAppend("Preloader");145 $('#' + divId).modal();146 $('#' + divId).on('shown.bs.modal', function () {147 $(document).off('focusin.modal');148 });149 }150}151function jPakAJx(url, data, success) {152 var type = "POST";153 if (data.length !== 0) {154 $.ajax({155 url: url,156 type: type,157 cache: false,158 contentType: false, // Not to set any content header159 processData: false, // Not to process data160 data: data,161 timeout: 30000,162 async: false,163 success: success,164 xhr: function () {165 var xhr = new window.XMLHttpRequest();166 xhr.upload.addEventListener("progress", function (evt) {167 if (evt.lengthComputable) {168 var percentComplete = evt.loaded / evt.total;169 percentComplete = parseInt(percentComplete * 100);170 /*$('.myprogress').text(percentComplete + '%');*/171 $('.myprogress').css('width', percentComplete + '%');172 }173 }, false);174 return xhr;175 },176 error: function (r) { /*swal("Oops!", "Some thing went wrong!", "warning");*/ }177 });178 } else {179 $.ajax({180 url: url,181 type: type,182 cache: false,183 timeout: 30000,184 async: false,185 contentType: false,186 processData: false,187 success: success,188 error: function (r) { /*swal("Oop!", "Some thing went wrong!", "warning");*/ }189 });190 }191}192function jPakSuccessFunc(a, r) {193 var row = document.getElementById('trc-' + a.edid);194 var rowC = $('.trc-' + a.edid);195 if (a.event === "remove") {196 if (row !== null) $('#trc-' + a.edid).remove();197 if (rowC !== null) $('.trc-' + a.edid).remove();198 if (a.showMsg === 'true') toastr.warning("Done");199 return false;200 }201 if (a.frmName !== undefined) {202 if (r.ReturnAction === "onlyPrepend") $('#' + r.RefreshArea).prepend(r.Data);203 else if (r.ReturnAction === "onlyAppend") $('#' + r.RefreshArea).append(r.Data);204 else if (r.ReturnAction === "refreshAll") $('#' + r.RefreshArea).empty().append(r.Data);205 if (a.showMsg === 'true' && (r.ErrorMessage !== undefined)) toastr.warning(r.ErrorMessage);206 if (document.forms[a.frmName] !== undefined) document.forms[a.frmName].reset();207 }208 if (a.returnAction === "refreshAll") {209 if (a.popUp === 'true') {210 $("#" + a.divId).modal('show');211 $('#' + a.divId + ' .modal-body').empty().html(r);212 } else213 $('#' + a.refreshArea).empty().append(r);214 }215 else if (a.returnAction === "onlyAppend") $('#' + a.refreshArea).append(r);216 else if (a.returnAction === "onlyPrepend") $('#' + a.refreshArea).prepend(r);217 else if (a.returnAction === "noReturn") {218 if (a.showMsg === 'true') toastr.warning("Done");219 }220 //else if (a.returnAction === "myFunc") a.func(r);221 else if (a.returnAction === "remoteFeed") {222 $.each(r,223 function (index, value) {224 if (value.ReturnAction === "onlyAppend")225 $('#' + value.RefreshArea).append(value.Data);226 else if (value.ReturnAction === "onlyPrepend")227 $('#' + value.RefreshArea).append(value.Data);228 else229 $('#' + value.RefreshArea).empty().append(value.Data);230 });231 } else {232 if (a.showMsg === 'true') toastr.warning("Done");233 }234}235//Dynamic Form236var FormAttrib = function (attr) {237 this.id = ((attr.id === undefined) ? "frm1" : attr.id);238 this.action = ((attr.action === undefined) ? "?" : attr.action);239 this.method = ((attr.method === undefined) ? "POST" : attr.method);240}241var InputText = function (attr) {242 this.label = ((attr.label === undefined) ? "-" : attr.label);243 this.labelDivClass = ((attr.labelDivClass === undefined) ? "control-label col-md-3" : attr.labelDivClass);244 this.DivFormat = ((attr.DivFormat === undefined) ? "{'col-md-3':'label','col-md-8':'input'}" : attr.DivFormat);245 this.pretxt = ((attr.pretxt === undefined) ? "-" : attr.pretxt);246 this.InputDivClass = ((attr.InputDivClass === undefined) ? "col-md-8" : attr.InputDivClass);247 this.posttxt = ((attr.posttxt === undefined) ? "-" : attr.posttxt);248 this.type = ((attr.type === undefined) ? "text" : attr.type);249 this.id = ((attr.id === undefined) ? "id1" : attr.id);250 this.value = ((attr.value === undefined) ? "" : attr.value);251 this.placeholder = ((attr.placeholder === undefined) ? "" : attr.placeholder);252 this.class = ((attr.class === undefined) ? "form-control" : attr.class);253 this.style = ((attr.style === undefined) ? "-" : attr.style);254 this.appendTo = ((attr.appendTo === undefined) ? "normal" : attr.appendTo);255 this.onChange = ((attr.onChange === undefined) ? "-" : attr.onChange);256 this.onClick = ((attr.onClick === undefined) ? "-" : attr.onClick);257 this.isNumber = ((this.type === 'number') ? "true" : "false");258 this.value = ((this.type === 'number') ? "1" : this.value);259 this.min = ((attr.min === undefined) ? "1" : attr.min);260 this.max = ((attr.max === undefined) ? "1" : attr.max);261 this.step = ((attr.step === undefined) ? "1" : attr.step);262 this.required = ((attr.required === undefined) ? "true" : attr.required);263 this.requiredmsg = ((attr.requiredmsg === undefined) ? "* <sub>required</sub>" : attr.requiredmsg);264};265function InpContainer(attrib) {266 var str = "";267 var arr = attrib.DivFormat;268 str = "<div class='form-group'>";269 Object.keys(arr).forEach(function (key) {270 str += "<div class='" + key + "'>{{" + arr[key] + "}}</div>";271 });272 str += "</div>";273 return str;274}275function ValidationMsgSpan(attrib) {276 var str = "";277 if (attrib.type !== "hidden") {278 str += " <span class='field-validation-valid text-danger' data-valmsg-for='" +279 attrib.id +280 "' data-valmsg-replace='true'></span>";281 }282 return str;283}284function InpHidden(attrib) {285 var str = "";286 if (attrib.type.toLowerCase() === "hidden") {287 str += "<input type='hidden' name='" + attrib.id + "' id='" + attrib.id + "' value='" + attrib.value + "' />";288 }289 return str;290}291function InpLabel(attrib) {292 var str = "";293 str += "<strong>" + attrib.label + "</strong>";294 return str;295}296function InpText(attrib) {297 var str = "";298 if (attrib.type.toLowerCase() === "text") {299 str += "<input name='" + attrib.id + "' ";300 Object.keys(attrib).forEach(function (key) {301 if (key !== "labelDivClass" &&302 key !== "label" &&303 key !== "DivFormat" &&304 key !== "inputsize" &&305 key !== "inputdivclass" &&306 key !== "posttxt" &&307 key !== "pretxt" &&308 key !== "labeldivclass" &&309 key !== "appendTo" &&310 key !== "min" &&311 key !== "max" &&312 key !== "step" &&313 attrib[key] !== "-") {314 if (key === "required") {315 str += "data-val='" + attrib[key] + "' ";316 } else if (key === "requiredmsg") {317 str += "data-val-required='" + attrib[key] + "' ";318 } else {319 str += key + "='" + attrib[key] + "' ";320 }321 }322 });323 str += " />";324 }325 return str;326}327function InpPassword(attrib) {328 var str = "";329 if (attrib.type.toLowerCase() === "password") {330 str += "<input name='" + attrib.id + "' ";331 Object.keys(attrib).forEach(function (key) {332 if (key !== "labelDivClass" &&333 key !== "label" &&334 key !== "DivFormat" &&335 key !== "inputsize" &&336 key !== "inputdivclass" &&337 key !== "posttxt" &&338 key !== "pretxt" &&339 key !== "labeldivclass" &&340 key !== "appendTo" &&341 key !== "min" &&342 key !== "max" &&343 key !== "step" &&344 attrib[key] !== "-") {345 if (key === "required") {346 str += "data-val='" + attrib[key] + "' ";347 } else if (key === "requiredmsg") {348 str += "data-val-required='" + attrib[key] + "' ";349 } else {350 str += key + "='" + attrib[key] + "' ";351 }352 }353 });354 str += " />";355 }356 return str;357}358function InpNumber(attrib) {359 var str = "";360 if (attrib.type.toLowerCase() === "number") {361 str += "<input name='" + attrib.id + "' ";362 Object.keys(attrib).forEach(function (key) {363 if (key !== "labelDivClass" &&364 key !== "label" &&365 key !== "DivFormat" &&366 key !== "inputsize" &&367 key !== "inputdivclass" &&368 key !== "posttxt" &&369 key !== "pretxt" &&370 key !== "labeldivclass" &&371 key !== "appendTo" &&372 key !== "min" &&373 key !== "max" &&374 key !== "step" &&375 attrib[key] !== "-") {376 if (key === "required") {377 str += "data-val='" + attrib[key] + "' ";378 } else if (key === "requiredmsg") {379 str += "data-val-required='" + attrib[key] + "' ";380 } else if (key === "isNumber") {381 str += "data-val-number='" + attrib[key] + "' ";382 if (attrib[key] !== "false") {383 str += (attrib.min !== "-" ? " min='" + attrib.min + "'" : "");384 str += (attrib.max !== "-" ? " max='" + attrib.max + "'" : "");385 str += (attrib.step !== "-" ? " step='" + attrib.step + "'" : "");386 }387 str += " onkeypress='return isNumberKey(event)' ";388 } else {389 str += key + "='" + attrib[key] + "' ";390 }391 }392 });393 str += " />";394 }395 return str;396}397function InpButton(attrib) {398 var str = "";399 if (attrib.type.toLowerCase() === "button") {400 str += "<button ";401 Object.keys(attrib).forEach(function (key) {402 if (key !== "labelDivClass" &&403 key !== "label" &&404 key !== "DivFormat" &&405 key !== "inputsize" &&406 key !== "labelDivClass" &&407 key !== "placeholder" &&408 key !== "InputDivClass" &&409 key !== "type" &&410 key !== "value" &&411 key !== "required" &&412 key !== "requiredmsg" &&413 key !== "isNumber" &&414 key !== "appendTo" &&415 key !== "posttxt" &&416 key !== "pretxt" &&417 key !== "min" &&418 key !== "max" &&419 key !== "step" &&420 attrib[key] !== "-") {421 str += key + "='" + attrib[key] + "' ";422 }423 });424 str += " >" + attrib.value + "</button>";425 }426 return str;427}428function InpDropdown(attrib) {429 var str = "";430 if (attrib.type.toLowerCase() === "select") {431 str += "<select name='" + attrib.id + "' ";432 Object.keys(attrib).forEach(function (key) {433 if (key !== "labelDivClass" &&434 key !== "label" &&435 key !== "DivFormat" &&436 key !== "inputsize" &&437 key !== "labelDivClass" &&438 key !== "placeholder" &&439 key !== "InputDivClass" &&440 key !== "type" &&441 key !== "value" &&442 key !== "required" &&443 key !== "requiredmsg" &&444 key !== "isNumber" &&445 key !== "appendTo" &&446 key !== "posttxt" &&447 key !== "pretxt" &&448 key !== "min" &&449 key !== "max" &&450 key !== "step" &&451 attrib[key] !== "-") {452 str += key + "='" + attrib[key] + "' ";453 }454 });455 str += " >";456 Object.keys(attrib.value).forEach(function (key) {457 var x = attrib.value[key];458 var tmp = x.split(':');459 str += "<option value='" +460 key +461 "' " +462 ((tmp[1] === undefined) ? " " : tmp[1]) +463 ">" +464 tmp[0] +465 "</option>";466 });467 str += "</select>";468 }469 return str;470}471function InpFeilds(attrib) {472 var str = "";473 if (attrib.type === "hidden") {474 str += InpHidden(attrib);475 } else if (attrib.type === "text") {476 str += InpText(attrib);477 ValidationMsgSpan(attrib);478 } else if (attrib.type === "number") {479 str += InpNumber(attrib);480 ValidationMsgSpan(attrib);481 } else if (attrib.type === "button") {482 str += InpButton(attrib);483 } else if (attrib.type === "password") {484 str += InpPassword(attrib);485 } else if (attrib.type === "select") {486 str += InpDropdown(attrib);487 }488 return str;489}490function InpDiv(attrib) {491 var str = "";492 var siz = 100;493 if (attrib.type !== "hidden") {494 if (attrib.DivFormat === "{'col-md-3':'label','col-md-8':'input'}") {495 str = "<div class='form-group'>";496 str += "<div class='" + attrib.labelDivClass + "'><strong>" + attrib.label + "</strong></div>";497 str += "<div class='" + attrib.InputDivClass + "'>";498 if (attrib.pretxt !== "-") {499 siz = siz - 10;500 str +=501 "<div style='width:10%;position: relative;top: 8px;display: block;text-align: center;float:left'>" +502 attrib.pretxt +503 "</div>";504 }505 str += "<div style='width:{{sizeofcolumn}};float:left'>" + InpFeilds(attrib) + "</div>";506 if (attrib.posttxt !== "-") {507 siz = siz - 10;508 str +=509 "<div style='width:10%;position: relative;top: 8px;display: block;text-align: center;float:left'>" +510 attrib.posttxt +511 "</div>";512 }513 str += "</div>";514 str += "</div>";515 str = str.replace("{{sizeofcolumn}}", siz + "%");516 } else {517 str += InpContainer(attrib);//<------------------------------------------------*****************************************518 }519 } else {520 str += InpFeilds(attrib);521 }522 return str;523}524function CreateForm(appendTo, formAttbr, inputsFeilds) {525 // alert(JSON.stringify(formAttbr) + " " + formAttbr.id);526 if (document.getElementById(formAttbr.id) === null) {527 var str = "<form ";528 Object.keys(formAttbr).forEach(function (key) {529 str += " " + key + "='" + formAttbr[key] + "' ";530 });531 str += "></form>";532 $(appendTo).append(str);533 var modalId = appendTo.split(" ");534 /* alert(JSON.stringify(modalId));*/535 $('#' + formAttbr.id).append('<div class="form-horizontal"></div>');536 Object.keys(inputsFeilds).forEach(function (key) {537 if (inputsFeilds[key]['type'] === "button" && inputsFeilds[key]['appendTo'] !== "normal") {538 $(modalId[0] + ' #' + inputsFeilds[key]['appendTo']).empty().append(InpFeilds(inputsFeilds[key]));539 } else {540 $('#' + formAttbr.id + ' .form-horizontal').append(InpDiv(inputsFeilds[key]));541 }542 });//form.submit();543 }544}545// General functions546function DateFormate(input) {547 var x = "";548 var d = new Date();549 if (input !== undefined) { d = new Date(input); }550 var yyyy = d.getFullYear().toString();551 var mm = (d.getMonth() + 1).toString(); // getMonth() is zero-based552 var dd = d.getDate().toString();553 return (mm[1] ? mm : "0" + mm[0]) + "/" + (dd[1] ? dd : "0" + dd[0]) + "/" + yyyy; // padding554};555function wholeNumber(numbr, leng) {556 var str = "";557 for (var i = 0; i < leng - numbr.toString().length; i++) {558 str += "0";559 }560 return str + numbr.toString();561}562function toPrice(inp) {563 var str = "";564 var valu = inp.toString();565 var a = valu.split('.');566 if (a.length > 1) {567 var c = (a[1].length === 1 ? a[1] + "0" : a[1]);568 str = a[0] + "." + c;569 } else { str = a[0] + ".00"; }570 return str;571}572function cleanPrice(inp) {573 var str = "";574 var valu = inp.toString();575 var a = valu.split('.');576 if (a.length > 1) {577 var c = (a[1].length === 1 ? a[1] + "0" : a[1]);578 str = a[0] + (c!=="00"?"." + c:"");579 } else { str = a[0] ; }580 return str;581}582function wait(seconds, callback) {583 return window.setTimeout(callback, seconds * 1000);584}585function ProgressAppend(divId) {586 var div = "<br><div class='progress'>";587 div = div + " <div class='progress-bar progress-bar-success myprogress' role='progressbar' style='width:0%'></div>";588 div = div + "</div>";589 $('#' + divId).append(div);590}591function LoaderAppend(divId) {592 $('#' + divId).empty()593 .html('<center><br><br><img src="/Content/img/Layout/Loading09.gif" style="margin: 0 auto;"/></center>');594}595function isEmail($email) {596 var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;597 return emailReg.test($email);598}599//onkeypress="return isNumberKey(event)"600function isNumberKey(evt) {601 var charCode = (evt.which) ? evt.which : event.keyCode;602 if (charCode != 46 && charCode > 31603 && (charCode < 48 || charCode > 57))604 return false;605 return true;606}607// Auth Purchase DeveloperDelPur608function AdmPurDel(a,data) {609 swal({610 title: "Security Alert!",611 text: "Please provide passCode:",612 type: "input",613 showCancelButton: true,614 closeOnConfirm: true,615 inputPlaceholder: "Code"616 }, function (inputValue) {617 if (inputValue === false) return false;618 if (inputValue === "") {619 swal.showInputError("Code");620 return false621 }622 var f = new FormData();623 f.append("code", inputValue);f.append("pi", a);f.append("id", data);624 GeneralAjax2("/AuthPurchase/AdminDPurchase", f, function (r) { toastr.warning(r);$('#' + data).hide();});625 });626}627//<button onclick="adjustHeights('strong');alert(1);return false">test</button>628function adjustHeights(elem) {629 var fontstep = 2;630 elem = elem instanceof jQuery ? elem : $(elem);631 if (elem.height() > elem.parent().height() || elem.width() > elem.parent().width()) {632 elem.css('font-size', ((elem.css('font-size').substr(0, 2) - fontstep)) + 'px').css('line-height', ((elem.css('font-size').substr(0, 2))) + 'px');633 adjustHeights(elem);634 }635}636function MyAjax(url, type, data, containerDiv) {637 if (type.length === 0) { type = "POST"; }638 if (url.length !== 0 && containerDiv.length !== 0) {639 if (data.length !== 0) {640 $.ajax({641 url: url,642 type: type,643 cache: false,644 contentType: false, // Not to set any content header645 processData: false, // Not to process data646 data: data,647 success: function (result) {648 if (result) {649 //alert(result);650 $('#' + containerDiv + ' .modal-body').empty().html(result);651 }652 },653 error: function (err) {654 alert(err.statusText);655 $('#' + containerDiv).modal('hide');656 }657 });658 } else {659 $.ajax({660 url: url,661 type: type,662 cache: false,663 contentType: false,664 processData: false,665 success: function (result) {666 if (result) {667 $('#' + containerDiv + ' .modal-body').empty().html(result);668 }669 },670 error: function (err) {671 alert(err.statusText);672 $('#' + containerDiv).modal('hide');673 }674 });675 }676 } else {677 alert("Error: I dont know where i am going.!");678 }679}680function GeneralAjax2(url, data, success) {681 var type = "POST";682 if (data.length !== 0) {683 $.ajax({684 url: url,685 type: type,686 cache: false,687 contentType: false, // Not to set any content header688 processData: false, // Not to process data689 data: data,690 success: success,691 xhr: function () {692 var xhr = new window.XMLHttpRequest();693 xhr.upload.addEventListener("progress", function (evt) {694 if (evt.lengthComputable) {695 var percentComplete = evt.loaded / evt.total;696 percentComplete = parseInt(percentComplete * 100);697 /*$('.myprogress').text(percentComplete + '%');*/698 $('.myprogress').css('width', percentComplete + '%');699 }700 }, false);701 return xhr;702 },703 error: function (r) { /*swal("Oops!", "Some thing went wrong!", "warning");*/ }704 });705 } else {706 $.ajax({707 url: url,708 type: type,709 cache: false,710 contentType: false,711 processData: false,712 success: success,713 error: function (r) { /*swal("Oop!", "Some thing went wrong!", "warning");*/ }714 });715 }716}717function GeneralAjax(url, type, data, success, error) {718 if (type.length === 0) { type = "POST"; }719 if (data.length !== 0) {720 $.ajax({721 url: url,722 type: type,723 cache: false,724 contentType: false, // Not to set any content header725 processData: false, // Not to process data726 data: data,727 success: success,728 xhr: function () {729 var xhr = new window.XMLHttpRequest();730 xhr.upload.addEventListener("progress", function (evt) {731 if (evt.lengthComputable) {732 var percentComplete = evt.loaded / evt.total;733 percentComplete = parseInt(percentComplete * 100);734 /*$('.myprogress').text(percentComplete + '%');*/735 $('.myprogress').css('width', percentComplete + '%');736 }737 }, false);738 return xhr;739 },740 error: error741 });742 } else {743 $.ajax({744 url: url,745 type: type,746 cache: false,747 contentType: false,748 processData: false,749 success: success,750 error: error751 });752 }753}754function CreateModalnAppend(divId, appendTo, sizeModal, modalHeader) {755 if (sizeModal.length === 0) { sizeModal = 'lg'; }756 if (modalHeader.length === 0) { modalHeader = 'General Information'; }757 if (document.getElementById(divId) === null) {758 var div = '<div class="modal fade" id="' + divId + '">';759 var sizeModeldiv = '<div class="modal-dialog modal-' + sizeModal + '">';760 var container = '<div class="modal-content">';761 var header =762 '<div class="modal-header"><button type="button" class="close" data-dismiss="modal">×</button><h4 class="modal-title">' +763 modalHeader +764 '</h4></div>';765 var body = '<div class="modal-body" id="modal-body"></div>';766 var footer = '<div class="modal-footer">' +767 '<div id="action-btn" style="width:49%;float:left;text-align:left"></div>' +768 '<div id="close-btn" style="width:49%;float:right"><button type="button" class="btn btn-default" data-dismiss="modal">Close</button></div>' +769 '</div>';770 container = container + header + body + footer + '</div>';771 sizeModeldiv = sizeModeldiv + container + '</div>';772 div = div + sizeModeldiv + '</div>';773 $(appendTo).append(div);774 $('.modal-body').append('<div class="Preloader" id="Preloader" style="display:none"></div>');775 LoaderAppend("Preloader");776 ProgressAppend("Preloader");777 }778}779function CreateModal(divId, sizeModal, modalHeader) {780 var wid = "";781 if (sizeModal.length === 0) { sizeModal = 'lg'; }782 if (sizeModal === 'lg') { wid = 'style="width:75%;"' }783 if (modalHeader.length === 0) { modalHeader = 'General Information'; }784 if (document.getElementById(divId) === null) {785 var div = '<div class="modal fade" id="' + divId + '">';786 var sizeModeldiv = '<div class="modal-dialog modal-' + sizeModal + '" '+wid+' >';787 var container = '<div class="modal-content">';788 var header = '<div class="modal-header"><button type="button" class="close" data-dismiss="modal">×</button><h4 class="modal-title">' +modalHeader +'</h4></div>';789 var body = '<div class="modal-body" id="modal-body" ></div>';790 var footer = '<div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">Close</button></div>';791 container = container + header + body + footer + '</div>';792 sizeModeldiv = sizeModeldiv + container + '</div>';793 div = div + sizeModeldiv + '</div>';794 $('body').append(div);795 $('.modal-body').append('<div class="Preloader" id="Preloader" style="display:none"></div>');796 LoaderAppend("Preloader");797 ProgressAppend("Preloader");798 }799}800function CreateModal2(divId, sizeModal) {801 if (sizeModal.length === 0) { sizeModal = 'lg'; }802 if (document.getElementById(divId) === null) {803 var div = '<div class="modal fade" id="' + divId + '" data-backdrop="static">';804 var body = '<div class="modal-dialog modal-' + sizeModal + ' modal-body" id="modal-body">';805 div += body + '</div></div>';806 $('body').append(div);807 $('.modal-body').append('<div class="Preloader" id="Preloader" style="display:none"></div>');808 LoaderAppend("Preloader");809 ProgressAppend("Preloader");810 }811}812function CreateModalBasic(divId, sizeModal) {813 if (sizeModal.length === 0) { sizeModal = 'lg'; }814 if (document.getElementById(divId) === null) {815 var div = '<div class="modal fade" id="' + divId + '">';816 var sizeModeldiv = '<div class="modal-dialog modal-' + sizeModal + '">';817 sizeModeldiv = sizeModeldiv + '<center><img src="/Content/img/Layout/Loading09.gif" style="margin: 0 auto;"/></center></div>';818 div = div + sizeModeldiv + '</div>';819 $('body').append(div);820 }821}822function CreatePictureModal(divId) {823 if (divId === undefined) { divId = "myModal"; }824 if (document.getElementById(divId) === null) {825 var div = ' <div class="PicModal" id="' + divId + '">';826 div = div + ' <span class="PicModalclose" style="margin-top:50px;">×</span>';827 div = div + ' <img class="PicModal-content" id="img01">';828 div = div + ' <div id="PicModalcaption"></div>';829 div = div + '</div>';830 $('body').append(div);831 }832}833function TranTypeToStr(tranId) {834 var str = "";835 var id = parseInt(tranId);836 if (id === 0) {837 str = "Purchase";838 } else if (id === 1) {839 str = "Sale";840 } else if (id === 2) {841 str = "Return";842 } else if (id === 3) {843 str = "Damaged";844 } else if (id === 4) {845 str = "Replace";846 } else if (id === 5) {847 str = "Issued to Ebay";848 } else if (id === 6) {849 str = "Return from Ebay";850 } else if (id === 7) {851 str = "Sold by Other Means / Adjustment";852 } else if (id === 11) {853 str = "Discount";854 } else if (id === 12) {855 str = "Transport";856 } else if (id === 13) {857 str = "PayPal Fee";858 } else {859 str = "Unknown";860 }861 return str;862}863function ModifyedTrColor() {864 var back = ["#22A7F0", "#8E44AD", "#AEA8D3", "#F62459", "#DB0A5B", "#D64541", "#D2527F", "#2C3E50", "#1E8BC3", "#87D37C", "#4ECDC4", "#3FC380", "#E87E04", "#F9690E", "#F9BF3B"];865 $('.modifyed').each(function () {866 // First random color867 var rand1 = back[Math.floor(Math.random() * back.length)];868 // Second random color869 var rand2 = back[Math.floor(Math.random() * back.length)];870 var grad = $(this);871 // Convert Hex color to RGB872 function convertHex(hex, opacity) {873 hex = hex.replace('#', '');874 r = parseInt(hex.substring(0, 2), 16);875 g = parseInt(hex.substring(2, 4), 16);876 b = parseInt(hex.substring(4, 6), 16);877 // Add Opacity to RGB to obtain RGBA878 result = 'rgba(' + r + ',' + g + ',' + b + ',' + opacity / 100 + ')';879 return result;880 }881 grad.removeClass('even');882 grad.removeClass('odd');883 // Gradient rules884 //$("#elem").css("cssText", "width: 100px !important;");885 grad.css("cssText", 'background-color:' + convertHex(rand1, 40) + '!important');886 grad.css("background-image", "-webkit-gradient(linear, left top, left bottom, color-stop(0%," + convertHex(rand1, 40) + "), color-stop(100%," + convertHex(rand2, 40) + "))");887 grad.css("background-image", "-webkit-linear-gradient(top, " + convertHex(rand1, 40) + " 0%," + convertHex(rand2, 40) + " 100%)");888 grad.css("background-image", "-o-linear-gradient(top, " + convertHex(rand1, 40) + " 0%," + convertHex(rand2, 40) + " 100%)");889 grad.css("background-image", "-ms-linear-gradient(top, " + convertHex(rand1, 40) + " 0%," + convertHex(rand2, 40) + " 100%)");890 grad.css("background-image", "linear-gradient(to bottom, " + convertHex(rand1, 40) + " 0%," + convertHex(rand2, 40) + " 100%)");891 grad.css("filter", "progid:DXImageTransform.Microsoft.gradient( startColorstr='" + convertHex(rand1, 40) + "', endColorstr='" + convertHex(rand2, 40) + "',GradientType=0 )");892 });893}894//home index + detial index895function flyToElement(flyer, flyingTo) {896 var $func = $(this);897 var divider = 3;898 var flyerClone = $(flyer).clone();899 //flyClone.attr("src", flyClone.attr("src").replace("_thumb", ""));900 $(flyerClone).css({ position: 'absolute', top: $(flyer).offset().top + "px", left: $(flyer).offset().left + "px", opacity: 1, 'z-index': 1000 });901 $('body').append($(flyerClone));902 var gotoX = $(flyingTo).offset().left + ($(flyingTo).width() / 2) - ($(flyer).width() / divider) / 2;903 var gotoY = $(flyingTo).offset().top + ($(flyingTo).height() / 2) - ($(flyer).height() / divider) / 2;904 $(flyerClone).animate({905 opacity: 0.4,906 left: gotoX,907 top: gotoY,908 width: $(flyer).width() / divider,909 height: $(flyer).height() / divider910 }, 700,911 function () {912 $(flyingTo).fadeOut('fast', function () {913 $(flyingTo).fadeIn('fast', function () {914 $(flyerClone).fadeOut('fast', function () {915 $(flyerClone).remove();916 });917 });918 });919 });920}921function sendToCart(obj, redirect, itemImg)922{923 var fileData = new FormData();924 fileData.append('sku', obj.attr("data-sku"));925 fileData.append('di', obj.attr("data-ref"));926 fileData.append('qty', obj.attr("data-qty"));927 fileData.append('did', obj.attr("data-did"));928 fileData.append('typ', obj.attr("data-typ"));929 flyToElement(itemImg, $('.cart_anchor'));930 var cnt = $("#itemCount").html();931 $("#itemCount").empty().html('<i class="fa fa-cog fa-spin fa-3x fa-fw" style="font-size:14px;"></i>');932 $.ajax({933 url: '/Cart/Add',934 type: "POST",935 contentType: false, // Not to set any content header936 processData: false, // Not to process data937 data: fileData,938 success: function (result) {939 var data = result;940 var arr = data.split(':');941 if (arr[0] === "Out of Stock") {942 swal({943 imageUrl: '/Content/img/Layout/OutofStock.png',944 title: "We are Sorry!",945 text: "This item is temporarily out of stock. If you want, We can contact you if new stock arrives",946 showCancelButton: true,947 confirmButtonClass: "btn-success",948 confirmButtonText: "Yes, please.",949 cancelButtonText: "No, thanks.",950 closeOnConfirm: false,951 closeOnCancel: false952 },953 function (isConfirm) {954 if (isConfirm) {955 swal({956 imageUrl: '/Content/img/Layout/Loading11.gif',957 title: "Notification",958 text: "New Stock Arrival Update, Email:",959 type: "input",960 showCancelButton: true,961 closeOnConfirm: false,962 inputPlaceholder: "Email@Domain.com"963 }, function (inputValue) {964 if (inputValue === false) return false;965 if (inputValue === "") {966 swal.showInputError("Email Valid!");967 return false;968 }969 if (isEmail(inputValue)) {970 // email saveing code here971 swal("Nice!", "Thank you!", "success");972 } else { swal.showInputError("Email Valid!"); }973 });974 } else {975 swal({976 title: "Ok!",977 text: "Sorry for the inconvenience.",978 imageUrl: '/Content/img/Layout/thumbs-up.jpg'979 });980 }981 });982 $("#itemCount").empty().html(cnt);983 } else if (arr[0] === "Done") {984 $("#itemCount").empty().html(arr[1]);985 if (pgId === "c1") { GetCartData(); }986 if (redirect === true) { window.location.href = '/Cart'; }987 }988 },989 error: function (err) {990 alert(err.statusText);991 $("#itemCount").empty().html(cnt);992 }993 });994}995function PurchaseTransactionConfirm(data, pi ) {996 swal({997 title: "Transaction Confirmation!",998 text: "Please provide the Transaction Id:" +data+ ":"+ pi ,999 type: "input",1000 showCancelButton: true,1001 closeOnConfirm: false,1002 inputPlaceholder: "Transaction Id"1003 },1004 function (inputValue) {1005 if (inputValue === false) return false;1006 if (inputValue === pi) {1007 swal({1008 title: "Are you sure?",1009 text: "Is this Transaction Confirmed?",1010 type: "warning",1011 showCancelButton: true,1012 confirmButtonClass: "btn-info",1013 confirmButtonText: "Yes, Confirm it!",1014 cancelButtonText: "No, cancel it!",1015 closeOnConfirm: true,1016 closeOnCancel: true1017 },1018 function (isConfirm) {1019 if (isConfirm) {1020 var fileData = new FormData();1021 fileData.append('id', data);1022 GeneralAjax2("/AuthPurchase/ProcessTransaction",fileData,function(r) {1023 if (r === "Done") {1024 toastr.info("Info", "Transaction Completed Succesfully", "success");1025 $("#sta-" + data).text("Confirmed!");1026 $('#' + data).hide();1027 } else {1028 toastr.error("Error", "Error :" + r, "error");1029 }1030 });1031 } else {1032 toastr.error("Error", "Error :" + r, "error");1033 }1034 });1035 } else {1036 swal.showInputError("Transaction Id");1037 return false;1038 }1039 return false;1040 });1041}1042function PurchaseTransactionTrash(data, pi) {1043 swal({1044 title: "Delete Transcation Confirmation!",1045 text: "Please provide PInvoice number: " + pi,1046 type: "input",1047 showCancelButton: true,1048 closeOnConfirm: false,1049 inputPlaceholder: "PInvoice number"1050 },1051 function (inputValue) {1052 if (inputValue === false) return false;1053 if (inputValue === pi) {1054 var fileData = new FormData();1055 fileData.append('id', data);1056 swal({1057 title: "Are you sure?",1058 text: "You will not be able to recover this Transaction!",1059 type: "warning",1060 showCancelButton: true,1061 confirmButtonClass: "btn-danger",1062 confirmButtonText: "Yes, delete it!",1063 cancelButtonText: "No, cancel plx!",1064 closeOnConfirm: true,1065 closeOnCancel: true1066 },1067 function (isConfirm) {1068 if (isConfirm) {1069 GeneralAjax2("/AuthPurchase/ProcessTransaction", fileData, function (r) {1070 if (r === "Done") {1071 toastr.success("Deleted!", "Your Transaction is Deleted.");1072 $('#' + data).hide();1073 } else {1074 toastr.error("Error", "Error :" + r);1075 }1076 },1077 function (r) {1078 toastr.error("Error", "Error :" + r, "error");1079 });1080 } else {1081 toastr.info("Cancelled", "Your Transaction is safe :)");1082 }1083 });1084 } else {1085 swal.showInputError("Please provide PInvoice number.");1086 return false;1087 }1088 });1089}1090//cart index1091function SingleSaveBtnStyle(num) {1092 var o = $('#oldQty-' + num).val();1093 var n = $('#js-num' + num).val();1094 1095 if (n === o) {1096 /*$("#singleSaveBtn" + num).stop().animate({ "opacity": 0 }, 300);;*/1097 $("#singleSaveBtn" + num).hide();1098 for (var j = 1; j <= eval($('#totalSn').val()) ; j++) {1099 if ($('#singleSaveBtn' + j).is(":visible") === true) {1100 $('#savebtn').show();1101 break;1102 }1103 $('#savebtn').hide();1104 $('#netshipping').text($('#hdnetshipping').val());1105 $('#netshippingTd').removeClass('text-danger');1106 $('.js-out-cart').show();1107 }1108 } else {1109 1110 /*$("#singleSaveBtn" + num).animate({ "opacity": 1 }, 300);*/1111 $("#singleSaveBtn" + num).show();1112 $('#savebtn').show();1113 $('.js-out-cart').hide();1114 $('#netshippingTd').addClass('text-danger');1115 }1116}1117function NoRecords() {1118 $("#cartitems").empty()1119 .html("<tr><th colspan='6' style='text-align:center'></th></tr>" +1120 "<tr><th colspan='6' style='text-align:center;height:320px;'><a href='/Home/' ><img src='/Content/img/Layout/emptyCart3.jpg'></a></th></tr>");1121 1122 $("#btnArea").empty();1123 $("#itemCount").empty().html("0");1124 $("#thd").hide();1125}1126function OpnAddressEntryFrm(customerid,appDiv)1127{1128 alert('no code in here,functions:445');1129}1130function OpnEmlEntryFrm(customerid, appDiv) {1131 1132 alert('no code in here,functions:448');1133}1134function OpnEml(id) {1135 var divId = 'EmailInvoice';1136 CreateModal(divId, "lg", 'Email Invoice');1137 $("#" + divId).modal('show');1138 var fileData = new FormData();1139 fileData.append('id', id);1140 MyAjax("/AuthPopups/GetEmail/", "POST", fileData, divId);1141}1142function OpnInv(id) {1143 var divId = 'InvoiceModal';1144 CreateModal(divId, "lg", '<img alt="paypal" style="width:113px; height:46px;" width="113" height="46" border="0" src="https://www.paypalobjects.com/en_US/i/logo/logo_emailheader_113wx46h.gif">');1145 $("#" + divId).modal('show');1146 var fileData = new FormData();1147 fileData.append('id', id);1148 MyAjax("/AuthPopups/GetInvoice/", "POST", fileData, divId);1149 1150}1151function OpnMap(lat, long) {1152 var divId = 'GeneralModal';1153 CreateModal(divId, "sm", "Location On Map");1154 $("#" + divId).modal('show');1155 $("#" + divId + " .modal-body").empty().html(lat + " - " + long);1156}1157function opnCart(id) {1158 jPak({ popUp: 'true', leavePopUpOpen: 'true', title: 'Shopping Cart', popUpSize: 'lg', ctrl: 'AuthTmpCart', ctrlAction: 'GetCart', edid: id, showLoader :'true'});1159 }1160function OpnPrd(sku) {1161 var divId = 'ProductModal';1162 CreateModal(divId, "lg","Product Description");1163 $("#" + divId).modal('show');1164 var fileData = new FormData();1165 fileData.append('sku', sku);1166 MyAjax("/AuthPopups/GetProduct/", "POST", fileData, divId);1167 1168}1169function OpnCus(id) {1170 var divId = 'CustomerModal';1171 CreateModal(divId, "md","Customer Profile");1172 $("#" + divId).modal('show');1173 var fileData = new FormData();1174 fileData.append('CustId', id);1175 MyAjax("/AuthPopups/GetCustomer/", "POST", fileData, divId);1176 }1177function OpnBrokenOdr(id) {1178 var divId = 'BrokenOrderModal';1179 CreateModal(divId, "lg","Broken Token in JSON Format");1180 $("#" + divId).modal('show');1181 var fileData = new FormData();1182 fileData.append('id', id);1183 MyAjax("/AuthPopups/GetBrokenOdr/", "POST", fileData, divId);1184 }1185function GetMore(section) {1186 1187 var btn = $('.js-' + section);1188 var dm = $('.js-dm-' + section);1189 var itmCnt = btn.attr('data-itmCnt');1190 1191 var rotation = btn.attr('data-rotation');1192 var appender = btn.attr('data-Append');1193 btn.fadeTo(250, 0).hide();1194 dm.fadeTo(200, 1).show();1195 var fileData = new FormData();1196 fileData.append('rot', rotation);1197 fileData.append('itm', itmCnt);1198 GeneralAjax("/AuthPopups/GetSection/", "POST", fileData,1199 function (r) {1200 dm.fadeTo(250, 0).hide();1201 btn.fadeTo(200, 1).show();1202 if (r !== "EOF") {1203 $("." + appender).append(r);1204 btn.attr('data-rotation', parseInt(rotation) + 1);1205 init();1206 } else {1207 $('.btn-more').hide();1208 }1209 },1210 function(r) {1211 dm.fadeTo(250, 0).hide();1212 btn.fadeTo(200, 1).show().addClass('disabled');1213 });1214 1215 1216}1217function Search() {1218 1219 $('.Items-Section-A').empty().append('<div id="preloader"><div id="status"> </div></div>');1220 jPak({ tsk: 'srh', frmName: 'frmX', ctrl: 'AuthPopups', returnAction: 'noReturn', showMsg: 'false', func: function (r) {1221 $('.Items-Section-A').empty().append(r); $('.more-btn-div').hide();1222 }1223 });1224}1225function OpnOrdPrc(trnId, spnid, oid) {1226 var spn = $("." + spnid);1227 swal({1228 title: "Transaction Confirmation!",1229 text: "Please provide the Paypal Transaction Id:",1230 type: "input",1231 showCancelButton: true,1232 closeOnConfirm: false,1233 inputPlaceholder: "Paypal Transaction Id"1234 },1235 function (inputValue) {1236 if (inputValue === false) return false;1237 if (inputValue === "") {1238 swal.showInputError("Please provide the Paypal Transaction Id");1239 return false;1240 }1241 if (inputValue === trnId) {1242 swal({1243 title: "Form Processing",1244 text: "Do you want to process you request?",1245 type: "info",1246 confirmButtonClass: "btn-danger",1247 confirmButtonText: "Yes, process it!",1248 cancelButtonText: "No, cancel plx!",1249 showCancelButton: true,1250 closeOnConfirm: false,1251 showLoaderOnConfirm: true1252 },1253 function (isConfirm) {1254 if (isConfirm) {1255 var fileData = new FormData();1256 fileData.append('id', oid);1257 GeneralAjax("/AuthOrders/OrderProcessing",1258 "POST",1259 fileData,1260 function (r) { if (r === "Done") { spn.empty().text("Completed"); swal("Process Completed"); } else { swal("Error", "There was an error, Request could not be completed." + r, "error"); } },1261 function (r) { swal("Error", "There was an error, Request could not be completed.", "error") });1262 1263 } else {swal("Cancelled", "Process Canceled!", "error");}1264 }1265 );1266 } else {1267 swal.showInputError("The Transaction Id does not match");1268 return false;1269 }1270 1271 });1272}1273function Popup(picid) {1274 CreatePictureModal("myModal");1275 var modal = document.getElementById("myModal");1276 var img = document.getElementById(picid);1277 var modalImg = document.getElementById("img01");1278 var captionText = document.getElementById("PicModalcaption");1279 modal.style.display = "block";1280 modalImg.src = img.src.replace("_thumb", "");1281 modalImg.style.width = "60%";1282 captionText.innerHTML = img.alt;1283 var span = document.getElementsByClassName("PicModalclose")[0];1284 span.onclick = function () { modal.style.display = "none"; }1285}1286 1287function StockTakeUp(sku, profile) {1288 if (profile === undefined && profile !== "false" && profile!== "true") { profile = true; }1289 if (sku === undefined) {1290 swal({1291 title: "Stock Take Up",1292 text: "Please provide a Product SKU:",1293 type: "input",1294 showCancelButton: true,1295 closeOnConfirm: true,1296 showLoaderOnConfirm: true,1297 inputPlaceholder: "Sku"1298 }, function (inputValue) {1299 if (inputValue === false) return false;1300 if (inputValue === "") { swal.showInputError("Please Provide a valid SKU"); return false; }1301 var fileData = new FormData();1302 fileData.append('sku', inputValue);1303 GeneralAjax("/AuthProducts/GetForm", "POST", fileData, 1304 function (r) {1305 if (r !== "Invalid SKU") {1306 CreateModal("StockTakeUp", "md", "Stock Take Up");1307 $("#StockTakeUp").modal('show');1308 $("#StockTakeUp .modal-body").empty().html(r);1309 } else {1310 swal("Error", "Error :" + r, "error");1311 StockTakeUp();1312 }1313 },1314 function(r) {1315 swal("Error", "Error :" + r, "error");1316 });1317 });1318 } else {1319 CreateModal("StockTakeUp", "md", "Stock Take Up");1320 $("#StockTakeUp").modal('show');1321 LoaderAppend("StockTakeUp .modal-body");1322 var fileData = new FormData();1323 fileData.append('sku', sku);1324 fileData.append('profile', profile);1325 1326 GeneralAjax("/AuthProducts/GetForm", "POST", fileData,1327 function (r) {1328 if (r !== "Invalid SKU" || r !== "Missing Parameter") {1329 var arr = r.split(':');1330 if (arr[0] === "Sorry") {1331 $("#StockTakeUp").modal('hide');1332 swal("Info", r, "warning");1333 } else {1334 $("#StockTakeUp .modal-body").empty().html(r);1335 }1336 } else {1337 swal("Error", "Error :" + r, "error");1338 $("#StockTakeUp").modal('hide');1339 StockTakeUp();1340 }1341 },1342 function (r) {1343 swal("Error", "Error :" + r, "error");1344 StockTakeUp();1345 $("#StockTakeUp").modal('hide');1346 });1347 }1348 1349}1350function ProductStatusChange(btnId, rmobj, shobj) {1351 1352 var btn = $(btnId);1353 swal({1354 title: "Are you sure?",1355 text: "Change the status of this record will alter its display properties",1356 type: "warning",1357 showCancelButton: true,1358 confirmButtonClass: "btn-warning",1359 confirmButtonText: "Yes, Change it!",1360 closeOnConfirm: false,1361 closeOnCancel: false1362 },1363 function (isConfirm) {1364 if (isConfirm) {1365 var fileData = new FormData();1366 var id = btn.attr("data-p-id");1367 var sta = btn.attr("data-p-sta");1368 fileData.append('id', id);1369 fileData.append('sta', sta);1370 $.ajax({1371 url: "/AuthProducts/Status/",1372 method: "POST",1373 contentType: false, // Not to set any content header1374 processData: false, // Not to process data1375 data: fileData,1376 success: function (r) {1377 if (r == "Show") {//'ï®' : 'ï°'1378 $(".js-sta-" + id).css('color', '').text('ï®');1379 btn.attr("data-p-sta", "Show");1380 swal("Enabled!", "Category has been enabled.", "success");1381 if (shobj !== undefined) { $(shobj).Show(); }1382 } else {1383 $(".js-sta-" + id).css('color', '#c0c0c0').text('ï°');1384 btn.attr("data-p-sta", "Hide");1385 swal("Disabled!", "Category has been disabled.", "info");1386 if (rmobj !== undefined) { $(rmobj).hide(); }1387 }1388 },1389 error: function (err) {1390 swal("Error!", "Any error has occured.", "warning");1391 }1392 });1393 } else {1394 swal("Cancelled", "Your safe :)", "error");1395 }1396 });1397}1398//product profile1399function TrashDefualt(transId,successFunction) {1400 if (successFunction === undefined)1401 successFunction= function (result) {1402 if (result === "done") alert('Done');1403 }1404 if (confirm("Are you sure you want to delete?")) {1405 if (window.FormData !== undefined) {1406 var fileData = new FormData();1407 fileData.append('a', transId);1408 $.ajax({1409 url: '/AuthProducts/TrashDefault',1410 type: "POST",1411 contentType: false, // Not to set any content header1412 processData: false, // Not to process data1413 data: fileData,1414 success: successFunction,1415 error: function (err) {alert(err.statusText);}1416 });1417 } else {1418 alert("FormData is not supported.");1419 }1420 }1421}1422function TrashIt(edid, confirm) {1423 if (confirm === undefined) confirm = false;1424 jPak({ ctrl: 'AuthProducts', ctrlAction: 'TrashPic', edid: edid, confirm: 'true', showMsg: 'false', func: function (r) { if (r.status === "done") { $("#tile" + edid).remove(); toastr.success("Image Removed"); } } });1425}1426function FormatPrice(a,b) {1427 var str = "";1428 var prc = a.split(".");1429 var cnt = (prc.length>1?prc[1]:"0");1430 str += prc[0] + ".<span class='cents'>" + wholeNumber(cnt,2) + "</span><span class='vat'>"+b+"</span>";1431 return str;1432}1433function filterArrayR(filterArr, indx, listArr) {1434 if (filterArr.length === 0) return listArr;1435 if (filterArr.length === indx) return listArr;1436 if (indx === undefined) indx = 0;1437 if (listArr === undefined) listArr = arr;1438 var nIndx = indx + 1;1439 var nnIndx = indx + 2;1440 var nnnIndx = nnIndx + 1;1441 narr = new Array(arr.length);1442 //alert(listArr.join('\r\n'));1443 //alert(listArr.join('\r\n') + " [" + filterArr.join('\t') + "][" + filterArr.length + "][" + nnIndx + "][" + indx);1444 for (var j = 0; j < listArr.length; j++) {1445 // 0 0 2 1 0 2+1=31446 // 2 0 4 3 0 4+1=51447 //alert(filterArr[indx] + "-" + listArr[j][nnIndx] + "-" + filterArr[nIndx] + "-" + listArr[j][nnnIndx]);1448 if (filterArr[indx] === listArr[j][nnIndx] && filterArr[nIndx] === listArr[j][nnnIndx]) {1449 var str = listArr[j].join(':');1450 //alert(str);1451 narr[j] = str.split(':');1452 }1453 }1454 narr = narr.filter(function (e) { return e });1455 if (nnIndx <= filterArr.length) filterArrayR(filterArr, nnIndx, narr);1456 return narr;1457}1458function create(pArr, indx) {1459 var rcnt = 0;1460 if (pArr == undefined) pArr = arr;1461 //alert(pArr.join('\r\n'));1462 for (var i = 0; i < pArr.length; i++) {1463 var param = [];1464 for (var j = 2; j < pArr[i].length; j += 2) {1465 var k = j + 1;1466 rcnt = (j + 2) / 2;1467 param.push(pArr[i][j]);1468 param.push(pArr[i][k]);1469 //alert(param.join('\r\n'));1470 if ((indx === undefined ? 2 : indx) <= j) {1471 radioBtn(pArr[i][j], pArr[i][k], rcnt, j, param.join("','"));1472 $('.tab-pane').removeClass("active");1473 $('.identifier').removeClass("active");1474 $('#pic-' + pArr[i][0]).addClass("active");1475 $('#li-' + pArr[i][0]).addClass("active");1476 var tar = pArr[i][1].split('|');1477 $('.product-title').empty().html(tar[1]);1478 var desc = decodeURIComponent(tar[5]);1479 $('.product-description').empty().html(desc);1480 $('.product-qty').empty().html(tar[2]);1481 $('.product-price').empty().html(tar[3]);1482 $('.product-sku').empty().html(tar[0]);1483 $('.product-sold').empty().html(tar[4]);1484 $('.addto-cart').attr("data-img", "img-p-"+pArr[i][0]);1485 $('.addto-cart').attr("data-ref", pArr[i][0]);1486 $('.addto-cart').attr("data-sku", tar[0]);1487 1488 }1489 }1490 }1491}1492function radioBtn(label, labelValue, cnt, idx, param) {1493 if (param === undefined) param = "['" + label + "','" + labelValue + "']";1494 var btn = "";1495 var ncnt = eval(cnt) + 1;1496 var labelV = replaceAll(labelValue, ['_', '-'], [' ', '.']);1497 if ($(".btn-" + labelValue).length !== 0) return btn;1498 btn += "<label class='btn btn-" + labelValue + "'>";1499 btn += "<input type='radio' name='r-" + cnt + "' id='r-" + cnt + "-" + label + "' value='" + labelValue + "' onchange=\"javascript: dis(" + ncnt + ", ['" + param + "']);\">";1500 btn += "<i class='fa fa-square-o fa-2x'></i><i class='fa fa-check-square-o fa-2x'></i><span> " + labelV + "</span>";1501 btn += "<input type='hidden' value='" + label + "' id='l-" + cnt + "'/></label>";1502 $('#div-' + label).append(btn);1503 return btn;1504}1505function replaceAll(str, find, replace) {1506 var t = str;1507 if (t != undefined) {1508 for (var i = 0; i < find.length; i++) {1509 t= t.replace(new RegExp(find[i], 'gi'), replace[i]);1510 }1511 }1512 return t;1513}1514function dis(nxt, filterArr) {1515 for (var i = nxt; i < arr[0].length; i++) {1516 var l = $('#l-' + i).val();1517 $('#div-' + l).empty();1518 }1519 var pnxt = nxt - 1;1520 var lvl = nxt - 2;1521 narr = filterArrayR(filterArr);1522 $('.addto-cart').attr("data-chk", lvl);1523 create(narr, pnxt);1524 d();1525 1526}1527 1528function d() {1529 var btn = $('.addto-cart');1530 if (btn.attr("data-chk") === "0") return false;1531 var productId = eval(btn.attr('data-ref'));1532 var quantity = eval($('#cQty').val());1533 if (JSON.stringify(json).toString() === "[{}]") { return false; }1534 //$('.vote').empty().append(JSON.stringify(json));1535 var a = $(json).filter(function (i, n) {return n.Prdid === productId;});1536 $('.ets-pro').empty().html(a[0].Data);1537 var mxDisPer = 0.0; var dislst = "";1538 var mxInd = 0;1539 var mx = 0;1540 if (a.length === 1 && a[0].Discount !== 0) {1541 var lst = $(a[0].Lst).filter(function (i, n) { return quantity >= n.Qty; });1542 var vl = a[0].Lst;1543 for (var i = 0; i < vl.length; i++) { dislst += "<tr><td>" + vl[i].Qty + "</td><td>" + toPrice(vl[i].Up) + "</td><td>" + vl[i].DPer + "</td></tr>"; }1544 if (lst.length !== 0) {1545 for (var i = 0; i < lst.length; i++) {1546 if (mx < lst[i].Qty) { max = lst[i].Qty; mxInd = i; }1547 if (mxDisPer < lst[i].DPer) { mxDisPer = lst[i].DPer; }1548 }1549 //$('.vote').append(JSON.stringify(lst[mxInd]));1550 //$('.vote').empty().append(mxDisPer + "%");1551 $('#tbdy').empty().append(dislst);1552 $('#nprc').show();1553 btn.attr("data-did", lst[mxInd].Did);1554 btn.attr("data-typ", 1);1555 $('#per').empty().append(" -" + lst[mxInd].DPer + "%");1556 $('#npr').empty().append(toPrice(lst[mxInd].Up));1557 $('#prc').addClass('line');1558 return lst[mxInd];1559 } else {1560 //$('.vote').empty().append("none");1561 $('#nprc').hide();1562 $('#per').empty();1563 $('#npr').empty().append(0);1564 $('#prc').removeClass('line');1565 btn.attr("data-did", 0);1566 btn.attr("data-typ", 0);1567 return false;1568 }1569 } else {1570 //$('.vote').empty().append("none1");1571 $('#nprc').hide();1572 $('#per').empty();1573 $('#npr').empty().append(0);1574 $('#prc').removeClass('line');1575 btn.attr("data-did", 0);1576 btn.attr("data-typ", 0);1577 return false;1578 }1579 return false;1580}1581function CheckPasswordStrength(password,msgDivId) {1582 var password_strength = document.getElementById(msgDivId);1583 //TextBox left blank.1584 if (password.length === 0) {1585 password_strength.innerHTML = "";1586 return;1587 }1588 //Regular Expressions.1589 var regex = new Array();1590 regex.push("[A-Z]"); //Uppercase Alphabet.1591 regex.push("[a-z]"); //Lowercase Alphabet.1592 regex.push("[0-9]"); //Digit.1593 regex.push("[$@$!%*#?&]"); //Special Character.1594 var passed = 0;1595 //Validate for each Regular Expression.1596 for (var i = 0; i < regex.length; i++) {1597 if (new RegExp(regex[i]).test(password)) {1598 passed++;1599 }1600 }1601 //Validate for length of Password.1602 if (passed > 2 && password.length > 8) {1603 passed++;1604 }1605 //Display status.1606 var color = "";1607 var strength = "";1608 switch (passed) {1609 case 0:1610 case 1:1611 strength = "Weak";1612 color = "red";1613 break;1614 case 2:1615 strength = "Good";1616 color = "darkorange";1617 break;1618 case 3:1619 case 4:1620 strength = "Strong";1621 color = "green";1622 break;1623 case 5:1624 strength = "Very Strong";1625 color = "darkgreen";1626 break;1627 }1628 password_strength.innerHTML = strength;1629 password_strength.style.color = color;1630}1631function OpnTab(evt, divId) {1632 // Declare all variables1633 var i, tabcontent, tablinks;1634 alert(evt.currentTarget.className);1635 // Get all elements with class="tabcontent" and hide them1636 tabcontent = document.getElementsByClassName("tabcontent");1637 for (i = 0; i < tabcontent.length; i++) {1638 tabcontent[i].style.display = "none";1639 }1640 // Get all elements with class="tablinks" and remove the class "active"1641 tablinks = document.getElementsByClassName("tablinks");1642 for (i = 0; i < tablinks.length; i++) {1643 tablinks[i].className = tablinks[i].className.replace(" active", "");1644 }1645 // Show the current tab, and add an "active" class to the link that opened the tab1646 document.getElementById(divId).style.display = "block";1647 evt.currentTarget.className += " active";1648}1649//################################################################################1650// Cart stuff1651//################################################################################1652function Popup() {1653 GetSect('Prd', 'Popup-0', 0, 'Free Gift List', 'popup2', 'Cart');1654}1655function apply(a) {1656 FrmSubmit("/Cart/ApplyCoupon", a, function (r) {1657 var arr = r.split(':'); $('#rmg').empty().html(arr[2]);1658 if (arr[0] === "info") toastr.info(arr[2]); if (arr[0] === "error") toastr.error(arr[2]); if (arr[0] === "warning") toastr.warning(arr[2]); if (arr[0] === "success") toastr.success(arr[2]);1659 });1660}1661function GetCartData() {1662 $('.coupon').hide();1663 $("#cartitems").empty()1664 .append("<tr><td colspan='6' id='Loader' style='text-align:center;background-color:#fff;'></td></tr>");1665 LoaderAppend("Loader");1666 ProgressAppend('Loader');1667 GeneralAjax('/Cart/Get/',1668 'POST',1669 new FormData(),1670 function (result) {1671 if (result === "No Items") {1672 NoRecords();1673 } else {1674 $("#thd").show();1675 $("#cartitems").empty().html(result);1676 $('.js-out-cart').show();1677 $('#btnArea').show();1678 $('.coupon').show();1679 }1680 },1681 function (err) { alert(err.statusText); });1682}1683function singleDel(btnObj) {1684 var btn = $(btnObj);1685 swal({1686 title: "Are you sure?",1687 text: "This item will be removed from the Cart.!",1688 type: "warning",1689 showCancelButton: true,1690 confirmButtonClass: "btn-warning",1691 confirmButtonText: "Yes, remove it!",1692 closeOnConfirm: false,1693 showLoaderOnConfirm: true1694 },1695 function () {1696 var fileData = new FormData();1697 fileData.append('sku', btn.attr("data-sku"));1698 $.ajax({1699 url: "/Cart/RemoveItmFrmCart/",1700 type: "POST",1701 contentType: false,1702 processData: false,1703 data: fileData,1704 success: function (r) {1705 var arr = r.split(':');1706 if (arr[0] === "Error") {1707 window.location.href = '/Cart/';1708 } else if (arr[0] === "Done" && arr[1] === "0") {1709 NoRecords();1710 swal({1711 title: "The Cart is Empty!",1712 text: "Do you want to continoue shopping?",1713 type: "info",1714 showCancelButton: true,1715 confirmButtonClass: "btn-info",1716 confirmButtonText: "Yes",1717 closeOnConfirm: false1718 },1719 function () {1720 window.location.href = '/Home';1721 });1722 } else {1723 GetCartData();1724 swal("Success!", "Item removed.!", "success");1725 }1726 },1727 error: function (err) {1728 swal("Error!", err.statusText);1729 }1730 });1731 });1732}1733function SingleSave(sku, qty, divId, num) {1734 var f = new FormData();1735 f.append("sku", sku);1736 f.append("qty", $('#' + qty).val());1737 GeneralAjax2("/Cart/AddQtyFrmCart",1738 f,1739 function (r) {1740 var data = r;1741 var arr = data.split(':');1742 if (arr[0] === "Done") {1743 //$('#netshipping').empty().text(arr[1]);1744 //$('#hdnetshipping').val(arr[2]);1745 //$('#handlingfee').empty().text(arr[3]);1746 //$('#discountdetail-' + num).empty().text((arr[4] === "-" ? "" : arr[4]));1747 //$('#discountprice-' + num).empty().text(arr[5]);1748 //$('#distype-' + num).val(arr[6]);1749 //if ($('#distype-' + num).val() !== "0") {1750 // $('#div-discountprice-' + num).show();1751 // $('#div-price-' + num).css('text-decoration', 'line-through');1752 //} else {1753 // $('#div-discountprice-' + num).hide();1754 // $('#div-price-' + num).css('text-decoration', 'none');1755 //}1756 //var n = $('#js-num' + num).val();1757 //var o = $('#oldQty-' + num).val(n);1758 //$("#itemCount").empty().html(arr[1]);1759 //SingleSaveBtnStyle(num);1760 //calc(num);1761 GetCartData();1762 }1763 });1764}1765function SndOrdbyMail() {1766 swal({1767 title: "Email This Order!",1768 text: "Please provide a valid Email Address",1769 type: "input",1770 showCancelButton: true,1771 closeOnConfirm: false,1772 imageUrl: '/Content/img/Layout/Loading11.gif',1773 inputPlaceholder: "Email address"1774 },1775 function (inputValue) {1776 if (inputValue === false) return false;1777 if (inputValue === "") {1778 swal.showInputError("Email Address is required here");1779 return false;1780 }1781 if (isEmail(inputValue)) {1782 swal({1783 title: "Sending Mail!",1784 text: "Your mail is on it way.",1785 imageUrl: '/Content/img/Layout/sendMail.gif'1786 });1787 } else {1788 swal.showInputError("Email Address is required here");1789 return false;1790 }1791 });1792}1793function calc(num) {1794 var total = new Array(0.0, 0.0, 0.0, 0.0, 0.0, 0.0);1795 for (var i = 1; i <= num; i++) {1796 var arr = Subcalc(i);1797 total[0] += eval(arr.gTotal);1798 total[1] += eval(arr.sumQty);1799 total[2] += eval(arr.sumWeight);1800 total[3] += eval(arr.sumVolume);1801 total[4] += eval(arr.calcP);1802 total[5] += eval(arr.calcV);1803 }1804 $('#sumQty').empty().text(wholeNumber(total[1], 4));1805 $('#sumWeight').empty().text(total[2]);1806 $('#sumVolume').empty().text(total[3].toFixed(2));1807 $('#netshipping').empty().text($('#hdnetshipping').val());1808 var handling = eval($('#handlingfee').text());1809 var netshipping = $('#netshipping').text();1810 $('#vatsum').empty().text(total[5].toFixed(2));1811 total[0] += eval(netshipping