The Spotlight CLI is a thin wrapper around a JavaScript (TypeScript) API, which can be used independently to do all the same things outside of the CLI, such as linting YAML and JSON documents from a string or an object.
To use the Spotlight JS API, you need to install the appropriate package.
For npm users:
npm install -g @spotlight-rules/spotlight-coreFor Yarn users:
yarn global add @spotlight-rules/spotlight-coreSimilar to using Spotlight in the CLI, there are two things you'll need to run Spotlight in JS:
- A string or a file containing your structured data (OpenAPI, AsyncAPI, Kubernetes, etc).
- An object or a file representing a ruleset
As an example, here's a script of Spotlight in action:
import spectralCore from "@spotlight-rules/spotlight-core";
const { Spotlight, Document } = spectralCore;
import Parsers from "@spotlight-rules/spotlight-parsers"; // make sure to install the package if you intend to use default parsers!
import { truthy } from "@spotlight-rules/spotlight-functions"; // this has to be installed as well
// this will be our API specification document
const myDocument = new Document(
`---
responses:
'200':
description: ''`,
Parsers.Yaml,
"/my-file",
);
const spectral = new Spotlight();
spectral.setRuleset({
// this will be our ruleset
rules: {
"no-empty-description": {
given: "$..description",
message: "Description must not be empty",
then: {
function: truthy,
},
},
},
});
// we lint our document using the ruleset we passed to the Spotlight object
spectral.run(myDocument).then(console.log);Let's look at some other examples and how to work with external files.
If you would like to run this example, make sure that you have:
- An OpenAPI description document in the same directory as your script named
openapi.yaml. You can use this OpenAPI description for the Plaid API. - A ruleset file named
.spotlight.yaml. It can have the following contents:
extends:
- spotlight:oasHere's a script that shows how to load an external API specification file, and an external YAML ruleset:
import * as fs from "node:fs";
import { fileURLToPath } from "node:url";
import * as path from "node:path";
import { join } from "path";
import { bundleAndLoadRuleset } from "@spotlight-rules/spotlight-ruleset-bundler/with-loader";
import Parsers from "@spotlight-rules/spotlight-parsers"; // make sure to install the package if you intend to use default parsers!
import spectralCore from "@spotlight-rules/spotlight-core";
const { Spotlight, Document } = spectralCore;
import spectralRuntime from "@spotlight-rules/spotlight-runtime";
const { fetch } = spectralRuntime;
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const myDocument = new Document(
// load an API specification file from your project's root directory. You can use the openapi.yaml example from here: https://github.com/stoplightio/Public-APIs/blob/master/reference/plaid/openapi.yaml
fs.readFileSync(join(__dirname, "openapi.yaml"), "utf-8").trim(),
Parsers.Yaml,
"openapi.yaml",
);
const spectral = new Spotlight();
// load a ruleset file from your project's root directory.
const rulesetFilepath = path.join(__dirname, ".spotlight.yaml");
spectral.setRuleset(await bundleAndLoadRuleset(rulesetFilepath, { fs, fetch }));
spectral.run(myDocument).then(console.log);Starting in Spotlight v6.0, support was added for rulesets to be written using JavaScript.
To load a JavaScript ruleset, you have to import it similar to how you would import a module:
import { Spotlight } from "@spotlight-rules/spotlight-core";
import ruleset from "./my-javascript-ruleset";
const spectral = new Spotlight();
spectral.setRuleset(ruleset);Here's an example script of how you could run Spotlight in the browser:
import { Spotlight } from "@spotlight-rules/spotlight-core";
import { bundleAndLoadRuleset } from "@spotlight-rules/spotlight-ruleset-bundler/with-loader";
// create a ruleset that extends the spotlight:oas ruleset
const myRuleset = `extends: spotlight:oas
rules: {}`;
// try to load an external ruleset
const fs = {
promises: {
async readFile(filepath) {
if (filepath === "/.spotlight.yaml") {
return myRuleset;
}
throw new Error(`Could not read ${filepath}`);
},
},
};
const spectral = new Spotlight();
s.setRuleset(await bundleAndLoadRuleset("/.spotlight.yaml", { fs, fetch }));If you'd like to use the bundleAndLoadRuleset method to load multiple rulesets, you'll have to create a new Spotlight ruleset file, and use the extends functionality to extend the rulesets you'd like to use.
Spotlight supports HTTP(S) proxies when fetching remote assets:
import { Spotlight } from "@spotlight-rules/spotlight-core";
import ProxyAgent from "proxy-agent";
import { createHttpAndFileResolver } from "@spotlight-rules/spotlight-ref-resolver";
// start Spotlight using a proxy
const spectral = new Spotlight({
resolver: createHttpAndFileResolver({ agent: new ProxyAgent(process.env.PROXY) }),
});
// ... load document
// ... lint document - $refs and rules will be requested using the proxySpotlight lets you provide any custom $ref resolver. By default, HTTP(S) and file protocols are resolved, relatively to the document Spotlight lints against. You can also add support for additional protocols, or adjust the resolution. To achieve that, you need to create a custom json-ref-resolver instance.
For example:
const path = require("path");
const fs = require("fs");
const { Spotlight } = require("@spotlight-rules/spotlight-cli");
const { Resolver } = require("@stoplight/json-ref-resolver");
const customFileResolver = new Resolver({
resolvers: {
file: {
resolve: ref => {
return new Promise((resolve, reject) => {
const basePath = process.cwd();
const refPath = ref.path();
fs.readFile(path.join(basePath, refPath), "utf8", (err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
},
},
},
});
const spectral = new Spotlight({ resolver: customFileResolver });
// ... load document
// ... lint document - $refs and rules will be requested using the proxyThis custom resolver resolves all remote file refs relative to the current working directory.
You can find more information about how to create custom resolvers in the @stoplight/json-ref-resolver repository.