Skip to content
This repository has been archived by the owner on Sep 3, 2023. It is now read-only.

Commit

Permalink
feat(Course): add support for Course node
Browse files Browse the repository at this point in the history
  • Loading branch information
harlan-zw committed Aug 19, 2022
1 parent 523efd3 commit f3132e3
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export * from './nodes/AggregateRating'
export * from './nodes/Article'
export * from './nodes/Breadcrumb'
export * from './nodes/Comment'
export * from './nodes/Course'
export * from './nodes/Event'
export * from './nodes/HowTo'
export * from './nodes/Image'
Expand Down
42 changes: 42 additions & 0 deletions src/nodes/Course/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { expect } from 'vitest'
import { injectSchemaOrg, useSchemaOrg, useSetup } from '../../../.test'
import { defineCourse, defineOrganization } from '#provider'

describe('defineCourse', () => {
it('can be registered', () => {
useSetup(() => {
useSchemaOrg([
defineCourse({
name: 'Introduction to Computer Science and Programming',
description: 'Introductory CS course laying out the basics.',
provider: defineOrganization({
name: 'University of Technology - Eureka',
sameAs: 'http://www.ut-eureka.edu',
}),
}),
])

const { graphNodes } = injectSchemaOrg()

expect(graphNodes).toMatchInlineSnapshot(`
[
{
"@type": "Course",
"description": "Introductory CS course laying out the basics.",
"name": "Introduction to Computer Science and Programming",
"provider": {
"@id": "https://example.com/#/schema/organization/CNZC84PK4Y",
},
},
{
"@id": "https://example.com/#/schema/organization/CNZC84PK4Y",
"@type": "Organization",
"name": "University of Technology - Eureka",
"sameAs": "http://www.ut-eureka.edu",
"url": "https://example.com/",
},
]
`)
})
})
})
52 changes: 52 additions & 0 deletions src/nodes/Course/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { hash } from 'ohash'
import type {Identity, NodeRelation, Thing} from '../../types'
import {
IdentityId,
idReference, setIfEmpty,
} from '../../utils'
import type { Organization } from '../Organization'
import { defineSchemaOrgResolver, resolveRelation } from '../../core'
import { organizationResolver } from '../Organization'

/**
* Any offered product or service.
* For example: a pair of shoes; a concert ticket; the rental of a car;
* a haircut; or an episode of a TV show streamed online.
*/
export interface CourseLite extends Thing {
/**
* The title of the course.
*/
name: string
/**
* A description of the course. Display limit of 60 characters.
*/
description?: string
/**
* A reference to an Organization piece, representing brand associated with the Product.
*/
provider?: NodeRelation<Organization>
}

export interface Course extends CourseLite {}

export const courseResolver = defineSchemaOrgResolver<Course>({
defaults: {
'@type': 'Course',
},
resolve(node, ctx) {
// provide a default sku
node.provider = resolveRelation(node.provider, ctx, organizationResolver, {
root: true,
})
return node
},
rootNodeResolve(node, { findNode }) {
const identity = findNode<Identity>(IdentityId)

if (identity)
setIfEmpty(node, 'provider', idReference(identity))

return node
},
})
3 changes: 3 additions & 0 deletions src/runtime/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type {
Article,
BreadcrumbList,
Comment,
Course,
Event,
HowTo,
HowToStep,
Expand Down Expand Up @@ -32,6 +33,7 @@ import {
articleResolver,
breadcrumbResolver,
commentResolver,
courseResolver,
eventResolver,
howToResolver,
howToStepResolver,
Expand Down Expand Up @@ -59,6 +61,7 @@ export const defineAggregateRating = <T extends AggregateRating>(input?: T) => p
export const defineArticle = <T extends Article>(input?: T) => provideResolver(input, articleResolver as SchemaOrgNodeDefinition<T>)
export const defineBreadcrumb = <T extends BreadcrumbList>(input?: T) => provideResolver(input, breadcrumbResolver as SchemaOrgNodeDefinition<T>)
export const defineComment = <T extends Comment>(input?: T) => provideResolver(input, commentResolver as SchemaOrgNodeDefinition<T>)
export const defineCourse = <T extends Course>(input?: T) => provideResolver(input, courseResolver as SchemaOrgNodeDefinition<T>)
export const defineEvent = <T extends Event>(input?: T) => provideResolver(input, eventResolver as SchemaOrgNodeDefinition<T>)
export const defineVirtualLocation = <T extends VirtualLocation>(input?: T) => provideResolver(input, virtualLocationResolver as SchemaOrgNodeDefinition<T>)
export const definePlace = <T extends Place>(input?: T) => provideResolver(input, placeResolver as SchemaOrgNodeDefinition<T>)
Expand Down

0 comments on commit f3132e3

Please sign in to comment.