diff --git a/ts/bindings/jsonld.ts b/ts/bindings/jsonld.ts index 9db79f16..07547b4d 100644 --- a/ts/bindings/jsonld.ts +++ b/ts/bindings/jsonld.ts @@ -11,23 +11,9 @@ import fs from 'fs-extra' import fromEntries from 'object.fromentries' import path from 'path' import { readSchemas } from '../helpers' +import { jsonLdUrl } from '../util' -/** - * Get the Schema major version for use in generated URLs - */ -const VERSION_MAJOR = fs - .readJSONSync(path.join(__dirname, '..', '..', 'package.json')) - .version.split('.')[0] - -/** - * The base URL for the Stencila JSON-LD context. - * - * This gets prefixed to all keys during JSON-LD expansion - * so the trailing slash is important so that for e.g. - * `CodeChunk` gets expanded to `http://schema.stenci.la/v0/jsonld/CodeChunk` - * (which in gets redirected to `https://unpkg.com/@stencila/schema@0.32.1/dist/CodeChunk.jsonld`) - */ -const STENCILA_CONTEXT_URL = `http://schema.stenci.la/v${VERSION_MAJOR}/jsonld/` +const STENCILA_CONTEXT_URL = jsonLdUrl() /** * The destination directory for generated JSON-LD files diff --git a/ts/schema.ts b/ts/schema.ts index 4147f1d5..7da80c20 100644 --- a/ts/schema.ts +++ b/ts/schema.ts @@ -13,22 +13,16 @@ import cloneDeep from 'lodash.clonedeep' import path from 'path' import log from './log' import Schema from './schema-interface' +import { versionMajor } from './util/version' const SCHEMA_SOURCE_DIR = path.join(__dirname, '..', 'schema') const SCHEMA_DEST_DIR = path.join(__dirname, '..', 'public') -/** - * Get the Schema major version for use in generated URLs - */ -const VERSION_MAJOR = fs - .readJSONSync(path.join(__dirname, '..', 'package.json')) - .version.split('.')[0] - /** * The base URL for JSON Schema `$id`s. */ const SCHEMA_DEST_URL = 'https://schema.stenci.la' -const ID_BASE_URL = `${SCHEMA_DEST_URL}/v${VERSION_MAJOR}` +const ID_BASE_URL = `${SCHEMA_DEST_URL}/v${versionMajor()}` /** * The base URL for source files. diff --git a/ts/util/index.ts b/ts/util/index.ts index 4da96ecf..44463d9f 100644 --- a/ts/util/index.ts +++ b/ts/util/index.ts @@ -2,3 +2,5 @@ export * from './guards' export * from './node-type' export * from './type-map' export * from './type-maps' +export * from './urls' +export * from './version' diff --git a/ts/util/urls.test.ts b/ts/util/urls.test.ts new file mode 100644 index 00000000..f30c743e --- /dev/null +++ b/ts/util/urls.test.ts @@ -0,0 +1,11 @@ +import pkg from '../../package.json' +import { jsonLdUrl } from './urls' + +test('jsonLdUrl', () => { + const expectedBase = `http://schema.stenci.la/v${ + pkg.version.split('.')[0] + }/jsonld/` + expect(jsonLdUrl()).toMatch(expectedBase) + expect(jsonLdUrl('CodeChunk')).toMatch(expectedBase + 'CodeChunk') + expect(jsonLdUrl('outputs')).toMatch(expectedBase + 'outputs') +}) diff --git a/ts/util/urls.ts b/ts/util/urls.ts new file mode 100644 index 00000000..1217c37f --- /dev/null +++ b/ts/util/urls.ts @@ -0,0 +1,18 @@ +import { versionMajor } from './version' + +/** + * Get the URL to the JSON-LD for this schema's `@context` or + * for a specific term e.g. `CodeChunk`, `outputs`. + * + * The `@context`'s URL needs to have a trailing slash because + * it gets prefixed to all keys during JSON-LD expansion. + * e.g. the term `CodeChunk` gets expanded to `http://schema.stenci.la/v0/jsonld/CodeChunk` + * (which in gets redirected to `https://unpkg.com/@stencila/schema@0.32.1/dist/CodeChunk.jsonld`) + * + * @param term The term (type or property) to generate the + * URL for. Defaults to empty string i.e. the context. + */ +export function jsonLdUrl(term = '') { + const version = versionMajor() + return `http://schema.stenci.la/v${version}/jsonld/${term}` +} diff --git a/ts/util/version.test.ts b/ts/util/version.test.ts new file mode 100644 index 00000000..75123b1b --- /dev/null +++ b/ts/util/version.test.ts @@ -0,0 +1,19 @@ +import pkg from '../../package.json' +import { version, versionMajor, versionMinor } from './version' + +test('version', () => { + expect(version()).toEqual(pkg.version) +}) + +test('versionMajor', () => { + expect(versionMajor()).toEqual(pkg.version.split('.')[0]) +}) + +test('versionMinor', () => { + expect(versionMinor()).toEqual( + pkg.version + .split('.') + .slice(0, 2) + .join('.') + ) +}) diff --git a/ts/util/version.ts b/ts/util/version.ts new file mode 100644 index 00000000..ca438142 --- /dev/null +++ b/ts/util/version.ts @@ -0,0 +1,39 @@ +import fs from 'fs' +import path from 'path' + +/** + * Lazily read, cached, package version + */ +let VERSION: string + +/** + * Get the version string (e.g "1.2.3") for this package + */ +export function version(): string { + if (VERSION === undefined) { + const json = fs.readFileSync( + path.join(__dirname, '..', '..', 'package.json'), + 'utf8' + ) + const pkg = JSON.parse(json) + VERSION = pkg.version + } + return VERSION +} + +/** + * Get the major version string (e.g "1") for this package + */ +export function versionMajor(): string { + return version().split('.')[0] +} + +/** + * Get the minor version string (e.g "1.2") for this package + */ +export function versionMinor(): string { + return version() + .split('.') + .slice(0, 2) + .join('.') +}