You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
stringifyRequestData: (data)=>{return(qs.stringify(data,{serializeDate: (d)=>Math.floor(d.getTime()/1000),})// Don't use strict form encoding by changing the square bracket control// characters back to their literals. This is fine by the server, and// makes these parameter strings easier to read..replace(/%5B/g,'[').replace(/%5D/g,']'));},
{service: "stripe",name: "rest:post",parameters: [{// overriding the default stylein: "searchParams",name: "date_between",style: "pipeDelimited",mapping: [["get",{path: "args.date_between"}]],},{// demonstrating this is same as our current directive pipelinein: "searchParams",name: "dinner",mapping: [["get",{path: "args.random.fish"}],["toLowerCase",{}],],},{// simple examplein: "path",name: "account",mapping: [["get",{path: "claims.sub"}]],},{// using root indicator '$', a sort will place this first so we'll effectively extend (if value is an object) this with later valuesin: "form",name: "$",mapping: [["get",{path: "args.random"}]],},{// going to nest an object then extend itin: "form",name: "nested_and_extended",mapping: [["get",{path: "args.random"}]],},{// override explode and style settings, `nested_and_extended` will be extended rather than overwritten if it is an extendable type (Object)in: "form",name: "nested_and_extended",objectExtend: true,explode: false,style: "form",mapping: [["get",{path: "args.list_items[0]"}]],},{// array push notation, irrelevant here, but important on the next onein: "form",name: "line_items",mapping: [["get",{path: "args.line_items"}]],},{// array push option here prevents overwriting `line_items`. Returned array will be concatenated, anything else will be pushed. If the existing value is not an array it will be overwritten with the array output of this.in: "form",name: "line_items",arrayPush: true,mapping: [["get",{path: "args.random"}]],},{// this name syntax allows setting a property on each item in the array, this may not be a good idea (perhaps should be handled as a special directive)in: "form",name: "line_items[].coupon",mapping: [["set",{value: "COUPON_CODE"}]],},{// override default style and explodein: "form",name: "mode",style: "form",explode: false,value: ["subscription","one-off"],},{// override style and nested object notationin: "form",name: "deep.path",style: "form",explode: false,value: "SPINDRIFT",},{// our existing Stripe examplein: "form",name: "expand",mapping: [["get",{path: "args.expand"}]],},{// our existing Stripe examplein: "form",name: "expand",arrayPush: true,value: "field_i_really_want",},],parametersOptions: {form: {style: "deepObject",explode: true,},path: {style: "simple",},searchParams: {style: "deepObject",explode: true,},},}
parameters uses a new config format, moving away from tuples to arrays of config options
parametersOptions has broad configuration options for how parameters are used. These pertain to serialization style and formatting. They are effectively defaults, which any individual parameter can override.
The special parameter name $ referring to the root of the hypothetical object representation of the parameter.
value which allows you to directly set (in the schema) the value of a key
mapping which evaluates an array of directives to get a value
objectExtend and arrayPush as explicit operations — presumably these could be set as default behaviors via the parametersOptions.
Extended use case
With this new format it becomes possible to do batch operations, say we had an earlier resolver return a
list and we want to iterate over a particular property.
{service: "stripe",name: "rest:batch:get",parameters: [{in: "searchParams",name: "expand",value: ["prices","invoices"],},{// batchKey identifies this as the parameter to iterate over to make multiple requests, schema validation could enforce having only one of thesein: "path",name: "product",batchKey: true,mapping: [["jsonPath",{path: "steps.listCustomerProducts.data.items[*].productId"},],],},],}
{service: "stripe",name: "rest:post",searchParams: {ops: [{op: "set",// the default, doesn't need to be specificpath: "date_between",mapping: [["get",{path: "args.date_between"}]],},{path: "dinner",mapping: [["get",{path: "args.random.fish"}],["toLowerCase",{}],],},],serialize: {date_between: {style: "pipeDelimited",},},},pathParams: {ops: [{path: "account",mapping: [["get",{path: "claims.sub"}]],},],},form: {ops: [{path: "$",mapping: [["get",{path: "args.random"}]],},{// Example of the flexibility of the `ops` approach, we can extend a base object, then remove props we might not wantop: "remove",path: "price",mapping: [["get",{path: "args.random"}]],},{// extend will coerce this to an object, e.g., if args.random = 'foo' `nested_and_extended: { foo: 'foo' }`op: "extend",path: "nested_and_extended",mapping: [["get",{path: "args.random"}]],},{// object coercion and then object extend — basically the op ensures an object in the outputop: "extend",path: "nested_and_extended",mapping: [["get",{path: "args.list_items[0]"}]],},{// If we explicitly set the empty brackets, coerce any result to an array.path: "line_items[]",// OR, maybe we use these two and avoid custom syntaxop: "push",path: "line_items",mapping: [["get",{path: "args.line_items"}]],},{/* This is how we handle the concat/push behavior, similar to: * { line_items: [...args.line_items, isArray(args.random) ? ...args.random : args.random] } **/path: "line_items[]",// ORop: "push",path: "line_items",mapping: [["get",{path: "args.random"}]],},{// Syntax, inspired by jsonpath-plus, for operating on every item in an arraypath: "line_items[*].coupon",// This one trips me up, as I can't think of a "boring" syntax for describing thismapping: [["set",{value: "COUPON_CODE"}]],},{path: "mode",value: ["subscription","one-off"],},{path: "deep.path",value: "SPINDRIFT",},{path: "expand[]",mapping: [["get",{path: "args.expand"}]],},{path: "expand[]",value: "field_i_really_want",},],serialize: {nested_and_extended: {explode: false,style: "form"},mode: {explode: false,style: "form"},deep: {explode: false,style: "form"},expand: {explode: true,style: "deepObject"},},},}
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Also objectExtend: true and arrayPush: true feel like they should be the defaults or there should be an op: 'set' | 'push' | 'extend' property on each line and we'd change the set: [..] key to ops: [..]
I don't quite follow this. Could you flesh out an example?
Also objectExtend: true and arrayPush: true feel like they should be the defaults or there should be an op: 'set' | 'push' | 'extend' property on each line and we'd change the set: [..] key to ops: [..]
I don't quite follow this. Could you flesh out an example?
constresolverConfig={"service": "stripe","name": "rest:post","searchParams": {"ops": [{"name": "date_between","mapping": [["get",{"path": "args.date_between"}]]},{"name": "dinner","mapping": [["get",{"path": "args.random.fish"}],["toLowerCase",{}]]}],"serialize": {"date_between": {"style": "pipeDelimited"}}},"pathParams": [{// simple example"name": "account","mapping": [["get",{"path": "claims.sub"}]]}],"form": {"ops": [{// going to nest an object then extend it"name": "nested_and_extended","mapping": [["get",{"path": "args.random"}]]},{// override explode and style settings, `nested_and_extended` will be extended rather than overwritten if it is an extendable type (Object)"name": "nested_and_extended","op": "extend","mapping": [["get",{"path": "args.list_items[0]"}]]},{// array push notation, irrelevant here, but important on the next one"name": "line_items","mapping": [["get",{"path": "args.line_items"}]]},{// array push option here prevents overwriting `line_items`. Returned array will be concatenated, anything else will be pushed. If the existing value is not an array it will be overwritten with the array output of this."name": "line_items","op": "push","mapping": [["get",{"path": "args.random"}]]},{// this name syntax allows setting a property on each item in the array, this may not be a good idea (perhaps should be handled as a special directive)"name": "line_items[].coupon","mapping": [["set",{"value": "COUPON_CODE"}]]},{// override default style and explode"name": "mode","value": ["subscription","one-off"]},{// override style and nested object notation"name": "deep.path","value": "SPINDRIFT"},{// our existing Stripe example"name": "expand","mapping": [["get",{"path": "args.expand"}]]},{// our existing Stripe example"name": "expand","op": "push","value": "field_i_really_want"}],"serialize": {"nested_and_extended": {"explode": false,"style": "form"},"mode": {"explode": false,"style": "form"},"deep": {"explode": false,"style": "form"}}}}
I don't quite follow this. Could you flesh out an example?