populate.ts 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import { INestApplicationContext } from '@nestjs/common';
  2. import fs from 'fs-extra';
  3. import path from 'path';
  4. import { lastValueFrom } from 'rxjs';
  5. import { logColored } from './cli-utils';
  6. // tslint:disable:no-console
  7. /**
  8. * @description
  9. * Populates the Vendure server with some initial data and (optionally) product data from
  10. * a supplied CSV file.
  11. *
  12. * @docsCategory import-export
  13. */
  14. export async function populate<T extends INestApplicationContext>(
  15. bootstrapFn: () => Promise<T | undefined>,
  16. initialDataPathOrObject: string | object,
  17. productsCsvPath?: string,
  18. ): Promise<T> {
  19. const app = await bootstrapFn();
  20. if (!app) {
  21. throw new Error('Could not bootstrap the Vendure app');
  22. }
  23. const initialData: import('@vendure/core').InitialData =
  24. typeof initialDataPathOrObject === 'string'
  25. ? require(initialDataPathOrObject)
  26. : initialDataPathOrObject;
  27. await populateInitialData(app, initialData, logColored);
  28. if (productsCsvPath) {
  29. const importResult = await importProductsFromCsv(app, productsCsvPath, initialData.defaultLanguage);
  30. if (importResult.errors && importResult.errors.length) {
  31. const errorFile = path.join(process.cwd(), 'vendure-import-error.log');
  32. console.log(
  33. `${importResult.errors.length} errors encountered when importing product data. See: ${errorFile}`,
  34. );
  35. await fs.writeFile(errorFile, importResult.errors.join('\n'));
  36. }
  37. logColored(`\nImported ${importResult.imported} products`);
  38. await populateCollections(app, initialData, logColored);
  39. }
  40. logColored('\nDone!');
  41. return app;
  42. }
  43. export async function populateInitialData(
  44. app: INestApplicationContext,
  45. initialData: import('@vendure/core').InitialData,
  46. loggingFn?: (message: string) => void,
  47. ) {
  48. const { Populator } = await import('@vendure/core');
  49. const populator = app.get(Populator);
  50. try {
  51. await populator.populateInitialData(initialData);
  52. if (typeof loggingFn === 'function') {
  53. loggingFn(`Populated initial data`);
  54. }
  55. } catch (err) {
  56. console.log(err.message);
  57. }
  58. }
  59. export async function populateCollections(
  60. app: INestApplicationContext,
  61. initialData: import('@vendure/core').InitialData,
  62. loggingFn?: (message: string) => void,
  63. ) {
  64. const { Populator } = await import('@vendure/core');
  65. const populator = app.get(Populator);
  66. try {
  67. if (initialData.collections.length) {
  68. await populator.populateCollections(initialData);
  69. if (typeof loggingFn === 'function') {
  70. loggingFn(`Created ${initialData.collections.length} Collections`);
  71. }
  72. }
  73. } catch (err) {
  74. console.log(err.message);
  75. }
  76. }
  77. export async function importProductsFromCsv(
  78. app: INestApplicationContext,
  79. productsCsvPath: string,
  80. languageCode: import('@vendure/core').LanguageCode,
  81. ): Promise<import('@vendure/core').ImportProgress> {
  82. const { Importer } = await import('@vendure/core');
  83. const importer = app.get(Importer);
  84. const productData = await fs.readFile(productsCsvPath, 'utf-8');
  85. return lastValueFrom(importer.parseAndImport(productData, languageCode, true));
  86. }