create-instantsearch-app 7.3.3 → 7.4.1
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/README.md +3 -0
- package/package.json +3 -3
- package/src/cli/__tests__/postProcessAnswers.js +18 -0
- package/src/cli/getPotentialImageAttributes.js +43 -0
- package/src/cli/index.js +35 -0
- package/src/cli/postProcessAnswers.js +3 -0
- package/src/templates/Angular InstantSearch/package.json +12 -12
- package/src/templates/InstantSearch.js/src/app.js.hbs +3 -0
- package/src/templates/JavaScript Client/src/app.js.hbs +3 -0
- package/src/templates/JavaScript Helper/src/app.js.hbs +3 -0
- package/src/templates/React InstantSearch/src/App.tsx.hbs +4 -1
- package/src/templates/Vue InstantSearch/src/App.vue +3 -0
- package/src/templates/Vue InstantSearch with Vue 3/src/App.vue +3 -0
package/README.md
CHANGED
|
@@ -71,6 +71,7 @@ $ create-instantsearch-app --help
|
|
|
71
71
|
--api-key <apiKey> The Algolia search API key
|
|
72
72
|
--index-name <indexName> The main index of your search
|
|
73
73
|
--attributes-to-display <attributesToDisplay> The attributes of your index to display
|
|
74
|
+
--image-attribute <imageAttribute> The attribute of your index to use for image display
|
|
74
75
|
--attributes-for-faceting <attributesForFaceting> The attributes for faceting
|
|
75
76
|
--template <template> The InstantSearch template to use
|
|
76
77
|
--library-version <libraryVersion> The version of the library
|
|
@@ -114,6 +115,7 @@ The `config` flag is handy to automate app generations.
|
|
|
114
115
|
"indexName": "MY_INDEX_NAME",
|
|
115
116
|
"searchPlaceholder": "Search",
|
|
116
117
|
"attributesToDisplay": ["name", "description"],
|
|
118
|
+
"imageAttribute": "image",
|
|
117
119
|
"attributesForFaceting": ["brand", "location"],
|
|
118
120
|
"enableInsights": true
|
|
119
121
|
}
|
|
@@ -136,6 +138,7 @@ const app = createInstantSearchApp('~/lab/my-app', {
|
|
|
136
138
|
template: 'InstantSearch.js',
|
|
137
139
|
libraryVersion: '2.0.0',
|
|
138
140
|
attributesToDisplay: ['name', 'description'],
|
|
141
|
+
imageAttribute: 'image',
|
|
139
142
|
attributesForFaceting: ['keywords'],
|
|
140
143
|
enableInsights: true,
|
|
141
144
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-instantsearch-app",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.4.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "⚡️ Build InstantSearch apps at the speed of thought",
|
|
6
6
|
"keywords": [
|
|
@@ -49,9 +49,9 @@
|
|
|
49
49
|
"validate-npm-package-name": "3.0.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@instantsearch/testutils": "1.
|
|
52
|
+
"@instantsearch/testutils": "1.24.0",
|
|
53
53
|
"jest-image-snapshot": "2.12.0",
|
|
54
54
|
"walk-sync": "2.0.2"
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "3f061b181adf4358629406027eec8f79d2577196"
|
|
57
57
|
}
|
|
@@ -263,3 +263,21 @@ describe('flags', () => {
|
|
|
263
263
|
});
|
|
264
264
|
});
|
|
265
265
|
});
|
|
266
|
+
|
|
267
|
+
test('removes `imageAttribute` from `attributesToDisplay`', async () => {
|
|
268
|
+
expect(
|
|
269
|
+
await postProcessAnswers({
|
|
270
|
+
configuration: {},
|
|
271
|
+
templateConfig: {},
|
|
272
|
+
optionsFromArguments: {},
|
|
273
|
+
answers: {
|
|
274
|
+
attributesToDisplay: ['test', 'image'],
|
|
275
|
+
imageAttribute: 'image',
|
|
276
|
+
},
|
|
277
|
+
})
|
|
278
|
+
).toEqual(
|
|
279
|
+
expect.objectContaining({
|
|
280
|
+
attributesToDisplay: ['test'],
|
|
281
|
+
})
|
|
282
|
+
);
|
|
283
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const getInformationFromIndex = require('./getInformationFromIndex');
|
|
2
|
+
|
|
3
|
+
module.exports = async function getPotentialImageAttributes({
|
|
4
|
+
appId,
|
|
5
|
+
apiKey,
|
|
6
|
+
indexName,
|
|
7
|
+
} = {}) {
|
|
8
|
+
try {
|
|
9
|
+
const { hits } = await getInformationFromIndex({
|
|
10
|
+
appId,
|
|
11
|
+
apiKey,
|
|
12
|
+
indexName,
|
|
13
|
+
});
|
|
14
|
+
const [firstHit] = hits;
|
|
15
|
+
const highlightedAttributes = Object.keys(firstHit._highlightResult);
|
|
16
|
+
return Object.entries(firstHit)
|
|
17
|
+
.filter(
|
|
18
|
+
([key, value]) =>
|
|
19
|
+
typeof value === 'string' &&
|
|
20
|
+
!/[\s]+/.test(value) &&
|
|
21
|
+
!highlightedAttributes.includes(key) &&
|
|
22
|
+
key !== 'objectID'
|
|
23
|
+
)
|
|
24
|
+
.map(([key]) => key)
|
|
25
|
+
.sort((a, b) => {
|
|
26
|
+
const regex = /image|img/;
|
|
27
|
+
const aIncludesImage = regex.test(a);
|
|
28
|
+
const bIncludesImage = regex.test(b);
|
|
29
|
+
|
|
30
|
+
if (aIncludesImage && !bIncludesImage) {
|
|
31
|
+
return -1;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!aIncludesImage && bIncludesImage) {
|
|
35
|
+
return 1;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return 0;
|
|
39
|
+
});
|
|
40
|
+
} catch (err) {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
};
|
package/src/cli/index.js
CHANGED
|
@@ -24,6 +24,7 @@ const getAnswersDefaultValues = require('./getAnswersDefaultValues');
|
|
|
24
24
|
const getAttributesFromIndex = require('./getAttributesFromIndex');
|
|
25
25
|
const getConfiguration = require('./getConfiguration');
|
|
26
26
|
const getFacetsFromIndex = require('./getFacetsFromIndex');
|
|
27
|
+
const getPotentialImageAttributes = require('./getPotentialImageAttributes');
|
|
27
28
|
const isQuestionAsked = require('./isQuestionAsked');
|
|
28
29
|
const postProcessAnswers = require('./postProcessAnswers');
|
|
29
30
|
|
|
@@ -44,6 +45,10 @@ program
|
|
|
44
45
|
'The attributes of your index to display in hits',
|
|
45
46
|
splitArray
|
|
46
47
|
)
|
|
48
|
+
.option(
|
|
49
|
+
'--image-attribute <imageAttribute>',
|
|
50
|
+
'The attribute for image display in hits'
|
|
51
|
+
)
|
|
47
52
|
.option(
|
|
48
53
|
'--attributes-for-faceting <attributesForFaceting>',
|
|
49
54
|
'The attributes to display as filters',
|
|
@@ -159,6 +164,36 @@ const getQuestions = ({ appName }) => ({
|
|
|
159
164
|
when: ({ appId, apiKey, indexName }) =>
|
|
160
165
|
attributesToDisplay.length === 0 && appId && apiKey && indexName,
|
|
161
166
|
},
|
|
167
|
+
{
|
|
168
|
+
type: 'list',
|
|
169
|
+
name: 'imageAttribute',
|
|
170
|
+
message: 'Attribute for image display',
|
|
171
|
+
suffix: `\n ${chalk.gray(
|
|
172
|
+
'Used to display images in the default result template'
|
|
173
|
+
)}`,
|
|
174
|
+
pageSize: 10,
|
|
175
|
+
choices: async (answers) => [
|
|
176
|
+
{
|
|
177
|
+
name: 'None',
|
|
178
|
+
value: undefined,
|
|
179
|
+
},
|
|
180
|
+
new inquirer.Separator(),
|
|
181
|
+
new inquirer.Separator('From your index'),
|
|
182
|
+
...(await getPotentialImageAttributes(answers)),
|
|
183
|
+
],
|
|
184
|
+
when: ({
|
|
185
|
+
appId,
|
|
186
|
+
apiKey,
|
|
187
|
+
indexName,
|
|
188
|
+
imageAttribute,
|
|
189
|
+
attributesToDisplay: selectedAttributes,
|
|
190
|
+
}) =>
|
|
191
|
+
selectedAttributes.length > 0 &&
|
|
192
|
+
!imageAttribute &&
|
|
193
|
+
appId &&
|
|
194
|
+
apiKey &&
|
|
195
|
+
indexName,
|
|
196
|
+
},
|
|
162
197
|
{
|
|
163
198
|
type: 'checkbox',
|
|
164
199
|
name: 'attributesForFaceting',
|
|
@@ -65,6 +65,9 @@ async function postProcessAnswers({
|
|
|
65
65
|
template: templatePath,
|
|
66
66
|
installation: optionsFromArguments.installation,
|
|
67
67
|
currentYear: new Date().getFullYear(),
|
|
68
|
+
attributesToDisplay: combinedAnswers.attributesToDisplay?.filter(
|
|
69
|
+
(attribute) => attribute !== combinedAnswers.imageAttribute
|
|
70
|
+
),
|
|
68
71
|
attributesForFaceting:
|
|
69
72
|
Array.isArray(combinedAnswers.attributesForFaceting) &&
|
|
70
73
|
combinedAnswers.attributesForFaceting.filter(
|
|
@@ -10,14 +10,14 @@
|
|
|
10
10
|
},
|
|
11
11
|
"private": true,
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@angular/animations": "
|
|
14
|
-
"@angular/common": "
|
|
15
|
-
"@angular/compiler": "
|
|
16
|
-
"@angular/core": "
|
|
17
|
-
"@angular/forms": "
|
|
18
|
-
"@angular/platform-browser": "
|
|
19
|
-
"@angular/platform-browser-dynamic": "
|
|
20
|
-
"@angular/router": "
|
|
13
|
+
"@angular/animations": "15.2.10",
|
|
14
|
+
"@angular/common": "15.2.10",
|
|
15
|
+
"@angular/compiler": "15.2.10",
|
|
16
|
+
"@angular/core": "15.2.10",
|
|
17
|
+
"@angular/forms": "15.2.10",
|
|
18
|
+
"@angular/platform-browser": "15.2.10",
|
|
19
|
+
"@angular/platform-browser-dynamic": "15.2.10",
|
|
20
|
+
"@angular/router": "15.2.10",
|
|
21
21
|
"algoliasearch": "4",
|
|
22
22
|
"angular-instantsearch": "{{libraryVersion}}",
|
|
23
23
|
"rxjs": "6.6.0",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"zone.js": "0.11.4"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@angular-devkit/build-angular": "
|
|
29
|
-
"@angular/cli": "
|
|
30
|
-
"@angular/compiler-cli": "
|
|
28
|
+
"@angular-devkit/build-angular": "15.2.10",
|
|
29
|
+
"@angular/cli": "15.2.10",
|
|
30
|
+
"@angular/compiler-cli": "15.2.10",
|
|
31
31
|
"@types/jasmine": "3.8.0",
|
|
32
32
|
"@types/node": "12.11.1",
|
|
33
33
|
"jasmine-core": "3.8.0",
|
|
@@ -36,6 +36,6 @@
|
|
|
36
36
|
"karma-coverage": "2.0.3",
|
|
37
37
|
"karma-jasmine": "4.0.0",
|
|
38
38
|
"karma-jasmine-html-reporter": "1.7.0",
|
|
39
|
-
"typescript": "4.
|
|
39
|
+
"typescript": "4.9.5"
|
|
40
40
|
}
|
|
41
41
|
}
|
|
@@ -39,6 +39,9 @@ search.addWidgets([
|
|
|
39
39
|
templates: {
|
|
40
40
|
item: (hit, { html, components }) => html`
|
|
41
41
|
<article>
|
|
42
|
+
{{#if imageAttribute}}
|
|
43
|
+
<img src=${ hit.{{imageAttribute}} } alt=${ hit.{{attributesToDisplay.[0]}} } />
|
|
44
|
+
{{/if}}
|
|
42
45
|
<h1>${components.Highlight({hit, attribute: "{{attributesToDisplay.[0]}}"})}</h1>
|
|
43
46
|
{{#each attributesToDisplay}}
|
|
44
47
|
{{#unless @first}}
|
|
@@ -17,6 +17,9 @@ function renderHits(query) {
|
|
|
17
17
|
`<li class="ais-hits--item">
|
|
18
18
|
<article>
|
|
19
19
|
{{#if attributesToDisplay}}
|
|
20
|
+
{{#if imageAttribute}}
|
|
21
|
+
<img src="${ hit.{{imageAttribute}} }" alt="${ hit.{{attributesToDisplay.[0]}} }" />
|
|
22
|
+
{{/if}}
|
|
20
23
|
<h1>${hit._highlightResult.{{attributesToDisplay.[0]}}.value}</h1>
|
|
21
24
|
{{#each attributesToDisplay}}
|
|
22
25
|
{{#unless @first}}
|
|
@@ -23,6 +23,9 @@ helper.on('result', ({ results }) => {
|
|
|
23
23
|
`<li class="ais-hits--item">
|
|
24
24
|
<article>
|
|
25
25
|
{{#if attributesToDisplay}}
|
|
26
|
+
{{#if imageAttribute}}
|
|
27
|
+
<img src="${ hit.{{imageAttribute}} }" alt="${ hit.{{attributesToDisplay.[0]}} }" />
|
|
28
|
+
{{/if}}
|
|
26
29
|
<h1>${hit._highlightResult.{{attributesToDisplay.[0]}}.value}</h1>
|
|
27
30
|
{{#each attributesToDisplay}}
|
|
28
31
|
{{#unless @first}}
|
|
@@ -54,7 +54,7 @@ export function App() {
|
|
|
54
54
|
<div className="search-panel">
|
|
55
55
|
<div className="search-panel__filters">
|
|
56
56
|
{{#if flags.dynamicWidgets}}
|
|
57
|
-
<DynamicWidgets
|
|
57
|
+
<DynamicWidgets fallbackComponent={RefinementList}>
|
|
58
58
|
{{#each attributesForFaceting}}
|
|
59
59
|
<Panel header="{{this}}">
|
|
60
60
|
<RefinementList attribute="{{this}}" />
|
|
@@ -93,6 +93,9 @@ function Hit({ hit }: HitProps) {
|
|
|
93
93
|
return (
|
|
94
94
|
<article>
|
|
95
95
|
{{#if attributesToDisplay}}
|
|
96
|
+
{{#if imageAttribute}}
|
|
97
|
+
<img src={ hit.{{imageAttribute}} } alt={ hit.{{attributesToDisplay.[0]}} } />
|
|
98
|
+
{{/if}}
|
|
96
99
|
<h1>
|
|
97
100
|
<Highlight attribute="{{attributesToDisplay.[0]}}" hit={hit} />
|
|
98
101
|
</h1>
|