vendure-cli.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #!/usr/bin/env node
  2. /* eslint-disable @typescript-eslint/no-var-requires */
  3. import { INestApplication } from '@nestjs/common';
  4. import program from 'commander';
  5. import fs from 'fs-extra';
  6. import path from 'path';
  7. import { logColored } from './cli-utils';
  8. import { importProductsFromCsv, populateCollections, populateInitialData } from './populate';
  9. // eslint-disable-next-line @typescript-eslint/no-var-requires
  10. const version = require('../../package.json').version;
  11. /* eslint-disable no-console */
  12. logColored(`
  13. _
  14. | |
  15. __ _____ _ __ __| |_ _ _ __ ___
  16. \\ \\ / / _ \\ '_ \\ / _\` | | | | '__/ _ \\
  17. \\ V / __/ | | | (_| | |_| | | | __/
  18. \\_/ \\___|_| |_|\\__,_|\\__,_|_| \\___|
  19. `);
  20. program.version(`Vendure CLI v${version as string}`, '-v --version').name('vendure');
  21. program
  22. .command('import-products <csvFile>')
  23. .option('-l, --language', 'Specify ISO 639-1 language code, e.g. "de", "es". Defaults to "en"')
  24. .description('Import product data from the specified csv file')
  25. .action(async (csvPath, command) => {
  26. const filePath = path.join(process.cwd(), csvPath);
  27. await importProducts(filePath, command.language);
  28. });
  29. program
  30. .command('init <initDataFile>')
  31. .description('Import initial data from the specified json file')
  32. .action(async (initDataFile, command) => {
  33. const filePath = path.join(process.cwd(), initDataFile);
  34. logColored(`\nPopulating initial data from "${filePath}"...\n`);
  35. const initialData = require(filePath);
  36. const app = await getApplicationRef();
  37. if (app) {
  38. await populateInitialData(app, initialData);
  39. logColored('\nDone!');
  40. await app.close();
  41. }
  42. process.exit(0);
  43. });
  44. program
  45. .command('create-collections <initDataFile>')
  46. .description('Create collections from the specified json file')
  47. .action(async (initDataFile, command) => {
  48. const filePath = path.join(process.cwd(), initDataFile);
  49. logColored(`\nCreating collections from "${filePath}"...\n`);
  50. const initialData = require(filePath);
  51. const app = await getApplicationRef();
  52. if (app) {
  53. await populateCollections(app, initialData);
  54. logColored('\nDone!');
  55. await app.close();
  56. }
  57. process.exit(0);
  58. });
  59. program.parse(process.argv);
  60. if (!process.argv.slice(2).length) {
  61. program.help();
  62. }
  63. async function importProducts(csvPath: string, languageCode: import('@vendure/core').LanguageCode) {
  64. logColored(`\nImporting from "${csvPath}"...\n`);
  65. const app = await getApplicationRef();
  66. if (app) {
  67. await importProductsFromCsv(app, csvPath, languageCode);
  68. logColored('\nDone!');
  69. await app.close();
  70. process.exit(0);
  71. }
  72. }
  73. async function getApplicationRef(): Promise<INestApplication | undefined> {
  74. const tsConfigFile = path.join(process.cwd(), 'vendure-config.ts');
  75. const jsConfigFile = path.join(process.cwd(), 'vendure-config.js');
  76. let isTs = false;
  77. let configFile: string | undefined;
  78. if (fs.existsSync(tsConfigFile)) {
  79. configFile = tsConfigFile;
  80. isTs = true;
  81. } else if (fs.existsSync(jsConfigFile)) {
  82. configFile = jsConfigFile;
  83. }
  84. if (!configFile) {
  85. console.error('Could not find a config file');
  86. console.error(`Checked "${tsConfigFile}", "${jsConfigFile}"`);
  87. process.exit(1);
  88. return;
  89. }
  90. if (isTs) {
  91. // we expect ts-node to be available
  92. const tsNode = require('ts-node');
  93. if (!tsNode) {
  94. console.error('For "populate" to work with TypeScript projects, you must have ts-node installed');
  95. process.exit(1);
  96. return;
  97. }
  98. require('ts-node').register();
  99. }
  100. const index = require(configFile);
  101. if (!index) {
  102. console.error(`Could not read the contents of "${configFile}"`);
  103. process.exit(1);
  104. return;
  105. }
  106. if (!index.config) {
  107. console.error(`The file "${configFile}" does not export a "config" object`);
  108. process.exit(1);
  109. return;
  110. }
  111. const config = index.config;
  112. // Force the sync mode on, so that all the tables are created
  113. // on this initial run.
  114. config.dbConnectionOptions.synchronize = true;
  115. const { bootstrap } = require('@vendure/core');
  116. console.log('Bootstrapping Vendure server...');
  117. const app = await bootstrap(config);
  118. return app;
  119. }