Skip to content

Commit

Permalink
Merge pull request #11 from guhmerces/feat/initial_structure
Browse files Browse the repository at this point in the history
Feat/initial structure
  • Loading branch information
rjrodger authored Aug 8, 2022
2 parents 6226638 + 9486308 commit 2e70030
Show file tree
Hide file tree
Showing 11 changed files with 419 additions and 84 deletions.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@
"seneca-promisify": ">=2"
},
"dependencies": {
"eventbrite": "^1.3.0"
"@types/lodash": "^4.14.178",
"eventbrite": "^1.3.0",
"lodash": "^4.17.21",
"msw": "^0.36.8"
}
}
36 changes: 35 additions & 1 deletion src/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,42 @@ const entities: EntityMap = {
method: "get",
path: "/events/:event_id/",
},
after: [
{ on: 'outent', field: 'event_id', set: { query: 'event_id' } }
]
},
save: {
request: {
method: "post",
path: "/events/:event_id/",
body: {
event: [
'name',
'description',
'start',
'end',
'currency',
'online_event',
'organizer_id',
'listed',
'shareable',
'invite_only',
'show_remaining',
'password',
'capacity',
'is_reserved_seating',
'is_series',
'show_pick_a_seat',
'show_seatmap_thumbnail',
'show_colors_in_seatmap_thumbnail',
]
},
},
before: [
{ on:'query', field: 'attribute', set: { query: 'event_id' } }
{ on: 'req', del: 'event.start.local' },
{ on: 'req', del: 'event.end.local' },
{ on: 'req', del: 'event.name.text' },
{ on: 'req', del: 'event.description.text' },
]
}
},
Expand Down
61 changes: 28 additions & 33 deletions src/eventbrite-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Sdk } from 'eventbrite/lib/types'
import { entities } from './entities'
import { make_actions } from './make-actions'
import { make_request } from './make-request'
import { ActionData, EntityMap } from './types'
import { EntData, EntityMap } from './types'

type EventbriteProviderOptions = {}

Expand All @@ -20,57 +20,52 @@ function EventbriteProvider(this: any, options: any) {
add_actions()

function add_actions() {
const actions = prepare_actions(entities)

for (const action of actions) {
switch (action.pattern.cmd) {
case 'load':
seneca.message(action.pattern, make_load(action))
break

case 'save':
seneca.message(action.pattern, make_save(action))
break
}
}
const ents = prepare_ents(entities)

for(const ent of ents) {
seneca.message(ent.load.pattern, (make_load(ent) || unknown_cmd))
seneca.message(ent.save.pattern, (make_save(ent) || unknown_cmd))
}
}

function make_load(action: ActionData) {
return make_actions(action)['load']
function make_load(ent: EntData) {
if(!ent.load.details) return false
return make_actions(ent.load).load
}

function make_save(action: ActionData) {
return make_actions(action)['save']
function make_save(ent: EntData) {
if(!ent.save.details) return false
return make_actions(ent.save).save
}

async function unknown_cmd(this: any, msg: any) {
throw new Error(`undefined action: ${msg.cmd}, entity: ${msg.ent.entity$}`)
}

// prepare links replacing placeholders
function prepare_actions(entities: EntityMap): ActionData[] {
const actions_details: ActionData[] = []
function prepare_ents(entities: EntityMap): EntData[] {
const ents_datas: EntData[] = []

for(const [ent_name, ent_details] of Object.entries(entities)) {
ent_details.name = ent_name
const ent_data: any = { load : {}, save: {} }

for(const [action_name, action_data] of Object.entries(ent_details.actions)) {
const common = {zone:'provider', base:'eventbrite', role:'entity', name: ent_name}

const pattern = {
name: ent_name,
cmd: action_name,
zone: 'provider',
base: 'eventbrite',
role: 'entity',
}
ent_data.load.pattern = {...common, cmd: 'load'}
ent_data.save.pattern = {...common, cmd: 'save'}

actions_details.push({
pattern,
req_fn: prepare_req_fn(action_data.request.method),
...action_data
for(const [action_name, details] of Object.entries(ent_details.actions)) {
Object.assign(ent_data[action_name], {
details,
req_fn: prepare_req_fn(details.request.method)
})
}

ents_datas.push(ent_data)
}
return actions_details

return ents_datas
}

function prepare_req_fn(method: string) {
Expand Down
52 changes: 49 additions & 3 deletions src/make-actions.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { ActionData } from "./types"
import { ActionData, Context } from "./types"
import { perform_tasks } from "./utils"

function make_actions(action_data: ActionData) {
const { req_fn, request, after, before } = action_data
const { req_fn, details } = action_data
const { request, after, before } = details
const { path } = request

async function load(this:any, msg:any) {
const { q } = msg

const context = {
const context: Context = {
query: q,
}

Expand All @@ -34,7 +35,52 @@ function make_actions(action_data: ActionData) {
}

async function save(this:any, msg:any) {
const { q, ent } = msg
let body: Record<string, any> = {}

let context: Context = {
query: q,
inent: ent,
}

const built_path = build_path(path, ent)

if(action_data.details.request.body) {
body = fill_body(action_data.details.request.body, ent)
}

if(before) {
context = perform_tasks(before, {...context, req: body})
}


const res = await req_fn(built_path, {
body: JSON.stringify(context.req)
})

const outent = this.make$(msg.ent.entity$).data$(res)

if(after) {
perform_tasks(after, {
res,
outent,
...context
})
}

return outent
}

function fill_body(body_specs: Record<string, Array<string>>, entity: Record<string, any>) {
let body: Record<string, any> = {}
for(const [key, body_args] of Object.entries(body_specs)) {
body[key] = {}
body_args.forEach(attr => {
body[key][attr] = entity[attr]
})
}

return body
}

function build_path(path: string, args: Record<string, any>) {
Expand Down
30 changes: 20 additions & 10 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,21 @@ type Actions = "load" | "save"
type ReqDetails = {
method: string
path: string
body_spec?: Record<string,any>
body?: Record<string, Array<string>>
}

type TasksTypes = SetTask | DelTask

type Task = {
on: keyof Context
field: string
set?: Set
}

type Set = {
[key in keyof Context]: string
interface SetTask extends Task {
field: string
set: {[key in keyof Context]: string}
}
interface DelTask extends Task {
del: string
}

type Context = {
Expand All @@ -30,8 +34,8 @@ type Context = {

type ActionDetails = {
request: ReqDetails
after?: Task[]
before?: Task[]
after?: TasksTypes[]
before?: TasksTypes[]
}

type EntDetails = {
Expand All @@ -42,12 +46,18 @@ type EntDetails = {
}

type TasksTypesFn = {
set: (task: Task, context: Context) => void
set: (task: SetTask, context: Context) => void
del: (task: DelTask, context: Context) => void
}

interface ActionData extends ActionDetails {
type ActionData = {
pattern: Record<string,string>
details: ActionDetails
req_fn: (path:string, options?: Record<any,string>) => Promise<any>
}

export type { EntityMap, EntDetails, ActionData, Task, Context, TasksTypesFn }
type EntData = {
[key in Actions]: ActionData
}

export type { Actions, EntityMap, EntDetails, ActionData, Task, Context, TasksTypesFn, SetTask, DelTask, EntData }
35 changes: 20 additions & 15 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
import { Context, Task, TasksTypesFn } from "./types"
import { Context, DelTask, SetTask, Task, TasksTypesFn } from "./types"
import * as _ from 'lodash'

function perform_tasks(tasks: Task[], context: Context ) {
tasks.forEach(task => {
const [_, __, ...types] = Object.keys(task)
const tasks = _.omit(task ,['on', 'field'])

types.forEach(type => {
const typeFn = tasksTypes[type as keyof TasksTypesFn]

if(!typeFn) {
for(const [type, data] of Object.entries(tasks)) {
const taskFn = tasksTypes[type as keyof TasksTypesFn]
if(!taskFn) {
throw new Error('unable to find task of type ' + type)
}

typeFn(task, context)
})
taskFn(task as DelTask & SetTask, context)
}
})

return context
}

function set(task: Task, context: Context) {
if(!task.set) {
return
}

function set(task: SetTask, context: Context) {
const source_name = Object.keys(task.set)[0]

if(!source_name) {
Expand All @@ -38,8 +35,16 @@ function set(task: Task, context: Context) {
target[target_field] = source[source_field]
}

function del(task: DelTask, context: Context) {
let target = context[task.on]
const field = task.del

context[task.on] = _.omit(target, [field])
}

const tasksTypes: TasksTypesFn = {
set
set,
del
}

export { perform_tasks };
Expand Down
40 changes: 40 additions & 0 deletions test/ents-tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { TestEntityMap } from "./types"

let test_args = {
event_id: '238083523227'
}

const ents_tests: TestEntityMap = {
event: {
load: {
args: {
event_id: test_args.event_id,
},
expectations: {
id: {
sameAs: test_args.event_id,
},
},
},
save: {
changes: {
description: {
html: '74a46e44d0cb9bcb5f8b'
},
},
expectations: {
id: {
sameAs: test_args.event_id,
},
description: {
toMatchObject: {
text: '74a46e44d0cb9bcb5f8b',
html: '74a46e44d0cb9bcb5f8b'
},
},
},
},
},
}

export { ents_tests }
Loading

0 comments on commit 2e70030

Please sign in to comment.