@flowgram.ai/runtime-nodejs 0.1.0-alpha.10

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.
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { OpenApiMeta } from 'trpc-openapi';
7
+ import { initTRPC } from '@trpc/server';
8
+
9
+ import type { Context } from '../server/context';
10
+
11
+ const t = initTRPC
12
+ .context<Context>()
13
+ .meta<OpenApiMeta>()
14
+ .create({
15
+ errorFormatter({ shape }) {
16
+ return shape;
17
+ },
18
+ });
19
+
20
+ export const router = t.router;
21
+ export const publicProcedure = t.procedure;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { BuildProcedure } from '@trpc/server';
7
+ import { FlowGramAPIDefine } from '@flowgram.ai/runtime-interface';
8
+
9
+ export interface APIHandler {
10
+ define: FlowGramAPIDefine;
11
+ procedure: BuildProcedure<any, any, any>;
12
+ }
13
+
14
+ export type APIRouter = Record<FlowGramAPIDefine['path'], APIHandler['procedure']>;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import type { ServerParams } from '@server/type';
7
+
8
+ export const ServerConfig: ServerParams = {
9
+ name: 'flowgram-runtime',
10
+ title: 'FlowGram Runtime',
11
+ description: 'FlowGram Runtime Demo',
12
+ runtime: 'nodejs',
13
+ version: '0.0.1',
14
+ dev: false,
15
+ port: 4000,
16
+ basePath: '/api',
17
+ docsPath: '/docs',
18
+ };
package/src/index.ts ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { createServer } from '@server/index';
7
+
8
+ async function main() {
9
+ const server = await createServer();
10
+ server.start();
11
+ }
12
+
13
+ main();
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import type { CreateFastifyContextOptions } from '@trpc/server/adapters/fastify';
7
+
8
+ export function createContext(ctx: CreateFastifyContextOptions) {
9
+ const { req, res } = ctx;
10
+ return { req, res };
11
+ }
12
+
13
+ export type Context = Awaited<ReturnType<typeof createContext>>;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { generateOpenApiDocument } from 'trpc-openapi';
7
+
8
+ import { ServerConfig } from '@config/index';
9
+ import { appRouter } from '@api/index';
10
+
11
+ // Generate OpenAPI schema document
12
+ export const serverDocument = generateOpenApiDocument(appRouter, {
13
+ title: ServerConfig.title,
14
+ description: ServerConfig.description,
15
+ version: ServerConfig.version,
16
+ baseUrl: `http://localhost:${ServerConfig.port}${ServerConfig.basePath}`,
17
+ docsUrl: 'https://flowgram.ai',
18
+ tags: ['Task'],
19
+ });
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { fastifyTRPCOpenApiPlugin } from 'trpc-openapi';
7
+ import fastify from 'fastify';
8
+ import { fastifyTRPCPlugin } from '@trpc/server/adapters/fastify';
9
+ import { ServerInfoDefine, type ServerInfoOutput } from '@flowgram.ai/runtime-interface';
10
+ import ws from '@fastify/websocket';
11
+ import fastifySwaggerUI from '@fastify/swagger-ui';
12
+ import fastifySwagger from '@fastify/swagger';
13
+ import cors from '@fastify/cors';
14
+
15
+ import { ServerConfig } from '@config/index';
16
+ import { appRouter } from '@api/index';
17
+ import { serverDocument } from './docs';
18
+ import { createContext } from './context';
19
+
20
+ export async function createServer() {
21
+ const server = fastify({ logger: ServerConfig.dev });
22
+
23
+ await server.register(cors);
24
+ await server.register(ws);
25
+ await server.register(fastifyTRPCPlugin, {
26
+ prefix: '/trpc',
27
+ useWss: false,
28
+ trpcOptions: { router: appRouter, createContext },
29
+ });
30
+ await server.register(fastifyTRPCOpenApiPlugin, {
31
+ basePath: ServerConfig.basePath,
32
+ router: appRouter,
33
+ createContext,
34
+ } as any);
35
+
36
+ await server.register(fastifySwagger, {
37
+ mode: 'static',
38
+ specification: { document: serverDocument },
39
+ uiConfig: { displayOperationId: true },
40
+ exposeRoute: true,
41
+ } as any);
42
+
43
+ await server.register(fastifySwaggerUI, {
44
+ routePrefix: ServerConfig.docsPath,
45
+ uiConfig: {
46
+ docExpansion: 'full',
47
+ deepLinking: false,
48
+ },
49
+ uiHooks: {
50
+ onRequest: function (request, reply, next) {
51
+ next();
52
+ },
53
+ preHandler: function (request, reply, next) {
54
+ next();
55
+ },
56
+ },
57
+ staticCSP: true,
58
+ transformStaticCSP: (header) => header,
59
+ transformSpecification: (swaggerObject, request, reply) => swaggerObject,
60
+ transformSpecificationClone: true,
61
+ });
62
+
63
+ server.get(ServerInfoDefine.path, async (): Promise<ServerInfoOutput> => {
64
+ const serverTime = new Date();
65
+ const output: ServerInfoOutput = {
66
+ name: ServerConfig.name,
67
+ title: ServerConfig.title,
68
+ description: ServerConfig.description,
69
+ runtime: ServerConfig.runtime,
70
+ version: ServerConfig.version,
71
+ time: serverTime.toISOString(),
72
+ };
73
+ return output;
74
+ });
75
+
76
+ const stop = async () => {
77
+ await server.close();
78
+ };
79
+ const start = async () => {
80
+ try {
81
+ const address = await server.listen({ port: ServerConfig.port });
82
+ await server.ready();
83
+ server.swagger();
84
+ console.log(
85
+ `> Listen Port: ${ServerConfig.port}\n> Server Address: ${address}\n> API Docs: http://localhost:4000/docs`
86
+ );
87
+ } catch (err) {
88
+ server.log.error(err);
89
+ process.exit(1);
90
+ }
91
+ };
92
+
93
+ return { server, start, stop };
94
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { ServerInfoOutput } from '@flowgram.ai/runtime-interface';
7
+
8
+ export interface ServerParams extends Omit<ServerInfoOutput, 'time'> {
9
+ dev: boolean;
10
+ port: number;
11
+ basePath: string;
12
+ docsPath: string;
13
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "extends": "@flowgram.ai/ts-config/tsconfig.flow.path.json",
3
+ "compilerOptions": {
4
+ "target": "esnext",
5
+ "lib": [
6
+ "dom",
7
+ "dom.iterable",
8
+ "esnext"
9
+ ],
10
+ "allowJs": true,
11
+ "skipLibCheck": true,
12
+ "strict": true,
13
+ "noEmit": true,
14
+ "esModuleInterop": true,
15
+ "module": "esnext",
16
+ "moduleResolution": "bundler",
17
+ "resolveJsonModule": true,
18
+ "isolatedModules": true,
19
+ "jsx": "preserve",
20
+ "plugins": [],
21
+ "baseUrl": "src",
22
+ "paths": {
23
+ "@api/*": [
24
+ "api/*"
25
+ ],
26
+ "@application/*": [
27
+ "application/*"
28
+ ],
29
+ "@server/*": [
30
+ "server/*"
31
+ ],
32
+ "@config/*": [
33
+ "config/*"
34
+ ],
35
+ "@workflow/*": [
36
+ "workflow/*"
37
+ ]
38
+ }
39
+ },
40
+ "include": [
41
+ "**/*.ts",
42
+ "**/*.tsx",
43
+ "src/workflow/executor/condition/constant.ts"
44
+ ],
45
+ "exclude": [
46
+ "node_modules"
47
+ ]
48
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { config } from "dotenv";
7
+ import path from 'path';
8
+ import { defineConfig } from 'vitest/config';
9
+
10
+ export default defineConfig({
11
+ build: {
12
+ commonjsOptions: {
13
+ transformMixedEsModules: true,
14
+ },
15
+ },
16
+ resolve: {
17
+ alias: [
18
+ {find: "@api", replacement: path.resolve(__dirname, './src/api') },
19
+ {find: "@application", replacement: path.resolve(__dirname, './src/application') },
20
+ {find: "@server", replacement: path.resolve(__dirname, './src/server') },
21
+ {find: "@config", replacement: path.resolve(__dirname, './src/config') },
22
+ {find: "@workflow", replacement: path.resolve(__dirname, './src/workflow') },
23
+ ],
24
+ },
25
+ test: {
26
+ globals: true,
27
+ mockReset: false,
28
+ environment: 'jsdom',
29
+ testTimeout: 15000,
30
+ setupFiles: [path.resolve(__dirname, './src/workflow/__tests__/setup.ts')],
31
+ include: ['**/?(*.){test,spec}.?(c|m)[jt]s?(x)'],
32
+ exclude: [
33
+ '**/__mocks__**',
34
+ '**/node_modules/**',
35
+ '**/dist/**',
36
+ '**/lib/**', // lib 编译结果忽略掉
37
+ '**/cypress/**',
38
+ '**/.{idea,git,cache,output,temp}/**',
39
+ '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*',
40
+ ],
41
+ env: {
42
+ ...config({ path: path.resolve(__dirname, './.env/.env.test') }).parsed
43
+ }
44
+ },
45
+ });