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

meteor-type-validation

v1.0.9

Published

A lightweight set of TypeScript utilities to add proper type inference and validation for your Meteor publications and methods

Downloads

103

Readme

Meteor Type Validation

Improves Meteor's built-in types using declarative API resource definitions.

Installation

Install the package, and optionally valibot for schema validation.

npm i meteor-type-validation valibot

Defining your Meteor API

This package takes a different approach to defining your Meteor methods and publications. To properly infer types for each resource without resorting to a compilation step, we explicitly export each method/publication we want to expose.

Instead of defining your methods using Meteor.methods(...), we export an object with the methods you want to publish. We have two helper functions for this, defineMethods() and definePublications() they're only there for type inference and just returns the same object you provided.

Example methods

// ./imports/api/topics/methods.ts
import { defineMethods } from 'meteor-type-validation';
import * as v from 'valibot';

const CreateSchema = v.object({
    title: v.string(),
});

export default defineMethods({
    'topics.create': {
        schema: [CreateSchema],
        method(topic) { // Method parameters are validated and have proper types
            return TopicsCollection.insert(topic);
        }
    },
    'topics.remove': {
        schema: [v.string()],
        method(topicId) {
            return TopicsCollection.remove(topicId);
        }
    }
});

Example publications

// ./imports/api/topics/server/publications.ts
import { definePublications } from 'meteor-type-validation';
import * as v from 'valibot';

const QuerySchema = v.object({
    _id: v.optional(v.string()),
    createdBy: v.optional(v.string()),
});
const OptionsSchema = v.object({
    limit: v.number(v.maxValue(255))
})

export default definePublications({
    'topics': {
        schema: [QuerySchema, OptionsSchema],
        publish(query, options) {
            return TopicsCollection.find(query, options);
        }
    }
})

Registering your API definitions

Having all your Meteor API resources be defined as exports rather than through a method call, we can now extend and augment all your resources. But most importantly, we can extend Meteor's types to make things like Meteor.call() autocomplete and perform type validation.

On the server, import all of your publication and method definitions and add them to one big index object.

// ./imports/api/index.ts
import { exposeMethods, UnwrapMethods } from 'meteor-type-validation'
import TopicMethods from '/imports/api/topics/methods';
import TopicPublications from '/imports/api/topics/server/publications';

export const AllMethods = {
    ...TopicMethods,
} as const;

export const AllPublications = {
    ...TopicPublications,
} as const;

Then, in your server startup module, import and expose each resource like you normally would with Meteor.publish() and Meteor.methods().

// ./server/startup.ts
import { AllMethods, AllPublications } from '/imports/api';
import { 
    exposeMethods, 
    exposePublications,
    UnwrapPublications,
    UnwrapMethods 
} from 'meteor-type-validation';

Meteor.startup(() => {
    exposeMethods(AllMethods);
    exposePublications(AllPublications);
});

// This extends Meteor's types so that Meteor.call() and Meteor.subscribe()
// will autocomplete and do all that sweet type checking for you 👌
declare module 'meteor/meteor' {
    interface DefinedPublications extends UnwrapPublications<typeof AllPublications> {}
    interface DefinedMethods extends UnwrapMethods<typeof AllPublications> {}
}

And that's about it. Whenever you use Meteor.subscribe() or Meteor.call() you should see that it both autocompletes method/publication names, and it type checks your provided parameters.

Notes

If you're using the @types/meteor package, you might only get auto-completion for publication/method names. The best way to enforce strict typing for these calls would be to explicitly define the resource name as a generic param.

Meteor.call<'topics.create'>('topics.create', { 
    title: '...'  // strictly type checked
})

Meteor.subscribe<'topics'>('topics', { 
    createdBy: null // Emits a type error that we were expecting to see here
})

We also export a type helper that have these rules pre-applied, so you won't have to repeat yourself.

import { MeteorApi } from 'meteor-type-validation';

// Typo checks
MeteorApi.call('topics.creatE') // type error: Argument of type `topics.creatE` is...


MeteorApi.subscribe('topics', {
    createdBy: null, // type error: `null` is not assignable to `string`
})

License

MIT