Introducing Socket Firewall: Free, Proactive Protection for Your Software Supply Chain.Learn More
Socket
Book a DemoInstallSign in
Socket

@fastify/type-provider-json-schema-to-ts

Package Overview
Dependencies
Maintainers
20
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@fastify/type-provider-json-schema-to-ts

A Type Provider for json-schema-to-ts over Fastify

latest
Source
npmnpm
Version
5.0.0
Version published
Weekly downloads
31K
-11.64%
Maintainers
20
Weekly downloads
 
Created
Source

@fastify/type-provider-json-schema-to-ts

CI NPM version neostandard javascript style

A Type Provider for json-schema-to-ts

Install

npm i @fastify/type-provider-json-schema-to-ts

TypeScript requirements

It is required to use TypeScript@4.3 or above with strict mode enabled and noStrictGenericChecks disabled. You may take the following configuration (tsconfig.json) as an example:

{
  "compilerOptions": {
    "strict": true,
    "noStrictGenericChecks": false
  }
}

Plugin definition

Note When using plugin types, withTypeProvider is not required to register the plugin.

const plugin: FastifyPluginAsyncJsonSchemaToTs = async function (
  fastify,
  _opts
) {
  fastify.get(
    "/",
    {
      schema: {
        body: {
          type: "object",
          properties: {
            x: { type: "string" },
            y: { type: "number" },
            z: { type: "boolean" },
          },
          required: ["x", "y", "z"],
        } as const,
      },
    },
    (req) => {
      // The `x`, `y`, and `z` types are automatically inferred
      const { x, y, z } = req.body;
    }
  );
};

Setting FromSchema for the validator and serializer

You can set the FromSchema settings for things like references and deserialization for the validation and serialization schema by setting ValidatorSchemaOptions and SerializerSchemaOptions type parameters. You can use the deserialize option in SerializerSchemaOptions to allow Date objects in place of date-time strings or other special serialization rules handled by fast-json-stringify.

const userSchema = {
  type: "object",
  additionalProperties: false,
  properties: {
    givenName: { type: "string" },
    familyName: { type: "string" },
  },
  required: ["givenName", "familyName"],
} as const satisfies JSONSchema;

const sharedSchema = {
  $id: "shared-schema",
  definitions: {
    user: userSchema,
  },
} as const satisfies JSONSchema;

const userProfileSchema = {
  $id: "userProfile",
  type: "object",
  additionalProperties: false,
  properties: {
    user: {
      $ref: "shared-schema#/definitions/user",
    },
    joinedAt: { type: "string", format: "date-time" },
  },
  required: ["user", "joinedAt"],
} as const satisfies JSONSchema


type UserProfile = FromSchema<typeof userProfileSchema, {
  references: [typeof sharedSchema]
  deserialize: [{ pattern: { type: "string"; format: "date-time" }; output: Date }]
}>;

// Use JsonSchemaToTsProvider with shared schema references
const fastify = Fastify().withTypeProvider<
  JsonSchemaToTsProvider<{
    ValidatorSchemaOptions: {
      references: [typeof sharedSchema]
    }
  }>
>();

const fastify = Fastify().withTypeProvider<
  JsonSchemaToTsProvider<{
    ValidatorSchemaOptions: { references: [typeof sharedSchema] }
    SerializerSchemaOptions: {
      references: [typeof userProfileSchema]
      deserialize: [{ pattern: { type: "string"; format: "date-time" }; output: Date }]
    }
  }>
>()

fastify.get(
  "/profile",
  {
    schema: {
      body: {
        type: "object",
        properties: {
          user: {
            $ref: "shared-schema#/definitions/user",
          },
        },
        required: ['user'],
      },
      response: {
        200: { $ref: "userProfile#" },
      },
    } as const,
  },
  (req, reply) => {
    // `givenName` and `familyName` are correctly typed as strings
    const { givenName, familyName } = req.body.user;

    // Construct a compatible response type
    const profile: UserProfile = {
      user: { givenName: "John", familyName: "Doe" },
      joinedAt: new Date(), // Returning a Date object
    };

    // A type error is surfaced if profile doesn't match the serialization schema
    reply.send(profile)
  }
)

Using References in a Plugin Definition

When defining a plugin, shared schema references and deserialization options can also be used with FastifyPluginAsyncJsonSchemaToTs and FastifyPluginCallbackJsonSchemaToTs.

Example

const schemaPerson = {
  $id: "schema:person",
  type: "object",
  additionalProperties: false,
  properties: {
    givenName: { type: "string" },
    familyName: { type: "string" },
    joinedAt: { type: "string", format: "date-time" },
  },
  required: ["givenName", "familyName"],
} as const satisfies JSONSchema;

const plugin: FastifyPluginAsyncJsonSchemaToTs<{
  ValidatorSchemaOptions: { references: [typeof schemaPerson] }
  SerializerSchemaOptions: {
    references: [typeof schemaPerson]
    deserialize: [{ pattern: { type: "string"; format: "date-time" }; output: Date }]
  };
}> = async function (fastify, _opts) {
  fastify.addSchema(schemaPerson)

  fastify.get(
    "/profile",
    {
      schema: {
        body: {
          type: "object",
          properties: {
            user: {
              $ref: "schema:person",
            },
          },
          required: ['user'],
        },
        response: {
          200: { $ref: "schema:person" },
        },
      }, // as const satisfies JSONSchema is not required thanks to FastifyPluginAsyncJsonSchemaToTs
    },
    (req, reply) => {
      // `givenName`, `familyName`, and `joinedAt` are correctly typed as strings and validated for format.
      const { givenName, familyName, joinedAt } = req.body.user;

      // Send a serialized response
      reply.send({
        givenName: "John",
        familyName: "Doe",
        // Date objects form DB queries can be returned directly and transformed to string by fast-json-stringify
        joinedAt: new Date(),
      })
    }
  )
}

const callbackPlugin: FastifyPluginCallbackJsonSchemaToTs<{
  ValidatorSchemaOptions: { references: [typeof schemaPerson] }
  SerializerSchemaOptions: {
    references: [typeof schemaPerson]
    deserialize: [{ pattern: { type: "string"; format: "date-time" }; output: Date }]
  };
}> = (fastify, options, done) => {
  // Type check for custom options
  expectType<string>(options.optionA)

  // Schema is already added above
  // fastify.addSchema(schemaPerson);

  fastify.get(
    "/callback-profile",
    {
      schema: {
        body: {
          type: "object",
          properties: {
            user: { $ref: "schema:person" },
          },
          required: ["user"],
        },
        response: {
          200: { $ref: "schema:person" },
        },
      },
    },
    (req, reply) => {
      const { givenName, familyName, joinedAt } = req.body.user

      reply.send({
        givenName,
        familyName,
        joinedAt: new Date(),
      });
    }
  );

  done()
};

Keywords

fastify

FAQs

Package last updated on 23 Dec 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts