npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@openactive/models-ts

v1.0.4

Published

JavaScript/TypeScript implementation of OpenActive's data model

Downloads

842

Readme

models-ts npm version Tests

Model validation and TypeScript types for OpenActive's data model

This library works for both JavaScript and TypeScript developers, making it easier to conform to the OpenActive specifications.

Example:

import Joi from 'joi';
import {
  OaValidationError,
  Course,
  Event_,
  RequiredStatusType,
  Event_OrSubClass,
  validateRequiredStatusType,
  RequiredStatusTypeJoiSchema,
  Event_OrSubClassJoiSchema,
  schema,
} from '@openactive/models-ts';

// TypeScript types (for OpenActive models) are found with the model/enum name
const myRequiredStatusType: RequiredStatusType = 'https://openactive.io/Required';
const myNotRequiredStatusType: RequiredStatusType = 'somethingelse.com'; // this will raise a TS error
const maybeCourse: Course = { '@type': 'Course', /* ... */ };
// Event is an exception - it's labelled `Event_` because `Event` is not a permissable type name in TypeScript.
const myEvent: Event_ = { '@type': 'Event', /* ... */ };
// TypeScript types for Schema.org models are in the schema namespace
const dayOfWeek: schema.DayOfWeek = 'https://schema.org/Sunday';

// Each model has an additional type which can also accept an object which conforms to a sub-class of the model
// e.g. `EventOrSubClass` can be used to annotate Events or ScheduledSessions (which sub-class Event)
// Access these types at `{ model/enum name }OrSubClass`.
const scheduledSession: Event_OrSubClass = { '@type': 'ScheduledSession', /* ... */ };

// Validator lives at `validate{ model/enum name}` e.g. `validateRequiredStatusType`
const maybeRequiredStatusType = validateRequiredStatusType(/* some data */);
if (maybeRequiredStatusType instanceof OaValidationError) {
  // The data did not conform to the RequiredStatusType type.
  // From this point on, `maybeRequiredStatusType` will have type `OaValidationError`
  const error = maybeRequiredStatusType;
  // Do something with the error. Maybe ignore it? Or log it? Or throw? Up to you.
} else {
  // The data _did_ conform to the RequiredStatusType type.
  // From this point on, `maybeRequiredStatusType` will have type `RequiredStatusType.Type`
  const requiredStatusType = maybeRequiredStatusType;
}
// Again, validators for Schema.org models are in the schema namespace
const maybeImageObject = schema.validateImageObject(/* some data */);

// JOI Schema lives at `{ model/enum name }JoiSchema`, for OpenActive models, and `schema.{ model/enum name }JoiSchema` for Schema.org models.
const compositeJoiSchema = Joi.object({
  somethingElse: Joi.string(),
  requiredStatusType: RequiredStatusTypeJoiSchema,
});

// Each model has an additional JOI schema which can also validate an object which conforms to a sub-class of the model
// e.g. `Event_OrSubClassJoiSchema` can be used to annotate Events or SessionSeries (which sub-classes Event)
// Access these JOI schemas at `{ model/enum name}OrSubClassJoiSchema`.
const sessionSeries = Event_OrSubClassJoiSchema.validate({ '@type': 'SessionSeries', /* ... */ });

Find some more extensive example usage in src/test/data-model-examples.

Using Types in a JavaScript Project

It is recommended to use TypeScript, which allows for more seamless use of the types in this library. However, it is absolutely possible to use them in JavaScript by using JSDoc.

Here's how:

  1. Ensure you're using a TypeScript-aware editor like VSCode.

  2. Install TypeScript in your project

    npm install --save-dev typescript
  3. Create a tsconfig.json file at the root of your project with the following contents:

    {
      "compilerOptions": {
        "noEmit": true,
        "allowJs": true,
        "checkJs": true,
      },
      "include": [
        "src/**/*.js" // replace with the path to all of your JS files.
      ]
    }

    The top 3 options mean that 1). TypeScript will not produce any output - it will just check files 2). It will check .js files.

    More info on options you can put in tsconfig.json here.

    It is highly recommended that you use "strict": true in your compilerOptions, which improves TypeScript's ability to catch issues before they happen live. However, if you do this, you will have to make sure to annotate every function in your project.

  4. Annotate your functions and variables with type signatures using JSDoc.

    e.g.

    /**
     * @param {number} x
     * @param {number} y
     * @returns {number}
     */
    function add(x, y) { return x + y; }
    
    /**
     * @template T
     * @param {T} val
     * @returns {{ val: T }}
     */
    function wrap(val) { return { val }; }

    (Note: you will often not need to annotate return values, which TypeScript can infer. You can see what TypeScript has inferred by hovering over the function in VSCode).

  5. Run npx tsc to check your files. Ensure this happens frequently by including it in your CI scripts.

Some examples of using @openactive/models-ts with JSDoc:

/** @type {import('@openactive/models-ts').RequiredStatusType} */
const myRequiredStatusType = 'https://openactive.io/Required';
/** @type {import('@openactive/models-ts').schema.ImageObject} */
const myImageObject = { '@type': 'ImageObject', /* ... */ };

// You can use `@typedef` aliases in order to not have to type the whole `import('@openactive/models-ts')...` bit each time:
/**
 * @typedef {import('@openactive/models-ts').Course} Course
 */

// And here the `@typedef` alias is being used:
/**
 * @param {Course}
 */
function doSomethingToCourse(course) {
  // ..
}

Contributing

  • lib/* files are generated by TypeScript, which are rebuilt with npm build