diff --git a/.changeset/cool-moose-kick.md b/.changeset/cool-moose-kick.md new file mode 100644 index 0000000000..ecbaf8698c --- /dev/null +++ b/.changeset/cool-moose-kick.md @@ -0,0 +1,5 @@ +--- +'@graphcommerce/magento-customer': patch +--- + +Solve issue where persisted Form-data would remain in the sessionStorage after logging out. diff --git a/.changeset/cuddly-tips-argue.md b/.changeset/cuddly-tips-argue.md new file mode 100644 index 0000000000..ecfa2ca546 --- /dev/null +++ b/.changeset/cuddly-tips-argue.md @@ -0,0 +1,12 @@ +--- +'@graphcommerce/next-config': minor +'@graphcommerce/graphql-mesh': minor +--- + +Solves the issue `TypeError: url?.startsWith is not a function`. The generated `.mesh/index.ts` would be generated as a requirejs module while next.js expects an esm module. In the end we properly generated the mesh correctly and now there is an `import.meta.url` instead of using `require('node:url')`. To solve this we needed to solve a chain of issues: + +1. The generation of the mesh is based on the version of the mesh that is imported (esm or commonjs). See [source](https://github.com/ardatan/graphql-mesh/blob/bf588d372c0078378aaa24beea2da794af7949e6/scripts/replace-import-meta-url-in-cjs.ts#L9-L10) for the lines that need to be different. This meant that we needed to change the @graphcommerce/cli package to be of type:module instead of a commonjs module. + +2) To properly convert the module to an esm module we've migrated the build of the cli package to use 'pkgroll' instead of tsc, because tsc is limited in what it outputs and can't really convert classic imports to esm. + +3) To load possible mesh plugins we require additional .ts files to be loaded with [tsx](https://tsx.is/). To get the tsx loader to work properly in combination with esm modules, we need at least [node 18.19.0](https://nodejs.org/en/blog/release/v18.19.0#new-nodemodule-api-register-for-module-customization-hooks-new-initialize-hook). Minimal Node version upped to 18.19.0 and add support for node 22. diff --git a/.changeset/nasty-coins-dream.md b/.changeset/nasty-coins-dream.md new file mode 100644 index 0000000000..45e0c843ea --- /dev/null +++ b/.changeset/nasty-coins-dream.md @@ -0,0 +1,6 @@ +--- +'@graphcommerce/magento-search': patch +'@graphcommerce/ecommerce-ui': patch +--- + +Solve issue: Warning: Cannot update a component (`FormAutoSubmitBase`) while rendering a different component (`ActionCardListForm`). diff --git a/.changeset/odd-mails-yell.md b/.changeset/odd-mails-yell.md new file mode 100644 index 0000000000..ed478f9b00 --- /dev/null +++ b/.changeset/odd-mails-yell.md @@ -0,0 +1,5 @@ +--- +'@graphcommerce/magento-customer': patch +--- + +Remove the inContext directive from the query before sending to the server diff --git a/.changeset/pink-students-greet.md b/.changeset/pink-students-greet.md new file mode 100644 index 0000000000..f3e378f029 --- /dev/null +++ b/.changeset/pink-students-greet.md @@ -0,0 +1,5 @@ +--- +'@graphcommerce/next-ui': patch +--- + +Solve an issue where internal full URL's would cause prefetching errors and would use a hard navigation. diff --git a/.changeset/rotten-pots-cheat.md b/.changeset/rotten-pots-cheat.md new file mode 100644 index 0000000000..66a7e9970b --- /dev/null +++ b/.changeset/rotten-pots-cheat.md @@ -0,0 +1,5 @@ +--- +'@graphcommerce/graphql': patch +--- + +measurePerformanceLink now reports queries made in the subgraph and is only included during development and not in production. diff --git a/docs/framework/config.md b/docs/framework/config.md index 255539f40a..5eb2799cec 100644 --- a/docs/framework/config.md +++ b/docs/framework/config.md @@ -372,6 +372,8 @@ Issues that this can cause are: ### GraphCommercePermissions +Permissions input + #### cart: CUSTOMER_ONLY | DISABLED | ENABLED Changes the availability of the add to cart buttons and the cart page to either customer only or completely disables it. @@ -386,6 +388,8 @@ Enables / disabled the account section of the website. DISABLE_REGISTRATION will #### website: ENABLED +Allows the option to require login or completely disable the site. + ### GraphCommerceStorefrontConfig All storefront configuration for the project diff --git a/examples/magento-graphcms/components/GraphCMS/RowColumnTwo/RowColumnTwoSpread.tsx b/examples/magento-graphcms/components/GraphCMS/RowColumnTwo/RowColumnTwoSpread.tsx index 8293653ee8..66d02672db 100644 --- a/examples/magento-graphcms/components/GraphCMS/RowColumnTwo/RowColumnTwoSpread.tsx +++ b/examples/magento-graphcms/components/GraphCMS/RowColumnTwo/RowColumnTwoSpread.tsx @@ -22,7 +22,7 @@ export function RowColumnTwoSpread(props: RowColumnTwoFragment) { {...props} nodeLength={ getNodeLength(colOne.raw as ElementOrTextNode) >= - getNodeLength(colTwo.raw as ElementOrTextNode) ?? false + getNodeLength(colTwo.raw as ElementOrTextNode) } colOneContent={ =18.19.0 <22.0.0" }, "scripts": { "dev": "concurrently -k -n codegen,next 'graphql-codegen -w' 'next dev'", @@ -20,7 +20,7 @@ "create-patch": "patch-package --exclude 'package.json$|gql.ts$|interceptor.tsx$'" }, "dependencies": { - "@apollo/client": "~3.10.8", + "@apollo/client": "~3.11.8", "@ducanh2912/next-pwa": "9.7.2", "@graphcommerce/cli": "9.0.0-canary.100", "@graphcommerce/demo-magento-graphcommerce": "9.0.0-canary.100", @@ -70,26 +70,27 @@ "@graphcommerce/next-config": "9.0.0-canary.100", "@graphcommerce/next-ui": "9.0.0-canary.100", "@graphcommerce/react-hook-form": "9.0.0-canary.100", - "@lingui/conf": "4.11.2", - "@lingui/core": "4.11.2", - "@lingui/macro": "4.11.2", - "@lingui/react": "4.11.2", - "@mui/lab": "5.0.0-alpha.171", - "@mui/material": "5.16.4", - "@next/env": "14.2.5", + "@lingui/conf": "4.11.4", + "@lingui/core": "4.11.4", + "@lingui/macro": "4.11.4", + "@lingui/react": "4.11.4", + "@mui/lab": "5.0.0-alpha.173", + "@mui/material": "5.16.7", + "@mui/utils": "^5.16.6", + "@next/env": "14.2.14", "@parcel/watcher": "^2.4.1", "@unts/patch-package": "^8.0.0", "concurrently": "8.2.2", "cross-env": "^7.0.3", "dotenv": "16.4.5", - "framer-motion": "10.18.0", + "framer-motion": "11.11.1", "graphql": "^16.9.0", - "next": "14.2.5", + "next": "14.2.14", "next-assetlinks": "^1.0.0", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-hook-form": "^7.52.1", - "sharp": "0.33.4", + "react-hook-form": "^7.53.0", + "sharp": "0.33.5", "ts-node": "^10.9.2", "webpack": "~5.93.0" }, @@ -97,22 +98,25 @@ "@graphcommerce/eslint-config-pwa": "9.0.0-canary.100", "@graphcommerce/prettier-config-pwa": "9.0.0-canary.100", "@graphcommerce/typescript-config-pwa": "9.0.0-canary.100", - "@lingui/cli": "4.11.2", - "@playwright/test": "1.45.1", - "@types/node": "^18.19.40", - "@types/react": "^18.3.3", + "@lingui/cli": "4.11.4", + "@playwright/test": "1.47.2", + "@types/node": "^18.19.54", + "@types/react": "^18.3.11", "@types/react-dom": "^18.3.0", "@types/react-is": "^18.3.0", "babel-plugin-macros": "^3.1.0", "eslint": "^8", "prettier": "3.3.3", - "type-fest": "^4.22.0", - "typescript": "5.5.3" + "type-fest": "^4.26.1", + "typescript": "5.6.2" }, "browserslist": [ "> 1% in alt-EU", "not IE 11" ], + "resolutions": { + "@emotion/react": "11.12.0" + }, "prettier": "@graphcommerce/prettier-config-pwa", "eslintConfig": { "extends": "@graphcommerce/eslint-config-pwa", diff --git a/examples/magento-graphcms/patches/@graphql-tools+delegate+10.0.17.patch b/examples/magento-graphcms/patches/@graphql-tools+delegate+10.0.17.patch deleted file mode 100644 index 17e903e96d..0000000000 --- a/examples/magento-graphcms/patches/@graphql-tools+delegate+10.0.17.patch +++ /dev/null @@ -1,65 +0,0 @@ -diff --git a/node_modules/@graphql-tools/delegate/esm/prepareGatewayDocument.js b/node_modules/@graphql-tools/delegate/esm/prepareGatewayDocument.js -index 4356899..0b39047 100644 ---- a/node_modules/@graphql-tools/delegate/esm/prepareGatewayDocument.js -+++ b/node_modules/@graphql-tools/delegate/esm/prepareGatewayDocument.js -@@ -7,59 +7,7 @@ export function prepareGatewayDocument(originalDocument, transformedSchema, retu - if (infoSchema == null) { - return wrappedConcreteTypesDocument; - } -- const visitedSelections = new WeakSet(); -- wrappedConcreteTypesDocument = visit(wrappedConcreteTypesDocument, { -- [Kind.SELECTION_SET](node) { -- const newSelections = []; -- for (const selectionNode of node.selections) { -- if (selectionNode.kind === Kind.INLINE_FRAGMENT && -- selectionNode.typeCondition != null && -- !visitedSelections.has(selectionNode)) { -- visitedSelections.add(selectionNode); -- const typeName = selectionNode.typeCondition.name.value; -- const type = infoSchema.getType(typeName); -- if (isAbstractType(type)) { -- const possibleTypes = infoSchema.getPossibleTypes(type); -- for (const possibleType of possibleTypes) { -- newSelections.push({ -- ...selectionNode, -- typeCondition: { -- kind: Kind.NAMED_TYPE, -- name: { -- kind: Kind.NAME, -- value: possibleType.name, -- }, -- }, -- }); -- } -- } -- const typeInSubschema = transformedSchema.getType(typeName); -- if (!typeInSubschema) { -- for (const selection of selectionNode.selectionSet.selections) { -- newSelections.push(selection); -- } -- } -- if (typeInSubschema && 'getFields' in typeInSubschema) { -- const fieldMap = typeInSubschema.getFields(); -- for (const selection of selectionNode.selectionSet.selections) { -- if (selection.kind === Kind.FIELD) { -- const fieldName = selection.name.value; -- const field = fieldMap[fieldName]; -- if (!field) { -- newSelections.push(selection); -- } -- } -- } -- } -- } -- newSelections.push(selectionNode); -- } -- return { -- ...node, -- selections: newSelections, -- }; -- }, -- }); -+ - const { possibleTypesMap, reversePossibleTypesMap, interfaceExtensionsMap, fieldNodesByType, fieldNodesByField, dynamicSelectionSetsByField, } = getSchemaMetaData(infoSchema, transformedSchema); - const { operations, fragments, fragmentNames } = getDocumentMetadata(wrappedConcreteTypesDocument); - const { expandedFragments, fragmentReplacements } = getExpandedFragments(fragments, fragmentNames, possibleTypesMap); diff --git a/package.json b/package.json index 7049fae367..4eeb07c23f 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "examples/*" ], "engines": { - "node": "16.x.x||18.x.x||20.x.x" + "node": ">=18.19.0 <23.0.0" }, "scripts": { "eslint:lint": "eslint --ignore-path .gitignore '**/{*.ts,*.tsx}'", @@ -46,8 +46,8 @@ } }, "dependencies": { - "@changesets/cli": "2.27.7", - "@testing-library/jest-dom": "^6.4.6", + "@changesets/cli": "2.27.9", + "@testing-library/jest-dom": "^6.5.0", "@testing-library/react": "^14.3.1", "@unts/patch-package": "^8.0.0", "concurrently": "8.2.2", @@ -56,20 +56,20 @@ }, "devDependencies": { "@graphql-codegen/testing": "3.0.3", - "@playwright/test": "1.45.1", + "@playwright/test": "1.47.2", "@types/event-stream": "^4.0.5", - "@types/jest": "^29.5.12", + "@types/jest": "^29.5.13", "eslint": "^8", "event-stream": "^4.0.1", "jest": "next", "jest-diff": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "prettier": "3.3.3", - "typescript": "5.5.3" + "typescript": "5.6.2" }, "resolutions": { "@changesets/assemble-release-plan": "5.2.4", "@changesets/config": "2.3.1", - "@graphql-tools/delegate": "10.0.13" + "@emotion/react": "11.12.0" } } diff --git a/packages/algolia-categories/package.json b/packages/algolia-categories/package.json index c0c33463f4..9fe824719f 100644 --- a/packages/algolia-categories/package.json +++ b/packages/algolia-categories/package.json @@ -27,7 +27,7 @@ "react": "^18.2.0" }, "devDependencies": { - "graphql": "^16.0.0", - "tsx": "^4.16.2" + "graphql": "^16.9.0", + "tsx": "^4.19.1" } } diff --git a/packages/algolia-insights/package.json b/packages/algolia-insights/package.json index 02dc5e5c49..4fdc7acea8 100644 --- a/packages/algolia-insights/package.json +++ b/packages/algolia-insights/package.json @@ -28,7 +28,7 @@ "react": "^18.2.0" }, "devDependencies": { - "graphql": "^16.0.0", - "tsx": "^4.16.2" + "graphql": "^16.9.0", + "tsx": "^4.19.1" } } diff --git a/packages/algolia-personalization/package.json b/packages/algolia-personalization/package.json index a5d45736dd..a5ec94a235 100644 --- a/packages/algolia-personalization/package.json +++ b/packages/algolia-personalization/package.json @@ -27,7 +27,7 @@ "react": "^18.2.0" }, "devDependencies": { - "graphql": "^16.0.0", - "tsx": "^4.16.2" + "graphql": "^16.9.0", + "tsx": "^4.19.1" } } diff --git a/packages/algolia-products/package.json b/packages/algolia-products/package.json index 6f2f34bfdb..2dba6621b6 100644 --- a/packages/algolia-products/package.json +++ b/packages/algolia-products/package.json @@ -26,7 +26,7 @@ "react": "^18.2.0" }, "devDependencies": { - "graphql": "^16.0.0", - "tsx": "^4.16.2" + "graphql": "^16.9.0", + "tsx": "^4.19.1" } } diff --git a/packages/algolia-recommend/package.json b/packages/algolia-recommend/package.json index c48d725261..09013856db 100644 --- a/packages/algolia-recommend/package.json +++ b/packages/algolia-recommend/package.json @@ -23,7 +23,7 @@ "react": "^18.2.0" }, "devDependencies": { - "graphql": "^16.0.0", - "tsx": "^4.16.2" + "graphql": "^16.9.0", + "tsx": "^4.19.1" } } diff --git a/packages/cli/dist/bin/codegen.js b/packages/cli/dist/bin/codegen.js index 9ebe7d614f..135bc52915 100755 --- a/packages/cli/dist/bin/codegen.js +++ b/packages/cli/dist/bin/codegen.js @@ -1,89 +1,70 @@ #!/usr/bin/env node -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -/* eslint-disable import/no-extraneous-dependencies */ -const promises_1 = __importDefault(require("node:fs/promises")); -const node_path_1 = __importDefault(require("node:path")); -const next_config_1 = require("@graphcommerce/next-config"); -const cli_1 = require("@graphql-codegen/cli"); -const dotenv_1 = __importDefault(require("dotenv")); -const rimraf_1 = require("rimraf"); -const yaml_1 = __importDefault(require("yaml")); +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { resolveDependenciesSync, packageRoots } from '@graphcommerce/next-config'; +import { cliError, loadCodegenConfig, runCli } from '@graphql-codegen/cli'; +import dotenv from 'dotenv'; +import { rimraf } from 'rimraf'; +import yaml from 'yaml'; + const [, , cmd] = process.argv; -dotenv_1.default.config(); +dotenv.config(); const root = process.cwd(); -const configLocation = node_path_1.default.join(root, `._tmp_codegen.yml`); +const configLocation = path.join(root, `._tmp_codegen.yml`); async function cleanup() { - try { - await promises_1.default.stat(configLocation).then((r) => { - if (r.isFile()) - return promises_1.default.unlink(configLocation); - return undefined; - }); - } - catch (e) { - // ignore - } - return undefined; + try { + await fs.stat(configLocation).then((r) => { + if (r.isFile()) return fs.unlink(configLocation); + return void 0; + }); + } catch (e) { + } + return void 0; } function appendDocumentLocations(conf, packages) { - const documents = Array.isArray(conf.documents) ? conf.documents : [conf.documents]; - documents.push(...packages.map((p) => `${p}/**/*.graphql`)); - return conf; + const documents = Array.isArray(conf.documents) ? conf.documents : [conf.documents]; + documents.push(...packages.map((p) => `${p}/**/*.graphql`)); + return conf; } async function main() { - // Make sure we dont already have a --config or -c cli argument as we're going to override it. - if (process.argv.includes('--config') || process.argv.includes('-c')) { - throw Error('--config or -c argument is not supported, modify codegen.yml to make changes'); - } - const deps = (0, next_config_1.resolveDependenciesSync)(); - const packages = [...deps.values()].filter((p) => p !== '.'); - // Load the current codegen.yml - // Todo: implement loading with a custom --config or -c here. - const conf = await (0, cli_1.loadCodegenConfig)({ configFilePath: root }); - // Get a a list of all generates configurations. - const generates = Object.entries(conf.config.generates).map(([generatedPath, value]) => { - const found = [...deps.entries()].find((dep) => generatedPath.startsWith(`node_modules/${dep[0]}`)); - if (!found) - return [generatedPath, value]; - const newPath = generatedPath.replace(`node_modules/${found[0]}`, found[1]); - return [newPath, value]; - }); - let extension; - // Find the file extension used for the generated graphql files and cleanup if not used anymore. - generates.forEach(([, gen]) => { - if (Array.isArray(gen)) - return; - if (gen.presetConfig?.extension) - extension = gen.presetConfig.extension; - }); - const isWatching = process.argv.includes('--watch') || process.argv.includes('-w'); - if (!isWatching && extension) - await (0, rimraf_1.rimraf)(node_path_1.default.join(root, `**/*${extension}`)); - // - Prepend the all targets with ../../ if we're running in a monorepo setup. - // - Append all the Graphcommerce packages to the configuration - conf.config.generates = Object.fromEntries(generates.map(([generateTarget, generateConf]) => [ - generateTarget, - Array.isArray(generateConf) ? generateConf : appendDocumentLocations(generateConf, packages), - ])); - (0, next_config_1.packageRoots)(packages).forEach((r) => { - conf.config.generates[r] = conf.config.generates['.']; - }); - // Reexport the mesh to is can be used by codegen - await promises_1.default.writeFile(configLocation, yaml_1.default.stringify(conf.config)); - // Append the new cli argument - process.argv.push('--config'); - process.argv.push(configLocation); - // Run the cli - const result = await (0, cli_1.runCli)(cmd); - await cleanup(); - process.exit(result); + if (process.argv.includes("--config") || process.argv.includes("-c")) { + throw Error("--config or -c argument is not supported, modify codegen.yml to make changes"); + } + const deps = resolveDependenciesSync(); + const packages = [...deps.values()].filter((p) => p !== "."); + const conf = await loadCodegenConfig({ configFilePath: root }); + const generates = Object.entries(conf.config.generates).map(([generatedPath, value]) => { + const found = [...deps.entries()].find( + (dep) => generatedPath.startsWith(`node_modules/${dep[0]}`) + ); + if (!found) return [generatedPath, value]; + const newPath = generatedPath.replace(`node_modules/${found[0]}`, found[1]); + return [newPath, value]; + }); + let extension; + generates.forEach(([, gen]) => { + if (Array.isArray(gen)) return; + if (gen.presetConfig?.extension) extension = gen.presetConfig.extension; + }); + const isWatching = process.argv.includes("--watch") || process.argv.includes("-w"); + if (!isWatching && extension) await rimraf(path.join(root, `**/*${extension}`)); + conf.config.generates = Object.fromEntries( + generates.map(([generateTarget, generateConf]) => [ + generateTarget, + Array.isArray(generateConf) ? generateConf : appendDocumentLocations(generateConf, packages) + ]) + ); + packageRoots(packages).forEach((r) => { + conf.config.generates[r] = conf.config.generates["."]; + }); + await fs.writeFile(configLocation, yaml.stringify(conf.config)); + process.argv.push("--config"); + process.argv.push(configLocation); + const result = await runCli(cmd); + await cleanup(); + process.exit(result); } main().catch((e) => { - // eslint-disable-next-line @typescript-eslint/no-floating-promises - cleanup(); - (0, cli_1.cliError)(e); + cleanup(); + cliError(e); }); diff --git a/packages/cli/dist/bin/graphcommerce.js b/packages/cli/dist/bin/graphcommerce.js index 622d417be8..0956a598af 100755 --- a/packages/cli/dist/bin/graphcommerce.js +++ b/packages/cli/dist/bin/graphcommerce.js @@ -1,43 +1,19 @@ #!/usr/bin/env node -"use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; const commands = { - 'codegen-config': () => Promise.resolve().then(() => __importStar(require('@graphcommerce/next-config'))).then((m) => m.generateConfig), - 'codegen-interceptors': () => Promise.resolve().then(() => __importStar(require('@graphcommerce/next-config'))).then((m) => m.codegenInterceptors), - 'export-config': () => Promise.resolve().then(() => __importStar(require('@graphcommerce/next-config'))).then((m) => m.exportConfig), - 'hygraph-migrate': () => Promise.resolve().then(() => __importStar(require('@graphcommerce/hygraph-cli'))).then((m) => m.migrateHygraph), + "codegen-config": () => import('@graphcommerce/next-config').then((m) => m.generateConfig), + "codegen-interceptors": () => import('@graphcommerce/next-config').then((m) => m.codegenInterceptors), + "export-config": () => import('@graphcommerce/next-config').then((m) => m.exportConfig), + "hygraph-migrate": () => import('@graphcommerce/hygraph-cli').then((m) => m.migrateHygraph) }; const args = process.argv.slice(2); const command = args[0]; if (!(command in commands)) { - console.error(`Unknown command: ${args.join(' ')}, possible commands: ${Object.keys(commands).join(', ')}`); - process.exit(1); + console.error( + `Unknown command: ${args.join(" ")}, possible commands: ${Object.keys(commands).join(", ")}` + ); + process.exit(1); } -commands[command]() - .then((c) => c()) - .catch((e) => { - console.error(e); - process.exit(1); +commands[command]().then((c) => c()).catch((e) => { + console.error(e); + process.exit(1); }); diff --git a/packages/cli/dist/bin/is-monorepo.js b/packages/cli/dist/bin/is-monorepo.js index 3e38d4594b..fdafcf6d8c 100755 --- a/packages/cli/dist/bin/is-monorepo.js +++ b/packages/cli/dist/bin/is-monorepo.js @@ -1,40 +1,26 @@ #!/usr/bin/env node -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const node_child_process_1 = require("node:child_process"); -const next_config_1 = require("@graphcommerce/next-config"); -const detect_package_manager_1 = require("detect-package-manager"); -/** - * Executes a command dependening if we're running in a monorepo or not Usage: - * - * is-monorepo '[pkgrun] run my-script' '[pkgrun] run my-other-script' - * - * We're using the `[pkgrun]` placeholder to replace it with the package manager we're using. For - * example, if we're using `yarn` it will replace `[pkgrun]` with `yarn`. If we're using `npm` it - * will replace `[pkgrun]` with `npm run`. - */ +import { spawn } from 'node:child_process'; +import { isMonorepo } from '@graphcommerce/next-config'; +import { detect } from 'detect-package-manager'; + async function main() { - const isMono = (0, next_config_1.isMonorepo)(); - const command = isMono ? process.argv.slice(2)[0] : process.argv.slice(2)[1]; - let packageManager = 'yarn'; - try { - packageManager = await (0, detect_package_manager_1.detect)({ cwd: isMono ? `../..` : `.` }); - } - catch { - console.error('Could not detect package manager, defaulting to yarn'); - } - const commandArray = command - .split(' ') - .map((arg) => arg.replace('[pkgrun]', `${packageManager} run`)); - if (isMono) - commandArray.unshift('cd', '../..', '&&'); - const [cmd, ...args] = commandArray; - const childProcess = (0, node_child_process_1.spawn)(cmd, args, { shell: true, stdio: 'inherit' }); - childProcess.on('exit', (code) => { - process.exit(code ?? 0); - }); + const isMono = isMonorepo(); + const command = isMono ? process.argv.slice(2)[0] : process.argv.slice(2)[1]; + let packageManager = "yarn"; + try { + packageManager = await detect({ cwd: isMono ? `../..` : `.` }); + } catch { + console.error("Could not detect package manager, defaulting to yarn"); + } + const commandArray = command.split(" ").map((arg) => arg.replace("[pkgrun]", `${packageManager} run`)); + if (isMono) commandArray.unshift("cd", "../..", "&&"); + const [cmd, ...args] = commandArray; + const childProcess = spawn(cmd, args, { shell: true, stdio: "inherit" }); + childProcess.on("exit", (code) => { + process.exit(code ?? 0); + }); } main().catch((error) => { - console.error(error); - process.exit(1); + console.error(error); + process.exit(1); }); diff --git a/packages/cli/dist/bin/mesh.js b/packages/cli/dist/bin/mesh.js index d5f16b0f44..57fca4fc92 100755 --- a/packages/cli/dist/bin/mesh.js +++ b/packages/cli/dist/bin/mesh.js @@ -1,162 +1,181 @@ #!/usr/bin/env node -"use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; +import { promises } from 'node:fs'; +import path$1 from 'node:path'; +import { exit } from 'node:process'; +import { loadConfig, resolveDependenciesSync, packageRoots, replaceConfigInString } from '@graphcommerce/next-config'; +import { DEFAULT_CLI_PARAMS, graphqlMesh } from '@graphql-mesh/cli'; +import { DefaultLogger, defaultImportFn, loadYaml, fileURLToPath } from '@graphql-mesh/utils'; +import dotenv from 'dotenv'; +import yaml from 'yaml'; +import path from 'path'; +import { cosmiconfig, defaultLoaders } from 'cosmiconfig'; +import 'tsx/cjs'; +import 'tsx/esm'; + +function customLoader(ext, importFn = defaultImportFn, initialLoggerPrefix = "\u{1F578}\uFE0F Mesh") { + const logger = new DefaultLogger(initialLoggerPrefix).child("config"); + function loader(filepath, content) { + if (process.env) { + content = content.replace(/\$\{(.*?)\}/g, (_, variable) => { + let varName = variable; + let defaultValue = ""; + if (variable.includes(":")) { + const spl = variable.split(":"); + varName = spl.shift(); + defaultValue = spl.join(":"); + } + return process.env[varName] || defaultValue; + }); } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.handleFatalError = handleFatalError; -/* eslint-disable import/no-extraneous-dependencies */ -const node_fs_1 = require("node:fs"); -const node_path_1 = __importDefault(require("node:path")); -const node_process_1 = require("node:process"); -const next_config_1 = require("@graphcommerce/next-config"); -const cli_1 = require("@graphql-mesh/cli"); -const utils_1 = require("@graphql-mesh/utils"); -const dotenv_1 = __importDefault(require("dotenv")); -const yaml_1 = __importDefault(require("yaml")); -const findConfig_1 = require("../utils/findConfig"); -// eslint-disable-next-line import/no-unresolved -require("tsx/cjs"); // support importing typescript configs in CommonJS -// eslint-disable-next-line import/no-unresolved -require("tsx/esm"); // support importing typescript configs in ESM -dotenv_1.default.config(); -function handleFatalError(e, logger = new utils_1.DefaultLogger('◈')) { - logger.error(e.stack || e.message); - // eslint-disable-next-line no-console - console.log(e); - if (process.env.JEST == null) - (0, node_process_1.exit)(1); + if (ext === "json") { + return defaultLoaders[".json"](filepath, content); + } + if (ext === "yaml") { + return loadYaml(filepath, content, logger); + } + if (ext === "js") { + return importFn(filepath); + } + } + return loader; +} +async function findConfig(options) { + const { configName = "mesh", dir: configDir = "", initialLoggerPrefix } = options || {}; + const dir = path.isAbsolute(configDir) ? configDir : path.join(process.cwd(), configDir); + const explorer = cosmiconfig(configName, { + searchPlaces: [ + "package.json", + `.${configName}rc`, + `.${configName}rc.json`, + `.${configName}rc.yaml`, + `.${configName}rc.yml`, + `.${configName}rc.js`, + `.${configName}rc.ts`, + `.${configName}rc.cjs`, + `${configName}.config.js`, + `${configName}.config.cjs` + ], + loaders: { + ".json": customLoader("json", options?.importFn, initialLoggerPrefix), + ".yaml": customLoader("yaml", options?.importFn, initialLoggerPrefix), + ".yml": customLoader("yaml", options?.importFn, initialLoggerPrefix), + ".js": customLoader("js", options?.importFn, initialLoggerPrefix), + ".ts": customLoader("js", options?.importFn, initialLoggerPrefix), + noExt: customLoader("yaml", options?.importFn, initialLoggerPrefix) + } + }); + const results = await explorer.search(dir); + if (!results) { + throw new Error(`No ${configName} config file found in "${dir}"!`); + } + const { config } = results; + return config; +} + +dotenv.config(); +function resolvePath(pathStr) { + return fileURLToPath(import.meta.resolve(pathStr)); +} +function handleFatalError(e, logger = new DefaultLogger("\u25C8")) { + logger.error(e.stack || e.message); + console.log(e); + if (process.env.JEST == null) exit(1); } const root = process.cwd(); -const meshDir = node_path_1.default.dirname(require.resolve('@graphcommerce/graphql-mesh')); -const relativePath = node_path_1.default.join(node_path_1.default.relative(meshDir, root), '/'); +const meshDir = path$1.dirname(resolvePath("@graphcommerce/graphql-mesh")); +const relativePath = path$1.join(path$1.relative(meshDir, root), "/"); const cliParams = { - ...cli_1.DEFAULT_CLI_PARAMS, - playgroundTitle: 'GraphCommerce® Mesh', + ...DEFAULT_CLI_PARAMS, + playgroundTitle: "GraphCommerce\xAE Mesh" }; const tmpMesh = `_tmp_mesh`; -const tmpMeshLocation = node_path_1.default.join(root, `.${tmpMesh}rc.yml`); +const tmpMeshLocation = path$1.join(root, `.${tmpMesh}rc.yml`); async function cleanup() { - try { - await node_fs_1.promises.stat(tmpMeshLocation).then((r) => { - if (r.isFile()) - return node_fs_1.promises.unlink(tmpMeshLocation); - return undefined; - }); - } - catch (e) { - // ignore - } - return undefined; + try { + await promises.stat(tmpMeshLocation).then((r) => { + if (r.isFile()) return promises.unlink(tmpMeshLocation); + return void 0; + }); + } catch (e) { + } + return void 0; } const main = async () => { - const baseConf = (await (0, findConfig_1.findConfig)({})); - const graphCommerce = (0, next_config_1.loadConfig)(root); - // eslint-disable-next-line global-require - // @ts-ignore Might not exist - const { meshConfig } = (await Promise.resolve().then(() => __importStar(require('@graphcommerce/graphql-mesh/meshConfig.interceptor')))); - const conf = meshConfig(baseConf, graphCommerce); - // We're configuring a custom fetch function - conf.customFetch = '@graphcommerce/graphql-mesh/customFetch'; - conf.serve = { ...conf.serve, endpoint: '/api/graphql' }; - // Rewrite additionalResolvers so we can use module resolution more easily - conf.additionalResolvers = conf.additionalResolvers ?? []; - conf.additionalResolvers = conf.additionalResolvers?.map((additionalResolver) => { - if (typeof additionalResolver !== 'string') - return additionalResolver; - if (additionalResolver.startsWith('@')) - return node_path_1.default.relative(root, require.resolve(additionalResolver)); - return additionalResolver; - }); - conf.sources = conf.sources.map((source) => { - const definedHandlers = Object.entries(source.handler); - return { - ...source, - handler: Object.fromEntries(definedHandlers.map(([key, value]) => { - if (key === 'openapi' && value) { - const openapi = value; - if (openapi.source.startsWith('@')) { - return [ - key, - { ...openapi, source: node_path_1.default.relative(root, require.resolve(openapi.source)) }, - ]; - } - } - return [key, value]; - })), - }; - }); - // Rewrite additionalTypeDefs so we can use module resolution more easily - if (!conf.additionalTypeDefs) - conf.additionalTypeDefs = []; - conf.additionalTypeDefs = (Array.isArray(conf.additionalTypeDefs) ? conf.additionalTypeDefs : [conf.additionalTypeDefs]).map((additionalTypeDef) => { - if (typeof additionalTypeDef === 'string' && additionalTypeDef.startsWith('@')) - return node_path_1.default.relative(root, require.resolve(additionalTypeDef)); - return additionalTypeDef; - }); - // Scan the current working directory to also read all graphqls files. - conf.additionalTypeDefs.push('graphql/**/*.graphqls'); - conf.additionalTypeDefs.push('components/**/*.graphqls'); - conf.additionalTypeDefs.push('lib/**/*.graphqls'); - conf.additionalTypeDefs.push('app/**/*.graphqls'); - const deps = (0, next_config_1.resolveDependenciesSync)(); - const packages = [...deps.values()].filter((p) => p !== '.'); - const mV = graphCommerce.magentoVersion ?? 246; - (0, next_config_1.packageRoots)(packages).forEach((r) => { - const alsoScan = [245, 246, 247, 248, 249, 250, 251, 252, 253, 254] - .filter((v) => v > mV) - .map((v) => `${r}/*/schema-${v}/**/*.graphqls`); - conf.additionalTypeDefs.push(`${r}/*/schema/**/*.graphqls`); - conf.additionalTypeDefs.push(...alsoScan); - }); - if (!conf.serve) - conf.serve = {}; - if (!conf.serve.playgroundTitle) - conf.serve.playgroundTitle = 'GraphCommerce® Mesh'; - conf.plugins = [ - ...(conf.plugins ?? []), - { - httpDetailsExtensions: { - if: "env.NODE_ENV === 'development'", - }, - }, - ]; - const yamlString = (0, next_config_1.replaceConfigInString)(yaml_1.default.stringify(conf), graphCommerce); - await node_fs_1.promises.writeFile(tmpMeshLocation, yamlString); - // Reexport the mesh to is can be used by packages - await node_fs_1.promises.writeFile(`${meshDir}/.mesh.ts`, `export * from '${relativePath.split(node_path_1.default.sep).join('/')}.mesh'`, { encoding: 'utf8' }); - await (0, cli_1.graphqlMesh)({ ...cliParams, configName: tmpMesh }); - await cleanup(); + const baseConf = await findConfig({}); + const graphCommerce = loadConfig(root); + const meshConfigf = await import('@graphcommerce/graphql-mesh/meshConfig.interceptor'); + const conf = meshConfigf.default.meshConfig(baseConf, graphCommerce); + conf.customFetch = "@graphcommerce/graphql-mesh/customFetch"; + conf.serve = { ...conf.serve, endpoint: "/api/graphql" }; + conf.additionalResolvers = conf.additionalResolvers ?? []; + conf.additionalResolvers = conf.additionalResolvers?.map((additionalResolver) => { + if (typeof additionalResolver !== "string") return additionalResolver; + if (additionalResolver.startsWith("@")) + return path$1.relative(root, resolvePath(additionalResolver)); + return additionalResolver; + }); + conf.sources = conf.sources.map((source) => { + const definedHandlers = Object.entries(source.handler); + return { + ...source, + handler: Object.fromEntries( + definedHandlers.map(([key, value]) => { + if (key === "openapi" && value) { + const openapi = value; + if (openapi.source.startsWith("@")) { + return [key, { ...openapi, source: path$1.relative(root, resolvePath(openapi.source)) }]; + } + } + return [key, value]; + }) + ) + }; + }); + if (!conf.additionalTypeDefs) conf.additionalTypeDefs = []; + conf.additionalTypeDefs = (Array.isArray(conf.additionalTypeDefs) ? conf.additionalTypeDefs : [conf.additionalTypeDefs]).map((additionalTypeDef) => { + if (typeof additionalTypeDef === "string" && additionalTypeDef.startsWith("@")) + return path$1.relative(root, resolvePath(additionalTypeDef)); + return additionalTypeDef; + }); + conf.additionalTypeDefs.push("graphql/**/*.graphqls"); + conf.additionalTypeDefs.push("components/**/*.graphqls"); + conf.additionalTypeDefs.push("lib/**/*.graphqls"); + conf.additionalTypeDefs.push("app/**/*.graphqls"); + const deps = resolveDependenciesSync(); + const packages = [...deps.values()].filter((p) => p !== "."); + const mV = graphCommerce.magentoVersion ?? 246; + packageRoots(packages).forEach((r) => { + const alsoScan = [245, 246, 247, 248, 249, 250, 251, 252, 253, 254].filter((v) => v > mV).map((v) => `${r}/*/schema-${v}/**/*.graphqls`); + conf.additionalTypeDefs.push(`${r}/*/schema/**/*.graphqls`); + conf.additionalTypeDefs.push(...alsoScan); + }); + if (!conf.serve) conf.serve = {}; + if (!conf.serve.playgroundTitle) conf.serve.playgroundTitle = "GraphCommerce\xAE Mesh"; + conf.plugins = [ + ...conf.plugins ?? [], + { + httpDetailsExtensions: { + if: "env.NODE_ENV === 'development'" + } + } + ]; + const yamlString = replaceConfigInString(yaml.stringify(conf), graphCommerce); + await promises.writeFile(tmpMeshLocation, yamlString); + await promises.writeFile( + `${meshDir}/.mesh.ts`, + `export * from '${relativePath.split(path$1.sep).join("/")}.mesh'`, + { encoding: "utf8" } + ); + await graphqlMesh({ ...cliParams, configName: tmpMesh }); + await cleanup(); }; -process.on('SIGINT', cleanup); -process.on('SIGTERM', cleanup); +process.on("SIGINT", cleanup); +process.on("SIGTERM", cleanup); main().catch((e) => { - // eslint-disable-next-line @typescript-eslint/no-floating-promises - cleanup(); - if (e instanceof Error) { - handleFatalError(e, new utils_1.DefaultLogger(cli_1.DEFAULT_CLI_PARAMS.initialLoggerPrefix)); - } + cleanup(); + if (e instanceof Error) { + handleFatalError(e, new DefaultLogger(DEFAULT_CLI_PARAMS.initialLoggerPrefix)); + } }); + +export { handleFatalError }; diff --git a/packages/cli/dist/index.js b/packages/cli/dist/index.js deleted file mode 100644 index c8ad2e549b..0000000000 --- a/packages/cli/dist/index.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/packages/cli/dist/utils/findConfig.js b/packages/cli/dist/utils/findConfig.js deleted file mode 100644 index 60df31cbb5..0000000000 --- a/packages/cli/dist/utils/findConfig.js +++ /dev/null @@ -1,71 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.findConfig = findConfig; -/* eslint-disable import/no-extraneous-dependencies */ -const path_1 = __importDefault(require("path")); -const utils_1 = require("@graphql-mesh/utils"); -const cosmiconfig_1 = require("cosmiconfig"); -function customLoader(ext, importFn = utils_1.defaultImportFn, initialLoggerPrefix = '🕸️ Mesh') { - const logger = new utils_1.DefaultLogger(initialLoggerPrefix).child('config'); - // eslint-disable-next-line consistent-return - function loader(filepath, content) { - if (process.env) { - // eslint-disable-next-line no-param-reassign - content = content.replace(/\$\{(.*?)\}/g, (_, variable) => { - let varName = variable; - let defaultValue = ''; - if (variable.includes(':')) { - const spl = variable.split(':'); - varName = spl.shift(); - defaultValue = spl.join(':'); - } - return process.env[varName] || defaultValue; - }); - } - if (ext === 'json') { - return cosmiconfig_1.defaultLoaders['.json'](filepath, content); - } - if (ext === 'yaml') { - return (0, utils_1.loadYaml)(filepath, content, logger); - } - if (ext === 'js') { - return importFn(filepath); - } - } - return loader; -} -async function findConfig(options) { - const { configName = 'mesh', dir: configDir = '', initialLoggerPrefix } = options || {}; - const dir = path_1.default.isAbsolute(configDir) ? configDir : path_1.default.join(process.cwd(), configDir); - const explorer = (0, cosmiconfig_1.cosmiconfig)(configName, { - searchPlaces: [ - 'package.json', - `.${configName}rc`, - `.${configName}rc.json`, - `.${configName}rc.yaml`, - `.${configName}rc.yml`, - `.${configName}rc.js`, - `.${configName}rc.ts`, - `.${configName}rc.cjs`, - `${configName}.config.js`, - `${configName}.config.cjs`, - ], - loaders: { - '.json': customLoader('json', options?.importFn, initialLoggerPrefix), - '.yaml': customLoader('yaml', options?.importFn, initialLoggerPrefix), - '.yml': customLoader('yaml', options?.importFn, initialLoggerPrefix), - '.js': customLoader('js', options?.importFn, initialLoggerPrefix), - '.ts': customLoader('js', options?.importFn, initialLoggerPrefix), - noExt: customLoader('yaml', options?.importFn, initialLoggerPrefix), - }, - }); - const results = await explorer.search(dir); - if (!results) { - throw new Error(`No ${configName} config file found in "${dir}"!`); - } - const { config } = results; - return config; -} diff --git a/packages/cli/package.json b/packages/cli/package.json index de61fdfd16..cd66525eed 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -4,13 +4,11 @@ "repository": "github:graphcommerce-org/graphcommerce", "version": "9.0.0-canary.100", "scripts": { - "dev": "tsc --preserveWatchOutput --watch", - "build": "tsc", - "prepack": "tsc" + "dev": "pkgroll --watch", + "build": "pkgroll", + "prepack": "pkgroll" }, - "type": "commonjs", - "main": "dist/index.js", - "types": "src/index.ts", + "type": "module", "bin": { "gql-gen": "dist/bin/codegen.js", "gql-mesh": "dist/bin/mesh.js", @@ -22,6 +20,7 @@ "mesh": "dist/bin/mesh.js" }, "dependencies": { + "@graphcommerce/graphql-mesh": "^9.0.0-canary.86", "@graphql-codegen/cli": "5.0.2", "@graphql-mesh/cli": "latest", "@graphql-mesh/cross-helpers": "latest", @@ -32,11 +31,13 @@ "@graphql-tools/utils": "^10.3.2", "cosmiconfig": "^8.3.6", "detect-package-manager": "^3.0.2", - "graphql-codegen-typescript-validation-schema": "^0.15.0", + "dotenv": "16.4.5", + "graphql-codegen-typescript-validation-schema": "^0.16.0", "graphql-tag": "^2.12.6", - "rimraf": "^5.0.9", - "tslib": "^2.6.3", - "tsx": "^4.16.2" + "rimraf": "^5.0.10", + "tslib": "^2.7.0", + "tsx": "^4.19.1", + "yaml": "2.5.1" }, "peerDependencies": { "@graphcommerce/eslint-config-pwa": "^9.0.0-canary.100", @@ -57,5 +58,8 @@ "parserOptions": { "project": "./tsconfig.json" } + }, + "devDependencies": { + "pkgroll": "^2.5.0" } } diff --git a/packages/cli/src/bin/mesh.ts b/packages/cli/src/bin/mesh.ts index 8198e2e714..c82e8242d7 100755 --- a/packages/cli/src/bin/mesh.ts +++ b/packages/cli/src/bin/mesh.ts @@ -1,8 +1,8 @@ -#!/usr/bin/env node /* eslint-disable import/no-extraneous-dependencies */ import { promises as fs } from 'node:fs' import path from 'node:path' import { exit } from 'node:process' +import type { meshConfig as meshConfigBase } from '@graphcommerce/graphql-mesh/meshConfig' import { loadConfig, packageRoots, @@ -11,20 +11,20 @@ import { } from '@graphcommerce/next-config' import { graphqlMesh, DEFAULT_CLI_PARAMS, GraphQLMeshCLIParams } from '@graphql-mesh/cli' import { Logger, YamlConfig } from '@graphql-mesh/types' -import { Handler } from '@graphql-mesh/types/typings/config' -import { DefaultLogger } from '@graphql-mesh/utils' +import { DefaultLogger, fileURLToPath } from '@graphql-mesh/utils' import dotenv from 'dotenv' import type { OmitIndexSignature, Entries } from 'type-fest' import yaml from 'yaml' import { findConfig } from '../utils/findConfig' -import type { meshConfig as meshConfigBase } from '@graphcommerce/graphql-mesh/meshConfig' -// eslint-disable-next-line import/no-unresolved -import 'tsx/cjs' // support importing typescript configs in CommonJS -// eslint-disable-next-line import/no-unresolved -import 'tsx/esm' // support importing typescript configs in ESM +import 'tsx/cjs' +import 'tsx/esm' dotenv.config() +function resolvePath(pathStr: string) { + return fileURLToPath(import.meta.resolve(pathStr)) +} + export function handleFatalError(e: Error, logger: Logger = new DefaultLogger('◈')) { logger.error(e.stack || e.message) // eslint-disable-next-line no-console @@ -33,7 +33,7 @@ export function handleFatalError(e: Error, logger: Logger = new DefaultLogger(' } const root = process.cwd() -const meshDir = path.dirname(require.resolve('@graphcommerce/graphql-mesh')) +const meshDir = path.dirname(resolvePath('@graphcommerce/graphql-mesh')) const relativePath = path.join(path.relative(meshDir, root), '/') const cliParams: GraphQLMeshCLIParams = { @@ -60,12 +60,14 @@ const main = async () => { const baseConf = (await findConfig({})) as YamlConfig.Config const graphCommerce = loadConfig(root) - // eslint-disable-next-line global-require - // @ts-ignore Might not exist - const { meshConfig } = (await import('@graphcommerce/graphql-mesh/meshConfig.interceptor')) as { - meshConfig: typeof meshConfigBase + const meshConfigf = (await import( + '@graphcommerce/graphql-mesh/meshConfig.interceptor' + )) as unknown as { + default: { + meshConfig: typeof meshConfigBase + } } - const conf = meshConfig(baseConf, graphCommerce) + const conf = meshConfigf.default.meshConfig(baseConf, graphCommerce) // We're configuring a custom fetch function conf.customFetch = '@graphcommerce/graphql-mesh/customFetch' @@ -76,12 +78,12 @@ const main = async () => { conf.additionalResolvers = conf.additionalResolvers?.map((additionalResolver) => { if (typeof additionalResolver !== 'string') return additionalResolver if (additionalResolver.startsWith('@')) - return path.relative(root, require.resolve(additionalResolver)) + return path.relative(root, resolvePath(additionalResolver)) return additionalResolver }) - type DefinedHandler = OmitIndexSignature + type DefinedHandler = OmitIndexSignature conf.sources = conf.sources.map((source) => { const definedHandlers = Object.entries(source.handler) as Entries @@ -92,10 +94,7 @@ const main = async () => { if (key === 'openapi' && value) { const openapi = value as NonNullable if (openapi.source.startsWith('@')) { - return [ - key, - { ...openapi, source: path.relative(root, require.resolve(openapi.source)) }, - ] + return [key, { ...openapi, source: path.relative(root, resolvePath(openapi.source)) }] } } @@ -111,7 +110,7 @@ const main = async () => { Array.isArray(conf.additionalTypeDefs) ? conf.additionalTypeDefs : [conf.additionalTypeDefs] ).map((additionalTypeDef) => { if (typeof additionalTypeDef === 'string' && additionalTypeDef.startsWith('@')) - return path.relative(root, require.resolve(additionalTypeDef)) + return path.relative(root, resolvePath(additionalTypeDef)) return additionalTypeDef }) diff --git a/packages/cli/tsconfig.json b/packages/cli/tsconfig.json index c2d49ff017..42bd1d5a3d 100644 --- a/packages/cli/tsconfig.json +++ b/packages/cli/tsconfig.json @@ -15,6 +15,8 @@ "outDir": "dist", "sourceMap": false, "noLib": false, - "strict": true + "strict": true, + "moduleResolution": "Bundler", + "module": "ESNext" } } diff --git a/packages/ecommerce-ui/Config.graphqls b/packages/ecommerce-ui/Config.graphqls index 40fe817075..e0ae17d17d 100644 --- a/packages/ecommerce-ui/Config.graphqls +++ b/packages/ecommerce-ui/Config.graphqls @@ -4,7 +4,13 @@ enum WebsitePermissions { # DISABLED will be implemented later } +""" +Permissions input +""" input GraphCommercePermissions { + """ + Allows the option to require login or completely disable the site. + """ website: WebsitePermissions } diff --git a/packages/ecommerce-ui/components/FormComponents/ActionCardListForm.tsx b/packages/ecommerce-ui/components/FormComponents/ActionCardListForm.tsx index b8a6a74230..784205a741 100644 --- a/packages/ecommerce-ui/components/FormComponents/ActionCardListForm.tsx +++ b/packages/ecommerce-ui/components/FormComponents/ActionCardListForm.tsx @@ -1,6 +1,6 @@ import { ActionCardList, ActionCardListProps, ActionCardProps } from '@graphcommerce/next-ui' import { ControllerProps, FieldValues, useController } from '@graphcommerce/react-hook-form' -import React, { MouseEventHandler } from 'react' +import React, { MouseEventHandler, useCallback } from 'react' export type ActionCardItemBase = Pick @@ -40,11 +40,14 @@ export function ActionCardListForm< } = props const RenderItem = render as React.FC> - function onSelect(itemValue: unknown, selectValues: unknown) { - return multiple - ? Array.isArray(selectValues) && selectValues.some((selectValue) => selectValue === itemValue) - : selectValues === itemValue - } + const onSelect = useCallback( + (itemValue: unknown, selectValues: unknown) => + multiple + ? Array.isArray(selectValues) && + selectValues.some((selectValue) => selectValue === itemValue) + : selectValues === itemValue, + [multiple], + ) const { field: { onChange, value, ref }, @@ -60,6 +63,14 @@ export function ActionCardListForm< shouldUnregister, }) + const handleReset = useCallback( + (e: React.MouseEvent) => { + e.preventDefault() + if (!requireOptionSelection) onChange(null) + }, + [onChange, requireOptionSelection], + ) + return ( onChange(incomming)} + onChange={(_, incoming) => onChange(incoming)} error={formState.isSubmitted && !!fieldState.error} errorMessage={fieldState.error?.message} > @@ -77,10 +88,7 @@ export function ActionCardListForm< key={`${item.value}`} value={item.value} selected={onSelect(item.value, value)} - onReset={(e) => { - e.preventDefault() - if (!requireOptionSelection) onChange(null) - }} + onReset={handleReset} /> ))} diff --git a/packages/ecommerce-ui/components/PreviewMode/PreviewMode.tsx b/packages/ecommerce-ui/components/PreviewMode/PreviewMode.tsx index 46be1b1312..21dc8f436d 100644 --- a/packages/ecommerce-ui/components/PreviewMode/PreviewMode.tsx +++ b/packages/ecommerce-ui/components/PreviewMode/PreviewMode.tsx @@ -1,6 +1,5 @@ import { PreviewData } from '@graphcommerce/graphql' import { - Button, IconSvg, MessageSnackbar, iconChevronRight, @@ -16,7 +15,6 @@ import { TextFieldElement } from '../FormComponents' import { LightTooltip } from './LightTooltip' import { PreviewModeActions } from './PreviewModeActions' import { PreviewModeToolbar } from './PreviewModeToolbar' -import { previewModeDefaults } from './previewModeDefaults' export function getPreviewUrl() { const url = new URL(window.location.href) @@ -26,9 +24,7 @@ export function getPreviewUrl() { } function PreviewModeEnabled() { - const form = useForm<{ secret: string; previewData: PreviewData }>({ - defaultValues: { previewData: previewModeDefaults() }, - }) + const form = useForm<{ secret: string; previewData: PreviewData }>({}) const submit = form.handleSubmit((formValues) => { const url = getPreviewUrl() @@ -102,7 +98,14 @@ function PreviewModeEnabled() { } function PreviewModeDisabled() { - const form = useForm<{ secret: string }>({}) + const form = useForm<{ secret: string }>({ + defaultValues: { + secret: + process.env.NODE_ENV === 'development' + ? (import.meta.graphCommerce.previewSecret ?? '') + : '', + }, + }) const submit = form.handleSubmit((formValues) => { const url = getPreviewUrl() diff --git a/packages/framer-next-pages/example/package.json b/packages/framer-next-pages/example/package.json index 849a1e2ba9..83a1af2b69 100644 --- a/packages/framer-next-pages/example/package.json +++ b/packages/framer-next-pages/example/package.json @@ -17,40 +17,40 @@ } }, "dependencies": { - "@lingui/core": "4.11.2", - "@lingui/macro": "4.11.2", - "@lingui/react": "4.11.2", - "@mui/lab": "5.0.0-alpha.171", - "@mui/material": "5.16.4", - "@next/env": "14.2.5", + "@lingui/core": "4.11.4", + "@lingui/macro": "4.11.4", + "@lingui/react": "4.11.4", + "@mui/lab": "5.0.0-alpha.173", + "@mui/material": "5.16.7", + "@next/env": "14.2.14", "@parcel/watcher": "^2.4.1", "@unts/patch-package": "^8.0.0", "concurrently": "8.2.2", "cross-env": "^7.0.3", "dotenv": "16.4.5", - "framer-motion": "10.18.0", + "framer-motion": "11.11.1", "graphql": "^16.9.0", - "next": "14.2.5", + "next": "14.2.14", "next-sitemap": "4.2.3", "react": "^18.3.1", "react-dom": "^18.3.1", - "sharp": "0.33.4", + "sharp": "0.33.5", "webpack": "~5.93.0" }, "devDependencies": { "@graphcommerce/eslint-config-pwa": "9.0.0-canary.100", "@graphcommerce/prettier-config-pwa": "9.0.0-canary.100", "@graphcommerce/typescript-config-pwa": "9.0.0-canary.100", - "@lingui/cli": "4.11.2", - "@playwright/test": "1.45.1", - "@types/node": "^18.19.40", - "@types/react": "^18.3.3", + "@lingui/cli": "4.11.4", + "@playwright/test": "1.47.2", + "@types/node": "^18.19.54", + "@types/react": "^18.3.11", "@types/react-dom": "^18.3.0", "@types/react-is": "^18.3.0", "babel-plugin-macros": "^3.1.0", "eslint": "^8", "prettier": "3.3.3", - "type-fest": "^4.22.0", - "typescript": "5.5.3" + "type-fest": "^4.26.1", + "typescript": "5.6.2" } } diff --git a/packages/framer-scroller/components/MotionImageAspect.tsx b/packages/framer-scroller/components/MotionImageAspect.tsx index d6b160d3b4..4cb1d7af78 100644 --- a/packages/framer-scroller/components/MotionImageAspect.tsx +++ b/packages/framer-scroller/components/MotionImageAspect.tsx @@ -12,7 +12,7 @@ export type MotionImageAspectProps = Omit * Note: We have a fallback for Safari 14 which doesn't yet support aspect-ratio, this causes a * problem when the layout is animated. Should be fixed in Safari 15 */ -export const MotionImageAspect = m( +export const MotionImageAspect = m.create( forwardRef((props, ref) => ( ((props, ref) => { const { direction, diff --git a/packages/framer-scroller/components/ScrollerDots.tsx b/packages/framer-scroller/components/ScrollerDots.tsx index 8ad99a92f4..44195a0481 100644 --- a/packages/framer-scroller/components/ScrollerDots.tsx +++ b/packages/framer-scroller/components/ScrollerDots.tsx @@ -15,7 +15,7 @@ export type DotsProps = { const componentName = 'ScrollerDots' const { classes } = extendableComponent(componentName, ['root', 'dot', 'circle'] as const) -export const ScrollerDots = m( +export const ScrollerDots = m.create( React.forwardRef((props, ref) => { const { fabProps, sx = [], ...containerProps } = props diff --git a/packages/framer-scroller/example/package.json b/packages/framer-scroller/example/package.json index f44a68d2f3..ac30a3e247 100644 --- a/packages/framer-scroller/example/package.json +++ b/packages/framer-scroller/example/package.json @@ -10,40 +10,40 @@ "start": "next start" }, "dependencies": { - "@lingui/core": "4.11.2", - "@lingui/macro": "4.11.2", - "@lingui/react": "4.11.2", - "@mui/lab": "5.0.0-alpha.171", - "@mui/material": "5.16.4", - "@next/env": "14.2.5", + "@lingui/core": "4.11.4", + "@lingui/macro": "4.11.4", + "@lingui/react": "4.11.4", + "@mui/lab": "5.0.0-alpha.173", + "@mui/material": "5.16.7", + "@next/env": "14.2.14", "@parcel/watcher": "^2.4.1", "@unts/patch-package": "^8.0.0", "concurrently": "8.2.2", "cross-env": "^7.0.3", "dotenv": "16.4.5", - "framer-motion": "10.18.0", + "framer-motion": "11.11.1", "graphql": "^16.9.0", - "next": "14.2.5", + "next": "14.2.14", "next-sitemap": "4.2.3", "react": "^18.3.1", "react-dom": "^18.3.1", - "sharp": "0.33.4", + "sharp": "0.33.5", "webpack": "~5.93.0" }, "devDependencies": { "@graphcommerce/eslint-config-pwa": "9.0.0-canary.100", "@graphcommerce/prettier-config-pwa": "9.0.0-canary.100", "@graphcommerce/typescript-config-pwa": "9.0.0-canary.100", - "@lingui/cli": "4.11.2", - "@playwright/test": "1.45.1", - "@types/node": "^18.19.40", - "@types/react": "^18.3.3", + "@lingui/cli": "4.11.4", + "@playwright/test": "1.47.2", + "@types/node": "^18.19.54", + "@types/react": "^18.3.11", "@types/react-dom": "^18.3.0", "@types/react-is": "^18.3.0", "babel-plugin-macros": "^3.1.0", "eslint": "^8", "prettier": "3.3.3", - "type-fest": "^4.22.0", - "typescript": "5.5.3" + "type-fest": "^4.26.1", + "typescript": "5.6.2" } } diff --git a/packages/google-datalayer/package.json b/packages/google-datalayer/package.json index b8268e5c9d..8c8252a090 100644 --- a/packages/google-datalayer/package.json +++ b/packages/google-datalayer/package.json @@ -43,6 +43,6 @@ } }, "dependencies": { - "web-vitals": "^3.5.2" + "web-vitals": "^4.2.3" } } diff --git a/packages/google-datalayer/plugins/GoogleDatalayerWebVitals.tsx b/packages/google-datalayer/plugins/GoogleDatalayerWebVitals.tsx index a35a9e07e5..e9ed8e1c29 100644 --- a/packages/google-datalayer/plugins/GoogleDatalayerWebVitals.tsx +++ b/packages/google-datalayer/plugins/GoogleDatalayerWebVitals.tsx @@ -2,7 +2,7 @@ import type { PagesProps } from '@graphcommerce/framer-next-pages' import type { PluginConfig, PluginProps } from '@graphcommerce/next-config' import { useEventCallback } from '@mui/material' import { useEffect } from 'react' -import { onCLS, onFCP, onFID, onINP, onLCP, onTTFB, Metric } from 'web-vitals/attribution' +import { onCLS, onFCP, onINP, onLCP, onTTFB, Metric } from 'web-vitals/attribution' import { useSendEvent } from '../api/sendEvent' export const config: PluginConfig = { @@ -32,8 +32,7 @@ export function FramerNextPages(props: PluginProps) { const opts = { reportAllChanges: true } onCLS((m) => sendCoreWebVitals(m, m.attribution.largestShiftTarget)) onFCP((m) => sendCoreWebVitals(m), opts) - onFID((m) => sendCoreWebVitals(m, m.attribution.eventTarget), opts) - onINP((m) => sendCoreWebVitals(m, m.attribution.eventTarget), opts) + onINP((m) => sendCoreWebVitals(m, m.attribution.interactionTarget), opts) onLCP((m) => sendCoreWebVitals(m, m.attribution.element), opts) onTTFB((m) => sendCoreWebVitals(m), opts) }, [sendCoreWebVitals]) diff --git a/packages/graphql-mesh/meshConfig.ts b/packages/graphql-mesh/meshConfig.ts index 0b7c7c5307..251a4788b2 100644 --- a/packages/graphql-mesh/meshConfig.ts +++ b/packages/graphql-mesh/meshConfig.ts @@ -1,8 +1,11 @@ import type { GraphCommerceConfig } from '@graphcommerce/next-config' -import type { Config } from '@graphql-mesh/types/typings/config' +import type { YamlConfig } from '@graphql-mesh/types' export type MeshConfigFunction = typeof meshConfig -export function meshConfig(config: Config, graphCommerceConfig: GraphCommerceConfig): Config { +export function meshConfig( + config: YamlConfig.Config, + graphCommerceConfig: GraphCommerceConfig, +): YamlConfig.Config { return config } diff --git a/packages/graphql-mesh/package.json b/packages/graphql-mesh/package.json index 0663bf0a01..e766eadcb9 100644 --- a/packages/graphql-mesh/package.json +++ b/packages/graphql-mesh/package.json @@ -27,10 +27,10 @@ "@graphql-mesh/types": "latest", "@graphql-mesh/utils": "latest", "@graphql-tools/utils": "^10.3.2", - "@whatwg-node/fetch": "^0.9.18", + "@whatwg-node/fetch": "^0.9.21", "fetch-retry": "^5.0.6", "long": "^5.2.3", - "tslib": "^2.6.3", + "tslib": "^2.7.0", "uglify-es": "3.3.10" }, "peerDependencies": { @@ -42,7 +42,7 @@ }, "devDependencies": { "@types/uglify-es": "^3.0.3", - "typescript": "5.5.3" + "typescript": "5.6.2" }, "sideEffects": false, "prettier": "@graphcommerce/prettier-config-pwa", diff --git a/packages/graphql/apollo.ts b/packages/graphql/apollo.ts index 94c709096b..2769ad84e7 100644 --- a/packages/graphql/apollo.ts +++ b/packages/graphql/apollo.ts @@ -4,5 +4,6 @@ export * from '@apollo/client' export * from '@apollo/client/link/schema' export * from '@apollo/client/link/context' export * from '@apollo/client/link/error' +export * from '@apollo/client/utilities' export { getOperationName } from '@apollo/client/utilities' diff --git a/packages/graphql/components/GraphQLProvider/measurePerformanceLink.ts b/packages/graphql/components/GraphQLProvider/measurePerformanceLink.ts index ceaae13c6d..63eccee0c8 100644 --- a/packages/graphql/components/GraphQLProvider/measurePerformanceLink.ts +++ b/packages/graphql/components/GraphQLProvider/measurePerformanceLink.ts @@ -1,7 +1,8 @@ /* eslint-disable no-console */ import { ApolloLink } from '@apollo/client' -import type { MeshFetchHTTPInformation } from '@graphql-mesh/plugin-http-details-extensions' import { print } from '@apollo/client/utilities' +import type { MeshFetchHTTPInformation } from '@graphql-mesh/plugin-http-details-extensions' +import { responsePathAsArray, stripIgnoredCharacters } from 'graphql' import { cliHyperlink } from '../../lib/hyperlinker' const running = new Map< @@ -12,6 +13,7 @@ const running = new Map< internalStart?: Date operationName: [string, string] additional?: [string, string] + idx?: number } >() @@ -87,7 +89,7 @@ export const flushMeasurePerf = () => { }) const items = [ - ['Operation', 'Mesh', ' Source', 'Timeline'], + ['Operation', 'Mesh', '', 'Timeline'], ...lines, renderLine({ serverStart: 0, @@ -109,22 +111,20 @@ export const flushMeasurePerf = () => { // padd the items to the max length items.forEach((item) => { item.forEach((_, index) => { - const [str] = (Array.isArray(item[index]) ? item[index] : [item[index], item[index]]) as [ - string, - string, - ] + const [str] = Array.isArray(item[index]) ? item[index] : [item[index], item[index]] - const val = (Array.isArray(item[index]) ? item[index][1] : item[index]) as string + const val = Array.isArray(item[index]) ? item[index][1] : (item[index] as string) const padLength = colWidths[index] + (val.length - str.length) item[index] = `${val.padEnd(padLength, ' ')}${index !== item.length - 1 ? `` : ''}` }) }) - - // render the items to a string - const output = [[''], ...items].map((item) => item.join(' ')).join('\n') - console.log(output) + ;[[''], ...items] + .map((item) => item.join(' ')) + .forEach((item) => { + console.log(item) + }) running.clear() } @@ -157,43 +157,72 @@ export const measurePerformanceLink = new ApolloLink((operation, forward) => { const httpDetails: MeshFetchHTTPInformation[] | undefined = data.extensions?.httpDetails let additional = [``, ``] as [string, string] - if (httpDetails) { - httpDetails.forEach((d) => { - const requestUrl = new URL(d.request.url) - requestUrl.searchParams.delete('extensions') - const title = `${d.sourceName} ${d.responseTime}ms` - additional = [ - `${additional[0]} ${title}`, - `${additional[1]} ${cliHyperlink(title, requestUrl.toString().replace(/\+/g, '%20'))}`, - ] - }) - } // Called after server responds const query = [ `# Variables: ${JSON.stringify(operation.variables)}`, `# Headers: ${JSON.stringify(operation.getContext().headers)}`, - print(operation.query), + stripIgnoredCharacters(print(operation.query)), ].join('\n') - const meshUrl = new URL(`${import.meta.graphCommerce.canonicalBaseUrl}/api/graphql`) + const meshUrl = new URL( + process.env.NODE_ENV === 'production' + ? `${import.meta.graphCommerce.canonicalBaseUrl}/api/graphql` + : 'http://localhost:3000/api/graphql', + ) + meshUrl.searchParams.set('query', query) + running.delete(operationString) running.set(operationString, { start: operation.getContext().measurePerformanceLinkStart as Date, end: new Date(), - operationName: [operation.operationName, operation.operationName], + operationName: [ + operation.operationName, + operation.operationName, + // cliHyperlink(operation.operationName, meshUrl.toString()), + ], additional, - // [ - // operation.operationName, - // cliHyperlink(operation.operationName, meshUrl.toString()), - // ], - // additional: [ - // `🔗 ${additional[0]}`, - // `${cliHyperlink('🔗', meshUrl.toString())} ${additional[1]}`, - // ], + idx: 0, }) + if (httpDetails) { + running.forEach((_, key) => { + if (key.startsWith(operationString)) running.delete(key) + }) + + httpDetails.forEach((d) => { + const requestUrl = new URL(d.request.url) + requestUrl.searchParams.delete('extensions') + + const sourceName = + !d.sourceName && URL.canParse(d.request.url) + ? new URL(d.request.url).hostname + : d.sourceName + + const key = `${operationString}.${responsePathAsArray(d.path).join('.')}` + const name = `${operation.operationName}.${responsePathAsArray(d.path).join('.')} (${sourceName})` + + let start = new Date(d.request.timestamp) + let end = new Date(d.response.timestamp) + let operationName: [string, string] = [name, name] + let idx = 0 + + if (running.has(key)) { + // Get the earliest start time and latest end time. + const existing = running.get(key) + if (existing) { + idx = (existing.idx ?? 0) + 1 + start = existing.start < start ? existing.start : start + end = existing?.end ? (existing.end > end ? existing.end : end) : end + operationName = [`${name} ⨉ ${idx}`, `${name} ⨉ ${idx}`] + } + } + + running.set(key, { start, end, operationName, idx }) + }) + } + markTimeout() return data diff --git a/packages/hygraph-cli/package.json b/packages/hygraph-cli/package.json index 9dc513d720..200bff8f23 100644 --- a/packages/hygraph-cli/package.json +++ b/packages/hygraph-cli/package.json @@ -12,8 +12,8 @@ "main": "dist/index.js", "types": "src/index.ts", "dependencies": { - "@hygraph/management-sdk": "1.2.4", - "@whatwg-node/fetch": "^0.9.18", + "@hygraph/management-sdk": "1.2.5", + "@whatwg-node/fetch": "^0.9.21", "graphql-tag": "^2.12.6", "prompts": "^2.4.2" }, @@ -28,7 +28,7 @@ }, "devDependencies": { "@types/prompts": "^2.4.9", - "typescript": "5.5.3" + "typescript": "5.6.2" }, "sideEffects": false, "prettier": "@graphcommerce/prettier-config-pwa", diff --git a/packages/hygraph-dynamic-rows-ui/package.json b/packages/hygraph-dynamic-rows-ui/package.json index f7e56942ef..50e8b179cd 100644 --- a/packages/hygraph-dynamic-rows-ui/package.json +++ b/packages/hygraph-dynamic-rows-ui/package.json @@ -16,17 +16,17 @@ "dev": "next dev" }, "dependencies": { - "@apollo/client": "~3.10.8", + "@apollo/client": "~3.11.8", "@graphcommerce/next-config": "9.0.0-canary.100", - "@hygraph/app-sdk-react": "^0.0.4", - "@lingui/core": "^4.11.2", - "@lingui/macro": "^4.11.2", - "@lingui/react": "^4.11.2", - "@mui/material": "5.16.4", + "@hygraph/app-sdk-react": "^0.0.5", + "@lingui/core": "4.11.4", + "@lingui/macro": "4.11.4", + "@lingui/react": "4.11.4", + "@mui/material": "5.16.7", "cross-env": "^7.0.3", "dotenv": "16.4.5", "graphql": "^16.9.0", - "next": "14.2.5", + "next": "14.2.14", "react": "^18.3.1", "react-dom": "^18.3.1", "webpack": "~5.93.0" @@ -39,6 +39,6 @@ "babel-plugin-macros": "^3.1.0", "eslint": "^8", "prettier": "3.3.3", - "typescript": "5.5.3" + "typescript": "5.6.2" } } diff --git a/packages/hygraph-ui/plugins/HygraphPreviewModeToolbar.tsx b/packages/hygraph-ui/plugins/HygraphPreviewModeToolbar.tsx index 233ef5c021..9f439c9edd 100644 --- a/packages/hygraph-ui/plugins/HygraphPreviewModeToolbar.tsx +++ b/packages/hygraph-ui/plugins/HygraphPreviewModeToolbar.tsx @@ -3,6 +3,7 @@ import { type PreviewModeToolbarProps, SelectElement, previewModeDefaults, + useWatch, } from '@graphcommerce/ecommerce-ui' import { TypedDocumentNode, gql, useQuery } from '@graphcommerce/graphql' import type { PluginConfig, PluginProps } from '@graphcommerce/next-config' @@ -40,16 +41,18 @@ const HygraphConfig = React.memo(() => { const contentStages = useQuery(ContentStages) - const defaultValue = previewModeDefaults().hygraphStage ?? 'PUBLISHED' + const defaultValue = + useWatch({ control, name: 'previewData.hygraphStage' }) ?? + previewModeDefaults().hygraphStage ?? + 'PUBLISHED' return useMemo( () => ( { } /> ), - [contentStages.data?.__type.enumValues, contentStages.loading, control], + [contentStages.data?.__type.enumValues, contentStages.loading, control, defaultValue], ) }) diff --git a/packages/image/example/package.json b/packages/image/example/package.json index cd2caf6d3b..c1fc946162 100644 --- a/packages/image/example/package.json +++ b/packages/image/example/package.json @@ -10,40 +10,40 @@ "start": "next start" }, "dependencies": { - "@lingui/core": "4.11.2", - "@lingui/macro": "4.11.2", - "@lingui/react": "4.11.2", - "@mui/lab": "5.0.0-alpha.171", - "@mui/material": "5.16.4", - "@next/env": "14.2.5", + "@lingui/core": "4.11.4", + "@lingui/macro": "4.11.4", + "@lingui/react": "4.11.4", + "@mui/lab": "5.0.0-alpha.173", + "@mui/material": "5.16.7", + "@next/env": "14.2.14", "@parcel/watcher": "^2.4.1", "@unts/patch-package": "^8.0.0", "concurrently": "8.2.2", "cross-env": "^7.0.3", "dotenv": "16.4.5", - "framer-motion": "10.18.0", + "framer-motion": "11.11.1", "graphql": "^16.9.0", - "next": "14.2.5", + "next": "14.2.14", "next-sitemap": "4.2.3", "react": "^18.3.1", "react-dom": "^18.3.1", - "sharp": "0.33.4", + "sharp": "0.33.5", "webpack": "~5.93.0" }, "devDependencies": { "@graphcommerce/eslint-config-pwa": "9.0.0-canary.100", "@graphcommerce/prettier-config-pwa": "9.0.0-canary.100", "@graphcommerce/typescript-config-pwa": "9.0.0-canary.100", - "@lingui/cli": "4.11.2", - "@playwright/test": "1.45.1", - "@types/node": "^18.19.40", - "@types/react": "^18.3.3", + "@lingui/cli": "4.11.4", + "@playwright/test": "1.47.2", + "@types/node": "^18.19.54", + "@types/react": "^18.3.11", "@types/react-dom": "^18.3.0", "@types/react-is": "^18.3.0", "babel-plugin-macros": "^3.1.0", "eslint": "^8", "prettier": "3.3.3", - "type-fest": "^4.22.0", - "typescript": "5.5.3" + "type-fest": "^4.26.1", + "typescript": "5.6.2" } } diff --git a/packages/magento-cart-items/package.json b/packages/magento-cart-items/package.json index 5248dd82f4..4c98c8dd89 100644 --- a/packages/magento-cart-items/package.json +++ b/packages/magento-cart-items/package.json @@ -34,6 +34,6 @@ "react-dom": "^18.2.0" }, "devDependencies": { - "type-fest": "^4.22.0" + "type-fest": "^4.26.1" } } diff --git a/packages/magento-cart/components/CartFab/CartFab.tsx b/packages/magento-cart/components/CartFab/CartFab.tsx index 3f8b862ae8..ee6be4c2e1 100644 --- a/packages/magento-cart/components/CartFab/CartFab.tsx +++ b/packages/magento-cart/components/CartFab/CartFab.tsx @@ -25,7 +25,7 @@ type CartFabContentProps = CartFabProps & CartTotalQuantityFragment const MotionDiv = styled(m.div)({}) -const MotionFab = m( +const MotionFab = m.create( // eslint-disable-next-line @typescript-eslint/no-explicit-any React.forwardRef>((props, ref) => ( diff --git a/packages/magento-cart/link/cartLink.ts b/packages/magento-cart/link/cartLink.ts index f5bde5a417..743f46e727 100644 --- a/packages/magento-cart/link/cartLink.ts +++ b/packages/magento-cart/link/cartLink.ts @@ -4,7 +4,7 @@ import { CustomerTokenDocument, getCustomerAccountCanSignIn } from '@graphcommer import { PushRouter, pushWithPromise } from '@graphcommerce/magento-customer/link/customerLink' import { ErrorCategory } from '@graphcommerce/magento-graphql' import { t } from '@lingui/macro' -import { GraphQLError } from 'graphql' +import { GraphQLError, GraphQLFormattedError } from 'graphql' import { writeCartId } from '../hooks' import { CreateEmptyCartDocument } from '../hooks/CreateEmptyCart.gql' import { getCartEnabledForUser } from '../utils' @@ -28,10 +28,10 @@ const cartErrorLink = onError(({ graphQLErrors, operation, forward }) => { if (!isCartOperation(operation) || !graphQLErrors) return undefined - const isErrorCategory = (err: GraphQLError, category: ErrorCategory) => + const isErrorCategory = (err: GraphQLFormattedError, category: ErrorCategory) => err.extensions?.category === category - const isNoSuchEntityError = (err: GraphQLError) => + const isNoSuchEntityError = (err: GraphQLFormattedError) => isErrorCategory(err, 'graphql-no-such-entity') && errorIsIncluded(err.path, [ 'cart', diff --git a/packages/magento-compare/components/CompareFab.tsx b/packages/magento-compare/components/CompareFab.tsx index a7de9ddee1..2808ec71c3 100644 --- a/packages/magento-compare/components/CompareFab.tsx +++ b/packages/magento-compare/components/CompareFab.tsx @@ -21,7 +21,7 @@ type CompareFabContentProps = CompareFabProps & { total_quantity: number } const MotionDiv = styled(m.div)({}) -const MotionFab = m( +const MotionFab = m.create( // eslint-disable-next-line @typescript-eslint/no-explicit-any React.forwardRef>((props, ref) => (