Skip to content

Commit

Permalink
CSS facelift for the Hello app and the schema-specific templates (#617)
Browse files Browse the repository at this point in the history
Mostly copying over what P&Q did for the Python app but with more direct
links to send the user to the right docs in each case.

---------

Signed-off-by: Alex Poliakov <alex.poliakov@dbos.dev>
Co-authored-by: Peter Kraft <peter.kraft@dbos.dev>
  • Loading branch information
apoliakov and kraftp authored Sep 2, 2024
1 parent a2a2e8d commit f7764bf
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 80 deletions.
56 changes: 37 additions & 19 deletions packages/create/templates/hello-drizzle/src/operations.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,52 @@
// Welcome to DBOS!

// This is the Quickstart Drizzle template app. It greets visitors, counting how many total greetings were made.
// To learn how to run this app, visit the Drizzle tutorial: https://docs.dbos.dev/tutorials/using-drizzle

import { HandlerContext, TransactionContext, Transaction, GetApi } from '@dbos-inc/dbos-sdk';
import { dbosHello } from './schema';
import { NodePgDatabase } from 'drizzle-orm/node-postgres';

const app_notes = `
To learn how to run this app on your computer, visit the
<a href="https://docs.dbos.dev/getting-started/quickstart" >DBOS Quickstart</a>.<br>
After that, to learn how to build apps, visit the
<a href="https://docs.dbos.dev/getting-started/quickstart-programming" >DBOS Programming Guide</a>.`;

export class Hello {

@GetApi('/') // Serve a quick readme for the app
static async readme(_ctxt: HandlerContext) {
const readme = `<html><body><p>
Welcome to the DBOS Hello App!<br><br>
Visit the route /greeting/:name to be greeted!<br>
For example, visit <a href="/greeting/dbos">/greeting/dbos</a>.<br>
The counter increments with each page visit.<br><br>
${app_notes}
</p></body></html>`;
return Promise.resolve(readme);
}

// Serve this function from HTTP GET requests at the /greeting endpoint with 'user' as a path parameter
@GetApi('/greeting/:user')
@Transaction()
static async helloTransaction(ctxt: TransactionContext<NodePgDatabase>, user: string) {
const greeting = `Hello, ${user}!`;
const greetings_output = await ctxt.client.insert(dbosHello).values({greeting}).returning({greet_count: dbosHello.greet_count});
const greeting_message = `${greeting} We have made ${greetings_output[0].greet_count} greetings.`;
const page = `<html><body><p>${greeting_message}<br><br>${app_notes}</p></body></html>`;
return Hello.makeHTML(greeting_message);
}

// Serve a quick readme for the app at the / endpoint
@GetApi('/')
static async readme(_ctxt: HandlerContext) {
const message = Hello.makeHTML(
`Visit the route <code class="bg-gray-100 px-1 rounded">/greeting/{name}</code> to be greeted!<br>
For example, visit <code class="bg-gray-100 px-1 rounded"><a href="/greeting/Mike" class="text-blue-600 hover:underline">/greeting/Mike</a></code><br>
The counter increments with each page visit.`
);
return Promise.resolve(message);
}

// A helper function to create HTML pages with some styling
static makeHTML(message: string) {
const page = `
<!DOCTYPE html>
<html lang="en">
<head>
<title>DBOS Template App</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="font-sans text-gray-800 p-6 max-w-2xl mx-auto">
<h1 class="text-3xl font-semibold mb-4">Welcome to DBOS!</h1>
<p class="mt-8 mb-8">` + message + `</p>
<p class="mb-2">
This is the Drizzle quickstart template app. Read the documentation for it <a href="https://docs.dbos.dev/tutorials/using-drizzle" class="text-blue-600 hover:underline">here</a>.
</p>
</body>
</html>`;
return page;
}
}
57 changes: 38 additions & 19 deletions packages/create/templates/hello-prisma/src/operations.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,15 @@
// Welcome to DBOS!

// This is the Quickstart Prisma template app. It greets visitors, counting how many total greetings were made.
// To learn how to run this app, visit the Prisma tutorial: https://docs.dbos.dev/tutorials/using-prisma

import { HandlerContext, TransactionContext, Transaction, GetApi } from '@dbos-inc/dbos-sdk';
import { PrismaClient } from "@prisma/client";

const app_notes = `
To learn how to run this app on your computer, visit the
<a href="https://docs.dbos.dev/getting-started/quickstart" >DBOS Quickstart</a>.<br>
After that, to learn how to build apps, visit the
<a href="https://docs.dbos.dev/getting-started/quickstart-programming" >DBOS Programming Guide</a>.`;
import { PrismaClient } from "@prisma/client";

export class Hello {

@GetApi('/') // Serve a quick readme for the app
static async readme(_ctxt: HandlerContext) {
const readme = `<html><body><p>
Welcome to the DBOS Hello App!<br><br>
Visit the route /greeting/:name to be greeted!<br>
For example, visit <a href="/greeting/dbos">/greeting/dbos</a>.<br>
The counter increments with each page visit.<br><br>
${app_notes}
</p></body></html>`;
return Promise.resolve(readme);
}

// Serve this function from HTTP GET requests at the /greeting endpoint with 'name' as a path parameter
@GetApi('/greeting/:name')
@Transaction()
static async helloTransaction(txnCtxt: TransactionContext<PrismaClient>, name: string) {
Expand All @@ -31,7 +20,37 @@ export class Hello {
},
});
const greeting_note = `Greeting ${res.greeting_id}: ${greeting}`;
const page = `<html><body><p>${greeting_note}<br><br>${app_notes}</p></body></html>`;
return Hello.makeHTML(greeting_note);
}

// Serve a quick readme for the app at the / endpoint
@GetApi('/')
static async readme(_ctxt: HandlerContext) {
const message = Hello.makeHTML(
`Visit the route <code class="bg-gray-100 px-1 rounded">/greeting/{name}</code> to be greeted!<br>
For example, visit <code class="bg-gray-100 px-1 rounded"><a href="/greeting/Mike" class="text-blue-600 hover:underline">/greeting/Mike</a></code><br>
The counter increments with each page visit.`
);
return Promise.resolve(message);
}

// A helper function to create HTML pages with some styling
static makeHTML(message: string) {
const page = `
<!DOCTYPE html>
<html lang="en">
<head>
<title>DBOS Template App</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="font-sans text-gray-800 p-6 max-w-2xl mx-auto">
<h1 class="text-3xl font-semibold mb-4">Welcome to DBOS!</h1>
<p class="mt-8 mb-8">` + message + `</p>
<p class="mb-2">
This is the Prisma quickstart template app. Read the documentation for it <a href="https://docs.dbos.dev/tutorials/using-prisma" class="text-blue-600 hover:underline">here</a>.
</p>
</body>
</html>`;
return page;
}
}
55 changes: 36 additions & 19 deletions packages/create/templates/hello-typeorm/src/operations.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,15 @@
// Welcome to DBOS!

// This is the Quickstart TypeORM template app. It greets visitors, counting how many total greetings were made.
// To learn how to run this app, visit the TypeORM tutorial: https://docs.dbos.dev/tutorials/using-typeorm

import { HandlerContext, TransactionContext, Transaction, GetApi, OrmEntities } from '@dbos-inc/dbos-sdk';
import { EntityManager } from "typeorm";
import { DBOSHello } from '../entities/DBOSHello';

const app_notes = `
To learn how to run this app on your computer, visit the
<a href="https://docs.dbos.dev/getting-started/quickstart" >DBOS Quickstart</a>.<br>
After that, to learn how to build apps, visit the
<a href="https://docs.dbos.dev/getting-started/quickstart-programming" >DBOS Programming Guide</a>.`;

@OrmEntities([DBOSHello])
export class Hello {

@GetApi('/') // Serve a quick readme for the app
static async readme(_ctxt: HandlerContext) {
const readme = `<html><body><p>
Welcome to the DBOS Hello App!<br><br>
Visit the route /greeting/:name to be greeted!<br>
For example, visit <a href="/greeting/dbos">/greeting/dbos</a>.<br>
The counter increments with each page visit.<br><br>
${app_notes}
</p></body></html>`;
return Promise.resolve(readme);
}

@GetApi('/greeting/:name')
@Transaction()
static async helloTransaction(txnCtxt: TransactionContext<EntityManager>, name: string) {
Expand All @@ -31,7 +18,37 @@ export class Hello {
entity.greeting = greeting;
entity = await txnCtxt.client.save(entity);
const greeting_note = `Greeting ${entity.greeting_id}: ${greeting}`;
const page = `<html><body><p>${greeting_note}<br><br>${app_notes}</p></body></html>`;
return Hello.makeHTML(greeting_note);
}

// Serve a quick readme for the app at the / endpoint
@GetApi('/')
static async readme(_ctxt: HandlerContext) {
const message = Hello.makeHTML(
`Visit the route <code class="bg-gray-100 px-1 rounded">/greeting/{name}</code> to be greeted!<br>
For example, visit <code class="bg-gray-100 px-1 rounded"><a href="/greeting/Mike" class="text-blue-600 hover:underline">/greeting/Mike</a></code><br>
The counter increments with each page visit.`
);
return Promise.resolve(message);
}

// A helper function to create HTML pages with some styling
static makeHTML(message: string) {
const page = `
<!DOCTYPE html>
<html lang="en">
<head>
<title>DBOS Template App</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="font-sans text-gray-800 p-6 max-w-2xl mx-auto">
<h1 class="text-3xl font-semibold mb-4">Welcome to DBOS!</h1>
<p class="mt-8 mb-8">` + message + `</p>
<p class="mb-2">
This is the TypeORM quickstart template app. Read the documentation for it <a href="https://docs.dbos.dev/tutorials/using-typeorm" class="text-blue-600 hover:underline">here</a>.
</p>
</body>
</html>`;
return page;
}
}
64 changes: 43 additions & 21 deletions packages/create/templates/hello/src/operations.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Welcome to DBOS!

// This is a sample "Hello" app built with DBOS.
// It greets visitors and keeps track of how many times each visitor has been greeted.
// To run this app, visit our Quickstart: https://docs.dbos.dev/getting-started/quickstart

import { HandlerContext, TransactionContext, Transaction, GetApi, ArgSource, ArgSources } from '@dbos-inc/dbos-sdk';
import { Knex } from 'knex';

const app_notes = `
To learn how to run this app on your computer, visit the
<a href="https://docs.dbos.dev/getting-started/quickstart" >DBOS Quickstart</a>.<br>
After that, to learn how to build apps, visit the
<a href="https://docs.dbos.dev/getting-started/quickstart-programming" >DBOS Programming Guide</a>.`;

// The schema of the database table used in this example.
export interface dbos_hello {
name: string;
Expand All @@ -15,28 +15,50 @@ export interface dbos_hello {

export class Hello {

@GetApi('/') // Serve a quick readme for the app
static async readme(_ctxt: HandlerContext) {
const readme = `<html><body><p>
Welcome to the DBOS Hello App!<br><br>
Visit the route /greeting/:name to be greeted!<br>
For example, visit <a href="/greeting/dbos">/greeting/dbos</a>.<br>
The counter increments with each page visit.<br>
If you visit a new name like <a href="/greeting/alice">/greeting/alice</a>, the counter starts at 1.<br><br>
${app_notes}
</p></body></html>`;
return Promise.resolve(readme);
}

@GetApi('/greeting/:user') // Serve this function from HTTP GET requests to the /greeting endpoint with 'user' as a path parameter
// Serve this function from HTTP GET requests at the /greeting endpoint with 'user' as a path parameter
@GetApi('/greeting/:user')
@Transaction() // Run this function as a database transaction
static async helloTransaction(ctxt: TransactionContext<Knex>, @ArgSource(ArgSources.URL) user: string) {
// Retrieve and increment the number of times this user has been greeted.
const query = "INSERT INTO dbos_hello (name, greet_count) VALUES (?, 1) ON CONFLICT (name) DO UPDATE SET greet_count = dbos_hello.greet_count + 1 RETURNING greet_count;";
const { rows } = await ctxt.client.raw(query, [user]) as { rows: dbos_hello[] };
const greet_count = rows[0].greet_count;
const greeting = `Hello, ${user}! You have been greeted ${greet_count} times.`;
const page = `<html><body><p>${greeting}<br><br>${app_notes}</p></body></html>`;
return Hello.makeHTML(greeting);
}

// Serve a quick readme for the app at the / endpoint
@GetApi('/')
static async readme(_ctxt: HandlerContext) {
const message = Hello.makeHTML(
`Visit the route <code class="bg-gray-100 px-1 rounded">/greeting/{name}</code> to be greeted!<br>
For example, visit <code class="bg-gray-100 px-1 rounded"><a href="/greeting/Mike" class="text-blue-600 hover:underline">/greeting/Mike</a></code><br>
The counter increments with each page visit.`
);
return Promise.resolve(message);
}

// A helper function to create HTML pages with some styling
static makeHTML(message: string) {
const page = `
<!DOCTYPE html>
<html lang="en">
<head>
<title>DBOS Template App</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="font-sans text-gray-800 p-6 max-w-2xl mx-auto">
<h1 class="text-3xl font-semibold mb-4">Welcome to DBOS!</h1>
<p class="mt-8 mb-8">` + message + `</p>
<p class="mb-2">
To learn how to run this app yourself, visit our
<a href="https://docs.dbos.dev/getting-started/quickstart" class="text-blue-600 hover:underline">Quickstart</a>.
</p><p class="mb-2">
Then, to learn how to build crashproof apps, continue to our
<a href="https://docs.dbos.dev/getting-started/quickstart-programming" class="text-blue-600 hover:underline">Programming Guide</a>.<br>
</p>
</body>
</html>`;
return page;
}
}
6 changes: 4 additions & 2 deletions packages/dbos-openapi/tests/openapi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ describe("TypeParser", () => {
const [$class] = classes!;
expect($class.name).toBe("Hello");
expect($class.decorators.length).toBe(0);
expect($class.methods.length).toBe(2);
expect($class.methods.length).toBe(3);

const method = $class.methods[0].name === "helloTransaction" ? $class.methods[0] : $class.methods[1];
const method = $class.methods[0].name === "helloTransaction" ? $class.methods[0] :
$class.methods[1].name === "helloTransaction" ? $class.methods[1] :
$class.methods[2];
expect(method.name).toBe("helloTransaction");
expect(method.decorators.length).toBe(2);

Expand Down

0 comments on commit f7764bf

Please sign in to comment.