Skip to content

Commit

Permalink
Replacing any with unknown and adding a few assertions. Dropping impl…
Browse files Browse the repository at this point in the history
…icit any.
  • Loading branch information
nathanb committed Dec 6, 2024
1 parent c1d1702 commit 3dfa624
Show file tree
Hide file tree
Showing 8 changed files with 915 additions and 3,094 deletions.
3,910 changes: 859 additions & 3,051 deletions package-lock.json

Large diffs are not rendered by default.

13 changes: 6 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,14 @@
"samples"
],
"devDependencies": {
"@eslint/js": "^9.9.0",
"@stylistic/eslint-plugin": "^2.6.4",
"eslint": "^8.57.0",
"eslint-plugin-n": "^17.10.2",
"@eslint/js": "^9.16.0",
"@stylistic/eslint-plugin": "^2.11.0",
"eslint": "^8.57.1",
"eslint-plugin-n": "^17.14.0",
"eslint-plugin-promise": "^6.6.0",
"eslint-plugin-react": "^7.35.0",
"globals": "^15.9.0",
"eslint-plugin-react": "^7.37.2",
"globals": "^15.13.0",
"i": "^0.3.7",
"npm": "^10.8.2",
"typescript-eslint": "^7.18.0"
}
}
6 changes: 3 additions & 3 deletions packages/json-csv-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@iwsio/json-csv-core",
"version": "1.1.7",
"version": "1.2.0-alpha.1",
"description": "Easily convert JSON to CSV. This is a core library built for browser and node to support buffered conversion to CSV.",
"keywords": [
"json",
Expand Down Expand Up @@ -41,9 +41,9 @@
},
"homepage": "https://github.com/iwsllc/json-csv/blob/main/packages/json-csv-core/README.md",
"devDependencies": {
"@types/chai": "^4.3.17",
"@types/chai": "^4.3.20",
"npm-run-all": "^4.1.5",
"rimraf": "^6.0.1",
"typescript": "^5.5.4"
"typescript": "^5.7.2"
}
}
50 changes: 28 additions & 22 deletions packages/json-csv-core/src/exporter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ExportOptions, FieldList } from './types.js'
import { ExportOptions, Field, FieldList } from './types.js'

export function checkOptions(opts?: Partial<ExportOptions>) {
const options: Partial<ExportOptions> = opts == null ? {} : { ...opts }
Expand All @@ -11,7 +11,7 @@ export function checkOptions(opts?: Partial<ExportOptions>) {
/**
* Main entry point. Convert a buffered array of data to a CSV string.
*/
export function buffered(data: Record<string, any>[], opts: Partial<ExportOptions>) {
export function buffered(data: Record<string, unknown>[], opts: Partial<ExportOptions>) {
const options = checkOptions(opts)
let output = ''
let writtenHeader = false
Expand All @@ -31,7 +31,7 @@ export function buffered(data: Record<string, any>[], opts: Partial<ExportOption
return output
}

export function prepValue(text: string, forceQuoted: boolean, fieldSeparator: string): any {
export function prepValue(text: string, forceQuoted: boolean, fieldSeparator: string): unknown {
if (text == null) text = ''
const quoted = forceQuoted || text.indexOf('"') >= 0 || text.indexOf(fieldSeparator) >= 0 || text.indexOf('\n') >= 0
let result = text.replace(/"/g, '""')
Expand All @@ -40,31 +40,32 @@ export function prepValue(text: string, forceQuoted: boolean, fieldSeparator: st
}

export function getHeaderRow(fields: FieldList, fieldSeparator: string) {
const fieldKeys = Object.keys(fields)
let header = fieldKeys.reduce((line, fieldKey) => {
const field = fields[fieldKey]
let header = ''
for (let ix = 0; ix < fields.length; ix++) {
const field = fields[ix]
const label = field.label || field.name
if (line === 'START') {
line = ''
} else {
line += fieldSeparator
if (ix > 0) {
header += fieldSeparator
}
line += prepValue(label, field.quoted, fieldSeparator)
return line
}, 'START')
header += prepValue(label, field.quoted, fieldSeparator)
}
header += '\r\n'
return header
}

export function getBodyRow(data: Record<string, any> | undefined | null, fields: FieldList, fieldSeparator: string): string {
const reducer = (line, field) => {
const assertString = (value: unknown): value is string => {
return typeof value === 'string'
}

export function getBodyRow(data: Record<string, unknown> | undefined | null, fields: FieldList, fieldSeparator: string): string {
const reducer = (line: string, field: Field) => {
if (line === 'START') {
line = ''
} else {
line += fieldSeparator
}
let val = getValue(data, field.name)
// vinicioslc support to OR || operator allowing multiples names to the same column
// support to OR || operator allowing multiples names to the same column
// the code will use the last non null and non empty value
if (field.name.includes('||')) {
// by default column is empty
Expand All @@ -75,7 +76,7 @@ export function getBodyRow(data: Record<string, any> | undefined | null, fields:
// get value and associate
const fieldVal = getValue(data, field)
// remove whitespaces and check if non null before assign
if (val != null && fieldVal.trim().length > 0 && fieldVal.trim() !== '') {
if (val != null && assertString(fieldVal) && fieldVal.trim().length > 0 && fieldVal.trim() !== '') {
val = fieldVal
}
// do this for every field
Expand All @@ -84,7 +85,7 @@ export function getBodyRow(data: Record<string, any> | undefined | null, fields:

if (typeof field.transform === 'function') {
val = field.transform(val)
} else if (typeof field.filter === 'function') {
} else if (typeof field.filter === 'function') { // backward compatibility
val = field.filter(val)
}
if (typeof val !== 'undefined' && val !== null) {
Expand All @@ -99,24 +100,29 @@ export function getBodyRow(data: Record<string, any> | undefined | null, fields:
return row
}

export function getValue(data: Record<string, any>, keyPath: string): any {
export function getValue(data: Record<string, unknown>, keyPath: string): unknown {
const keys = keyPath.split('.')
if (keys.length > 0) return getValueIx(data, keys, 0)
return ''
}

export function getValueIx(data: Record<string, any> | undefined | null, keys: string[], ix: number): any {
const assertObject = (value: unknown): value is Record<string, unknown> => {
if (typeof value === 'object') return true
return false
}

export function getValueIx(data: Record<string, unknown> | undefined | null, keys: string[], ix: number): unknown {
if (data == null) return ''

// for filtered fields using the whole row as a source.
// `this` is a keyword here; hoping not to conflict with existing fields.
if (keys[0] === 'this') return data

const val = data[keys[ix]]
if (typeof val === 'undefined') return ''
if (val == null) return ''

// walk the dot-notation recursively to get the remaining values.
if ((keys.length - 1) > ix) return getValueIx(val, keys, ix + 1)
if ((keys.length - 1) > ix && assertObject(val)) return getValueIx(val, keys, ix + 1)

return val
}
Expand Down
9 changes: 8 additions & 1 deletion packages/json-csv-core/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
export type Field = {
name: string
label?: string
transform?: (source: any) => string
transform?: (source: unknown) => string
/**
* @deprecated Please use `transform` instead
* @param source unknown value to be transformed
* @returns string transformed value
*/
filter?: (source: unknown) => string
quoted?: boolean
}

export type FieldList = Field[]
Expand Down
10 changes: 5 additions & 5 deletions packages/json-csv-node/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@iwsio/json-csv-node",
"version": "6.1.7",
"version": "6.2.0-alpha.1",
"description": "ESM/CJS module that easily converts JSON to CSV. This package supports streaming and buffered conversion to CSV.",
"homepage": "https://github.com/IWSLLC/json-csv",
"author": "Nathan Bridgewater <[email protected]>",
Expand Down Expand Up @@ -41,14 +41,14 @@
"clean": "rimraf dist"
},
"devDependencies": {
"@types/node": "^22.4.0",
"debug": "^4.3.6",
"@types/node": "^22.10.1",
"debug": "^4.4.0",
"npm-run-all": "^4.1.5",
"rimraf": "^6.0.1",
"typescript": "^5.5.4"
"typescript": "^5.7.2"
},
"dependencies": {
"@iwsio/json-csv-core": "^1.1.6"
"@iwsio/json-csv-core": "^1"
},
"bugs": {
"url": "https://github.com/IWSLLC/json-csv/issues"
Expand Down
10 changes: 5 additions & 5 deletions packages/json-csv-node/src/string-writer.cts
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,23 @@ import { StringDecoder } from 'string_decoder'
* See: https://nodejs.org/docs/latest-v14.x/api/stream.html#stream_decoding_buffers_in_a_writable_stream
*/
export default class StringWriter extends Writable {
_decoder: any
_decoder: StringDecoder
data: any
constructor(options?: WritableOptions) {
super(options)
this._decoder = new StringDecoder(options?.defaultEncoding)
this._decoder = new StringDecoder(options?.defaultEncoding ?? 'utf8')
this.data = ''
}

_write(chunk, encoding, callback) {
if (encoding === 'buffer') {
_write(chunk: any, encoding: BufferEncoding, callback: (error?: Error | null) => void) {
if (encoding != null) {
chunk = this._decoder.write(chunk)
}
this.data += chunk
callback()
}

_final(callback) {
_final(callback: (error?: Error | null) => void) {
this.data += this._decoder.end()
callback()
}
Expand Down
1 change: 1 addition & 0 deletions tsconfig-base.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"lib": ["ES6"],
"module": "NodeNext",
"moduleResolution": "NodeNext",
"noImplicitAny": true,
"resolveJsonModule": true,
"skipDefaultLibCheck": true,
"skipLibCheck": true,
Expand Down

0 comments on commit 3dfa624

Please sign in to comment.