diff --git a/apps/csk-marketing-site/package.json b/apps/csk-marketing-site/package.json index 79812f890..b6b68595f 100644 --- a/apps/csk-marketing-site/package.json +++ b/apps/csk-marketing-site/package.json @@ -1,6 +1,6 @@ { "name": "@uniformdev/csk-marketing-site", - "version": "6.1.72", + "version": "6.1.73", "private": true, "engines": { "yarn": "please-use-npm", diff --git a/apps/csk-storybook/package.json b/apps/csk-storybook/package.json index 10f7e4b63..f0de205d5 100644 --- a/apps/csk-storybook/package.json +++ b/apps/csk-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@uniformdev/csk-storybook", - "version": "6.1.72", + "version": "6.1.73", "description": "CSK vNext Storybook is an interactive Storybook build showcasing components from the CSK vNext component starter kit. It provides detailed documentation, live previews, and testing capabilities for easy integration into your projects.", "main": "index.js", "scripts": { diff --git a/apps/csk/README.md b/apps/csk/README.md index ae4615f44..03f3c9f9d 100644 --- a/apps/csk/README.md +++ b/apps/csk/README.md @@ -82,6 +82,17 @@ Alternatively you can use `npm run pull:content:dev` and `npm run push:content:d > Developer-owned content typically scoped to components, content types, component patterns but can vary based on the stage of your project lifecycle and your preferences. For example, at some point, you may not want to sync assets like images, videos, etc. +## Running behind a corporate proxy + +Both the Next.js runtime and the CLI scripts (`pull:dex`, `push:dex`, `pull:locales`) honor `HTTPS_PROXY` / `HTTP_PROXY`: + +```bash +export HTTPS_PROXY=http://your-proxy.example.com:8080 +export HTTP_PROXY=http://your-proxy.example.com:8080 +``` + +If your proxy intercepts TLS with a custom root CA, also set `NODE_EXTRA_CA_CERTS=/path/to/ca.pem`, otherwise Node rejects the certificate with `UNABLE_TO_VERIFY_LEAF_SIGNATURE`. Each CLI also accepts `--proxy ` to override the env var for a single run. + ## Other scripts ### **Design Extension Sync** diff --git a/apps/csk/package.json b/apps/csk/package.json index a7d62dd76..7e060c321 100644 --- a/apps/csk/package.json +++ b/apps/csk/package.json @@ -1,6 +1,6 @@ { "name": "@uniformdev/component-starter-kit", - "version": "6.1.72", + "version": "6.1.73", "private": true, "engines": { "yarn": "please-use-npm", @@ -38,6 +38,7 @@ "dependencies": { "@uniformdev/assets": "^20.61.2-alpha.3", "@uniformdev/canvas": "^20.61.2-alpha.3", + "@uniformdev/csk-cli": "*", "@uniformdev/csk-components": "*", "@uniformdev/design-extensions-tools": "*", "@uniformdev/next-app-router": "^20.61.2-alpha.3", @@ -58,7 +59,6 @@ "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", "@uniformdev/cli": "^20.61.2-alpha.3", - "@uniformdev/csk-cli": "*", "@uniformdev/csk-recipes": "*", "cross-env": "^10.1.0", "eslint": "^9.31.0", diff --git a/apps/csk/src/instrumentation.ts b/apps/csk/src/instrumentation.ts new file mode 100644 index 000000000..5056fa5ef --- /dev/null +++ b/apps/csk/src/instrumentation.ts @@ -0,0 +1,5 @@ +import { applyGlobalProxy } from '@uniformdev/csk-cli/proxy-fetch'; + +export function register() { + applyGlobalProxy(); +} diff --git a/package-lock.json b/package-lock.json index 0d2860fbf..7b0ea98e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "csk-packages", - "version": "6.1.72", + "version": "6.1.73", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "csk-packages", - "version": "6.1.72", + "version": "6.1.73", "workspaces": [ "apps/*", "packages/*" @@ -27,10 +27,11 @@ }, "apps/csk": { "name": "@uniformdev/component-starter-kit", - "version": "6.1.72", + "version": "6.1.73", "dependencies": { "@uniformdev/assets": "^20.61.2-alpha.3", "@uniformdev/canvas": "^20.61.2-alpha.3", + "@uniformdev/csk-cli": "*", "@uniformdev/csk-components": "*", "@uniformdev/design-extensions-tools": "*", "@uniformdev/next-app-router": "^20.61.2-alpha.3", @@ -51,7 +52,6 @@ "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", "@uniformdev/cli": "^20.61.2-alpha.3", - "@uniformdev/csk-cli": "*", "@uniformdev/csk-recipes": "*", "cross-env": "^10.1.0", "eslint": "^9.31.0", @@ -74,7 +74,7 @@ }, "apps/csk-marketing-site": { "name": "@uniformdev/csk-marketing-site", - "version": "6.1.72", + "version": "6.1.73", "dependencies": { "@uniformdev/assets": "^20.61.2-alpha.3", "@uniformdev/canvas": "^20.61.2-alpha.3", @@ -132,7 +132,7 @@ }, "apps/csk-storybook": { "name": "@uniformdev/csk-storybook", - "version": "6.1.72", + "version": "6.1.73", "devDependencies": { "@chromatic-com/storybook": "^4.1.3", "@repo/eslint-config": "*", @@ -21079,7 +21079,6 @@ "version": "7.25.0", "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz", "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=20.18.1" @@ -22022,13 +22021,14 @@ }, "packages/csk-cli": { "name": "@uniformdev/csk-cli", - "version": "6.1.72", + "version": "6.1.73", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@inquirer/prompts": "^7.1.0", "commander": "^9.0.0", "dotenv": "16.4.7", - "ora": "^8.2.0" + "ora": "^8.2.0", + "undici": "^7.16.0" }, "bin": { "csk-cli": "cli.js" @@ -22093,7 +22093,7 @@ }, "packages/csk-components": { "name": "@uniformdev/csk-components", - "version": "6.1.72", + "version": "6.1.73", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@inquirer/prompts": "^7.1.0", @@ -22184,7 +22184,7 @@ }, "packages/csk-recipes": { "name": "@uniformdev/csk-recipes", - "version": "6.1.72", + "version": "6.1.73", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@inquirer/prompts": "^7.1.0", @@ -22258,14 +22258,15 @@ }, "packages/design-extensions-tools": { "name": "@uniformdev/design-extensions-tools", - "version": "6.1.72", + "version": "6.1.73", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@inquirer/prompts": "^7.1.0", "color": "^5.0.0", "commander": "^9.0.0", "dotenv": "16.4.7", - "ora": "^8.2.0" + "ora": "^8.2.0", + "undici": "^7.16.0" }, "bin": { "design-extensions-tools": "cli.js" @@ -22273,6 +22274,7 @@ "devDependencies": { "@repo/eslint-config": "*", "@repo/typescript-config": "*", + "@uniformdev/csk-cli": "*", "next": "^16.2.6", "react": "^19.2.3", "react-dom": "^19.2.3", @@ -22327,7 +22329,7 @@ }, "packages/eslint-config": { "name": "@repo/eslint-config", - "version": "6.1.72", + "version": "6.1.73", "devDependencies": { "@eslint/js": "^9.31.0", "@next/eslint-plugin-next": "^16.2.6", @@ -22359,14 +22361,28 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "packages/internal": { + "name": "@repo/internal", + "version": "6.1.73", + "extraneous": true, + "dependencies": { + "undici": "^7.16.0" + }, + "devDependencies": { + "@repo/eslint-config": "*", + "@repo/typescript-config": "*", + "tsup": "^8.3.0", + "typescript": "^5.7.3" + } + }, "packages/internal-scripts": { "name": "@repo/internal-scripts", - "version": "6.1.72", + "version": "6.1.73", "license": "ISC" }, "packages/typescript-config": { "name": "@repo/typescript-config", - "version": "6.1.72", + "version": "6.1.73", "license": "MIT" } } diff --git a/package.json b/package.json index f249813c0..2d183a9f3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "csk-packages", - "version": "6.1.72", + "version": "6.1.73", "private": true, "scripts": { "build": "turbo build", diff --git a/packages/csk-cli/package.json b/packages/csk-cli/package.json index 3c6d8603e..ed1407ed9 100644 --- a/packages/csk-cli/package.json +++ b/packages/csk-cli/package.json @@ -1,6 +1,6 @@ { "name": "@uniformdev/csk-cli", - "version": "6.1.72", + "version": "6.1.73", "description": "Command-line interface (CLI) tool designed to streamline the development workflow within Uniform projects. It provides commands for pulling additional data and generating components based on Canvas data", "license": "SEE LICENSE IN LICENSE.txt", "engines": { @@ -19,6 +19,10 @@ "./components": { "types": "./dist/components.d.mts", "default": "./dist/components.mjs" + }, + "./proxy-fetch": { + "types": "./dist/proxy-fetch.d.mts", + "default": "./dist/proxy-fetch.mjs" } }, "types": "./dist/index.d.mts", @@ -38,7 +42,8 @@ "@inquirer/prompts": "^7.1.0", "commander": "^9.0.0", "dotenv": "16.4.7", - "ora": "^8.2.0" + "ora": "^8.2.0", + "undici": "^7.16.0" }, "devDependencies": { "@repo/eslint-config": "*", diff --git a/packages/csk-cli/src/commands/pull/index.ts b/packages/csk-cli/src/commands/pull/index.ts index 2b7bb327c..3e6310c40 100644 --- a/packages/csk-cli/src/commands/pull/index.ts +++ b/packages/csk-cli/src/commands/pull/index.ts @@ -12,13 +12,14 @@ type PullArgs = { allSettings: boolean; dev?: boolean; uniform?: boolean; + proxy?: string; }; export const pullCommand = async (args: PullArgs) => { - const { dev, uniform, locales } = args || {}; + const { dev, uniform, locales, proxy } = args || {}; if (locales) { console.info('Pulling locales...'); - pullLocales().catch(e => console.error(e)); + pullLocales({ proxy }).catch(e => console.error(e)); return; } else if (uniform) { console.info('Pulling uniform canvas data...'); diff --git a/packages/csk-cli/src/commands/pull/pull-locales.ts b/packages/csk-cli/src/commands/pull/pull-locales.ts index 09a748897..e188feeec 100644 --- a/packages/csk-cli/src/commands/pull/pull-locales.ts +++ b/packages/csk-cli/src/commands/pull/pull-locales.ts @@ -3,6 +3,7 @@ import path from 'node:path'; import { LocaleClient, LocalesGetResponse } from '@uniformdev/canvas'; import { CONFIG_FILE, PATH_TO_LOCALES_FOLDER } from './constants'; import { syncSuccessLog } from './utils'; +import { createProxyFetch, getProxyUrl } from '../../proxy-fetch'; type LocalizationSettings = { locales: string[]; @@ -11,7 +12,7 @@ type LocalizationSettings = { defaultLocale: string | null; }; -export const pullLocales = async () => { +export const pullLocales = async ({ proxy }: { proxy?: string } = {}) => { if (!fs.existsSync(PATH_TO_LOCALES_FOLDER)) { console.error( `No such directory for locales files: ${PATH_TO_LOCALES_FOLDER}. You can override it by setting LOCALES_PATH environment variable.` @@ -23,6 +24,7 @@ export const pullLocales = async () => { projectId: process.env.UNIFORM_PROJECT_ID, apiKey: process.env.UNIFORM_API_KEY, apiHost: process.env.UNIFORM_CLI_BASE_URL || 'https://uniform.app', + fetch: createProxyFetch(getProxyUrl(proxy)), }); const localeResponse: LocalesGetResponse = await client.get(); diff --git a/packages/csk-cli/src/index.ts b/packages/csk-cli/src/index.ts index 2c720fd44..e0007cb0c 100644 --- a/packages/csk-cli/src/index.ts +++ b/packages/csk-cli/src/index.ts @@ -11,6 +11,7 @@ program .option('-l, --locales', 'locales configuration') .option('-u, --uniform', 'uniform canvas data') .option('-d, --dev', 'development mode') + .option('--proxy ', 'HTTP(S) proxy URL for outbound requests. Defaults to HTTPS_PROXY/HTTP_PROXY env var.') .action(pullCommand); program diff --git a/packages/csk-cli/src/proxy-fetch.ts b/packages/csk-cli/src/proxy-fetch.ts new file mode 100644 index 000000000..32b935a73 --- /dev/null +++ b/packages/csk-cli/src/proxy-fetch.ts @@ -0,0 +1,43 @@ +import { setGlobalDispatcher, fetch as undiciFetch, ProxyAgent, RequestInit as UndiciRequestInit } from 'undici'; + +export function getProxyUrl(explicit?: string): string | undefined { + return explicit || process.env.HTTPS_PROXY || process.env.HTTP_PROXY; +} + +export function createProxyFetch(proxyUrl?: string): typeof fetch { + if (proxyUrl) console.info(`\u{1F991} Using proxy ${proxyUrl}`); + const dispatcher = proxyUrl ? new ProxyAgent(proxyUrl) : undefined; + return ((input: RequestInfo | URL, init?: RequestInit) => + undiciFetch( + input as URL, + { + ...(init as UndiciRequestInit), + dispatcher, + } as UndiciRequestInit + )) as unknown as typeof fetch; +} + +let configuredProxyUrl: string | undefined; +let cachedFetch: typeof fetch | undefined; + +export function setProxyUrl(url: string | undefined): void { + configuredProxyUrl = url; + cachedFetch = undefined; +} + +export function getConfiguredFetch(): typeof fetch { + if (cachedFetch) return cachedFetch; + cachedFetch = createProxyFetch(configuredProxyUrl ?? getProxyUrl()); + return cachedFetch; +} + +// Installs a proxy as the global undici dispatcher. Used by the Next.js +// instrumentation hook to patch the runtime transport without replacing +// globalThis.fetch — preserves Next.js's fetch-cache wrapper. +export function applyGlobalProxy(): boolean { + const proxyUrl = getProxyUrl(); + if (!proxyUrl) return false; + setGlobalDispatcher(new ProxyAgent(proxyUrl)); + console.info(`[proxy-fetch] Routing fetch through proxy: ${proxyUrl}`); + return true; +} diff --git a/packages/csk-cli/tsup.config.ts b/packages/csk-cli/tsup.config.ts index de0f77086..326d400d6 100644 --- a/packages/csk-cli/tsup.config.ts +++ b/packages/csk-cli/tsup.config.ts @@ -1,7 +1,7 @@ import { defineConfig } from 'tsup'; export default defineConfig({ - entry: ['src/index.ts'], + entry: ['src/index.ts', 'src/proxy-fetch.ts'], format: ['esm'], dts: true, splitting: true, diff --git a/packages/csk-components/package.json b/packages/csk-components/package.json index b8b22072d..0d74db540 100644 --- a/packages/csk-components/package.json +++ b/packages/csk-components/package.json @@ -1,6 +1,6 @@ { "name": "@uniformdev/csk-components", - "version": "6.1.72", + "version": "6.1.73", "description": "Components Starter Kit that provides a set of basic components for building websites within a Uniform project", "license": "SEE LICENSE IN LICENSE.txt", "engines": { diff --git a/packages/csk-recipes/package.json b/packages/csk-recipes/package.json index 32674f31c..3ce276315 100644 --- a/packages/csk-recipes/package.json +++ b/packages/csk-recipes/package.json @@ -1,6 +1,6 @@ { "name": "@uniformdev/csk-recipes", - "version": "6.1.72", + "version": "6.1.73", "description": "command-line interface (CLI) and utility functions to help you work with recipes in a CSK project. It simplifies project initialization by allowing you to choose templates and include specific recipes", "license": "SEE LICENSE IN LICENSE.txt", "engines": { diff --git a/packages/design-extensions-tools/package.json b/packages/design-extensions-tools/package.json index d23a2460d..520e1f759 100644 --- a/packages/design-extensions-tools/package.json +++ b/packages/design-extensions-tools/package.json @@ -1,6 +1,6 @@ { "name": "@uniformdev/design-extensions-tools", - "version": "6.1.72", + "version": "6.1.73", "description": "Command-line interface (CLI) tool and a set of utilities for working with design extension integrations", "license": "SEE LICENSE IN LICENSE.txt", "engines": { @@ -36,11 +36,13 @@ "color": "^5.0.0", "commander": "^9.0.0", "dotenv": "16.4.7", - "ora": "^8.2.0" + "ora": "^8.2.0", + "undici": "^7.16.0" }, "devDependencies": { "@repo/eslint-config": "*", "@repo/typescript-config": "*", + "@uniformdev/csk-cli": "*", "next": "^16.2.6", "react": "^19.2.3", "react-dom": "^19.2.3", diff --git a/packages/design-extensions-tools/src/index.ts b/packages/design-extensions-tools/src/index.ts index f40a78046..ee2def425 100644 --- a/packages/design-extensions-tools/src/index.ts +++ b/packages/design-extensions-tools/src/index.ts @@ -1,5 +1,6 @@ import { program } from 'commander'; import type { Command } from 'commander'; +import { setProxyUrl } from '@uniformdev/csk-cli/proxy-fetch'; import { buildAllowedGroups, buildBorders, @@ -34,7 +35,8 @@ const addConnectionOptions = (cmd: Command) => '-p, --project ', 'Uniform project id. Defaults to UNIFORM_PROJECT_ID env var. Supports dotenv.', process.env.UNIFORM_PROJECT_ID - ); + ) + .option('--proxy ', 'HTTP(S) proxy URL for outbound requests. Defaults to HTTPS_PROXY/HTTP_PROXY env var.'); type PullArgs = ConnectionOptions & { colors?: boolean; @@ -44,6 +46,7 @@ type PullArgs = ConnectionOptions & { groups?: boolean; allTokens?: boolean; allSettings: boolean; + proxy?: string; }; addConnectionOptions(program.command('pull').description('Pull data from the integration')) @@ -55,6 +58,7 @@ addConnectionOptions(program.command('pull').description('Pull data from the int .option('-at, --allTokens', 'all tokens') .option('-as, --allSettings', 'all settings') .action(async (args: PullArgs) => { + setProxyUrl(args.proxy); const connectionOptions: ConnectionOptions = { apiKey: args.apiKey, apiHost: args.apiHost, @@ -144,6 +148,7 @@ type PushArgs = ConnectionOptions & { groups?: boolean; allTokens?: boolean; allSettings: boolean; + proxy?: string; }; addConnectionOptions(program.command('push').description('Push data to the integration')) @@ -155,6 +160,7 @@ addConnectionOptions(program.command('push').description('Push data to the integ .option('-at, --allTokens', 'all tokens') .option('-as, --allSettings', 'all settings') .action(async (args: PushArgs) => { + setProxyUrl(args.proxy); const connectionOptions: ConnectionOptions = { apiKey: args.apiKey, apiHost: args.apiHost, diff --git a/packages/design-extensions-tools/src/utils/index.ts b/packages/design-extensions-tools/src/utils/index.ts index d86e70885..a2837e0d8 100644 --- a/packages/design-extensions-tools/src/utils/index.ts +++ b/packages/design-extensions-tools/src/utils/index.ts @@ -1,3 +1,4 @@ +import { getConfiguredFetch } from '@uniformdev/csk-cli/proxy-fetch'; import { ConnectionOptions } from 'src/types'; import { CONFIG_FILE, DEFAULT_INTEGRATION_URL, FG_GREEN, CONFIGURATION_KEYS, CONFIG_FILE_PATH } from '../constants'; @@ -28,7 +29,7 @@ export const checkConnectionOptions = (connectionOptions: ConnectionOptions) => }; export const fetchTokenValue = (endPoint: string, connectionOptions: ConnectionOptions, ...queryParams: string[]) => - fetch( + getConfiguredFetch()( `${process.env.INTEGRATION_URL || DEFAULT_INTEGRATION_URL}/api/${endPoint}?projectId=${connectionOptions.project}${queryParams.length ? `&${queryParams.join('&')}` : ''}`, { cache: 'no-cache' } ).then(response => { @@ -42,7 +43,7 @@ export const fetchTokenValue = (endPoint: string, connectionOptions: ConnectionO }); export const pushTokenValue = (endPoint: string, body: BodyInit | null, connectionOptions: ConnectionOptions) => - fetch( + getConfiguredFetch()( `${process.env.INTEGRATION_URL || DEFAULT_INTEGRATION_URL}/api/${endPoint}?projectId=${connectionOptions.project}&baseUrl=${connectionOptions.apiHost}`, { cache: 'no-cache', diff --git a/packages/design-extensions-tools/tsconfig.json b/packages/design-extensions-tools/tsconfig.json index 466f8a772..19888fe78 100644 --- a/packages/design-extensions-tools/tsconfig.json +++ b/packages/design-extensions-tools/tsconfig.json @@ -2,7 +2,8 @@ "extends": "@repo/typescript-config/react-library.json", "compilerOptions": { "outDir": "dist", - "baseUrl": "." + "baseUrl": ".", + "moduleResolution": "bundler" }, "include": [ "src", diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json index 246bddc06..b48b96469 100644 --- a/packages/eslint-config/package.json +++ b/packages/eslint-config/package.json @@ -1,6 +1,6 @@ { "name": "@repo/eslint-config", - "version": "6.1.72", + "version": "6.1.73", "type": "module", "private": true, "exports": { diff --git a/packages/internal-scripts/package.json b/packages/internal-scripts/package.json index ccdba3319..504784428 100644 --- a/packages/internal-scripts/package.json +++ b/packages/internal-scripts/package.json @@ -1,6 +1,6 @@ { "name": "@repo/internal-scripts", - "version": "6.1.72", + "version": "6.1.73", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", diff --git a/packages/typescript-config/package.json b/packages/typescript-config/package.json index 8321941e8..691dc9b26 100644 --- a/packages/typescript-config/package.json +++ b/packages/typescript-config/package.json @@ -1,6 +1,6 @@ { "name": "@repo/typescript-config", - "version": "6.1.72", + "version": "6.1.73", "private": true, "license": "MIT", "publishConfig": {