@shopify/cli-hydrogen 7.1.0 → 7.1.2
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/dist/commands/hydrogen/build-vite.js +131 -0
- package/dist/commands/hydrogen/build.js +6 -15
- package/dist/commands/hydrogen/check.js +1 -1
- package/dist/commands/hydrogen/codegen.js +3 -3
- package/dist/commands/hydrogen/debug/cpu.js +1 -1
- package/dist/commands/hydrogen/deploy.js +46 -31
- package/dist/commands/hydrogen/deploy.test.js +35 -49
- package/dist/commands/hydrogen/dev-vite.js +159 -0
- package/dist/commands/hydrogen/dev.js +11 -14
- package/dist/commands/hydrogen/env/list.js +1 -1
- package/dist/commands/hydrogen/env/pull.js +3 -3
- package/dist/commands/hydrogen/env/pull.test.js +2 -0
- package/dist/commands/hydrogen/env/push__unstable.js +190 -0
- package/dist/commands/hydrogen/env/push__unstable.test.js +383 -0
- package/dist/commands/hydrogen/generate/route.js +2 -2
- package/dist/commands/hydrogen/init.d.ts +69 -0
- package/dist/commands/hydrogen/init.js +5 -5
- package/dist/commands/hydrogen/init.test.js +2 -2
- package/dist/commands/hydrogen/link.js +2 -2
- package/dist/commands/hydrogen/list.js +1 -1
- package/dist/commands/hydrogen/login.js +2 -9
- package/dist/commands/hydrogen/logout.js +1 -1
- package/dist/commands/hydrogen/preview.js +15 -7
- package/dist/commands/hydrogen/setup/css.js +3 -3
- package/dist/commands/hydrogen/setup/markets.js +4 -4
- package/dist/commands/hydrogen/setup/vite.js +209 -0
- package/dist/commands/hydrogen/setup.js +8 -6
- package/dist/commands/hydrogen/unlink.js +1 -1
- package/dist/commands/hydrogen/upgrade.js +5 -3
- package/dist/generator-templates/assets/vite/package.json +15 -0
- package/dist/generator-templates/assets/vite/vite.config.js +13 -0
- package/dist/generator-templates/starter/CHANGELOG.md +49 -0
- package/dist/generator-templates/starter/app/components/Search.tsx +12 -7
- package/dist/generator-templates/starter/app/root.tsx +1 -2
- package/dist/generator-templates/starter/app/routes/api.predictive-search.tsx +8 -15
- package/dist/generator-templates/starter/package.json +9 -8
- package/dist/generator-templates/starter/public/.gitkeep +0 -0
- package/dist/lib/build.js +2 -1
- package/dist/lib/codegen.js +8 -3
- package/dist/lib/environment-variables.test.js +4 -2
- package/dist/lib/flags.js +149 -95
- package/dist/lib/graphql/admin/pull-variables.js +1 -0
- package/dist/lib/graphql/admin/pull-variables.test.js +7 -1
- package/dist/lib/graphql/admin/push-variables.js +35 -0
- package/dist/lib/log.js +1 -0
- package/dist/lib/mini-oxygen/common.js +2 -1
- package/dist/lib/mini-oxygen/node.js +2 -2
- package/dist/lib/mini-oxygen/workerd-inspector.js +1 -1
- package/dist/lib/mini-oxygen/workerd.js +29 -17
- package/dist/lib/onboarding/common.js +0 -3
- package/dist/lib/onboarding/local.js +4 -1
- package/dist/lib/onboarding/remote.js +16 -11
- package/dist/lib/remix-config.js +1 -1
- package/dist/lib/request-events.js +3 -3
- package/dist/lib/setups/css/assets.js +7 -2
- package/dist/lib/template-diff.js +26 -11
- package/dist/lib/template-downloader.js +11 -2
- package/dist/lib/vite/hydrogen-middleware.js +82 -0
- package/dist/lib/vite/mini-oxygen.js +152 -0
- package/dist/lib/vite/plugins.d.ts +27 -0
- package/dist/lib/vite/plugins.js +139 -0
- package/dist/lib/vite/shared.js +10 -0
- package/dist/lib/vite/utils.js +55 -0
- package/dist/lib/vite/worker-entry.js +1518 -0
- package/dist/lib/vite-config.js +45 -0
- package/dist/virtual-routes/lib/useDebugNetworkServer.jsx +4 -2
- package/dist/virtual-routes/routes/index.jsx +5 -5
- package/dist/virtual-routes/routes/subrequest-profiler.jsx +1 -1
- package/dist/virtual-routes/virtual-root.jsx +1 -1
- package/oclif.manifest.json +1127 -494
- package/package.json +36 -11
- /package/dist/generator-templates/starter/{public → app/assets}/favicon.svg +0 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { resolvePath } from '@shopify/cli-kit/node/path';
|
|
2
|
+
import Command from '@shopify/cli-kit/node/base-command';
|
|
3
|
+
import { renderConfirmationPrompt, renderTasks, renderSuccess } from '@shopify/cli-kit/node/ui';
|
|
4
|
+
import { moveFile, removeFile, copyFile, writeFile } from '@shopify/cli-kit/node/fs';
|
|
5
|
+
import { installNodeModules, getPackageManager } from '@shopify/cli-kit/node/node-package-manager';
|
|
6
|
+
import { commonFlags, flagsToCamelObject } from '../../../lib/flags.js';
|
|
7
|
+
import { getRemixConfig } from '../../../lib/remix-config.js';
|
|
8
|
+
import { replaceFileContent, mergePackageJson } from '../../../lib/file.js';
|
|
9
|
+
import { importLangAstGrep } from '../../../lib/ast.js';
|
|
10
|
+
import { getAssetDir } from '../../../lib/build.js';
|
|
11
|
+
import { getCodeFormatOptions } from '../../../lib/format-code.js';
|
|
12
|
+
|
|
13
|
+
class SetupVite extends Command {
|
|
14
|
+
static description = "EXPERIMENTAL: Upgrades the project to use Vite.";
|
|
15
|
+
static flags = {
|
|
16
|
+
...commonFlags.path
|
|
17
|
+
};
|
|
18
|
+
async run() {
|
|
19
|
+
const { flags } = await this.parse(SetupVite);
|
|
20
|
+
const directory = flags.path ? resolvePath(flags.path) : process.cwd();
|
|
21
|
+
await runSetupVite({
|
|
22
|
+
...flagsToCamelObject(flags),
|
|
23
|
+
directory
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function runSetupVite({ directory }) {
|
|
28
|
+
const remixConfigPromise = getRemixConfig(directory);
|
|
29
|
+
const shouldContinue = await renderConfirmationPrompt({
|
|
30
|
+
message: "Are you sure you want to upgrade to Vite?\nThis is still an experimental feature and may not work as expected"
|
|
31
|
+
});
|
|
32
|
+
if (!shouldContinue)
|
|
33
|
+
return;
|
|
34
|
+
const handlePartialIssue = () => {
|
|
35
|
+
};
|
|
36
|
+
const backgroundWorkPromise = Promise.all([
|
|
37
|
+
moveFile(
|
|
38
|
+
resolvePath(directory, "remix.env.d.ts"),
|
|
39
|
+
resolvePath(directory, "env.d.ts")
|
|
40
|
+
).then(
|
|
41
|
+
() => replaceFileContent(
|
|
42
|
+
resolvePath(directory, "env.d.ts"),
|
|
43
|
+
false,
|
|
44
|
+
(content) => content.replace('types="@remix-run/dev"', 'types="vite/client"')
|
|
45
|
+
)
|
|
46
|
+
).catch(handlePartialIssue),
|
|
47
|
+
moveFile(
|
|
48
|
+
resolvePath(directory, ".eslintrc.js"),
|
|
49
|
+
resolvePath(directory, ".eslintrc.cjs")
|
|
50
|
+
).catch(handlePartialIssue),
|
|
51
|
+
moveFile(
|
|
52
|
+
resolvePath(directory, "postcss.config.js"),
|
|
53
|
+
resolvePath(directory, "postcss.config.cjs")
|
|
54
|
+
).catch(handlePartialIssue),
|
|
55
|
+
remixConfigPromise.then((config) => {
|
|
56
|
+
const serverEntry = config.serverEntryPoint || "server.js";
|
|
57
|
+
const isTS = serverEntry.endsWith(".ts");
|
|
58
|
+
const fileExt = isTS ? "tsx" : "jsx";
|
|
59
|
+
const viteAssets = getAssetDir("vite");
|
|
60
|
+
return Promise.all([
|
|
61
|
+
removeFile(resolvePath(directory, "remix.config.js")).catch(
|
|
62
|
+
handlePartialIssue
|
|
63
|
+
),
|
|
64
|
+
copyFile(
|
|
65
|
+
resolvePath(viteAssets, "vite.config.js"),
|
|
66
|
+
resolvePath(directory, "vite.config." + fileExt.slice(0, 2))
|
|
67
|
+
),
|
|
68
|
+
mergePackageJson(viteAssets, directory),
|
|
69
|
+
replaceFileContent(
|
|
70
|
+
resolvePath(directory, serverEntry),
|
|
71
|
+
false,
|
|
72
|
+
(content) => (isTS ? "// @ts-ignore\n" : "") + content.replace(
|
|
73
|
+
"@remix-run/dev/server-build",
|
|
74
|
+
"virtual:remix/server-build"
|
|
75
|
+
)
|
|
76
|
+
),
|
|
77
|
+
importLangAstGrep(fileExt).then(async (astGrep) => {
|
|
78
|
+
const codeFormatOpt = getCodeFormatOptions(directory);
|
|
79
|
+
const rootFilepath = resolvePath(
|
|
80
|
+
config.appDirectory,
|
|
81
|
+
"root." + fileExt
|
|
82
|
+
);
|
|
83
|
+
await new Promise(async (resolve, reject) => {
|
|
84
|
+
const fileNumber = await astGrep.findInFiles(
|
|
85
|
+
{
|
|
86
|
+
paths: [
|
|
87
|
+
rootFilepath,
|
|
88
|
+
resolvePath(config.appDirectory, "routes")
|
|
89
|
+
],
|
|
90
|
+
matcher: {
|
|
91
|
+
rule: {
|
|
92
|
+
kind: "string_fragment",
|
|
93
|
+
regex: "\\.css$",
|
|
94
|
+
inside: {
|
|
95
|
+
kind: "import_statement",
|
|
96
|
+
stopBy: "end"
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
async (err, nodes) => {
|
|
102
|
+
if (err)
|
|
103
|
+
reject(err);
|
|
104
|
+
const nodeMap = {};
|
|
105
|
+
nodes.forEach((node) => {
|
|
106
|
+
const filename = node.getRoot().filename();
|
|
107
|
+
const content = node.getRoot().root().text();
|
|
108
|
+
const position = node.range().end.index;
|
|
109
|
+
const tmp = nodeMap[filename] || { content, positions: [] };
|
|
110
|
+
tmp.positions.push(position);
|
|
111
|
+
nodeMap[filename] = tmp;
|
|
112
|
+
});
|
|
113
|
+
await Promise.all(
|
|
114
|
+
Object.entries(nodeMap).flatMap(
|
|
115
|
+
([filename, { content, positions }]) => {
|
|
116
|
+
positions.reverse();
|
|
117
|
+
for (const position of positions) {
|
|
118
|
+
content = content.slice(0, position) + "?url" + content.slice(position);
|
|
119
|
+
}
|
|
120
|
+
return writeFile(filename, content);
|
|
121
|
+
}
|
|
122
|
+
)
|
|
123
|
+
);
|
|
124
|
+
resolve(null);
|
|
125
|
+
}
|
|
126
|
+
);
|
|
127
|
+
if (fileNumber === 0)
|
|
128
|
+
resolve(null);
|
|
129
|
+
});
|
|
130
|
+
await replaceFileContent(
|
|
131
|
+
rootFilepath,
|
|
132
|
+
await codeFormatOpt,
|
|
133
|
+
(content) => {
|
|
134
|
+
const root = astGrep.parse(content).root();
|
|
135
|
+
const liveReloadRegex = "LiveReload";
|
|
136
|
+
const hasLiveReloadRule = {
|
|
137
|
+
kind: "identifier",
|
|
138
|
+
regex: liveReloadRegex
|
|
139
|
+
};
|
|
140
|
+
const liveReloadImport = root.find({
|
|
141
|
+
rule: {
|
|
142
|
+
kind: "import_specifier",
|
|
143
|
+
regex: liveReloadRegex,
|
|
144
|
+
inside: {
|
|
145
|
+
kind: "import_statement",
|
|
146
|
+
stopBy: "end"
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
const liveReloadElements = root.findAll({
|
|
151
|
+
rule: {
|
|
152
|
+
any: [
|
|
153
|
+
{
|
|
154
|
+
kind: "jsx_self_closing_element",
|
|
155
|
+
has: hasLiveReloadRule
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
kind: "jsx_element",
|
|
159
|
+
has: {
|
|
160
|
+
kind: "jsx_opening_element",
|
|
161
|
+
has: hasLiveReloadRule
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
for (const node of [
|
|
168
|
+
// From bottom to top
|
|
169
|
+
...liveReloadElements.reverse(),
|
|
170
|
+
liveReloadImport
|
|
171
|
+
]) {
|
|
172
|
+
if (!node)
|
|
173
|
+
continue;
|
|
174
|
+
const { start, end } = node.range();
|
|
175
|
+
content = content.slice(0, start.index) + content.slice(end.index);
|
|
176
|
+
}
|
|
177
|
+
return content.replace(/,\s*,/g, ",");
|
|
178
|
+
}
|
|
179
|
+
);
|
|
180
|
+
})
|
|
181
|
+
]);
|
|
182
|
+
})
|
|
183
|
+
]);
|
|
184
|
+
await renderTasks([
|
|
185
|
+
{
|
|
186
|
+
title: "Updating files",
|
|
187
|
+
task: async () => {
|
|
188
|
+
await backgroundWorkPromise;
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
title: "Installing new dependencies",
|
|
193
|
+
task: async () => {
|
|
194
|
+
await installNodeModules({
|
|
195
|
+
directory,
|
|
196
|
+
packageManager: await getPackageManager(directory),
|
|
197
|
+
args: []
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
]);
|
|
202
|
+
renderSuccess({
|
|
203
|
+
headline: `Your Vite project is ready!`,
|
|
204
|
+
body: `We've modified your project to use Vite experimental.
|
|
205
|
+
Please use git to review the changes.`
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export { SetupVite as default, runSetupVite };
|
|
@@ -13,12 +13,14 @@ import { getTemplateAppFile } from '../../lib/build.js';
|
|
|
13
13
|
class Setup extends Command {
|
|
14
14
|
static description = "Scaffold routes and core functionality.";
|
|
15
15
|
static flags = {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
...commonFlags.path,
|
|
17
|
+
...commonFlags.force,
|
|
18
|
+
...commonFlags.styling,
|
|
19
|
+
...commonFlags.markets,
|
|
20
|
+
...commonFlags.shortcut,
|
|
21
|
+
...overrideFlag(commonFlags.installDeps, {
|
|
22
|
+
"install-deps": { default: true }
|
|
23
|
+
})
|
|
22
24
|
};
|
|
23
25
|
async run() {
|
|
24
26
|
const { flags } = await this.parse(Setup);
|
|
@@ -7,7 +7,7 @@ import { getConfig, unsetStorefront } from '../../lib/shopify-config.js';
|
|
|
7
7
|
class Unlink extends Command {
|
|
8
8
|
static description = "Unlink a local project from a Hydrogen storefront.";
|
|
9
9
|
static flags = {
|
|
10
|
-
|
|
10
|
+
...commonFlags.path
|
|
11
11
|
};
|
|
12
12
|
async run() {
|
|
13
13
|
const { flags } = await this.parse(Unlink);
|
|
@@ -10,6 +10,7 @@ import { renderSuccess, renderInfo, renderConfirmationPrompt, renderTasks, rende
|
|
|
10
10
|
import { readFile, isDirectory, mkdir, fileExists, touchFile, removeFile, writeFile } from '@shopify/cli-kit/node/fs';
|
|
11
11
|
import { installNodeModules, getPackageManager, getDependencies } from '@shopify/cli-kit/node/node-package-manager';
|
|
12
12
|
import { AbortError } from '@shopify/cli-kit/node/error';
|
|
13
|
+
import { getCliCommand } from '../../lib/shell.js';
|
|
13
14
|
import { commonFlags, flagsToCamelObject } from '../../lib/flags.js';
|
|
14
15
|
import { getProjectPaths } from '../../lib/remix-config.js';
|
|
15
16
|
|
|
@@ -17,7 +18,7 @@ const INSTRUCTIONS_FOLDER = ".hydrogen";
|
|
|
17
18
|
class Upgrade extends Command {
|
|
18
19
|
static description = "Upgrade Remix and Hydrogen npm dependencies.";
|
|
19
20
|
static flags = {
|
|
20
|
-
|
|
21
|
+
...commonFlags.path,
|
|
21
22
|
version: Flags.string({
|
|
22
23
|
description: "A target hydrogen version to update to",
|
|
23
24
|
required: false,
|
|
@@ -153,7 +154,7 @@ async function getHydrogenVersion({ appPath }) {
|
|
|
153
154
|
async function getChangelog() {
|
|
154
155
|
if (CACHED_CHANGELOG)
|
|
155
156
|
return CACHED_CHANGELOG;
|
|
156
|
-
if (process.env.FORCE_CHANGELOG_SOURCE === "local" || process.env.FORCE_CHANGELOG_SOURCE !== "remote" && !!process.env.
|
|
157
|
+
if (process.env.FORCE_CHANGELOG_SOURCE === "local" || process.env.FORCE_CHANGELOG_SOURCE !== "remote" && !!process.env.LOCAL_DEV) {
|
|
157
158
|
const require2 = createRequire(import.meta.url);
|
|
158
159
|
return require2(fileURLToPath(
|
|
159
160
|
new URL("../../../../../docs/changelog.json", import.meta.url)
|
|
@@ -681,6 +682,7 @@ async function displayDevUpgradeNotice({
|
|
|
681
682
|
return `${version} - ${release.title}`;
|
|
682
683
|
}).slice(0, 5) : [];
|
|
683
684
|
let headline = Object.keys(uniqueAvailableUpgrades).length > 1 ? `There are ${Object.keys(uniqueAvailableUpgrades).length} new @shopify/hydrogen versions available.` : `There's a new @shopify/hydrogen version available.`;
|
|
685
|
+
const cliCommand = await getCliCommand();
|
|
684
686
|
renderInfo({
|
|
685
687
|
headline,
|
|
686
688
|
body: [`Current: ${currentVersion} | Latest: ${pinnedLatestVersion}`],
|
|
@@ -705,7 +707,7 @@ async function displayDevUpgradeNotice({
|
|
|
705
707
|
{
|
|
706
708
|
list: {
|
|
707
709
|
items: [
|
|
708
|
-
`Run
|
|
710
|
+
`Run \`${cliCommand} upgrade\` or \`${cliCommand} upgrade --version XXXX.X.XX\``,
|
|
709
711
|
,
|
|
710
712
|
`Read release notes at https://hydrogen.shopify.dev/releases`
|
|
711
713
|
]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "module",
|
|
3
|
+
"scripts": {
|
|
4
|
+
"build": "shopify hydrogen build-vite --codegen",
|
|
5
|
+
"dev": "shopify hydrogen dev-vite --codegen"
|
|
6
|
+
},
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@remix-run/node": "^2.8.0",
|
|
9
|
+
"isbot": "^3.8.0"
|
|
10
|
+
},
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"vite": "~5.1.0",
|
|
13
|
+
"vite-tsconfig-paths": "^4.3.1"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {defineConfig} from 'vite';
|
|
2
|
+
import {hydrogen, oxygen} from '@shopify/cli-hydrogen/experimental-vite';
|
|
3
|
+
import {vitePlugin as remix} from '@remix-run/dev';
|
|
4
|
+
import tsconfigPaths from 'vite-tsconfig-paths';
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
plugins: [
|
|
8
|
+
hydrogen(),
|
|
9
|
+
oxygen(),
|
|
10
|
+
remix({buildDirectory: 'dist'}),
|
|
11
|
+
tsconfigPaths(),
|
|
12
|
+
],
|
|
13
|
+
});
|
|
@@ -1,5 +1,54 @@
|
|
|
1
1
|
# skeleton
|
|
2
2
|
|
|
3
|
+
## 1.0.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Improve performance of predictive search: ([#1823](https://github.com/Shopify/hydrogen/pull/1823)) by [@frandiox](https://github.com/frandiox)
|
|
8
|
+
|
|
9
|
+
- Change the request to be GET instead of POST to avoid Remix route revalidations.
|
|
10
|
+
- Add Cache-Control headers to the response to get quicker results when typing.
|
|
11
|
+
|
|
12
|
+
Aside from that, it now shows a loading state when fetching the results instead of "No results found.".
|
|
13
|
+
|
|
14
|
+
- Updated dependencies [[`351b3c1b`](https://github.com/Shopify/hydrogen/commit/351b3c1b7768870793ff072ba91426107ba0180c), [`5060cf57`](https://github.com/Shopify/hydrogen/commit/5060cf57f69d8391b425b54acaa487af1f7405ae), [`2888014e`](https://github.com/Shopify/hydrogen/commit/2888014e54fab72c150e9eca55df3c6dd789503e)]:
|
|
15
|
+
- @shopify/hydrogen@2024.1.4
|
|
16
|
+
- @shopify/cli-hydrogen@7.1.2
|
|
17
|
+
|
|
18
|
+
## 1.0.5
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- Update the `@shopify/cli` dependency: ([#1786](https://github.com/Shopify/hydrogen/pull/1786)) by [@frandiox](https://github.com/frandiox)
|
|
23
|
+
|
|
24
|
+
```diff
|
|
25
|
+
- "@shopify/cli": "3.52.0",
|
|
26
|
+
+ "@shopify/cli": "3.56.3",
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
- Update Remix and associated packages to 2.8.0. ([#1781](https://github.com/Shopify/hydrogen/pull/1781)) by [@frandiox](https://github.com/frandiox)
|
|
30
|
+
|
|
31
|
+
```diff
|
|
32
|
+
"dependencies": {
|
|
33
|
+
- "@remix-run/react": "^2.6.0",
|
|
34
|
+
- "@remix-run/server-runtime": "^2.6.0",
|
|
35
|
+
+ "@remix-run/react": "^2.8.0",
|
|
36
|
+
+ "@remix-run/server-runtime": "^2.8.0",
|
|
37
|
+
//...
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
- "@remix-run/dev": "^2.6.0",
|
|
41
|
+
- "@remix-run/eslint-config": "^2.6.0",
|
|
42
|
+
+ "@remix-run/dev": "^2.8.0",
|
|
43
|
+
+ "@remix-run/eslint-config": "^2.8.0",
|
|
44
|
+
//...
|
|
45
|
+
},
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- Updated dependencies [[`ced1d4cb`](https://github.com/Shopify/hydrogen/commit/ced1d4cb5b1eeeb4303449eb1d60aac44f33480e), [`fc013401`](https://github.com/Shopify/hydrogen/commit/fc013401c5727948b602c9c6b6963a2df21cbd38), [`e641255e`](https://github.com/Shopify/hydrogen/commit/e641255eccc5783b41c8fabbc88313a610f539d0), [`d7e04cb6`](https://github.com/Shopify/hydrogen/commit/d7e04cb6a33d40ea86fa8ac2712d7a5ea785de2d), [`eedd9c49`](https://github.com/Shopify/hydrogen/commit/eedd9c497b36aba47a641cecbc710e18f5b14e46)]:
|
|
49
|
+
- @shopify/cli-hydrogen@7.1.1
|
|
50
|
+
- @shopify/hydrogen@2024.1.3
|
|
51
|
+
|
|
3
52
|
## 1.0.4
|
|
4
53
|
|
|
5
54
|
### Patch Changes
|
|
@@ -263,20 +263,18 @@ type ChildrenRenderProps = {
|
|
|
263
263
|
|
|
264
264
|
type SearchFromProps = {
|
|
265
265
|
action?: FormProps['action'];
|
|
266
|
-
method?: FormProps['method'];
|
|
267
266
|
className?: string;
|
|
268
267
|
children: (passedProps: ChildrenRenderProps) => React.ReactNode;
|
|
269
268
|
[key: string]: unknown;
|
|
270
269
|
};
|
|
271
270
|
|
|
272
271
|
/**
|
|
273
|
-
* Search form component that
|
|
272
|
+
* Search form component that sends search requests to the `/search` route
|
|
274
273
|
**/
|
|
275
274
|
export function PredictiveSearchForm({
|
|
276
275
|
action,
|
|
277
276
|
children,
|
|
278
277
|
className = 'predictive-search-form',
|
|
279
|
-
method = 'POST',
|
|
280
278
|
...props
|
|
281
279
|
}: SearchFromProps) {
|
|
282
280
|
const params = useParams();
|
|
@@ -287,13 +285,14 @@ export function PredictiveSearchForm({
|
|
|
287
285
|
|
|
288
286
|
function fetchResults(event: React.ChangeEvent<HTMLInputElement>) {
|
|
289
287
|
const searchAction = action ?? '/api/predictive-search';
|
|
288
|
+
const newSearchTerm = event.target.value || '';
|
|
290
289
|
const localizedAction = params.locale
|
|
291
290
|
? `/${params.locale}${searchAction}`
|
|
292
291
|
: searchAction;
|
|
293
|
-
|
|
292
|
+
|
|
294
293
|
fetcher.submit(
|
|
295
294
|
{q: newSearchTerm, limit: '6'},
|
|
296
|
-
{method, action: localizedAction},
|
|
295
|
+
{method: 'GET', action: localizedAction},
|
|
297
296
|
);
|
|
298
297
|
}
|
|
299
298
|
|
|
@@ -322,7 +321,7 @@ export function PredictiveSearchForm({
|
|
|
322
321
|
}
|
|
323
322
|
|
|
324
323
|
export function PredictiveSearchResults() {
|
|
325
|
-
const {results, totalResults, searchInputRef, searchTerm} =
|
|
324
|
+
const {results, totalResults, searchInputRef, searchTerm, state} =
|
|
326
325
|
usePredictiveSearch();
|
|
327
326
|
|
|
328
327
|
function goToSearchResult(event: React.MouseEvent<HTMLAnchorElement>) {
|
|
@@ -333,9 +332,14 @@ export function PredictiveSearchResults() {
|
|
|
333
332
|
window.location.href = event.currentTarget.href;
|
|
334
333
|
}
|
|
335
334
|
|
|
335
|
+
if (state === 'loading') {
|
|
336
|
+
return <div>Loading...</div>;
|
|
337
|
+
}
|
|
338
|
+
|
|
336
339
|
if (!totalResults) {
|
|
337
340
|
return <NoPredictiveSearchResults searchTerm={searchTerm} />;
|
|
338
341
|
}
|
|
342
|
+
|
|
339
343
|
return (
|
|
340
344
|
<div className="predictive-search-results">
|
|
341
345
|
<div>
|
|
@@ -452,6 +456,7 @@ function SearchResultItem({goToSearchResult, item}: SearchResultItemProps) {
|
|
|
452
456
|
type UseSearchReturn = NormalizedPredictiveSearch & {
|
|
453
457
|
searchInputRef: React.MutableRefObject<HTMLInputElement | null>;
|
|
454
458
|
searchTerm: React.MutableRefObject<string>;
|
|
459
|
+
state: ReturnType<typeof useFetcher>['state'];
|
|
455
460
|
};
|
|
456
461
|
|
|
457
462
|
function usePredictiveSearch(): UseSearchReturn {
|
|
@@ -474,7 +479,7 @@ function usePredictiveSearch(): UseSearchReturn {
|
|
|
474
479
|
searchInputRef.current = document.querySelector('input[type="search"]');
|
|
475
480
|
}, []);
|
|
476
481
|
|
|
477
|
-
return {...search, searchInputRef, searchTerm};
|
|
482
|
+
return {...search, searchInputRef, searchTerm, state: searchFetcher.state};
|
|
478
483
|
}
|
|
479
484
|
|
|
480
485
|
/**
|
|
@@ -17,8 +17,7 @@ import {
|
|
|
17
17
|
isRouteErrorResponse,
|
|
18
18
|
type ShouldRevalidateFunction,
|
|
19
19
|
} from '@remix-run/react';
|
|
20
|
-
import
|
|
21
|
-
import favicon from '../public/favicon.svg';
|
|
20
|
+
import favicon from './assets/favicon.svg';
|
|
22
21
|
import resetStyles from './styles/reset.css';
|
|
23
22
|
import appStyles from './styles/app.css';
|
|
24
23
|
import {Layout} from '~/components/Layout';
|
|
@@ -34,18 +34,16 @@ const DEFAULT_SEARCH_TYPES: PredictiveSearchTypes[] = [
|
|
|
34
34
|
* Fetches the search results from the predictive search API
|
|
35
35
|
* requested by the SearchForm component
|
|
36
36
|
*/
|
|
37
|
-
export async function
|
|
38
|
-
if (request.method !== 'POST') {
|
|
39
|
-
throw new Error('Invalid request method');
|
|
40
|
-
}
|
|
41
|
-
|
|
37
|
+
export async function loader({request, params, context}: LoaderFunctionArgs) {
|
|
42
38
|
const search = await fetchPredictiveSearchResults({
|
|
43
39
|
params,
|
|
44
40
|
request,
|
|
45
41
|
context,
|
|
46
42
|
});
|
|
47
43
|
|
|
48
|
-
return json(search
|
|
44
|
+
return json(search, {
|
|
45
|
+
headers: {'Cache-Control': `max-age=${search.searchTerm ? 60 : 3600}`},
|
|
46
|
+
});
|
|
49
47
|
}
|
|
50
48
|
|
|
51
49
|
async function fetchPredictiveSearchResults({
|
|
@@ -55,15 +53,10 @@ async function fetchPredictiveSearchResults({
|
|
|
55
53
|
}: Pick<LoaderFunctionArgs, 'params' | 'context' | 'request'>) {
|
|
56
54
|
const url = new URL(request.url);
|
|
57
55
|
const searchParams = new URLSearchParams(url.search);
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const searchTerm = String(body?.get('q') || searchParams.get('q') || '');
|
|
63
|
-
const limit = Number(body?.get('limit') || searchParams.get('limit') || 10);
|
|
64
|
-
const rawTypes = String(
|
|
65
|
-
body?.get('type') || searchParams.get('type') || 'ANY',
|
|
66
|
-
);
|
|
56
|
+
const searchTerm = searchParams.get('q') || '';
|
|
57
|
+
const limit = Number(searchParams.get('limit') || 10);
|
|
58
|
+
const rawTypes = String(searchParams.get('type') || 'ANY');
|
|
59
|
+
|
|
67
60
|
const searchTypes =
|
|
68
61
|
rawTypes === 'ANY'
|
|
69
62
|
? DEFAULT_SEARCH_TYPES
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
"name": "skeleton",
|
|
3
3
|
"private": true,
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.6",
|
|
6
|
+
"type": "commonjs",
|
|
6
7
|
"scripts": {
|
|
7
8
|
"build": "shopify hydrogen build",
|
|
8
9
|
"dev": "shopify hydrogen dev --codegen",
|
|
@@ -13,11 +14,11 @@
|
|
|
13
14
|
},
|
|
14
15
|
"prettier": "@shopify/prettier-config",
|
|
15
16
|
"dependencies": {
|
|
16
|
-
"@remix-run/react": "^2.
|
|
17
|
-
"@remix-run/server-runtime": "^2.
|
|
18
|
-
"@shopify/cli": "3.
|
|
19
|
-
"@shopify/cli-hydrogen": "^7.1.
|
|
20
|
-
"@shopify/hydrogen": "~2024.1.
|
|
17
|
+
"@remix-run/react": "^2.8.0",
|
|
18
|
+
"@remix-run/server-runtime": "^2.8.0",
|
|
19
|
+
"@shopify/cli": "3.56.3",
|
|
20
|
+
"@shopify/cli-hydrogen": "^7.1.2",
|
|
21
|
+
"@shopify/hydrogen": "~2024.1.4",
|
|
21
22
|
"@shopify/remix-oxygen": "^2.0.3",
|
|
22
23
|
"graphql": "^16.6.0",
|
|
23
24
|
"graphql-tag": "^2.12.6",
|
|
@@ -26,8 +27,8 @@
|
|
|
26
27
|
"react-dom": "^18.2.0"
|
|
27
28
|
},
|
|
28
29
|
"devDependencies": {
|
|
29
|
-
"@remix-run/dev": "^2.
|
|
30
|
-
"@remix-run/eslint-config": "^2.
|
|
30
|
+
"@remix-run/dev": "^2.8.0",
|
|
31
|
+
"@remix-run/eslint-config": "^2.8.0",
|
|
31
32
|
"@shopify/oxygen-workers-types": "^4.0.0",
|
|
32
33
|
"@shopify/prettier-config": "^1.1.2",
|
|
33
34
|
"@total-typescript/ts-reset": "^0.4.2",
|
|
File without changes
|
package/dist/lib/build.js
CHANGED
package/dist/lib/codegen.js
CHANGED
|
@@ -2,7 +2,7 @@ import { spawn } from 'node:child_process';
|
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
3
|
import { getCodeFormatOptions, formatCode } from './format-code.js';
|
|
4
4
|
import { renderWarning, renderFatalError } from '@shopify/cli-kit/node/ui';
|
|
5
|
-
import { relativePath, joinPath, basename } from '@shopify/cli-kit/node/path';
|
|
5
|
+
import { relativePath, joinPath, resolvePath, basename } from '@shopify/cli-kit/node/path';
|
|
6
6
|
import { AbortError } from '@shopify/cli-kit/node/error';
|
|
7
7
|
|
|
8
8
|
const nodePath = process.argv[1];
|
|
@@ -36,7 +36,7 @@ function spawnCodegenProcess({
|
|
|
36
36
|
[
|
|
37
37
|
fileURLToPath(import.meta.url),
|
|
38
38
|
rootDirectory,
|
|
39
|
-
appDirectory,
|
|
39
|
+
appDirectory ?? resolvePath("app"),
|
|
40
40
|
configFilePath ?? ""
|
|
41
41
|
],
|
|
42
42
|
{ stdio: ["inherit", "ignore", "pipe"] }
|
|
@@ -46,6 +46,8 @@ function spawnCodegenProcess({
|
|
|
46
46
|
if (!dataString)
|
|
47
47
|
return;
|
|
48
48
|
const { message, details } = normalizeCodegenError(dataString, rootDirectory);
|
|
49
|
+
if (/`punycode`/.test(message))
|
|
50
|
+
return;
|
|
49
51
|
console.log("");
|
|
50
52
|
renderWarning({ headline: message, body: details });
|
|
51
53
|
});
|
|
@@ -110,7 +112,10 @@ async function generateTypes({
|
|
|
110
112
|
return acc;
|
|
111
113
|
}, {});
|
|
112
114
|
}
|
|
113
|
-
async function generateDefaultConfig({
|
|
115
|
+
async function generateDefaultConfig({
|
|
116
|
+
rootDirectory,
|
|
117
|
+
appDirectory = resolvePath(rootDirectory, "app")
|
|
118
|
+
}, forceSfapiVersion) {
|
|
114
119
|
const { getSchema, preset, pluckConfig } = await import('@shopify/hydrogen-codegen');
|
|
115
120
|
const { loadConfig } = await import('graphql-config');
|
|
116
121
|
const gqlConfig = await loadConfig({
|
|
@@ -34,7 +34,8 @@ describe("getAllEnvironmentVariables()", () => {
|
|
|
34
34
|
id: "gid://shopify/HydrogenStorefrontEnvironmentVariable/1",
|
|
35
35
|
key: "PUBLIC_API_TOKEN",
|
|
36
36
|
value: "abc123",
|
|
37
|
-
isSecret: false
|
|
37
|
+
isSecret: false,
|
|
38
|
+
readOnly: false
|
|
38
39
|
}
|
|
39
40
|
]
|
|
40
41
|
});
|
|
@@ -102,7 +103,8 @@ describe("getAllEnvironmentVariables()", () => {
|
|
|
102
103
|
id: "gid://shopify/HydrogenStorefrontEnvironmentVariable/1",
|
|
103
104
|
key: "PUBLIC_API_TOKEN",
|
|
104
105
|
value: "",
|
|
105
|
-
isSecret: true
|
|
106
|
+
isSecret: true,
|
|
107
|
+
readOnly: false
|
|
106
108
|
}
|
|
107
109
|
]
|
|
108
110
|
});
|