create-instantsearch-app 7.3.2 → 7.4.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/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.2",
3
+ "version": "7.4.0",
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.20.0",
52
+ "@instantsearch/testutils": "1.22.0",
53
53
  "jest-image-snapshot": "2.12.0",
54
54
  "walk-sync": "2.0.2"
55
55
  },
56
- "gitHead": "967178e0e39302f1ff9552a42cfbdd9e06fd6864"
56
+ "gitHead": "4e99d1220b9c7872130f52bded4c1a84900bd0a3"
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": "12.2.16",
14
- "@angular/common": "12.2.16",
15
- "@angular/compiler": "12.2.16",
16
- "@angular/core": "12.2.16",
17
- "@angular/forms": "12.2.16",
18
- "@angular/platform-browser": "12.2.16",
19
- "@angular/platform-browser-dynamic": "12.2.16",
20
- "@angular/router": "12.2.16",
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": "12.2.16",
29
- "@angular/cli": "12.2.16",
30
- "@angular/compiler-cli": "12.2.16",
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.3.5"
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 fallback={RefinementList}>
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>
@@ -3,9 +3,9 @@
3
3
  "version": "1.0.0",
4
4
  "private": true,
5
5
  "scripts": {
6
- "start": "vue-cli-service serve --port 3000",
7
- "build": "vue-cli-service build",
8
- "lint": "vue-cli-service lint",
6
+ "start": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service serve --port 3000",
7
+ "build": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service build",
8
+ "lint": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service lint",
9
9
  "lint:fix": "npm run lint -- --fix"
10
10
  },
11
11
  "dependencies": {
@@ -50,6 +50,9 @@
50
50
  <ais-hits>
51
51
  <template slot="item" slot-scope="{ item }">
52
52
  <article>
53
+ {{#if imageAttribute}}
54
+ <img :src="item.{{imageAttribute}}" :alt="item.{{attributesToDisplay.[0]}}" />
55
+ {{/if}}
53
56
  <h1>
54
57
  <ais-highlight
55
58
  :hit="item"
@@ -49,6 +49,9 @@
49
49
  <ais-hits>
50
50
  <template v-slot:item="{ item }">
51
51
  <article>
52
+ {{#if imageAttribute}}
53
+ <img :src="item.{{imageAttribute}}" :alt="item.{{attributesToDisplay.[0]}}" />
54
+ {{/if}}
52
55
  <h1>
53
56
  <ais-highlight
54
57
  :hit="item"