Skip to content

Commit

Permalink
Replace lodash with native js (#753)
Browse files Browse the repository at this point in the history
* Replace lodash isArray with native Array.isArray

* Replace simple map calls

* Replace lodash mapValue calls

* Replace lodash keys with Object.keys

* Replace lodash intersection with native filter

* Replace lodash map obj with native Object.keys and map

* Remove lodash import

* Replace lodash chain with native Object.keys and filter

* Remove lodash dependencies

* Add temporary console.log

* Revert "Replace lodash chain with native Object.keys and filter"

This reverts commit 360cb7c.

* Add temporary console.log

* Replace lodash chain with native Object.keys, filter and map

* Remove lodash dependencies

* Use Object.entries

* Add intersection util function

* Restore node v10 compatibility
  • Loading branch information
Shinigami92 authored Apr 27, 2021
1 parent 5f54a59 commit 4e3e892
Show file tree
Hide file tree
Showing 11 changed files with 63 additions and 62 deletions.
9 changes: 2 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,12 @@
"dependencies": {
"@types/pg": "^7.4.0",
"decamelize": "^4.0.0",
"lodash": "~4.17.0",
"mkdirp": "~1.0.0",
"yargs": "~16.2.0"
},
"devDependencies": {
"@types/chai": "4.2.15",
"@types/chai-as-promised": "7.1.3",
"@types/lodash": "4.14.168",
"@types/mkdirp": "1.0.1",
"@types/mocha": "8.2.1",
"@types/proxyquire": "1.3.28",
Expand Down
9 changes: 4 additions & 5 deletions src/operations/extensions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash'
import { MigrationOptions } from '../types'
import { CreateExtension, DropExtension } from './extensionsTypes'

Expand All @@ -7,10 +6,10 @@ export { CreateExtension, DropExtension }
export function dropExtension(mOptions: MigrationOptions) {
const _drop: DropExtension = (_extensions, options = {}) => {
const { ifExists, cascade } = options
const extensions = _.isArray(_extensions) ? _extensions : [_extensions]
const extensions = Array.isArray(_extensions) ? _extensions : [_extensions]
const ifExistsStr = ifExists ? ' IF EXISTS' : ''
const cascadeStr = cascade ? ' CASCADE' : ''
return _.map(extensions, (extension) => {
return extensions.map((extension) => {
const extensionStr = mOptions.literal(extension)
return `DROP EXTENSION${ifExistsStr} ${extensionStr}${cascadeStr};`
})
Expand All @@ -21,10 +20,10 @@ export function dropExtension(mOptions: MigrationOptions) {
export function createExtension(mOptions: MigrationOptions) {
const _create: CreateExtension = (_extensions, options = {}) => {
const { ifNotExists, schema } = options
const extensions = _.isArray(_extensions) ? _extensions : [_extensions]
const extensions = Array.isArray(_extensions) ? _extensions : [_extensions]
const ifNotExistsStr = ifNotExists ? ' IF NOT EXISTS' : ''
const schemaStr = schema ? ` SCHEMA ${mOptions.literal(schema)}` : ''
return _.map(extensions, (extension) => {
return extensions.map((extension) => {
const extensionStr = mOptions.literal(extension)
return `CREATE EXTENSION${ifNotExistsStr} ${extensionStr}${schemaStr};`
})
Expand Down
7 changes: 3 additions & 4 deletions src/operations/indexes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash'
import { MigrationOptions, Literal } from '../types'
import { Name } from './generalTypes'
import { DropIndex, CreateIndex, CreateIndexOptions, DropIndexOptions, IndexColumn } from './indexesTypes'
Expand Down Expand Up @@ -51,7 +50,7 @@ function generateColumnsString(columns: (string | IndexColumn)[], mOptions: Migr
export function dropIndex(mOptions: MigrationOptions) {
const _drop: DropIndex = (tableName, rawColumns, options = {}) => {
const { concurrently, ifExists, cascade } = options
const columns = _.isArray(rawColumns) ? rawColumns.slice() : [rawColumns]
const columns = Array.isArray(rawColumns) ? rawColumns.slice() : [rawColumns]
const concurrentlyStr = concurrently ? ' CONCURRENTLY' : ''
const ifExistsStr = ifExists ? ' IF EXISTS' : ''
const indexName = generateIndexName(tableName, columns, options, mOptions.schemalize)
Expand All @@ -76,7 +75,7 @@ export function createIndex(mOptions: MigrationOptions) {
ifNotExists - optionally create index
options.method - [ btree | hash | gist | spgist | gin ]
*/
const columns = _.isArray(rawColumns) ? rawColumns.slice() : [rawColumns]
const columns = Array.isArray(rawColumns) ? rawColumns.slice() : [rawColumns]
if (options.opclass) {
mOptions.logger.warn(
"Using opclass is deprecated. You should use it as part of column definition e.g. pgm.createIndex('table', [['column', 'opclass', 'ASC']])",
Expand Down Expand Up @@ -104,7 +103,7 @@ export function createIndex(mOptions: MigrationOptions) {
const method = options.method ? ` USING ${options.method}` : ''
const where = options.where ? ` WHERE ${options.where}` : ''
const include = options.include
? ` INCLUDE (${(_.isArray(options.include) ? options.include : [options.include])
? ` INCLUDE (${(Array.isArray(options.include) ? options.include : [options.include])
.map(mOptions.literal)
.join(', ')})`
: ''
Expand Down
7 changes: 3 additions & 4 deletions src/operations/roles.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { isArray } from 'lodash'
import { MigrationOptions } from '../types'
import { escapeValue } from '../utils'
import { CreateRole, DropRole, AlterRole, RenameRole, RoleOptions } from './rolesTypes'
Expand Down Expand Up @@ -40,15 +39,15 @@ const formatRoleOptions = (roleOptions: RoleOptions = {}) => {
options.push(`VALID UNTIL ${valid}`)
}
if (roleOptions.inRole) {
const inRole = isArray(roleOptions.inRole) ? roleOptions.inRole.join(',') : roleOptions.inRole
const inRole = Array.isArray(roleOptions.inRole) ? roleOptions.inRole.join(',') : roleOptions.inRole
options.push(`IN ROLE ${inRole}`)
}
if (roleOptions.role) {
const role = isArray(roleOptions.role) ? roleOptions.role.join(',') : roleOptions.role
const role = Array.isArray(roleOptions.role) ? roleOptions.role.join(',') : roleOptions.role
options.push(`ROLE ${role}`)
}
if (roleOptions.admin) {
const admin = isArray(roleOptions.admin) ? roleOptions.admin.join(',') : roleOptions.admin
const admin = Array.isArray(roleOptions.admin) ? roleOptions.admin.join(',') : roleOptions.admin
options.push(`ADMIN ${admin}`)
}

Expand Down
67 changes: 37 additions & 30 deletions src/operations/tables.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import _ from 'lodash'
import { MigrationOptions, Literal } from '../types'
import { applyType, applyTypeAdapters, makeComment, escapeValue, formatLines } from '../utils'
import { applyType, applyTypeAdapters, escapeValue, formatLines, intersection, makeComment } from '../utils'
import { parseSequenceOptions } from './sequences'
import {
CreateTable,
Expand All @@ -22,6 +21,7 @@ import {
ColumnDefinitions,
} from './tablesTypes'
import { Name } from './generalTypes'
import { FunctionParamType } from './functionsTypes'

export {
CreateTable,
Expand Down Expand Up @@ -70,32 +70,39 @@ const parseColumns = (
comments: string[]
} => {
const extendingTypeShorthands = mOptions.typeShorthands
let columnsWithOptions = _.mapValues(columns, (column) => applyType(column, extendingTypeShorthands))
let columnsWithOptions = Object.keys(columns).reduce<{
[x: string]: ColumnDefinition & FunctionParamType
}>((previous, column) => ({ ...previous, [column]: applyType(columns[column], extendingTypeShorthands) }), {})

const primaryColumns = _.chain(columnsWithOptions)
.map((options: ColumnDefinition, columnName) => (options.primaryKey ? columnName : null))
.filter((columnName): columnName is string => Boolean(columnName))
.value()
const primaryColumns = Object.entries(columnsWithOptions)
.filter(([, { primaryKey }]) => Boolean(primaryKey))
.map(([columnName]) => columnName)
const multiplePrimaryColumns = primaryColumns.length > 1

if (multiplePrimaryColumns) {
columnsWithOptions = _.mapValues(columnsWithOptions, (options) => ({
...options,
primaryKey: false,
}))
columnsWithOptions = Object.entries(columnsWithOptions).reduce(
(previous, [columnName, options]) => ({
...previous,
[columnName]: {
...options,
primaryKey: false,
},
}),
{},
)
}

const comments = _.chain(columnsWithOptions)
.map(
(options: ColumnDefinition, columnName) =>
typeof options.comment !== 'undefined' &&
makeComment('COLUMN', `${mOptions.literal(tableName)}.${mOptions.literal(columnName)}`, options.comment),
)
const comments = Object.entries(columnsWithOptions)
.map(([columnName, { comment }]) => {
return (
typeof comment !== 'undefined' &&
makeComment('COLUMN', `${mOptions.literal(tableName)}.${mOptions.literal(columnName)}`, comment)
)
})
.filter((comment): comment is string => Boolean(comment))
.value()

return {
columns: _.map(columnsWithOptions, (options: ColumnDefinition, columnName) => {
columns: Object.entries(columnsWithOptions).map(([columnName, options]) => {
const {
type,
collation,
Expand Down Expand Up @@ -174,7 +181,7 @@ const parseConstraints = (table: Name, options: ConstraintOptions, optionName: s
let constraints = []
const comments = []
if (check) {
if (_.isArray(check)) {
if (Array.isArray(check)) {
check.forEach((ch, i) => {
const name = literal(optionName || `${tableName}_chck_${i + 1}`)
constraints.push(`CONSTRAINT ${name} CHECK (${ch})`)
Expand All @@ -185,23 +192,23 @@ const parseConstraints = (table: Name, options: ConstraintOptions, optionName: s
}
}
if (unique) {
const uniqueArray: Array<Name | Name[]> = _.isArray(unique) ? unique : [unique]
const isArrayOfArrays = uniqueArray.some((uniqueSet) => _.isArray(uniqueSet))
const uniqueArray: Array<Name | Name[]> = Array.isArray(unique) ? unique : [unique]
const isArrayOfArrays = uniqueArray.some((uniqueSet) => Array.isArray(uniqueSet))
;((isArrayOfArrays ? uniqueArray : [uniqueArray]) as Array<Name | Name[]>).forEach((uniqueSet) => {
const cols = _.isArray(uniqueSet) ? uniqueSet : [uniqueSet]
const cols = Array.isArray(uniqueSet) ? uniqueSet : [uniqueSet]
const name = literal(optionName || `${tableName}_uniq_${cols.join('_')}`)
constraints.push(`CONSTRAINT ${name} UNIQUE (${cols.map(literal).join(', ')})`)
})
}
if (primaryKey) {
const name = literal(optionName || `${tableName}_pkey`)
const key = (_.isArray(primaryKey) ? primaryKey : [primaryKey]).map(literal).join(', ')
const key = (Array.isArray(primaryKey) ? primaryKey : [primaryKey]).map(literal).join(', ')
constraints.push(`CONSTRAINT ${name} PRIMARY KEY (${key})`)
}
if (foreignKeys) {
;(_.isArray(foreignKeys) ? foreignKeys : [foreignKeys]).forEach((fk) => {
;(Array.isArray(foreignKeys) ? foreignKeys : [foreignKeys]).forEach((fk) => {
const { columns, referencesConstraintName, referencesConstraintComment } = fk
const cols = _.isArray(columns) ? columns : [columns]
const cols = Array.isArray(columns) ? columns : [columns]
const name = literal(referencesConstraintName || optionName || `${tableName}_fk_${cols.join('_')}`)
const key = cols.map(literal).join(', ')
const referencesStr = parseReferences(fk, literal)
Expand Down Expand Up @@ -231,7 +238,7 @@ const parseConstraints = (table: Name, options: ConstraintOptions, optionName: s

const parseLike = (like: Name | { table: Name; options?: LikeOptions }, literal: Literal) => {
const formatOptions = (name: 'INCLUDING' | 'EXCLUDING', options?: Like | Like[]) =>
(_.isArray(options) ? options : [options])
(Array.isArray(options) ? options : [options])
.filter((option): option is Like => option !== undefined)
.map((option) => ` ${name} ${option}`)
.join('')
Expand Down Expand Up @@ -266,7 +273,7 @@ export function createTable(mOptions: MigrationOptions) {
columns,
mOptions,
)
const dupes = _.intersection(Object.keys(optionsConstraints), Object.keys(crossColumnConstraints))
const dupes = intersection(Object.keys(optionsConstraints), Object.keys(crossColumnConstraints))
if (dupes.length > 0) {
const dupesStr = dupes.join(', ')
throw new Error(`There is duplicate constraint definition in table and columns options: ${dupesStr}`)
Expand Down Expand Up @@ -321,8 +328,8 @@ export function dropColumns(mOptions: MigrationOptions) {
const { ifExists, cascade } = options
if (typeof columns === 'string') {
columns = [columns] // eslint-disable-line no-param-reassign
} else if (!_.isArray(columns) && typeof columns === 'object') {
columns = _.keys(columns) // eslint-disable-line no-param-reassign
} else if (!Array.isArray(columns) && typeof columns === 'object') {
columns = Object.keys(columns) // eslint-disable-line no-param-reassign
}
const columnsStr = formatLines(
columns.map(mOptions.literal),
Expand Down
3 changes: 1 addition & 2 deletions src/operations/triggers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { isArray } from 'lodash'
import { MigrationOptions } from '../types'
import { escapeValue } from '../utils'
import { createFunction, dropFunction } from './functions'
Expand Down Expand Up @@ -29,7 +28,7 @@ export function createTrigger(mOptions: MigrationOptions) {
) => {
const { constraint, condition, operation, deferrable, deferred, functionParams = [] } = triggerOptions
let { when, level = 'STATEMENT', function: functionName } = triggerOptions
const operations = isArray(operation) ? operation.join(' OR ') : operation
const operations = Array.isArray(operation) ? operation.join(' OR ') : operation
if (constraint) {
when = 'AFTER'
}
Expand Down
13 changes: 7 additions & 6 deletions src/operations/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash'
import { MigrationOptions } from '../types'
import { applyType, escapeValue } from '../utils'
import {
Expand Down Expand Up @@ -38,15 +37,17 @@ export function dropType(mOptions: MigrationOptions) {

export function createType(mOptions: MigrationOptions) {
const _create: CreateType = (typeName, options) => {
if (_.isArray(options)) {
if (Array.isArray(options)) {
const optionsStr = options.map(escapeValue).join(', ')
const typeNameStr = mOptions.literal(typeName)
return `CREATE TYPE ${typeNameStr} AS ENUM (${optionsStr});`
}
const attributes = _.map(options, (attribute, attributeName) => {
const typeStr = applyType(attribute, mOptions.typeShorthands).type
return `${mOptions.literal(attributeName)} ${typeStr}`
}).join(',\n')
const attributes = Object.entries(options)
.map(([attributeName, attribute]) => {
const typeStr = applyType(attribute, mOptions.typeShorthands).type
return `${mOptions.literal(attributeName)} ${typeStr}`
})
.join(',\n')
return `CREATE TYPE ${mOptions.literal(typeName)} AS (\n${attributes}\n);`
}
_create.reverse = dropType(mOptions)
Expand Down
4 changes: 4 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,7 @@ export const formatLines = (lines: string[], replace = ' ', separator = ',') =>
.map((line) => line.replace(/(?:\r\n|\r|\n)+/g, ' '))
.join(`${separator}\n`)
.replace(/^/gm, replace)

export function intersection<T>(list1: T[], list2: T[]): T[] {
return list1.filter((element) => list2.includes(element))
}
2 changes: 1 addition & 1 deletion tsconfig-test.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"moduleResolution": "node",
"baseUrl": "src",
"outDir": "dist",
"lib": ["es2018"],
"lib": ["es2019"],
"esModuleInterop": true,
"sourceMap": false,
"forceConsistentCasingInFileNames": true,
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"moduleResolution": "node",
"rootDir": "src",
"outDir": "dist",
"lib": ["es2018"],
"lib": ["es2019"],
"esModuleInterop": true,
"sourceMap": false,
"forceConsistentCasingInFileNames": true,
Expand Down

0 comments on commit 4e3e892

Please sign in to comment.