create-instantsearch-app 6.3.1 → 6.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/package.json +5 -6
- package/src/api/__tests__/index.test.js +1 -0
- package/src/api/__tests__/resolve-template.test.js +1 -0
- package/src/api/check-config.js +2 -1
- package/src/api/index.js +4 -2
- package/src/api/resolve-template.js +2 -0
- package/src/cli/__tests__/getConfiguration.test.js +1 -0
- package/src/cli/__tests__/getInformationFromIndex.js +1 -0
- package/src/cli/__tests__/postProcessAnswers.js +105 -28
- package/src/cli/getInformationFromIndex.js +1 -1
- package/src/cli/index.js +10 -7
- package/src/cli/postProcessAnswers.js +8 -2
- package/src/tasks/common/build.js +3 -3
- package/src/tasks/common/clean.js +1 -0
- package/src/tasks/ios/install.js +1 -0
- package/src/tasks/ios/setup.js +1 -0
- package/src/tasks/node/install.js +3 -1
- package/src/tasks/node/teardown.js +3 -1
- package/src/templates/InstantSearch.js/.template.js +1 -0
- package/src/templates/InstantSearch.js/src/app.js.hbs +7 -6
- package/src/templates/React InstantSearch Hooks/.template.js +1 -0
- package/src/templates/React InstantSearch Hooks/package.json +0 -1
- package/src/templates/React InstantSearch Hooks/src/App.tsx.hbs +1 -1
- package/src/templates/React InstantSearch Hooks Native/package.json +0 -1
- package/src/templates/Vue InstantSearch/.template.js +2 -1
- package/src/templates/Vue InstantSearch/src/App.vue +1 -0
- package/src/templates/Vue InstantSearch with Vue 3/.template.js +2 -1
- package/src/templates/Vue InstantSearch with Vue 3/src/App.vue +1 -0
- package/src/utils/index.js +3 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-instantsearch-app",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.4.1",
|
|
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.
|
|
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": "
|
|
55
|
+
"gitHead": "f4acbc0c1106a4fd7c7ad95a3e02de4fdac1ad27"
|
|
57
56
|
}
|
package/src/api/check-config.js
CHANGED
package/src/api/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
-
|
|
3
|
-
const resolveTemplate = require('./resolve-template');
|
|
2
|
+
|
|
4
3
|
const buildTask = require('../tasks/common/build');
|
|
5
4
|
const cleanTask = require('../tasks/common/clean');
|
|
6
5
|
const { getAllTemplates } = require('../utils');
|
|
7
6
|
|
|
7
|
+
const checkConfig = require('./check-config');
|
|
8
|
+
const resolveTemplate = require('./resolve-template');
|
|
9
|
+
|
|
8
10
|
const supportedTemplates = getAllTemplates();
|
|
9
11
|
|
|
10
12
|
function noop() {}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const postProcessAnswers = require('../postProcessAnswers');
|
|
2
1
|
const utils = require('../../utils');
|
|
2
|
+
const postProcessAnswers = require('../postProcessAnswers');
|
|
3
3
|
|
|
4
4
|
jest.mock('../../utils', () => ({
|
|
5
5
|
...jest.requireActual('../../utils'),
|
|
@@ -80,32 +80,109 @@ test('creates alternative names', async () => {
|
|
|
80
80
|
);
|
|
81
81
|
});
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
const os = require('os');
|
|
2
3
|
const path = require('path');
|
|
3
4
|
const process = require('process');
|
|
4
|
-
|
|
5
|
+
|
|
6
|
+
const chalk = require('chalk');
|
|
5
7
|
const program = require('commander');
|
|
6
8
|
const inquirer = require('inquirer');
|
|
7
|
-
const chalk = require('chalk');
|
|
8
|
-
const latestSemver = require('latest-semver');
|
|
9
9
|
const semver = require('semver');
|
|
10
10
|
|
|
11
|
+
const { version } = require('../../package.json');
|
|
11
12
|
const createInstantSearchApp = require('../api');
|
|
12
13
|
const {
|
|
13
14
|
checkAppPath,
|
|
@@ -18,13 +19,13 @@ const {
|
|
|
18
19
|
getTemplatePath,
|
|
19
20
|
splitArray,
|
|
20
21
|
} = require('../utils');
|
|
22
|
+
|
|
23
|
+
const getAnswersDefaultValues = require('./getAnswersDefaultValues');
|
|
21
24
|
const getAttributesFromIndex = require('./getAttributesFromIndex');
|
|
25
|
+
const getConfiguration = require('./getConfiguration');
|
|
22
26
|
const getFacetsFromIndex = require('./getFacetsFromIndex');
|
|
23
|
-
const getAnswersDefaultValues = require('./getAnswersDefaultValues');
|
|
24
27
|
const isQuestionAsked = require('./isQuestionAsked');
|
|
25
|
-
const getConfiguration = require('./getConfiguration');
|
|
26
28
|
const postProcessAnswers = require('./postProcessAnswers');
|
|
27
|
-
const { version } = require('../../package.json');
|
|
28
29
|
|
|
29
30
|
let appPathFromArgument;
|
|
30
31
|
|
|
@@ -75,7 +76,9 @@ const getQuestions = ({ appName }) => ({
|
|
|
75
76
|
|
|
76
77
|
try {
|
|
77
78
|
const versions = await fetchLibraryVersions(libraryName);
|
|
78
|
-
const latestStableVersion =
|
|
79
|
+
const latestStableVersion = semver.maxSatisfying(versions, '*', {
|
|
80
|
+
includePrerelease: false,
|
|
81
|
+
});
|
|
79
82
|
|
|
80
83
|
if (!latestStableVersion) {
|
|
81
84
|
return versions;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const camelCase = require('lodash.camelcase');
|
|
2
|
-
const
|
|
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
|
|
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
|
+
const inPlace = require('@metalsmith/in-place');
|
|
2
|
+
const remove = require('@metalsmith/remove');
|
|
1
3
|
const metalsmith = require('metalsmith');
|
|
2
|
-
const inPlace = require('metalsmith-in-place');
|
|
3
4
|
const rename = require('metalsmith-rename');
|
|
4
|
-
const ignore = require('metalsmith-ignore');
|
|
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(
|
|
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`
|
package/src/tasks/ios/install.js
CHANGED
package/src/tasks/ios/setup.js
CHANGED
|
@@ -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
|
|
24
|
+
<h1>${components.Highlight({hit, attribute: "{{attributesToDisplay.[0]}}"})}</h1>
|
|
24
25
|
{{#each attributesToDisplay}}
|
|
25
26
|
{{#unless @first}}
|
|
26
|
-
<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}}',
|
|
@@ -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">
|
|
@@ -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',
|
|
@@ -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',
|
package/src/utils/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
const { execSync } = require('child_process');
|
|
1
2
|
const fs = require('fs');
|
|
2
3
|
const path = require('path');
|
|
3
|
-
|
|
4
|
+
|
|
5
|
+
const algoliasearch = require('algoliasearch');
|
|
4
6
|
const chalk = require('chalk');
|
|
5
7
|
const semver = require('semver');
|
|
6
8
|
const validateProjectName = require('validate-npm-package-name');
|
|
7
|
-
const algoliasearch = require('algoliasearch');
|
|
8
9
|
|
|
9
10
|
const TEMPLATES_FOLDER = path.join(__dirname, '../templates');
|
|
10
11
|
|