style: apply biome formatting to config and generated files

- Convert spaces to tabs in tsconfig files
- Format CLI commands and prompts
- Update generated Convex files
- Format betterauth adapter and schema

Co-authored-by: Ona <no-reply@ona.com>
This commit is contained in:
2025-11-08 18:03:32 +00:00
parent 015524cd63
commit 027a315a04
18 changed files with 341 additions and 253 deletions

View File

@@ -1,11 +1,7 @@
import { generateApiKey, newPrefix } from "@drexa/auth"
import chalk from "chalk"
import { Command } from "commander"
import {
promptNumber,
promptOptionalDate,
promptText,
} from "../../prompts.ts"
import { promptNumber, promptOptionalDate, promptText } from "../../prompts.ts"
export const apikeyCommand = new Command("apikey")
.description("Generate a new API key")
@@ -53,7 +49,8 @@ export const apikeyCommand = new Command("apikey")
console.log(chalk.green(` ${result.unhashedKey}\n`))
console.log(chalk.gray("─".repeat(60)))
console.log(
chalk.bold("\nHashed Key ") + chalk.dim("(store this in your database):"),
chalk.bold("\nHashed Key ") +
chalk.dim("(store this in your database):"),
)
console.log(chalk.dim(` ${result.hashedKey}\n`))
console.log(chalk.bold("Description:"))

View File

@@ -29,7 +29,9 @@ export async function promptNumber(
): Promise<number> {
const rl = createReadlineInterface()
try {
const defaultStr = defaultValue ? chalk.dim(` (default: ${defaultValue})`) : ""
const defaultStr = defaultValue
? chalk.dim(` (default: ${defaultValue})`)
: ""
const input = await rl.question(chalk.cyan(`${message}${defaultStr} `))
if ((!input || input.trim() === "") && defaultValue !== undefined) {
@@ -59,7 +61,8 @@ export async function promptOptionalDate(
const rl = createReadlineInterface()
try {
const input = await rl.question(
chalk.cyan(`${message} `) + chalk.dim("(optional, format: YYYY-MM-DD) "),
chalk.cyan(`${message} `) +
chalk.dim("(optional, format: YYYY-MM-DD) "),
)
if (!input || input.trim() === "") {
@@ -68,7 +71,9 @@ export async function promptOptionalDate(
const date = new Date(input.trim())
if (Number.isNaN(date.getTime())) {
console.error(chalk.red("✗ Invalid date format. Please use YYYY-MM-DD"))
console.error(
chalk.red("✗ Invalid date format. Please use YYYY-MM-DD"),
)
process.exit(1)
}

83
apps/cli/test-example.md Normal file
View File

@@ -0,0 +1,83 @@
# Testing the CLI
To test the API key generation interactively, run:
```bash
bun drexa generate apikey
```
## Example Session
The CLI now uses **chalk** for beautiful colored output!
```
$ bun drexa generate apikey
🔑 Generate API Key
Enter API key prefix (e.g., 'proxy', 'admin'): testkey
Enter key byte length: (default: 32)
Enter description: Test API Key for development
Enter expiration date (optional, format: YYYY-MM-DD):
⏳ Generating API key...
✓ API Key Generated Successfully!
────────────────────────────────────────────────────────────
⚠️ IMPORTANT: Save the unhashed key now. It won't be shown again!
Unhashed Key (save this):
sk-testkey-AbCdEfGhIjKlMnOpQrStUvWxYz0123456789
────────────────────────────────────────────────────────────
Hashed Key (store this in your database):
$argon2id$v=19$m=4,t=3,p=1$...
Description:
Test API Key for development
Expires At:
Never
────────────────────────────────────────────────────────────
```
### Color Scheme
- **Prompts**: Cyan text with dimmed hints
- **Success messages**: Green with checkmark
- **Warnings**: Yellow with warning icon
- **Errors**: Red with X mark
- **Important data**: Green (unhashed key), dimmed (hashed key)
- **Separators**: Gray lines
## Testing with Invalid Input
### Invalid prefix (contains dash)
```bash
$ bun drexa generate apikey
Enter API key prefix (e.g., 'proxy', 'admin'): test-key
✗ Invalid prefix: cannot contain "-" character. Please use alphanumeric characters only.
```
### Invalid key byte length
```bash
$ bun drexa generate apikey
Enter API key prefix (e.g., 'proxy', 'admin'): testkey
Enter key byte length: (default: 32) -5
✗ Please enter a valid positive number
```
### Invalid date format
```bash
$ bun drexa generate apikey
Enter API key prefix (e.g., 'proxy', 'admin'): testkey
Enter key byte length: (default: 32)
Enter description: Test
Enter expiration date (optional, format: YYYY-MM-DD): invalid-date
✗ Invalid date format. Please use YYYY-MM-DD
```
All error messages are displayed in red for better visibility.

View File

@@ -62,10 +62,14 @@ export class WebCryptoSha256Hasher implements PassswordHasher {
}
return btoa(binary).replace(/[+/=]/g, (char) => {
switch (char) {
case "+": return "-"
case "/": return "_"
case "=": return ""
default: return char
case "+":
return "-"
case "/":
return "_"
case "=":
return ""
default:
return char
}
})
}

View File

@@ -1,6 +1,6 @@
import { createApi } from "@convex-dev/better-auth";
import schema from "./schema";
import { createAuth } from "../auth";
import { createApi } from "@convex-dev/better-auth"
import { createAuth } from "../auth"
import schema from "./schema"
export const {
create,
@@ -10,4 +10,4 @@ export const {
updateMany,
deleteOne,
deleteMany,
} = createApi(schema, createAuth);
} = createApi(schema, createAuth)

View File

@@ -1,5 +1,5 @@
import { createAuth } from '../auth'
import { getStaticAuth } from '@convex-dev/better-auth'
import { getStaticAuth } from "@convex-dev/better-auth"
import { createAuth } from "../auth"
// Export a static instance for Better Auth schema generation
export const auth = getStaticAuth(createAuth)

View File

@@ -1,5 +1,5 @@
import { defineComponent } from "convex/server";
import { defineComponent } from "convex/server"
const component = defineComponent("betterAuth");
const component = defineComponent("betterAuth")
export default component;
export default component

View File

@@ -2,8 +2,8 @@
// To regenerate the schema, run:
// `npx @better-auth/cli generate --output undefined -y`
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
import { defineSchema, defineTable } from "convex/server"
import { v } from "convex/values"
export const tables = {
user: defineTable({
@@ -63,8 +63,8 @@ export const tables = {
privateKey: v.string(),
createdAt: v.number(),
}),
};
}
const schema = defineSchema(tables);
const schema = defineSchema(tables)
export default schema;
export default schema

View File

@@ -12,7 +12,7 @@ import type {
ApiFromModules,
FilterApi,
FunctionReference,
} from "convex/server";
} from "convex/server"
/**
* A utility for referencing Convex functions in your app's API.
@@ -22,12 +22,12 @@ import type {
* const myFunctionReference = api.myModule.myFunction;
* ```
*/
declare const fullApi: ApiFromModules<{}>;
declare const fullApi: ApiFromModules<{}>
export declare const api: FilterApi<
typeof fullApi,
FunctionReference<any, "public">
>;
>
export declare const internal: FilterApi<
typeof fullApi,
FunctionReference<any, "internal">
>;
>

View File

@@ -8,7 +8,7 @@
* @module
*/
import { anyApi } from "convex/server";
import { anyApi } from "convex/server"
/**
* A utility for referencing Convex functions in your app's API.
@@ -18,5 +18,5 @@ import { anyApi } from "convex/server";
* const myFunctionReference = api.myModule.myFunction;
* ```
*/
export const api = anyApi;
export const internal = anyApi;
export const api = anyApi
export const internal = anyApi

View File

@@ -8,8 +8,8 @@
* @module
*/
import { AnyDataModel } from "convex/server";
import type { GenericId } from "convex/values";
import { AnyDataModel } from "convex/server"
import type { GenericId } from "convex/values"
/**
* No `schema.ts` file found!
@@ -25,12 +25,12 @@ import type { GenericId } from "convex/values";
/**
* The names of all of your Convex tables.
*/
export type TableNames = string;
export type TableNames = string
/**
* The type of a document stored in Convex.
*/
export type Doc = any;
export type Doc = any
/**
* An identifier for a document in Convex.
@@ -43,8 +43,7 @@ export type Doc = any;
* IDs are just strings at runtime, but this type can be used to distinguish them from other
* strings when type checking.
*/
export type Id<TableName extends TableNames = TableNames> =
GenericId<TableName>;
export type Id<TableName extends TableNames = TableNames> = GenericId<TableName>
/**
* A type describing your Convex data model.
@@ -55,4 +54,4 @@ export type Id<TableName extends TableNames = TableNames> =
* This type is used to parameterize methods like `queryGeneric` and
* `mutationGeneric` to make them type-safe.
*/
export type DataModel = AnyDataModel;
export type DataModel = AnyDataModel

View File

@@ -18,8 +18,8 @@ import {
GenericQueryCtx,
GenericDatabaseReader,
GenericDatabaseWriter,
} from "convex/server";
import type { DataModel } from "./dataModel.js";
} from "convex/server"
import type { DataModel } from "./dataModel.js"
/**
* Define a query in this Convex app's public API.
@@ -29,7 +29,7 @@ import type { DataModel } from "./dataModel.js";
* @param func - The query function. It receives a {@link QueryCtx} as its first argument.
* @returns The wrapped query. Include this as an `export` to name it and make it accessible.
*/
export declare const query: QueryBuilder<DataModel, "public">;
export declare const query: QueryBuilder<DataModel, "public">
/**
* Define a query that is only accessible from other Convex functions (but not from the client).
@@ -39,7 +39,7 @@ export declare const query: QueryBuilder<DataModel, "public">;
* @param func - The query function. It receives a {@link QueryCtx} as its first argument.
* @returns The wrapped query. Include this as an `export` to name it and make it accessible.
*/
export declare const internalQuery: QueryBuilder<DataModel, "internal">;
export declare const internalQuery: QueryBuilder<DataModel, "internal">
/**
* Define a mutation in this Convex app's public API.
@@ -49,7 +49,7 @@ export declare const internalQuery: QueryBuilder<DataModel, "internal">;
* @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
* @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.
*/
export declare const mutation: MutationBuilder<DataModel, "public">;
export declare const mutation: MutationBuilder<DataModel, "public">
/**
* Define a mutation that is only accessible from other Convex functions (but not from the client).
@@ -59,7 +59,7 @@ export declare const mutation: MutationBuilder<DataModel, "public">;
* @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
* @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.
*/
export declare const internalMutation: MutationBuilder<DataModel, "internal">;
export declare const internalMutation: MutationBuilder<DataModel, "internal">
/**
* Define an action in this Convex app's public API.
@@ -72,7 +72,7 @@ export declare const internalMutation: MutationBuilder<DataModel, "internal">;
* @param func - The action. It receives an {@link ActionCtx} as its first argument.
* @returns The wrapped action. Include this as an `export` to name it and make it accessible.
*/
export declare const action: ActionBuilder<DataModel, "public">;
export declare const action: ActionBuilder<DataModel, "public">
/**
* Define an action that is only accessible from other Convex functions (but not from the client).
@@ -80,7 +80,7 @@ export declare const action: ActionBuilder<DataModel, "public">;
* @param func - The function. It receives an {@link ActionCtx} as its first argument.
* @returns The wrapped function. Include this as an `export` to name it and make it accessible.
*/
export declare const internalAction: ActionBuilder<DataModel, "internal">;
export declare const internalAction: ActionBuilder<DataModel, "internal">
/**
* Define an HTTP action.
@@ -92,7 +92,7 @@ export declare const internalAction: ActionBuilder<DataModel, "internal">;
* @param func - The function. It receives an {@link ActionCtx} as its first argument.
* @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up.
*/
export declare const httpAction: HttpActionBuilder;
export declare const httpAction: HttpActionBuilder
/**
* A set of services for use within Convex query functions.
@@ -103,7 +103,7 @@ export declare const httpAction: HttpActionBuilder;
* This differs from the {@link MutationCtx} because all of the services are
* read-only.
*/
export type QueryCtx = GenericQueryCtx<DataModel>;
export type QueryCtx = GenericQueryCtx<DataModel>
/**
* A set of services for use within Convex mutation functions.
@@ -111,7 +111,7 @@ export type QueryCtx = GenericQueryCtx<DataModel>;
* The mutation context is passed as the first argument to any Convex mutation
* function run on the server.
*/
export type MutationCtx = GenericMutationCtx<DataModel>;
export type MutationCtx = GenericMutationCtx<DataModel>
/**
* A set of services for use within Convex action functions.
@@ -119,7 +119,7 @@ export type MutationCtx = GenericMutationCtx<DataModel>;
* The action context is passed as the first argument to any Convex action
* function run on the server.
*/
export type ActionCtx = GenericActionCtx<DataModel>;
export type ActionCtx = GenericActionCtx<DataModel>
/**
* An interface to read from the database within Convex query functions.
@@ -128,7 +128,7 @@ export type ActionCtx = GenericActionCtx<DataModel>;
* document by its {@link Id}, or {@link DatabaseReader.query}, which starts
* building a query.
*/
export type DatabaseReader = GenericDatabaseReader<DataModel>;
export type DatabaseReader = GenericDatabaseReader<DataModel>
/**
* An interface to read from and write to the database within Convex mutation
@@ -139,4 +139,4 @@ export type DatabaseReader = GenericDatabaseReader<DataModel>;
* your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control)
* for the guarantees Convex provides your functions.
*/
export type DatabaseWriter = GenericDatabaseWriter<DataModel>;
export type DatabaseWriter = GenericDatabaseWriter<DataModel>

View File

@@ -11,12 +11,12 @@
import {
actionGeneric,
httpActionGeneric,
queryGeneric,
mutationGeneric,
internalActionGeneric,
internalMutationGeneric,
internalQueryGeneric,
} from "convex/server";
mutationGeneric,
queryGeneric,
} from "convex/server"
/**
* Define a query in this Convex app's public API.
@@ -26,7 +26,7 @@ import {
* @param func - The query function. It receives a {@link QueryCtx} as its first argument.
* @returns The wrapped query. Include this as an `export` to name it and make it accessible.
*/
export const query = queryGeneric;
export const query = queryGeneric
/**
* Define a query that is only accessible from other Convex functions (but not from the client).
@@ -36,7 +36,7 @@ export const query = queryGeneric;
* @param func - The query function. It receives a {@link QueryCtx} as its first argument.
* @returns The wrapped query. Include this as an `export` to name it and make it accessible.
*/
export const internalQuery = internalQueryGeneric;
export const internalQuery = internalQueryGeneric
/**
* Define a mutation in this Convex app's public API.
@@ -46,7 +46,7 @@ export const internalQuery = internalQueryGeneric;
* @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
* @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.
*/
export const mutation = mutationGeneric;
export const mutation = mutationGeneric
/**
* Define a mutation that is only accessible from other Convex functions (but not from the client).
@@ -56,7 +56,7 @@ export const mutation = mutationGeneric;
* @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
* @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.
*/
export const internalMutation = internalMutationGeneric;
export const internalMutation = internalMutationGeneric
/**
* Define an action in this Convex app's public API.
@@ -69,7 +69,7 @@ export const internalMutation = internalMutationGeneric;
* @param func - The action. It receives an {@link ActionCtx} as its first argument.
* @returns The wrapped action. Include this as an `export` to name it and make it accessible.
*/
export const action = actionGeneric;
export const action = actionGeneric
/**
* Define an action that is only accessible from other Convex functions (but not from the client).
@@ -77,7 +77,7 @@ export const action = actionGeneric;
* @param func - The function. It receives an {@link ActionCtx} as its first argument.
* @returns The wrapped function. Include this as an `export` to name it and make it accessible.
*/
export const internalAction = internalActionGeneric;
export const internalAction = internalActionGeneric
/**
* Define a Convex HTTP action.
@@ -86,4 +86,4 @@ export const internalAction = internalActionGeneric;
* as its second.
* @returns The wrapped endpoint function. Route a URL path to this function in `convex/http.js`.
*/
export const httpAction = httpActionGeneric;
export const httpAction = httpActionGeneric