create-instantsearch-app 6.3.1 → 6.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-instantsearch-app",
3
- "version": "6.3.1",
3
+ "version": "6.4.0",
4
4
  "license": "MIT",
5
5
  "description": "⚡️ Build InstantSearch apps at the speed of thought",
6
6
  "keywords": [
@@ -33,17 +33,16 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@algolia/cache-in-memory": "4",
36
+ "@metalsmith/in-place": "4.6.0",
37
+ "@metalsmith/remove": "1.3.0",
36
38
  "algoliasearch": "4",
37
39
  "chalk": "3.0.0",
38
40
  "commander": "4.1.1",
39
41
  "inquirer": "8.0.0",
40
42
  "jstransformer-handlebars": "1.1.0",
41
- "latest-semver": "2.0.0",
42
43
  "load-json-file": "6.2.0",
43
44
  "lodash.camelcase": "4.3.0",
44
- "metalsmith": "2.3.0",
45
- "metalsmith-ignore": "1.0.0",
46
- "metalsmith-in-place": "4.4.1",
45
+ "metalsmith": "2.5.1",
47
46
  "metalsmith-rename": "1.0.0",
48
47
  "prettier": "1.19.1",
49
48
  "semver": "6.1.1",
@@ -53,5 +52,5 @@
53
52
  "jest-image-snapshot": "2.12.0",
54
53
  "walk-sync": "2.0.2"
55
54
  },
56
- "gitHead": "c483ae31e1e615be61dffb5d0bc04a4927960a67"
55
+ "gitHead": "f224d502edb8cf119213cb9cd6e557dc03180521"
57
56
  }
@@ -80,32 +80,109 @@ test('creates alternative names', async () => {
80
80
  );
81
81
  });
82
82
 
83
- test('detects dynamic widgets', async () => {
84
- expect(
85
- await postProcessAnswers({
86
- configuration: {},
87
- templateConfig: {},
88
- optionsFromArguments: {},
89
- answers: { attributesForFaceting: ['ais.dynamicWidgets', 'test'] },
90
- })
91
- ).toEqual(
92
- expect.objectContaining({
93
- attributesForFaceting: ['test'],
94
- flags: { dynamicWidgets: true },
95
- })
96
- );
83
+ describe('flags', () => {
84
+ describe('dynamicWidgets', () => {
85
+ test('with usage of dynamicWidgets in attributesForFaceting', async () => {
86
+ expect(
87
+ await postProcessAnswers({
88
+ configuration: {},
89
+ templateConfig: {},
90
+ optionsFromArguments: {},
91
+ answers: { attributesForFaceting: ['ais.dynamicWidgets', 'test'] },
92
+ })
93
+ ).toEqual(
94
+ expect.objectContaining({
95
+ attributesForFaceting: ['test'],
96
+ flags: expect.objectContaining({ dynamicWidgets: true }),
97
+ })
98
+ );
99
+ });
97
100
 
98
- expect(
99
- await postProcessAnswers({
100
- configuration: {},
101
- templateConfig: {},
102
- optionsFromArguments: {},
103
- answers: { attributesForFaceting: ['test'] },
104
- })
105
- ).toEqual(
106
- expect.objectContaining({
107
- attributesForFaceting: ['test'],
108
- flags: { dynamicWidgets: false },
109
- })
110
- );
101
+ test('without usage of dynamicWidgets in attributesForFaceting', async () => {
102
+ expect(
103
+ await postProcessAnswers({
104
+ configuration: {},
105
+ templateConfig: {},
106
+ optionsFromArguments: {},
107
+ answers: { attributesForFaceting: ['test'] },
108
+ })
109
+ ).toEqual(
110
+ expect.objectContaining({
111
+ attributesForFaceting: ['test'],
112
+ flags: expect.objectContaining({ dynamicWidgets: false }),
113
+ })
114
+ );
115
+ });
116
+
117
+ test('without attributes', async () => {
118
+ expect(
119
+ await postProcessAnswers({
120
+ configuration: {},
121
+ templateConfig: {},
122
+ optionsFromArguments: {},
123
+ answers: {},
124
+ })
125
+ ).toEqual(
126
+ expect.objectContaining({
127
+ flags: expect.objectContaining({ dynamicWidgets: false }),
128
+ })
129
+ );
130
+ });
131
+ });
132
+
133
+ describe('insights', () => {
134
+ test('with a valid version', async () => {
135
+ utils.fetchLibraryVersions.mockImplementationOnce(() =>
136
+ Promise.resolve(['1.2.0'])
137
+ );
138
+
139
+ expect(
140
+ (
141
+ await postProcessAnswers({
142
+ configuration: {},
143
+ templateConfig: {
144
+ libraryName: 'instantsearch.js',
145
+ flags: {
146
+ insights: '>= 1',
147
+ },
148
+ },
149
+ optionsFromArguments: {},
150
+ })
151
+ ).flags
152
+ ).toEqual(expect.objectContaining({ insights: true }));
153
+ });
154
+
155
+ test('with an invalid version', async () => {
156
+ utils.fetchLibraryVersions.mockImplementationOnce(() =>
157
+ Promise.resolve(['1.2.0'])
158
+ );
159
+
160
+ expect(
161
+ (
162
+ await postProcessAnswers({
163
+ configuration: {},
164
+ templateConfig: {
165
+ libraryName: 'instantsearch.js',
166
+ flags: {
167
+ insights: '>= 1.3',
168
+ },
169
+ },
170
+ optionsFromArguments: {},
171
+ })
172
+ ).flags
173
+ ).toEqual(expect.objectContaining({ insights: false }));
174
+ });
175
+
176
+ test('without config', async () => {
177
+ expect(
178
+ (
179
+ await postProcessAnswers({
180
+ configuration: {},
181
+ templateConfig: {},
182
+ optionsFromArguments: {},
183
+ })
184
+ ).flags
185
+ ).toEqual(expect.objectContaining({ insights: false }));
186
+ });
187
+ });
111
188
  });
package/src/cli/index.js CHANGED
@@ -5,7 +5,6 @@ const os = require('os');
5
5
  const program = require('commander');
6
6
  const inquirer = require('inquirer');
7
7
  const chalk = require('chalk');
8
- const latestSemver = require('latest-semver');
9
8
  const semver = require('semver');
10
9
 
11
10
  const createInstantSearchApp = require('../api');
@@ -75,7 +74,9 @@ const getQuestions = ({ appName }) => ({
75
74
 
76
75
  try {
77
76
  const versions = await fetchLibraryVersions(libraryName);
78
- const latestStableVersion = latestSemver(versions);
77
+ const latestStableVersion = semver.maxSatisfying(versions, '*', {
78
+ includePrerelease: false,
79
+ });
79
80
 
80
81
  if (!latestStableVersion) {
81
82
  return versions;
@@ -1,5 +1,5 @@
1
1
  const camelCase = require('lodash.camelcase');
2
- const latestSemver = require('latest-semver');
2
+ const semver = require('semver');
3
3
 
4
4
  const { fetchLibraryVersions } = require('../utils');
5
5
 
@@ -24,10 +24,13 @@ async function getLibraryVersion(config, templateConfig) {
24
24
 
25
25
  if (libraryName && !libraryVersion) {
26
26
  const versions = await fetchLibraryVersions(libraryName);
27
+ const latestStableVersion = semver.maxSatisfying(versions, '*', {
28
+ includePrerelease: false,
29
+ });
27
30
 
28
31
  // Return the latest available version when
29
32
  // the stable version is not available
30
- return latestSemver(versions) || versions[0];
33
+ return latestStableVersion || versions[0];
31
34
  }
32
35
 
33
36
  return libraryVersion;
@@ -71,6 +74,9 @@ async function postProcessAnswers({
71
74
  dynamicWidgets:
72
75
  Array.isArray(combinedAnswers.attributesForFaceting) &&
73
76
  combinedAnswers.attributesForFaceting.includes('ais.dynamicWidgets'),
77
+ insights:
78
+ Boolean(templateConfig.flags && templateConfig.flags.insights) &&
79
+ semver.satisfies(libraryVersion, templateConfig.flags.insights),
74
80
  },
75
81
  };
76
82
  }
@@ -1,7 +1,7 @@
1
1
  const metalsmith = require('metalsmith');
2
- const inPlace = require('metalsmith-in-place');
2
+ const inPlace = require('@metalsmith/in-place');
3
3
  const rename = require('metalsmith-rename');
4
- const ignore = require('metalsmith-ignore');
4
+ const remove = require('@metalsmith/remove');
5
5
 
6
6
  module.exports = function build(config) {
7
7
  return new Promise((resolve, reject) => {
@@ -9,7 +9,7 @@ module.exports = function build(config) {
9
9
  .source(config.template)
10
10
  .destination(config.path)
11
11
  .metadata(config)
12
- .use(ignore(['.template.js']))
12
+ .use(remove(['.template.js']))
13
13
  .use(
14
14
  // Add the `.hbs` extension to any templating files that need
15
15
  // their placeholders to get filled with `metalsmith-in-place`
@@ -7,6 +7,7 @@ module.exports = {
7
7
  supportedVersion: '>= 3.0.0 < 5.0.0',
8
8
  flags: {
9
9
  dynamicWidgets: '>= 4.30',
10
+ insights: '>= 4.55',
10
11
  },
11
12
  templateName: 'instantsearch.js',
12
13
  appName: 'instantsearch.js-app',
@@ -5,6 +5,7 @@ const searchClient = algoliasearch('{{appId}}', '{{apiKey}}');
5
5
  const search = instantsearch({
6
6
  indexName: '{{indexName}}',
7
7
  searchClient,
8
+ {{#if flags.insights}}insights: true,{{/if}}
8
9
  });
9
10
 
10
11
  search.addWidgets([
@@ -18,12 +19,12 @@ search.addWidgets([
18
19
  container: '#hits',
19
20
  {{#if attributesToDisplay}}
20
21
  templates: {
21
- item: `
22
+ item: (hit, { html, components }) => html`
22
23
  <article>
23
- <h1>\{{#helpers.highlight}}{ "attribute": "{{attributesToDisplay.[0]}}" }\{{/helpers.highlight}}</h1>
24
+ <h1>${components.Highlight({hit, attribute: "{{attributesToDisplay.[0]}}"})}</h1>
24
25
  {{#each attributesToDisplay}}
25
26
  {{#unless @first}}
26
- <p>\{{#helpers.highlight}}{ "attribute": "{{this}}" }\{{/helpers.highlight}}</p>
27
+ <p>${components.Highlight({hit, attribute: "{{this}}"})}</p>
27
28
  {{/unless}}
28
29
  {{/each}}
29
30
  </article>
@@ -38,7 +39,7 @@ search.addWidgets([
38
39
  instantsearch.widgets.dynamicWidgets({
39
40
  container: '#dynamic-widgets',
40
41
  fallbackWidget({ container, attribute }) {
41
- return instantsearch.widgets.panel({ templates: { header: attribute } })(
42
+ return instantsearch.widgets.panel({ templates: { header: () => attribute } })(
42
43
  instantsearch.widgets.refinementList
43
44
  )({
44
45
  container,
@@ -49,7 +50,7 @@ search.addWidgets([
49
50
  {{#each attributesForFaceting}}
50
51
  container =>
51
52
  instantsearch.widgets.panel({
52
- templates: { header: '{{this}}' },
53
+ templates: { header: () => '{{this}}' },
53
54
  })(instantsearch.widgets.refinementList)({
54
55
  container,
55
56
  attribute: '{{this}}',
@@ -60,7 +61,7 @@ search.addWidgets([
60
61
  {{else}}
61
62
  {{#each attributesForFaceting}}
62
63
  instantsearch.widgets.panel({
63
- templates: { header: '{{this}}' },
64
+ templates: { header: () => '{{this}}' },
64
65
  })(instantsearch.widgets.refinementList)({
65
66
  container: '#{{this}}-list',
66
67
  attribute: '{{this}}',
@@ -7,6 +7,7 @@ module.exports = {
7
7
  supportedVersion: '>= 6.0.0 < 7.0.0',
8
8
  flags: {
9
9
  dynamicWidgets: '>=6.16',
10
+ insights: '>=6.43',
10
11
  },
11
12
  templateName: 'react-instantsearch-hooks',
12
13
  appName: 'react-instantsearch-hooks-app',
@@ -8,7 +8,6 @@
8
8
  },
9
9
  "dependencies": {
10
10
  "algoliasearch": "4",
11
- "instantsearch.js": "4.43.1",
12
11
  "react": "18.1.0",
13
12
  "react-dom": "18.1.0",
14
13
  "react-instantsearch-hooks-web": "{{libraryVersion}}"
@@ -47,7 +47,7 @@ export function App() {
47
47
  </header>
48
48
 
49
49
  <div className="container">
50
- <InstantSearch searchClient={searchClient} indexName="{{indexName}}">
50
+ <InstantSearch searchClient={searchClient} indexName="{{indexName}}" {{#if flags.insights}}insights{{/if}}>
51
51
  <Configure hitsPerPage={8} />
52
52
  <div className="search-panel">
53
53
  <div className="search-panel__filters">
@@ -14,7 +14,6 @@
14
14
  "algoliasearch": "4.12.1",
15
15
  "expo": "~44.0.0",
16
16
  "expo-status-bar": "~1.2.0",
17
- "instantsearch.js": "4.38.1",
18
17
  "react": "17.0.1",
19
18
  "react-dom": "17.0.1",
20
19
  "react-instantsearch-hooks": "{{libraryVersion}}",
@@ -6,7 +6,8 @@ module.exports = {
6
6
  libraryName: 'vue-instantsearch',
7
7
  supportedVersion: '>= 3.0.0 < 5.0.0',
8
8
  flags: {
9
- dynamicWidgets: '>=4.2.0',
9
+ dynamicWidgets: '>= 4.2.0',
10
+ insights: '>= 4.9.0',
10
11
  },
11
12
  templateName: 'vue-instantsearch',
12
13
  appName: 'vue-instantsearch-app',
@@ -18,6 +18,7 @@
18
18
  <ais-instant-search
19
19
  :search-client="searchClient"
20
20
  index-name="{{indexName}}"
21
+ {{#if flags.insights}}insights{{/if}}
21
22
  >
22
23
  <ais-configure :hits-per-page.camel="8" />
23
24
  <div class="search-panel">
@@ -6,7 +6,8 @@ module.exports = {
6
6
  libraryName: 'vue-instantsearch',
7
7
  supportedVersion: '>= 4.3.3 < 5.0.0',
8
8
  flags: {
9
- dynamicWidgets: '>=4.2.0',
9
+ dynamicWidgets: '>= 4.2.0',
10
+ insights: '>= 4.9.0',
10
11
  },
11
12
  templateName: 'vue-instantsearch-vue3',
12
13
  appName: 'vue-instantsearch-app',
@@ -16,6 +16,7 @@
16
16
  <ais-instant-search
17
17
  :search-client="searchClient"
18
18
  index-name="{{indexName}}"
19
+ {{#if flags.insights}}insights{{/if}}
19
20
  >
20
21
  <ais-configure :hits-per-page.camel="8" />
21
22
  <div class="search-panel">