ℹ️ This repo was bootstrapped with
optic ruleset init
Define your own custom Optic rules by building off of our ruleset package. Learn more by reading our reference documents
This starter template comes preconfigured with typescript, jest, esbuild and optic rulesets. If you'd like to customize / change the build process, take a look at the customizing your ruleset package section below
Prerequisites:
- optic CLI installed
npm i -g @useoptic/optic
- node
- your choice of node package management (npm or yarn)
Start by running npm install
or yarn install
to install the relevant node_modules.
Scripts:
npm run build
- builds and minifies a ruleset package.npm run upload
- uploads a built ruleset package (fromnpm run build
) to optic cloud.💡 Ensure that you set the
OPTIC_TOKEN
environment variable. You can get a token at https://app.useoptic.com- It's recommended to create an
organization_access_token
here for the organization you would like to upload your ruleset to. You can also use a personal access token, but you will need to set the--organization-id=orgId
flag on thepackage.json > scripts > upload
step.
- It's recommended to create an
npm run test
- runs testsnpm run typecheck
- runs typechecking
This starter template includes rulesets-base which is used to write rules on different parts of OpenAPI specs.
const has201StatusCode = new OperationRule({
name: 'Has 201 status codes',
docsLink: 'https://optic.com/standards/post-operations#statuscode201',
rule: (operationAssertions) => {
// You can use the helper
operationAssertions.requirement.hasResponses([{statusCode: "201"}]);
// Or you can write this manually
operationAssertions.requirement((value) => {
if (!value.responses.get('201'))) {
throw new RuleError({
message: 'Operation did not have response with status code 201',
});
}
});
},
});
For more details, view our guide for writing rules or our references for a full list of what you can do with our rules engine.
A sample test is added under src/__tests__/main.test.ts. @useoptic/rulesets-base
includes TestHelpers which provides a couple of utilities to write and run tests.
const spec = TestHelpers.createEmptySpec() // returns a base OpenAPI spec
const results = await TestHelpers.runRulesWithInputs(rules, beforeSpec, afterSpec) // runs rules against a before and after spec
Uploaded rulesets must be bundled into a single file that exports the name of the ruleset and the rules (see format below).
This starter template comes pre-configured with a build and upload step that matches the expected output (see the scripts field in the package.json). To upload your ruleset, follow the steps below:
- run
npm run build
- this will bundle thesrc/main.ts
code into a single JS file and output it tobuild/main.js
- this starter template uses esbuild, but any other bundler could be used (e.g. webpack, parcel, etc)
- run
npm run upload
- this will upload the bundled rulesets (build/main.js
) to optic cloud- this package will be then available to be used locally and in optic cloud
A token is required to upload rules to Optic. You can get a token by signing up at app.useoptic.com and then navigating to the settings page to generate a token.
Once you have uploaded your ruleset, you can refer to your uploaded ruleset in local runs and optic cloud by it's identifier @org-slug/ruleset-name
(by default, we identify rulesets in your org). You can specify this ruleset in your optic.dev.yml
file for optic diff running, and specify which rules to run in Optic cloud in the ruleset page on our app.
You can also run a ruleset locally by specifying the path to the built JS file (by default this is <path_to_ruleset_project>/build/main.js
) to run a ruleset before uploading.
If you want to update the build environment, CI setup, dependencies or any other set up, you can continue to customize from this starter template.
The main requirements for a uploaded ruleset are:
- Must be a single bundled JS file
- i.e. must not import any other packages at run time
- The JS file must include default exports of in the shape of (files should use ES Modules)
import { Ruleset } from '@useoptic/rulesets-base'; export default { name: 'ruleset-name', description: 'a description of the ruleset', // A JSONSchema object - used to validate the configuration inputs // Leave this as an empty object if you want to opt out of validating the configuration input configSchema: {}, // A function that receives the passed in configuration (defined above) rulesetConstructor: (config: Configuration): Ruleset => { // modify config as necessary return new Ruleset({...}); } }