From a104a067f54bcbb8226f136cf0db63ab4f97c45a Mon Sep 17 00:00:00 2001 From: Rafa Mel Date: Thu, 18 Feb 2021 10:33:50 +0100 Subject: [PATCH] feat(tasks): adds consume function parse --- src/helpers/parse-record.ts | 84 +++++++++++++++++++++++++++++++++++++ src/tasks/consume/index.ts | 1 + src/tasks/consume/parse.ts | 17 ++++++++ 3 files changed, 102 insertions(+) create mode 100644 src/helpers/parse-record.ts create mode 100644 src/tasks/consume/parse.ts diff --git a/src/helpers/parse-record.ts b/src/helpers/parse-record.ts new file mode 100644 index 0000000..5cc0465 --- /dev/null +++ b/src/helpers/parse-record.ts @@ -0,0 +1,84 @@ +import { Task } from '../definitions'; +import { series } from '../tasks/transform/series'; +import { context } from '../tasks/transform/context'; +import ObjectPath from 'objectpath'; + +export interface TaskItem { + name: string; + route: string[]; + task: Task; +} + +/** + * Returns an ordered array + */ +export function parseRecord( + record: Task.Record, + cb?: (route: string[]) => string +): TaskItem[] { + const names: string[] = []; + + return parseRecordHelper(record).map(([route, task]) => { + const name = cb ? cb(route) : ObjectPath.stringify(route, "'", false); + + if (names.includes(name)) { + throw Error(`Name collusion on parse: ${name}`); + } + + names.push(name); + return { name, route, task }; + }); +} + +function parseRecordHelper(record: Task.Record): Array<[string[], Task]> { + const arr: Array<[string[], Task]> = []; + + for (const [name, task] of Object.entries(record)) { + if (typeof task === 'function') { + arr.push([ + [name], + context( + (ctx) => ({ + ...ctx, + route: ctx.route.slice(0, -1).concat(name) + }), + task + ) + ]); + } else { + const all: Task[] = []; + const every: Array<[string[], Task]> = []; + for (const [route, bTask] of parseRecordHelper(task)) { + every.push([[name, ...route], bTask]); + + if (route.length <= 1) { + const bName = route.slice(-1)[0]; + all.push( + context( + (ctx) => ({ + ...ctx, + route: ctx.route.slice(0, -1).concat(bName) + }), + bTask + ) + ); + } + } + + if (all.length) { + arr.push([ + [name], + context( + (ctx) => ({ ...ctx, route: ctx.route.slice(0, -1).concat(name) }), + series(...all) + ) + ]); + } + if (every.length) { + arr.push(...every); + } + } + } + + return arr; +} diff --git a/src/tasks/consume/index.ts b/src/tasks/consume/index.ts index 2e6f967..1b9c6c6 100644 --- a/src/tasks/consume/index.ts +++ b/src/tasks/consume/index.ts @@ -1 +1,2 @@ +export * from './parse'; export * from './run'; diff --git a/src/tasks/consume/parse.ts b/src/tasks/consume/parse.ts new file mode 100644 index 0000000..2da88b4 --- /dev/null +++ b/src/tasks/consume/parse.ts @@ -0,0 +1,17 @@ +import { Task } from '../../definitions'; +import { parseRecord } from '../../helpers/parse-record'; +import { Members } from 'type-core'; + +export function parse( + tasks: Task.Record, + cb?: (route: string[]) => string +): Members { + const arr = parseRecord(tasks, cb); + + const members: Members = {}; + for (const item of arr) { + members[item.name] = item.task; + } + + return members; +}