create-flowdular 0.1.0 → 0.2.1
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/README.md +73 -33
- package/assets/flowdular-banner.png +0 -0
- package/dist/bin.js +8 -13
- package/package.json +3 -2
- package/template/default/README.md +1 -1
- package/template/default/flowdular.json +7 -2
- package/template/default/modules/example/package.json +2 -2
- package/template/default/package.json +1 -1
- package/template/default/platform/octane.config.ts +13 -13
- package/template/default/platform/package.json +1 -1
- package/template/default/platform/src/App.tsrx +6 -4
- package/template/default/platform/src/generated/modules.client.ts +1 -0
- package/template/default/platform/src/generated/modules.server.ts +3 -1
package/README.md
CHANGED
|
@@ -1,51 +1,91 @@
|
|
|
1
|
+
[](https://flowdular.com)
|
|
2
|
+
|
|
1
3
|
# create-flowdular
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/create-flowdular)
|
|
6
|
+
[](https://nodejs.org/)
|
|
7
|
+
[](https://github.com/Flowdular/flowdular/blob/main/LICENSE)
|
|
8
|
+
|
|
9
|
+
Create a Flowdular application with the platform, an example module and local development configuration. Start with embedded PostgreSQL, then extend the application with your own business modules.
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
4
12
|
|
|
5
|
-
|
|
13
|
+
Use Node.js **22.22.2 or newer**:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
6
16
|
npm create flowdular@latest my-app
|
|
17
|
+
cd my-app
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
For this new local application, initialize demo authentication and start the development server:
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
pnpm flowdular setup
|
|
24
|
+
pnpm dev
|
|
7
25
|
```
|
|
8
26
|
|
|
9
|
-
`
|
|
10
|
-
same package. `npx create-flowdular@latest my-app` runs it directly.
|
|
27
|
+
Open [localhost:4310](http://localhost:4310). `setup` opens an interactive wizard for a local demo, PostgreSQL settings or a configuration check. It asks before resetting the local demo database.
|
|
11
28
|
|
|
12
|
-
|
|
13
|
-
module), rewrites the package name, generates this app's secret keys into
|
|
14
|
-
`.env`, installs the pnpm workspace dependencies, and
|
|
15
|
-
makes the first commit.
|
|
29
|
+
`npm create` launches the generator. The generated application uses **pnpm workspaces**. If pnpm is unavailable during installation, the generator invokes its pinned version through `npm exec`.
|
|
16
30
|
|
|
17
|
-
|
|
31
|
+
You can also launch the generator directly:
|
|
18
32
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
| `--pm <manager>` | `pnpm` | Use `pnpm` for this template |
|
|
23
|
-
| `--no-install` | installs | Skip dependency installation |
|
|
24
|
-
| `--no-git` | commits | Skip repository initialization |
|
|
25
|
-
| `-f, --force` | refuses | Scaffold into a directory that is not empty |
|
|
26
|
-
| `-h, --help` | | Show usage |
|
|
27
|
-
| `-v, --version` | | Show the version |
|
|
33
|
+
```sh
|
|
34
|
+
npx create-flowdular@latest my-app
|
|
35
|
+
```
|
|
28
36
|
|
|
29
|
-
## What
|
|
37
|
+
## What you get
|
|
30
38
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
`
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
39
|
+
| Included | Purpose |
|
|
40
|
+
| ----------------- | ---------------------------------------------------------- |
|
|
41
|
+
| `platform/` | Application shell and generated module composition |
|
|
42
|
+
| `modules/` | An example module and space for your business modules |
|
|
43
|
+
| `flowdular.json` | Workspace and module configuration |
|
|
44
|
+
| `.env` | Local database selection and freshly generated secret keys |
|
|
45
|
+
| Workspace scripts | Development server, type checking, tests and validation |
|
|
37
46
|
|
|
38
|
-
The
|
|
39
|
-
manager install, which `--no-install` skips. It collects nothing.
|
|
47
|
+
The generator installs dependencies and initializes Git by default. Local development uses PGlite, an embedded PostgreSQL implementation, so the default setup needs no external database server.
|
|
40
48
|
|
|
41
|
-
##
|
|
49
|
+
## Options
|
|
42
50
|
|
|
43
|
-
|
|
51
|
+
Pass generator flags after `--` when using `npm create`:
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
npm create flowdular@latest my-app -- --no-install --no-git
|
|
44
55
|
cd my-app
|
|
45
|
-
pnpm
|
|
46
|
-
pnpm dev
|
|
56
|
+
pnpm install
|
|
47
57
|
```
|
|
48
58
|
|
|
49
|
-
|
|
59
|
+
| Option | Behavior |
|
|
60
|
+
| ----------------------- | ------------------------------------------------------------- |
|
|
61
|
+
| `-t, --template <name>` | Select a template; defaults to `default` |
|
|
62
|
+
| `--pm pnpm` | Select the package manager supported by this template |
|
|
63
|
+
| `--no-install` | Generate files without installing dependencies |
|
|
64
|
+
| `--no-git` | Skip Git initialization and the initial commit |
|
|
65
|
+
| `-f, --force` | Allow a nonempty target directory; inspect its contents first |
|
|
66
|
+
| `-h, --help` | Show usage |
|
|
67
|
+
| `-v, --version` | Show the generator version |
|
|
68
|
+
|
|
69
|
+
## Configuration and secrets
|
|
70
|
+
|
|
71
|
+
Each run generates separate random 32-byte keys for agent credentials, agent grants, workflow payloads, workflow cursors and authentication MFA. They are written to the new application's `.env`. Keep that file private and provide deployment secrets through your hosting environment.
|
|
72
|
+
|
|
73
|
+
The default adapter is `FD_DATABASE_ADAPTER=pglite`. For a hosted PostgreSQL deployment, follow the [database adapter guide](https://github.com/Flowdular/flowdular/blob/main/docs/database-adapters.md) and [configuration reference](https://github.com/Flowdular/flowdular/blob/main/docs/configuration.md).
|
|
74
|
+
|
|
75
|
+
## Next steps
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
pnpm flowdular doctor
|
|
79
|
+
pnpm verify
|
|
80
|
+
pnpm flowdular help
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Read the [module guide](https://github.com/Flowdular/flowdular/blob/main/docs/modules.md) to extend the application. Business modules from [Official Modules](https://github.com/Flowdular/official-modules) are installed as source through the CLI.
|
|
84
|
+
|
|
85
|
+
## Packages and support
|
|
86
|
+
|
|
87
|
+
- [@flowdular/sdk](https://www.npmjs.com/package/@flowdular/sdk): shared platform APIs, UI and core modules.
|
|
88
|
+
- [flowdular](https://www.npmjs.com/package/flowdular): workspace CLI.
|
|
89
|
+
- [Documentation](https://github.com/Flowdular/flowdular/tree/main/docs) · [Source and issues](https://github.com/Flowdular/flowdular) · [Website](https://flowdular.com)
|
|
50
90
|
|
|
51
|
-
|
|
91
|
+
Licensed under MIT. Repository documentation and source require repository access while the repositories are private.
|
|
Binary file
|
package/dist/bin.js
CHANGED
|
@@ -256,15 +256,7 @@ function nextSteps(input) {
|
|
|
256
256
|
return [
|
|
257
257
|
`cd ${input.directory}`,
|
|
258
258
|
...input.installed ? [] : [`${input.packageManager} install`],
|
|
259
|
-
runScript(
|
|
260
|
-
input.packageManager,
|
|
261
|
-
"flowdular",
|
|
262
|
-
"setup",
|
|
263
|
-
"quick",
|
|
264
|
-
"--apply",
|
|
265
|
-
"--confirm",
|
|
266
|
-
"reset-local-auth"
|
|
267
|
-
),
|
|
259
|
+
runScript(input.packageManager, "flowdular", "setup"),
|
|
268
260
|
runScript(input.packageManager, "dev")
|
|
269
261
|
];
|
|
270
262
|
}
|
|
@@ -275,7 +267,7 @@ function renderNextSteps(input) {
|
|
|
275
267
|
"",
|
|
276
268
|
...nextSteps(input).map((step) => ` ${step}`),
|
|
277
269
|
"",
|
|
278
|
-
`Then open ${DEV_URL} and
|
|
270
|
+
`Then open ${DEV_URL} and follow the setup choice. Local demo uses admin@example.com.`,
|
|
279
271
|
""
|
|
280
272
|
].join("\n");
|
|
281
273
|
}
|
|
@@ -313,20 +305,23 @@ var SECRET_KEYS = [
|
|
|
313
305
|
function generateSecrets() {
|
|
314
306
|
const secrets = {};
|
|
315
307
|
for (const key of SECRET_KEYS)
|
|
316
|
-
secrets[key] = randomBytes(32).toString(
|
|
308
|
+
secrets[key] = randomBytes(32).toString(
|
|
309
|
+
key === "FD_AUTH_MFA_KEY" ? "base64url" : "base64"
|
|
310
|
+
);
|
|
317
311
|
return secrets;
|
|
318
312
|
}
|
|
319
313
|
function renderEnvironmentFile(secrets) {
|
|
320
314
|
return [
|
|
321
315
|
"# Local configuration for this Flowdular app. Never commit it.",
|
|
322
|
-
"# Regenerate
|
|
316
|
+
"# Regenerate service keys with: openssl rand -base64 32",
|
|
317
|
+
"# For FD_AUTH_MFA_KEY use: openssl rand -hex 32",
|
|
323
318
|
"",
|
|
324
319
|
"# Local development runs on embedded PostgreSQL, so there is no server to",
|
|
325
320
|
"# install and no connection string to configure. A deployment sets",
|
|
326
321
|
"# FD_DATABASE_ADAPTER=postgresql and the FD_DATABASE_* URLs instead.",
|
|
327
322
|
"FD_DATABASE_ADAPTER=pglite",
|
|
328
323
|
"",
|
|
329
|
-
"#
|
|
324
|
+
"# 32 byte keys, generated once for this app; MFA uses base64url.",
|
|
330
325
|
...SECRET_KEYS.map((key) => `${key}=${secrets[key]}`),
|
|
331
326
|
""
|
|
332
327
|
].join("\n");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-flowdular",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Scaffold a Flowdular application: the platform, one example module and the secrets a fresh install needs.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
"files": [
|
|
25
25
|
"dist",
|
|
26
26
|
"template",
|
|
27
|
-
"README.md"
|
|
27
|
+
"README.md",
|
|
28
|
+
"assets"
|
|
28
29
|
],
|
|
29
30
|
"engines": {
|
|
30
31
|
"node": ">=22.22.2"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "./node_modules/@flowdular/contracts/schemas/project.schema.json",
|
|
2
|
+
"$schema": "./platform/node_modules/@flowdular/sdk/packages/contracts/schemas/project.schema.json",
|
|
3
3
|
"schemaVersion": 1,
|
|
4
4
|
"architectureVersion": "0.2.0",
|
|
5
5
|
"specs": {
|
|
@@ -10,5 +10,10 @@
|
|
|
10
10
|
"roots": ["modules"],
|
|
11
11
|
"enabled": ["system.core", "auth.core", "example.core"]
|
|
12
12
|
},
|
|
13
|
-
"locales": ["en", "pl"]
|
|
13
|
+
"locales": ["en", "pl"],
|
|
14
|
+
"agent": {
|
|
15
|
+
"policy": "platform/node_modules/@flowdular/sdk/.ai/policies/capabilities.yaml",
|
|
16
|
+
"modelRouting": "platform/node_modules/@flowdular/sdk/.ai/policies/model-routing.yaml",
|
|
17
|
+
"blueprints": "platform/node_modules/@flowdular/sdk/.ai/blueprints"
|
|
18
|
+
}
|
|
14
19
|
}
|
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"octane": "0.1.51",
|
|
18
18
|
"segment-state": "0.2.0",
|
|
19
|
-
"@flowdular/sdk": "0.1
|
|
19
|
+
"@flowdular/sdk": "0.2.1"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@tsrx/typescript-plugin": "0.3.120",
|
|
23
23
|
"@types/node": "24.13.3",
|
|
24
24
|
"typescript": "5.9.3",
|
|
25
|
-
"vitest": "4.1.
|
|
25
|
+
"vitest": "4.1.11"
|
|
26
26
|
}
|
|
27
27
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
assertRouteConflicts,
|
|
3
3
|
createModuleWebRoutes,
|
|
4
|
+
createApplicationRoutes,
|
|
5
|
+
validateApplicationPath,
|
|
4
6
|
} from '@flowdular/sdk/server';
|
|
5
7
|
import { resolve } from 'node:path';
|
|
6
8
|
import { defineConfig, RenderRoute } from '@octanejs/vite-plugin';
|
|
@@ -16,6 +18,7 @@ import {
|
|
|
16
18
|
import {
|
|
17
19
|
composeModuleServer,
|
|
18
20
|
moduleWebMounts,
|
|
21
|
+
applicationBasePath,
|
|
19
22
|
} from './src/generated/modules.server.ts';
|
|
20
23
|
import {
|
|
21
24
|
createPlatformDatabaseProvider,
|
|
@@ -35,8 +38,12 @@ const workspaceRoot = resolve(import.meta.dirname, '..');
|
|
|
35
38
|
const databases = createPlatformDatabaseProvider(
|
|
36
39
|
databaseProviderConfigFromEnvironment(process.env, workspaceRoot),
|
|
37
40
|
);
|
|
41
|
+
const configuredApplicationPath = validateApplicationPath(
|
|
42
|
+
process.env.FD_APPLICATION_PATH ?? applicationBasePath,
|
|
43
|
+
);
|
|
38
44
|
const authRuntime = createAuthRuntime({
|
|
39
45
|
...authRuntimeOptionsFromEnvironment(process.env, workspaceRoot),
|
|
46
|
+
applicationPath: configuredApplicationPath,
|
|
40
47
|
databases,
|
|
41
48
|
});
|
|
42
49
|
|
|
@@ -83,22 +90,17 @@ export default defineConfig({
|
|
|
83
90
|
middlewares: [authRuntime.middleware],
|
|
84
91
|
router: {
|
|
85
92
|
routes: checkedRoutes([
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
new RenderRoute({ path: '/auth/reset-password', entry: SHELL }),
|
|
92
|
-
new RenderRoute({ path: '/auth/accept-invitation', entry: SHELL }),
|
|
93
|
-
new RenderRoute({ path: '/auth/mfa', entry: SHELL }),
|
|
94
|
-
new RenderRoute({ path: '/app', entry: SHELL }),
|
|
95
|
-
new RenderRoute({ path: '/app/:workspace', entry: SHELL }),
|
|
96
|
-
new RenderRoute({ path: '/app/:workspace/:view', entry: SHELL }),
|
|
93
|
+
...createApplicationRoutes({
|
|
94
|
+
path: configuredApplicationPath,
|
|
95
|
+
entry: SHELL,
|
|
96
|
+
publicRoot: moduleWebMounts.some((site) => site.path === '/'),
|
|
97
|
+
}),
|
|
97
98
|
...createAuthRoutes(authRuntime),
|
|
98
99
|
...moduleCompositions.flatMap((composition) => composition.routes),
|
|
99
100
|
...createModuleWebRoutes({
|
|
100
101
|
modules: moduleCompositions,
|
|
101
102
|
mounts: moduleWebMounts,
|
|
103
|
+
applicationPath: configuredApplicationPath,
|
|
102
104
|
resolveIdentity: (context) => {
|
|
103
105
|
const principal = principalFromContext(context);
|
|
104
106
|
return principal
|
|
@@ -110,8 +112,6 @@ export default defineConfig({
|
|
|
110
112
|
: null;
|
|
111
113
|
},
|
|
112
114
|
}),
|
|
113
|
-
new RenderRoute({ path: '/:workspace', entry: SHELL }),
|
|
114
|
-
new RenderRoute({ path: '/:workspace/:view', entry: SHELL }),
|
|
115
115
|
]),
|
|
116
116
|
},
|
|
117
117
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { configureApplicationFromPage } from '@flowdular/sdk/client/routing';
|
|
2
2
|
import {
|
|
3
3
|
ApplicationShell,
|
|
4
4
|
activeLocale,
|
|
@@ -12,11 +12,12 @@ import {
|
|
|
12
12
|
import type { AuthPrincipal } from '@flowdular/sdk/modules/auth';
|
|
13
13
|
import { Head } from '@octanejs/seo';
|
|
14
14
|
import type { RenderRouteProps } from '@octanejs/vite-plugin';
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
createModuleClientContributions,
|
|
17
|
+
applicationBasePath,
|
|
18
|
+
} from './generated/modules.client.ts';
|
|
16
19
|
import './styles.css';
|
|
17
20
|
|
|
18
|
-
configureApplicationRouting(applicationBasePath);
|
|
19
|
-
|
|
20
21
|
interface AuthenticatedAppProps {
|
|
21
22
|
initialUrl: string;
|
|
22
23
|
principal: AuthPrincipal;
|
|
@@ -62,6 +63,7 @@ function AuthenticatedApp(props: AuthenticatedAppProps) @{
|
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
export function App(props?: RenderRouteProps) @{
|
|
66
|
+
configureApplicationFromPage(props, applicationBasePath);
|
|
65
67
|
const initialUrl =
|
|
66
68
|
props?.url ?? (typeof window === 'undefined' ? '/' : window.location.href);
|
|
67
69
|
<Head>
|
|
@@ -4,6 +4,7 @@ import type {
|
|
|
4
4
|
PlatformServerComposition,
|
|
5
5
|
PlatformServerContext,
|
|
6
6
|
} from '@flowdular/sdk/modules/auth/server';
|
|
7
|
+
import type { WebMount } from '@flowdular/sdk/server';
|
|
7
8
|
import { createServerComposition as system_core } from '@flowdular/sdk/modules/system/platform';
|
|
8
9
|
import { createServerComposition as example_core } from '@app/module-example/platform';
|
|
9
10
|
|
|
@@ -28,4 +29,5 @@ export function composeModuleServer(
|
|
|
28
29
|
];
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
export const moduleWebMounts = [] as const;
|
|
32
|
+
export const moduleWebMounts: readonly WebMount[] = [] as const;
|
|
33
|
+
export const applicationBasePath = '/app';
|