utils.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /* eslint-disable no-console */
  2. import chalk from 'chalk';
  3. import { execSync } from 'child_process';
  4. import { createHash } from 'crypto';
  5. import * as fs from 'fs-extra';
  6. import * as path from 'path';
  7. import { STATIC_ASSETS_OUTPUT_DIR } from './constants';
  8. import {
  9. AdminUiExtension,
  10. AdminUiExtensionWithId,
  11. Extension,
  12. GlobalStylesExtension,
  13. SassVariableOverridesExtension,
  14. StaticAssetDefinition,
  15. StaticAssetExtension,
  16. TranslationExtension,
  17. } from './types';
  18. export const logger = {
  19. log: (message: string) => console.log(chalk.green(message)),
  20. error: (message: string) => console.log(chalk.red(message)),
  21. };
  22. /**
  23. * Checks for the global yarn binary to determine whether to use yarn or npm.
  24. */
  25. export function determinePackageManager(): 'yarn' | 'npm' {
  26. try {
  27. execSync('yarnpkg --version', { stdio: 'ignore' });
  28. return 'yarn';
  29. } catch (e: any) {
  30. return 'npm';
  31. }
  32. }
  33. /**
  34. * Returns the string path of a static asset
  35. */
  36. export function getStaticAssetPath(staticAssetDef: StaticAssetDefinition): string {
  37. return typeof staticAssetDef === 'string' ? staticAssetDef : staticAssetDef.path;
  38. }
  39. /**
  40. * Copy the @vendure/ui-devkit files to the static assets dir.
  41. */
  42. export function copyUiDevkit(outputPath: string) {
  43. const devkitDir = path.join(outputPath, STATIC_ASSETS_OUTPUT_DIR, 'devkit');
  44. fs.ensureDirSync(devkitDir);
  45. fs.copySync(require.resolve('@vendure/ui-devkit'), path.join(devkitDir, 'ui-devkit.js'));
  46. }
  47. /**
  48. * Copies over any files defined by the extensions' `staticAssets` array to the shared
  49. * static assets directory. When the app is built by the ng cli, this assets directory is
  50. * the copied over to the final static assets location (i.e. http://domain/admin/assets/)
  51. */
  52. export async function copyStaticAsset(outputPath: string, staticAssetDef: StaticAssetDefinition) {
  53. const staticAssetPath = getStaticAssetPath(staticAssetDef);
  54. const assetBasename = path.basename(staticAssetPath);
  55. const assetOutputPath = path.join(outputPath, STATIC_ASSETS_OUTPUT_DIR, assetBasename);
  56. fs.copySync(staticAssetPath, assetOutputPath);
  57. if (typeof staticAssetDef !== 'string') {
  58. // The asset is being renamed
  59. const newName = path.join(path.dirname(assetOutputPath), staticAssetDef.rename);
  60. try {
  61. // We use copy, remove rather than rename due to problems with the
  62. // EPERM error in Windows.
  63. await fs.copy(assetOutputPath, newName);
  64. await fs.remove(assetOutputPath);
  65. } catch (e: any) {
  66. logger.log(e);
  67. }
  68. }
  69. }
  70. /**
  71. * Ensures each extension has an ID and a value for the optional properties.
  72. * If not defined by the user, a deterministic ID is generated
  73. * from a hash of the extension config.
  74. */
  75. export function normalizeExtensions(extensions?: AdminUiExtension[]): AdminUiExtensionWithId[] {
  76. return (extensions || []).map(e => {
  77. let id = e.id;
  78. if (!id) {
  79. const hash = createHash('sha256');
  80. hash.update(JSON.stringify(e));
  81. id = hash.digest('hex');
  82. }
  83. return {
  84. staticAssets: [],
  85. translations: {},
  86. globalStyles: [],
  87. ...e,
  88. id,
  89. };
  90. });
  91. }
  92. export function isAdminUiExtension(input: Extension): input is AdminUiExtension {
  93. return input.hasOwnProperty('extensionPath');
  94. }
  95. export function isTranslationExtension(input: Extension): input is TranslationExtension {
  96. return input.hasOwnProperty('translations');
  97. }
  98. export function isStaticAssetExtension(input: Extension): input is StaticAssetExtension {
  99. return input.hasOwnProperty('staticAssets');
  100. }
  101. export function isGlobalStylesExtension(input: Extension): input is GlobalStylesExtension {
  102. return input.hasOwnProperty('globalStyles');
  103. }
  104. export function isSassVariableOverridesExtension(input: Extension): input is SassVariableOverridesExtension {
  105. return input.hasOwnProperty('sassVariableOverrides');
  106. }