Skip to content

Commit

Permalink
Upgrade to using ESM
Browse files Browse the repository at this point in the history
  • Loading branch information
Brad-Turner committed Oct 22, 2023
1 parent b141aec commit 6f23f0c
Show file tree
Hide file tree
Showing 12 changed files with 2,282 additions and 1,138 deletions.
5 changes: 5 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"]
}
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
node_modules/
lib/
docs/
docs/
dist/
.vscode/
3 changes: 1 addition & 2 deletions .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@
"printWidth": 120,
"jsxSingleQuote": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "none"
"tabWidth": 2
}
3,265 changes: 2,205 additions & 1,060 deletions package-lock.json

Large diffs are not rendered by default.

32 changes: 16 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
{
"name": "swtc",
"type": "module",
"version": "1.2.0",
"description": "Framework to start supplied Docker containers before running a script",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"bin": {
"swtc": "lib/bin/index.js"
"swtc": "dist/bin/index.mjs"
},
"files": [
"lib"
"dist"
],
"scripts": {
"build": "tsc",
"clean": "rimraf lib docs",
"clean": "rimraf dist docs",
"docs": "typedoc"
},
"repository": {
Expand All @@ -33,19 +34,18 @@
"homepage": "https://github.com/Brad-Turner/start-with-containers#readme",
"devDependencies": {
"@types/node": "^17.0.21",
"@typescript-eslint/eslint-plugin": "^5.13.0",
"@typescript-eslint/parser": "^5.13.0",
"@typescript-eslint/eslint-plugin": "^6.8.0",
"@typescript-eslint/parser": "^6.8.0",
"eslint": "^8.10.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.0.0",
"prettier": "^2.5.1",
"rimraf": "^3.0.2",
"typedoc": "^0.22.14",
"typescript": "^4.5.5"
"eslint-config-prettier": "^9.0.0",
"prettier": "^3.0.3",
"rimraf": "^5.0.5",
"typedoc": "^0.25.2",
"typescript": "^5.2.2"
},
"dependencies": {
"commander": "^9.1.0",
"testcontainers": "^8.4.0",
"ts-node": "^10.7.0"
"commander": "^11.1.0",
"testcontainers": "^10.2.1",
"ts-node": "^10.9.1"
}
}
21 changes: 21 additions & 0 deletions src/bin/index.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env -S node --loader ts-node/esm

import { Command } from 'commander';
import { fileURLToPath } from 'node:url';
import { startWithTestContainers } from '../index.js';

const packageJsonPath = fileURLToPath(new URL('../../package.json', import.meta.url));
const { default: packageJson } = await import(`file://${packageJsonPath}`, { assert: { type: 'json' } });
const program = new Command();

program
.name('swtc')
.description(
'CLI to start a node process with specified Docker containers. Refer to https://github.com/Brad-Turner/swtc for more information.',
)
.version(packageJson.version)
.option('-p, --project <path>', 'Specifies the path to the swtc entypoint file', 'swtc.ts');

program.parse(process.argv);

await startWithTestContainers(program.opts());
20 changes: 0 additions & 20 deletions src/bin/index.ts

This file was deleted.

4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { StartedTestContainer } from 'testcontainers';
export { ContainerDefinition, OnStartHook, SwtcFile, SwtcSettings } from './types';
export { ContainerDefinition, OnStartHook, SwtcFile, SwtcSettings } from './types/index.js';

export { startWithTestContainers } from './swtc';
export { startWithTestContainers } from './swtc.js';
29 changes: 13 additions & 16 deletions src/swtc.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,31 @@
import { GenericContainer } from 'testcontainers';
import { ContainerDefinition, SwtcSettings, SwtcFile } from './types';
import { loadFile, onShutdown, resolveStringToPath } from './util';
import { ContainerDefinition, SwtcSettings, SwtcFile } from './types/index.js';
import { loadFile, onShutdown } from './util.js';
import { pathToFileURL } from 'node:url';

function mapDefinitionToContainer(def: ContainerDefinition): GenericContainer {
const container = new GenericContainer(def.image).withExposedPorts(...def.ports);

if (def.name) container.withName(def.name);
if (def.env) {
Object.entries(def.env).forEach(([key, value]) => container.withEnv(key, value));
}
if (Array.isArray(def.withCommand)) {
container.withCmd(def.withCommand);
}
if (def.env) container.withEnvironment(def.env);
if (Array.isArray(def.withCommand)) container.withCommand(def.withCommand);

const ref = container.start;
container.start = async function () {
const instance = await ref.apply(this);
// const ref = container.start;
// container.start = async function () {
// const instance = await ref.apply(this);

if (def.onStart) def.onStart(instance);
return instance;
};
// if (def.onStart) await def.onStart(instance);
// return instance;
// };

return container;
}

export async function startWithTestContainers(settings: SwtcSettings = {}): Promise<void> {
const swtcPath = resolveStringToPath(settings.project, 'swtc.ts');
const swtcPath = pathToFileURL(settings.project ?? './swtc.ts');
const swtc = await loadFile<SwtcFile>(swtcPath);

const containers = swtc?.containers.map(mapDefinitionToContainer) ?? [];
const containers = swtc?.containers.map((def) => mapDefinitionToContainer(def)) ?? [];

console.log('Starting containers...');

Expand Down
2 changes: 1 addition & 1 deletion src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { StartedTestContainer } from 'testcontainers';

export type OnStartHook = (container: StartedTestContainer) => void;
export type OnStartHook = (container: StartedTestContainer) => Promise<void>;

export interface ContainerDefinition {
image: string;
Expand Down
15 changes: 5 additions & 10 deletions src/util.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { EventEmitter } from 'events';
import { constants, PathLike, promises as fs } from 'fs';
import { isAbsolute, resolve } from 'path';
import { constants, promises as fs } from 'fs';
import { URL } from 'node:url';

export function onShutdown(handle: (signal?: string) => Promise<void> | void) {
const events = ['beforeExit', 'SIGINT', 'SIGTERM', 'SIGHUP', 'SIGBREAK'];
Expand All @@ -9,17 +9,12 @@ export function onShutdown(handle: (signal?: string) => Promise<void> | void) {
events.forEach((signal) => process.on(signal, (code) => shutdownEmitter.emit('shutdown', code)));
}

export function resolveStringToPath(path: string | undefined, defaultPath: string): PathLike {
if (!path) path = defaultPath;

return isAbsolute(path) ? path : resolve(process.cwd(), path);
}

export async function loadFile<T>(path: PathLike): Promise<T | undefined> {
export async function loadFile<T>(path: URL): Promise<T | undefined> {
try {
await fs.access(path, constants.F_OK);
const esmPath = path.toString().replace(/\.(c|m)?ts$/, '.$1js');

const file: T = await import(path.toString());
const file: T = await import(esmPath.toString());

// validate here
return file;
Expand Down
20 changes: 10 additions & 10 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */

/* Language and Environment */
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
"target": "es2022" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
Expand All @@ -24,16 +24,16 @@
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */

/* Modules */
"module": "commonjs", /* Specify what module code is generated. */
"module": "node16" /* Specify what module code is generated. */,
// "rootDir": "./", /* Specify the root folder within your source files. */
"moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
"moduleResolution": "node16" /* Specify how TypeScript looks up a file from a given module specifier. */,
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "resolveJsonModule": true, /* Enable importing .json files */
"resolveJsonModule": true /* Enable importing .json files */,
// "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */

/* JavaScript Support */
Expand All @@ -42,12 +42,12 @@
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */

/* Emit */
"declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
"declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */,
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
"outDir": "./lib", /* Specify an output folder for all emitted files. */
"outDir": "./dist" /* Specify an output folder for all emitted files. */,
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
Expand All @@ -69,12 +69,12 @@
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */,
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,

/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
"strict": true /* Enable all strict type-checking options. */,
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
// "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
Expand All @@ -96,7 +96,7 @@

/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
},

"typedocOptions": {
Expand Down

0 comments on commit 6f23f0c

Please sign in to comment.