From a5c5ea9c5b416af720b9d8fa5076484413b2b3df Mon Sep 17 00:00:00 2001 From: David Worms Date: Sun, 10 Jul 2022 22:31:57 +0200 Subject: [PATCH] test(csv-ts-demo-node16): demo assiated with PR #341 --- demo/ts-module-node16/lib/stringify.ts | 32 ++++++++++++ demo/ts-module-node16/package.json | 31 ++++++++++++ demo/ts-module-node16/test/loaders/all.js | 16 ++++++ demo/ts-module-node16/test/loaders/coffee.js | 20 ++++++++ .../test/loaders/legacy/all.js | 37 ++++++++++++++ .../test/loaders/legacy/coffee.js | 50 +++++++++++++++++++ demo/ts-module-node16/test/samples.coffee | 26 ++++++++++ demo/ts-module-node16/tsconfig.json | 7 +++ 8 files changed, 219 insertions(+) create mode 100644 demo/ts-module-node16/lib/stringify.ts create mode 100644 demo/ts-module-node16/package.json create mode 100644 demo/ts-module-node16/test/loaders/all.js create mode 100644 demo/ts-module-node16/test/loaders/coffee.js create mode 100644 demo/ts-module-node16/test/loaders/legacy/all.js create mode 100644 demo/ts-module-node16/test/loaders/legacy/coffee.js create mode 100644 demo/ts-module-node16/test/samples.coffee create mode 100644 demo/ts-module-node16/tsconfig.json diff --git a/demo/ts-module-node16/lib/stringify.ts b/demo/ts-module-node16/lib/stringify.ts new file mode 100644 index 000000000..f4cf1db94 --- /dev/null +++ b/demo/ts-module-node16/lib/stringify.ts @@ -0,0 +1,32 @@ + +import assert from 'assert' +import { stringify, Stringifier } from 'csv-stringify'; + +let output: string = ''; +// Create the parser +const stringifier: Stringifier = stringify({ + delimiter: ':', + encoding: 'utf8' +}); +// Use the readable stream api to consume records +stringifier.on('readable', function(){ + let record; while ((record = stringifier.read()) !== null) { + output += record + } +}); +// Catch any error +stringifier.on('error', function(err){ + console.error(err.message) +}); +// Test that the parsed records matched what's expected +stringifier.on('end', function(){ + assert.deepStrictEqual( + output, + 'a:b:c\n1:2:3\n' + ) +}); +// Write data to the stream +stringifier.write(["a", "b", "c"]); +stringifier.write([1, 2, 3]); +// Close the readable stream +stringifier.end(); diff --git a/demo/ts-module-node16/package.json b/demo/ts-module-node16/package.json new file mode 100644 index 000000000..96edaddca --- /dev/null +++ b/demo/ts-module-node16/package.json @@ -0,0 +1,31 @@ +{ + "name": "csv-ts-demo-node16", + "version": "0.0.0", + "main": "index.js", + "license": "MIT", + "type": "module", + "private": true, + "devDependencies": { + "@types/node": "^18.0.3", + "coffeescript": "^2.7.0", + "mocha": "^10.0.0", + "should": "^13.2.3", + "ts-node": "^10.8.2", + "typescript": "^4.7.4" + }, + "mocha": { + "inline-diffs": true, + "loader": "./test/loaders/all.js", + "recursive": true, + "reporter": "spec", + "require": [ + "should" + ], + "throw-deprecation": true, + "timeout": 40000 + }, + "scripts": { + "test": "mocha 'test/**/*.coffee'", + "test:legacy": "mocha --loader=./test/loaders/legacy/all.js 'test/**/*.{coffee,ts}'" + } +} diff --git a/demo/ts-module-node16/test/loaders/all.js b/demo/ts-module-node16/test/loaders/all.js new file mode 100644 index 000000000..344154640 --- /dev/null +++ b/demo/ts-module-node16/test/loaders/all.js @@ -0,0 +1,16 @@ + +import * as coffee from './coffee.js' +import * as ts from 'ts-node/esm' + +const coffeeRegex = /\.coffee$|\.litcoffee$|\.coffee\.md$/; +const tsRegex = /\.ts$/; + +export function load(url, context, next) { + if (coffeeRegex.test(url)) { + return coffee.load.apply(this, arguments) + } + if (tsRegex.test(url)) { + return ts.load.apply(this, arguments) + } + return next(url, context, next); +} diff --git a/demo/ts-module-node16/test/loaders/coffee.js b/demo/ts-module-node16/test/loaders/coffee.js new file mode 100644 index 000000000..c7b277cb7 --- /dev/null +++ b/demo/ts-module-node16/test/loaders/coffee.js @@ -0,0 +1,20 @@ +import CoffeeScript from 'coffeescript'; + +// See https://github.com/nodejs/node/issues/36396 +const extensionsRegex = /\.coffee$|\.litcoffee$|\.coffee\.md$/; + +export async function load(url, context, next) { + if (extensionsRegex.test(url)) { + const format = 'module'; + const { source: rawSource } = await next(url, { format }); + const source = CoffeeScript.compile(rawSource.toString(), { + bare: true, + inlineMap: true, + filename: url, + header: false, + sourceMap: false, + }); + return {format, source}; + } + return next(url, context); +} diff --git a/demo/ts-module-node16/test/loaders/legacy/all.js b/demo/ts-module-node16/test/loaders/legacy/all.js new file mode 100644 index 000000000..c95db0b56 --- /dev/null +++ b/demo/ts-module-node16/test/loaders/legacy/all.js @@ -0,0 +1,37 @@ + +import * as coffee from './coffee.js' +import * as ts from 'ts-node/esm' + +const coffeeRegex = /\.coffee$|\.litcoffee$|\.coffee\.md$/; +const tsRegex = /\.ts$/; + +export function resolve(specifier, context, defaultResolve) { + if (coffeeRegex.test(specifier)) { + return coffee.resolve.apply(this, arguments) + } + if (tsRegex.test(specifier)) { + return ts.resolve.apply(this, arguments) + } + return ts.resolve.apply(this, arguments); +} + +export function getFormat(url, context, defaultGetFormat) { + if (coffeeRegex.test(url)) { + return coffee.getFormat.apply(this, arguments) + } + if (tsRegex.test(url)) { + return ts.getFormat.apply(this, arguments) + } + return ts.getFormat.apply(this, arguments); +} + +export function transformSource(source, context, defaultTransformSource) { + const { url } = context; + if (coffeeRegex.test(url)) { + return coffee.transformSource.apply(this, arguments) + } + if (tsRegex.test(url)) { + return ts.transformSource.apply(this, arguments) + } + return ts.transformSource.apply(this, arguments); +} diff --git a/demo/ts-module-node16/test/loaders/legacy/coffee.js b/demo/ts-module-node16/test/loaders/legacy/coffee.js new file mode 100644 index 000000000..f4945adb7 --- /dev/null +++ b/demo/ts-module-node16/test/loaders/legacy/coffee.js @@ -0,0 +1,50 @@ +// coffeescript-loader.mjs +import { URL, pathToFileURL } from 'url'; +import CoffeeScript from 'coffeescript'; +import { cwd } from 'process'; + +const baseURL = pathToFileURL(`${cwd()}/`).href; + +// CoffeeScript files end in .coffee, .litcoffee or .coffee.md. +const extensionsRegex = /\.coffee$|\.litcoffee$|\.coffee\.md$/; + +export function resolve(specifier, context, defaultResolve) { + const { parentURL = baseURL } = context; + // Node.js normally errors on unknown file extensions, so return a URL for + // specifiers ending in the CoffeeScript file extensions. + if (extensionsRegex.test(specifier)) { + return { + url: new URL(specifier, parentURL).href, + stop: true + }; + } + // Let Node.js handle all other specifiers. + return defaultResolve(specifier, context, defaultResolve); +} + +export function getFormat(url, context, defaultGetFormat) { + // Now that we patched resolve to let CoffeeScript URLs through, we need to + // tell Node.js what format such URLs should be interpreted as. For the + // purposes of this loader, all CoffeeScript URLs are ES modules. + if (extensionsRegex.test(url)) { + return { + format: 'module', + stop: true + }; + } + // Let Node.js handle all other URLs. + return defaultGetFormat(url, context, defaultGetFormat); +} + +export function transformSource(source, context, defaultTransformSource) { + const { url, format } = context; + + if (extensionsRegex.test(url)) { + return { + source: CoffeeScript.compile(String(source), { bare: true }) + }; + } + + // Let Node.js handle all other sources. + return defaultTransformSource(source, context, defaultTransformSource); +} diff --git a/demo/ts-module-node16/test/samples.coffee b/demo/ts-module-node16/test/samples.coffee new file mode 100644 index 000000000..0a2b28d54 --- /dev/null +++ b/demo/ts-module-node16/test/samples.coffee @@ -0,0 +1,26 @@ + +import fs from 'fs' +import path from 'path' +import { exec } from 'child_process' + +import { fileURLToPath } from 'url' +__dirname = path.dirname fileURLToPath import.meta.url +dir = path.resolve __dirname, '../lib' +samples = fs.readdirSync dir + +describe 'Samples', -> + + samples + .filter (sample) -> + return false unless /\.(js|ts)?$/.test sample + true + .map (sample) -> + it "Sample #{sample}", (callback) -> + ext = /\.(\w+)?$/.exec(sample)[0] + bin = switch ext + when '.js' + 'node' + when '.ts' + 'node --loader ts-node/esm' + exec "#{bin} #{path.resolve dir, sample}", (err, stdout, stderr) -> + callback err diff --git a/demo/ts-module-node16/tsconfig.json b/demo/ts-module-node16/tsconfig.json new file mode 100644 index 000000000..b7a38adc0 --- /dev/null +++ b/demo/ts-module-node16/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "esModuleInterop": true, + "module": "Node16", + "strict": true, + } +}