[READ-ONLY] a fast, modern browser for the npm registry

chore: use `getEnv` in `oauth` module for platform agnosticity (#1148)

Co-authored-by: Daniel Roe <daniel@roe.dev>

authored by philippeserhal.com

Daniel Roe and committed by
GitHub
d325cf08 737eb13a

+236 -24
+59 -4
config/env.ts
··· 1 + // TODO(serhalp): Extract most of this module to https://github.com/unjs/std-env. 2 + 1 3 import Git from 'simple-git' 2 4 import * as process from 'node:process' 3 5 ··· 27 29 28 30 /** 29 31 * Environment variable `CONTEXT` provided by Netlify. 32 + * `dev`, `production`, `deploy-preview`, `branch-deploy`, `preview-server`, or a branch name 30 33 * @see {@link https://docs.netlify.com/build/configure-builds/environment-variables/#build-metadata} 31 34 * 32 35 * Environment variable `VERCEL_ENV` provided by Vercel. 36 + * `production`, `preview`, or `development` 33 37 * @see {@link https://vercel.com/docs/environment-variables/system-environment-variables#VERCEL_ENV} 34 38 * 35 - * Whether triggered by PR, `deploy-preview` or `dev`. 39 + * Whether this is some sort of preview environment. 36 40 */ 37 41 export const isPreview = 38 42 isPR || 39 - process.env.CONTEXT === 'deploy-preview' || 40 - process.env.CONTEXT === 'dev' || 43 + (process.env.CONTEXT && process.env.CONTEXT !== 'production') || 41 44 process.env.VERCEL_ENV === 'preview' || 42 45 process.env.VERCEL_ENV === 'development' 46 + export const isProduction = 47 + process.env.CONTEXT === 'production' || process.env.VERCEL_ENV === 'production' 48 + 49 + /** 50 + * Environment variable `URL` provided by Netlify. 51 + * This is always the current deploy URL, regardless of env. 52 + * @see {@link https://docs.netlify.com/build/functions/environment-variables/#functions} 53 + * 54 + * Environment variable `VERCEL_URL` provided by Vercel. 55 + * This is always the current deploy URL, regardless of env. 56 + * NOTE: Not a valid URL, as the protocol is omitted. 57 + * @see {@link https://vercel.com/docs/environment-variables/system-environment-variables#VERCEL_URL} 58 + * 59 + * Preview URL for the current deployment, only available in preview environments. 60 + */ 61 + export const getPreviewUrl = () => 62 + isPreview 63 + ? process.env.URL 64 + ? process.env.URL 65 + : process.env.NUXT_ENV_VERCEL_URL 66 + ? `https://${process.env.NUXT_ENV_VERCEL_URL}` 67 + : undefined 68 + : undefined 69 + 70 + /** 71 + * Environment variable `URL` provided by Netlify. 72 + * This is always the current deploy URL, regardless of env. 73 + * @see {@link https://docs.netlify.com/build/functions/environment-variables/#functions} 74 + * 75 + * Environment variable `VERCEL_PROJECT_PRODUCTION_URL` provided by Vercel. 76 + * NOTE: Not a valid URL, as the protocol is omitted. 77 + * @see {@link https://vercel.com/docs/environment-variables/system-environment-variables#VERCEL_PROJECT_PRODUCTION_URL} 78 + * 79 + * Production URL for the current deployment, only available in production environments. 80 + */ 81 + export const getProductionUrl = () => 82 + isProduction 83 + ? process.env.URL 84 + ? process.env.URL 85 + : process.env.NUXT_ENV_VERCEL_PROJECT_PRODUCTION_URL 86 + ? `https://${process.env.NUXT_ENV_VERCEL_PROJECT_PRODUCTION_URL}` 87 + : undefined 88 + : undefined 43 89 44 90 const git = Git() 45 91 export async function getGitInfo() { ··· 92 138 : branch === 'main' 93 139 ? 'canary' 94 140 : 'release' 95 - return { commit, shortCommit, branch, env } as const 141 + const previewUrl = getPreviewUrl() 142 + const productionUrl = getProductionUrl() 143 + return { 144 + commit, 145 + shortCommit, 146 + branch, 147 + env, 148 + previewUrl, 149 + productionUrl, 150 + } as const 96 151 }
+4 -13
modules/oauth.ts
··· 3 3 import { join } from 'node:path' 4 4 import { appendFileSync, existsSync, readFileSync } from 'node:fs' 5 5 import { randomUUID } from 'node:crypto' 6 + import { getEnv } from '../config/env.ts' 6 7 7 8 export default defineNuxtModule({ 8 9 meta: { 9 10 name: 'oauth', 10 11 }, 11 - setup() { 12 + async setup() { 12 13 const nuxt = useNuxt() 13 14 14 - const env = process.env.NUXT_ENV_VERCEL_ENV 15 - const previewUrl = process.env.NUXT_ENV_VERCEL_URL 16 - const prodUrl = process.env.NUXT_ENV_VERCEL_PROJECT_PRODUCTION_URL 17 - 18 - let clientUri: string 19 - if (env === 'preview' && previewUrl) { 20 - clientUri = `https://${previewUrl}` 21 - } else if (env === 'production' && prodUrl) { 22 - clientUri = `https://${prodUrl}` 23 - } else { 24 - clientUri = 'http://127.0.0.1:3000' 25 - } 15 + const { previewUrl, productionUrl } = await getEnv(nuxt.options.dev) 16 + const clientUri = productionUrl || previewUrl || 'http://127.0.0.1:3000' 26 17 27 18 // bake it into a virtual file 28 19 addServerTemplate({
+173
test/unit/config/env.spec.ts
··· 1 + import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' 2 + 3 + const ALL_ENV_VARS = [ 4 + 'CONTEXT', 5 + 'VERCEL_ENV', 6 + 'URL', 7 + 'NUXT_ENV_VERCEL_URL', 8 + 'NUXT_ENV_VERCEL_PROJECT_PRODUCTION_URL', 9 + ] 10 + 11 + describe('getPreviewUrl', () => { 12 + beforeEach(() => { 13 + // Reset consts evaluated at module init time 14 + vi.resetModules() 15 + }) 16 + 17 + beforeEach(() => { 18 + for (const envVar of ALL_ENV_VARS) { 19 + vi.stubEnv(envVar, undefined) 20 + } 21 + }) 22 + 23 + afterEach(() => { 24 + vi.unstubAllEnvs() 25 + }) 26 + 27 + it('returns `undefined` if no known preview env is detected', async () => { 28 + const { getPreviewUrl } = await import('../../../config/env') 29 + 30 + expect(getPreviewUrl()).toBeUndefined() 31 + }) 32 + 33 + it.each([ 34 + ['Netlify production', { CONTEXT: 'production', URL: 'https://prod.example.com' }], 35 + ['Vercel production', { VERCEL_ENV: 'production', NUXT_ENV_VERCEL_URL: 'prod.example.com' }], 36 + ])('%s environment returns `undefined`', async (_name, envVars) => { 37 + for (const [key, value] of Object.entries(envVars)) { 38 + vi.stubEnv(key, value) 39 + } 40 + const { getPreviewUrl } = await import('../../../config/env') 41 + 42 + expect(getPreviewUrl()).toBeUndefined() 43 + }) 44 + 45 + it.each([ 46 + ['Netlify dev', { CONTEXT: 'dev', URL: 'https://dev.example.com' }, 'https://dev.example.com'], 47 + [ 48 + 'Netlify deploy-preview', 49 + { 50 + CONTEXT: 'deploy-preview', 51 + URL: 'https://preview.example.com', 52 + }, 53 + 'https://preview.example.com', 54 + ], 55 + [ 56 + 'Netlify branch-deploy', 57 + { CONTEXT: 'branch-deploy', URL: 'https://beta.example.com' }, 58 + 'https://beta.example.com', 59 + ], 60 + [ 61 + 'Netlify preview-server', 62 + { 63 + CONTEXT: 'preview-server', 64 + URL: 'https://my-feat--preview.example.com', 65 + }, 66 + 'https://my-feat--preview.example.com', 67 + ], 68 + [ 69 + 'Vercel development', 70 + { VERCEL_ENV: 'development', NUXT_ENV_VERCEL_URL: 'dev.example.com' }, 71 + 'https://dev.example.com', 72 + ], 73 + [ 74 + 'Vercel preview', 75 + { VERCEL_ENV: 'preview', NUXT_ENV_VERCEL_URL: 'preview.example.com' }, 76 + 'https://preview.example.com', 77 + ], 78 + ])('%s environment returns preview URL', async (_name, envVars, expectedUrl) => { 79 + for (const [key, value] of Object.entries(envVars)) { 80 + vi.stubEnv(key, value) 81 + } 82 + 83 + const { getPreviewUrl } = await import('../../../config/env') 84 + 85 + expect(getPreviewUrl()).toBe(expectedUrl) 86 + }) 87 + }) 88 + 89 + describe('getProductionUrl', () => { 90 + beforeEach(() => { 91 + // Reset consts evaluated at module init time 92 + vi.resetModules() 93 + }) 94 + 95 + beforeEach(() => { 96 + for (const envVar of ALL_ENV_VARS) { 97 + vi.stubEnv(envVar, undefined) 98 + } 99 + }) 100 + 101 + afterEach(() => { 102 + vi.unstubAllEnvs() 103 + }) 104 + 105 + it('returns `undefined` if no known production env is detected', async () => { 106 + const { getProductionUrl } = await import('../../../config/env') 107 + 108 + expect(getProductionUrl()).toBeUndefined() 109 + }) 110 + 111 + it.each([ 112 + ['Netlify dev', { CONTEXT: 'dev', URL: 'https://dev.example.com' }], 113 + [ 114 + 'Netlify deploy-preview', 115 + { 116 + CONTEXT: 'deploy-preview', 117 + URL: 'https://preview.example.com', 118 + }, 119 + ], 120 + ['Netlify branch-deploy', { CONTEXT: 'branch-deploy', URL: 'https://beta.example.com' }], 121 + [ 122 + 'Netlify preview-server', 123 + { 124 + CONTEXT: 'preview-server', 125 + URL: 'https://my-feat--preview.example.com', 126 + }, 127 + ], 128 + [ 129 + 'Vercel development', 130 + { 131 + VERCEL_ENV: 'development', 132 + NUXT_ENV_VERCEL_PROJECT_PRODUCTION_URL: 'dev.example.com', 133 + }, 134 + ], 135 + [ 136 + 'Vercel preview', 137 + { 138 + VERCEL_ENV: 'preview', 139 + NUXT_ENV_VERCEL_PROJECT_PRODUCTION_URL: 'preview.example.com', 140 + }, 141 + ], 142 + ])('%s environment returns `undefined`', async (_name, envVars) => { 143 + for (const [key, value] of Object.entries(envVars)) { 144 + vi.stubEnv(key, value) 145 + } 146 + const { getProductionUrl } = await import('../../../config/env') 147 + 148 + expect(getProductionUrl()).toBeUndefined() 149 + }) 150 + 151 + it.each([ 152 + [ 153 + 'Netlify production', 154 + { CONTEXT: 'production', URL: 'https://prod.example.com' }, 155 + 'https://prod.example.com', 156 + ], 157 + [ 158 + 'Vercel production', 159 + { 160 + VERCEL_ENV: 'production', 161 + NUXT_ENV_VERCEL_PROJECT_PRODUCTION_URL: 'prod.example.com', 162 + }, 163 + 'https://prod.example.com', 164 + ], 165 + ])('%s environment returns production URL', async (_name, envVars, expectedUrl) => { 166 + for (const [key, value] of Object.entries(envVars)) { 167 + vi.stubEnv(key, value) 168 + } 169 + const { getProductionUrl } = await import('../../../config/env') 170 + 171 + expect(getProductionUrl()).toBe(expectedUrl) 172 + }) 173 + })
-7
test/unit/index.spec.ts
··· 1 - import { describe, expect, it } from 'vitest' 2 - 3 - describe('work', () => { 4 - it('should work', () => { 5 - expect(true).toBe(true) 6 - }) 7 - })