@dbos-inc/create 1.31.17-preview → 1.31.21-preview
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +16 -9
- package/dist/cli.js.map +1 -1
- package/dist/github-create.d.ts +4 -0
- package/dist/github-create.d.ts.map +1 -0
- package/dist/github-create.js +57 -0
- package/dist/github-create.js.map +1 -0
- package/dist/init.d.ts +3 -0
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +38 -11
- package/dist/init.js.map +1 -1
- package/package.json +3 -9
- package/templates/hello-nextjs/package.json +3 -3
- package/templates/hello-nextjs/src/actions/dbosWorkflow.ts +12 -0
- package/templates/hello-nextjs/src/actions/hello.ts +15 -0
- package/templates/hello-nextjs/src/app/greetings/route.ts +2 -2
- package/templates/hello-nextjs/src/app/page.tsx +4 -0
- package/templates/hello-nextjs/src/components/client/BackGroundTask.tsx +0 -1
- package/templates/hello-nextjs/src/dbos/background.ts +23 -0
- package/templates/hello-nextjs/src/dbos/hello.ts +24 -0
- package/templates/hello-nextjs/src/dbos/operations.ts +9 -0
- package/templates/hello-nextjs/src/actions/dbosWorkflow.tsx +0 -61
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
|
-
import { init } from './init.js';
|
|
3
|
+
import { init, isValidApplicationName, listTemplates } from './init.js';
|
|
4
4
|
import fs from 'fs';
|
|
5
5
|
import path from "path";
|
|
6
|
-
import { input } from "@inquirer/prompts";
|
|
6
|
+
import { input, select } from "@inquirer/prompts";
|
|
7
7
|
const program = new Command();
|
|
8
8
|
////////////////////////
|
|
9
9
|
/* LOCAL DEVELOPMENT */
|
|
@@ -26,18 +26,25 @@ program
|
|
|
26
26
|
template = template || 'hello';
|
|
27
27
|
}
|
|
28
28
|
else {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
const templates = listTemplates();
|
|
30
|
+
// TODO: add descriptions for each template.
|
|
31
|
+
template = await select({
|
|
32
|
+
message: 'Choose a template to use:',
|
|
33
|
+
choices: templates.map(t => ({ name: t, value: t })),
|
|
33
34
|
});
|
|
34
35
|
appName = await input({
|
|
35
36
|
message: 'What is the application/directory name to create?',
|
|
36
|
-
//
|
|
37
|
-
|
|
37
|
+
default: template, // Default to the template name
|
|
38
|
+
validate: isValidApplicationName,
|
|
38
39
|
});
|
|
39
40
|
}
|
|
40
|
-
|
|
41
|
+
try {
|
|
42
|
+
await init(appName, template);
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
console.error(e.message);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
41
48
|
})
|
|
42
49
|
.allowUnknownOption(false);
|
|
43
50
|
program.parse(process.argv);
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACxE,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,wBAAwB;AACxB,wBAAwB;AACxB,wBAAwB;AAExB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAY,CAAC;AAClH,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;AAErC,OAAO;KACJ,WAAW,CAAC,yBAAyB,CAAC;KACtC,MAAM,CAAC,kCAAkC,EAAE,kBAAkB,CAAC;KAC9D,MAAM,CAAC,gCAAgC,EAAE,sCAAsC,CAAC;KAChF,MAAM,CAAC,KAAK,EAAE,OAAgD,EAAE,OAAgB,EAAE,EAAE;IACnF,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,yBAAyB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IAC3F,CAAC;IACD,IAAI,EAAC,OAAO,EAAE,QAAQ,EAAC,GAAG,OAAO,CAAC;IAClC,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;QACxB,OAAO,GAAG,OAAO,IAAI,gBAAgB,CAAC;QACtC,QAAQ,GAAG,QAAQ,IAAI,OAAO,CAAC;IACjC,CAAC;SACI,CAAC;QACJ,MAAM,SAAS,GAAG,aAAa,EAAE,CAAC;QAClC,4CAA4C;QAC5C,QAAQ,GAAG,MAAM,MAAM,CACrB;YACE,OAAO,EAAE,2BAA2B;YACpC,OAAO,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;SACrD,CAAC,CAAC;QACL,OAAO,GAAG,MAAM,KAAK,CACnB;YACE,OAAO,EAAE,mDAAmD;YAC5D,OAAO,EAAE,QAAQ,EAAE,+BAA+B;YAClD,QAAQ,EAAE,sBAAsB;SACjC,CAAC,CAAC;IACP,CAAC;IACD,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC;QACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC;KACD,kBAAkB,CAAC,KAAK,CAAC,CAAC;AAE7B,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-create.d.ts","sourceRoot":"","sources":["../github-create.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,eAAe,UAA2F,CAAC;AACxH,eAAO,MAAM,YAAY,QAAwD,CAAC;AA4BlF,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,iBAsBnF"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
const DEMO_REPO_API = 'https://api.github.com/repos/dbos-inc/dbos-demo-apps';
|
|
5
|
+
const TS_DEMO_PATH = 'typescript/';
|
|
6
|
+
const BRANCH = 'main';
|
|
7
|
+
export const IGNORE_PATTERNS = ['.dbos/', 'node_modules/', 'dist/', '.git/', 'venv/', '.venv/', '.direnv/', '.devenv/'];
|
|
8
|
+
export const IGNORE_REGEX = new RegExp(`^.*\\/(${IGNORE_PATTERNS.join('|')}).*$`);
|
|
9
|
+
const GITHUB_TOKEN = process.env.GITHUB_TOKEN;
|
|
10
|
+
export async function createTemplateFromGitHub(appName, templateName) {
|
|
11
|
+
console.log(`Creating a new application named ${chalk.bold(appName)} from the template ${chalk.bold(templateName)}`);
|
|
12
|
+
const tree = await fetchGitHubTree(BRANCH);
|
|
13
|
+
const templatePath = `${TS_DEMO_PATH}${templateName}/`;
|
|
14
|
+
const filesToDownload = tree.filter((item) => item.path.startsWith(templatePath) && item.type === 'blob');
|
|
15
|
+
// Download every file from the template
|
|
16
|
+
await Promise.all(filesToDownload
|
|
17
|
+
.filter((item) => !IGNORE_REGEX.test(item.path))
|
|
18
|
+
.map(async (item) => {
|
|
19
|
+
const rawContent = await fetchGitHubItem(item.url);
|
|
20
|
+
const content = Buffer.from(rawContent, 'binary').toString('utf-8');
|
|
21
|
+
const filePath = item.path.replace(templatePath, '');
|
|
22
|
+
const targetPath = `${appName}/${filePath}`;
|
|
23
|
+
await fs.promises.mkdir(path.dirname(targetPath), { recursive: true });
|
|
24
|
+
await fs.promises.writeFile(targetPath, content, { mode: parseInt(item.mode, 8) });
|
|
25
|
+
}));
|
|
26
|
+
console.log(`Downloaded ${filesToDownload.length} files from the template GitHub repository`);
|
|
27
|
+
}
|
|
28
|
+
async function fetchGitHub(url) {
|
|
29
|
+
const requestInit = {};
|
|
30
|
+
if (GITHUB_TOKEN) {
|
|
31
|
+
requestInit.headers = {
|
|
32
|
+
Authorization: `Bearer ${GITHUB_TOKEN}`,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const response = await fetch(url, requestInit);
|
|
36
|
+
if (!response.ok) {
|
|
37
|
+
if (response.headers.get('x-ratelimit-remaining') === '0') {
|
|
38
|
+
throw new Error(`Error fetching from GitHub API: rate limit exceeded.\r\nPlease wait a few minutes and try again.\r\nTo increase the limit, you can create a personal access token and set it in the ${chalk.bold('GITHUB_TOKEN')} environment variable. \r\nDetails: https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api`);
|
|
39
|
+
}
|
|
40
|
+
else if (response.status === 401) {
|
|
41
|
+
throw new Error(`Error fetching content from GitHub ${url}: ${response.status} ${response.statusText}.\r\nPlease ensure your ${chalk.bold('GITHUB_TOKEN')} environment variable is set to a valid personal access token.`);
|
|
42
|
+
}
|
|
43
|
+
throw new Error(`Error fetching content from GitHub ${url}: ${response.status} ${response.statusText}`);
|
|
44
|
+
}
|
|
45
|
+
return response;
|
|
46
|
+
}
|
|
47
|
+
async function fetchGitHubTree(tag) {
|
|
48
|
+
const response = await fetchGitHub(`${DEMO_REPO_API}/git/trees/${tag}?recursive=1`);
|
|
49
|
+
const { tree } = (await response.json());
|
|
50
|
+
return tree;
|
|
51
|
+
}
|
|
52
|
+
async function fetchGitHubItem(url) {
|
|
53
|
+
const response = await fetchGitHub(url);
|
|
54
|
+
const { content: contentBase64 } = (await response.json());
|
|
55
|
+
return atob(contentBase64); // Decode base64
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=github-create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-create.js","sourceRoot":"","sources":["../github-create.ts"],"names":[],"mappings":"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"}
|
package/dist/init.d.ts
CHANGED
|
@@ -2,6 +2,9 @@ interface CopyOption {
|
|
|
2
2
|
rename?: (basename: string) => string;
|
|
3
3
|
}
|
|
4
4
|
export declare const copy: (src: string, targets: string[], dest: string, { rename }?: CopyOption) => Promise<void[]>;
|
|
5
|
+
export declare function isValidApplicationName(appName: string): boolean | string;
|
|
5
6
|
export declare function init(appName: string, templateName: string): Promise<void>;
|
|
7
|
+
export declare const DEMO_TEMPLATES: string[];
|
|
8
|
+
export declare function listTemplates(): string[];
|
|
6
9
|
export {};
|
|
7
10
|
//# sourceMappingURL=init.d.ts.map
|
package/dist/init.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../init.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../init.ts"],"names":[],"mappings":"AASA,UAAU,UAAU;IAClB,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;CACvC;AAID,eAAO,MAAM,IAAI,QACV,MAAM,WACF,MAAM,EAAE,QACX,MAAM,eACW,UAAU,oBA4BlC,CAAA;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAQxE;AAyDD,wBAAsB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,iBAmC/D;AAGD,eAAO,MAAM,cAAc,UAAwB,CAAA;AAGnD,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAWxC"}
|
package/dist/init.js
CHANGED
|
@@ -4,6 +4,8 @@ import fs from 'fs';
|
|
|
4
4
|
import { execSync } from 'child_process';
|
|
5
5
|
import validator from 'validator';
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
7
|
+
import { createTemplateFromGitHub } from './github-create.js';
|
|
8
|
+
import chalk from 'chalk';
|
|
7
9
|
const identity = (x) => x;
|
|
8
10
|
export const copy = async (src, targets, dest, { rename = identity } = {}) => {
|
|
9
11
|
if (targets.length === 0 || !dest) {
|
|
@@ -26,11 +28,14 @@ export const copy = async (src, targets, dest, { rename = identity } = {}) => {
|
|
|
26
28
|
return fs.promises.copyFile(from, to);
|
|
27
29
|
}));
|
|
28
30
|
};
|
|
29
|
-
function isValidApplicationName(appName) {
|
|
31
|
+
export function isValidApplicationName(appName) {
|
|
30
32
|
if (appName.length < 3 || appName.length > 30) {
|
|
31
|
-
return
|
|
33
|
+
return "Application name must be between 3 and 30 characters long";
|
|
34
|
+
}
|
|
35
|
+
if (!validator.matches(appName, "^[a-z0-9-_]+$")) {
|
|
36
|
+
return "Application name can only contain lowercase letters, numbers, hyphens and underscores";
|
|
32
37
|
}
|
|
33
|
-
return
|
|
38
|
+
return true;
|
|
34
39
|
}
|
|
35
40
|
const filesAllowedInEmpty = ['.gitignore', 'readme.md'];
|
|
36
41
|
const pathPrefixesAllowedInEmpty = ['.']; // Directories that start with
|
|
@@ -79,21 +84,29 @@ function mergeGitignoreFiles(existingFilePath, templateFilePath, outputFilePath)
|
|
|
79
84
|
console.log(`Merged .gitignore files saved to ${outputFilePath}`);
|
|
80
85
|
}
|
|
81
86
|
export async function init(appName, templateName) {
|
|
82
|
-
if (
|
|
87
|
+
if (isValidApplicationName(appName) !== true) {
|
|
83
88
|
throw new Error(`Invalid application name: ${appName}. Application name must be between 3 and 30 characters long and can only contain lowercase letters, numbers, hyphens and underscores. Exiting...`);
|
|
84
89
|
}
|
|
85
90
|
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
|
86
91
|
const templatePath = path.resolve(__dirname, '..', 'templates', templateName);
|
|
87
|
-
|
|
88
|
-
|
|
92
|
+
const allTemplates = listTemplates();
|
|
93
|
+
if (!allTemplates.includes(templateName)) {
|
|
94
|
+
throw new Error(`Template does not exist: ${chalk.yellow(templateName)}. Please choose from: ${chalk.bold(allTemplates.join(', '))}. Exiting...`);
|
|
89
95
|
}
|
|
90
96
|
if (dirHasStuffInIt(appName)) {
|
|
91
|
-
throw new Error(`Directory ${appName} already exists,
|
|
97
|
+
throw new Error(`Directory ${chalk.yellow(appName)} already exists, please choose another name. Exiting...`);
|
|
98
|
+
}
|
|
99
|
+
if (DEMO_TEMPLATES.includes(templateName)) {
|
|
100
|
+
// Download the template from the demo apps repository
|
|
101
|
+
await createTemplateFromGitHub(appName, templateName);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
// Copy the template from the local templates directory
|
|
105
|
+
const targets = ["**"];
|
|
106
|
+
await copy(templatePath, targets, appName);
|
|
107
|
+
mergeGitignoreFiles(path.join(appName, '.gitignore'), path.join(appName, 'gitignore.template'), path.join(appName, '.gitignore'));
|
|
108
|
+
fs.rmSync(path.resolve(appName, 'gitignore.template'));
|
|
92
109
|
}
|
|
93
|
-
const targets = ["**"];
|
|
94
|
-
await copy(templatePath, targets, appName);
|
|
95
|
-
mergeGitignoreFiles(path.join(appName, '.gitignore'), path.join(appName, 'gitignore.template'), path.join(appName, '.gitignore'));
|
|
96
|
-
fs.rmSync(path.resolve(appName, 'gitignore.template'));
|
|
97
110
|
const packageJsonName = path.resolve(appName, 'package.json');
|
|
98
111
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonName, 'utf-8'));
|
|
99
112
|
packageJson.name = appName;
|
|
@@ -103,4 +116,18 @@ export async function init(appName, templateName) {
|
|
|
103
116
|
execSync("npm install --no-fund --save-dev @dbos-inc/dbos-cloud@latest", { cwd: appName, stdio: 'inherit' });
|
|
104
117
|
console.log("Application initialized successfully!");
|
|
105
118
|
}
|
|
119
|
+
// Templates that will be downloaded through the demo apps repository
|
|
120
|
+
export const DEMO_TEMPLATES = ['dbos-node-starter'];
|
|
121
|
+
// Return a list of available templates
|
|
122
|
+
export function listTemplates() {
|
|
123
|
+
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
|
124
|
+
const templatePath = path.resolve(__dirname, '..', 'templates');
|
|
125
|
+
const items = fs.readdirSync(templatePath, { withFileTypes: true });
|
|
126
|
+
const templates = items
|
|
127
|
+
.filter(item => item.isDirectory())
|
|
128
|
+
.map(folder => folder.name);
|
|
129
|
+
// Insert demo templates at the beginning of the list
|
|
130
|
+
templates.unshift(...DEMO_TEMPLATES);
|
|
131
|
+
return templates;
|
|
132
|
+
}
|
|
106
133
|
//# sourceMappingURL=init.js.map
|
package/dist/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../init.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,SAAS,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../init.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,SAAS,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC;AAElC,MAAM,CAAC,MAAM,IAAI,GAAG,KAAK,EACvB,GAAW,EACX,OAAiB,EACjB,IAAY,EACZ,EAAE,MAAM,GAAG,QAAQ,KAAiB,EAAE,EACtC,EAAE;IACF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAClC,MAAM,IAAI,SAAS,CAAC,+BAA+B,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE;QACtC,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,IAAI;QACT,QAAQ,EAAE,KAAK;QACf,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE,CAAC,mBAAmB,EAAE,oBAAoB,EAAE,YAAY,CAAC;KAClE,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,GAAG,CAChB,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAE1C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAClC,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAE9C,0CAA0C;QAC1C,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE/D,OAAO,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACxC,CAAC,CAAC,CACH,CAAC;AACJ,CAAC,CAAA;AAED,MAAM,UAAU,sBAAsB,CAAC,OAAe;IACpD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QAC9C,OAAO,2DAA2D,CAAC;IACrE,CAAC;IACD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE,CAAC;QACjD,OAAO,uFAAuF,CAAC;IACjG,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,mBAAmB,GAAG,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;AACxD,MAAM,0BAA0B,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,8BAA8B;AAExE,SAAS,eAAe,CAAC,QAAgB;IACvC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC3C,MAAM,WAAW,GAAG,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QAEzD,IAAI,WAAW,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;YACrF,wGAAwG;YACxG,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,8EAA8E;QAC9E,IAAI,CAAC,WAAW,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YACpE,mGAAmG;YACnG,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,iBAAiB,CAAC,QAAgB;IACzC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,GAAG,EAAE,CAAC;IAC/C,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,cAAc,CAAC,aAA0B,EAAE,aAA0B;IAC1E,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IACzC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QACzB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;IACL,CAAC,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChD,OAAO,MAAM,CAAC,UAAU,CAAC,KAAK,EAAC,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,mBAAmB,CAAC,gBAAwB,EAAE,gBAAwB,EAAE,cAAsB;IACnG,MAAM,WAAW,GAAG,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;IACxD,MAAM,WAAW,GAAG,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;IACxD,MAAM,aAAa,GAAG,cAAc,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAC/D,EAAE,CAAC,aAAa,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,oCAAoC,cAAc,EAAE,CAAC,CAAC;AACtE,CAAC;AAGD,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,OAAe,EAAE,YAAoB;IAC9D,IAAI,sBAAsB,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,6BAA6B,OAAO,kJAAkJ,CAAC,CAAC;IAC1M,CAAC;IAED,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;IAC9E,MAAM,YAAY,GAAG,aAAa,EAAE,CAAC;IACrC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,yBAAyB,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,CAAC;IACpJ,CAAC;IAED,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,aAAa,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,yDAAyD,CAAC,CAAC;IAC/G,CAAC;IAED,IAAI,cAAc,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAC1C,sDAAsD;QACtD,MAAM,wBAAwB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACxD,CAAC;SAAM,CAAC;QACN,uDAAuD;QACvD,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,CAAA;QACtB,MAAM,IAAI,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC3C,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,oBAAoB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;QAClI,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAC9D,MAAM,WAAW,GAAqB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAqB,CAAC;IAChH,WAAW,CAAC,IAAI,GAAG,OAAO,CAAC;IAC3B,EAAE,CAAC,aAAa,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACjF,QAAQ,CAAC,yEAAyE,EAAE,EAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAC,CAAC,CAAA;IACrH,QAAQ,CAAC,kCAAkC,EAAE,EAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAC,CAAC,CAAA;IAC9E,QAAQ,CAAC,8DAA8D,EAAE,EAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAC,CAAC,CAAA;IAC1G,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAA;AACtD,CAAC;AAED,qEAAqE;AACrE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,mBAAmB,CAAC,CAAA;AAEnD,uCAAuC;AACvC,MAAM,UAAU,aAAa;IAC3B,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,YAAY,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,MAAM,SAAS,GAAG,KAAK;SAClB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;SAClC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAEhC,qDAAqD;IACrD,SAAS,CAAC,OAAO,CAAC,GAAG,cAAc,CAAC,CAAC;IACrC,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dbos-inc/create",
|
|
3
|
-
"version": "1.31.
|
|
3
|
+
"version": "1.31.21-preview",
|
|
4
4
|
"description": "Tool for performing project initialization from template",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -26,16 +26,10 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@inquirer/prompts": "^5.3.8",
|
|
29
|
-
"axios": "^1.7.4",
|
|
30
29
|
"chalk": "4.1.2",
|
|
31
30
|
"commander": "^12.0.0",
|
|
32
|
-
"fast-glob": "^3.3.
|
|
33
|
-
"open": "^10.1.0",
|
|
34
|
-
"prompt-sync": "^4.2.0",
|
|
31
|
+
"fast-glob": "^3.3.3",
|
|
35
32
|
"update-notifier": "^7.0.0",
|
|
36
|
-
"validator": "^13.
|
|
37
|
-
"winston": "^3.12.0",
|
|
38
|
-
"winston-transport": "^4.7.0",
|
|
39
|
-
"yaml": "^2.5.0"
|
|
33
|
+
"validator": "^13.12.0"
|
|
40
34
|
}
|
|
41
35
|
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"lint": "next lint"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@dbos-inc/dbos-sdk": "^1.
|
|
12
|
+
"@dbos-inc/dbos-sdk": "^1.31.17-preview",
|
|
13
13
|
"next": "15.0.3",
|
|
14
14
|
"react": "19.0.0-rc-66855b96-20241106",
|
|
15
15
|
"react-dom": "19.0.0-rc-66855b96-20241106",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"eslint": "^8",
|
|
27
27
|
"eslint-config-next": "15.0.3",
|
|
28
28
|
"postcss": "^8",
|
|
29
|
-
"
|
|
30
|
-
"
|
|
29
|
+
"tailwindcss": "^3.4.1",
|
|
30
|
+
"typescript": "^5"
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
|
|
3
|
+
import { DBOS } from "@dbos-inc/dbos-sdk";
|
|
4
|
+
import { dbosWorkflowClass } from "../dbos/operations";
|
|
5
|
+
|
|
6
|
+
console.log("Hello from dbosWorkflow.ts");
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
export async function dbosBackgroundTask(workflowID: string) {
|
|
10
|
+
DBOS.logger.info("Hello from DBOS!");
|
|
11
|
+
return DBOS.startWorkflow(dbosWorkflowClass, {workflowID: workflowID}).backgroundTask(10);
|
|
12
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
|
|
3
|
+
import { DBOS } from "@dbos-inc/dbos-sdk";
|
|
4
|
+
import { helloWorkflowClass } from "../dbos/operations";
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
console.log("Hello from hello.ts");
|
|
8
|
+
|
|
9
|
+
// The exported function is the entry point for the workflow
|
|
10
|
+
// The function is exported and not the class because Next does not support exporting classes
|
|
11
|
+
export async function helloWorkflow(userName: string) {
|
|
12
|
+
DBOS.logger.info("Hello from DBOS!");
|
|
13
|
+
return await helloWorkflowClass.helloDBOS(userName);
|
|
14
|
+
}
|
|
15
|
+
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
|
-
import {
|
|
2
|
+
import { helloWorkflow } from "../../actions/hello";
|
|
3
3
|
import { DBOS } from "@dbos-inc/dbos-sdk";
|
|
4
4
|
|
|
5
5
|
export async function POST(request: Request) {
|
|
6
6
|
const body = await request.json();
|
|
7
7
|
const { userName } = body;
|
|
8
8
|
DBOS.logger.info(`Received request with name: ${userName}`);
|
|
9
|
-
const response = await
|
|
9
|
+
const response = await helloWorkflow(userName);
|
|
10
10
|
return NextResponse.json(response);
|
|
11
11
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Image from "next/image";
|
|
2
2
|
import BackGroundTask from "@/components/client/BackGroundTask";
|
|
3
|
+
import CallDBOSWorkflow from "@/components/client/callDBOSWorkflow";
|
|
3
4
|
|
|
4
5
|
export default function Home() {
|
|
5
6
|
return (
|
|
@@ -13,6 +14,9 @@ export default function Home() {
|
|
|
13
14
|
<p className="mb-4">
|
|
14
15
|
DBOS helps you build applications that are <strong>resilient to any failure</strong>—no matter how many times you crash this app, your background task will always recover from its last completed step in about ten seconds.
|
|
15
16
|
</p>
|
|
17
|
+
<div>
|
|
18
|
+
<CallDBOSWorkflow wfResult="" />
|
|
19
|
+
</div>
|
|
16
20
|
<div>
|
|
17
21
|
<BackGroundTask />
|
|
18
22
|
</div>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
import { DBOS } from "@dbos-inc/dbos-sdk";
|
|
3
|
+
|
|
4
|
+
export class dbosWorkflowClass {
|
|
5
|
+
|
|
6
|
+
@DBOS.transaction()
|
|
7
|
+
static async backgroundTaskStep(i : number) {
|
|
8
|
+
DBOS.logger.info(`Completed step ${i}`);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
@DBOS.workflow()
|
|
12
|
+
static async backgroundTask(i: number) {
|
|
13
|
+
DBOS.logger.info("Hello from background task!");
|
|
14
|
+
for (let j = 1; j <= i; j++) {
|
|
15
|
+
await dbosWorkflowClass.backgroundTaskStep(j);
|
|
16
|
+
DBOS.logger.info("Sleeping for 2 seconds");
|
|
17
|
+
await DBOS.sleepSeconds(2);
|
|
18
|
+
await DBOS.setEvent("steps_event", j)
|
|
19
|
+
}
|
|
20
|
+
DBOS.logger.info("Background task complete!");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { DBOS } from "@dbos-inc/dbos-sdk";
|
|
2
|
+
import { Knex } from "knex";
|
|
3
|
+
|
|
4
|
+
export interface dbos_hello {
|
|
5
|
+
name: string;
|
|
6
|
+
greet_count: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function getClient() {return DBOS.knexClient as Knex;}
|
|
10
|
+
|
|
11
|
+
export class helloWorkflowClass {
|
|
12
|
+
|
|
13
|
+
@DBOS.transaction()
|
|
14
|
+
static async helloDBOS(userName: string) {
|
|
15
|
+
DBOS.logger.info("Hello from DBOS Transaction!");
|
|
16
|
+
// Retrieve and increment the number of times this user has been greeted.
|
|
17
|
+
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;";
|
|
18
|
+
const { rows } = await getClient().raw(query, [userName]) as { rows: dbos_hello[] };
|
|
19
|
+
const greet_count = rows[0].greet_count;
|
|
20
|
+
const greeting = `Hello! You have been greeted ${greet_count} times.`;
|
|
21
|
+
return greeting;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { DBOS } from "@dbos-inc/dbos-sdk";
|
|
2
|
+
export { dbosWorkflowClass } from "./background";
|
|
3
|
+
export { helloWorkflowClass } from "./hello";
|
|
4
|
+
|
|
5
|
+
console.log("Hello from operations.ts");
|
|
6
|
+
|
|
7
|
+
if (process.env.NEXT_PHASE !== "phase-production-build") {
|
|
8
|
+
await DBOS.launch()
|
|
9
|
+
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
"use server";
|
|
2
|
-
|
|
3
|
-
import { DBOS } from "@dbos-inc/dbos-sdk";
|
|
4
|
-
|
|
5
|
-
// The schema of the database table used in this example.
|
|
6
|
-
export interface dbos_hello {
|
|
7
|
-
name: string;
|
|
8
|
-
greet_count: number;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
// Order matters: DBOS decorators must be declared before being used
|
|
12
|
-
class dbosWorkflowClass {
|
|
13
|
-
@DBOS.transaction()
|
|
14
|
-
static async helloDBOS(userName: string) {
|
|
15
|
-
DBOS.logger.info("Hello from DBOS Transaction!");
|
|
16
|
-
// Retrieve and increment the number of times this user has been greeted.
|
|
17
|
-
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;";
|
|
18
|
-
const { rows } = await DBOS.sqlClient.client.raw(query, [userName]) as { rows: dbos_hello[] };
|
|
19
|
-
const greet_count = rows[0].greet_count;
|
|
20
|
-
const greeting = `Hello! You have been greeted ${greet_count} times.`;
|
|
21
|
-
return greeting;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
@DBOS.transaction()
|
|
25
|
-
static async backgroundTaskStep(i : number) {
|
|
26
|
-
DBOS.logger.info(`Completed step ${i}`);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
@DBOS.workflow()
|
|
30
|
-
static async backgroundTask(i: number) {
|
|
31
|
-
DBOS.logger.info("Hello from background task!");
|
|
32
|
-
for (let j = 1; j <= i; j++) {
|
|
33
|
-
await dbosWorkflowClass.backgroundTaskStep(j);
|
|
34
|
-
DBOS.logger.info("Sleeping for 2 seconds");
|
|
35
|
-
await DBOS.sleepSeconds(2);
|
|
36
|
-
await DBOS.setEvent("steps_event", j)
|
|
37
|
-
}
|
|
38
|
-
DBOS.logger.info("Background task complete!");
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Launch the DBOS runtime
|
|
45
|
-
// This code needs to execute at least once to launch the DBOS runtime
|
|
46
|
-
// Do not delete this code
|
|
47
|
-
if (process.env.NEXT_PHASE !== "phase-production-build") {
|
|
48
|
-
await DBOS.launch();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// The exported function is the entry point for the workflow
|
|
52
|
-
// The function is exported and not the class because Next does not support exporting classes
|
|
53
|
-
export async function dbosWorkflow(userName: string) {
|
|
54
|
-
DBOS.logger.info("Hello from DBOS!");
|
|
55
|
-
return await dbosWorkflowClass.helloDBOS(userName);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export async function dbosBackgroundTask(workflowID: string) {
|
|
59
|
-
DBOS.logger.info("Hello from DBOS!");
|
|
60
|
-
return DBOS.startWorkflow(dbosWorkflowClass, {workflowID: workflowID}).backgroundTask(10);
|
|
61
|
-
}
|