Skip to content

Commit

Permalink
feat: Support relative $refs and update 1.0 -> 2.0 script
Browse files Browse the repository at this point in the history
  • Loading branch information
jlacivita committed Jan 18, 2024
1 parent 5805869 commit 51690c0
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 10 deletions.
7 changes: 6 additions & 1 deletion src/cli.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import sdk from './sdk/index.mjs'
import docs from './docs/index.mjs'
import openrpc from './openrpc/index.mjs'
import validate from './validate/index.mjs'
import update from './update/index.mjs'

import nopt from 'nopt'
import path from 'path'
Expand Down Expand Up @@ -62,6 +63,10 @@ else if (task === 'validate') {
}
else if (task === 'openrpc') {
openrpc(parsedArgs).then(signOff)
} else {
}
else if (task === 'update') {
update(parsedArgs).then(signOff)
}
else {
console.log("Invalid build type")
}
8 changes: 4 additions & 4 deletions src/openrpc/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ const run = async ({
}) => {

let openrpc = await readJson(template)
const sharedSchemaList = schemas ? (await Promise.all(schemas.map(d => readDir(d, { recursive: true })))).flat() : []
const sharedSchemas = await readFiles(sharedSchemaList)
const sharedSchemaList = schemas ? (await Promise.all(schemas.map(d => readDir(d, { recursive: true, base: path.resolve('.') })))).flat() : []
const sharedSchemas = await readFiles(sharedSchemaList, path.resolve('.'))

try {
const packageJson = await readJson(path.join(input, '..', 'package.json'))
Expand All @@ -54,10 +54,10 @@ const run = async ({
}
})

const moduleList = input ? await readDir(path.join(input, 'openrpc'), { recursive: true }) : []
const moduleList = input ? await readDir(path.join(input, 'openrpc'), { recursive: true, base: path.resolve('.') }) : []
const modules = await readFiles(moduleList, path.resolve('..'))

const descriptionsList = input ? await readDir(path.join(input, 'descriptions'), { recursive: true }) : []
const descriptionsList = input ? await readDir(path.join(input, 'descriptions'), { recursive: true, base: path.resolve('.') }) : []
const markdown = await readFiles(descriptionsList, path.join(input, 'descriptions'))

Object.keys(modules).forEach(key => {
Expand Down
11 changes: 6 additions & 5 deletions src/shared/filesystem.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,18 @@ const readJson = ref => readFile(ref)
const writeJson = (ref, json) => writeText(ref, JSON.stringify(json, null, '\t'))

const readDir = async (ref, options) => {

if (!options.base) {
options.base = path.join(ref, '..')
}

let i = 0
const isJustAFile = lstatSync(ref).isFile()
const files = isJustAFile ? [ { name:'', isDirectory: _ => false } ] : await readdir(ref, { withFileTypes: true })
const results = files.filter(file => !file.isDirectory()).map(file => path.join(ref, file.name))
const results = files.filter(file => !file.isDirectory()).map(file => path.relative(options.base, path.join(ref, file.name)))

if (!options.base) {
options.base = path.join(ref, '..')
}
if (options.recursive) {
for (var index=files.length-1; index>=0; index--) {

if (files[index].isDirectory()) {
results.push(...((await readDir(path.join(ref, files[index].name), options))))
}
Expand Down
6 changes: 6 additions & 0 deletions src/shared/methods.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const tag = (method, name) => method.tags.find(tag => tag.name === name)
export const capabilities = method => tag(method, 'capabilities')
export const provides = method => capabilities(method)['x-provides']
export const pusher = method => capabilities(method)['x-push']
export const notifier = method => method.tags.find(t => t.name === 'notifier')
export const event = method => tag(method, 'event')
143 changes: 143 additions & 0 deletions src/update/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/*
* Copyright 2021 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/

import { readJson, readFiles, readDir, writeJson, writeFiles } from "../shared/filesystem.mjs"
import { addExternalMarkdown, addExternalSchemas, fireboltize } from "../shared/modules.mjs"
import path from "path"
import { logHeader, logSuccess } from "../shared/io.mjs"
import { capabilities, event, provides, pusher } from "../shared/methods.mjs"
import { getPath } from '../shared/json-schema.mjs'

const run = async ({
input: input,
output: output
}) => {

logHeader(`Upgrading modules to latest Firebolt OpenRPC schema`)

console.dir(input)
const moduleList = input ? await readDir(path.join(input, 'openrpc'), { recursive: true }) : []
console.dir(moduleList)
const modules = await readFiles(moduleList, path.resolve('.') + '/.')
console.dir(Object.keys(modules))

Object.keys(modules).forEach(key => {
let json = JSON.parse(modules[key])

// Do the firebolt API magic
update(json)

modules[key] = JSON.stringify(json, null, '\t')

logSuccess(`Updated the ${json.info.title} module.`)
})

await writeFiles(modules)
console.log(Object.keys(modules))

console.log()
logSuccess(`Wrote file ${path.relative('.', output)}`)

return Promise.resolve()
}

function update(json) {
json.methods = json.methods.map(method => {
// update providers
if (provides(method)) {
// handle Provider Interfaces
if (method.name.startsWith('onRequest')) {
// simplify name
method.name = method.name.charAt(9).toLowerCase() + method.name.substr(10)

// move params out of custom extension, and unwrap them into individual parameters
method.params = []
const request = getPath(method.result.schema.$ref, json)
const params = getPath((request.allOf ? request.allOf[1] : request).properties.parameters.$ref, json)

// add required params first, in order listed
params.required && params.required.forEach(p => {
method.params.push({
name: p,
required: true,
schema: params.properties[p]
})
delete params.properties[p]
})

// add unrequired params in arbitrary order... (there's currently no provider method method with more than one unrequired param)
Object.keys(params.properties).forEach(p => {
method.params.push({
name: p,
required: false,
schema: params[p]
})
delete params.properties[p]
})


// move result out of custom extension
method.result = {
name: 'result',
schema: event(method)['x-response']
}

// fix example pairings
method.examples.forEach((example, i) => {
example.params = Object.entries(example.result.value.parameters).map(entry => ({
name: entry[0],
value: entry[1]
}))
const result = method.result.schema.examples ? method.result.schema.examples[Math.min(i, method.result.schema.examples.length-1)] : getPath(method.result.schema.$ref, json).examples[0]
example.result = {
"name": "result",
"value": result
}
})

// delete examples, TODO: this needs to go into the method pairing examples...
delete method.result.schema.examples

// TODO handle x-error

method.tags = method.tags.filter(tag => (tag.name !== "event" && tag.name !== "rpc-only"))
}
}
else if (event(method)) {
console.dir(method.name)
// store the subscriber name in the x-event extension
event(method)['x-event'] = json.info.title + '.' + method.name

// simplify name
method.name = method.name.charAt(2).toLowerCase() + method.name.substr(3)
// move the result into the single param
method.params = [
method.result
]

// rename the event tag to notifier
event(method).name = "notifier"

// remove the result, since this is a notification
delete method.result
}
return method
})
}

export default run

0 comments on commit 51690c0

Please sign in to comment.