dev-config.ts 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. /* eslint-disable no-console */
  2. import { AdminUiPlugin } from '@vendure/admin-ui-plugin';
  3. import { AssetServerPlugin } from '@vendure/asset-server-plugin';
  4. import { ADMIN_API_PATH, API_PORT, SHOP_API_PATH } from '@vendure/common/lib/shared-constants';
  5. import {
  6. Asset,
  7. DefaultJobQueuePlugin,
  8. DefaultLogger,
  9. DefaultSearchPlugin,
  10. dummyPaymentHandler,
  11. LanguageCode,
  12. LogLevel,
  13. VendureConfig,
  14. } from '@vendure/core';
  15. import { ElasticsearchPlugin } from '@vendure/elasticsearch-plugin';
  16. import { defaultEmailHandlers, EmailPlugin } from '@vendure/email-plugin';
  17. import { BullMQJobQueuePlugin } from '@vendure/job-queue-plugin/package/bullmq';
  18. import 'dotenv/config';
  19. import { compileUiExtensions } from '@vendure/ui-devkit/compiler';
  20. import path from 'path';
  21. import { DataSourceOptions } from 'typeorm';
  22. import { MultivendorPlugin } from './test-plugins/multivendor-plugin/multivendor.plugin';
  23. /**
  24. * Config settings used during development
  25. */
  26. export const devConfig: VendureConfig = {
  27. apiOptions: {
  28. port: API_PORT,
  29. adminApiPath: ADMIN_API_PATH,
  30. adminApiPlayground: {
  31. settings: {
  32. 'request.credentials': 'include',
  33. } as any,
  34. },
  35. adminApiDebug: true,
  36. shopApiPath: SHOP_API_PATH,
  37. shopApiPlayground: {
  38. settings: {
  39. 'request.credentials': 'include',
  40. } as any,
  41. },
  42. shopApiDebug: true,
  43. },
  44. authOptions: {
  45. disableAuth: false,
  46. tokenMethod: ['bearer', 'cookie'] as const,
  47. requireVerification: true,
  48. customPermissions: [],
  49. cookieOptions: {
  50. secret: 'abc',
  51. },
  52. },
  53. dbConnectionOptions: {
  54. synchronize: false,
  55. logging: false,
  56. migrations: [path.join(__dirname, 'migrations/*.ts')],
  57. ...getDbConfig(),
  58. },
  59. paymentOptions: {
  60. paymentMethodHandlers: [dummyPaymentHandler],
  61. },
  62. customFields: {
  63. Product: [
  64. {
  65. name: 'searchKeywords',
  66. label: [{ languageCode: LanguageCode.en, value: 'Search keywords' }],
  67. type: 'string',
  68. defaultValue: '',
  69. public: false,
  70. },
  71. {
  72. name: 'noIndex',
  73. label: [{ languageCode: LanguageCode.en, value: 'Do not allow crawlers to index' }],
  74. type: 'boolean',
  75. defaultValue: false,
  76. public: true,
  77. ui: { tab: 'SEO' },
  78. },
  79. ],
  80. ProductVariant: [
  81. {
  82. name: 'weight',
  83. type: 'int',
  84. defaultValue: 0,
  85. nullable: false,
  86. min: 0,
  87. step: 1,
  88. public: true,
  89. label: [{ languageCode: LanguageCode.en, value: 'Weight' }],
  90. ui: { component: 'number-form-input', suffix: 'g' },
  91. },
  92. {
  93. name: 'gtin',
  94. type: 'string',
  95. nullable: true,
  96. public: true,
  97. label: [{ languageCode: LanguageCode.en, value: 'GTIN (barcode)' }],
  98. },
  99. ],
  100. },
  101. /* customFields: {
  102. ProductVariant: [
  103. {
  104. name: 'weight',
  105. type: 'int',
  106. defaultValue: 0,
  107. nullable: false,
  108. min: 0,
  109. step: 1,
  110. public: true,
  111. label: [{ languageCode: LanguageCode.en, value: 'Weight' }],
  112. ui: { component: 'number-form-input', suffix: 'g' },
  113. },
  114. {
  115. name: 'rrp',
  116. type: 'int',
  117. nullable: true,
  118. min: 0,
  119. step: 1,
  120. public: true,
  121. label: [{ languageCode: LanguageCode.en, value: 'RRP' }],
  122. ui: { component: 'currency-form-input' },
  123. },
  124. {
  125. name: 'gtin',
  126. type: 'string',
  127. nullable: true,
  128. public: true,
  129. label: [{ languageCode: LanguageCode.en, value: 'GTIN (barcode)' }],
  130. },
  131. {
  132. name: 'additionalInformation',
  133. type: 'text',
  134. nullable: true,
  135. public: true,
  136. label: [{ languageCode: LanguageCode.en, value: 'Additional Information' }],
  137. ui: { component: 'json-editor-form-input' },
  138. },
  139. ],
  140. Product: [
  141. {
  142. name: 'searchKeywords',
  143. label: [{ languageCode: LanguageCode.en, value: 'Search keywords' }],
  144. type: 'string',
  145. defaultValue: '',
  146. public: false,
  147. },
  148. {
  149. name: 'pageType',
  150. label: [{ languageCode: LanguageCode.en, value: 'Page type' }],
  151. type: 'string',
  152. defaultValue: 'default',
  153. public: true,
  154. options: [
  155. { value: 'default', label: [{ languageCode: LanguageCode.en, value: 'Default' }] },
  156. {
  157. value: 'colour-chart',
  158. label: [{ languageCode: LanguageCode.en, value: 'Colour chart' }],
  159. },
  160. {
  161. value: 'select-menu',
  162. label: [{ languageCode: LanguageCode.en, value: 'Select menu' }],
  163. },
  164. { value: 'gift-card', label: [{ languageCode: LanguageCode.en, value: 'Gift card' }] },
  165. ],
  166. ui: { tab: 'Display' },
  167. },
  168. {
  169. name: 'keyFeatures',
  170. label: [{ languageCode: LanguageCode.en, value: 'Key features' }],
  171. type: 'text',
  172. public: true,
  173. nullable: true,
  174. ui: { component: 'rich-text-form-input' },
  175. },
  176. {
  177. name: 'videoUrls',
  178. label: [{ languageCode: LanguageCode.en, value: 'Video urls' }],
  179. type: 'string',
  180. list: true,
  181. public: true,
  182. nullable: false,
  183. defaultValue: [],
  184. },
  185. {
  186. name: 'variantOrdering',
  187. label: [{ languageCode: LanguageCode.en, value: 'Variant ordering' }],
  188. type: 'string',
  189. defaultValue: 'default',
  190. public: true,
  191. options: [
  192. { value: 'default', label: [{ languageCode: LanguageCode.en, value: 'Default' }] },
  193. {
  194. value: 'alphabetical',
  195. label: [{ languageCode: LanguageCode.en, value: 'Alphabetical' }],
  196. },
  197. {
  198. value: 'brush-size',
  199. label: [{ languageCode: LanguageCode.en, value: 'Brush size (000, 00, 0, 1, ...)' }],
  200. },
  201. {
  202. value: 'dimension',
  203. label: [
  204. { languageCode: LanguageCode.en, value: 'Dimension (5" x 5", 10" x 12",...)' },
  205. ],
  206. },
  207. ],
  208. ui: { tab: 'Display' },
  209. },
  210. {
  211. name: 'seoTitle',
  212. type: 'localeString',
  213. public: true,
  214. label: [{ languageCode: LanguageCode.en, value: 'SEO Title' }],
  215. nullable: true,
  216. ui: { tab: 'SEO' },
  217. },
  218. {
  219. name: 'seoDescription',
  220. type: 'localeString',
  221. public: true,
  222. label: [{ languageCode: LanguageCode.en, value: 'SEO Description' }],
  223. nullable: true,
  224. ui: { tab: 'SEO', component: 'textarea-form-input' },
  225. },
  226. {
  227. name: 'seoImage',
  228. type: 'relation',
  229. entity: Asset,
  230. public: true,
  231. label: [{ languageCode: LanguageCode.en, value: 'SEO Image' }],
  232. nullable: true,
  233. ui: { tab: 'SEO' },
  234. },
  235. {
  236. name: 'boost',
  237. type: 'int',
  238. public: true,
  239. defaultValue: 0,
  240. min: 0,
  241. max: 5,
  242. label: [{ languageCode: LanguageCode.en, value: 'Boost in list pages' }],
  243. nullable: true,
  244. },
  245. {
  246. name: 'minimumOrderQuantity',
  247. type: 'int',
  248. public: true,
  249. min: 0,
  250. label: [{ languageCode: LanguageCode.en, value: 'Minimum order quantity' }],
  251. description: [
  252. {
  253. languageCode: LanguageCode.en,
  254. value: 'If set, the customer must order at least this number of any variants of this product',
  255. },
  256. ],
  257. nullable: true,
  258. },
  259. ],
  260. Collection: [
  261. {
  262. name: 'excludeFromNavMenu',
  263. label: [{ languageCode: LanguageCode.en, value: 'Exclude from nav menu' }],
  264. type: 'boolean',
  265. defaultValue: false,
  266. public: true,
  267. },
  268. {
  269. name: 'excludeFromSubCollections',
  270. label: [{ languageCode: LanguageCode.en, value: 'Exclude from sub collections' }],
  271. type: 'boolean',
  272. defaultValue: false,
  273. public: true,
  274. },
  275. {
  276. name: 'noIndex',
  277. label: [{ languageCode: LanguageCode.en, value: 'Do not allow crawlers to index' }],
  278. type: 'boolean',
  279. defaultValue: false,
  280. public: true,
  281. ui: { tab: 'SEO' },
  282. },
  283. {
  284. name: 'searchKeywords',
  285. label: [{ languageCode: LanguageCode.en, value: 'Search keywords' }],
  286. type: 'string',
  287. defaultValue: '',
  288. public: false,
  289. },
  290. {
  291. name: 'layout',
  292. type: 'string',
  293. public: true,
  294. nullable: false,
  295. defaultValue: 'fullWidth',
  296. label: [{ languageCode: LanguageCode.en, value: 'Layout mode' }],
  297. options: [
  298. { value: 'default', label: [{ languageCode: LanguageCode.en, value: 'Default' }] },
  299. { value: 'fullWidth', label: [{ languageCode: LanguageCode.en, value: 'Full width' }] },
  300. ],
  301. },
  302. {
  303. name: 'seoTitle',
  304. type: 'localeString',
  305. public: true,
  306. label: [{ languageCode: LanguageCode.en, value: 'SEO Meta Title' }],
  307. nullable: true,
  308. ui: { tab: 'SEO' },
  309. },
  310. {
  311. name: 'seoDescription',
  312. type: 'localeString',
  313. public: true,
  314. label: [{ languageCode: LanguageCode.en, value: 'SEO Meta Description' }],
  315. nullable: true,
  316. ui: { tab: 'SEO', component: 'textarea-form-input' },
  317. },
  318. {
  319. name: 'seoImage',
  320. type: 'relation',
  321. entity: Asset,
  322. public: true,
  323. label: [{ languageCode: LanguageCode.en, value: 'SEO Meta Image' }],
  324. nullable: true,
  325. ui: { tab: 'SEO' },
  326. },
  327. {
  328. name: 'extendedDescription',
  329. type: 'text',
  330. public: true,
  331. label: [{ languageCode: LanguageCode.en, value: 'Extended description' }],
  332. nullable: true,
  333. ui: { tab: 'SEO', component: 'rich-text-form-input' },
  334. },
  335. {
  336. name: 'isOfferCollection',
  337. type: 'boolean',
  338. public: true,
  339. label: [{ languageCode: LanguageCode.en, value: 'Is offer collecion' }],
  340. nullable: true,
  341. defaultValue: false,
  342. ui: { tab: 'Offers' },
  343. },
  344. {
  345. name: 'offerName',
  346. type: 'string',
  347. public: true,
  348. label: [{ languageCode: LanguageCode.en, value: 'Offer name' }],
  349. nullable: true,
  350. ui: { tab: 'Offers' },
  351. },
  352. {
  353. name: 'offerDescription',
  354. type: 'string',
  355. public: true,
  356. label: [{ languageCode: LanguageCode.en, value: 'Offer description' }],
  357. nullable: true,
  358. ui: { tab: 'Offers', component: 'rich-text-form-input' },
  359. },
  360. {
  361. name: 'displayRrpDiscount',
  362. type: 'boolean',
  363. public: true,
  364. label: [{ languageCode: LanguageCode.en, value: 'Display RRP discount' }],
  365. description: [
  366. {
  367. languageCode: LanguageCode.en,
  368. value: 'When enabled, the RRP discount of included products will be displayed in the storefront',
  369. },
  370. ],
  371. nullable: true,
  372. ui: { tab: 'Offers' },
  373. },
  374. ],
  375. }, */
  376. logger: new DefaultLogger({ level: LogLevel.Verbose }),
  377. importExportOptions: {
  378. importAssetsDir: path.join(__dirname, 'import-assets'),
  379. },
  380. plugins: [
  381. // MultivendorPlugin,
  382. AssetServerPlugin.init({
  383. route: 'assets',
  384. assetUploadDir: path.join(__dirname, 'assets'),
  385. }),
  386. DefaultSearchPlugin.init({ bufferUpdates: false, indexStockStatus: false }),
  387. BullMQJobQueuePlugin.init({}),
  388. // DefaultJobQueuePlugin.init({}),
  389. // JobQueueTestPlugin.init({ queueCount: 10 }),
  390. // ElasticsearchPlugin.init({
  391. // host: 'http://localhost',
  392. // port: 9200,
  393. // bufferUpdates: true,
  394. // }),
  395. EmailPlugin.init({
  396. devMode: true,
  397. route: 'mailbox',
  398. handlers: defaultEmailHandlers,
  399. templatePath: path.join(__dirname, '../email-plugin/templates'),
  400. outputPath: path.join(__dirname, 'test-emails'),
  401. globalTemplateVars: {
  402. verifyEmailAddressUrl: 'http://localhost:4201/verify',
  403. passwordResetUrl: 'http://localhost:4201/reset-password',
  404. changeEmailAddressUrl: 'http://localhost:4201/change-email-address',
  405. },
  406. }),
  407. AdminUiPlugin.init({
  408. route: 'admin',
  409. port: 5001,
  410. // Un-comment to compile a custom admin ui
  411. // app: compileUiExtensions({
  412. // outputPath: path.join(__dirname, './custom-admin-ui'),
  413. // extensions: [
  414. // {
  415. // id: 'test-ui-extension',
  416. // extensionPath: path.join(__dirname, 'test-plugins/with-ui-extension/ui'),
  417. // ngModules: [
  418. // {
  419. // type: 'lazy',
  420. // route: 'greetz',
  421. // ngModuleFileName: 'greeter.module.ts',
  422. // ngModuleName: 'GreeterModule',
  423. // },
  424. // {
  425. // type: 'shared',
  426. // ngModuleFileName: 'greeter-shared.module.ts',
  427. // ngModuleName: 'GreeterSharedModule',
  428. // },
  429. // ],
  430. // },
  431. // {
  432. // globalStyles: path.join(
  433. // __dirname,
  434. // 'test-plugins/with-ui-extension/ui/custom-theme.scss',
  435. // ),
  436. // },
  437. // {
  438. // id: 'external-ui-extension',
  439. // extensionPath: path.join(__dirname, 'test-plugins/with-external-ui-extension'),
  440. // ngModules: [
  441. // {
  442. // type: 'lazy',
  443. // route: 'greet',
  444. // ngModuleFileName: 'external-ui-extension.ts',
  445. // ngModuleName: 'ExternalUiExtensionModule',
  446. // },
  447. // ],
  448. // staticAssets: [
  449. // {
  450. // path: path.join(__dirname, 'test-plugins/with-external-ui-extension/app'),
  451. // rename: 'external-app',
  452. // },
  453. // ],
  454. // },
  455. // ],
  456. // devMode: true,
  457. // }),
  458. }),
  459. ],
  460. };
  461. function getDbConfig(): DataSourceOptions {
  462. const dbType = process.env.DB || 'mysql';
  463. switch (dbType) {
  464. case 'postgres':
  465. console.log('Using postgres connection');
  466. return {
  467. synchronize: false,
  468. type: 'postgres',
  469. host: process.env.DB_HOST || 'localhost',
  470. port: Number(process.env.DB_PORT) || 5432,
  471. username: process.env.DB_USERNAME || 'postgres',
  472. password: process.env.DB_PASSWORD || 'postgres',
  473. database: process.env.DB_NAME || 'vendure',
  474. schema: process.env.DB_SCHEMA || 'public',
  475. };
  476. case 'sqlite':
  477. console.log('Using sqlite connection');
  478. return {
  479. synchronize: false,
  480. type: 'better-sqlite3',
  481. database: path.join(__dirname, 'vendure.sqlite'),
  482. };
  483. case 'sqljs':
  484. console.log('Using sql.js connection');
  485. return {
  486. type: 'sqljs',
  487. autoSave: true,
  488. database: new Uint8Array([]),
  489. location: path.join(__dirname, 'vendure.sqlite'),
  490. };
  491. case 'mysql':
  492. default:
  493. console.log('Using mysql connection');
  494. return {
  495. synchronize: true,
  496. type: 'mariadb',
  497. host: '127.0.0.1',
  498. port: 3306,
  499. username: 'root',
  500. password: '',
  501. database: 'vendure2-dev',
  502. };
  503. }
  504. }