Skip to content

Commit

Permalink
fix: Validatilon and Transforms
Browse files Browse the repository at this point in the history
  • Loading branch information
jlacivita committed Jun 12, 2024
1 parent 131dbb1 commit e52ef87
Show file tree
Hide file tree
Showing 13 changed files with 201 additions and 223 deletions.
2 changes: 1 addition & 1 deletion languages/javascript/templates/codeblocks/subscriber.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
* Subscriber: ${method.summary}
*
*/
function ${method.alternative}(subscriber: (${method.result.name}: ${method.result.type}) => void): Promise<number>
function ${method.alternative}(subscriber: (${event.result.name}: ${event.result.type}) => void): Promise<number>
3 changes: 3 additions & 0 deletions languages/javascript/templates/codeblocks/transform.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.then( result => {
return Results.transform(result, ${transforms})
})
4 changes: 1 addition & 3 deletions languages/javascript/templates/methods/calls-metrics.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
import { ${method.name} as log${method.Name} } from '../Metrics/index.mjs'

function ${method.name}(${method.params.list}) {
const transforms = ${method.transforms}

const p = Gateway.request('${info.title}.${method.name}', { ${method.params.list} }, transforms)
const p = Gateway.request('${info.title}.${method.name}', { ${method.params.list} })${method.transform}

p.then(_ => {
setTimeout(_ => {
Expand Down
7 changes: 1 addition & 6 deletions languages/javascript/templates/methods/default.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@

function ${method.name}(${method.params.list}) {

const transforms = ${method.transforms}

return Gateway.request('${info.title}.${method.name}', { ${method.params.list} }).then( (result) => {
return Results.transform(result, transforms)
})
return Gateway.request('${info.title}.${method.name}', { ${method.params.list} })
}
6 changes: 2 additions & 4 deletions languages/javascript/templates/methods/polymorphic-reducer.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@

function ${method.name}(${method.params.list}) {
const transforms = ${method.transforms}

if (arguments.length === 1 && Array.isArray(arguments[0])) {
return Gateway.request('${info.title}.${method.name}', arguments[0], transforms)
return Gateway.request('${info.title}.${method.name}', arguments[0])${method.transform}
}
else {
return Gateway.request('${info.title}.${method.name}', { ${method.params.list} }, transforms)
return Gateway.request('${info.title}.${method.name}', { ${method.params.list} })${method.transform}
}
}
4 changes: 1 addition & 3 deletions languages/javascript/templates/methods/temporal-set.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ function ${method.name}(...args) {
else if (typeof args[args.length-1] === 'number') {
timeout = args.pop()
}

const transforms = ${method.transforms}

return TemporalSet.start('${info.title}', '${method.name}', '${method.temporalset.add}', '${method.temporalset.remove}', args, add, remove, timeout, transforms)
return TemporalSet.start('${info.title}', '${method.name}', '${method.temporalset.add}', '${method.temporalset.remove}', args, add, remove, timeout)
}
6 changes: 6 additions & 0 deletions src/firebolt-openrpc.json
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,12 @@
},
"x-provided-by": {
"type": "string"
},
"x-requestor": {
"type": "string"
},
"x-push": {
"type": "boolean"
}
},
"if": {
Expand Down
5 changes: 4 additions & 1 deletion src/macrofier/engine.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1298,6 +1298,7 @@ function insertMethodMacros(template, methodObj, server, client, templates, type
name: methodObj.name.split('.').pop(),
params: methodObj.params.map(p => p.name).join(', '),
transforms: null,
transform: '',
alternative: null,
deprecated: isDeprecatedMethod(methodObj),
context: []
Expand All @@ -1320,6 +1321,7 @@ function insertMethodMacros(template, methodObj, server, client, templates, type
method.transforms = {
methods: getMethodAttributes(flattenedMethod)
}
method.transform = getTemplate('/codeblocks/transform', templates).replace(/\$\{transforms\}/g, JSON.stringify(method.transforms))
}

const paramDelimiter = config.operators ? config.operators.paramDelimiter : ''
Expand Down Expand Up @@ -1370,7 +1372,6 @@ function insertMethodMacros(template, methodObj, server, client, templates, type
const setterFor = methodObj.tags.find(t => t.name === 'setter') && methodObj.tags.find(t => t.name === 'setter')['x-setter-for'] || ''
const pullsResult = (puller || pullsFor) ? localizeDependencies(pullsFor || methodObj, server).params.findLast(x=>true).schema : null
const pullsParams = (puller || pullsFor) ? localizeDependencies(getPayloadFromEvent(puller || methodObj, document), document, null, { mergeAllOfs: true }).properties.parameters : null

const pullsResultType = (pullsResult && (type === 'methods')) ? Types.getSchemaShape(pullsResult, server, { templateDir: state.typeTemplateDir, namespace: !config.copySchemasIntoModules }) : ''
const pullsForType = pullsResult && Types.getSchemaType(pullsResult, server, { templateDir: state.typeTemplateDir, namespace: !config.copySchemasIntoModules })
const pullsParamsType = (pullsParams && (type === 'methods')) ? Types.getSchemaShape(pullsParams, server, { templateDir: state.typeTemplateDir, namespace: !config.copySchemasIntoModules }) : ''
Expand Down Expand Up @@ -1512,6 +1513,7 @@ function insertMethodMacros(template, methodObj, server, client, templates, type
.replace(/\$\{method\.property\.readonly\}/g, !getSetterFor(methodObj.name, server))
.replace(/\$\{method\.temporalset\.add\}/g, temporalAddName)
.replace(/\$\{method\.temporalset\.remove\}/g, temporalRemoveName)
.replace(/\$\{method\.transform}/g, method.transform)
.replace(/\$\{method\.transforms}/g, JSON.stringify(method.transforms))
.replace(/\$\{method\.seeAlso\}/g, seeAlso)
.replace(/\$\{method\.item\}/g, itemName)
Expand All @@ -1523,6 +1525,7 @@ function insertMethodMacros(template, methodObj, server, client, templates, type
.replace(/\$\{method\.result\.type\}/g, Types.getSchemaType(result.schema, server, { templateDir: state.typeTemplateDir, title: true, asPath: false, result: true, namespace: !config.copySchemasIntoModules })) //, baseUrl: options.baseUrl
.replace(/\$\{method\.result\.json\}/g, Types.getSchemaType(result.schema, server, { templateDir: 'json-types', title: true, code: false, link: false, asPath: false, expandEnums: false, namespace: !config.copySchemasIntoModules }))
.replace(/\$\{event\.result\.type\}/g, isEventMethod(methodObj) ? Types.getSchemaType(event.result.schema, document, { templateDir: state.typeTemplateDir, title: true, asPath: false, result: true, namespace: !config.copySchemasIntoModules }) : '')
.replace(/\$\{event\.result\.name\}/g, isEventMethod(methodObj) ? event.result.name : '')
.replace(/\$\{event\.result\.json\.type\}/g, resultJsonType)
.replace(/\$\{event\.result\.json\.type\}/g, callbackResultJsonType)
.replace(/\$\{event\.pulls\.param\.name\}/g, pullsEventParamName)
Expand Down
7 changes: 4 additions & 3 deletions src/openrpc/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ const run = async ({
server: server,
template: template,
schemas: schemas,
argv: {
remain: moduleWhitelist
}
}) => {

let serverOpenRPC = await readJson(template)
Expand Down Expand Up @@ -66,9 +69,7 @@ const run = async ({
const isClientAPI = method => client && (isNotifier(method) || isProvider(method))
const isServerAPI = method => !isClientAPI(method)

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

Object.values(modules).map(JSON.parse).filter(m => moduleWhitelist.length ? moduleWhitelist.includes(m.info.title) : true).forEach(json => {
// pull in external markdown files for descriptions
json = addExternalMarkdown(json, markdown)

Expand Down
2 changes: 2 additions & 0 deletions src/shared/methods.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ export const rename = (method, renamer) => method.name.split('.').map((x, i, arr

export const getNotifier = (method, client) => client.methods.find(m => m.name === method.tags.find(t => t.name === "event")['x-notifier'])
export const getEvent = (method, server) => server.methods.find(m => m.name === method.tags.find(t => t.name === "notifier")['x-event'])
export const getCapability = (method) => Object.values(capabilities(method)).map(v => Array.isArray(v) ? v.shift() : v).filter(v => typeof v === 'string').find(x => (x.startsWith('xrn:firebolt:capability')))
export const getRole = (method) => Object.keys(capabilities(method)).find(x => ['x-uses', 'x-provides', 'x-manages'].includes(x))

export const provides = (method) => extension(method, 'x-provides')

132 changes: 54 additions & 78 deletions src/shared/modules.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import predicates from 'crocks/predicates/index.js'
import { getExternalSchemaPaths, isDefinitionReferencedBySchema, isNull, localizeDependencies, isSchema, getLocalSchemaPaths, replaceRef, getPropertySchema, getLinkedSchemaUris, getAllValuesForName, replaceUri } from './json-schema.mjs'
import { getReferencedSchema } from './json-schema.mjs'
const { isObject, isArray, propEq, pathSatisfies, hasProp, propSatisfies } = predicates
import { extension, getNotifier, name as methodName, rename as methodRename, provides } from './methods.mjs'
import { extension, getNotifier, isEvent, isNotifier, isPusher, name as methodName, rename as methodRename, provides } from './methods.mjs'

// TODO remove these when major/rpc branch is merged
const name = method => method.name.split('.').pop()
Expand Down Expand Up @@ -98,7 +98,11 @@ const getProvidedCapabilities = (json) => {
return Array.from(new Set([...getMethods(json).filter(isProviderInterfaceMethod).map(method => method.tags.find(tag => tag['x-provides'])['x-provides'])]))
}
const getProvidedInterfaces = (json) => {
// return json.methods?.filter(m => extension(m, 'x-interface')).map(m => extension(m, 'x-interface')) || []
return getInterfaces(json)

const list = Array.from(new Set((json.methods || []).filter(m => m.tags.find(t => t['x-provides']))
.filter(m => !extension(m, 'x-push'))
.filter(m => !m.tags.find(t => t.name.startsWith('polymorphic-pull')))
.map(m => m.name.split('.')[0])))

Expand All @@ -109,6 +113,7 @@ const getInterfaces = (json) => {
const list = Array.from(new Set((json.methods || []).filter(m => m.tags.find(t => t['x-provides']))
.filter(m => !m.tags.find(t => t.name.startsWith('registration')))
.filter(m => !m.tags.find(t => t.name.startsWith('polymorphic-pull')))
.filter(m => !extension(m, 'x-push'))
.map(m => m.name.split('.')[0])))

return list
Expand Down Expand Up @@ -370,7 +375,7 @@ const getPayloadFromEvent = (event, client) => {
}
}
catch (error) {
console.dir(event)
m(event)
throw error
}
}
Expand Down Expand Up @@ -467,25 +472,50 @@ const createEventResultSchemaFromProperty = (property, type='Changed') => {
}
}

const createNotifierFromProperty = property => {
const createNotifierFromProperty = (property, type='Changed') => {
const subscriberType = property.tags.map(t => t['x-subscriber-type']).find(t => typeof t === 'string') || 'context'

const notifier = JSON.parse(JSON.stringify(property))
notifier.name = methodRename(notifier, name => name + 'Changed')
notifier.name = methodRename(notifier, name => name + type)

Object.assign(notifier.tags.find(t => t.name.startsWith('property')), {
name: 'notifier',
'x-notifier-for': property.name,
'x-event': methodRename(notifier, name => 'on' + name.charAt(0).toUpperCase() + name.substring(1))
})

notifier.params.push(notifier.result)
delete notifier.result
if (subscriberType === 'global') {
notifier.params = [
{
name: "info",
schema: {
"$ref": "#/components/schemas/" + methodRename(notifier, name => name.charAt(0).toUpperCase() + name.substr(1) + 'Info')
}
}
]
}
else {
notifier.params.push(notifier.result)
}

notifier.examples.forEach(example => {
example.params.push(example.result)
delete example.result
})
delete notifier.result

if (subscriberType === 'global') {
notifier.examples = property.examples.map(example => ({
params: [
{
name: "info",
value: Object.assign(Object.fromEntries(example.params.map(p => [p.name, p.value])), Object.fromEntries([[example.result.name, example.result.value]]))
}
]
}))
}
else {
notifier.examples.forEach(example => {
example.params.push(example.result)
delete example.result
})
}

return notifier
}
Expand Down Expand Up @@ -573,65 +603,19 @@ const createPullEventFromPush = (pusher, json) => {
return event
}

const createPullProvider = (requestor, params) => {
const event = eventDefaults(JSON.parse(JSON.stringify(requestor)))
event.name = requestor.tags.find(t => t['x-provided-by'])['x-provided-by']
const createPullProvider = (requestor) => {
const provider = JSON.parse(JSON.stringify(requestor))
provider.name = requestor.tags.find(t => t['x-provided-by'])['x-provided-by']
const old_tags = JSON.parse(JSON.stringify(requestor.tags))

const value = event.result

event.tags[0]['x-response'] = value.schema
event.tags[0]['x-response'].examples = event.examples.map(e => e.result.value)

event.result = {
"name": "request",
"schema": {
"type": "object",
"required": ["correlationId", "parameters"],
"properties":{
"correlationId": {
"type": "string",
},
"parameters": {
"$ref": "#/components/schemas/" + params
}
},
"additionalProperties": false
}
}

event.params = []

event.examples = event.examples.map(example => {
example.result = {
"name": "request",
"value": {
"correlationId": "xyz",
"parameters": {}
}
}
example.params.forEach(p => {
example.result.value.parameters[p.name] = p.value
})
example.params = []
return example
})

old_tags.forEach(t => {
if (t.name !== 'push-pull')
{
event.tags.push(t)
}
})

const caps = event.tags.find(t => t.name === 'capabilities')
const caps = provider.tags.find(t => t.name === 'capabilities')
caps['x-provides'] = caps['x-uses'].pop() || caps['x-manages'].pop()
caps['x-requestor'] = requestor.name
delete caps['x-uses']
delete caps['x-manages']
delete caps['x-provided-by']

return event
return provider
}

const createPullProviderParams = (requestor) => {
Expand Down Expand Up @@ -1038,21 +1022,13 @@ const generatePolymorphicPullEvents = json => {
}

const generateProvidedByMethods = json => {
const requestors = json.methods.filter(m => !m.tags.find(t => t.name === 'event')).filter( m => m.tags && m.tags.find( t => t['x-provided-by'])) || []
const events = json.methods .filter(m => m.tags.find(t => t.name === 'event'))
.filter( m => m.tags && m.tags.find( t => t['x-provided-by']))
.filter(e => !json.methods.find(m => m.name === e.tags.find(t => t['x-provided-by'])['x-provided-by']))

const pushers = events.map(m => createNotifierFromEvent(m, json))
pushers.forEach(m => json.methods.push(m))
const requestors = json.methods.filter(m => !m.tags.find(t => t.name === 'notifier')).filter( m => m.tags && m.tags.find( t => t['x-provided-by'])) || []

requestors.forEach(requestor => {
const schema = createPullProviderParams(requestor)
json.methods.push(createPullProvider(requestor, schema.title))

json.components = json.components || {}
json.components.schemas = json.components.schemas || {}
json.components.schemas[schema.title] = schema
const provider = json.methods.find(m => (m.name === extension(requestor, 'x-provided-by')) && provides(m) && !isEvent(m) && !isPusher(m) && !isNotifier(m))
if (!provider) {
json.methods.push(createPullProvider(requestor))
}
})

return json
Expand Down Expand Up @@ -1187,7 +1163,7 @@ const generateEventSubscribers = json => {
const tag = notifier.tags.find(tag => tag.name === 'notifier')
// if there's an x-event extension, this denotes an editorially created subscriber
if (!tag['x-event']) {
tag['x-event'] = methodRename(notifier, name => 'on' + name.charAt(0).toUpperCase() +! name.substring(1))
tag['x-event'] = methodRename(notifier, name => 'on' + name.charAt(0).toUpperCase() + name.substring(1))
}
const subscriber = json.methods.find(method => method.name === tag['x-event'])

Expand Down Expand Up @@ -1250,7 +1226,7 @@ const generateProviderRegistrars = json => {

if (!registration) {
json.methods.push({
name: name + ".provide",
name: `${name}.provide`,
tags: [
{
"name": "registration",
Expand Down Expand Up @@ -1605,7 +1581,7 @@ const fireboltize = (json, bidirectional) => {
json = generatePropertySetters(json)
// TODO: we don't use this yet... consider removing?
// json = generatePushPullMethods(json)
// json = generateProvidedByMethods(json)
json = generateProvidedByMethods(json)
json = generatePolymorphicPullEvents(json)

if (bidirectional) {
Expand Down Expand Up @@ -1890,7 +1866,7 @@ const getClientModule = (name, client, server) => {
let openrpc = JSON.parse(JSON.stringify(client))

openrpc.methods = openrpc.methods
.filter(method => notifierFor(method) && notifierFor(method).startsWith(name + '.') || interfaces.find(name => method.name.startsWith(name + '.')))
.filter(method => (notifierFor(method) && notifierFor(method).startsWith(name + '.') || interfaces.find(name => method.name.startsWith(name + '.'))))
openrpc.info.title = name
openrpc.components.schemas = Object.fromEntries(Object.entries(openrpc.components.schemas).filter( ([key, schema]) => key.startsWith('http') || key.split('.')[0] === name))
if (client.info['x-module-descriptions'] && client.info['x-module-descriptions'][name]) {
Expand Down
Loading

0 comments on commit e52ef87

Please sign in to comment.