mirror of
https://github.com/sern-handler/cli
synced 2026-06-06 01:16:53 +00:00
chore: for the statistics only
permalink: http://whatthecommit.com/f6cb5f952917639c9e28f94ae495bd59
This commit is contained in:
@@ -1,68 +1,66 @@
|
||||
import esbuild from 'esbuild'
|
||||
import { getConfig } from '../utilities/getConfig'
|
||||
import { resolve } from 'node:path'
|
||||
import { glob } from 'glob'
|
||||
import { configDotenv } from 'dotenv'
|
||||
import assert from 'node:assert'
|
||||
import { imageLoader, validExtensions } from '../plugins/imageLoader'
|
||||
import defaultEsbuild from '../utilities/defaultEsbuildConfig'
|
||||
import { require } from '../utilities/require'
|
||||
import { pathExists, pathExistsSync } from 'find-up'
|
||||
import { mkdir, writeFile } from 'fs/promises'
|
||||
import * as Preprocessor from '../utilities/preprocessor'
|
||||
import { bold, magentaBright } from 'colorette'
|
||||
import esbuild from 'esbuild';
|
||||
import { getConfig } from '../utilities/getConfig';
|
||||
import { resolve } from 'node:path';
|
||||
import { glob } from 'glob';
|
||||
import { configDotenv } from 'dotenv';
|
||||
import assert from 'node:assert';
|
||||
import { imageLoader, validExtensions } from '../plugins/imageLoader';
|
||||
import defaultEsbuild from '../utilities/defaultEsbuildConfig';
|
||||
import { require } from '../utilities/require';
|
||||
import { pathExists, pathExistsSync } from 'find-up';
|
||||
import { mkdir, writeFile } from 'fs/promises';
|
||||
import * as Preprocessor from '../utilities/preprocessor';
|
||||
import { bold, magentaBright } from 'colorette';
|
||||
|
||||
type BuildOptions = {
|
||||
/**
|
||||
* Define __VERSION__
|
||||
* This option is a quick switch to defining the __VERSION__ constant which will be a string of the version provided in
|
||||
* cwd's package.json
|
||||
*/
|
||||
defineVersion?: boolean
|
||||
* Define __VERSION__
|
||||
* This option is a quick switch to defining the __VERSION__ constant which will be a string of the version provided in
|
||||
* cwd's package.json
|
||||
*/
|
||||
defineVersion?: boolean;
|
||||
/**
|
||||
* default = esm
|
||||
*/
|
||||
format?: 'cjs' | 'esm'
|
||||
/**
|
||||
* extra esbuild plugins to build with sern.
|
||||
*/
|
||||
esbuildPlugins?: esbuild.Plugin[]
|
||||
* default = esm
|
||||
*/
|
||||
format?: 'cjs' | 'esm';
|
||||
/**
|
||||
* extra esbuild plugins to build with sern.
|
||||
*/
|
||||
esbuildPlugins?: esbuild.Plugin[];
|
||||
/**
|
||||
* https://esbuild.github.io/api/#drop-labels
|
||||
**/
|
||||
dropLabels?: string[]
|
||||
dropLabels?: string[];
|
||||
/**
|
||||
* https://esbuild.github.io/api/#define
|
||||
**/
|
||||
define?: Record<string, string>
|
||||
define?: Record<string, string>;
|
||||
|
||||
tsconfig?: string;
|
||||
/**
|
||||
* default = 'development'
|
||||
*/
|
||||
mode: 'production' | 'development',
|
||||
* default = 'development'
|
||||
*/
|
||||
mode: 'production' | 'development';
|
||||
/**
|
||||
* will search for env file. If none exists,
|
||||
* default to .env.
|
||||
*/
|
||||
env?: string
|
||||
}
|
||||
* will search for env file. If none exists,
|
||||
* default to .env.
|
||||
*/
|
||||
env?: string;
|
||||
};
|
||||
|
||||
|
||||
export async function build(options: Record<string,any>) {
|
||||
if(!options.supressWarnings) {
|
||||
console.info(`${magentaBright('EXPERIMENTAL')}: This API has not been stabilized. add -W or --suppress-warnings flag to suppress`)
|
||||
export async function build(options: Record<string, any>) {
|
||||
if (!options.supressWarnings) {
|
||||
console.info(`${magentaBright('EXPERIMENTAL')}: This API has not been stabilized. add -W or --suppress-warnings flag to suppress`);
|
||||
}
|
||||
const sernConfig = await getConfig()
|
||||
let buildConfig: Partial<BuildOptions> = {};
|
||||
const sernConfig = await getConfig();
|
||||
let buildConfig: Partial<BuildOptions> = {};
|
||||
const entryPoints = await glob(`./src/**/*{${validExtensions.join(',')}}`, {
|
||||
//for some reason, my ignore glob wasn't registering correctly'
|
||||
ignore: {
|
||||
ignored: p => p.name.endsWith('.d.ts')
|
||||
}
|
||||
})
|
||||
const buildConfigPath = resolve(options.project ?? 'sern.build.js')
|
||||
|
||||
//for some reason, my ignore glob wasn't registering correctly'
|
||||
ignore: {
|
||||
ignored: (p) => p.name.endsWith('.d.ts'),
|
||||
},
|
||||
});
|
||||
const buildConfigPath = resolve(options.project ?? 'sern.build.js');
|
||||
|
||||
const defaultBuildConfig = {
|
||||
defineVersion: true,
|
||||
@@ -70,96 +68,94 @@ export async function build(options: Record<string,any>) {
|
||||
mode: options.mode ?? 'development',
|
||||
dropLabels: [],
|
||||
tsconfig: options.tsconfig ?? resolve('tsconfig.json'),
|
||||
|
||||
env: options.env ?? resolve('.env')
|
||||
}
|
||||
if(pathExistsSync(buildConfigPath)) {
|
||||
|
||||
env: options.env ?? resolve('.env'),
|
||||
};
|
||||
if (pathExistsSync(buildConfigPath)) {
|
||||
try {
|
||||
buildConfig = {
|
||||
...defaultBuildConfig,
|
||||
...(await import('file:///'+buildConfigPath)).default,
|
||||
}
|
||||
} catch(e) {
|
||||
console.log(e)
|
||||
process.exit(1)
|
||||
...(await import('file:///' + buildConfigPath)).default,
|
||||
};
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
process.exit(1);
|
||||
}
|
||||
} else {
|
||||
buildConfig = {
|
||||
...defaultBuildConfig
|
||||
}
|
||||
console.log('No build config found, defaulting')
|
||||
...defaultBuildConfig,
|
||||
};
|
||||
console.log('No build config found, defaulting');
|
||||
}
|
||||
let env = {} as Record<string,string>
|
||||
configDotenv({ path: buildConfig.env, processEnv: env })
|
||||
let env = {} as Record<string, string>;
|
||||
configDotenv({ path: buildConfig.env, processEnv: env });
|
||||
|
||||
|
||||
if(env.MODE && !env.NODE_ENV) {
|
||||
if (env.MODE && !env.NODE_ENV) {
|
||||
console.warn('Use NODE_ENV instead of MODE');
|
||||
console.warn('MODE has no effect.')
|
||||
console.warn('MODE has no effect.');
|
||||
console.warn(`https://nodejs.dev/en/learn/nodejs-the-difference-between-development-and-production/`);
|
||||
}
|
||||
|
||||
if(env.NODE_ENV) {
|
||||
buildConfig.mode = env.NODE_ENV as 'production' | 'development'
|
||||
console.log(magentaBright('NODE_ENV:'), 'Found NODE_ENV variable, setting `mode` to this.')
|
||||
|
||||
if (env.NODE_ENV) {
|
||||
buildConfig.mode = env.NODE_ENV as 'production' | 'development';
|
||||
console.log(magentaBright('NODE_ENV:'), 'Found NODE_ENV variable, setting `mode` to this.');
|
||||
}
|
||||
assert(buildConfig.mode === 'development' || buildConfig.mode === 'production', "Mode is not `production` or `development`");
|
||||
assert(buildConfig.mode === 'development' || buildConfig.mode === 'production', 'Mode is not `production` or `development`');
|
||||
|
||||
const defaultTsConfig = {
|
||||
extends: "./.sern/tsconfig.json",
|
||||
}
|
||||
extends: './.sern/tsconfig.json',
|
||||
};
|
||||
!buildConfig.tsconfig && console.log('Using default options for tsconfig', defaultTsConfig);
|
||||
const tsconfigRaw = require(buildConfig.tsconfig!);
|
||||
|
||||
sernConfig.language === 'typescript' && tsconfigRaw && !tsconfigRaw.extends && (
|
||||
console.warn('tsconfig does not contain an "extends". Will not use sern automatic path aliasing'),
|
||||
console.warn('For projects that predate sern build and want to fully integrate, extend the tsconfig generated in .sern'),
|
||||
console.warn('Extend preexisting tsconfig with top level: "extends": "./.sern/tsconfig.json"')
|
||||
);
|
||||
console.log(bold('Building with:'))
|
||||
console.log(' ', magentaBright('defineVersion'), buildConfig.defineVersion)
|
||||
console.log(' ', magentaBright('format'), buildConfig.format)
|
||||
console.log(' ', magentaBright('mode'), buildConfig.mode)
|
||||
console.log(' ', magentaBright('tsconfig'), buildConfig.tsconfig)
|
||||
console.log(' ', magentaBright('env'), buildConfig.env)
|
||||
|
||||
sernConfig.language === 'typescript' &&
|
||||
tsconfigRaw &&
|
||||
!tsconfigRaw.extends &&
|
||||
(console.warn('tsconfig does not contain an "extends". Will not use sern automatic path aliasing'),
|
||||
console.warn('For projects that predate sern build and want to fully integrate, extend the tsconfig generated in .sern'),
|
||||
console.warn('Extend preexisting tsconfig with top level: "extends": "./.sern/tsconfig.json"'));
|
||||
console.log(bold('Building with:'));
|
||||
console.log(' ', magentaBright('defineVersion'), buildConfig.defineVersion);
|
||||
console.log(' ', magentaBright('format'), buildConfig.format);
|
||||
console.log(' ', magentaBright('mode'), buildConfig.mode);
|
||||
console.log(' ', magentaBright('tsconfig'), buildConfig.tsconfig);
|
||||
console.log(' ', magentaBright('env'), buildConfig.env);
|
||||
|
||||
const sernDir = resolve('.sern'),
|
||||
genDir = resolve(sernDir, 'generated'),
|
||||
ambientFilePath = resolve(sernDir, 'ambient.d.ts'),
|
||||
packageJsonPath = resolve('package.json'),
|
||||
sernTsConfigPath = resolve(sernDir, 'tsconfig.json'),
|
||||
packageJson = () => require(packageJsonPath)
|
||||
genDir = resolve(sernDir, 'generated'),
|
||||
ambientFilePath = resolve(sernDir, 'ambient.d.ts'),
|
||||
packageJsonPath = resolve('package.json'),
|
||||
sernTsConfigPath = resolve(sernDir, 'tsconfig.json'),
|
||||
packageJson = () => require(packageJsonPath);
|
||||
|
||||
|
||||
if(!(await pathExists(genDir))) {
|
||||
console.log('Making .sern/generated dir, does not exist')
|
||||
await mkdir(genDir)
|
||||
if (!(await pathExists(genDir))) {
|
||||
console.log('Making .sern/generated dir, does not exist');
|
||||
await mkdir(genDir);
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
const defVersion = () => JSON.stringify(packageJson().version)
|
||||
const defVersion = () => JSON.stringify(packageJson().version);
|
||||
const define = {
|
||||
...buildConfig.define ?? {},
|
||||
__DEV__: `${buildConfig.mode === 'development'}`,
|
||||
__PROD__: `${buildConfig.mode === 'production'}`,
|
||||
...(buildConfig.define ?? {}),
|
||||
__DEV__: `${buildConfig.mode === 'development'}`,
|
||||
__PROD__: `${buildConfig.mode === 'production'}`,
|
||||
} satisfies Record<string, string>;
|
||||
|
||||
buildConfig.defineVersion && Object.assign(define, { '__VERSION__': defVersion() });
|
||||
buildConfig.defineVersion && Object.assign(define, { __VERSION__: defVersion() });
|
||||
|
||||
await Preprocessor.writeTsConfig(buildConfig.format!, sernTsConfigPath, writeFile);
|
||||
await Preprocessor.writeAmbientFile(ambientFilePath, define, writeFile);
|
||||
|
||||
|
||||
//https://esbuild.github.io/content-types/#tsconfig-json
|
||||
await esbuild.build({
|
||||
await esbuild.build({
|
||||
entryPoints,
|
||||
plugins: [imageLoader, ...buildConfig.esbuildPlugins??[] ],
|
||||
plugins: [imageLoader, ...(buildConfig.esbuildPlugins ?? [])],
|
||||
...defaultEsbuild(buildConfig.format!, tsconfigRaw),
|
||||
define,
|
||||
dropLabels: [ buildConfig.mode === 'production' ? '__DEV__' : '__PROD__', ...buildConfig.dropLabels!],
|
||||
})
|
||||
} catch(e) {
|
||||
console.error(e)
|
||||
process.exit(1)
|
||||
dropLabels: [buildConfig.mode === 'production' ? '__DEV__' : '__PROD__', ...buildConfig.dropLabels!],
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,8 @@ import { fork } from 'node:child_process';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
export async function publish(commandDir: string | undefined, args: Partial<PublishArgs>) {
|
||||
if(!args.suppressWarnings) {
|
||||
console.info(`${magentaBright('EXPERIMENTAL')}: This API has not been stabilized. add -W or --suppress-warnings flag to suppress`)
|
||||
|
||||
if (!args.suppressWarnings) {
|
||||
console.info(`${magentaBright('EXPERIMENTAL')}: This API has not been stabilized. add -W or --suppress-warnings flag to suppress`);
|
||||
}
|
||||
const config = await getConfig();
|
||||
// pass in args into the command.
|
||||
@@ -36,7 +35,7 @@ export async function publish(commandDir: string | undefined, args: Partial<Publ
|
||||
}
|
||||
|
||||
interface PublishArgs {
|
||||
suppressWarnings: boolean
|
||||
suppressWarnings: boolean;
|
||||
import: string[];
|
||||
token: string;
|
||||
applicationId: string;
|
||||
|
||||
@@ -215,7 +215,6 @@ const guildCommandMap = associateGuildIdsWithData(guildedCommands);
|
||||
|
||||
let guildCommandMapResponse = new Map<string, Record<string, unknown>>();
|
||||
|
||||
|
||||
for (const [guildId, array] of guildCommandMap.entries()) {
|
||||
const spin = ora(`[${cyanBright(guildId)}] Updating commands for guild`);
|
||||
spin.start();
|
||||
|
||||
28
src/index.ts
28
src/index.ts
@@ -4,36 +4,32 @@ import { Command } from 'commander';
|
||||
import { yellowBright } from 'colorette';
|
||||
export const program = new Command();
|
||||
|
||||
const importDynamic = async <T extends string>(filename: T) => import(`./commands/${filename}` as const)
|
||||
declare const __VERSION__: string
|
||||
const importDynamic = async <T extends string>(filename: T) => import(`./commands/${filename}` as const);
|
||||
declare const __VERSION__: string;
|
||||
|
||||
program
|
||||
.name('sern')
|
||||
.description(await importDynamic('help.js').then(m => m.help))
|
||||
.description(await importDynamic('help.js').then((m) => m.help))
|
||||
.version(`sern CLI v${__VERSION__}`, '-v, --version')
|
||||
.exitOverride(() => process.exit(0));
|
||||
|
||||
program
|
||||
.command('init')
|
||||
.description(
|
||||
`Quickest way to scaffold a new project ${yellowBright('[DEPRECATED]')}`
|
||||
)
|
||||
.description(`Quickest way to scaffold a new project ${yellowBright('[DEPRECATED]')}`)
|
||||
.option('-y', 'Finishes setup as default')
|
||||
.option('-s, --sync', 'Syncs the project and generates sern.config.json')
|
||||
.action(async (...args) => importDynamic('init.js').then(m => m.init(...args)));
|
||||
.action(async (...args) => importDynamic('init.js').then((m) => m.init(...args)));
|
||||
|
||||
program
|
||||
.command('plugins')
|
||||
.description(
|
||||
'Install plugins from https://github.com/sern-handler/awesome-plugins'
|
||||
)
|
||||
.description('Install plugins from https://github.com/sern-handler/awesome-plugins')
|
||||
.option('-n --name', 'Name of plugin')
|
||||
.action((...args) => importDynamic('plugins.js').then(m => m.plugins(...args)));
|
||||
.action((...args) => importDynamic('plugins.js').then((m) => m.plugins(...args)));
|
||||
|
||||
program
|
||||
.command('extra')
|
||||
.description('Easy way to add extra things in your sern project')
|
||||
.action((...args) => importDynamic('extra.js').then(m => m.extra(...args)));
|
||||
.action((...args) => importDynamic('extra.js').then((m) => m.extra(...args)));
|
||||
|
||||
program //
|
||||
.command('commands')
|
||||
@@ -46,10 +42,10 @@ program //
|
||||
.option('-t, --token [token]')
|
||||
.option('--appId [applicationId]')
|
||||
.argument('[path]', 'path with respect to current working directory that will locate all published files')
|
||||
.action(async (...args) => importDynamic('publish.js').then(m => m.publish(...args)))
|
||||
.action(async (...args) => importDynamic('publish.js').then((m) => m.publish(...args)))
|
||||
);
|
||||
|
||||
program
|
||||
program
|
||||
.command('build')
|
||||
.description('Build your bot')
|
||||
.option('-f --format [fmt]', 'The module system of your application. `cjs` or `esm`', 'esm')
|
||||
@@ -57,7 +53,7 @@ program
|
||||
.option('-W --suppress-warnings', 'suppress experimental warning')
|
||||
.option('-p --project [filePath]', 'build with this sern.build file')
|
||||
.option('-e --env', 'path to .env file')
|
||||
.option('--tsconfig [filePath]', "Use this tsconfig")
|
||||
.action(async (...args) => importDynamic('build.js').then(m => m.build(...args)))
|
||||
.option('--tsconfig [filePath]', 'Use this tsconfig')
|
||||
.action(async (...args) => importDynamic('build.js').then((m) => m.build(...args)));
|
||||
|
||||
program.parse();
|
||||
|
||||
@@ -1,40 +1,39 @@
|
||||
import fs from 'fs/promises'
|
||||
import path from 'node:path'
|
||||
import { require } from '../utilities/require.js'
|
||||
import { type Plugin } from 'esbuild'
|
||||
import { basename } from 'node:path'
|
||||
import fs from 'fs/promises';
|
||||
import path from 'node:path';
|
||||
import { require } from '../utilities/require.js';
|
||||
import { type Plugin } from 'esbuild';
|
||||
import { basename } from 'node:path';
|
||||
|
||||
export const validExtensions = ['.ts','.js', '.json', '.png', '.jpg', '.jpeg', '.webp']
|
||||
export const validExtensions = ['.ts', '.js', '.json', '.png', '.jpg', '.jpeg', '.webp'];
|
||||
|
||||
//https://github.com/evanw/esbuild/issues/1051
|
||||
export const imageLoader = {
|
||||
name: 'attachment-loader',
|
||||
setup: b => {
|
||||
const filter = new RegExp(`\.${validExtensions.slice(3).join('|')}$`)
|
||||
b.onResolve({ filter }, args => {
|
||||
setup: (b) => {
|
||||
const filter = new RegExp(`\.${validExtensions.slice(3).join('|')}$`);
|
||||
b.onResolve({ filter }, (args) => {
|
||||
//if the module is being imported, resolve the path and transform to the js stub
|
||||
if(args.importer) {
|
||||
const newPath = path
|
||||
if (args.importer) {
|
||||
const newPath = path
|
||||
.format({ ...path.parse(args.path), base: '', ext: '.js' })
|
||||
.split(path.sep)
|
||||
.join(path.posix.sep)
|
||||
return { path: newPath, namespace: 'attachment-loader', external: true }
|
||||
.join(path.posix.sep);
|
||||
return { path: newPath, namespace: 'attachment-loader', external: true };
|
||||
}
|
||||
// if the file is actually the attachment, resolve the full dir
|
||||
return { path: require.resolve(args.path, { paths: [args.resolveDir] }), namespace: 'attachment-loader' }
|
||||
})
|
||||
// if the file is actually the attachment, resolve the full dir
|
||||
return { path: require.resolve(args.path, { paths: [args.resolveDir] }), namespace: 'attachment-loader' };
|
||||
});
|
||||
|
||||
b.onLoad({ filter: /.*/, namespace: 'attachment-loader' },
|
||||
async (args) => {
|
||||
const base64 = await fs.readFile(args.path).then(s => s.toString('base64'))
|
||||
return {
|
||||
contents: `
|
||||
b.onLoad({ filter: /.*/, namespace: 'attachment-loader' }, async (args) => {
|
||||
const base64 = await fs.readFile(args.path).then((s) => s.toString('base64'));
|
||||
return {
|
||||
contents: `
|
||||
var __toBuffer = (base64) => Buffer.from(base64, "base64");
|
||||
module.exports = {
|
||||
name: '${basename(args.path)}',
|
||||
attachment: __toBuffer("${base64}")
|
||||
}`,
|
||||
}
|
||||
})
|
||||
}
|
||||
} satisfies Plugin
|
||||
};
|
||||
});
|
||||
},
|
||||
} satisfies Plugin;
|
||||
|
||||
14
src/types/config.d.ts
vendored
14
src/types/config.d.ts
vendored
@@ -6,16 +6,14 @@ export interface sernConfig {
|
||||
};
|
||||
scripts?: {
|
||||
prepublish?: string;
|
||||
}
|
||||
};
|
||||
buildPath: string;
|
||||
rest?: Record<string, Record<string,unknown>>;
|
||||
rest?: Record<string, Record<string, unknown>>;
|
||||
}
|
||||
|
||||
export interface TheoreticalEnv {
|
||||
DISCORD_TOKEN: string
|
||||
APPLICATION_ID: string,
|
||||
MODE: 'PROD' | 'DEV'
|
||||
[name: string]: string
|
||||
DISCORD_TOKEN: string;
|
||||
APPLICATION_ID: string;
|
||||
MODE: 'PROD' | 'DEV';
|
||||
[name: string]: string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import type esbuild from 'esbuild'
|
||||
import { resolve } from 'path'
|
||||
import type esbuild from 'esbuild';
|
||||
import { resolve } from 'path';
|
||||
|
||||
export default (format: 'cjs' | 'esm', tsconfigRaw: unknown) => ({
|
||||
platform: 'node',
|
||||
format,
|
||||
tsconfigRaw: tsconfigRaw as esbuild.TsconfigRaw,
|
||||
logLevel: 'info',
|
||||
minify: false,
|
||||
outdir: resolve('dist'),
|
||||
|
||||
} satisfies esbuild.BuildOptions)
|
||||
export default (format: 'cjs' | 'esm', tsconfigRaw: unknown) =>
|
||||
({
|
||||
platform: 'node',
|
||||
format,
|
||||
tsconfigRaw: tsconfigRaw as esbuild.TsconfigRaw,
|
||||
logLevel: 'info',
|
||||
minify: false,
|
||||
outdir: resolve('dist'),
|
||||
} satisfies esbuild.BuildOptions);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { findUp } from 'find-up';
|
||||
import assert from 'node:assert';
|
||||
@@ -21,5 +20,5 @@ export interface sernConfig {
|
||||
commands: string;
|
||||
events?: string;
|
||||
};
|
||||
buildPath: string
|
||||
buildPath: string;
|
||||
}
|
||||
|
||||
@@ -1,96 +1,90 @@
|
||||
const declareConstType = (name: string, type: string) => String.raw`declare var ${name}: ${type}`
|
||||
const declareConstType = (name: string, type: string) => String.raw`declare var ${name}: ${type}`;
|
||||
|
||||
const processEnvType = (env: NodeJS.ProcessEnv) => {
|
||||
const entries = Object.keys(env)
|
||||
const entries = Object.keys(env);
|
||||
|
||||
const envBuilder = new StringWriter()
|
||||
const envBuilder = new StringWriter();
|
||||
|
||||
for(const key of entries) {
|
||||
envBuilder.tab()
|
||||
envBuilder.tab()
|
||||
envBuilder.envField(key)
|
||||
for (const key of entries) {
|
||||
envBuilder.tab();
|
||||
envBuilder.tab();
|
||||
envBuilder.envField(key);
|
||||
}
|
||||
return envBuilder.build()
|
||||
}
|
||||
return envBuilder.build();
|
||||
};
|
||||
|
||||
const determineJSONType = (s : string) => {
|
||||
return typeof JSON.parse(s)
|
||||
}
|
||||
const determineJSONType = (s: string) => {
|
||||
return typeof JSON.parse(s);
|
||||
};
|
||||
|
||||
type FileWriter = (path: string, content: string, format: BufferEncoding) => Promise<void>;
|
||||
const writeAmbientFile = async (
|
||||
path: string,
|
||||
define: Record<string, string>,
|
||||
writeFile: FileWriter
|
||||
) => {
|
||||
const fileContent = new StringWriter()
|
||||
for(const [k,v] of Object.entries(define)) {
|
||||
fileContent.varDecl(k,v)
|
||||
const writeAmbientFile = async (path: string, define: Record<string, string>, writeFile: FileWriter) => {
|
||||
const fileContent = new StringWriter();
|
||||
for (const [k, v] of Object.entries(define)) {
|
||||
fileContent.varDecl(k, v);
|
||||
}
|
||||
fileContent
|
||||
.println('declare namespace NodeJS {')
|
||||
.println('declare namespace NodeJS {')
|
||||
.tab()
|
||||
.println('interface ProcessEnv {')
|
||||
.envFields(process.env)
|
||||
.tab()
|
||||
.println('}')
|
||||
.println('}')
|
||||
|
||||
await writeFile(path, fileContent.build(), 'utf8')
|
||||
}
|
||||
.println('}');
|
||||
|
||||
await writeFile(path, fileContent.build(), 'utf8');
|
||||
};
|
||||
|
||||
const writeTsConfig = async (format: 'cjs' | 'esm', configPath: string, fw: FileWriter) => {
|
||||
//maybe better way to do this
|
||||
const target = format === 'esm' ? { target: 'esnext' } : {};
|
||||
const target = format === 'esm' ? { target: 'esnext' } : {};
|
||||
const sernTsConfig = {
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
compilerOptions: {
|
||||
moduleResolution: 'node',
|
||||
strict: true,
|
||||
skipLibCheck: true,
|
||||
...target,
|
||||
"rootDirs": ["./generated", "../src"]
|
||||
rootDirs: ['./generated', '../src'],
|
||||
},
|
||||
"include": ["./ambient.d.ts", "../src"]
|
||||
}
|
||||
include: ['./ambient.d.ts', '../src'],
|
||||
};
|
||||
|
||||
await fw(configPath, JSON.stringify(sernTsConfig, null, 3), 'utf8')
|
||||
|
||||
}
|
||||
await fw(configPath, JSON.stringify(sernTsConfig, null, 3), 'utf8');
|
||||
};
|
||||
class StringWriter {
|
||||
private fileString = ""
|
||||
private fileString = '';
|
||||
|
||||
tab() {
|
||||
this.fileString+=" "
|
||||
this.fileString += ' ';
|
||||
return this;
|
||||
}
|
||||
|
||||
varDecl(name: string, type: string) {
|
||||
this.fileString+=declareConstType(name, determineJSONType(type))+'\n'
|
||||
this.fileString += declareConstType(name, determineJSONType(type)) + '\n';
|
||||
return this;
|
||||
}
|
||||
|
||||
println(data: string) {
|
||||
this.fileString+=data+"\n"
|
||||
this.fileString += data + '\n';
|
||||
return this;
|
||||
}
|
||||
envField(key: string) {
|
||||
if(/\s|\(|\)/g.test(key)) {
|
||||
this.fileString+=`"${key}": string`
|
||||
if (/\s|\(|\)/g.test(key)) {
|
||||
this.fileString += `"${key}": string`;
|
||||
} else {
|
||||
this.fileString+=key+ ':'+ 'string'
|
||||
this.fileString += key + ':' + 'string';
|
||||
}
|
||||
this.fileString+="\n"
|
||||
this.fileString += '\n';
|
||||
return this;
|
||||
}
|
||||
|
||||
envFields(env: NodeJS.ProcessEnv) {
|
||||
this.fileString+=processEnvType(env);
|
||||
this.fileString += processEnvType(env);
|
||||
return this;
|
||||
}
|
||||
build() {
|
||||
return this.fileString;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { writeAmbientFile, writeTsConfig }
|
||||
export { writeAmbientFile, writeTsConfig };
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { readdir, stat } from 'fs/promises'
|
||||
import { basename, join, extname } from 'path'
|
||||
function isSkippable (filename: string) {
|
||||
import { readdir, stat } from 'fs/promises';
|
||||
import { basename, join, extname } from 'path';
|
||||
function isSkippable(filename: string) {
|
||||
//empty string is for non extension files (directories)
|
||||
const validExtensions = ['.js', '.cjs', '.mts', '.mjs', '.cts', '.ts', ''];
|
||||
return filename[0] === '!' || !validExtensions.includes(extname(filename));
|
||||
}
|
||||
|
||||
|
||||
async function deriveFileInfo(dir: string, file: string) {
|
||||
const fullPath = join(dir, file);
|
||||
return {
|
||||
@@ -16,22 +15,15 @@ async function deriveFileInfo(dir: string, file: string) {
|
||||
};
|
||||
}
|
||||
|
||||
export async function* readPaths(
|
||||
dir: string,
|
||||
shouldDebug: boolean
|
||||
): AsyncGenerator<string> {
|
||||
export async function* readPaths(dir: string, shouldDebug: boolean): AsyncGenerator<string> {
|
||||
try {
|
||||
const files = await readdir(dir);
|
||||
for (const file of files) {
|
||||
const { fullPath, fileStats, base } = await deriveFileInfo(
|
||||
dir,
|
||||
file
|
||||
);
|
||||
const { fullPath, fileStats, base } = await deriveFileInfo(dir, file);
|
||||
if (fileStats.isDirectory()) {
|
||||
//Todo: refactor so that i dont repeat myself for files (line 71)
|
||||
if (isSkippable(base)) {
|
||||
if (shouldDebug)
|
||||
console.info(`ignored directory: ${fullPath}`);
|
||||
if (shouldDebug) console.info(`ignored directory: ${fullPath}`);
|
||||
} else {
|
||||
yield* readPaths(fullPath, shouldDebug);
|
||||
}
|
||||
@@ -47,4 +39,3 @@ export async function* readPaths(
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import { createRequire } from 'node:module'
|
||||
import { createRequire } from 'node:module';
|
||||
|
||||
export const require = createRequire(import.meta.url)
|
||||
export const require = createRequire(import.meta.url);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { defineConfig } from 'tsup';
|
||||
import { createRequire } from 'node:module'
|
||||
import { createRequire } from 'node:module';
|
||||
const shared = {
|
||||
entry: ['src/index.ts', 'src/create-publish.mts', 'src/commands/**', 'sern-tsconfig.json'],
|
||||
clean: true,
|
||||
@@ -16,10 +16,10 @@ export default defineConfig({
|
||||
platform: 'node',
|
||||
splitting: true,
|
||||
define: {
|
||||
__VERSION__: `"${createRequire(import.meta.url)('./package.json').version}"`
|
||||
__VERSION__: `"${createRequire(import.meta.url)('./package.json').version}"`,
|
||||
},
|
||||
loader: {
|
||||
'.json': 'file'
|
||||
'.json': 'file',
|
||||
},
|
||||
...shared,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user