Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

run optionally returns output #497

Merged
merged 3 commits into from
Sep 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
### 1.5.4
- Dependency updates
- Option to have `run` resolve with an object containing the outputs. https://github.com/anvilco/spectaql/pull/497

### 1.5.3
- Dependency updates
- Better support for parsing `@spectaql` directive options. https://github.com/anvilco/spectaql/pull/462 Thanks @kylebjordahl
Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,21 @@ You can also see a minimal-ish working example YAML in the [examples/config.yml]

Several options are supported via the CLI. Some are exclusive to the CLI, while others are also possible to specify in the YAML config. Options specified in the CLI take precedence over those that exist in the YAML config. All the supported options and their descriptions can be found in [/src/cli.js][cli].

## Using SpectaQL as a Dependency

In addition to using SpectaQL as a global (or local) binary executable, it can also be used by your Node application as a dependency. More documentation will be coming soon but here is a quick example to get you started:

```node
import { run } from 'spectaql'
...
const spectaqlOtions = {
specFile: 'path/to/your/config.yml',
resolveWithOutput: true,
}
const { html } = await run(spectaqlOptions)
...
```

## Metadata

In our experience, nearly all of the stuff we need for the content of the documentation comes from things supported in GraphQL and introspection queries...but not everything. To supplement some things that are missing, SpectaQL provides support for including "metadata" about your schema that can be used when generating the output. The following options are currently supported:
Expand Down
5 changes: 5 additions & 0 deletions config-example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ spectaql:
# Default: false
displayAllServers: false

# Would you like the "run" function to resolve with an object containing the output as a string?
# Useful if you are using SpectaQL as a dependency (as opposed to running the binary executable)
#
# Default: true
resolveWithOutput: true

introspection:
##############################################
Expand Down
34 changes: 24 additions & 10 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import fs from 'fs'
import path from 'path'
import _ from 'lodash'
import tmp from 'tmp'
Expand All @@ -10,6 +9,8 @@ import {
normalizePathFromRoot,
normalizePathFromCwd,
pathToRoot,
readTextFile,
writeTextFile,
} from './spectaql/utils'

export {
Expand Down Expand Up @@ -68,6 +69,7 @@ const defaults = Object.freeze({
const spectaqlOptionDefaults = Object.freeze({
errorOnInterpolationReferenceNotFound: true,
displayAllServers: false,
resolveWithOutput: true,
})

const spectaqlDirectiveDefault = Object.freeze({
Expand Down Expand Up @@ -329,8 +331,8 @@ export const run = function (cliOptions = {}) {
grunt.log.ok = function () {}
}

var cwd = process.cwd() // change CWD for loadNpmTasks global install
var exists = grunt.file.exists(
const cwd = process.cwd() // change CWD for loadNpmTasks global install
const exists = grunt.file.exists(
path.join(
path.resolve('node_modules'),
'grunt-contrib-concat',
Expand All @@ -353,16 +355,18 @@ export const run = function (cliOptions = {}) {

process.chdir(cwd)

const pathToHtmlFile = opts.cacheDir + '/' + opts.targetFile

grunt.registerTask(
'predentation',
'Remove indentation from generated <pre> tags.',
function () {
var html = fs.readFileSync(opts.cacheDir + '/' + opts.targetFile, 'utf8')
let html = readTextFile(pathToHtmlFile)
html = html.replace(
/<pre.*?><code.*?>([\s\S]*?)<\/code><\/pre>/gim,
function (x, _y) {
var lines = x.split('\n'),
level = null
const lines = x.split('\n')
let level = null
if (lines) {
// Determine the level of indentation
lines.forEach(function (line) {
Expand All @@ -375,15 +379,15 @@ export const run = function (cliOptions = {}) {
})

// Remove indentation
var regex = new RegExp('^\\s{' + level + '}')
const regex = new RegExp('^\\s{' + level + '}')
lines.forEach(function (line, index, lines) {
lines[index] = line.replace(regex, '')
})
}
return lines.join('\n')
}
)
fs.writeFileSync(opts.cacheDir + '/' + opts.targetFile, html)
writeTextFile(pathToHtmlFile, html)
}
)

Expand Down Expand Up @@ -442,7 +446,7 @@ export const run = function (cliOptions = {}) {
})

// Report, etc when all tasks have completed.
var donePromise = new Promise(function (resolve, reject) {
const donePromise = new Promise(function (resolve, reject) {
grunt.task.options({
error: function (e) {
if (!opts.quiet) {
Expand All @@ -455,7 +459,17 @@ export const run = function (cliOptions = {}) {
if (!opts.quiet) {
console.log('All tasks complete')
}
resolve()

let result
if (opts.resolveWithOutput) {
result = {
html: readTextFile(pathToHtmlFile),
// eventually?
// css: '',
// js: '',
}
}
resolve(result)
},
})
})
Expand Down
4 changes: 4 additions & 0 deletions src/spectaql/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ export function readTextFile(pth, options = {}) {
return fs.readFileSync(pth, optionsForReadFileSync)
}

export function writeTextFile(pth, text, _options = {}) {
return fs.writeFileSync(pth, text)
}

export function fileToObject(pathToFile, options = {}) {
let { normalizePath = true, ...otherOptions } = options
if (normalizePath) {
Expand Down
8 changes: 8 additions & 0 deletions test/src/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ describe('index', function () {

expect(options.oneFile).to.be.false

expect(options).to.include({
targetFile: 'index.html',
oneFile: false,
resolveWithOutput: true,
})

expect(options.specData.introspection).to.include({
removeTrailingPeriodFromDescriptions: false,

Expand Down Expand Up @@ -65,6 +71,7 @@ describe('index', function () {
spectaql: {
oneFile: true,
themeDir: './my-custom-theme',
resolveWithOutput: false,
},
introspection: {
url: 'http://mysite.com/graphql',
Expand All @@ -83,6 +90,7 @@ describe('index', function () {

expect(options.oneFile).to.be.true
expect(options.themeDir.endsWith('my-custom-theme')).to.be.true
expect(options.resolveWithOutput).to.be.false
// Not a path
expect(options.specData.introspection.url).to.eql(
'http://mysite.com/graphql'
Expand Down