@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.
Files changed (72) hide show
  1. package/dist/commands/hydrogen/build-vite.js +131 -0
  2. package/dist/commands/hydrogen/build.js +6 -15
  3. package/dist/commands/hydrogen/check.js +1 -1
  4. package/dist/commands/hydrogen/codegen.js +3 -3
  5. package/dist/commands/hydrogen/debug/cpu.js +1 -1
  6. package/dist/commands/hydrogen/deploy.js +46 -31
  7. package/dist/commands/hydrogen/deploy.test.js +35 -49
  8. package/dist/commands/hydrogen/dev-vite.js +159 -0
  9. package/dist/commands/hydrogen/dev.js +11 -14
  10. package/dist/commands/hydrogen/env/list.js +1 -1
  11. package/dist/commands/hydrogen/env/pull.js +3 -3
  12. package/dist/commands/hydrogen/env/pull.test.js +2 -0
  13. package/dist/commands/hydrogen/env/push__unstable.js +190 -0
  14. package/dist/commands/hydrogen/env/push__unstable.test.js +383 -0
  15. package/dist/commands/hydrogen/generate/route.js +2 -2
  16. package/dist/commands/hydrogen/init.d.ts +69 -0
  17. package/dist/commands/hydrogen/init.js +5 -5
  18. package/dist/commands/hydrogen/init.test.js +2 -2
  19. package/dist/commands/hydrogen/link.js +2 -2
  20. package/dist/commands/hydrogen/list.js +1 -1
  21. package/dist/commands/hydrogen/login.js +2 -9
  22. package/dist/commands/hydrogen/logout.js +1 -1
  23. package/dist/commands/hydrogen/preview.js +15 -7
  24. package/dist/commands/hydrogen/setup/css.js +3 -3
  25. package/dist/commands/hydrogen/setup/markets.js +4 -4
  26. package/dist/commands/hydrogen/setup/vite.js +209 -0
  27. package/dist/commands/hydrogen/setup.js +8 -6
  28. package/dist/commands/hydrogen/unlink.js +1 -1
  29. package/dist/commands/hydrogen/upgrade.js +5 -3
  30. package/dist/generator-templates/assets/vite/package.json +15 -0
  31. package/dist/generator-templates/assets/vite/vite.config.js +13 -0
  32. package/dist/generator-templates/starter/CHANGELOG.md +49 -0
  33. package/dist/generator-templates/starter/app/components/Search.tsx +12 -7
  34. package/dist/generator-templates/starter/app/root.tsx +1 -2
  35. package/dist/generator-templates/starter/app/routes/api.predictive-search.tsx +8 -15
  36. package/dist/generator-templates/starter/package.json +9 -8
  37. package/dist/generator-templates/starter/public/.gitkeep +0 -0
  38. package/dist/lib/build.js +2 -1
  39. package/dist/lib/codegen.js +8 -3
  40. package/dist/lib/environment-variables.test.js +4 -2
  41. package/dist/lib/flags.js +149 -95
  42. package/dist/lib/graphql/admin/pull-variables.js +1 -0
  43. package/dist/lib/graphql/admin/pull-variables.test.js +7 -1
  44. package/dist/lib/graphql/admin/push-variables.js +35 -0
  45. package/dist/lib/log.js +1 -0
  46. package/dist/lib/mini-oxygen/common.js +2 -1
  47. package/dist/lib/mini-oxygen/node.js +2 -2
  48. package/dist/lib/mini-oxygen/workerd-inspector.js +1 -1
  49. package/dist/lib/mini-oxygen/workerd.js +29 -17
  50. package/dist/lib/onboarding/common.js +0 -3
  51. package/dist/lib/onboarding/local.js +4 -1
  52. package/dist/lib/onboarding/remote.js +16 -11
  53. package/dist/lib/remix-config.js +1 -1
  54. package/dist/lib/request-events.js +3 -3
  55. package/dist/lib/setups/css/assets.js +7 -2
  56. package/dist/lib/template-diff.js +26 -11
  57. package/dist/lib/template-downloader.js +11 -2
  58. package/dist/lib/vite/hydrogen-middleware.js +82 -0
  59. package/dist/lib/vite/mini-oxygen.js +152 -0
  60. package/dist/lib/vite/plugins.d.ts +27 -0
  61. package/dist/lib/vite/plugins.js +139 -0
  62. package/dist/lib/vite/shared.js +10 -0
  63. package/dist/lib/vite/utils.js +55 -0
  64. package/dist/lib/vite/worker-entry.js +1518 -0
  65. package/dist/lib/vite-config.js +45 -0
  66. package/dist/virtual-routes/lib/useDebugNetworkServer.jsx +4 -2
  67. package/dist/virtual-routes/routes/index.jsx +5 -5
  68. package/dist/virtual-routes/routes/subrequest-profiler.jsx +1 -1
  69. package/dist/virtual-routes/virtual-root.jsx +1 -1
  70. package/oclif.manifest.json +1127 -494
  71. package/package.json +36 -11
  72. /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
- path: commonFlags.path,
17
- force: commonFlags.force,
18
- styling: commonFlags.styling,
19
- markets: commonFlags.markets,
20
- shortcut: commonFlags.shortcut,
21
- "install-deps": overrideFlag(commonFlags.installDeps, { default: true })
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
- path: commonFlags.path
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
- path: commonFlags.path,
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.LOCAL_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 \`h2 upgrade\` or \`h2 upgrade --version XXXX.X.XX\``,
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 posts search requests to the `/search` route
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
- const newSearchTerm = event.target.value || '';
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 type {CustomerAccessToken} from '@shopify/hydrogen/storefront-api-types';
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 action({request, params, context}: LoaderFunctionArgs) {
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
- let body;
59
- try {
60
- body = await request.formData();
61
- } catch (error) {}
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.4",
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.6.0",
17
- "@remix-run/server-runtime": "^2.6.0",
18
- "@shopify/cli": "3.52.0",
19
- "@shopify/cli-hydrogen": "^7.1.0",
20
- "@shopify/hydrogen": "~2024.1.2",
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.6.0",
30
- "@remix-run/eslint-config": "^2.6.0",
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",
package/dist/lib/build.js CHANGED
@@ -10,7 +10,8 @@ const GENERATOR_SETUP_ASSETS_SUB_DIRS = [
10
10
  "tailwind",
11
11
  "css-modules",
12
12
  "vanilla-extract",
13
- "postcss"
13
+ "postcss",
14
+ "vite"
14
15
  ];
15
16
  function getAssetDir(feature) {
16
17
  if (process.env.NODE_ENV === "test") {
@@ -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({ rootDirectory, appDirectory }, forceSfapiVersion) {
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
  });