Skip to content

Commit 97012e1

Browse files
Merge pull request #302 from DimaNike/mle-ords-backend
feat: mle-ts-ords-backend template #301
2 parents d9fdae3 + 73b4258 commit 97012e1

File tree

20 files changed

+1160
-405
lines changed

20 files changed

+1160
-405
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ The package offers the following templates, some of them connect to the database
5959
- `node-react-todo`: A simple task manager template that uses Node.js and [React](https://react.dev/). It demonstrates the use of the database for Create, Read, Update and Delete (CRUD) operations. It is built by [vite](https://vitejs.dev/).
6060
- `ords-remix-jwt-sample`: A full stack Concert Application made with [Remix](https://remix.run/) that showcases the [Oracle REST Data Services](https://www.oracle.com/database/technologies/appdev/rest.html) functionalities. Some extra configuration is required, learn more about it in the `ords-remix-jwt-sample` [Getting Started Guide](/templates/ords-remix-jwt-sample/README.md#getting-started).
6161
- `mle-ts-sample`: A starter template application that demonstrates how backend applications can be developed using [Oracle Database Multilingual Engine (MLE)](https://docs.oracle.com/en/database/oracle/oracle-database/23/mlejs/introduction-to-mle.html). Requires SQLcl to be installed, for more information please read [README](/templates/mle-ts-sample/README.md)
62+
- `mle-ts-ords-backend`: A starter template application that demonstrates how to expose MLE-based backend logic as RESTful endpoints using [Oracle REST Data Services](https://docs.oracle.com/en/database/oracle/oracle-rest-data-services/) (ORDS). This template requires both SQLcl and ORDS to be installed. For more information, please refer to the [README](/templates/mle-ts-ords-backend/).
6263

6364
Each of the templates include documentation for you to get started with them, as well as NPM scripts for you to use right after generating the application.
6465

generators/index.ts

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,34 @@ export default class extends Generator {
9292
const { protocol, hostname, port, serviceName } = retrieveConnectionStringDetailsFromORAFile( path.join( walletPath, 'tnsnames.ora' ) );
9393
this.options.connectionString = generateConnectionString( protocol, hostname, port, serviceName );
9494
}
95-
// Copy files that are common to all of the templates.
96-
this.fs.copyTpl(
97-
this.templatePath( this.options.templateChoice ),
98-
this.destinationPath(),
99-
{
100-
appName: this.options.appName
101-
}
102-
);
95+
if(this.options.templateChoice.includes('mle-ts-ords-backend')) {
96+
const files = ['src/todos.ts', 'test/users.test.js', 'utils/db.mjs', 'utils/database/initdb.sql', 'utils/database/cleanup.sql', 'deploy.mjs', 'tsconfig.json',''];
97+
files.forEach(file => {
98+
this.fs.copyTpl(
99+
this.templatePath(`../../templates/mle-ts-sample/${file}`),
100+
this.destinationPath(file),
101+
{
102+
appName: this.options.appName
103+
}
104+
);
105+
});
106+
// Copy files that are common to all of the templates.
107+
this.fs.copyTpl(
108+
this.templatePath( this.options.templateChoice ),
109+
this.destinationPath(),
110+
this.options
111+
);
112+
} else {
113+
// Copy files that are common to all of the templates.
114+
this.fs.copyTpl(
115+
this.templatePath( this.options.templateChoice ),
116+
this.destinationPath(),
117+
{
118+
appName: this.options.appName
119+
}
120+
);
121+
}
122+
103123
this.fs.copy(
104124
this.templatePath(`${ path.dirname( this.options.templateChoice ) }/app/.github`),
105125
this.destinationPath('.github')
@@ -142,7 +162,7 @@ export default class extends Generator {
142162
this.templatePath( `${this.options.templateChoice}/.env.example` ),
143163
this.destinationPath( '.env.example' ),
144164
);
145-
} else if (this.options.templateChoice.includes('mle-ts-sample')) {
165+
} else if (this.options.templateChoice.includes('mle-ts-sample') || this.options.templateChoice.includes('mle-ts-ords-backend')) {
146166
if( 'walletPath' in this.options ) {
147167
this.fs.copyTpl(
148168
this.templatePath( `${this.options.templateChoice}/.env.example.wallet` ),

src/index.ts

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ export default class Generate extends Command {
207207
'template': Flags.string({
208208
char: 't',
209209
description: 'Template to use',
210-
options: ['node-vanilla', 'node-react', 'node-vue', 'node-react-todo', 'node-jet', 'node-angular', 'ords-remix-jwt-sample', 'mle-ts-sample'],
210+
options: ['node-vanilla', 'node-react', 'node-vue', 'node-react-todo', 'node-jet', 'node-angular', 'ords-remix-jwt-sample', 'mle-ts-sample', 'mle-ts-ords-backend'],
211211
multiple: false
212212
}),
213213

@@ -314,6 +314,7 @@ export default class Generate extends Command {
314314
const databaseServiceName = flags['db-service-name'] ?? '';
315315
const databaseUsername = flags['db-username'] ?? '';
316316
const sqlclPath = flags['sqlcl'] ?? '';
317+
const ordsHost = flags['ords-host'] ?? '';
317318

318319
// TODO: Validate and use wallet path
319320
const walletPathDirectory = flags['wallet-path'] ? flags['wallet-path'] : '';
@@ -379,6 +380,11 @@ export default class Generate extends Command {
379380
value: 'mle-ts-sample',
380381
description: 'This creates an empty project with MLE and Oracle database connection starter code.'
381382
},
383+
{
384+
name: 'mle-ts-ords-backend',
385+
value: 'mle-ts-ords-backend',
386+
description: 'Creates a starter project with MLE integration, Oracle Database connectivity, and scaffolded ORDS REST endpoints.'
387+
},
382388
],
383389
pageSize: 10,
384390
default: 'node-vanilla'
@@ -476,8 +482,10 @@ export default class Generate extends Command {
476482

477483
// This will be config object for the basic connection type.
478484
Object.assign(configObject, {
479-
connectionString: generateConnectionString( protocol, hostname, port, serviceValue )
480-
});
485+
connectionString: generateConnectionString( protocol, hostname, port, serviceValue ),
486+
serviceValue: serviceValue,
487+
databasePort: port
488+
});
481489
} else if( databaseConnectionType === 'walletPath' ) {
482490
let walletPath = '';
483491

@@ -509,23 +517,29 @@ export default class Generate extends Command {
509517
// This is the config object that represents the wallet connection type.
510518
Object.assign(configObject, {
511519
walletPath: walletPath,
512-
walletPassword: walletPassword
520+
walletPassword: walletPassword,
521+
serviceValue: "",
522+
databasePort: 8080,
513523
});
514524
}
515525

516-
if(templateChoice !== 'ords-remix-jwt-sample'){
526+
if(templateChoice !== 'ords-remix-jwt-sample') {
517527
// Ask the user for the database connection username.
528+
let databaseUser = databaseUsername === '' ? await input(
529+
{
530+
message: 'What\'s your database username?',
531+
validate ( input ) {
532+
return input.trim().length === 0 ? 'This field cannot be empty!' : true;
533+
}
534+
},
535+
) : databaseUsername;
536+
if (templateChoice === 'mle-ts-ords-backend') {
537+
databaseUser = databaseUser.toLowerCase();
538+
}
518539
Object.assign( configObject, {
519-
connectionUsername: databaseUsername === '' ? await input(
520-
{
521-
message: 'What\'s your database username?',
522-
validate ( input ) {
523-
return input.trim().length === 0 ? 'This field cannot be empty!' : true;
524-
}
525-
},
526-
) : databaseUsername
527-
} );
528-
540+
connectionUsername: databaseUser
541+
});
542+
529543
// Ask the user for the database connection password.
530544
Object.assign( configObject, {
531545
connectionPassword: await password(
@@ -540,7 +554,8 @@ export default class Generate extends Command {
540554
} );
541555
}
542556

543-
if(templateChoice == 'mle-ts-sample'){
557+
if(templateChoice === 'mle-ts-sample' || templateChoice === 'mle-ts-ords-backend')
558+
{
544559
// Ask the user for the path to SQLcl
545560
Object.assign( configObject, {
546561
sqlclPath: sqlclPath === '' ? await input(
@@ -552,6 +567,22 @@ export default class Generate extends Command {
552567
},
553568
) : sqlclPath
554569
});
570+
if (templateChoice === 'mle-ts-ords-backend')
571+
{
572+
let ordsHostURL = ordsHost === '' ? await input(
573+
{
574+
message: 'Please provide ORDS Base URL: ',
575+
validate ( input ) {
576+
return input.trim().length === 0 ? 'This field cannot be empty!' : true;
577+
},
578+
default: 'http://localhost:8080/ords'
579+
},
580+
) : ordsHost;
581+
const normalizedBaseURL = ordsHostURL.replace(/\/+$/, '');
582+
Object.assign( configObject, {
583+
ordsHost: normalizedBaseURL
584+
});
585+
}
555586
}
556587

557588
generateDatabaseApp( configObject );
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Database User
2+
DB_USER=<%= connectionUsername %>
3+
# Database User Password
4+
DB_PASSWORD=<%= connectionPassword %>
5+
# Connection string to your Autonomous Database/
6+
# Oracle Database instance
7+
CONNECT_STRING=<%= connectionString %>
8+
# Oracle MLE Module name
9+
MLE_MODULE=
10+
# Optional HTTP Proxy Settings
11+
# HTTPS_PROXY=
12+
# HTTPS_PROXY_PORT=
13+
14+
# Path to your local SQL Developer Command Line
15+
# installation
16+
SQL_CL_PATH=<%= sqlclPath %>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Path to database wallet
2+
WALLET_PATH=<%= walletPath %>
3+
WALLET_PASSWORD=<%= walletPassword %>
4+
# Database User
5+
DB_USER=<%= connectionUsername %>
6+
# Database User Password
7+
DB_PASSWORD=<%= connectionPassword %>
8+
# Connection string to your Autonomous Database/
9+
# Oracle Database instance
10+
CONNECT_STRING=<%= connectionString %>
11+
# Oracle MLE Module name
12+
MLE_MODULE=
13+
# Optional HTTP Proxy Settings
14+
# HTTPS_PROXY=
15+
# HTTPS_PROXY_PORT=
16+
17+
# Path to your local SQL Developer Command Line
18+
# installation
19+
SQL_CL_PATH=<%= sqlclPath %>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Editor directories and files
16+
.DS_Store
17+
18+
/.env
19+
/.env.*
20+
!/.env.example
21+
!/.env.*.example
22+
/server/utils/db/wallet

0 commit comments

Comments
 (0)