Skip to content

Commit

Permalink
Merge pull request #309 from kellnerd/ts-migration
Browse files Browse the repository at this point in the history
TypeScript migration
  • Loading branch information
MonkeyDo committed Oct 18, 2023
2 parents 72db721 + d0c9658 commit 014034f
Show file tree
Hide file tree
Showing 114 changed files with 794 additions and 353 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
},
"homepage": "https://github.com/bookbrainz/bookbrainz-data-js",
"dependencies": {
"@metabrainz/bookshelf": "^1.3.1",
"@metabrainz/bookshelf": "^1.4.0",
"bookshelf-virtuals-plugin": "^1.0.0",
"deep-diff": "^1.0.2",
"immutable": "^3.8.2",
Expand All @@ -83,6 +83,7 @@
"@babel/register": "^7.13.16",
"@types/lodash": "^4.14.168",
"@types/node": "^18.11.18",
"@types/pg": "^8.6.0",
"@typescript-eslint/eslint-plugin": "^5.48.2",
"@typescript-eslint/parser": "^5.48.2",
"babel-plugin-lodash": "^3.3.4",
Expand Down
20 changes: 9 additions & 11 deletions src/func/alias.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,25 @@
*/

import * as _ from 'lodash';
import type {
FormAliasT as Alias,
FormAliasWithDefaultT as AliasWithDefault,
Transaction
} from './types';
import type {AliasWithDefaultT, NewOrExistingAliasT} from '../types/aliases';
import {
createNewSetWithItems,
getAddedItems,
getRemovedItems,
getUnchangedItems
} from './set';
import type {EntityTypeString} from '../types/entity';
import type {ORM} from '..';
import type {Transaction} from './types';
import {snakeToCamel} from '../util';


export async function updateAliasSet(
orm: any, transacting: Transaction, oldSet: any,
orm: ORM, transacting: Transaction, oldSet: any,
oldDefaultAliasId: number | null | undefined,
newSetItemsWithDefault: Array<AliasWithDefault>
newSetItemsWithDefault: Array<AliasWithDefaultT>
) {
function comparisonFunc(obj: Alias, other: Alias) {
function comparisonFunc(obj: NewOrExistingAliasT, other: NewOrExistingAliasT) {
return (
obj.name === other.name &&
obj.sortName === other.sortName &&
Expand All @@ -49,10 +47,10 @@ export async function updateAliasSet(

const {AliasSet} = orm;

const newSetItems: Array<Alias> =
const newSetItems: Array<NewOrExistingAliasT> =
newSetItemsWithDefault.map((item) => _.omit(item, 'default'));

const oldSetItems: Array<Alias> =
const oldSetItems: Array<NewOrExistingAliasT> =
oldSet ? oldSet.related('aliases').toJSON() : [];

if (_.isEmpty(oldSetItems) && _.isEmpty(newSetItems)) {
Expand Down Expand Up @@ -161,7 +159,7 @@ export async function getBBIDsWithMatchingAlias(
const aliasIds = _.map(
await getAliasIds(transacting, name, caseSensitive),
'id'
) as Array<string|number>;
) as Array<string | number>;

const aliasSetIds = _.map(
await transacting.distinct('set_id')
Expand Down
5 changes: 3 additions & 2 deletions src/func/annotation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,20 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

import type {ORM} from '..';
import type {Transaction} from './types';


/**
* @param {Object} orm - Bookbrainz orm wrapper holding all models
* @param {ORM} orm - Bookbrainz orm wrapper holding all models
* @param {Transaction} transacting - The present knex transacting object
* @param {Object} oldAnnotation - The old annotation object
* @param {string} newContent - New annotation to be set
* @param {Object} revision - The present revision object
* @returns {Promise<Object>} - Returns Annotation object
*/
export function updateAnnotation(
orm: any, transacting: Transaction, oldAnnotation: any,
orm: ORM, transacting: Transaction, oldAnnotation: any,
newContent: string, revision: any
) {
const {Annotation} = orm;
Expand Down
19 changes: 15 additions & 4 deletions src/func/area.js → src/func/area.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import type Bookshelf from '@metabrainz/bookshelf';
import type {ORM} from '..';
import type {QueryResult} from 'pg';

/**
* Recursively fetches an area's parents (with "has part" link)
* Adapted from https://github.com/metabrainz/musicbrainz-server/blob/f79b6d0d2d4bd67254cc34426f17cf8eb21ec5bb/lib/MusicBrainz/Server/Data/Utils.pm#L255-L273
* @param {object} orm - the BookBrainz ORM, initialized during app setup
* @param {string} areaId - The entity model name.
* @param {object} orm - the BookBrainz ORM, initialized during app setup, or a Bookshelf instance
* @param {string} areaId - The BBID (= MBID) of the area
* @param {boolean} checkAllLevels - By default limits to the area types Country, Subdivision and City
* @returns {Promise} The returned Promise returns the entity's
* parent default alias
*/
export async function recursivelyGetAreaParentsWithNames(orm, areaId, checkAllLevels = false) {
export async function recursivelyGetAreaParentsWithNames(orm: ORM | Bookshelf, areaId: string, checkAllLevels = false) {
const levelsCondition = checkAllLevels ? '' :
'WHERE area.type IN (1, 2, 3)';
const rawSql = `
Expand All @@ -30,9 +33,17 @@ export async function recursivelyGetAreaParentsWithNames(orm, areaId, checkAllLe
`;

// Query the database to get the area parents recursively
const queryResult = await (orm.bookshelf || orm).knex.raw(rawSql);
const knex = 'bookshelf' in orm ? orm.bookshelf.knex : orm.knex;
const queryResult = await knex.raw<QueryResult<AreaDescendantRow>>(rawSql);
if (!Array.isArray(queryResult.rows)) {
return [];
}
return queryResult.rows;
}

type AreaDescendantRow = {
descendant: string;
parent: string;
depth: number;
name: string;
};
33 changes: 21 additions & 12 deletions src/func/author-credit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@

import * as _ from 'lodash';
import type {AuthorCreditNameT, Transaction} from './types';
import type Bookshelf from '@metabrainz/bookshelf';
import type {ORM} from '..';
import type {QueryResult} from 'pg';


function findAuthorCredit(
orm: any, transacting: Transaction, authorCredit: Array<AuthorCreditNameT>
orm: ORM, transacting: Transaction, authorCredit: Array<AuthorCreditNameT>
) {
const tables = {cc: 'bookbrainz.author_credit'};

Expand Down Expand Up @@ -58,16 +61,17 @@ function findAuthorCredit(


export async function fetchOrCreateCredit(
orm: any, transacting: Transaction, authorCredit: Array<AuthorCreditNameT>
orm: ORM, transacting: Transaction, authorCredit: Array<AuthorCreditNameT>
) {
const {AuthorCredit} = orm;
const result = await findAuthorCredit(orm, transacting, authorCredit);

if (result) {
return orm.AuthorCredit.forge({id: result.id})
.fetch({transacting, withRelated: 'names'});
return new AuthorCredit({id: result.id})
.fetch({transacting, withRelated: ['names']});
}

const newCredit = await new orm.AuthorCredit(
const newCredit = await new AuthorCredit(
{authorCount: authorCredit.length}
).save(null, {transacting});

Expand All @@ -88,7 +92,7 @@ export async function fetchOrCreateCredit(
}

export function updateAuthorCredit(
orm: any, transacting: Transaction, oldCredit: any,
orm: ORM, transacting: Transaction, oldCredit: any,
newCreditNames: Array<AuthorCreditNameT>
): Promise<any> {
/* eslint-disable consistent-return */
Expand Down Expand Up @@ -122,13 +126,13 @@ export function updateAuthorCredit(

/**
* Fetches all the Edition entities credited to an Author (with Author Credits)
* @param {object} bookshelf - the BookBrainz ORM, initialized during app setup
* @param {Bookshelf} bookshelf - the Bookshelf instance, initialized during app setup
* @param {string} authorBBID - The target Author's BBID.
* @returns {Promise} The returned Promise returns the Edition BBID and default alias
*/

export async function getEditionsCreditedToAuthor(
bookshelf: any, authorBBID: string
bookshelf: Bookshelf, authorBBID: string
) {
const rawSql = ` SELECT e.bbid , alias."name" from bookbrainz.author
LEFT JOIN bookbrainz.author_credit_name acn on acn.author_bbid = author.bbid
Expand All @@ -140,7 +144,7 @@ export async function getEditionsCreditedToAuthor(
AND e.master = true
AND e.data_id is not null
`;
let queryResult;
let queryResult: QueryResult<AliasAndBBIDRow>;
try {
queryResult = await bookshelf.knex.raw(rawSql);
}
Expand All @@ -156,13 +160,13 @@ export async function getEditionsCreditedToAuthor(

/**
* Fetches all the Edition Group entities credited to an Author (with Author Credits)
* @param {object} bookshelf - the BookBrainz ORM, initialized during app setup
* @param {Bookshelf} bookshelf - the Bookshelf instance, initialized during app setup
* @param {string} authorBBID - The target Author's BBID.
* @returns {Promise} The returned Promise returns the Edition Group BBID and default alias
*/

export async function getEditionGroupsCreditedToAuthor(
bookshelf: any, authorBBID: string
bookshelf: Bookshelf, authorBBID: string
) {
const rawSql = ` SELECT eg.bbid , alias."name" from bookbrainz.author
LEFT JOIN bookbrainz.author_credit_name acn on acn.author_bbid = author.bbid
Expand All @@ -174,7 +178,7 @@ export async function getEditionGroupsCreditedToAuthor(
AND eg.master = true
AND eg.data_id is not null
`;
let queryResult;
let queryResult: QueryResult<AliasAndBBIDRow>;
try {
queryResult = await bookshelf.knex.raw(rawSql);
}
Expand All @@ -187,3 +191,8 @@ export async function getEditionGroupsCreditedToAuthor(
}
return queryResult.rows;
}

type AliasAndBBIDRow = {
name: string;
bbid: string;
};
24 changes: 13 additions & 11 deletions src/func/create-entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@
*/

import * as _ from 'lodash';
import type {
FormAliasWithDefaultT as AliasWithDefault, FormIdentifierT as Identifier,
Transaction
} from './types';
import {
getAdditionalEntityProps, getEntityModelByType, getEntitySetMetadataByType
} from './entity';
import type {AliasWithDefaultT} from '../types/aliases';
import type {EntityTypeString} from '../types/entity';
import type {IdentifierT} from '../types/identifiers';
import type {ORM} from '..';
import type {Transaction} from './types';
import {createNote} from './note';
import {incrementEditorEditCountById} from './editor';
import {updateAliasSet} from './alias';
Expand All @@ -37,26 +38,27 @@ import {updateIdentifierSet} from './identifier';


interface EntityDataType {
aliases: Array<AliasWithDefault>,
aliases: Array<AliasWithDefaultT>,
annotation: string,
disambiguation: string,
identifiers: Array<Identifier>,
identifiers: Array<IdentifierT>,
note: string,
type: string
type: EntityTypeString
}

interface ExtraEntityDataType extends EntityDataType {
[propName: string]: any;
}

interface CreateEntityPropsType {
orm: any,
orm: ORM,
transacting: Transaction,
editorId: string,
entityData: ExtraEntityDataType,
entityType: string
entityType: EntityTypeString
}

// TODO: function seems to be unused across all BB repos, ignore its errors (and delete it?)
export async function createEntity({
editorId, entityData, orm, transacting
}: CreateEntityPropsType) {
Expand Down Expand Up @@ -129,9 +131,9 @@ export async function createEntity({
revisionId: revisionRecord && revisionRecord.get('id')
}, entitySets, additionalProps);

const model = getEntityModelByType(orm, entityType);
const Model = getEntityModelByType(orm, entityType);

const entityModel = await model.forge(propsToSet)
const entityModel = await new Model(propsToSet)
.save(null, {
method: 'insert',
transacting
Expand Down
5 changes: 3 additions & 2 deletions src/func/disambiguation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,19 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

import type {ORM} from '..';
import type {Transaction} from './types';


/**
* @param {Object} orm - The BookBrainz orm wrapper containing all models
* @param {ORM} orm - The BookBrainz orm wrapper containing all models
* @param {Transaction} transacting - The current knex transaction object
* @param {Object} oldDisambiguation - The previous disambiguation object
* @param {string} newComment - The new disambiguation string
* @returns {Promise<Object>} - Returns Promise holding Disambiguation object
*/
export function updateDisambiguation(
orm: any, transacting: Transaction, oldDisambiguation: any,
orm: ORM, transacting: Transaction, oldDisambiguation: any,
newComment: string
) {
const {Disambiguation} = orm;
Expand Down
5 changes: 3 additions & 2 deletions src/func/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,20 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

import {ORM} from '..';
import type {Transaction} from './types';

/**
* Adds 1 to the edit count of the specified editor
*
* @param {object} orm - the BookBrainz ORM, initialized during app setup
* @param {ORM} orm - the BookBrainz ORM, initialized during app setup
* @param {string} id - row ID of editor to be updated
* @param {Transaction} transacting - Bookshelf transaction object (must be in
* progress)
* @returns {Promise} - Resolves to the updated editor model
*/
export function incrementEditorEditCountById(
orm: any,
orm: ORM,
id: string,
transacting: Transaction
): Promise<any> {
Expand Down
9 changes: 6 additions & 3 deletions src/func/entity-sets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ import {
createNewSetWithItems, getAddedItems, getComparisonFunc, getRemovedItems,
getUnchangedItems
} from './set';
import type {EntitySetMetadataT} from './entity';
import type {ORM} from '..';


function updateEntitySet<Item extends SetItemT>(
transacting: Transaction, oldSet: any, newItems: Array<Item>,
derivedSet: any, orm: Record<string, unknown>
derivedSet: EntitySetMetadataT, orm: ORM
): Promise<any> {
const oldItems =
oldSet ? oldSet.related(derivedSet.propName).toJSON() : [];
Expand Down Expand Up @@ -61,8 +63,8 @@ function updateEntitySet<Item extends SetItemT>(


export async function updateEntitySets(
derivedSets: Array<any> | null | undefined, currentEntity: any,
entityData: any, transacting: Transaction, orm: Record<string, unknown>
derivedSets: EntitySetMetadataT[] | null | undefined, currentEntity: any,
entityData: any, transacting: Transaction, orm: ORM
): Promise<Record<string, unknown> | null | undefined> {
// If no entity sets, return null
if (!derivedSets) {
Expand All @@ -77,6 +79,7 @@ export async function updateEntitySets(
return Promise.resolve(null);
}

// TODO: Find out why we expect a non-existing `model` property here!?
const oldSetRecord = await derivedSet.model.forge({
id: currentEntity[derivedSet.name].id
}).fetch({
Expand Down
Loading

0 comments on commit 014034f

Please sign in to comment.