@mindful-web/marko-web-search 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +1 -0
- package/LICENSE +21 -0
- package/browser/.eslintrc.js +1 -0
- package/browser/index.js +9 -0
- package/browser/sort-select.vue +37 -0
- package/browser/toggle-filter-button.vue +69 -0
- package/browser/toggle-filters-button.vue +87 -0
- package/components/build-href.marko +14 -0
- package/components/build-href.marko.js +46 -0
- package/components/filters/content-types.marko +12 -0
- package/components/filters/content-types.marko.js +40 -0
- package/components/filters/filter-block.marko +66 -0
- package/components/filters/filter-block.marko.js +151 -0
- package/components/filters/filter-container.marko +29 -0
- package/components/filters/filter-container.marko.js +85 -0
- package/components/filters/load-website-sections.js +69 -0
- package/components/filters/marko.json +36 -0
- package/components/filters/selected/index.marko +51 -0
- package/components/filters/selected/index.marko.js +113 -0
- package/components/filters/selected/item.marko +27 -0
- package/components/filters/selected/item.marko.js +101 -0
- package/components/filters/selected/marko.json +8 -0
- package/components/filters/website-sections-by-alias.marko +46 -0
- package/components/filters/website-sections-by-alias.marko.js +139 -0
- package/components/filters/website-sections.marko +42 -0
- package/components/filters/website-sections.marko.js +123 -0
- package/components/form/index.marko +23 -0
- package/components/form/index.marko.js +79 -0
- package/components/form/input.marko +8 -0
- package/components/form/input.marko.js +30 -0
- package/components/form/marko.json +10 -0
- package/components/links/link.marko +14 -0
- package/components/links/link.marko.js +47 -0
- package/components/links/marko.json +17 -0
- package/components/links/next-page.marko +25 -0
- package/components/links/next-page.marko.js +59 -0
- package/components/links/previous-page.marko +25 -0
- package/components/links/previous-page.marko.js +59 -0
- package/components/links/reset-filter.marko +24 -0
- package/components/links/reset-filter.marko.js +55 -0
- package/components/links/set-filter-value.marko +45 -0
- package/components/links/set-filter-value.marko.js +86 -0
- package/components/marko.json +25 -0
- package/components/pagination-controls.marko +42 -0
- package/components/pagination-controls.marko.js +108 -0
- package/components/query-child-sections.marko +24 -0
- package/components/query-child-sections.marko.js +60 -0
- package/components/query.marko +30 -0
- package/components/query.marko.js +67 -0
- package/components/sort-by/index.marko +25 -0
- package/components/sort-by/index.marko.js +72 -0
- package/components/sort-by/marko.json +5 -0
- package/config/index.js +84 -0
- package/config/param.js +69 -0
- package/config/query-params.js +101 -0
- package/index.js +113 -0
- package/loaders/search.js +108 -0
- package/marko.json +6 -0
- package/middleware.js +9 -0
- package/package.json +32 -0
package/config/param.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const { isFunction: isFn } = require('@mindful-web/utils');
|
|
2
|
+
|
|
3
|
+
class MarkoWebSearchQueryParam {
|
|
4
|
+
constructor({
|
|
5
|
+
name,
|
|
6
|
+
type,
|
|
7
|
+
defaultValue,
|
|
8
|
+
validator,
|
|
9
|
+
filter,
|
|
10
|
+
toInput,
|
|
11
|
+
fromInput,
|
|
12
|
+
} = {}) {
|
|
13
|
+
this.name = name;
|
|
14
|
+
this.type = type;
|
|
15
|
+
this.defaultValue = defaultValue;
|
|
16
|
+
this.validator = validator;
|
|
17
|
+
this.filter = filter;
|
|
18
|
+
this.toInput = toInput;
|
|
19
|
+
this.fromInput = fromInput;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
toInputValue(value, $markoWebSearch) {
|
|
23
|
+
const { toInput, filter, validator } = this;
|
|
24
|
+
const defaultValue = this.getDefaultValue();
|
|
25
|
+
|
|
26
|
+
let input = isFn(toInput) ? toInput(value) : value;
|
|
27
|
+
if (input == null) input = defaultValue;
|
|
28
|
+
if (isFn(filter)) input = filter(input);
|
|
29
|
+
const isValid = isFn(validator) ? validator(input, $markoWebSearch) : true;
|
|
30
|
+
return isValid ? input : defaultValue;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
toQueryValue(input, $markoWebSearch) {
|
|
34
|
+
const { fromInput, filter, validator } = this;
|
|
35
|
+
const defaultValue = this.getDefaultValue();
|
|
36
|
+
|
|
37
|
+
let v = input;
|
|
38
|
+
if (v == null) v = defaultValue;
|
|
39
|
+
if (isFn(filter)) v = filter(v);
|
|
40
|
+
const isValid = isFn(validator) ? validator(v, $markoWebSearch) : true;
|
|
41
|
+
if (!isValid) v = defaultValue;
|
|
42
|
+
if (this.isDefaultValue(v)) return null;
|
|
43
|
+
if (isFn(fromInput)) v = fromInput(v);
|
|
44
|
+
return v;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
isDefaultValue(input) {
|
|
48
|
+
const defaultValue = this.getDefaultValue();
|
|
49
|
+
return this.areInputsEqual(input, defaultValue);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
areInputsEqual(input1, input2) {
|
|
53
|
+
if (this.isArray()) {
|
|
54
|
+
return input1.sort().join('') === input2.sort().join('');
|
|
55
|
+
}
|
|
56
|
+
return input1 === input2;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
getDefaultValue() {
|
|
60
|
+
const { defaultValue } = this;
|
|
61
|
+
return (isFn(defaultValue)) ? defaultValue() : defaultValue;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
isArray() {
|
|
65
|
+
return this.type === Array;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = MarkoWebSearchQueryParam;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
const MarkoWebSearchQueryParam = require('./param');
|
|
2
|
+
|
|
3
|
+
const { isArray } = Array;
|
|
4
|
+
|
|
5
|
+
const unqArray = (array) => [...new Set(array)];
|
|
6
|
+
|
|
7
|
+
const toArrayInput = (str, mapFunc) => {
|
|
8
|
+
if (!str) return undefined;
|
|
9
|
+
const trimmed = str.trim();
|
|
10
|
+
if (!trimmed) return undefined;
|
|
11
|
+
return unqArray(trimmed.split(',').map(mapFunc).filter((v) => v));
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const fromArrayInput = (arr) => {
|
|
15
|
+
if (!isArray(arr) || !arr.length) return null;
|
|
16
|
+
return unqArray(arr.sort().filter((i) => i)).join(',');
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const toIntArrayInput = (arr) => toArrayInput(arr, (v) => parseInt(v, 10));
|
|
20
|
+
const toStringArrayInput = (arr) => toArrayInput(arr, (v) => v.trim());
|
|
21
|
+
|
|
22
|
+
const sortFieldSet = new Set(['NAME', 'PUBLISHED', 'SCORE']);
|
|
23
|
+
const sortOrderSet = new Set(['DESC', 'ASC']);
|
|
24
|
+
|
|
25
|
+
class MarkoWebSearchQueryParamConfig {
|
|
26
|
+
constructor({
|
|
27
|
+
resultsPerPage = {},
|
|
28
|
+
contentTypeIds = [],
|
|
29
|
+
defaultSortField = 'PUBLISHED',
|
|
30
|
+
} = {}) {
|
|
31
|
+
this.params = new Map();
|
|
32
|
+
|
|
33
|
+
const contentTypeIdMap = contentTypeIds.reduce((m, id) => {
|
|
34
|
+
m.set(id, true);
|
|
35
|
+
return m;
|
|
36
|
+
}, new Map());
|
|
37
|
+
|
|
38
|
+
this
|
|
39
|
+
.add('limit', {
|
|
40
|
+
type: Number,
|
|
41
|
+
defaultValue: resultsPerPage.default,
|
|
42
|
+
validator: (v) => (v >= resultsPerPage.min && v <= resultsPerPage.max),
|
|
43
|
+
toInput: (v) => parseInt(v, 10),
|
|
44
|
+
})
|
|
45
|
+
.add('page', {
|
|
46
|
+
type: Number,
|
|
47
|
+
defaultValue: 1,
|
|
48
|
+
validator: (v, search) => {
|
|
49
|
+
if (v < 1) return false;
|
|
50
|
+
const limit = search.getInputValueFor('limit');
|
|
51
|
+
return ((v * limit) <= 10000);
|
|
52
|
+
},
|
|
53
|
+
toInput: (v) => parseInt(v, 10),
|
|
54
|
+
})
|
|
55
|
+
.add('searchQuery', {
|
|
56
|
+
type: String,
|
|
57
|
+
defaultValue: '',
|
|
58
|
+
})
|
|
59
|
+
.add('contentTypes', {
|
|
60
|
+
type: Array,
|
|
61
|
+
defaultValue: () => contentTypeIds.slice(),
|
|
62
|
+
filter: (types) => types.filter((type) => contentTypeIdMap.has(type)),
|
|
63
|
+
validator: (types) => types.every((type) => contentTypeIdMap.has(type)),
|
|
64
|
+
toInput: toStringArrayInput,
|
|
65
|
+
fromInput: fromArrayInput,
|
|
66
|
+
})
|
|
67
|
+
.add('assignedToWebsiteSectionIds', {
|
|
68
|
+
type: Array,
|
|
69
|
+
defaultValue: () => [],
|
|
70
|
+
toInput: toIntArrayInput,
|
|
71
|
+
fromInput: fromArrayInput,
|
|
72
|
+
})
|
|
73
|
+
.add('sortField', {
|
|
74
|
+
type: String,
|
|
75
|
+
defaultValue: defaultSortField,
|
|
76
|
+
validator: (v) => sortFieldSet.has(v),
|
|
77
|
+
})
|
|
78
|
+
.add('sortOrder', {
|
|
79
|
+
type: String,
|
|
80
|
+
defaultValue: 'DESC',
|
|
81
|
+
validator: (v) => sortOrderSet.has(v),
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
add(name, param) {
|
|
86
|
+
this.params.set(name, new MarkoWebSearchQueryParam({ ...param, name }));
|
|
87
|
+
return this;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
names() {
|
|
91
|
+
return [...this.params.keys()].sort();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
getDefinition(name) {
|
|
95
|
+
const param = this.params.get(name);
|
|
96
|
+
if (!param) throw new Error(`No query parameter definition was found for ${name}`);
|
|
97
|
+
return param;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
module.exports = MarkoWebSearchQueryParamConfig;
|
package/index.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
class MarkoWebSearch {
|
|
2
|
+
constructor({ config, query = {} } = {}) {
|
|
3
|
+
this.config = config;
|
|
4
|
+
this.query = query;
|
|
5
|
+
this.input = this.getAllInputValues();
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
buildURLSearchParams(newValues = {}, omit = {}) {
|
|
9
|
+
return new URLSearchParams(this.queryParamNames.reduce((o, name) => {
|
|
10
|
+
if (omit[name]) return o;
|
|
11
|
+
const value = this.getQueryStringValueFor(name, newValues[name]);
|
|
12
|
+
if (value == null) return o;
|
|
13
|
+
return { ...o, [name]: value };
|
|
14
|
+
}, {}));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
buildQueryString(newValues = {}, omit = {}) {
|
|
18
|
+
const params = this.buildURLSearchParams(newValues, omit);
|
|
19
|
+
const str = `${params}`;
|
|
20
|
+
return str ? `?${str}` : '';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Gets all component (internal) input values from the current Express request query.
|
|
25
|
+
*
|
|
26
|
+
* Invalid values are reset to the definition's default value.
|
|
27
|
+
* @returns {object}
|
|
28
|
+
*/
|
|
29
|
+
getAllInputValues() {
|
|
30
|
+
return this.queryParamNames.reduce((o, name) => {
|
|
31
|
+
const value = this.getInputValueFor(name);
|
|
32
|
+
return { ...o, [name]: value };
|
|
33
|
+
}, {});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Gets the component (internal) input value for the provided parameter name and
|
|
38
|
+
* current Express request query.
|
|
39
|
+
*
|
|
40
|
+
* Invalid values are reset to the definition's default value.
|
|
41
|
+
*
|
|
42
|
+
* @param {string} name The query parameter name.
|
|
43
|
+
* @param {object} query The Express request query object.
|
|
44
|
+
* @returns {*}
|
|
45
|
+
*/
|
|
46
|
+
getInputValueFor(name) {
|
|
47
|
+
const definition = this.config.queryParams.getDefinition(name);
|
|
48
|
+
return definition.toInputValue(this.query[name], this);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
isInputValueSelectedFor(name, incomingInput) {
|
|
52
|
+
const definition = this.config.queryParams.getDefinition(name);
|
|
53
|
+
const currentInput = this.getInputValueFor(name);
|
|
54
|
+
return definition.areInputsEqual(currentInput, incomingInput);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
isDefaultInputValueFor(name) {
|
|
58
|
+
const definition = this.config.queryParams.getDefinition(name);
|
|
59
|
+
const input = this.getInputValueFor(name);
|
|
60
|
+
return definition.isDefaultValue(input);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
isArrayParam(name) {
|
|
64
|
+
const definition = this.config.queryParams.getDefinition(name);
|
|
65
|
+
return definition.isArray();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
*
|
|
70
|
+
* @param {string} name The query parameter name
|
|
71
|
+
* @param {*} [newValue] The optional new value to replace
|
|
72
|
+
* @returns {string?}
|
|
73
|
+
*/
|
|
74
|
+
getQueryStringValueFor(name, newValue) {
|
|
75
|
+
const definition = this.config.queryParams.getDefinition(name);
|
|
76
|
+
const value = typeof newValue === 'undefined' ? this.input[name] : newValue;
|
|
77
|
+
return definition.toQueryValue(value, this);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
get queryParamNames() {
|
|
81
|
+
return this.config.queryParams.names();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
getCurrentPage() {
|
|
85
|
+
return this.getInputValueFor('page');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
getLimit() {
|
|
89
|
+
return this.getInputValueFor('limit');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
getSkip() {
|
|
93
|
+
return this.getLimit() * (this.getCurrentPage() - 1);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
getTotalPages(totalCount = 0) {
|
|
97
|
+
const count = totalCount > 10000 ? 10000 : totalCount;
|
|
98
|
+
return Math.ceil(count / this.getLimit());
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
getNextPage(totalCount = 0) {
|
|
102
|
+
const page = this.getCurrentPage();
|
|
103
|
+
const total = this.getTotalPages(totalCount);
|
|
104
|
+
return page < total ? page + 1 : null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
getPrevPage() {
|
|
108
|
+
const page = this.getCurrentPage();
|
|
109
|
+
return page > 1 ? page - 1 : null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
module.exports = MarkoWebSearch;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
const gql = require('graphql-tag');
|
|
2
|
+
const { extractFragmentData } = require('@mindful-web/web-common/utils');
|
|
3
|
+
|
|
4
|
+
const buildMindfulWebQuery = ({ queryFragment, opSuffix = '' } = {}) => {
|
|
5
|
+
const { spreadFragmentName, processedFragment } = extractFragmentData(queryFragment);
|
|
6
|
+
return gql`
|
|
7
|
+
query MarkoWebSearchContentIdsFromBrowse${opSuffix}($ids: [Int!]!, $limit: Int!) {
|
|
8
|
+
allContent(input: { ids: $ids, pagination: { limit: $limit } }) {
|
|
9
|
+
edges {
|
|
10
|
+
node {
|
|
11
|
+
id
|
|
12
|
+
${spreadFragmentName}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
${processedFragment}
|
|
18
|
+
`;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const baseBrowseQuery = gql`
|
|
22
|
+
query MarkoWebSearchSearchContentIds($input: BrowseContentQueryInput!) {
|
|
23
|
+
searchContentIds(input: $input) {
|
|
24
|
+
totalCount
|
|
25
|
+
pageInfo {
|
|
26
|
+
hasNextPage
|
|
27
|
+
hasPreviousPage
|
|
28
|
+
}
|
|
29
|
+
ids
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @param {object} clients
|
|
36
|
+
* @param {ApolloClient} clients.apolloMindfulWebCMS The Mindful Web client that will perform the
|
|
37
|
+
* query.
|
|
38
|
+
* @param {ApolloClient} clients.apolloBaseBrowse The BaseBrowse client that will perform the query.
|
|
39
|
+
* @param {object} params
|
|
40
|
+
* @param {number} [params.limit]
|
|
41
|
+
* @param {number} [params.skip]
|
|
42
|
+
* @param {string} [params.sortField=PUBLISHED]
|
|
43
|
+
* @param {string} [params.sortOrder=DESC]
|
|
44
|
+
* @param {string} [params.searchQuery]
|
|
45
|
+
* @param {string[]} [params.contentTypes]
|
|
46
|
+
* @param {string[]} [params.countryCodes]
|
|
47
|
+
* @param {string[]} [params.assignedToWebsiteSiteIds]
|
|
48
|
+
* @param {number[]} [params.assignedToWebsiteSectionIds]
|
|
49
|
+
* @param {string} [params.queryFragment] The `graphql-tag` fragment
|
|
50
|
+
* to apply to the `allContent` query.
|
|
51
|
+
* @param {string} [params.opSuffix] A suffix to add to the GraphQL operation name.
|
|
52
|
+
*/
|
|
53
|
+
module.exports = async ({ apolloMindfulWebCMS, apolloBaseBrowse } = {}, {
|
|
54
|
+
limit,
|
|
55
|
+
skip,
|
|
56
|
+
|
|
57
|
+
sortField = 'PUBLISHED',
|
|
58
|
+
sortOrder = 'DESC',
|
|
59
|
+
|
|
60
|
+
searchQuery,
|
|
61
|
+
contentTypes = [],
|
|
62
|
+
countryCodes = [],
|
|
63
|
+
assignedToWebsiteSiteIds = [],
|
|
64
|
+
assignedToWebsiteSectionIds = [],
|
|
65
|
+
|
|
66
|
+
queryFragment,
|
|
67
|
+
opSuffix,
|
|
68
|
+
searchType,
|
|
69
|
+
} = {}) => {
|
|
70
|
+
if (!apolloMindfulWebCMS || !apolloBaseBrowse) throw new Error('Both the Mindful Web and Base Browse Apollo clients must be provided.');
|
|
71
|
+
const input = {
|
|
72
|
+
omitScheduledAndExpiredContent: true,
|
|
73
|
+
statuses: ['PUBLISHED'],
|
|
74
|
+
contentTypes,
|
|
75
|
+
countryCodes,
|
|
76
|
+
...(searchQuery && { search: { query: searchQuery, type: searchType } }),
|
|
77
|
+
...((assignedToWebsiteSiteIds.length || assignedToWebsiteSectionIds.length) && {
|
|
78
|
+
assignedToWebsites: {
|
|
79
|
+
...(assignedToWebsiteSiteIds.length && { siteIds: assignedToWebsiteSiteIds }),
|
|
80
|
+
...(assignedToWebsiteSectionIds.length && { sectionIds: assignedToWebsiteSectionIds }),
|
|
81
|
+
},
|
|
82
|
+
}),
|
|
83
|
+
pagination: { limit, skip },
|
|
84
|
+
sort: {
|
|
85
|
+
field: sortField,
|
|
86
|
+
order: sortOrder,
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const { data: baseBrowseData } = await apolloBaseBrowse.query({
|
|
91
|
+
query: baseBrowseQuery,
|
|
92
|
+
variables: { input },
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const { ids, pageInfo, totalCount } = baseBrowseData.searchContentIds;
|
|
96
|
+
if (!ids.length) return { nodes: [], pageInfo, totalCount };
|
|
97
|
+
|
|
98
|
+
const { data } = await apolloMindfulWebCMS.query({
|
|
99
|
+
query: buildMindfulWebQuery({ queryFragment, opSuffix }),
|
|
100
|
+
variables: { ids, limit: ids.length },
|
|
101
|
+
});
|
|
102
|
+
const nodes = data.allContent.edges
|
|
103
|
+
.map((edge) => (edge && edge.node ? edge.node : null))
|
|
104
|
+
.filter((c) => c);
|
|
105
|
+
const map = nodes.reduce((m, node) => m.set(`${node.id}`, node), new Map());
|
|
106
|
+
const ordered = ids.map((id) => map.get(`${id}`)).filter((node) => node);
|
|
107
|
+
return { nodes: ordered, pageInfo, totalCount };
|
|
108
|
+
};
|
package/marko.json
ADDED
package/middleware.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mindful-web/marko-web-search",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"author": "Jacob Bare <jacob@parameter1.com>",
|
|
5
|
+
"repository": "https://github.com/parameter1/mindful-web/tree/main/packages/marko-web-search",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"lint:fix": "yarn lint --fix",
|
|
9
|
+
"lint": "eslint --ext .js --ext .vue --max-warnings 5 ./",
|
|
10
|
+
"compile": "mindful-web-marko-compile compile",
|
|
11
|
+
"prepublish": "yarn compile --silent",
|
|
12
|
+
"test": "yarn compile --no-clean && yarn lint"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@mindful-web/inflector": "^1.0.0",
|
|
16
|
+
"@mindful-web/marko-web-icons": "^1.0.0",
|
|
17
|
+
"@mindful-web/object-path": "^1.0.0",
|
|
18
|
+
"@mindful-web/utils": "^1.0.0",
|
|
19
|
+
"@mindful-web/web-common": "^1.0.0",
|
|
20
|
+
"@parameter1/joi": "^1.2.10",
|
|
21
|
+
"graphql": "^14.7.0",
|
|
22
|
+
"graphql-tag": "^2.12.6"
|
|
23
|
+
},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"@mindful-web/marko-core": "^0.0.0",
|
|
26
|
+
"@mindful-web/marko-web": "^0.0.0"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"gitHead": "0b77cab713eb5841202bb86c7119949866bc68b5"
|
|
32
|
+
}
|