mirror of
https://github.com/sern-handler/cli
synced 2026-06-06 01:16:53 +00:00
fix up typing gen for process env and watch mode
This commit is contained in:
@@ -22,10 +22,6 @@ type BuildOptions = {
|
||||
* default = esm
|
||||
*/
|
||||
format?: 'cjs' | 'esm';
|
||||
/**
|
||||
* extra esbuild plugins to build with sern.
|
||||
*/
|
||||
esbuildPlugins?: esbuild.Plugin[];
|
||||
/**
|
||||
* https://esbuild.github.io/api/#drop-labels
|
||||
**/
|
||||
@@ -46,32 +42,23 @@ type BuildOptions = {
|
||||
*/
|
||||
env?: string;
|
||||
};
|
||||
const CommandHandlerPlugin = (commandPaths: Array<{name: string}>, eventsPaths: Array<{name: string}>) => {
|
||||
const CommandHandlerPlugin = (buildConfig: Partial<BuildOptions>, ambientFilePath: string, sernTsConfigPath: string) => {
|
||||
return {
|
||||
name: "commandhandler",
|
||||
setup(build) {
|
||||
build.onEnd(async result => {
|
||||
if(result.errors.length) return;
|
||||
const commandsImports = commandPaths.map((fname, i) =>
|
||||
`import cm${i} from "./commands/${fname.name}"`);
|
||||
const eventImports = eventsPaths.map((fname, i) =>
|
||||
`import em${i} from "./events/${fname.name}"`);
|
||||
const commandMapTemplate =
|
||||
'export const __commands = new Map();\n ' +
|
||||
commandPaths.map((_, i) => `__commands.set(cm${i}.meta.id, cm${i});`).join("\n");
|
||||
const eventsMapTemplate =
|
||||
'export const __events = new Map();\n' +
|
||||
eventsPaths.map((_, i) => `__events.set(em${i}.meta.id, em${i});`).join("\n");
|
||||
|
||||
const presence = await glob("./src/presence.{ts,js}");
|
||||
const startFile =
|
||||
commandsImports.join('\n') + '\n' +
|
||||
eventImports.join('\n') + '\n' +
|
||||
(presence.length ? `import p0 from './presence.js'` : '') + "\n" +
|
||||
commandMapTemplate + "\n"+
|
||||
eventsMapTemplate + "\n";
|
||||
await writeFile("./dist/handler.js", startFile);
|
||||
})
|
||||
const options = build.initialOptions
|
||||
|
||||
const defVersion = () => JSON.stringify(require(p.resolve('package.json')).version);
|
||||
options.define = {
|
||||
...buildConfig.define ?? {},
|
||||
__DEV__: `${buildConfig.mode === 'development'}`,
|
||||
__PROD__: `${buildConfig.mode === 'production'}`,
|
||||
__VERSION__: `${buildConfig.defineVersion ? `${defVersion()}` : 'undefined'}`
|
||||
} ?? {}
|
||||
Preprocessor.writeTsConfig(buildConfig.format!, sernTsConfigPath, writeFile);
|
||||
Preprocessor.writeAmbientFile(ambientFilePath, options.define!, writeFile);
|
||||
|
||||
}
|
||||
} as esbuild.Plugin
|
||||
}
|
||||
@@ -105,20 +92,12 @@ export async function build(options: Record<string, any>) {
|
||||
buildConfig = defaultBuildConfig;
|
||||
console.log('No build config found, defaulting');
|
||||
}
|
||||
let env = {} as Record<string, string>;
|
||||
configDotenv({ path: buildConfig.env, processEnv: env });
|
||||
const modeButNotNodeEnvExists = env.MODE && !env.NODE_ENV;
|
||||
if (modeButNotNodeEnvExists) {
|
||||
console.warn('Use NODE_ENV instead of MODE \n\
|
||||
MODE has no effect. \n\
|
||||
https://nodejs.org/en/learn/getting-started/nodejs-the-difference-between-development-and-production');
|
||||
}
|
||||
|
||||
if (env.NODE_ENV) {
|
||||
buildConfig.mode = env.NODE_ENV as 'production' | 'development';
|
||||
configDotenv({ path: buildConfig.env });
|
||||
|
||||
if (process.env.NODE_ENV) {
|
||||
buildConfig.mode = process.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`');
|
||||
try {
|
||||
let config = require(buildConfig.tsconfig!);
|
||||
@@ -128,7 +107,7 @@ export async function build(options: Record<string, any>) {
|
||||
console.error(`Please create a ${sernConfig.language === 'javascript' ? 'jsconfig.json' : 'tsconfig.json' }`);
|
||||
console.error('It should have at least extend the generated one sern makes.\n \
|
||||
{ "extends": "./.sern/tsconfig.json" }');
|
||||
throw e;
|
||||
throw e;
|
||||
}
|
||||
|
||||
console.log(bold('Building with:'));
|
||||
@@ -139,10 +118,8 @@ export async function build(options: Record<string, any>) {
|
||||
console.log(' ', magentaBright('env'), buildConfig.env);
|
||||
|
||||
const sernDir = p.resolve('.sern'),
|
||||
genDir = p.resolve(sernDir, 'generated'),
|
||||
ambientFilePath = p.resolve(sernDir, 'ambient.d.ts'),
|
||||
sernTsConfigPath = p.resolve(sernDir, 'tsconfig.json'),
|
||||
packageJson = () => require(p.resolve('package.json'));
|
||||
[ambientFilePath, sernTsConfigPath, genDir] =
|
||||
['ambient.d.ts', 'tsconfig.json', 'generated'].map(f => p.resolve(sernDir, f));
|
||||
|
||||
if (!(await pathExists(genDir))) {
|
||||
console.log('Making .sern/generated dir, does not exist');
|
||||
@@ -150,36 +127,23 @@ export async function build(options: Record<string, any>) {
|
||||
}
|
||||
|
||||
const entryPoints = await glob(`./src/**/*{${validExtensions.join(',')}}`);
|
||||
const [commandsPaths, eventsPaths] = await Promise.all([
|
||||
glob(`**/*`, {
|
||||
withFileTypes: true,
|
||||
ignore: { ignored: p => p.isDirectory() },
|
||||
cwd: "./src/commands/"
|
||||
}),
|
||||
glob(`**/*`, {
|
||||
withFileTypes: true,
|
||||
ignore: { ignored: p => p.isDirectory() },
|
||||
cwd: "./src/events/"
|
||||
})
|
||||
])
|
||||
|
||||
const defVersion = () => JSON.stringify(packageJson().version);
|
||||
const define = {
|
||||
...(buildConfig.define ?? {}),
|
||||
__DEV__: `${buildConfig.mode === 'development'}`,
|
||||
__PROD__: `${buildConfig.mode === 'production'}`,
|
||||
__VERSION__: `${buildConfig.defineVersion ? `${defVersion()}` : 'undefined'}`
|
||||
} satisfies Record<string, string>;
|
||||
// const [commandsPaths, eventsPaths] = await Promise.all([
|
||||
// glob(`**/*`, { withFileTypes: true, ignore: { ignored: p => p.isDirectory() }, cwd: "./src/commands/" }),
|
||||
// glob(`**/*`, { withFileTypes: true, ignore: { ignored: p => p.isDirectory() }, cwd: "./src/events/" })
|
||||
// ])
|
||||
|
||||
await Preprocessor.writeTsConfig(buildConfig.format!, sernTsConfigPath, writeFile);
|
||||
await Preprocessor.writeAmbientFile(ambientFilePath, define, writeFile);
|
||||
|
||||
|
||||
//https://esbuild.github.io/content-types/#tsconfig-json
|
||||
await esbuild.build({
|
||||
const ctx = await esbuild.context({
|
||||
entryPoints,
|
||||
plugins: [CommandHandlerPlugin(commandsPaths, eventsPaths)],
|
||||
plugins: [CommandHandlerPlugin(buildConfig, ambientFilePath, sernTsConfigPath)],
|
||||
...defaultEsbuild(buildConfig.format!, buildConfig.tsconfig),
|
||||
define,
|
||||
dropLabels: [buildConfig.mode === 'production' ? '__DEV__' : '__PROD__', ...buildConfig.dropLabels!],
|
||||
});
|
||||
if(options.watch) {
|
||||
} else {
|
||||
ctx.rebuild()
|
||||
ctx.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,18 +17,17 @@ export async function getLang(): Promise<'typescript' | 'javascript'> {
|
||||
return output.language;
|
||||
}
|
||||
|
||||
export async function getConfig(): Promise<sernConfig> {
|
||||
export async function getConfig(): Promise<SernConfig> {
|
||||
const sernLocation = await findUp('sern.config.json');
|
||||
assert(sernLocation, "Can't find sern.config.json");
|
||||
|
||||
const output = JSON.parse(await readFile(sernLocation, 'utf8')) as sernConfig;
|
||||
const output = JSON.parse(await readFile(sernLocation, 'utf8')) as SernConfig;
|
||||
|
||||
assert(output, "Can't read your sern.config.json.");
|
||||
|
||||
return output;
|
||||
}
|
||||
export interface sernConfig {
|
||||
type?: "serverless" | "websocket"
|
||||
export interface SernConfig {
|
||||
language: 'typescript' | 'javascript';
|
||||
defaultPrefix?: string;
|
||||
paths: {
|
||||
@@ -36,4 +35,7 @@ export interface sernConfig {
|
||||
commands: string;
|
||||
events?: string;
|
||||
};
|
||||
build?: {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ const writeAmbientFile = async (path: string, define: Record<string, string>, wr
|
||||
|
||||
const writeTsConfig = async (format: 'cjs' | 'esm', configPath: string, fw: FileWriter) => {
|
||||
//maybe better way to do this
|
||||
const target = format === 'esm' ? { target: 'esnext' } : {};
|
||||
const sernTsConfig = {
|
||||
compilerOptions: {
|
||||
//module determines top level await. CJS doesn't have that abliity afaik
|
||||
@@ -45,7 +44,7 @@ const writeTsConfig = async (format: 'cjs' | 'esm', configPath: string, fw: File
|
||||
moduleResolution: 'node16',
|
||||
strict: true,
|
||||
skipLibCheck: true,
|
||||
...target,
|
||||
target: 'esnext',
|
||||
rootDirs: ['./generated', '../src'],
|
||||
},
|
||||
include: ['./ambient.d.ts', '../src'],
|
||||
|
||||
Reference in New Issue
Block a user