-
Notifications
You must be signed in to change notification settings - Fork 158
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add project preview command (#1367)
* feat: add project previiew command * chore: use stdout instead of console.log * Update packages/cli/src/commands/preview-project/index.ts Co-authored-by: Andrew Tatomyr <[email protected]> * fix: apply port argument * chore: command defaults, naming, and descriptions adjustments --------- Co-authored-by: Andrew Tatomyr <[email protected]>
- Loading branch information
1 parent
ac878d4
commit 8e29966
Showing
5 changed files
with
131 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { Product } from './types'; | ||
|
||
export const PRODUCT_PACKAGES = { | ||
realm: '@redocly/realm', | ||
'redoc-revel': '@redocly/redoc-revel', | ||
'revel-reef': '@redocly/revel-reef', | ||
'redoc-reef': '@redocly/redoc-reef', | ||
redoc: '@redocly/redoc', | ||
revel: '@redocly/revel', | ||
reef: '@redocly/reef', | ||
}; | ||
|
||
export const PRODUCT_NAMES: { [key in Product]: string } = { | ||
redoc: 'Redoc', | ||
revel: 'Revel', | ||
reef: 'Reef', | ||
realm: 'Realm', | ||
'redoc-revel': 'Redoc + Revel', | ||
'redoc-reef': 'Redoc + Reef', | ||
'revel-reef': 'Revel + Reef', | ||
}; | ||
|
||
export const PRODUCT_PLANS = ['pro', 'enterprise'] as const; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import path = require('path'); | ||
import { existsSync, readFileSync } from 'fs'; | ||
import { spawn } from 'child_process'; | ||
import { PRODUCT_NAMES, PRODUCT_PACKAGES } from './constants'; | ||
|
||
import type { PreviewProjectOptions, Product } from './types'; | ||
|
||
export const previewProject = async (args: PreviewProjectOptions) => { | ||
const { plan, port } = args; | ||
const projectDir = args['source-dir']; | ||
|
||
const product = args.product || tryGetProductFromPackageJson(projectDir); | ||
|
||
if (!isValidProduct(product)) { | ||
process.stderr.write(`Invalid product ${product}`); | ||
throw new Error(`Project preview launch failed`); | ||
} | ||
|
||
const productName = PRODUCT_NAMES[product]; | ||
const packageName = PRODUCT_PACKAGES[product]; | ||
|
||
process.stdout.write(`\nLaunching preview of ${productName} ${plan} using NPX\n\n`); | ||
|
||
spawn('npx', ['-y', packageName, 'develop', `--plan=${plan}`, `--port=${port || 4000}`], { | ||
stdio: 'inherit', | ||
cwd: projectDir, | ||
}); | ||
}; | ||
|
||
const isValidProduct = (product: string | undefined): product is Product => { | ||
if (!product) { | ||
return false; | ||
} | ||
|
||
return !!PRODUCT_NAMES[product as Product]; | ||
}; | ||
|
||
const tryGetProductFromPackageJson = (projectDir: string): Product => { | ||
const packageJsonPath = path.join(process.cwd(), projectDir, 'package.json'); | ||
|
||
if (existsSync(packageJsonPath)) { | ||
try { | ||
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8')); | ||
const packageJsonDeps = packageJson.dependencies || {}; | ||
|
||
for (const [product, packageName] of Object.entries(PRODUCT_PACKAGES)) { | ||
if (packageJsonDeps[packageName]) { | ||
process.stdout.write(`\n${packageName} detected in project's 'package.json'`); | ||
return product as Product; | ||
} | ||
} | ||
} catch (error) { | ||
process.stdout.write(`Invalid 'package.json': ${packageJsonPath}. Using Realm.`); | ||
} | ||
} | ||
|
||
return 'realm'; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { PRODUCT_PACKAGES, PRODUCT_PLANS } from './constants'; | ||
|
||
export type Product = keyof typeof PRODUCT_PACKAGES; | ||
export type ProductPlan = typeof PRODUCT_PLANS[number]; | ||
|
||
export type PreviewProjectOptions = { | ||
product?: Product | string; | ||
plan: ProductPlan | string; | ||
port?: number; | ||
'source-dir': string; | ||
config: string | undefined; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8e29966
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Coverage report
Test suite run success
671 tests passing in 94 suites.
Report generated by 🧪jest coverage report action from 8e29966