Procházet zdrojové kódy

feat(server): Populate country & tax data via CLI

Michael Bromley před 7 roky
rodič
revize
ebf402d700

+ 4 - 63
server/cli/assets/index.hbs

@@ -1,66 +1,7 @@
-{{#if isTs }}import{{ else }}const{{/if}} {
-    bootstrap,
-    fakePalPaymentHandler,
-    gripePaymentHandler,
-    defaultEmailTypes,
-    HandlebarsMjmlGenerator,
-    DefaultAssetServerPlugin,
-} {{#if isTs}}from 'vendure'; {{ else }}= require('vendure');{{/if}}
-{{#if isTs }}
-import * as path from 'path';
-{{ else }}
-const path = require('path');
-{{/if}}
+{{#if isTs }}import { bootstrap } from 'vendure';{{else}}const { import } = require('vendure');{{/if}}
+{{#if isTs }}import { config } from './vendure-config';{{else}}const { config } = require('./vendure-config');{{/if}}
 
-bootstrap({
-    defaultChannelToken: 'default-channel',
-    authOptions: {
-        sessionSecret: '{{ sessionSecret }}',
-    },
-    port: 3000,
-    apiPath: 'api',
-    dbConnectionOptions: {
-        type: '{{ dbType }}',
-        synchronize: true, // turn this off for production
-        logging: false,
-        host: '{{ dbHost }}',
-        port: 3306,
-        username: '{{ dbUserName }}',
-        password: '{{ dbPassword }}',
-        database: '{{ dbName }}',
-    },
-    paymentOptions: {
-        paymentMethodHandlers: [fakePalPaymentHandler, gripePaymentHandler],
-    },
-    customFields: {},
-    emailOptions: {
-        emailTypes: defaultEmailTypes,
-        generator: new HandlebarsMjmlGenerator(path.join(__dirname, 'vendure', 'email', 'templates', 'partials')),
-        transport: {
-            type: 'file',
-            outputPath: path.join(__dirname, 'vendure', 'email', 'test-emails'),
-        },
-    },
-    importExportOptions: {
-        importAssetsDir: path.join(__dirname, 'vendure', 'import-assets'),
-    },
-    plugins: [
-        new DefaultAssetServerPlugin({
-            route: 'assets',
-            assetUploadDir: path.join(__dirname, 'vendure', 'assets'),
-            port: 4000,
-            hostname: 'http://localhost',
-            previewMaxHeight: 1600,
-            previewMaxWidth: 1600,
-            presets: [
-                { name: 'tiny', width: 50, height: 50, mode: 'crop' },
-                { name: 'thumb', width: 150, height: 150, mode: 'crop' },
-                { name: 'small', width: 300, height: 300, mode: 'resize' },
-                { name: 'medium', width: 500, height: 500, mode: 'resize' },
-                { name: 'large', width: 800, height: 800, mode: 'resize' },
-            ],
-        }),
-    ],
-}).catch(err => {
+bootstrap(config).catch(err => {
+    // tslint:disable-next-line:no-console
     console.log(err);
 });

+ 1250 - 0
server/cli/assets/initial-data.json

@@ -0,0 +1,1250 @@
+{
+    "defaultLanguage": "en",
+    "taxRates": [
+        { "name": "Standard Tax", "percentage": 20 },
+        { "name": "Reduced Tax", "percentage": 10 },
+        { "name": "Zero Tax", "percentage": 0 }
+    ],
+    "countries": [
+        {
+            "name": "Afghanistan",
+            "code": "AF",
+            "zone": "Asia"
+        },
+        {
+            "name": "Åland Islands",
+            "code": "AX",
+            "zone": "Europe"
+        },
+        {
+            "name": "Albania",
+            "code": "AL",
+            "zone": "Europe"
+        },
+        {
+            "name": "Algeria",
+            "code": "DZ",
+            "zone": "Africa"
+        },
+        {
+            "name": "American Samoa",
+            "code": "AS",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Andorra",
+            "code": "AD",
+            "zone": "Europe"
+        },
+        {
+            "name": "Angola",
+            "code": "AO",
+            "zone": "Africa"
+        },
+        {
+            "name": "Anguilla",
+            "code": "AI",
+            "zone": "Americas"
+        },
+        {
+            "name": "Antigua and Barbuda",
+            "code": "AG",
+            "zone": "Americas"
+        },
+        {
+            "name": "Argentina",
+            "code": "AR",
+            "zone": "Americas"
+        },
+        {
+            "name": "Armenia",
+            "code": "AM",
+            "zone": "Asia"
+        },
+        {
+            "name": "Aruba",
+            "code": "AW",
+            "zone": "Americas"
+        },
+        {
+            "name": "Australia",
+            "code": "AU",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Austria",
+            "code": "AT",
+            "zone": "Europe"
+        },
+        {
+            "name": "Azerbaijan",
+            "code": "AZ",
+            "zone": "Asia"
+        },
+        {
+            "name": "Bahamas",
+            "code": "BS",
+            "zone": "Americas"
+        },
+        {
+            "name": "Bahrain",
+            "code": "BH",
+            "zone": "Asia"
+        },
+        {
+            "name": "Bangladesh",
+            "code": "BD",
+            "zone": "Asia"
+        },
+        {
+            "name": "Barbados",
+            "code": "BB",
+            "zone": "Americas"
+        },
+        {
+            "name": "Belarus",
+            "code": "BY",
+            "zone": "Europe"
+        },
+        {
+            "name": "Belgium",
+            "code": "BE",
+            "zone": "Europe"
+        },
+        {
+            "name": "Belize",
+            "code": "BZ",
+            "zone": "Americas"
+        },
+        {
+            "name": "Benin",
+            "code": "BJ",
+            "zone": "Africa"
+        },
+        {
+            "name": "Bermuda",
+            "code": "BM",
+            "zone": "Americas"
+        },
+        {
+            "name": "Bhutan",
+            "code": "BT",
+            "zone": "Asia"
+        },
+        {
+            "name": "Bolivia (Plurinational State of)",
+            "code": "BO",
+            "zone": "Americas"
+        },
+        {
+            "name": "Bonaire, Sint Eustatius and Saba",
+            "code": "BQ",
+            "zone": "Americas"
+        },
+        {
+            "name": "Bosnia and Herzegovina",
+            "code": "BA",
+            "zone": "Europe"
+        },
+        {
+            "name": "Botswana",
+            "code": "BW",
+            "zone": "Africa"
+        },
+        {
+            "name": "Bouvet Island",
+            "code": "BV",
+            "zone": "Americas"
+        },
+        {
+            "name": "Brazil",
+            "code": "BR",
+            "zone": "Americas"
+        },
+        {
+            "name": "British Indian Ocean Territory",
+            "code": "IO",
+            "zone": "Africa"
+        },
+        {
+            "name": "Brunei Darussalam",
+            "code": "BN",
+            "zone": "Asia"
+        },
+        {
+            "name": "Bulgaria",
+            "code": "BG",
+            "zone": "Europe"
+        },
+        {
+            "name": "Burkina Faso",
+            "code": "BF",
+            "zone": "Africa"
+        },
+        {
+            "name": "Burundi",
+            "code": "BI",
+            "zone": "Africa"
+        },
+        {
+            "name": "Cabo Verde",
+            "code": "CV",
+            "zone": "Africa"
+        },
+        {
+            "name": "Cambodia",
+            "code": "KH",
+            "zone": "Asia"
+        },
+        {
+            "name": "Cameroon",
+            "code": "CM",
+            "zone": "Africa"
+        },
+        {
+            "name": "Canada",
+            "code": "CA",
+            "zone": "Americas"
+        },
+        {
+            "name": "Cayman Islands",
+            "code": "KY",
+            "zone": "Americas"
+        },
+        {
+            "name": "Central African Republic",
+            "code": "CF",
+            "zone": "Africa"
+        },
+        {
+            "name": "Chad",
+            "code": "TD",
+            "zone": "Africa"
+        },
+        {
+            "name": "Chile",
+            "code": "CL",
+            "zone": "Americas"
+        },
+        {
+            "name": "China",
+            "code": "CN",
+            "zone": "Asia"
+        },
+        {
+            "name": "Christmas Island",
+            "code": "CX",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Cocos (Keeling) Islands",
+            "code": "CC",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Colombia",
+            "code": "CO",
+            "zone": "Americas"
+        },
+        {
+            "name": "Comoros",
+            "code": "KM",
+            "zone": "Africa"
+        },
+        {
+            "name": "Congo",
+            "code": "CG",
+            "zone": "Africa"
+        },
+        {
+            "name": "Congo (Democratic Republic of the)",
+            "code": "CD",
+            "zone": "Africa"
+        },
+        {
+            "name": "Cook Islands",
+            "code": "CK",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Costa Rica",
+            "code": "CR",
+            "zone": "Americas"
+        },
+        {
+            "name": "Côte d'Ivoire",
+            "code": "CI",
+            "zone": "Africa"
+        },
+        {
+            "name": "Croatia",
+            "code": "HR",
+            "zone": "Europe"
+        },
+        {
+            "name": "Cuba",
+            "code": "CU",
+            "zone": "Americas"
+        },
+        {
+            "name": "Curaçao",
+            "code": "CW",
+            "zone": "Americas"
+        },
+        {
+            "name": "Cyprus",
+            "code": "CY",
+            "zone": "Asia"
+        },
+        {
+            "name": "Czechia",
+            "code": "CZ",
+            "zone": "Europe"
+        },
+        {
+            "name": "Denmark",
+            "code": "DK",
+            "zone": "Europe"
+        },
+        {
+            "name": "Djibouti",
+            "code": "DJ",
+            "zone": "Africa"
+        },
+        {
+            "name": "Dominica",
+            "code": "DM",
+            "zone": "Americas"
+        },
+        {
+            "name": "Dominican Republic",
+            "code": "DO",
+            "zone": "Americas"
+        },
+        {
+            "name": "Ecuador",
+            "code": "EC",
+            "zone": "Americas"
+        },
+        {
+            "name": "Egypt",
+            "code": "EG",
+            "zone": "Africa"
+        },
+        {
+            "name": "El Salvador",
+            "code": "SV",
+            "zone": "Americas"
+        },
+        {
+            "name": "Equatorial Guinea",
+            "code": "GQ",
+            "zone": "Africa"
+        },
+        {
+            "name": "Eritrea",
+            "code": "ER",
+            "zone": "Africa"
+        },
+        {
+            "name": "Estonia",
+            "code": "EE",
+            "zone": "Europe"
+        },
+        {
+            "name": "Eswatini",
+            "code": "SZ",
+            "zone": "Africa"
+        },
+        {
+            "name": "Ethiopia",
+            "code": "ET",
+            "zone": "Africa"
+        },
+        {
+            "name": "Falkland Islands (Malvinas)",
+            "code": "FK",
+            "zone": "Americas"
+        },
+        {
+            "name": "Faroe Islands",
+            "code": "FO",
+            "zone": "Europe"
+        },
+        {
+            "name": "Fiji",
+            "code": "FJ",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Finland",
+            "code": "FI",
+            "zone": "Europe"
+        },
+        {
+            "name": "France",
+            "code": "FR",
+            "zone": "Europe"
+        },
+        {
+            "name": "French Guiana",
+            "code": "GF",
+            "zone": "Americas"
+        },
+        {
+            "name": "French Polynesia",
+            "code": "PF",
+            "zone": "Oceania"
+        },
+        {
+            "name": "French Southern Territories",
+            "code": "TF",
+            "zone": "Africa"
+        },
+        {
+            "name": "Gabon",
+            "code": "GA",
+            "zone": "Africa"
+        },
+        {
+            "name": "Gambia",
+            "code": "GM",
+            "zone": "Africa"
+        },
+        {
+            "name": "Georgia",
+            "code": "GE",
+            "zone": "Asia"
+        },
+        {
+            "name": "Germany",
+            "code": "DE",
+            "zone": "Europe"
+        },
+        {
+            "name": "Ghana",
+            "code": "GH",
+            "zone": "Africa"
+        },
+        {
+            "name": "Gibraltar",
+            "code": "GI",
+            "zone": "Europe"
+        },
+        {
+            "name": "Greece",
+            "code": "GR",
+            "zone": "Europe"
+        },
+        {
+            "name": "Greenland",
+            "code": "GL",
+            "zone": "Americas"
+        },
+        {
+            "name": "Grenada",
+            "code": "GD",
+            "zone": "Americas"
+        },
+        {
+            "name": "Guadeloupe",
+            "code": "GP",
+            "zone": "Americas"
+        },
+        {
+            "name": "Guam",
+            "code": "GU",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Guatemala",
+            "code": "GT",
+            "zone": "Americas"
+        },
+        {
+            "name": "Guernsey",
+            "code": "GG",
+            "zone": "Europe"
+        },
+        {
+            "name": "Guinea",
+            "code": "GN",
+            "zone": "Africa"
+        },
+        {
+            "name": "Guinea-Bissau",
+            "code": "GW",
+            "zone": "Africa"
+        },
+        {
+            "name": "Guyana",
+            "code": "GY",
+            "zone": "Americas"
+        },
+        {
+            "name": "Haiti",
+            "code": "HT",
+            "zone": "Americas"
+        },
+        {
+            "name": "Heard Island and McDonald Islands",
+            "code": "HM",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Holy See",
+            "code": "VA",
+            "zone": "Europe"
+        },
+        {
+            "name": "Honduras",
+            "code": "HN",
+            "zone": "Americas"
+        },
+        {
+            "name": "Hong Kong",
+            "code": "HK",
+            "zone": "Asia"
+        },
+        {
+            "name": "Hungary",
+            "code": "HU",
+            "zone": "Europe"
+        },
+        {
+            "name": "Iceland",
+            "code": "IS",
+            "zone": "Europe"
+        },
+        {
+            "name": "India",
+            "code": "IN",
+            "zone": "Asia"
+        },
+        {
+            "name": "Indonesia",
+            "code": "ID",
+            "zone": "Asia"
+        },
+        {
+            "name": "Iran (Islamic Republic of)",
+            "code": "IR",
+            "zone": "Asia"
+        },
+        {
+            "name": "Iraq",
+            "code": "IQ",
+            "zone": "Asia"
+        },
+        {
+            "name": "Ireland",
+            "code": "IE",
+            "zone": "Europe"
+        },
+        {
+            "name": "Isle of Man",
+            "code": "IM",
+            "zone": "Europe"
+        },
+        {
+            "name": "Israel",
+            "code": "IL",
+            "zone": "Asia"
+        },
+        {
+            "name": "Italy",
+            "code": "IT",
+            "zone": "Europe"
+        },
+        {
+            "name": "Jamaica",
+            "code": "JM",
+            "zone": "Americas"
+        },
+        {
+            "name": "Japan",
+            "code": "JP",
+            "zone": "Asia"
+        },
+        {
+            "name": "Jersey",
+            "code": "JE",
+            "zone": "Europe"
+        },
+        {
+            "name": "Jordan",
+            "code": "JO",
+            "zone": "Asia"
+        },
+        {
+            "name": "Kazakhstan",
+            "code": "KZ",
+            "zone": "Asia"
+        },
+        {
+            "name": "Kenya",
+            "code": "KE",
+            "zone": "Africa"
+        },
+        {
+            "name": "Kiribati",
+            "code": "KI",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Korea (Democratic People's Republic of)",
+            "code": "KP",
+            "zone": "Asia"
+        },
+        {
+            "name": "Korea (Republic of)",
+            "code": "KR",
+            "zone": "Asia"
+        },
+        {
+            "name": "Kuwait",
+            "code": "KW",
+            "zone": "Asia"
+        },
+        {
+            "name": "Kyrgyzstan",
+            "code": "KG",
+            "zone": "Asia"
+        },
+        {
+            "name": "Lao People's Democratic Republic",
+            "code": "LA",
+            "zone": "Asia"
+        },
+        {
+            "name": "Latvia",
+            "code": "LV",
+            "zone": "Europe"
+        },
+        {
+            "name": "Lebanon",
+            "code": "LB",
+            "zone": "Asia"
+        },
+        {
+            "name": "Lesotho",
+            "code": "LS",
+            "zone": "Africa"
+        },
+        {
+            "name": "Liberia",
+            "code": "LR",
+            "zone": "Africa"
+        },
+        {
+            "name": "Libya",
+            "code": "LY",
+            "zone": "Africa"
+        },
+        {
+            "name": "Liechtenstein",
+            "code": "LI",
+            "zone": "Europe"
+        },
+        {
+            "name": "Lithuania",
+            "code": "LT",
+            "zone": "Europe"
+        },
+        {
+            "name": "Luxembourg",
+            "code": "LU",
+            "zone": "Europe"
+        },
+        {
+            "name": "Macao",
+            "code": "MO",
+            "zone": "Asia"
+        },
+        {
+            "name": "Macedonia (the former Yugoslav Republic of)",
+            "code": "MK",
+            "zone": "Europe"
+        },
+        {
+            "name": "Madagascar",
+            "code": "MG",
+            "zone": "Africa"
+        },
+        {
+            "name": "Malawi",
+            "code": "MW",
+            "zone": "Africa"
+        },
+        {
+            "name": "Malaysia",
+            "code": "MY",
+            "zone": "Asia"
+        },
+        {
+            "name": "Maldives",
+            "code": "MV",
+            "zone": "Asia"
+        },
+        {
+            "name": "Mali",
+            "code": "ML",
+            "zone": "Africa"
+        },
+        {
+            "name": "Malta",
+            "code": "MT",
+            "zone": "Europe"
+        },
+        {
+            "name": "Marshall Islands",
+            "code": "MH",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Martinique",
+            "code": "MQ",
+            "zone": "Americas"
+        },
+        {
+            "name": "Mauritania",
+            "code": "MR",
+            "zone": "Africa"
+        },
+        {
+            "name": "Mauritius",
+            "code": "MU",
+            "zone": "Africa"
+        },
+        {
+            "name": "Mayotte",
+            "code": "YT",
+            "zone": "Africa"
+        },
+        {
+            "name": "Mexico",
+            "code": "MX",
+            "zone": "Americas"
+        },
+        {
+            "name": "Micronesia (Federated States of)",
+            "code": "FM",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Moldova (Republic of)",
+            "code": "MD",
+            "zone": "Europe"
+        },
+        {
+            "name": "Monaco",
+            "code": "MC",
+            "zone": "Europe"
+        },
+        {
+            "name": "Mongolia",
+            "code": "MN",
+            "zone": "Asia"
+        },
+        {
+            "name": "Montenegro",
+            "code": "ME",
+            "zone": "Europe"
+        },
+        {
+            "name": "Montserrat",
+            "code": "MS",
+            "zone": "Americas"
+        },
+        {
+            "name": "Morocco",
+            "code": "MA",
+            "zone": "Africa"
+        },
+        {
+            "name": "Mozambique",
+            "code": "MZ",
+            "zone": "Africa"
+        },
+        {
+            "name": "Myanmar",
+            "code": "MM",
+            "zone": "Asia"
+        },
+        {
+            "name": "Namibia",
+            "code": "NA",
+            "zone": "Africa"
+        },
+        {
+            "name": "Nauru",
+            "code": "NR",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Nepal",
+            "code": "NP",
+            "zone": "Asia"
+        },
+        {
+            "name": "Netherlands",
+            "code": "NL",
+            "zone": "Europe"
+        },
+        {
+            "name": "New Caledonia",
+            "code": "NC",
+            "zone": "Oceania"
+        },
+        {
+            "name": "New Zealand",
+            "code": "NZ",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Nicaragua",
+            "code": "NI",
+            "zone": "Americas"
+        },
+        {
+            "name": "Niger",
+            "code": "NE",
+            "zone": "Africa"
+        },
+        {
+            "name": "Nigeria",
+            "code": "NG",
+            "zone": "Africa"
+        },
+        {
+            "name": "Niue",
+            "code": "NU",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Norfolk Island",
+            "code": "NF",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Northern Mariana Islands",
+            "code": "MP",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Norway",
+            "code": "NO",
+            "zone": "Europe"
+        },
+        {
+            "name": "Oman",
+            "code": "OM",
+            "zone": "Asia"
+        },
+        {
+            "name": "Pakistan",
+            "code": "PK",
+            "zone": "Asia"
+        },
+        {
+            "name": "Palau",
+            "code": "PW",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Palestine, State of",
+            "code": "PS",
+            "zone": "Asia"
+        },
+        {
+            "name": "Panama",
+            "code": "PA",
+            "zone": "Americas"
+        },
+        {
+            "name": "Papua New Guinea",
+            "code": "PG",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Paraguay",
+            "code": "PY",
+            "zone": "Americas"
+        },
+        {
+            "name": "Peru",
+            "code": "PE",
+            "zone": "Americas"
+        },
+        {
+            "name": "Philippines",
+            "code": "PH",
+            "zone": "Asia"
+        },
+        {
+            "name": "Pitcairn",
+            "code": "PN",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Poland",
+            "code": "PL",
+            "zone": "Europe"
+        },
+        {
+            "name": "Portugal",
+            "code": "PT",
+            "zone": "Europe"
+        },
+        {
+            "name": "Puerto Rico",
+            "code": "PR",
+            "zone": "Americas"
+        },
+        {
+            "name": "Qatar",
+            "code": "QA",
+            "zone": "Asia"
+        },
+        {
+            "name": "Réunion",
+            "code": "RE",
+            "zone": "Africa"
+        },
+        {
+            "name": "Romania",
+            "code": "RO",
+            "zone": "Europe"
+        },
+        {
+            "name": "Russian Federation",
+            "code": "RU",
+            "zone": "Europe"
+        },
+        {
+            "name": "Rwanda",
+            "code": "RW",
+            "zone": "Africa"
+        },
+        {
+            "name": "Saint Barthélemy",
+            "code": "BL",
+            "zone": "Americas"
+        },
+        {
+            "name": "Saint Helena, Ascension and Tristan da Cunha",
+            "code": "SH",
+            "zone": "Africa"
+        },
+        {
+            "name": "Saint Kitts and Nevis",
+            "code": "KN",
+            "zone": "Americas"
+        },
+        {
+            "name": "Saint Lucia",
+            "code": "LC",
+            "zone": "Americas"
+        },
+        {
+            "name": "Saint Martin (French part)",
+            "code": "MF",
+            "zone": "Americas"
+        },
+        {
+            "name": "Saint Pierre and Miquelon",
+            "code": "PM",
+            "zone": "Americas"
+        },
+        {
+            "name": "Saint Vincent and the Grenadines",
+            "code": "VC",
+            "zone": "Americas"
+        },
+        {
+            "name": "Samoa",
+            "code": "WS",
+            "zone": "Oceania"
+        },
+        {
+            "name": "San Marino",
+            "code": "SM",
+            "zone": "Europe"
+        },
+        {
+            "name": "Sao Tome and Principe",
+            "code": "ST",
+            "zone": "Africa"
+        },
+        {
+            "name": "Saudi Arabia",
+            "code": "SA",
+            "zone": "Asia"
+        },
+        {
+            "name": "Senegal",
+            "code": "SN",
+            "zone": "Africa"
+        },
+        {
+            "name": "Serbia",
+            "code": "RS",
+            "zone": "Europe"
+        },
+        {
+            "name": "Seychelles",
+            "code": "SC",
+            "zone": "Africa"
+        },
+        {
+            "name": "Sierra Leone",
+            "code": "SL",
+            "zone": "Africa"
+        },
+        {
+            "name": "Singapore",
+            "code": "SG",
+            "zone": "Asia"
+        },
+        {
+            "name": "Sint Maarten (Dutch part)",
+            "code": "SX",
+            "zone": "Americas"
+        },
+        {
+            "name": "Slovakia",
+            "code": "SK",
+            "zone": "Europe"
+        },
+        {
+            "name": "Slovenia",
+            "code": "SI",
+            "zone": "Europe"
+        },
+        {
+            "name": "Solomon Islands",
+            "code": "SB",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Somalia",
+            "code": "SO",
+            "zone": "Africa"
+        },
+        {
+            "name": "South Africa",
+            "code": "ZA",
+            "zone": "Africa"
+        },
+        {
+            "name": "South Georgia and the South Sandwich Islands",
+            "code": "GS",
+            "zone": "Americas"
+        },
+        {
+            "name": "South Sudan",
+            "code": "SS",
+            "zone": "Africa"
+        },
+        {
+            "name": "Spain",
+            "code": "ES",
+            "zone": "Europe"
+        },
+        {
+            "name": "Sri Lanka",
+            "code": "LK",
+            "zone": "Asia"
+        },
+        {
+            "name": "Sudan",
+            "code": "SD",
+            "zone": "Africa"
+        },
+        {
+            "name": "Suriname",
+            "code": "SR",
+            "zone": "Americas"
+        },
+        {
+            "name": "Svalbard and Jan Mayen",
+            "code": "SJ",
+            "zone": "Europe"
+        },
+        {
+            "name": "Sweden",
+            "code": "SE",
+            "zone": "Europe"
+        },
+        {
+            "name": "Switzerland",
+            "code": "CH",
+            "zone": "Europe"
+        },
+        {
+            "name": "Syrian Arab Republic",
+            "code": "SY",
+            "zone": "Asia"
+        },
+        {
+            "name": "Taiwan, Province of China",
+            "code": "TW",
+            "zone": "Asia"
+        },
+        {
+            "name": "Tajikistan",
+            "code": "TJ",
+            "zone": "Asia"
+        },
+        {
+            "name": "Tanzania, United Republic of",
+            "code": "TZ",
+            "zone": "Africa"
+        },
+        {
+            "name": "Thailand",
+            "code": "TH",
+            "zone": "Asia"
+        },
+        {
+            "name": "Timor-Leste",
+            "code": "TL",
+            "zone": "Asia"
+        },
+        {
+            "name": "Togo",
+            "code": "TG",
+            "zone": "Africa"
+        },
+        {
+            "name": "Tokelau",
+            "code": "TK",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Tonga",
+            "code": "TO",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Trinidad and Tobago",
+            "code": "TT",
+            "zone": "Americas"
+        },
+        {
+            "name": "Tunisia",
+            "code": "TN",
+            "zone": "Africa"
+        },
+        {
+            "name": "Turkey",
+            "code": "TR",
+            "zone": "Asia"
+        },
+        {
+            "name": "Turkmenistan",
+            "code": "TM",
+            "zone": "Asia"
+        },
+        {
+            "name": "Turks and Caicos Islands",
+            "code": "TC",
+            "zone": "Americas"
+        },
+        {
+            "name": "Tuvalu",
+            "code": "TV",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Uganda",
+            "code": "UG",
+            "zone": "Africa"
+        },
+        {
+            "name": "Ukraine",
+            "code": "UA",
+            "zone": "Europe"
+        },
+        {
+            "name": "United Arab Emirates",
+            "code": "AE",
+            "zone": "Asia"
+        },
+        {
+            "name": "United Kingdom of Great Britain and Northern Ireland",
+            "code": "GB",
+            "zone": "UK"
+        },
+        {
+            "name": "United States of America",
+            "code": "US",
+            "zone": "Americas"
+        },
+        {
+            "name": "United States Minor Outlying Islands",
+            "code": "UM",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Uruguay",
+            "code": "UY",
+            "zone": "Americas"
+        },
+        {
+            "name": "Uzbekistan",
+            "code": "UZ",
+            "zone": "Asia"
+        },
+        {
+            "name": "Vanuatu",
+            "code": "VU",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Venezuela (Bolivarian Republic of)",
+            "code": "VE",
+            "zone": "Americas"
+        },
+        {
+            "name": "Viet Nam",
+            "code": "VN",
+            "zone": "Asia"
+        },
+        {
+            "name": "Virgin Islands (British)",
+            "code": "VG",
+            "zone": "Americas"
+        },
+        {
+            "name": "Virgin Islands (U.S.)",
+            "code": "VI",
+            "zone": "Americas"
+        },
+        {
+            "name": "Wallis and Futuna",
+            "code": "WF",
+            "zone": "Oceania"
+        },
+        {
+            "name": "Western Sahara",
+            "code": "EH",
+            "zone": "Africa"
+        },
+        {
+            "name": "Yemen",
+            "code": "YE",
+            "zone": "Asia"
+        },
+        {
+            "name": "Zambia",
+            "code": "ZM",
+            "zone": "Africa"
+        },
+        {
+            "name": "Zimbabwe",
+            "code": "ZW",
+            "zone": "Africa"
+        }
+    ]
+}

+ 72 - 0
server/cli/assets/vendure-config.hbs

@@ -0,0 +1,72 @@
+{{#if isTs }}import{{ else }}const{{/if}} {
+    fakePalPaymentHandler,
+    gripePaymentHandler,
+    defaultEmailTypes,
+    HandlebarsMjmlGenerator,
+    DefaultAssetServerPlugin,
+    {{#if isTs}}VendureConfig,{{/if}}
+} {{#if isTs}}from 'vendure'; {{ else }}= require('vendure');{{/if}}
+{{#if isTs }}
+import * as path from 'path';
+{{ else }}
+const path = require('path');
+{{/if}}
+
+{{#if isTs}}export {{/if}}const config{{#if isTs}}: VendureConfig{{/if}} = {
+    defaultChannelToken: 'default-channel',
+    authOptions: {
+        sessionSecret: '{{ sessionSecret }}',
+    },
+    port: 3000,
+    apiPath: 'api',
+    dbConnectionOptions: {
+        type: '{{ dbType }}',
+        synchronize: true, // turn this off for production
+        logging: false,
+        database: '{{ dbName }}',
+        {{#if isSQLite}}
+        {{else}}
+        host: '{{ dbHost }}',
+        port: {{ dbPort }},
+        username: '{{ dbUserName }}',
+        password: '{{ dbPassword }}',
+        {{/if}}
+    },
+    paymentOptions: {
+        paymentMethodHandlers: [fakePalPaymentHandler, gripePaymentHandler],
+    },
+    customFields: {},
+    emailOptions: {
+        emailTypes: defaultEmailTypes,
+        generator: new HandlebarsMjmlGenerator(path.join(__dirname, 'vendure', 'email', 'templates', 'partials')),
+        transport: {
+            type: 'file',
+            outputPath: path.join(__dirname, 'vendure', 'email', 'test-emails'),
+        },
+    },
+    importExportOptions: {
+        importAssetsDir: path.join(__dirname, 'vendure', 'import-assets'),
+    },
+    plugins: [
+        new DefaultAssetServerPlugin({
+            route: 'assets',
+            assetUploadDir: path.join(__dirname, 'vendure', 'assets'),
+            port: 4000,
+            hostname: 'http://localhost',
+            previewMaxHeight: 1600,
+            previewMaxWidth: 1600,
+            presets: [
+                { name: 'tiny', width: 50, height: 50, mode: 'crop' },
+                { name: 'thumb', width: 150, height: 150, mode: 'crop' },
+                { name: 'small', width: 300, height: 300, mode: 'resize' },
+                { name: 'medium', width: 500, height: 500, mode: 'resize' },
+                { name: 'large', width: 800, height: 800, mode: 'resize' },
+            ],
+        }),
+    ],
+};
+{{#if isTs}}
+{{else}}
+
+module.exports = { config };
+{{/if}}

+ 7 - 0
server/cli/cli-utils.ts

@@ -0,0 +1,7 @@
+// tslint:disable:no-console
+/**
+ * Logs to the console in a fetching blueish color.
+ */
+export function logColored(message: string) {
+    console.log('\x1b[36m%s\x1b[0m', message);
+}

+ 153 - 0
server/cli/init.ts

@@ -0,0 +1,153 @@
+import * as fs from 'fs-extra';
+import * as Handlebars from 'handlebars';
+import * as path from 'path';
+import { PromptObject } from 'prompts';
+import * as prompts from 'prompts';
+
+// tslint:disable:no-console
+export async function init(): Promise<string> {
+    function defaultPort(_dbType: string) {
+        switch (_dbType) {
+            case 'mysql':
+                return 3306;
+            case 'postgres':
+                return 5432;
+            case 'mssql':
+                return 1433;
+            case 'oracle':
+                return 1521;
+            default:
+                return 3306;
+        }
+    }
+
+    function onSubmit(prompt: PromptObject, answer: any) {
+        if (prompt.name === 'dbType') {
+            dbType = answer;
+        }
+    }
+
+    let dbType: string;
+
+    console.log(`Let's get started with a new Vendure server!\n`);
+
+    const answers = await prompts(
+        [
+            {
+                type: 'select',
+                name: 'dbType',
+                message: 'Which database are you using?',
+                choices: [
+                    { title: 'MySQL / MariaDB', value: 'mysql' },
+                    { title: 'Postgres', value: 'postgres' },
+                    { title: 'SQLite', value: 'sqlite' },
+                    { title: 'MS SQL Server', value: 'mssql' },
+                    { title: 'Oracle', value: 'oracle' },
+                ],
+                initial: 0 as any,
+            },
+            {
+                type: (() => (dbType === 'sqlite' ? null : 'text')) as any,
+                name: 'dbHost',
+                message: `What's the database host address?`,
+                initial: '192.168.99.100',
+            },
+            {
+                type: (() => (dbType === 'sqlite' ? null : 'text')) as any,
+                name: 'dbPort',
+                message: `What port is the database listening on?`,
+                initial: (() => defaultPort(dbType)) as any,
+            },
+            {
+                type: 'text',
+                name: 'dbName',
+                message: () =>
+                    dbType === 'sqlite'
+                        ? `What is the path to the SQLite database file?`
+                        : `What's the name of the database?`,
+                initial: (() =>
+                    dbType === 'sqlite' ? path.join(__dirname, 'vendure.sqlite') : 'vendure') as any,
+            },
+            {
+                type: (() => (dbType === 'sqlite' ? null : 'text')) as any,
+                name: 'dbUserName',
+                message: `What's the database user name?`,
+                initial: 'root',
+            },
+            {
+                type: (() => (dbType === 'sqlite' ? null : 'password')) as any,
+                name: 'dbPassword',
+                message: `What's the database password?`,
+            },
+            {
+                type: 'select',
+                name: 'language',
+                message: 'Which programming language will you be using?',
+                choices: [{ title: 'TypeScript', value: 'ts' }, { title: 'JavaScript', value: 'js' }],
+                initial: 0 as any,
+            },
+        ],
+        {
+            onSubmit,
+            onCancel() {
+                /* */
+            },
+        },
+    );
+
+    if (!answers.language) {
+        console.log('Setup aborted. No changes made');
+        process.exit(0);
+    }
+
+    await createDirectoryStructure();
+    await copyEmailTemplates();
+    return createFilesForBootstrap(answers);
+}
+
+/**
+ * Generate the default directory structure for a new Vendure project
+ */
+async function createDirectoryStructure() {
+    const cwd = process.cwd();
+    await fs.ensureDir(path.join(cwd, 'vendure', 'email', 'test-emails'));
+    await fs.ensureDir(path.join(cwd, 'vendure', 'import-assets'));
+    await fs.ensureDir(path.join(cwd, 'vendure', 'assets'));
+}
+
+/**
+ * Copy the email templates into the app
+ */
+async function copyEmailTemplates() {
+    const templateDir = path.join(__dirname, 'assets', 'email-templates');
+    try {
+        await fs.copy(templateDir, path.join(process.cwd(), 'vendure', 'email', 'templates'));
+    } catch (err) {
+        console.error(`Failed to copy email templates.`);
+    }
+}
+
+/**
+ * Create the server index and config files based on the options specified by the CLI prompts.
+ */
+async function createFilesForBootstrap(answers: any): Promise<string> {
+    const cwd = process.cwd();
+    const filePath = (fileName: string): string => path.join(cwd, `${fileName}.${answers.language}`);
+
+    const templateContext = {
+        ...answers,
+        isTs: answers.language === 'ts',
+        isSQLite: answers.dbType === 'sqlite',
+        sessionSecret: Math.random()
+            .toString(36)
+            .substr(3),
+    };
+    const configTemplate = await fs.readFile(path.join(__dirname, 'assets', 'vendure-config.hbs'), 'utf-8');
+    const configSource = Handlebars.compile(configTemplate)(templateContext);
+    await fs.writeFile(filePath('vendure-config'), configSource);
+    const indexTemplate = await fs.readFile(path.join(__dirname, 'assets', 'index.hbs'), 'utf-8');
+    const indexSource = Handlebars.compile(indexTemplate)(templateContext);
+    await fs.writeFile(filePath('index'), indexSource);
+
+    return filePath('index');
+}

+ 71 - 0
server/cli/populate.ts

@@ -0,0 +1,71 @@
+import { INestApplication } from '@nestjs/common';
+import * as fs from 'fs-extra';
+import * as path from 'path';
+import { Connection } from 'typeorm';
+
+import { logColored } from './cli-utils';
+
+// tslint:disable:no-console
+export async function populate() {
+    logColored('\nPopulating... (this may take a minute or two)\n');
+    const app = await getApplicationRef();
+    if (app) {
+        const { Populator } = require('vendure');
+        const populator = app.get(Populator);
+        const initialData = require('./assets/initial-data.json');
+        await populator.populateInitialData(initialData);
+        logColored('Done!');
+        await app.close();
+        process.exit(0);
+    }
+}
+
+async function getApplicationRef(): Promise<INestApplication | undefined> {
+    const tsConfigFile = path.join(process.cwd(), 'vendure-config.ts');
+    const jsConfigFile = path.join(process.cwd(), 'vendure-config.js');
+    let isTs = false;
+    let configFile: string | undefined;
+    if (fs.existsSync(tsConfigFile)) {
+        configFile = tsConfigFile;
+        isTs = true;
+    } else if (fs.existsSync(jsConfigFile)) {
+        configFile = jsConfigFile;
+    }
+
+    if (!configFile) {
+        console.error(`Could not find a config file`);
+        console.error(`Checked "${tsConfigFile}", "${jsConfigFile}"`);
+        process.exit(1);
+        return;
+    }
+
+    if (isTs) {
+        // we expect ts-node to be available
+        const tsNode = require('ts-node');
+        if (!tsNode) {
+            console.error(`For "populate" to work with TypeScript projects, you must have ts-node installed`);
+            process.exit(1);
+            return;
+        }
+        require('ts-node').register();
+    }
+
+    const index = require(configFile);
+
+    if (!index) {
+        console.error(`Could not read the contents of "${configFile}"`);
+        process.exit(1);
+        return;
+    }
+    if (!index.config) {
+        console.error(`The file "${configFile}" does not export a "config" object`);
+        process.exit(1);
+        return;
+    }
+
+    const config = index.config;
+    const { bootstrap } = require('vendure');
+    console.log('Bootstrapping Vendure server...');
+    const app = await bootstrap(config);
+    return app;
+}

+ 37 - 107
server/cli/vendure-cli.ts

@@ -1,119 +1,49 @@
 #!/usr/bin/env node
-
-import * as fs from 'fs-extra';
-import * as Handlebars from 'handlebars';
-import * as path from 'path';
+import * as program from 'commander';
 import * as prompts from 'prompts';
 
+import { logColored } from './cli-utils';
+import { init } from './init';
+import { populate } from './populate';
+// tslint:disable-next-line:no-var-requires
+const version = require('../../package.json').version;
+
 // tslint:disable:no-console
-console.log(
-    '\x1b[36m%s\x1b[0m',
-    `
+logColored(`
                       _
                      | |
  __   _____ _ __   __| |_   _ _ __ ___
  \\ \\ / / _ \\ '_ \\ / _\` | | | | '__/ _ \\
   \\ V /  __/ | | | (_| | |_| | | |  __/
    \\_/ \\___|_| |_|\\__,_|\\__,_|_|  \\___|
-
-
-                                       `,
-);
-
-console.log(`Let's get started with a new Vendure server!\n`);
-prompts([
-    {
-        type: 'select',
-        name: 'dbType',
-        message: 'Which database are you using?',
-        choices: [
-            { title: 'MySQL / MariaDB', value: 'mysql' },
-            { title: 'Postgres', value: 'postgres' },
-            { title: 'SQLite', value: 'sqlite' },
-            { title: 'MS SQL Server', value: 'mssql' },
-            { title: 'Oracle', value: 'oracle' },
-        ],
-        initial: 0 as any,
-    },
-    {
-        type: 'text',
-        name: 'dbHost',
-        message: `What's the database host address?`,
-        initial: '192.168.99.100',
-    },
-    {
-        type: 'text',
-        name: 'dbName',
-        message: `What's the name of the database?`,
-        initial: 'vendure',
-    },
-    {
-        type: 'text',
-        name: 'dbUserName',
-        message: `What's the database user name?`,
-        initial: 'root',
-    },
-    {
-        type: 'password',
-        name: 'dbPassword',
-        message: `What's the database password?`,
-    },
-    {
-        type: 'select',
-        name: 'language',
-        message: 'Which language will you be using?',
-        choices: [{ title: 'TypeScript', value: 'ts' }, { title: 'JavaScript', value: 'js' }],
-        initial: 0 as any,
-    },
-]).then(
-    async answers => {
-        if (!answers.language) {
-            console.log('Setup aborted. No changes made');
-            process.exit(0);
+                                       `);
+
+program.version(`Vendure CLI v${version}`, '-v --version').name('vendure');
+program
+    .command('init')
+    .description('Initialize a new Vendure server application')
+    .action(async (command: any) => {
+        const indexFile = await init();
+        const answer = await prompts({
+            type: 'toggle',
+            name: 'populate',
+            message: 'Populate the database with some data to get you started (recommended)?',
+            active: 'yes',
+            inactive: 'no',
+            initial: true as any,
+        });
+        if (answer.populate) {
+            await populate();
         }
-        await createDirectoryStructure();
-        await copyEmailTemplates();
-        await createIndexFile(answers);
-        console.log(
-            '\x1b[36m%s\x1b[0m',
-            `\nAll done! You can now execute the index.${answers.language} file to start the server.`,
-        );
-    },
-    err => console.log('error', err),
-);
-
-/**
- * Generate the default directory structure for a new Vendure project
- */
-async function createDirectoryStructure() {
-    const cwd = process.cwd();
-    await fs.ensureDir(path.join(cwd, 'vendure', 'email', 'test-emails'));
-    await fs.ensureDir(path.join(cwd, 'vendure', 'import-assets'));
-    await fs.ensureDir(path.join(cwd, 'vendure', 'assets'));
-}
-
-/**
- * Copy the email templates into the app
- */
-async function copyEmailTemplates() {
-    const templateDir = path.join(__dirname, 'assets', 'email-templates');
-    await fs.copy(templateDir, path.join(process.cwd(), 'vendure', 'email', 'templates'));
-}
-
-/**
- * Create the server index file based on the options specified by the CLI prompts.
- */
-async function createIndexFile(answers: any) {
-    const cwd = process.cwd();
-
-    const templateContext = {
-        ...answers,
-        isTs: answers.language === 'ts',
-        sessionSecret: Math.random()
-            .toString(36)
-            .substr(3),
-    };
-    const template = await fs.readFile(path.join(__dirname, 'assets', 'index.hbs'), 'utf-8');
-    const indexSource = Handlebars.compile(template)(templateContext);
-    await fs.writeFile(path.join(cwd, 'index.' + answers.language), indexSource);
+        logColored(`\nAll done! Run "${indexFile}" to start the server.`);
+    });
+program
+    .command('populate')
+    .description('Populate a new Vendure server instance with some initial data')
+    .action(async () => {
+        await populate();
+    });
+program.parse(process.argv);
+if (!process.argv.slice(2).length) {
+    program.help();
 }

+ 2 - 0
server/package.json

@@ -30,6 +30,7 @@
     "apollo-server-express": "^2.2.2",
     "bcrypt": "^3.0.2",
     "body-parser": "^1.18.3",
+    "commander": "^2.19.0",
     "cookie-session": "^2.0.0-beta.3",
     "csv-parse": "^4.0.1",
     "dateformat": "^3.0.3",
@@ -61,6 +62,7 @@
   },
   "devDependencies": {
     "@types/bcrypt": "^3.0.0",
+    "@types/commander": "^2.12.2",
     "@types/cookie-session": "^2.0.36",
     "@types/csv-parse": "^1.1.11",
     "@types/express": "^4.0.39",

+ 11 - 4
server/yarn.lock

@@ -187,6 +187,13 @@
     "@types/events" "*"
     "@types/node" "*"
 
+"@types/commander@^2.12.2":
+  version "2.12.2"
+  resolved "https://registry.yarnpkg.com/@types/commander/-/commander-2.12.2.tgz#183041a23842d4281478fa5d23c5ca78e6fd08ae"
+  integrity sha512-0QEFiR8ljcHp9bAbWxecjVRuAMr16ivPiGOw6KFQBVrVd0RQIcM3xKdRisH2EDWgVWujiYtHwhSkSUoAAGzH7Q==
+  dependencies:
+    commander "*"
+
 "@types/connect@*":
   version "3.4.32"
   resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.32.tgz#aa0e9616b9435ccad02bc52b5b454ffc2c70ba28"
@@ -1544,14 +1551,14 @@ combined-stream@~1.0.6:
   dependencies:
     delayed-stream "~1.0.0"
 
+commander@*, commander@^2.11.0, commander@^2.15.1, commander@^2.19.0:
+  version "2.19.0"
+  resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
+
 commander@2.17.x, commander@~2.17.1:
   version "2.17.1"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
 
-commander@^2.11.0, commander@^2.15.1, commander@^2.19.0:
-  version "2.19.0"
-  resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
-
 compare-versions@^3.1.0:
   version "3.3.0"
   resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.3.0.tgz#af93ea705a96943f622ab309578b9b90586f39c3"