1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const lodash_1 = require("lodash");
|
4 | const SerializeError_1 = require("./SerializeError");
|
5 | const ListItem_1 = require("./ListItem");
|
6 | const GenericList_1 = require("./GenericList");
|
7 | const getArgType = (thing) => {
|
8 | if (thing instanceof ListBuilder) {
|
9 | return 'ListBuilder';
|
10 | }
|
11 | if (isPromise(thing)) {
|
12 | return 'Promise';
|
13 | }
|
14 | return Array.isArray(thing) ? 'array' : typeof thing;
|
15 | };
|
16 | const isListItem = (item) => {
|
17 | return item.type === 'listItem';
|
18 | };
|
19 | const resolveChildForItem = (itemId, options) => {
|
20 | const parentItem = options.parent;
|
21 | const items = parentItem.items.filter(isListItem);
|
22 | const target = (items.find(item => item.id === itemId) || { child: undefined }).child;
|
23 | if (!target || typeof target !== 'function') {
|
24 | return target;
|
25 | }
|
26 | return typeof target === 'function' ? target(itemId, options) : target;
|
27 | };
|
28 | function maybeSerializeListItem(item, index, path) {
|
29 | if (item instanceof ListItem_1.ListItemBuilder) {
|
30 | return item.serialize({ path, index });
|
31 | }
|
32 | const listItem = item;
|
33 | if (listItem && listItem.type === 'divider') {
|
34 | return item;
|
35 | }
|
36 | if (!listItem || listItem.type !== 'listItem') {
|
37 | const gotWhat = (listItem && listItem.type) || getArgType(listItem);
|
38 | const helpText = gotWhat === 'array' ? ' - did you forget to spread (...moreItems)?' : '';
|
39 | throw new SerializeError_1.SerializeError(`List items must be of type "listItem", got "${gotWhat}"${helpText}`, path, index).withHelpUrl(SerializeError_1.HELP_URL.INVALID_LIST_ITEM);
|
40 | }
|
41 | return item;
|
42 | }
|
43 | function isPromise(thing) {
|
44 | return thing && typeof thing.then === 'function';
|
45 | }
|
46 | class ListBuilder extends GenericList_1.GenericListBuilder {
|
47 | constructor(spec) {
|
48 | super();
|
49 | this.spec = spec ? spec : {};
|
50 | }
|
51 | items(items) {
|
52 | return this.clone({ items });
|
53 | }
|
54 | getItems() {
|
55 | return this.spec.items;
|
56 | }
|
57 | serialize(options = { path: [] }) {
|
58 | const id = this.spec.id;
|
59 | if (typeof id !== 'string' || !id) {
|
60 | throw new SerializeError_1.SerializeError('`id` is required for lists', options.path, options.index).withHelpUrl(SerializeError_1.HELP_URL.ID_REQUIRED);
|
61 | }
|
62 | const items = typeof this.spec.items === 'undefined' ? [] : this.spec.items;
|
63 | if (!Array.isArray(items)) {
|
64 | throw new SerializeError_1.SerializeError('`items` must be an array of items', options.path, options.index).withHelpUrl(SerializeError_1.HELP_URL.LIST_ITEMS_MUST_BE_ARRAY);
|
65 | }
|
66 | const path = (options.path || []).concat(id);
|
67 | const serializedItems = items.map((item, index) => maybeSerializeListItem(item, index, path));
|
68 | const dupes = serializedItems.filter((val, i) => lodash_1.find(serializedItems, { id: val.id }, i + 1));
|
69 | if (dupes.length > 0) {
|
70 | const dupeIds = dupes.map(item => item.id).slice(0, 5);
|
71 | const dupeDesc = dupes.length > 5 ? `${dupeIds.join(', ')}...` : dupeIds.join(', ');
|
72 | throw new SerializeError_1.SerializeError(`List items with same ID found (${dupeDesc})`, options.path, options.index).withHelpUrl(SerializeError_1.HELP_URL.LIST_ITEM_IDS_MUST_BE_UNIQUE);
|
73 | }
|
74 | return Object.assign({}, super.serialize(options), { type: 'list', child: this.spec.child || resolveChildForItem, items: serializedItems });
|
75 | }
|
76 | clone(withSpec) {
|
77 | const builder = new ListBuilder();
|
78 | builder.spec = Object.assign({}, this.spec, (withSpec || {}));
|
79 | return builder;
|
80 | }
|
81 | }
|
82 | exports.ListBuilder = ListBuilder;
|
83 |
|
84 |
|