diff --git a/src/types/preprint-id.ts b/src/types/preprint-id.ts index 5755f241a..ffef8ed77 100644 --- a/src/types/preprint-id.ts +++ b/src/types/preprint-id.ts @@ -305,6 +305,7 @@ export function fromUrl(url: URL): Option.Option { .with(['biorxiv.org', P.select()], extractFromBiorxivMedrxivPath('biorxiv')) .with(['edarxiv.org', P.select()], extractFromEdarxivPath) .with(['engrxiv.org', P.select()], extractFromEngrxivPath) + .with(['jxiv.jst.go.jp', P.select()], extractFromJxivPath) .with(['medrxiv.org', P.select()], extractFromBiorxivMedrxivPath('medrxiv')) .with(['osf.io', P.select()], extractFromOsfPath) .with(['philsci-archive.pitt.edu', P.select()], extractFromPhilsciPath) @@ -363,6 +364,12 @@ const extractFromFigsharePath = (type: 'africarxiv') => Option.andThen(doi => ({ type, value: doi }) satisfies AfricarxivFigsharePreprintId), ) +const extractFromJxivPath = flow( + decodeURIComponent, + Option.liftNullable(s => /^index\.php\/jxiv\/preprint\/(?:view|download)\/([1-9][0-9]*)(?:\/|$)/.exec(s)?.[1]), + Option.andThen(flow(id => `10.51094/jxiv.${id}`, parsePreprintDoi)), +) + const extractFromOsfPath = flow( decodeURIComponent, Option.liftNullable(s => diff --git a/test/fc.ts b/test/fc.ts index b8d1049e3..cec2f3323 100644 --- a/test/fc.ts +++ b/test/fc.ts @@ -450,6 +450,7 @@ export const supportedPreprintUrl = (): fc.Arbitrary<[URL, PreprintId]> => biorxivPreprintUrl(), edarxivPreprintUrl(), engrxivPreprintUrl(), + jxivPreprintUrl(), medrxivPreprintUrl(), metaarxivPreprintUrl(), osfPreprintsPreprintUrl(), @@ -653,6 +654,14 @@ export const jxivPreprintId = (): fc.Arbitrary => value: doi(constant('51094')), }) +export const jxivPreprintUrl = (): fc.Arbitrary<[URL, JxivPreprintId]> => + fc + .integer({ min: 1 }) + .map(id => [ + new URL(`https://jxiv.jst.go.jp/index.php/jxiv/preprint/view/${id}`), + { type: 'jxiv', value: `10.51094/jxiv.${id}` as Doi<'51094'> }, + ]) + export const medrxivPreprintId = (): fc.Arbitrary => fc.record({ type: constant('medrxiv'), diff --git a/test/types/preprint-id.test.ts b/test/types/preprint-id.test.ts index de109633f..24f265d95 100644 --- a/test/types/preprint-id.test.ts +++ b/test/types/preprint-id.test.ts @@ -328,6 +328,31 @@ describe('fromUrl', () => { expect(_.fromUrl(url)).toStrictEqual(Option.some({ type: 'engrxiv', value: doi })) }) + test.prop([fc.jxivPreprintUrl().map(([url, id]) => [url, id.value] as const)], { + examples: [ + [ + [ + new URL('https://jxiv.jst.go.jp/index.php/jxiv/preprint/view/1041/version/1215'), // version + Doi('10.51094/jxiv.1041'), + ], + ], + [ + [ + new URL('https://jxiv.jst.go.jp/index.php/jxiv/preprint/view/1041/2898'), // html view of pdf + Doi('10.51094/jxiv.1041'), + ], + ], + [ + [ + new URL('https://jxiv.jst.go.jp/index.php/jxiv/preprint/download/1041/2898'), // pdf + Doi('10.51094/jxiv.1041'), + ], + ], + ], + })('with a Jxiv URL', ([url, doi]) => { + expect(_.fromUrl(url)).toStrictEqual(Option.some({ type: 'jxiv', value: doi })) + }) + test.prop([fc.medrxivPreprintUrl().map(([url, id]) => [url, id.value] as const)], { examples: [ [