
Research
/Security News
DuckDB npm Account Compromised in Continuing Supply Chain Attack
Ongoing npm supply chain attack spreads to DuckDB: multiple packages compromised with the same wallet-drainer malware.
write I/O agnostic utilities
adapter
is a tiny TypeScript helper for writing I/O agnostic utilities in a standardized way. Your code could run in a headless process, an interactive commandline tool, or in a graphical program, but either way your code remains the same.
The idea is difficult to appreciate without an example. If you're comfortable with writing your own Promises and async
/await
patterns, the following example should be fairly intuitive.
Let's say that you have some code that creates a remote repository via the GitHub API. It might look roughly like this:
import axios from 'axios'; // http library
const url = 'https://api.github.com/user/repos';
const headers = { Authorization: 'token <access-token>' };
const data = { name: '<repo-name>', private: true };
await axios.post(url, data, {headers});
adapter
can be used to improve this code by injecting (or "plugging in") the means of handling I/O (input
/output
), just as Promises inject the means of handling success/failure (resolve
/reject
). Let's rewrite the above code leveraging these injections:
// github-service.ts
import axios, {AxiosResponse} from 'axios';
import {makeAdapter} from 'adapter';
type Resolve = AxiosResponse;
type Input = {
types: { 'text': string, 'yes-no': boolean },
options: {
[type: string]: { message: string }
},
keys: {
'access-token': 'text',
'repo-name': 'text',
'private': 'yes-no',
'retry': 'yes-no',
}
};
type Output = string;
export const createRepo = () => makeAdapter<Resolve, Input, Output>(
async (input, output) => {
const url = 'https://api.github.com/user/repos';
const headers = {
Authorization: 'token ' + await input(
'access-token', 'text', {message: 'Personal Access Token: '}
)
};
const data = {
name: await input(
'repo-name', 'text', {message: 'Repository Name: '}
),
private: await input(
'private', 'yes-no', {message: 'Private?: '}
)
};
output('Making API call to GitHub...');
let response;
try {
response = await axios.post(url, data, {headers});
} catch (e) {
output('Something went wrong... Status code: ' + e.response.status);
if (await input('retry', 'yes-no', {message: 'Would you like to try again? '})) {
return await createRepo().attach({input, output});
} else {
throw e;
}
}
output('Repository created!');
return response;
}
);
Now that our input and output functions are injected, we can use this service anywhere. Say we want to use it as part of a CLI application:
// cli-app.ts
import {prompt} from 'inquirer'; // inquirer is tool for getting cli input
import {createRepo} from './github-service';
const then = console.info;
const output = console.log;
const input = async (type, key, options) => {
if (type === 'text') type = 'input';
if (type === 'yes-no') type = 'confirm';
return await prompt([{
name: key,
type: type,
message: options.message
}]);
};
createRepo() // calling our service gives us an `Adapter`
.attach({then, output, input}) // here we "plug in" our attachments
.exec(); // and this executes our code
We could also utilize the same service in a web application:
// browser-app.ts
import service from './service';
service() // you can also attach handlers independently,
.then(console.info) // like so:
.catch(console.error)
.output(console.log)
.input(async (type, key, options) => {
if (type === 'yes-no') {
const yn = window.prompt(options.message + '(Y/n)');
return yn === 'y';
} else {
return window.prompt(options.message);
}
})
.exec();
Hopefully seeing these two applications side by side illustrates the advantages of using adapter
.
npm install adapter
or
yarn add adapter
More complete documentation is coming soon!
Tanner Nielsen tannerntannern@gmail.com
FAQs
A TypeScript utility for writing I/O agnostic programs
We found that adapter demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
/Security News
Ongoing npm supply chain attack spreads to DuckDB: multiple packages compromised with the same wallet-drainer malware.
Security News
The MCP Steering Committee has launched the official MCP Registry in preview, a central hub for discovering and publishing MCP servers.
Product
Socket’s new Pull Request Stories give security teams clear visibility into dependency risks and outcomes across scanned pull requests.