Skip to content

Commit

Permalink
recursion check + jsdoc
Browse files Browse the repository at this point in the history
  • Loading branch information
mmkal committed May 26, 2024
1 parent 55be2bc commit 827827e
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 12 deletions.
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {ZodError} from 'zod'
import {type JsonSchema7Type} from 'zod-to-json-schema'
import * as zodValidationError from 'zod-validation-error'
import {flattenedProperties, incompatiblePropertyPairs, getDescription} from './json-schema'
import {primitiveOrJsonConsoleLogger} from './logging'
import {lineByLineConsoleLogger} from './logging'
import {Logger, TrpcCliParams} from './types'
import {parseProcedureInputs} from './zod-procedure'

Expand Down Expand Up @@ -52,7 +52,7 @@ export const trpcCli = <R extends AnyRouter>({router, ...params}: TrpcCliParams<
)

async function run(runParams?: {argv?: string[]; logger?: Logger; process?: {exit: (code: number) => never}}) {
const logger = {...primitiveOrJsonConsoleLogger, ...runParams?.logger}
const logger = {...lineByLineConsoleLogger, ...runParams?.logger}
const _process = runParams?.process || process
let verboseErrors: boolean = false

Expand Down
29 changes: 21 additions & 8 deletions src/logging.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import {LogMethod, Logger} from './types'
import {LogMethod as LogFn, Logger} from './types'

export const primitiveOrJsonLogger = getLoggerTransformer(log => {
const transformed: LogMethod = (...args) => {
if (args.length === 1 && Array.isArray(args[0])) {
args[0].forEach(item => transformed(item))
export const lineByLineLogger = getLoggerTransformer(log => {
/**
* @param args values to log. if `logger.info('a', 1)` is called, `args` will be `['a', 1]`
* @param depth tracks whether the current call recursive. Used to make sure we don't flatten nested arrays
*/
const wrapper = (args: unknown[], depth: number) => {
if (args.length === 1 && Array.isArray(args[0]) && depth === 0) {
args[0].forEach(item => wrapper([item], 1))
} else if (args.every(isPrimitive)) {
log(...args)
} else if (args.length === 1) {
Expand All @@ -13,16 +17,17 @@ export const primitiveOrJsonLogger = getLoggerTransformer(log => {
}
}

return transformed
return (...args) => wrapper(args, 0)
})

const isPrimitive = (value: unknown): value is string | number | boolean => {
const type = typeof value
return type === 'string' || type === 'number' || type === 'boolean'
}

type TransformLogMethod = (method: LogMethod) => LogMethod
type TransformLogMethod = (log: LogFn) => LogFn

/** Takes a function that wraps an individual log function, and returns a function that wraps the `info` and `error` functions for a logger */
function getLoggerTransformer(transform: TransformLogMethod) {
return (logger: Logger): Logger => {
const info = logger.info && transform(logger.info)
Expand All @@ -31,4 +36,12 @@ function getLoggerTransformer(transform: TransformLogMethod) {
}
}

export const primitiveOrJsonConsoleLogger = primitiveOrJsonLogger(console)
/**
* A logger which uses `console.log` and `console.error` to log in the following way:
* - Primitives are logged directly
* - Arrays are logged item-by-item
* - Objects are logged as JSON
*
* This is useful for logging structured data in a human-readable way, and for piping logs to other tools.
*/
export const lineByLineConsoleLogger = lineByLineLogger(console)
22 changes: 20 additions & 2 deletions test/logging.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {beforeEach, expect, test, vi} from 'vitest'
import {primitiveOrJsonLogger} from '../src/logging'
import {lineByLineLogger} from '../src/logging'

const info = vi.fn()
const error = vi.fn()
const mocks = {info, error}
const jsonish = primitiveOrJsonLogger(mocks)
const jsonish = lineByLineLogger(mocks)

beforeEach(() => {
vi.clearAllMocks()
Expand Down Expand Up @@ -43,6 +43,24 @@ test('primitives array', async () => {
`)
})

test('array array', async () => {
jsonish.info!([
['m1', 'm2'],
['m3', 'm4'],
])

expect(info).toMatchInlineSnapshot(`
[
"m1",
"m2"
]
[
"m3",
"m4"
]
`)
})

test('multi primitives', async () => {
jsonish.info!('m1', 11, true, 'm2')
jsonish.info!('m1', 12, false, 'm2')
Expand Down

0 comments on commit 827827e

Please sign in to comment.