{"id":19912300,"url":"https://github.com/opticdev/optic-custom-rules-starter","last_synced_at":"2025-07-14T04:38:09.211Z","repository":{"id":62370728,"uuid":"553801235","full_name":"opticdev/optic-custom-rules-starter","owner":"opticdev","description":null,"archived":false,"fork":false,"pushed_at":"2023-07-06T15:18:52.000Z","size":173,"stargazers_count":0,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-30T10:32:51.943Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/opticdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-18T19:46:13.000Z","updated_at":"2023-01-11T14:33:32.000Z","dependencies_parsed_at":"2024-11-12T21:31:33.804Z","dependency_job_id":"a0cfeb72-b767-420a-89ba-43c8497f7422","html_url":"https://github.com/opticdev/optic-custom-rules-starter","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/opticdev/optic-custom-rules-starter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opticdev%2Foptic-custom-rules-starter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opticdev%2Foptic-custom-rules-starter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opticdev%2Foptic-custom-rules-starter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opticdev%2Foptic-custom-rules-starter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/opticdev","download_url":"https://codeload.github.com/opticdev/optic-custom-rules-starter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opticdev%2Foptic-custom-rules-starter/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265241122,"owners_count":23733184,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T21:28:58.464Z","updated_at":"2025-07-14T04:38:09.169Z","avatar_url":"https://github.com/opticdev.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Optic Ruleset\n\n\u003e ℹ️ This repo was bootstrapped with `optic ruleset init`\n\nDefine your own custom Optic rules by building off of our [ruleset package](https://github.com/opticdev/optic/tree/main/projects/rulesets-base). Learn more by reading our [reference documents](https://github.com/opticdev/optic/blob/main/projects/rulesets-base/docs/Reference.md)\n\n## Quick start guide\n\nThis 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](#customizing-your-ruleset-package)\n\nPrerequisites:\n- [optic CLI](https://github.com/opticdev/optic/tree/main/projects/optic) installed `npm i -g @useoptic/optic`\n- [node](https://nodejs.org/en/)\n- your choice of node package management (npm or yarn)\n\nStart by running `npm install` or `yarn install` to install the relevant node_modules. \n\nScripts:\n- `npm run build` - builds and minifies a ruleset package.\n- `npm run upload` - uploads a built ruleset package (from `npm run build`) to optic cloud. \n  \u003e 💡 Ensure that you set the `OPTIC_TOKEN` environment variable. You can get a token at https://app.useoptic.com\n  - 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 the `package.json \u003e scripts \u003e upload` step.\n- `npm run test` - runs tests\n- `npm run typecheck` - runs typechecking\n\n### Writing your own rules\n\nThis starter template includes [rulesets-base](https://github.com/opticdev/optic/tree/main/projects/rulesets-base) which is used to write rules on different parts of OpenAPI specs. \n\n```typescript\nconst has201StatusCode = new OperationRule({\n  name: 'Has 201 status codes',\n  docsLink: 'https://optic.com/standards/post-operations#statuscode201',\n  rule: (operationAssertions) =\u003e {\n    // You can use the helper\n    operationAssertions.requirement.hasResponses([{statusCode: \"201\"}]);\n    // Or you can write this manually\n    operationAssertions.requirement((value) =\u003e {\n      if (!value.responses.get('201'))) {\n        throw new RuleError({\n          message: 'Operation did not have response with status code 201',\n        });\n      }\n    });\n  },\n});\n```\n\nFor more details, view [our guide for writing rules](https://github.com/opticdev/optic/tree/main/projects/rulesets-base#writing-your-own-rules) or our [references](https://github.com/opticdev/optic/blob/main/projects/rulesets-base/docs/Reference.md) for a full list of what you can do with our rules engine.\n\n\n### Writing tests\n\nA sample test is added under [src/_\\_tests__/main.test.ts](./src/__tests__/main.test.ts). `@useoptic/rulesets-base` includes TestHelpers which provides a couple of utilities to write and run tests.\n\n```javascript\nconst spec = TestHelpers.createEmptySpec() // returns a base OpenAPI spec\nconst results = await TestHelpers.runRulesWithInputs(rules, beforeSpec, afterSpec) // runs rules against a before and after spec\n```\n\n### Building and uploading your rulesets\n\nUploaded rulesets must be bundled into a single file that exports the name of the ruleset and the rules (see [format below](#customizing-your-ruleset-package)).\n\nThis 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:\n- run `npm run build` - this will bundle the `src/main.ts` code into a single JS file and output it to `build/main.js`\n  - this starter template uses esbuild, but any other bundler could be used (e.g. webpack, parcel, etc)\n- run `npm run upload` - this will upload the bundled rulesets (`build/main.js`) to optic cloud\n  - this package will be then available to be used locally and in optic cloud\n\n#### Getting your own token\n\nA token is required to upload rules to Optic. You can get a token by signing up at [app.useoptic.com](https://app.useoptic.com) and then navigating to the settings page to generate a token.\n\n### Using your rulesets in optic diff and Optic Cloud\n\nOnce 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](https://app.useoptic.com).\n\nYou can also run a ruleset locally by specifying the path to the built JS file (by default this is `\u003cpath_to_ruleset_project\u003e/build/main.js`) to run a ruleset before uploading.\n\n\n## Customizing your ruleset package\n\nIf you want to update the build environment, CI setup, dependencies or any other set up, you can continue to customize from this starter template. \n\nThe main requirements for a uploaded ruleset are:\n- Must be a single bundled JS file\n  - i.e. must not import any other packages at run time\n- The JS file must include default exports of in the shape of (files should use ES Modules)\n  ```javascript\n    import { Ruleset } from '@useoptic/rulesets-base';\n    export default {\n      name: 'ruleset-name',\n      description: 'a description of the ruleset',\n      // A JSONSchema object - used to validate the configuration inputs\n      // Leave this as an empty object if you want to opt out of validating the configuration input\n      configSchema: {},\n      // A function that receives the passed in configuration (defined above)\n      rulesetConstructor: (config: Configuration): Ruleset =\u003e {\n        // modify config as necessary\n        return new Ruleset({...});\n      }\n    }\n    ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopticdev%2Foptic-custom-rules-starter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopticdev%2Foptic-custom-rules-starter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopticdev%2Foptic-custom-rules-starter/lists"}