@lynx-js/qrcode-rsbuild-plugin
Version:
A rsbuild plugin for printing QRCode in terminal
133 lines (132 loc) • 5.45 kB
JavaScript
function generateDevUrls(api, entry, schemaFn, port) {
const { dev: { assetPrefix } } = api.getNormalizedConfig();
const { config } = api.useExposed(Symbol.for('rspeedy.api'));
if ('string' != typeof assetPrefix) {
const errorMsg = 'dev.assetPrefix is not string, skip printing QRCode';
throw new Error(errorMsg);
}
const defaultFilename = '[name].[platform].bundle';
const { filename } = config.output ?? {};
const bundle = 'object' == typeof filename ? filename.bundle ?? filename.template : filename;
const name = ('function' == typeof bundle ? bundle({
lazyBundle: false,
entryName: entry,
platform: 'lynx'
}) : bundle) ?? defaultFilename;
const customSchema = schemaFn(new URL(name.replace('[name]', entry).replace('[platform]', 'lynx'), assetPrefix.replaceAll('<port>', String(port))).toString());
return 'string' == typeof customSchema ? {
default: customSchema
} : customSchema;
}
const gExistingShortcuts = new WeakSet();
async function registerConsoleShortcuts(options) {
if (!(process.stdin.isTTY && process.stdout.isTTY)) {
await printNonTTY(options);
return ()=>{};
}
const [{ default: showQRCode }] = await Promise.all([
import("./showQRCode.js").then((m)=>m.showQRCode_namespaceObject)
]);
const shouldShowQRCode = options.showQRCode ?? true;
const currentEntry = options.entries[0];
const devUrls = generateDevUrls(options.api, currentEntry, options.schema, options.port);
const value = Object.values(devUrls)[0];
await options.onPrint?.(value);
if (shouldShowQRCode) showQRCode(value);
gExistingShortcuts.add(options);
loop(options, value, devUrls);
function off() {
gExistingShortcuts.delete(options);
}
return off;
}
async function printNonTTY(options) {
const lines = [];
const urls = [];
for (const entry of options.entries){
const devUrls = generateDevUrls(options.api, entry, options.schema, options.port);
lines.push(entry);
for (const [schemaName, url] of Object.entries(devUrls)){
lines.push(` ${schemaName}: ${url}`);
urls.push(url);
}
}
process.stdout.write(lines.join('\n') + '\n');
for (const url of urls)await options.onPrint?.(url);
}
async function loop(options, value, devUrls) {
const [{ autocomplete, select, selectKey, isCancel, cancel }, { default: showQRCode }] = await Promise.all([
import("./@clack/prompts.js").then((m)=>m.dist_namespaceObject),
import("./showQRCode.js").then((m)=>m.showQRCode_namespaceObject)
]);
const shouldShowQRCode = options.showQRCode ?? true;
const selectFn = (length)=>length > 5 ? autocomplete : select;
let currentEntry = options.entries[0];
let currentSchema = Object.keys(devUrls)[0];
while(!isCancel(value)){
const name = await selectKey({
message: 'Usage',
options: [
{
value: 'r',
label: 'Switch entries'
},
{
value: 'a',
label: 'Switch schema'
},
{
value: 'h',
label: 'Help'
},
...Object.values(options.customShortcuts ?? {}),
{
value: 'q',
label: 'Quit'
}
],
initialValue: 'q'
});
if (isCancel(name) || 'q' === name || !gExistingShortcuts.has(options)) break;
if ('r' === name) {
const selection = await selectFn(options.entries.length)({
message: 'Select entry',
options: options.entries.map((entry)=>({
value: entry,
label: entry,
hint: generateDevUrls(options.api, entry, options.schema, options.port)[currentSchema]
})),
initialValue: currentEntry
});
if (isCancel(selection)) break;
currentEntry = selection;
value = getCurrentUrl();
} else if ('a' === name) {
const devUrls = generateDevUrls(options.api, currentEntry, options.schema, options.port);
const selection = await selectFn(Object.keys(devUrls).length)({
message: 'Select schema',
options: Object.entries(devUrls).map(([name, url])=>({
value: name,
label: name,
hint: url
})),
initialValue: currentSchema
});
if (isCancel(selection)) break;
currentSchema = selection;
value = getCurrentUrl();
} else if (options.customShortcuts?.[name]) await options.customShortcuts[name].action?.();
await options.onPrint?.(value);
if (shouldShowQRCode) showQRCode(value);
}
if (gExistingShortcuts.has(options)) await exit(1);
function getCurrentUrl() {
return generateDevUrls(options.api, currentEntry, options.schema, options.port)[currentSchema];
}
function exit(code) {
cancel('exiting...');
const { exit } = options.api.useExposed(Symbol.for('rspeedy.api'));
return exit(code);
}
}
export { registerConsoleShortcuts };