diff --git a/apis/core/lib/domain/column-mapping/delete.ts b/apis/core/lib/domain/column-mapping/delete.ts index b17f166ab..535168c63 100644 --- a/apis/core/lib/domain/column-mapping/delete.ts +++ b/apis/core/lib/domain/column-mapping/delete.ts @@ -8,6 +8,8 @@ import { getDimensionMetaDataCollection } from '../queries/dimension-metadata.js import * as TableQueries from '../queries/table.js' import * as ColumnMappingQueries from '../queries/column-mapping.js' import { findOrganization } from '../organization/query.js' +import { getTableForColumnMapping } from '../queries/table.js' +import { dimensionIsUsedByOtherMapping } from '../queries/column-mapping.js' interface DeleteColumnMappingCommand { resource: NamedNode @@ -19,8 +21,6 @@ interface DeleteColumnMappingCommand { export async function deleteColumnMapping({ resource, store, - tableQueries: { getTableForColumnMapping } = TableQueries, - columnMappingQueries: { dimensionIsUsedByOtherMapping } = ColumnMappingQueries, }: DeleteColumnMappingCommand): Promise { const columnMapping = await store.getResource(resource, { allowMissing: true }) if (!columnMapping) return diff --git a/apis/core/lib/domain/column-mapping/update.ts b/apis/core/lib/domain/column-mapping/update.ts index 77746f98f..616a62921 100644 --- a/apis/core/lib/domain/column-mapping/update.ts +++ b/apis/core/lib/domain/column-mapping/update.ts @@ -17,7 +17,7 @@ import type { Organization } from '@rdfine/schema' import { Dictionary } from '@rdfine/prov' import { ResourceStore } from '../../ResourceStore.js' import { getDimensionMetaDataCollection } from '../queries/dimension-metadata.js' -import * as TableQueries from '../queries/table.js' +import { getTableForColumnMapping } from '../queries/table.js' import * as id from '../identifiers.js' import { findOrganization } from '../organization/query.js' import { findMapping } from './lib/index.js' @@ -25,18 +25,15 @@ import { findMapping } from './lib/index.js' interface UpdateColumnMappingCommand { resource: GraphPointer store: ResourceStore - tableQueries?: Pick } export async function updateLiteralColumnMapping({ resource, store, - tableQueries = TableQueries, }: UpdateColumnMappingCommand): Promise { const { columnMapping, table } = await updateColumnMapping({ resource, store, - tableQueries, }) const columnId = resource.out(cc.sourceColumn).term! @@ -63,12 +60,10 @@ export async function updateLiteralColumnMapping({ export async function updateReferenceColumnMapping({ resource, store, - tableQueries = TableQueries, }: UpdateColumnMappingCommand): Promise { const { columnMapping, table } = await updateColumnMapping({ resource, store, - tableQueries, }) // Update referencedTable @@ -106,7 +101,6 @@ export async function updateReferenceColumnMapping({ async function updateColumnMapping({ resource, store, - tableQueries: { getTableForColumnMapping } = TableQueries, }: UpdateColumnMappingCommand): Promise<{ columnMapping: T; table: Table }> { const columnMapping = await store.getResource(resource.term) diff --git a/apis/core/lib/domain/dimension/update.ts b/apis/core/lib/domain/dimension/update.ts index 57d7e8697..0273c82bd 100644 --- a/apis/core/lib/domain/dimension/update.ts +++ b/apis/core/lib/domain/dimension/update.ts @@ -2,7 +2,7 @@ import type { NamedNode, Quad, Term } from '@rdfjs/types' import type { GraphPointer } from 'clownface' import $rdf from '@cube-creator/env' import { DimensionMetadataCollection, Project } from '@cube-creator/model' -import { createNoMeasureDimensionError, Error } from '@cube-creator/model/DimensionMetadata' +import { noMeasureDimensionError, Error } from '@cube-creator/model/DimensionMetadata' import { prov, rdf, schema } from '@tpluscode/rdf-ns-builders' import { cc } from '@cube-creator/core/namespace' import { ResourceStore } from '../../ResourceStore.js' @@ -59,7 +59,7 @@ export async function update({ } if (!metadata.hasPart.some(dim => dim.isMeasureDimension)) { - metadata.addError?.(createNoMeasureDimensionError($rdf)) + metadata.addError?.($rdf.rdfine.schema.Thing(noMeasureDimensionError)) } else { metadata.removeError?.(Error.MissingMeasureDimension) } diff --git a/apis/core/lib/domain/queries/dimension-metadata.ts b/apis/core/lib/domain/queries/dimension-metadata.ts index ba6954051..4bab2568b 100644 --- a/apis/core/lib/domain/queries/dimension-metadata.ts +++ b/apis/core/lib/domain/queries/dimension-metadata.ts @@ -38,10 +38,10 @@ export async function getDimensionMetaDataCollection(csvMapping: Term, client = ` .execute(client) if (results.length < 1) { - throw new Error(`No DimensionMetadata for table ${csvMapping} found`) + throw new Error(`No DimensionMetadata for table ${csvMapping.value} found`) } if (results.length > 1) { - throw new Error(`More than one DimensionMetadata for table ${csvMapping} found`) + throw new Error(`More than one DimensionMetadata for table ${csvMapping.value} found`) } return results[0].dimensionMetadata } diff --git a/apis/core/lib/domain/table/delete.ts b/apis/core/lib/domain/table/delete.ts index f8a6ce87a..c8f3aec71 100644 --- a/apis/core/lib/domain/table/delete.ts +++ b/apis/core/lib/domain/table/delete.ts @@ -1,22 +1,17 @@ import type { NamedNode } from '@rdfjs/types' import { cc } from '@cube-creator/core/namespace' import { ResourceStore } from '../../ResourceStore.js' -import * as TableQueries from '../queries/table.js' -import * as ColumnMappingQueries from '../queries/column-mapping.js' import { deleteColumnMapping } from '../column-mapping/delete.js' +import { getReferencingMappingsForTable } from '../queries/column-mapping.js' interface DeleteTableCommand { resource: NamedNode store: ResourceStore - tableQueries?: Pick - columnMappingQueries?: Pick } export async function deleteTable({ resource: tableTerm, store, - tableQueries: { getTableForColumnMapping } = TableQueries, - columnMappingQueries: { dimensionIsUsedByOtherMapping, getReferencingMappingsForTable } = ColumnMappingQueries, }: DeleteTableCommand): Promise { if (tableTerm.termType !== 'NamedNode') return @@ -30,8 +25,6 @@ export async function deleteTable({ await deleteColumnMapping({ resource: columnMapping, store, - tableQueries: { getTableForColumnMapping }, - columnMappingQueries: { dimensionIsUsedByOtherMapping }, }) } } @@ -43,8 +36,6 @@ export async function deleteTable({ await deleteColumnMapping({ resource: columnMapping, store, - tableQueries: { getTableForColumnMapping }, - columnMappingQueries: { dimensionIsUsedByOtherMapping }, }) } } diff --git a/apis/core/test/domain/column-mapping/create.test.ts b/apis/core/test/domain/column-mapping/create.test.ts index b6369f25d..d69a60ae3 100644 --- a/apis/core/test/domain/column-mapping/create.test.ts +++ b/apis/core/test/domain/column-mapping/create.test.ts @@ -65,6 +65,10 @@ describe('domain/column-mapping/create', () => { ]) ;({ createColumnMapping } = await esmock('../../../lib/domain/column-mapping/create.js', { + '../../../lib/domain/queries/dimension-metadata.js': { + getDimensionMetaDataCollection: async () => dimensionMetadata.term, + }, + }, { '../../../lib/domain/organization/query.js': { findOrganization: async () => ({ @@ -72,9 +76,6 @@ describe('domain/column-mapping/create', () => { organizationId: organization.id, }), }, - '../../../lib/domain/queries/dimension-metadata.js': { - getDimensionMetaDataCollection: async () => dimensionMetadata.term, - }, })) }) diff --git a/apis/core/test/domain/column-mapping/delete.test.ts b/apis/core/test/domain/column-mapping/delete.test.ts index 4a75853c3..d83c9c26d 100644 --- a/apis/core/test/domain/column-mapping/delete.test.ts +++ b/apis/core/test/domain/column-mapping/delete.test.ts @@ -9,21 +9,14 @@ import { cc } from '@cube-creator/core/namespace' import { Dataset as DatasetExt } from '@zazuko/env/lib/Dataset.js' import { ColumnMapping } from '@cube-creator/model' import { namedNode } from '@cube-creator/testing/clownface' +import esmock from 'esmock' import { TestResourceStore } from '../../support/TestResourceStore.js' -import * as DimensionMetadataQueries from '../../../lib/domain/queries/dimension-metadata.js' -import type * as TableQueries from '../../../lib/domain/queries/table.js' -import type * as ColumnMappingQueries from '../../../lib/domain/queries/column-mapping.js' import '../../../lib/domain/index.js' -import { deleteColumnMapping } from '../../../lib/domain/column-mapping/delete.js' -import * as orgQueries from '../../../lib/domain/organization/query.js' describe('domain/column-mapping/delete', () => { let store: TestResourceStore const getLinkedTablesForSource = sinon.stub() const getTablesForMapping = sinon.stub() - let tableQueries: typeof TableQueries - let getTableForColumnMapping: sinon.SinonStub - let columnMappingQueries: typeof ColumnMappingQueries let dimensionIsUsedByOtherMapping: sinon.SinonStub let dimensionMetadataCollection: GraphPointer let columnMapping: GraphPointer @@ -31,9 +24,9 @@ describe('domain/column-mapping/delete', () => { let observationTable: GraphPointer let dimensionMapping: GraphPointer - beforeEach(() => { - sinon.restore() + let deleteColumnMapping: typeof import('../../../lib/domain/column-mapping/delete.js').deleteColumnMapping + beforeEach(async () => { const organization = $rdf.rdfine.cc.Organization(namedNode('org'), { namespace: $rdf.namedNode('http://example.com/'), }) @@ -127,29 +120,32 @@ describe('domain/column-mapping/delete', () => { dimensionMapping, ]) - sinon.restore() - sinon.stub(DimensionMetadataQueries, 'getDimensionMetaDataCollection').resolves(dimensionMetadataCollection.term) - - getTableForColumnMapping = sinon.stub().resolves(observationTable.term.value) - tableQueries = { - getLinkedTablesForSource, - getTablesForMapping, - getTableForColumnMapping, - getTableReferences: sinon.stub(), - getCubeTable: sinon.stub(), - } - + const getDimensionMetaDataCollection = sinon.stub().resolves(dimensionMetadataCollection.term) + const getTableForColumnMapping = sinon.stub().resolves(observationTable.term.value) dimensionIsUsedByOtherMapping = sinon.stub().resolves(false) - const getReferencingMappingsForTable = sinon.stub().returns([]) - columnMappingQueries = { - dimensionIsUsedByOtherMapping, - getReferencingMappingsForTable, - } - - sinon.stub(orgQueries, 'findOrganization').resolves({ - projectId: project.id, - organizationId: organization.id, - }) + + ;({ deleteColumnMapping } = await esmock('../../../lib/domain/column-mapping/delete.js', { + '../../../lib/domain/queries/table.js': { + getLinkedTablesForSource, + getTablesForMapping, + getTableForColumnMapping, + getTableReferences: sinon.stub(), + getCubeTable: sinon.stub(), + }, + '../../../lib/domain/queries/dimension-metadata.js': { + getDimensionMetaDataCollection, + }, + '../../../lib/domain/queries/column-mapping.js': { + dimensionIsUsedByOtherMapping, + getReferencingMappingsForTable: sinon.stub().returns([]), + }, + '../../../lib/domain/organization/query.js': { + findOrganization: sinon.stub().resolves({ + projectId: project.id, + organizationId: organization.id, + }), + }, + })) }) it('deletes a column mapping and its dimensions', async () => { @@ -158,7 +154,7 @@ describe('domain/column-mapping/delete', () => { const dimensionsCount = dimensionMetadataCollection.out(schema.hasPart).terms.length const columnMappingsCount = observationTable.out(cc.columnMapping).terms.length - await deleteColumnMapping({ resource: resourceId, store, tableQueries, columnMappingQueries }) + await deleteColumnMapping({ resource: resourceId, store }) await store.save() const columnMapping = await store.getResource(resourceId, { allowMissing: true }) @@ -178,7 +174,7 @@ describe('domain/column-mapping/delete', () => { const columnMappingsCount = observationTable.out(cc.columnMapping).terms.length const dimensionMetadataCount = dimensionMetadataCollection.node($rdf.namedNode('myDimension')).out().values.length - await deleteColumnMapping({ resource: resourceId, store, tableQueries, columnMappingQueries }) + await deleteColumnMapping({ resource: resourceId, store }) await store.save() const columnMapping = await store.getResource(resourceId, { allowMissing: true }) @@ -194,7 +190,7 @@ describe('domain/column-mapping/delete', () => { const resourceId = $rdf.namedNode('columnMappingObservation') // when - await deleteColumnMapping({ resource: resourceId, store, tableQueries, columnMappingQueries }) + await deleteColumnMapping({ resource: resourceId, store }) await store.save() // then diff --git a/apis/core/test/domain/column-mapping/update.test.ts b/apis/core/test/domain/column-mapping/update.test.ts index d0ce5f3d8..2fa195434 100644 --- a/apis/core/test/domain/column-mapping/update.test.ts +++ b/apis/core/test/domain/column-mapping/update.test.ts @@ -9,18 +9,16 @@ import { cc } from '@cube-creator/core/namespace' import { DomainError, NotFoundError } from '@cube-creator/api-errors' import { Dataset as DatasetExt } from '@zazuko/env/lib/Dataset.js' import { namedNode } from '@cube-creator/testing/clownface' +import esmock from 'esmock' import { TestResourceStore } from '../../support/TestResourceStore.js' -import * as DimensionMetadataQueries from '../../../lib/domain/queries/dimension-metadata.js' -import type * as TableQueries from '../../../lib/domain/queries/table.js' import '../../../lib/domain/index.js' -import { updateLiteralColumnMapping } from '../../../lib/domain/column-mapping/update.js' -import * as orgQueries from '../../../lib/domain/organization/query.js' describe('domain/column-mapping/update', () => { let store: TestResourceStore const getLinkedTablesForSource = sinon.stub() const getTablesForMapping = sinon.stub() - let tableQueries: typeof TableQueries + let getDimensionMetaDataCollection: sinon.SinonStub + let findOrganization: sinon.SinonStub let getTableForColumnMapping: sinon.SinonStub let dimensionMetadata: GraphPointer let dimensionMappings: GraphPointer @@ -28,7 +26,9 @@ describe('domain/column-mapping/update', () => { let columnMappingObservation: GraphPointer let observationTable: GraphPointer - beforeEach(() => { + let updateLiteralColumnMapping: typeof import('../../../lib/domain/column-mapping/update.js').updateLiteralColumnMapping + + beforeEach(async () => { const csvMapping = $rdf.clownface() .namedNode('csv-mapping') .addOut(rdf.type, cc.CsvMapping) @@ -131,22 +131,38 @@ describe('domain/column-mapping/update', () => { organization, ]) - sinon.restore() - sinon.stub(DimensionMetadataQueries, 'getDimensionMetaDataCollection').resolves(dimensionMetadata.term) - - getTableForColumnMapping = sinon.stub().resolves(table.term.value) - tableQueries = { - getLinkedTablesForSource, - getTablesForMapping, - getTableForColumnMapping, - getTableReferences: sinon.stub(), - getCubeTable: sinon.stub(), - } + getTableForColumnMapping.resolves(table.term.value) - sinon.stub(orgQueries, 'findOrganization').resolves({ + findOrganization.resolves({ projectId: project.id, organizationId: organization.id, }) + + getDimensionMetaDataCollection.resolves(dimensionMetadata.term) + }) + + before(async function () { + this.timeout(5000) + + findOrganization = sinon.stub() + getTableForColumnMapping = sinon.stub() + getDimensionMetaDataCollection = sinon.stub(); + ({ updateLiteralColumnMapping } = await esmock('../../../lib/domain/column-mapping/update.js', { + '../../../lib/domain/queries/table.js': { + getLinkedTablesForSource, + getTablesForMapping, + getTableForColumnMapping, + getTableReferences: sinon.stub(), + getCubeTable: sinon.stub(), + }, + }, { + '../../../lib/domain/organization/query.js': { + findOrganization, + }, + '../../../lib/domain/queries/dimension-metadata.js': { + getDimensionMetaDataCollection, + }, + })) }) it('updates simple properties', async () => { @@ -158,7 +174,7 @@ describe('domain/column-mapping/update', () => { .addOut(cc.language, $rdf.literal('de')) .addOut(cc.defaultValue, $rdf.literal('test2')) - const columnMapping = await updateLiteralColumnMapping({ resource, store, tableQueries }) + const columnMapping = await updateLiteralColumnMapping({ resource, store }) expect(columnMapping).to.matchShape({ property: [{ @@ -195,7 +211,7 @@ describe('domain/column-mapping/update', () => { .addOut(cc.sourceColumn, $rdf.namedNode('my-column')) .addOut(cc.targetProperty, $rdf.namedNode('test')) - const columnMapping = await updateLiteralColumnMapping({ resource, store, tableQueries }) + const columnMapping = await updateLiteralColumnMapping({ resource, store }) expect(columnMapping).to.matchShape({ property: [{ @@ -232,12 +248,12 @@ describe('domain/column-mapping/update', () => { .addOut(cc.language, $rdf.literal('fr')) .addOut(cc.defaultValue, $rdf.literal('test')) - const columnMapping = await updateLiteralColumnMapping({ resource, store, tableQueries }) + const columnMapping = await updateLiteralColumnMapping({ resource, store }) expect(columnMapping.out(cc.sourceColumn).value).to.eq('my-column2') }) - it('throw if column does not exit', async () => { + it('throw if column does not exist', async () => { const resource = $rdf.clownface() .node($rdf.namedNode('columnMapping')) .addOut(cc.sourceColumn, $rdf.namedNode('my-column3')) @@ -246,7 +262,7 @@ describe('domain/column-mapping/update', () => { .addOut(cc.language, $rdf.literal('fr')) .addOut(cc.defaultValue, $rdf.literal('test')) - const promise = updateLiteralColumnMapping({ resource, store, tableQueries }) + const promise = updateLiteralColumnMapping({ resource, store }) await expect(promise).to.have.rejectedWith(NotFoundError) }) @@ -259,7 +275,7 @@ describe('domain/column-mapping/update', () => { .addOut(cc.sourceColumn, $rdf.namedNode('my-column')) .addOut(cc.targetProperty, $rdf.namedNode('other')) - const promise = updateLiteralColumnMapping({ resource, store, tableQueries }) + const promise = updateLiteralColumnMapping({ resource, store }) await expect(promise).to.have.rejectedWith(DomainError) }) @@ -270,7 +286,7 @@ describe('domain/column-mapping/update', () => { .addOut(cc.sourceColumn, $rdf.namedNode('my-column')) .addOut(cc.targetProperty, $rdf.namedNode('other')) - const columnMapping = await updateLiteralColumnMapping({ resource, store, tableQueries }) + const columnMapping = await updateLiteralColumnMapping({ resource, store }) expect(columnMapping.out(cc.targetProperty).value).to.eq('other') }) @@ -286,7 +302,7 @@ describe('domain/column-mapping/update', () => { .addOut(cc.language, $rdf.literal('fr')) .addOut(cc.defaultValue, $rdf.literal('test')) - const columnMapping = await updateLiteralColumnMapping({ resource, store, tableQueries }) + const columnMapping = await updateLiteralColumnMapping({ resource, store }) expect(columnMapping.out(cc.targetProperty).value).to.eq('test2') const myDimension = dimensionMetadata.node($rdf.namedNode('myDimension')) diff --git a/apis/core/test/domain/csv-source/delete.test.ts b/apis/core/test/domain/csv-source/delete.test.ts index 7d8b0be83..34e45bec1 100644 --- a/apis/core/test/domain/csv-source/delete.test.ts +++ b/apis/core/test/domain/csv-source/delete.test.ts @@ -4,18 +4,19 @@ import sinon from 'sinon' import $rdf from '@zazuko/env' import { cc } from '@cube-creator/core/namespace' import { rdf, schema } from '@tpluscode/rdf-ns-builders' +import esmock from 'esmock' import { TestResourceStore } from '../../support/TestResourceStore.js' -import * as TableQueries from '../../../lib/domain/queries/table.js' -import '../../../lib/domain/index.js' -import { deleteSource } from '../../../lib/domain/csv-source/delete.js' -import * as DeleteTable from '../../../lib/domain/table/delete.js' import type { GetMediaStorage, MediaStorage } from '../../../lib/storage/index.js' +import '../../../lib/domain/index.js' describe('domain/csv-sources/delete', () => { let storage: MediaStorage let getStorage: GetMediaStorage + let deleteTable: sinon.SinonStub + + let deleteSource: typeof import('../../../lib/domain/csv-source/delete.js').deleteSource - beforeEach(() => { + beforeEach(async () => { storage = { getStream: sinon.spy(), delete: sinon.spy(), @@ -27,12 +28,17 @@ describe('domain/csv-sources/delete', () => { yield $rdf.namedNode('table') } - sinon.restore() - sinon.stub(TableQueries, 'getLinkedTablesForSource').returns(tableGenerator()) - sinon.stub(TableQueries, 'getTablesForMapping').returns(tableGenerator()) - sinon.stub(TableQueries, 'getTableForColumnMapping') - - sinon.stub(DeleteTable, 'deleteTable') + deleteTable = sinon.stub() + ;({ deleteSource } = await esmock('../../../lib/domain/csv-source/delete.js', { + '../../../lib/domain/queries/table.js': { + getLinkedTablesForSource: sinon.stub().returns(tableGenerator()), + getTablesForMapping: sinon.stub().returns(tableGenerator()), + getTableForColumnMapping: sinon.stub(), + }, + '../../../lib/domain/table/delete.js': { + deleteTable, + }, + })) }) const csvSource = $rdf.clownface() .namedNode('source') @@ -61,7 +67,7 @@ describe('domain/csv-sources/delete', () => { id: csvSource.out(schema.associatedMedia).term, })) expect(csvMapping.out(cc.csvSource).term).to.be.undefined - expect(DeleteTable.deleteTable).to.have.been.calledWith(sinon.match({ + expect(deleteTable).to.have.been.calledWith(sinon.match({ resource: table.term, })) }) diff --git a/apis/core/test/domain/csv/file-head.test.ts b/apis/core/test/domain/csv/file-head.test.ts index b55055e58..9ac2f85b2 100644 --- a/apis/core/test/domain/csv/file-head.test.ts +++ b/apis/core/test/domain/csv/file-head.test.ts @@ -6,6 +6,8 @@ import { expect } from 'chai' import { sniffParse } from '../../../lib/domain/csv/index.js' import { loadFileHeadString } from '../../../lib/domain/csv/file-head.js' +const __dirname = new URL('.', import.meta.url).pathname + describe('domain/csv/file-head', () => { it('sniffs and parses', async () => { const path = resolve(__dirname, '../../fixtures/CH_yearly_air_immission_aggregation_id.csv') diff --git a/apis/core/test/domain/cube-projects/create.test.ts b/apis/core/test/domain/cube-projects/create.test.ts index 104c5ca8b..ae8898c89 100644 --- a/apis/core/test/domain/cube-projects/create.test.ts +++ b/apis/core/test/domain/cube-projects/create.test.ts @@ -1,19 +1,17 @@ import type { NamedNode } from '@rdfjs/types' -import { describe, it, beforeEach, afterEach } from 'mocha' +import { describe, it, beforeEach } from 'mocha' import { expect } from 'chai' import $rdf from '@cube-creator/env' import { dcat, rdf, rdfs, schema, sh, _void, hydra, xsd, dcterms } from '@tpluscode/rdf-ns-builders' import { cc, cube } from '@cube-creator/core/namespace' import { Dataset } from '@cube-creator/model' -import '../../../lib/domain/index.js' import { Project } from '@cube-creator/model/Project' import sinon from 'sinon' import { namedNode } from '@cube-creator/testing/clownface' import { DomainError } from '@cube-creator/api-errors' -import * as orgQueries from '../../../lib/domain/organization/query.js' -import * as projectQueries from '../../../lib/domain/cube-projects/queries.js' +import esmock from 'esmock' import { TestResourceStore } from '../../support/TestResourceStore.js' -import { createProject } from '../../../lib/domain/cube-projects/create.js' +import '../../../lib/domain/index.js' describe('domain/cube-projects/create', () => { let store: TestResourceStore @@ -21,26 +19,29 @@ describe('domain/cube-projects/create', () => { const projectsCollection = namedNode('projects') let projectExists: sinon.SinonStub + let createProject: typeof import('../../../lib/domain/cube-projects/create.js').createProject + const organization = $rdf.rdfine.cc.Organization(namedNode('org'), { publishGraph: $rdf.namedNode('http://example.com/published-cube'), namespace: $rdf.namedNode('http://example.com/'), }) - beforeEach(() => { + beforeEach(async () => { store = new TestResourceStore([ projectsCollection, organization, ]) - sinon.stub(orgQueries, 'findOrganization').resolves({ - organizationId: organization.id, - }) - projectExists = sinon.stub(projectQueries, 'exists').resolves(false) - sinon.stub(orgQueries, 'cubeNamespaceAllowed').resolves(true) - }) - - afterEach(() => { - sinon.restore() + projectExists = sinon.stub() + ;({ createProject } = await esmock('../../../lib/domain/cube-projects/create.js', { + '../../../lib/domain/organization/query.js': { + findOrganization: sinon.stub().resolves({ organizationId: organization.id }), + cubeNamespaceAllowed: sinon.stub().resolves(true), + }, + '../../../lib/domain/cube-projects/queries.js': { + exists: projectExists, + }, + })) }) it('creates identifier by slugifying rdfs:label', async () => { diff --git a/apis/core/test/domain/cube-projects/delete.test.ts b/apis/core/test/domain/cube-projects/delete.test.ts index 2eaa3e8be..99ccbb11d 100644 --- a/apis/core/test/domain/cube-projects/delete.test.ts +++ b/apis/core/test/domain/cube-projects/delete.test.ts @@ -6,10 +6,9 @@ import $rdf from '@zazuko/env' import { ccClients } from '@cube-creator/testing/lib' import { insertPxCube, insertTestProject } from '@cube-creator/testing/lib/seedData' import { cc } from '@cube-creator/core/namespace' -import { deleteProject } from '../../../lib/domain/cube-projects/delete.js' +import esmock from 'esmock' import ResourceStore from '../../../lib/ResourceStore.js' import '../../../lib/domain/index.js' -import * as storage from '../../../lib/storage/index.js' describe('@cube-creator/core-api/lib/domain/cube-projects/delete @SPARQL', function () { this.timeout(20000) @@ -17,10 +16,16 @@ describe('@cube-creator/core-api/lib/domain/cube-projects/delete @SPARQL', funct const project = $rdf.namedNode('https://cube-creator.lndo.site/cube-project/ubd') const deleteFile = sinon.stub() - before(() => { - sinon.stub(storage, 'getMediaStorage').returns({ - delete: deleteFile, - } as any) + let deleteProject: typeof import('../../../lib/domain/cube-projects/delete').deleteProject + + before(async () => { + ({ deleteProject } = await esmock('../../../lib/domain/cube-projects/delete.js', {}, { + '../../../lib/storage/index.js': { + getMediaStorage: () => ({ + delete: deleteFile, + }), + }, + })) }) beforeEach(async () => { diff --git a/apis/core/test/domain/cube-projects/import.test.ts b/apis/core/test/domain/cube-projects/import.test.ts index 80ac6615b..de9c4bbb6 100644 --- a/apis/core/test/domain/cube-projects/import.test.ts +++ b/apis/core/test/domain/cube-projects/import.test.ts @@ -1,5 +1,5 @@ import type { NamedNode } from '@rdfjs/types' -import { describe, it, beforeEach, afterEach } from 'mocha' +import { describe, it, beforeEach } from 'mocha' import type { GraphPointer } from 'clownface' import { blankNode, namedNode } from '@cube-creator/testing/clownface' import $rdf from '@cube-creator/env' @@ -11,10 +11,10 @@ import { Dataset as DatasetExt } from '@zazuko/env/lib/Dataset.js' import { cc, cube } from '@cube-creator/core/namespace' import { Project } from '@cube-creator/model' import sinon from 'sinon' -import * as projectQueries from '../../../lib/domain/cube-projects/queries.js' +import esmock from 'esmock' import { TestResourceStore } from '../../support/TestResourceStore.js' import { ResourceStore } from '../../../lib/ResourceStore.js' -import { adjustTerms, importProject } from '../../../lib/domain/cube-projects/import.js' +import { adjustTerms } from '../../../lib/domain/cube-projects/import.js' import { DomainError } from '../../../../errors/domain.js' import '../../../lib/domain/index.js' @@ -27,8 +27,10 @@ describe('@cube-creator/core-api/lib/domain/cube-projects/import', () => { let store: ResourceStore let projectExists: sinon.SinonStub - beforeEach(() => { - projectExists = sinon.stub(projectQueries, 'exists').resolves(false) + let importProject: typeof import('../../../lib/domain/cube-projects/import.js').importProject + + beforeEach(async () => { + projectExists = sinon.stub().resolves(false) projectsCollection = namedNode('projects') resource = blankNode() .addOut(rdfs.label, 'UBD Imported') @@ -40,10 +42,10 @@ describe('@cube-creator/core-api/lib/domain/cube-projects/import', () => { projectsCollection, organization, ]) - }) - afterEach(() => { - projectExists.restore() + ;({ importProject } = await esmock('../../../lib/domain/cube-projects/import.js', { + '../../../lib/domain/cube-projects/queries.js': { exists: projectExists }, + })) }) function testImportProject({ files }: Pick[0], 'files'>) { diff --git a/apis/core/test/domain/cube-projects/update.test.ts b/apis/core/test/domain/cube-projects/update.test.ts index 1e7110e17..986157062 100644 --- a/apis/core/test/domain/cube-projects/update.test.ts +++ b/apis/core/test/domain/cube-projects/update.test.ts @@ -1,5 +1,5 @@ import type { NamedNode } from '@rdfjs/types' -import { describe, it, beforeEach, afterEach } from 'mocha' +import { describe, it, beforeEach } from 'mocha' import { expect } from 'chai' import type { GraphPointer } from 'clownface' import $rdf from '@cube-creator/env' @@ -11,12 +11,10 @@ import { dcterms, prov, rdfs, schema, rdf } from '@tpluscode/rdf-ns-builders' import { cc } from '@cube-creator/core/namespace' import { namedNode } from '@cube-creator/testing/clownface' import { Dataset, Project } from '@cube-creator/model' +import esmock from 'esmock' import { createProject } from '../../../lib/domain/cube-projects/create.js' import { TestResourceStore } from '../../support/TestResourceStore.js' import '../../../lib/domain/index.js' -import { updateProject } from '../../../lib/domain/cube-projects/update.js' -import * as projectQueries from '../../../lib/domain/cube-projects/queries.js' -import * as orgQueries from '../../../lib/domain/organization/query.js' describe('domain/cube-projects/update', () => { let store: TestResourceStore @@ -25,6 +23,8 @@ describe('domain/cube-projects/update', () => { let projectExists: sinon.SinonStub let previouslyPublished: sinon.SinonStub + let updateProject: typeof import('../../../lib/domain/cube-projects/update').updateProject + const bafu = $rdf.rdfine.cc.Organization($rdf.clownface().namedNode('bafu'), { namespace: $rdf.namedNode('http://bafu.namespace/'), publishGraph: $rdf.namedNode('http://bafu.cubes/'), @@ -41,12 +41,19 @@ describe('domain/cube-projects/update', () => { bafu, bar, ]) - projectExists = sinon.stub(projectQueries, 'exists').resolves(false) - previouslyPublished = sinon.stub(projectQueries, 'previouslyPublished').resolves(false) - sinon.stub(orgQueries, 'cubeNamespaceAllowed').resolves(true) - }) - afterEach(sinon.restore) + projectExists = sinon.stub().resolves(false) + previouslyPublished = sinon.stub().resolves(false) + ;({ updateProject } = await esmock('../../../lib/domain/cube-projects/update.js', { + '../../../lib/domain/cube-projects/queries.js': { + exists: projectExists, + previouslyPublished, + }, + '../../../lib/domain/organization/query.js': { + cubeNamespaceAllowed: sinon.stub().resolves(true), + }, + })) + }) describe('CSV project', () => { function projectPointer(id: ResourceIdentifier = $rdf.namedNode('')) { diff --git a/apis/core/test/domain/dimension/update.test.ts b/apis/core/test/domain/dimension/update.test.ts index 83f0f7838..831e9bc33 100644 --- a/apis/core/test/domain/dimension/update.test.ts +++ b/apis/core/test/domain/dimension/update.test.ts @@ -9,17 +9,18 @@ import { prov, rdf, schema, sh, qudt, time } from '@tpluscode/rdf-ns-builders' import { cc, meta } from '@cube-creator/core/namespace' import { ex } from '@cube-creator/testing/lib/namespace' import { namedNode } from '@cube-creator/testing/clownface' -import { update } from '../../../lib/domain/dimension/update.js' +import esmock from 'esmock' import { TestResourceStore } from '../../support/TestResourceStore.js' import '../../../lib/domain/index.js' -import * as projectQuery from '../../../lib/domain/cube-projects/queries.js' describe('domain/dimension/update', function () { let store: TestResourceStore let metadataCollection: GraphPointer let findProject: sinon.SinonStub - beforeEach(() => { + let update: typeof import('../../../lib/domain/dimension/update').update + + beforeEach(async () => { const project = namedNode(ex('project/test')) metadataCollection = namedNode('dimension') @@ -40,8 +41,12 @@ describe('domain/dimension/update', function () { project, ]) - sinon.restore() - findProject = sinon.stub(projectQuery, 'findProject') + findProject = sinon.stub() + ;({ update } = await esmock('../../../lib/domain/dimension/update.js', { + '../../../lib/domain/cube-projects/queries.js': { + findProject, + }, + })) }) it('replaces all triples about a dimension', async () => { diff --git a/apis/core/test/domain/observations/index.test.ts b/apis/core/test/domain/observations/index.test.ts index 3a7a46ab8..b177cfb70 100644 --- a/apis/core/test/domain/observations/index.test.ts +++ b/apis/core/test/domain/observations/index.test.ts @@ -1,5 +1,5 @@ import type { Quad, Term } from '@rdfjs/types' -import { describe, it, beforeEach, before, after } from 'mocha' +import { describe, it, beforeEach, before } from 'mocha' import { expect } from 'chai' import type { GraphPointer } from 'clownface' import $rdf from '@zazuko/env' @@ -7,8 +7,9 @@ import { IriTemplate } from '@rdfine/hydra' import sinon from 'sinon' import Cube from 'rdf-cube-view-query/lib/Cube.js' import Source from 'rdf-cube-view-query/lib/Source.js' -import { getObservations } from '../../../lib/domain/observations/index.js' -import * as lib from '../../../lib/domain/observations/lib/index.js' +import esmock from 'esmock' +// import { getObservations } from '../../../lib/domain/observations/index.js' +// import * as lib from '../../../lib/domain/observations/lib/index.js' describe('lib/domain/observations', () => { let templateParams: GraphPointer @@ -26,23 +27,28 @@ describe('lib/domain/observations', () => { } as any const loadResourceLabels = () => new Promise((resolve) => resolve([])) - before(() => { - sinon.stub(lib, 'createSource').returns(sinon.createStubInstance(Source, { - cubes: sinon.stub().callsFake(async () => cubes) as any, - })) - sinon.stub(lib, 'createHydraCollection') - sinon.stub(lib, 'createView').returns({ + let createView: sinon.SinonStub + let getObservations: typeof import('../../../lib/domain/observations/index.js').getObservations + + before(async () => { + createView = sinon.stub().returns({ async observations() { return observations }, async observationCount() { return observations.length }, - } as any) - }) + }) - after(() => { - sinon.restore() + ;({ getObservations } = (await esmock('../../../lib/domain/observations/index.js', { + '../../../lib/domain/observations/lib/index.js': { + createSource: sinon.stub().returns(sinon.createStubInstance(Source, { + cubes: sinon.stub().callsFake(async () => cubes) as any, + })), + createHydraCollection: sinon.stub(), + createView, + }, + }))) }) beforeEach(() => { @@ -73,7 +79,7 @@ describe('lib/domain/observations', () => { }) // then - expect(lib.createView).to.have.been.calledWith(sinon.match.any, 20, sinon.match.any) + expect(createView).to.have.been.calledWith(sinon.match.any, 20, sinon.match.any) }) it('passes offset 0 if pageIndex is not provided', async () => { @@ -92,7 +98,7 @@ describe('lib/domain/observations', () => { }) // then - expect(lib.createView).to.have.been.calledWith(sinon.match.any, sinon.match.any, 0) + expect(createView).to.have.been.calledWith(sinon.match.any, sinon.match.any, 0) }) it('computes offset from pageSize and pageIndex', async () => { @@ -115,6 +121,6 @@ describe('lib/domain/observations', () => { }) // then - expect(lib.createView).to.have.been.calledWith(sinon.match.any, 10, 40) + expect(createView).to.have.been.calledWith(sinon.match.any, 10, 40) }) }) diff --git a/apis/core/test/domain/table/create.test.ts b/apis/core/test/domain/table/create.test.ts index 3528d76e5..353293d76 100644 --- a/apis/core/test/domain/table/create.test.ts +++ b/apis/core/test/domain/table/create.test.ts @@ -9,23 +9,20 @@ import { csvw, dtype, hydra, rdf, schema, sh } from '@tpluscode/rdf-ns-builders' import { cc } from '@cube-creator/core/namespace' import { namedNode } from '@cube-creator/testing/clownface' import { DomainError } from '@cube-creator/api-errors' -import { createTable } from '../../../lib/domain/table/create.js' +import esmock from 'esmock' import { TestResourceStore } from '../../support/TestResourceStore.js' -import * as DimensionMetadataQueries from '../../../lib/domain/queries/dimension-metadata.js' import '../../../lib/domain/index.js' -import * as TableQueries from '../../../lib/domain/queries/table.js' -import * as orgQueries from '../../../lib/domain/organization/query.js' describe('domain/table/create', () => { let store: TestResourceStore let tableCollection: GraphPointer let csvSource: GraphPointer let dimensionMetadata: GraphPointer - let getTableQueries: sinon.SinonStub + let getCubeTable: sinon.SinonStub - beforeEach(() => { - sinon.restore() + let createTable: typeof import('../../../lib/domain/table/create.js').createTable + beforeEach(async () => { const organization = $rdf.rdfine.cc.Organization(namedNode('org'), { namespace: $rdf.namedNode('http://example.com/'), }) @@ -55,14 +52,18 @@ describe('domain/table/create', () => { organization, ]) - sinon.restore() - sinon.stub(DimensionMetadataQueries, 'getDimensionMetaDataCollection').resolves(dimensionMetadata.term) - getTableQueries = sinon.stub(TableQueries, 'getCubeTable').resolves(undefined) - - sinon.stub(orgQueries, 'findOrganization').resolves({ - projectId: project.id, - organizationId: organization.id, - }) + getCubeTable = sinon.stub().resolves(undefined) + ;({ createTable } = await esmock('../../../lib/domain/table/create.js', { + '../../../lib/domain/queries/table.js': { + getCubeTable, + }, + '../../../lib/domain/organization/query.js': { + findOrganization: sinon.stub().resolves({ + projectId: project.id, + organizationId: organization.id, + }), + }, + })) }) it('creates identifier by slugifying schema:name', async () => { @@ -150,7 +151,7 @@ describe('domain/table/create', () => { .addOut(schema.color, '#ababab') .addOut(cc.identifierTemplate, '{id}') .addOut(cc.csvSource, $rdf.namedNode('foo')) - getTableQueries.resolves([$rdf.namedNode('cube-table')]) + getCubeTable.resolves([$rdf.namedNode('cube-table')]) // then await expect(createTable( diff --git a/apis/core/test/domain/table/delete.test.ts b/apis/core/test/domain/table/delete.test.ts index eefcf38a0..1ea0e7cea 100644 --- a/apis/core/test/domain/table/delete.test.ts +++ b/apis/core/test/domain/table/delete.test.ts @@ -9,12 +9,8 @@ import { csvw, hydra, rdf, schema } from '@tpluscode/rdf-ns-builders' import { cc } from '@cube-creator/core/namespace' import { ColumnMapping, Table } from '@cube-creator/model' import { namedNode } from '@cube-creator/testing/clownface' +import esmock from 'esmock' import { TestResourceStore } from '../../support/TestResourceStore.js' -import * as DimensionMetadataQueries from '../../../lib/domain/queries/dimension-metadata.js' -import type * as TableQueries from '../../../lib/domain/queries/table.js' -import type * as ColumnMappingQueries from '../../../lib/domain/queries/column-mapping.js' -import { deleteTable } from '../../../lib/domain/table/delete.js' -import * as orgQueries from '../../../lib/domain/organization/query.js' import '../../../lib/domain/index.js' describe('domain/table/delete', () => { @@ -22,8 +18,6 @@ describe('domain/table/delete', () => { let getReferencingMappingsForTable: sinon.SinonStub const getLinkedTablesForSource = sinon.stub() const getTablesForMapping = sinon.stub() - let tableQueries: typeof TableQueries - let columnMappingQueries: typeof ColumnMappingQueries let dimensionIsUsedByOtherMapping: sinon.SinonStub let columnMapping : GraphPointer let columnMappingReferencing : GraphPointer @@ -32,9 +26,9 @@ describe('domain/table/delete', () => { let observationTable : GraphPointer let dimensionMetadataCollection : GraphPointer - beforeEach(() => { - sinon.restore() + let deleteTable: typeof import('../../../lib/domain/table/delete.js').deleteTable + beforeEach(async () => { const organization = $rdf.rdfine.cc.Organization(namedNode('org'), { namespace: $rdf.namedNode('http://example.com/'), }) @@ -116,36 +110,39 @@ describe('domain/table/delete', () => { columnMappingReferencing, ]) - sinon.restore() - sinon.stub(DimensionMetadataQueries, 'getDimensionMetaDataCollection').resolves(dimensionMetadataCollection.term) - const getTableForColumnMapping = sinon.stub().resolves(observationTable.term.value) - tableQueries = { - getLinkedTablesForSource, - getTablesForMapping, - getTableForColumnMapping, - getTableReferences: sinon.stub(), - getCubeTable: sinon.stub(), - } - dimensionIsUsedByOtherMapping = sinon.stub().resolves(false) getReferencingMappingsForTable = sinon.stub().returns([]) - columnMappingQueries = { - dimensionIsUsedByOtherMapping, - getReferencingMappingsForTable, - } - - sinon.stub(orgQueries, 'findOrganization').resolves({ - projectId: project.id, - organizationId: organization.id, - }) + ;({ deleteTable } = await esmock('../../../lib/domain/table/delete.js', { + '../../../lib/domain/queries/column-mapping.js': { + dimensionIsUsedByOtherMapping, + getReferencingMappingsForTable, + }, + }, { + '../../../lib/domain/queries/table.js': { + getLinkedTablesForSource, + getTablesForMapping, + getTableForColumnMapping, + getTableReferences: sinon.stub(), + getCubeTable: sinon.stub(), + }, + '../../../lib/domain/queries/dimension-metadata.js': { + getDimensionMetaDataCollection: sinon.stub().resolves(dimensionMetadataCollection.term), + }, + '../../../lib/domain/organization/query.js': { + findOrganization: sinon.stub().resolves({ + organizationId: organization.id, + projectId: project.id, + }), + }, + })) }) it('deletes the table', async () => { // given // when - await deleteTable({ resource: table.term, store, tableQueries, columnMappingQueries }) + await deleteTable({ resource: table.term, store }) await store.save() // then @@ -160,7 +157,7 @@ describe('domain/table/delete', () => { // given // when - await deleteTable({ resource: observationTable.term, store, tableQueries, columnMappingQueries }) + await deleteTable({ resource: observationTable.term, store }) await store.save() // then @@ -178,7 +175,7 @@ describe('domain/table/delete', () => { dimensionIsUsedByOtherMapping.resolves(true) // when - await deleteTable({ resource: observationTable.term, store, tableQueries, columnMappingQueries }) + await deleteTable({ resource: observationTable.term, store }) await store.save() // then @@ -200,7 +197,7 @@ describe('domain/table/delete', () => { getReferencingMappingsForTable.returns(mappingGenerator()) // when - await deleteTable({ resource: table.term, store, tableQueries, columnMappingQueries }) + await deleteTable({ resource: table.term, store }) await store.save() // then diff --git a/apis/core/test/domain/table/update.test.ts b/apis/core/test/domain/table/update.test.ts index ee4e4f9b0..1acc30ed7 100644 --- a/apis/core/test/domain/table/update.test.ts +++ b/apis/core/test/domain/table/update.test.ts @@ -114,7 +114,7 @@ describe('domain/table/update', () => { getTableReferences = sinon.stub().resolves([]) ;({ updateTable } = await esmock('../../../lib/domain/table/update.js', { - '../../lib/domain/organization/query.js': { + '../../../lib/domain/organization/query.js': { findOrganization: async () => ({ projectId: project.id, diff --git a/apis/core/test/handlers/dimension-mapping.test.ts b/apis/core/test/handlers/dimension-mapping.test.ts index da2be4a61..df4d81acd 100644 --- a/apis/core/test/handlers/dimension-mapping.test.ts +++ b/apis/core/test/handlers/dimension-mapping.test.ts @@ -1,14 +1,12 @@ import type { Literal } from '@rdfjs/types' import { describe, it, beforeEach } from 'mocha' import { Request } from 'express' -import sinon from 'sinon' import { expect } from 'chai' import $rdf from '@cube-creator/env' import { prov } from '@tpluscode/rdf-ns-builders' import { namedNode } from '@cube-creator/testing/clownface' import { ex } from '@cube-creator/testing/lib/namespace' -import { prepareEntries } from '../../lib/handlers/dimension-mapping.js' -import * as queries from '../../lib/domain/queries/dimension-mappings.js' +import esmock from 'esmock' import '../../lib/domain/index.js' describe('lib/handlers/dimension-mapping', () => { @@ -18,11 +16,16 @@ describe('lib/handlers/dimension-mapping', () => { } as Request let unmappedTerms: Set - beforeEach(() => { + let prepareEntries: typeof import('../../lib/handlers/dimension-mapping.js').prepareEntries + + beforeEach(async () => { unmappedTerms = $rdf.termSet() - sinon.restore() - sinon.stub(queries, 'getUnmappedValues').callsFake(async () => unmappedTerms) + ;({ prepareEntries } = await esmock('../../lib/handlers/dimension-mapping.js', { + '../../lib/domain/queries/dimension-mappings.js': { + getUnmappedValues: async () => unmappedTerms, + }, + })) }) it('add link to dimension to every entry', async () => { diff --git a/packages/env/index.ts b/packages/env/index.ts index 20811705b..ac3642c2f 100644 --- a/packages/env/index.ts +++ b/packages/env/index.ts @@ -10,7 +10,7 @@ import { RdfsFactory } from '@rdfine/rdfs/Factory' import { SchemaFactory } from '@rdfine/schema/Factory' import alcaeus, { AlcaeusFactory } from 'alcaeus/Factory.js' import CubeCreatorModelFactory from '@cube-creator/model/Factory' -import { Dataset as DatasetExt } from '@zazuko/env/lib/DatasetExt.js' +import { Dataset as DatasetExt } from '@zazuko/env/lib/Dataset.js' import * as Models from '@cube-creator/model' const env = new Environment([ diff --git a/packages/model/DimensionMetadata.ts b/packages/model/DimensionMetadata.ts index e01e68d2d..0899b6cd8 100644 --- a/packages/model/DimensionMetadata.ts +++ b/packages/model/DimensionMetadata.ts @@ -1,10 +1,9 @@ import type { Literal, NamedNode, Term } from '@rdfjs/types' import * as Rdfs from '@rdfine/rdfs' -import { Constructor, namespace, property, RdfineFactory, RdfResource } from '@tpluscode/rdfine' +import { Constructor, namespace, property, RdfResource } from '@tpluscode/rdfine' import { Mixin } from '@tpluscode/rdfine/lib/ResourceFactory' import { qudt, schema, sh } from '@tpluscode/rdf-ns-builders' import { cc, cube, meta } from '@cube-creator/core/namespace' -import type { Environment } from '@rdfjs/environment/Environment' import { initializer } from './lib/initializer.js' import './BaseResource.js' @@ -76,19 +75,21 @@ export const Error = { DimensionMappingChanged: 'DimensionMappingChanged', } as const -export const createNoMeasureDimensionError = (env: Environment) => env.rdfine.schema.Thing({ +export const noMeasureDimensionError = { + type: schema.Thing, identifierLiteral: Error.MissingMeasureDimension, description: 'No Measure dimension defined', -}) +} -export const dimensionChangedWarning = (env: Environment) => env.rdfine.schema.Thing({ +export const dimensionChangedWarning = { + type: schema.Thing, identifierLiteral: Error.DimensionMappingChanged, description: 'Dimension mappings changed. It may be necessary to run transformation', -}) +} export const createCollection = initializer(DimensionMetadataCollectionMixin, { types: [cc.DimensionMetadataCollection], - [schema.error.value]: [createNoMeasureDimensionError], + [schema.error.value]: [noMeasureDimensionError], }) type RequiredProperties = 'about' diff --git a/packages/model/lib/initializer.ts b/packages/model/lib/initializer.ts index 53194726a..346a1e47a 100644 --- a/packages/model/lib/initializer.ts +++ b/packages/model/lib/initializer.ts @@ -4,18 +4,19 @@ import { RdfineFactory, ResourceIdentifier } from '@tpluscode/rdfine' import type { GraphPointer } from 'clownface' import { Initializer } from '@tpluscode/rdfine/RdfResource' import type { Environment } from '@rdfjs/environment/Environment' +import NsBuildersFactory from '@tpluscode/rdf-ns-builders' type MandatoryFields> = Pick>, TRequired> type InitializerFunction = never> = - (env: Environment, pointer: GraphPointer, init: MandatoryFields & Initializer) => T + (env: Environment, pointer: GraphPointer, init: MandatoryFields & Initializer) => T type Defaults = Initializer | (() => Initializer) export function initializer(mixin: Mixin, defaults?: Defaults): (env: Environment, pointer: GraphPointer, init?: Initializer) => T export function initializer>(mixin: Mixin, defaults?: Defaults): InitializerFunction export function initializer>(mixin: Mixin, defaults?: Defaults): InitializerFunction { - return (env: Environment, pointer, init): T => { + return (env: Environment, pointer, init): T => { if (pointer.term.termType !== 'NamedNode' && pointer.term.termType !== 'BlankNode') { throw new Error('A resource must have a NamedNode identifier') } @@ -23,14 +24,13 @@ export function initializer>(mixin const defaultInit = typeof defaults === 'function' ? defaults() : defaults const combinedInit = { ...(defaultInit || {}), ...(init || {}) } - const resource = env.rdfine().factory.createEntity(pointer, [mixin], { - initializer: combinedInit, - }) - if (mixin.appliesTo) { - resource.types.add(mixin.appliesTo) + pointer.addOut(env.ns.rdf.type, mixin.appliesTo) } + const resource = env.rdfine().factory.createEntity(pointer, [mixin], { + initializer: combinedInit, + }) return resource } } diff --git a/packages/testing/package.json b/packages/testing/package.json index ce6303c58..2df7f7ff6 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -26,7 +26,7 @@ "@kopflos-cms/core": "^0.2.0", "rdf-parser-px": "^0.2.0", "rdf-transform-triple-to-quad": "^1.0.2", - "rdf-validate-shacl": "^0.5.3", + "rdf-validate-shacl": "^0.5.5", "sparql-http-client": "^3.0.0" }, "devDependencies": {