Skip to content

Commit

Permalink
feat(create): Rework folder structure, add build & migration scripts
Browse files Browse the repository at this point in the history
Closes #175
  • Loading branch information
michaelbromley committed Oct 16, 2019
1 parent 8837117 commit 746abff
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 25 deletions.
47 changes: 32 additions & 15 deletions packages/create/src/create-vendure-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,15 @@ async function createApp(

const root = path.resolve(name);
const appName = path.basename(root);
const { dbType, usingTs, configSource, indexSource, indexWorkerSource, populateProducts } = isCi
? await gatherCiUserResponses(root)
: await gatherUserResponses(root);
const {
dbType,
usingTs,
configSource,
indexSource,
indexWorkerSource,
migrationSource,
populateProducts,
} = isCi ? await gatherCiUserResponses(root) : await gatherUserResponses(root);

const useYarn = useNpm ? false : shouldUseYarn();
const originalDirectory = process.cwd();
Expand All @@ -85,9 +91,13 @@ async function createApp(
version: '0.1.0',
private: true,
scripts: {
'run:server': usingTs ? 'ts-node index.ts' : 'node index.js',
'run:worker': usingTs ? 'ts-node index-worker.ts' : 'node index-worker.js',
'run:server': usingTs ? 'ts-node ./src/index.ts' : 'node ./src/index.js',
'run:worker': usingTs ? 'ts-node ./src/index-worker.ts' : 'node ./src/index-worker.js',
start: useYarn ? 'concurrently yarn:run:*' : 'concurrently npm:run:*',
...(usingTs ? { build: 'tsc' } : undefined),
'migration:generate': usingTs ? 'ts-node migration generate' : 'node migration generate',
'migration:run': usingTs ? 'ts-node migration run' : 'node migration run',
'migration:revert': usingTs ? 'ts-node migration revert' : 'node migration revert',
},
};

Expand Down Expand Up @@ -129,22 +139,29 @@ async function createApp(
title: 'Generating app scaffold',
task: ctx => {
return new Observable(subscriber => {
fs.ensureDirSync(path.join(root, 'src'));
const assetPath = (fileName: string) => path.join(__dirname, '../assets', fileName);
const srcPathScript = (fileName: string): string =>
path.join(root, 'src', `${fileName}.${usingTs ? 'ts' : 'js'}`);
const rootPathScript = (fileName: string): string =>
path.join(root, `${fileName}.${usingTs ? 'ts' : 'js'}`);
ctx.configFile = rootPathScript('vendure-config');
ctx.configFile = srcPathScript('vendure-config');

fs.writeFile(ctx.configFile, configSource)
.then(() => {
subscriber.next(`Created config`);
return fs.writeFile(rootPathScript('index'), indexSource);
subscriber.next(`Created config file`);
return fs.writeFile(srcPathScript('index'), indexSource);
})
.then(() => {
subscriber.next(`Created index`);
return fs.writeFile(rootPathScript('index-worker'), indexWorkerSource);
subscriber.next(`Created index file`);
return fs.writeFile(srcPathScript('index-worker'), indexWorkerSource);
})
.then(() => {
subscriber.next(`Created worker`);
subscriber.next(`Created worker file`);
return fs.writeFile(rootPathScript('migration'), migrationSource);
})
.then(() => {
subscriber.next(`Created migration file`);
if (usingTs) {
return fs.copyFile(
assetPath('tsconfig.template.json'),
Expand Down Expand Up @@ -274,9 +291,9 @@ function runPreChecks(name: string | undefined, useNpm: boolean): name is string
* Generate the default directory structure for a new Vendure project
*/
async function createDirectoryStructure(root: string) {
await fs.ensureDir(path.join(root, 'vendure', 'email', 'test-emails'));
await fs.ensureDir(path.join(root, 'vendure', 'import-assets'));
await fs.ensureDir(path.join(root, 'vendure', 'assets'));
await fs.ensureDir(path.join(root, 'static', 'email', 'test-emails'));
await fs.ensureDir(path.join(root, 'static', 'import-assets'));
await fs.ensureDir(path.join(root, 'static', 'assets'));
}

/**
Expand All @@ -285,7 +302,7 @@ async function createDirectoryStructure(root: string) {
async function copyEmailTemplates(root: string) {
const templateDir = path.join(root, 'node_modules/@vendure/email-plugin/templates');
try {
await fs.copy(templateDir, path.join(root, 'vendure', 'email', 'templates'));
await fs.copy(templateDir, path.join(root, 'static', 'email', 'templates'));
} catch (err) {
console.error(chalk.red(`Failed to copy email templates.`));
}
Expand Down
23 changes: 19 additions & 4 deletions packages/create/src/gather-user-responses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,15 @@ export async function gatherUserResponses(root: string): Promise<UserResponses>
process.exit(0);
}

const { indexSource, indexWorkerSource, configSource } = await generateSources(root, answers);
const { indexSource, indexWorkerSource, configSource, migrationSource } = await generateSources(
root,
answers,
);
return {
indexSource,
indexWorkerSource,
configSource,
migrationSource,
usingTs: answers.language === 'ts',
dbType: answers.dbType,
populateProducts: answers.populateProducts,
Expand All @@ -119,11 +123,15 @@ export async function gatherCiUserResponses(root: string): Promise<UserResponses
language: 'ts',
populateProducts: true,
};
const { indexSource, indexWorkerSource, configSource } = await generateSources(root, ciAnswers);
const { indexSource, indexWorkerSource, configSource, migrationSource } = await generateSources(
root,
ciAnswers,
);
return {
indexSource,
indexWorkerSource,
configSource,
migrationSource,
usingTs: ciAnswers.language === 'ts',
dbType: ciAnswers.dbType,
populateProducts: ciAnswers.populateProducts,
Expand All @@ -136,7 +144,12 @@ export async function gatherCiUserResponses(root: string): Promise<UserResponses
async function generateSources(
root: string,
answers: any,
): Promise<{ indexSource: string; indexWorkerSource: string; configSource: string }> {
): Promise<{
indexSource: string;
indexWorkerSource: string;
configSource: string;
migrationSource: string;
}> {
const assetPath = (fileName: string) => path.join(__dirname, '../assets', fileName);

const templateContext = {
Expand All @@ -155,7 +168,9 @@ async function generateSources(
const indexSource = Handlebars.compile(indexTemplate)(templateContext);
const indexWorkerTemplate = await fs.readFile(assetPath('index-worker.hbs'), 'utf-8');
const indexWorkerSource = Handlebars.compile(indexWorkerTemplate)(templateContext);
return { indexSource, indexWorkerSource, configSource };
const migrationTemplate = await fs.readFile(assetPath('migration.hbs'), 'utf-8');
const migrationSource = Handlebars.compile(migrationTemplate)(templateContext);
return { indexSource, indexWorkerSource, configSource, migrationSource };
}

function defaultDBPort(dbType: DbType): number {
Expand Down
1 change: 1 addition & 0 deletions packages/create/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export interface UserResponses {
indexSource: string;
indexWorkerSource: string;
configSource: string;
migrationSource: string;
}

export type CliLogLevel = 'silent' | 'info' | 'verbose';
27 changes: 27 additions & 0 deletions packages/create/templates/migration.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{{#if isTs }}import { generateMigration, revertLastMigration, runMigrations } from '@vendure/core';{{else}}const { generateMigration, revertLastMigration, runMigrations } = require('@vendure/core');{{/if}}
{{#if isTs }}import program from 'commander';{{else}}const program = require('commander');{{/if}}

{{#if isTs }}import { config } from './src/vendure-config';{{else}}const { config } = require('./src/vendure-config');{{/if}}

program
.command('generate <name>')
.description('Generate a new migration file with the given name')
.action(name => {
return generateMigration(config, { name, outputDir: './migrations' });
});

program
.command('run')
.description('Run all pending migrations')
.action(() => {
return runMigrations(config);
});

program
.command('revert')
.description('Revert the last applied migration')
.action(() => {
return revertLastMigration(config);
});

program.parse(process.argv);
2 changes: 1 addition & 1 deletion packages/create/templates/tsconfig.template.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@
"outDir": "./dist",
"baseUrl": "./"
},
"exclude": ["node_modules"]
"exclude": ["node_modules", "migration.ts"]
}
10 changes: 5 additions & 5 deletions packages/create/templates/vendure-config.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const path = require('path');
synchronize: false, // not working with SQLite/SQL.js, see https://github.com/typeorm/typeorm/issues/2576
{{/if}}
logging: false,
database: {{#if isSQLjs}}new Uint8Array([]){{else if isSQLite}}path.join(__dirname, 'vendure.sqlite'){{else}}'{{ dbName }}'{{/if}},
database: {{#if isSQLjs}}new Uint8Array([]){{else if isSQLite}}path.join(__dirname, '../vendure.sqlite'){{else}}'{{ dbName }}'{{/if}},
{{#if isSQLjs}}
location: path.join(__dirname, 'vendure.sqlite'),
autoSave: true,
Expand All @@ -50,7 +50,7 @@ const path = require('path');
username: '{{ dbUserName }}',
password: '{{ dbPassword }}',
{{/if}}
migrations: [path.join(__dirname, 'migrations/*.ts')],
migrations: [path.join(__dirname, '../migrations/*.ts')],
},
paymentOptions: {
paymentMethodHandlers: [examplePaymentHandler],
Expand All @@ -59,16 +59,16 @@ const path = require('path');
plugins: [
AssetServerPlugin.init({
route: 'assets',
assetUploadDir: path.join(__dirname, 'vendure/assets'),
assetUploadDir: path.join(__dirname, '../static/assets'),
port: 3001,
}),
DefaultSearchPlugin,
EmailPlugin.init({
devMode: true,
outputPath: path.join(__dirname, 'vendure/email/test-emails'),
outputPath: path.join(__dirname, '../static/email/test-emails'),
mailboxPort: 3003,
handlers: defaultEmailHandlers,
templatePath: path.join(__dirname, 'vendure/email/templates'),
templatePath: path.join(__dirname, '../static/email/templates'),
globalTemplateVars: {
// The following variables will change depending on your storefront implementation
fromAddress: '"example" <noreply@example.com>',
Expand Down

0 comments on commit 746abff

Please sign in to comment.