UNPKG

3.36 kBPlain TextView Raw
1import {
2 ExternalDataSource,
3 ExternalDataSourceHelper,
4 Converter as ConverterI,
5 ConverterInstructions,
6 CONVERTER_SPREAD_INSTRUCTION,
7 BaseUrls
8} from "../typings";
9import formatQuillDelta from "./content/formatQuillDelta";
10import url from "url";
11
12export type ExternalDataSourceWithOptionalHelper =
13 | ExternalDataSource
14 | ((helper: ExternalDataSourceHelper) => ExternalDataSource);
15
16type Opts = {
17 baseUrls: Partial<BaseUrls>;
18};
19
20type GenericDict = { [key: string]: any };
21
22const SPREAD: CONVERTER_SPREAD_INSTRUCTION = "$$CONVERTER_SPREAD";
23
24function convert<From, To>(
25 inputs: From,
26 passThrough: Array<keyof From>,
27 instructions: ConverterInstructions<From, To>
28) {
29 return Object.keys(instructions).reduce(
30 async (memo: Promise<GenericDict>, key) => {
31 const [resolvedMemo, value] = await Promise.all([
32 memo,
33 (instructions as GenericDict)[key as string](inputs)
34 ]);
35
36 if (key === SPREAD) {
37 return {
38 ...resolvedMemo,
39 ...value
40 } as To;
41 }
42
43 return {
44 ...resolvedMemo,
45 [key]: value
46 } as To;
47 },
48 Promise.resolve(
49 passThrough.reduce(
50 (memo: GenericDict, key) => {
51 memo[key as string] = (inputs as GenericDict)[key as string];
52
53 return memo as To;
54 },
55 {} as GenericDict
56 )
57 )
58 ) as Promise<To>;
59}
60
61class Converter<ApiDataSet, HubDataSet>
62 implements ConverterI<ApiDataSet, HubDataSet> {
63 static SPREAD = SPREAD;
64 private passThroughKeys: Array<keyof ApiDataSet>;
65 private toHubInstructions: ConverterInstructions<ApiDataSet, HubDataSet>;
66 private fromHubInstructions: ConverterInstructions<HubDataSet, ApiDataSet>;
67
68 constructor(
69 passThrough: Array<keyof ApiDataSet>,
70 toHub: ConverterInstructions<ApiDataSet, HubDataSet> = {},
71 fromHub: ConverterInstructions<HubDataSet, ApiDataSet> = {}
72 ) {
73 this.passThroughKeys = passThrough;
74 this.toHubInstructions = toHub;
75 this.fromHubInstructions = fromHub;
76 this.toHub = this.toHub.bind(this);
77 this.fromHub = this.fromHub.bind(this);
78 }
79 toHub(input: ApiDataSet): Promise<HubDataSet> {
80 return convert<ApiDataSet, HubDataSet>(
81 input,
82 this.passThroughKeys,
83 this.toHubInstructions
84 );
85 }
86 fromHub(input: HubDataSet): Promise<ApiDataSet> {
87 return convert<HubDataSet, ApiDataSet>(
88 input,
89 (this.passThroughKeys as unknown) as Array<keyof HubDataSet>,
90 this.fromHubInstructions
91 );
92 }
93}
94
95function buildHelper(opts: Opts): ExternalDataSourceHelper {
96 const staticUrl = (opts.baseUrls || {}).media || "";
97 return {
98 richtextToHtml(delta) {
99 return formatQuillDelta(delta, "html");
100 },
101 Converter,
102 media: {
103 original(image: string) {
104 if (image.match(/^http/)) {
105 return image;
106 }
107
108 return url.resolve(staticUrl, `./${image}`);
109 },
110 fromOriginal(image: string) {
111 return image.replace(new RegExp(`^${staticUrl}`), "");
112 }
113 }
114 };
115}
116
117export function provide(
118 externalDataSources: ExternalDataSourceWithOptionalHelper[] = [],
119 opts: Opts
120) {
121 const helper = buildHelper(opts);
122 return externalDataSources.map(externalDataSource => {
123 if (typeof externalDataSource === "function") {
124 return externalDataSource(helper);
125 }
126
127 return externalDataSource;
128 });
129}
130
\No newline at end of file