diff --git a/.changeset/bright-auth-skeleton.md b/.changeset/bright-auth-skeleton.md new file mode 100644 index 00000000000..57af0687d26 --- /dev/null +++ b/.changeset/bright-auth-skeleton.md @@ -0,0 +1,5 @@ +--- +'@shopify/dev-platform-auth': minor +--- + +Add the `@shopify/dev-platform-auth` package skeleton. diff --git a/.changeset/config.json b/.changeset/config.json index d12fe1e0daa..607e96235eb 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -12,7 +12,8 @@ "@shopify/cli-kit", "@shopify/theme", "@shopify/plugin-cloudflare", - "@shopify/plugin-did-you-mean" + "@shopify/plugin-did-you-mean", + "@shopify/dev-platform-auth" ]], "access": "public", "baseBranch": "main", diff --git a/package.json b/package.json index ef13b64368f..37ed24217a1 100644 --- a/package.json +++ b/package.json @@ -248,6 +248,17 @@ ] } }, + "packages/dev-platform-auth": { + "entry": [ + "**/index.ts!" + ], + "project": "**/*.ts!", + "vite": { + "config": [ + "vite.config.ts" + ] + } + }, "packages/store": { "entry": [ "**/{commands,hooks}/**/*.ts!", diff --git a/packages/dev-platform-auth/README.md b/packages/dev-platform-auth/README.md new file mode 100644 index 00000000000..a4187459040 --- /dev/null +++ b/packages/dev-platform-auth/README.md @@ -0,0 +1,7 @@ +# @shopify/dev-platform-auth + +`@shopify/dev-platform-auth` provides portable Shopify developer auth flows. + +This package is currently a skeleton. Identity device flow and `client_credentials` flow modules will arrive in subsequent pull requests. + +The portability contract is ESM on Node.js >=20, with no Node built-ins in the `.` entry. Only `.` and `./testing` are exported. diff --git a/packages/dev-platform-auth/package.json b/packages/dev-platform-auth/package.json new file mode 100644 index 00000000000..fff33fd9139 --- /dev/null +++ b/packages/dev-platform-auth/package.json @@ -0,0 +1,56 @@ +{ + "name": "@shopify/dev-platform-auth", + "version": "4.6.0", + "packageManager": "pnpm@10.11.1", + "private": false, + "description": "Portable Shopify developer auth flows", + "homepage": "https://github.com/shopify/cli#readme", + "bugs": { + "url": "https://community.shopify.dev/c/shopify-cli-libraries/14" + }, + "repository": { + "type": "git", + "url": "https://github.com/Shopify/cli.git", + "directory": "packages/dev-platform-auth" + }, + "license": "MIT", + "type": "module", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "node": "./dist/index.js" + }, + "./testing": { + "types": "./dist/testing/index.d.ts", + "import": "./dist/testing/index.js", + "node": "./dist/testing/index.js" + } + }, + "files": ["dist"], + "scripts": { + "build": "nx build", + "clean": "nx clean", + "lint": "nx lint", + "lint:fix": "nx lint:fix", + "type-check": "nx type-check", + "vitest": "vitest" + }, + "eslintConfig": { + "extends": ["../../.eslintrc.cjs"] + }, + "devDependencies": { + "@types/node": "18.19.130", + "@vitest/coverage-istanbul": "^3.2.7", + "esbuild": "0.28.1" + }, + "engines": { + "node": ">=20.10.0" + }, + "publishConfig": { + "@shopify:registry": "https://registry.npmjs.org", + "access": "public" + }, + "sideEffects": false, + "engine-strict": true +} diff --git a/packages/dev-platform-auth/project.json b/packages/dev-platform-auth/project.json new file mode 100644 index 00000000000..4c17ed8d9f4 --- /dev/null +++ b/packages/dev-platform-auth/project.json @@ -0,0 +1,46 @@ +{ + "name": "dev-platform-auth", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "packages/dev-platform-auth/src", + "projectType": "library", + "tags": ["scope:foundation"], + "targets": { + "clean": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm rimraf dist/", + "cwd": "packages/dev-platform-auth" + } + }, + "build": { + "executor": "nx:run-commands", + "outputs": ["{workspaceRoot}/packages/dev-platform-auth/dist"], + "inputs": ["{projectRoot}/src/**/*", "{projectRoot}/package.json", "{projectRoot}/tsconfig.build.json"], + "options": { + "command": "pnpm tsc -b ./tsconfig.build.json", + "cwd": "packages/dev-platform-auth" + } + }, + "lint": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm eslint src", + "cwd": "packages/dev-platform-auth" + } + }, + "lint:fix": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm eslint src --fix", + "cwd": "packages/dev-platform-auth" + } + }, + "type-check": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm tsc --noEmit", + "cwd": "packages/dev-platform-auth" + } + } + } +} diff --git a/packages/dev-platform-auth/src/index.ts b/packages/dev-platform-auth/src/index.ts new file mode 100644 index 00000000000..0cd68764c53 --- /dev/null +++ b/packages/dev-platform-auth/src/index.ts @@ -0,0 +1,3 @@ +export const PACKAGE_NAME = '@shopify/dev-platform-auth' + +export type AuthFlowPlaceholder = 'skeleton' diff --git a/packages/dev-platform-auth/src/portability.test.ts b/packages/dev-platform-auth/src/portability.test.ts new file mode 100644 index 00000000000..747fd3e2c6b --- /dev/null +++ b/packages/dev-platform-auth/src/portability.test.ts @@ -0,0 +1,38 @@ +/* eslint-disable no-restricted-imports, import-x/order */ +import {execFileSync} from 'node:child_process' +import {readFileSync} from 'node:fs' +import {resolve} from 'node:path' +import {build} from 'esbuild' +import {describe, expect, test} from 'vitest' + +const packageRoot = resolve(__dirname, '..') +const entry = resolve(packageRoot, 'dist/index.js') + +function buildPackage() { + execFileSync('pnpm', ['exec', 'nx', 'build', 'dev-platform-auth'], { + cwd: resolve(packageRoot, '../..'), + stdio: 'ignore', + }) +} + +describe('package portability', () => { + test('can be consumed by plain JavaScript', () => { + buildPackage() + execFileSync(process.execPath, [resolve(packageRoot, 'tests/consumer.mjs')], {stdio: 'pipe'}) + }) + + test('does not include Node built-ins or CommonJS in the portable entry', () => { + buildPackage() + const output = readFileSync(entry, 'utf8') + const nodeBuiltins = + /(?:node:)?(?:assert|buffer|child_process|cluster|crypto|dgram|dns|events|fs|http|https|module|net|os|path|perf_hooks|process|querystring|readline|stream|string_decoder|timers|tls|tty|url|util|v8|vm|worker_threads|zlib)/ + + expect(output).not.toMatch(nodeBuiltins) + expect(output).not.toContain('require(') + }) + + test('bundles for browsers without external dependencies', async () => { + buildPackage() + await expect(build({entryPoints: [entry], bundle: true, platform: 'browser', write: false})).resolves.toBeDefined() + }) +}) diff --git a/packages/dev-platform-auth/src/testing/index.ts b/packages/dev-platform-auth/src/testing/index.ts new file mode 100644 index 00000000000..ce50e735361 --- /dev/null +++ b/packages/dev-platform-auth/src/testing/index.ts @@ -0,0 +1 @@ +export const TESTING_PACKAGE_NAME = '@shopify/dev-platform-auth/testing' diff --git a/packages/dev-platform-auth/tests/consumer.mjs b/packages/dev-platform-auth/tests/consumer.mjs new file mode 100644 index 00000000000..f55476d8927 --- /dev/null +++ b/packages/dev-platform-auth/tests/consumer.mjs @@ -0,0 +1,5 @@ +import {PACKAGE_NAME} from '../dist/index.js' + +if (PACKAGE_NAME !== '@shopify/dev-platform-auth') { + throw new Error(`Unexpected package name: ${PACKAGE_NAME}`) +} diff --git a/packages/dev-platform-auth/tsconfig.build.json b/packages/dev-platform-auth/tsconfig.build.json new file mode 100644 index 00000000000..d472b2c2aa0 --- /dev/null +++ b/packages/dev-platform-auth/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["**/*.test.ts"] +} diff --git a/packages/dev-platform-auth/tsconfig.json b/packages/dev-platform-auth/tsconfig.json new file mode 100644 index 00000000000..3d7207d293a --- /dev/null +++ b/packages/dev-platform-auth/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../configurations/tsconfig.json", + "include": ["./src/**/*.ts"], + "exclude": ["./dist"], + "compilerOptions": { + "lib": ["ES2022"], + "target": "ES2022", + "outDir": "dist", + "rootDir": "src", + "tsBuildInfoFile": "dist/tsconfig.tsbuildinfo", + "types": ["node", "vitest/importMeta"] + }, + "references": [] +} diff --git a/packages/dev-platform-auth/vite.config.ts b/packages/dev-platform-auth/vite.config.ts new file mode 100644 index 00000000000..9536586ca45 --- /dev/null +++ b/packages/dev-platform-auth/vite.config.ts @@ -0,0 +1,3 @@ +import config from '../../configurations/vite.config' + +export default config(__dirname) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 797f738fef9..79bb5c347e7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -544,6 +544,18 @@ importers: specifier: ^2.1.1 version: 2.1.1(esbuild@0.28.1) + packages/dev-platform-auth: + devDependencies: + '@types/node': + specifier: 18.19.130 + version: 18.19.130 + '@vitest/coverage-istanbul': + specifier: ^3.2.7 + version: 3.2.7(vitest@4.1.10) + esbuild: + specifier: 0.28.1 + version: 0.28.1 + packages/e2e: devDependencies: '@iarna/toml':