@flxbl-dev/cli 0.1.0
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 +185 -0
- package/bin/flxbl +5 -0
- package/dist/codegen/client-generator.d.ts +6 -0
- package/dist/codegen/client-generator.d.ts.map +1 -0
- package/dist/codegen/client-generator.js +46 -0
- package/dist/codegen/client-generator.js.map +1 -0
- package/dist/codegen/codegen-pipeline.d.ts +23 -0
- package/dist/codegen/codegen-pipeline.d.ts.map +1 -0
- package/dist/codegen/codegen-pipeline.js +61 -0
- package/dist/codegen/codegen-pipeline.js.map +1 -0
- package/dist/codegen/enum-generator.d.ts +6 -0
- package/dist/codegen/enum-generator.d.ts.map +1 -0
- package/dist/codegen/enum-generator.js +40 -0
- package/dist/codegen/enum-generator.js.map +1 -0
- package/dist/codegen/index-generator.d.ts +8 -0
- package/dist/codegen/index-generator.d.ts.map +1 -0
- package/dist/codegen/index-generator.js +23 -0
- package/dist/codegen/index-generator.js.map +1 -0
- package/dist/codegen/query-types-generator.d.ts +8 -0
- package/dist/codegen/query-types-generator.d.ts.map +1 -0
- package/dist/codegen/query-types-generator.js +30 -0
- package/dist/codegen/query-types-generator.js.map +1 -0
- package/dist/codegen/relationship-generator.d.ts +6 -0
- package/dist/codegen/relationship-generator.d.ts.map +1 -0
- package/dist/codegen/relationship-generator.js +40 -0
- package/dist/codegen/relationship-generator.js.map +1 -0
- package/dist/codegen/schema-fetcher.d.ts +27 -0
- package/dist/codegen/schema-fetcher.d.ts.map +1 -0
- package/dist/codegen/schema-fetcher.js +42 -0
- package/dist/codegen/schema-fetcher.js.map +1 -0
- package/dist/codegen/type-generator.d.ts +13 -0
- package/dist/codegen/type-generator.d.ts.map +1 -0
- package/dist/codegen/type-generator.js +62 -0
- package/dist/codegen/type-generator.js.map +1 -0
- package/dist/commands/data.d.ts +6 -0
- package/dist/commands/data.d.ts.map +1 -0
- package/dist/commands/data.js +85 -0
- package/dist/commands/data.js.map +1 -0
- package/dist/commands/dev.d.ts +6 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +81 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/generate.d.ts +13 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +69 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +82 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +6 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +68 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +6 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +33 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/schema/create.d.ts +6 -0
- package/dist/commands/schema/create.d.ts.map +1 -0
- package/dist/commands/schema/create.js +466 -0
- package/dist/commands/schema/create.js.map +1 -0
- package/dist/commands/schema/delete.d.ts +6 -0
- package/dist/commands/schema/delete.d.ts.map +1 -0
- package/dist/commands/schema/delete.js +50 -0
- package/dist/commands/schema/delete.js.map +1 -0
- package/dist/commands/schema/diff.d.ts +6 -0
- package/dist/commands/schema/diff.d.ts.map +1 -0
- package/dist/commands/schema/diff.js +144 -0
- package/dist/commands/schema/diff.js.map +1 -0
- package/dist/commands/schema/export.d.ts +6 -0
- package/dist/commands/schema/export.d.ts.map +1 -0
- package/dist/commands/schema/export.js +120 -0
- package/dist/commands/schema/export.js.map +1 -0
- package/dist/commands/schema/index.d.ts +8 -0
- package/dist/commands/schema/index.d.ts.map +1 -0
- package/dist/commands/schema/index.js +32 -0
- package/dist/commands/schema/index.js.map +1 -0
- package/dist/commands/schema/migrate.d.ts +6 -0
- package/dist/commands/schema/migrate.d.ts.map +1 -0
- package/dist/commands/schema/migrate.js +70 -0
- package/dist/commands/schema/migrate.js.map +1 -0
- package/dist/commands/schema/schema-file.d.ts +43 -0
- package/dist/commands/schema/schema-file.d.ts.map +1 -0
- package/dist/commands/schema/schema-file.js +106 -0
- package/dist/commands/schema/schema-file.js.map +1 -0
- package/dist/commands/schema/show.d.ts +15 -0
- package/dist/commands/schema/show.d.ts.map +1 -0
- package/dist/commands/schema/show.js +100 -0
- package/dist/commands/schema/show.js.map +1 -0
- package/dist/commands/schema/template.d.ts +6 -0
- package/dist/commands/schema/template.d.ts.map +1 -0
- package/dist/commands/schema/template.js +110 -0
- package/dist/commands/schema/template.js.map +1 -0
- package/dist/commands/schema/validation.d.ts +87 -0
- package/dist/commands/schema/validation.d.ts.map +1 -0
- package/dist/commands/schema/validation.js +281 -0
- package/dist/commands/schema/validation.js.map +1 -0
- package/dist/commands/schema/versions.d.ts +6 -0
- package/dist/commands/schema/versions.d.ts.map +1 -0
- package/dist/commands/schema/versions.js +64 -0
- package/dist/commands/schema/versions.js.map +1 -0
- package/dist/commands/whoami.d.ts +6 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +58 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/config/loader.d.ts +23 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +47 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/types.d.ts +24 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +5 -0
- package/dist/config/types.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/ui/logger.d.ts +16 -0
- package/dist/ui/logger.d.ts.map +1 -0
- package/dist/ui/logger.js +18 -0
- package/dist/ui/logger.js.map +1 -0
- package/dist/ui/prompts.d.ts +6 -0
- package/dist/ui/prompts.d.ts.map +1 -0
- package/dist/ui/prompts.js +6 -0
- package/dist/ui/prompts.js.map +1 -0
- package/dist/ui/table.d.ts +11 -0
- package/dist/ui/table.d.ts.map +1 -0
- package/dist/ui/table.js +25 -0
- package/dist/ui/table.js.map +1 -0
- package/dist/watcher/schema-watcher.d.ts +30 -0
- package/dist/watcher/schema-watcher.d.ts.map +1 -0
- package/dist/watcher/schema-watcher.js +53 -0
- package/dist/watcher/schema-watcher.js.map +1 -0
- package/package.json +62 -0
package/README.md
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# @flxbl-dev/cli
|
|
2
|
+
|
|
3
|
+
Developer CLI for [FLXBL](https://flxbl.dev) — generate typed TypeScript SDKs from your schema, manage authentication, visualize data in the terminal, and watch for schema changes.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -D @flxbl-dev/cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Authenticate
|
|
15
|
+
flxbl login
|
|
16
|
+
|
|
17
|
+
# Initialize a project (creates flxbl.config.ts)
|
|
18
|
+
flxbl init
|
|
19
|
+
|
|
20
|
+
# Generate typed SDK from your active schema
|
|
21
|
+
flxbl generate
|
|
22
|
+
|
|
23
|
+
# Use the generated client in your code
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { createFlxblClient } from './flxbl/_generated';
|
|
28
|
+
|
|
29
|
+
const db = createFlxblClient({
|
|
30
|
+
instanceUrl: 'https://api.flxbl.dev',
|
|
31
|
+
apiKey: process.env.FLXBL_API_KEY,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const users = await db.users.findMany({ where: { role: 'admin' } });
|
|
35
|
+
const post = await db.posts.create({ title: 'Hello', content: '...' });
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Commands
|
|
39
|
+
|
|
40
|
+
### Authentication
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Interactive login (email/password)
|
|
44
|
+
flxbl login
|
|
45
|
+
|
|
46
|
+
# Login with API key
|
|
47
|
+
flxbl login --api-key flxbl_abc123...
|
|
48
|
+
|
|
49
|
+
# Login to a specific instance
|
|
50
|
+
flxbl login --instance https://api.flxbl.dev
|
|
51
|
+
|
|
52
|
+
# Show current auth status
|
|
53
|
+
flxbl whoami
|
|
54
|
+
|
|
55
|
+
# Remove stored credentials
|
|
56
|
+
flxbl logout
|
|
57
|
+
flxbl logout --all # all instances
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Project Setup
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Interactive setup — creates flxbl.config.ts
|
|
64
|
+
flxbl init
|
|
65
|
+
flxbl init --instance https://api.flxbl.dev --output-dir ./src/flxbl
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Code Generation
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Generate typed SDK from active schema
|
|
72
|
+
flxbl generate
|
|
73
|
+
|
|
74
|
+
# Specify output directory
|
|
75
|
+
flxbl generate --output ./src/generated
|
|
76
|
+
|
|
77
|
+
# Generate with Zod schemas instead of plain interfaces
|
|
78
|
+
flxbl generate --format zod
|
|
79
|
+
|
|
80
|
+
# Pull is an alias for generate
|
|
81
|
+
flxbl pull
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Watch Mode
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Watch for schema changes and auto-regenerate
|
|
88
|
+
flxbl dev
|
|
89
|
+
|
|
90
|
+
# Custom poll interval (default: 3000ms)
|
|
91
|
+
flxbl dev --poll-interval 5000
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Data Viewer
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# View entity data in a terminal table
|
|
98
|
+
flxbl data User
|
|
99
|
+
|
|
100
|
+
# With filters and field selection
|
|
101
|
+
flxbl data User --where '{"role": "admin"}' --fields id,email,role --limit 50
|
|
102
|
+
|
|
103
|
+
# JSON output
|
|
104
|
+
flxbl data Post --format json
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Schema Info
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# Table view of entities and relationships
|
|
111
|
+
flxbl schema
|
|
112
|
+
|
|
113
|
+
# Tree view
|
|
114
|
+
flxbl schema --format tree
|
|
115
|
+
|
|
116
|
+
# Raw JSON
|
|
117
|
+
flxbl schema --format json
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Configuration
|
|
121
|
+
|
|
122
|
+
Create a `flxbl.config.ts` at your project root (or run `flxbl init`):
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
import type { FlxblConfig } from '@flxbl-dev/cli';
|
|
126
|
+
|
|
127
|
+
export default {
|
|
128
|
+
instanceUrl: 'https://api.flxbl.dev',
|
|
129
|
+
outputDir: './flxbl/_generated',
|
|
130
|
+
codegen: {
|
|
131
|
+
format: 'interface', // 'interface' or 'zod'
|
|
132
|
+
includeRelationships: true,
|
|
133
|
+
includeQueryTypes: true,
|
|
134
|
+
},
|
|
135
|
+
dev: {
|
|
136
|
+
pollInterval: 3000,
|
|
137
|
+
},
|
|
138
|
+
} satisfies FlxblConfig;
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The config file is resolved by walking up the directory tree from the current working directory (like `tsconfig.json`). Supports `.ts`, `.js`, and `.mjs` extensions.
|
|
142
|
+
|
|
143
|
+
## Authentication Resolution
|
|
144
|
+
|
|
145
|
+
Auth is resolved in this order:
|
|
146
|
+
|
|
147
|
+
1. CLI flag (`--api-key`)
|
|
148
|
+
2. Environment variable (`FLXBL_API_KEY`, `FLXBL_INSTANCE_URL`)
|
|
149
|
+
3. Project config (`flxbl.config.ts` — for `instanceUrl` only)
|
|
150
|
+
4. Stored credentials (`~/.flxbl/tokens.json` — shared with MCP server)
|
|
151
|
+
|
|
152
|
+
## Generated Output
|
|
153
|
+
|
|
154
|
+
Running `flxbl generate` produces the following files in your output directory:
|
|
155
|
+
|
|
156
|
+
| File | Contents |
|
|
157
|
+
|------|----------|
|
|
158
|
+
| `entities.ts` | TypeScript interfaces for each entity |
|
|
159
|
+
| `create-dtos.ts` | `CreateXInput` / `UpdateXInput` DTOs |
|
|
160
|
+
| `enums.ts` | Union types for ENUM fields |
|
|
161
|
+
| `relationships.ts` | Relationship name union + definition interfaces |
|
|
162
|
+
| `query-types.ts` | Per-entity `WhereClause`, `QueryOptions`, `QueryResult` |
|
|
163
|
+
| `client.ts` | `TypedFlxblClient` with per-entity collections |
|
|
164
|
+
| `index.ts` | Barrel re-export |
|
|
165
|
+
| `_metadata.json` | Generation timestamp, schema version |
|
|
166
|
+
|
|
167
|
+
Add `flxbl/_generated/` to your `.gitignore` — these files are regenerated from the schema.
|
|
168
|
+
|
|
169
|
+
## Environment Variables
|
|
170
|
+
|
|
171
|
+
| Variable | Description |
|
|
172
|
+
|----------|-------------|
|
|
173
|
+
| `FLXBL_INSTANCE_URL` | FLXBL instance URL |
|
|
174
|
+
| `FLXBL_API_KEY` | API key for authentication |
|
|
175
|
+
| `FLXBL_TOKEN_PATH` | Custom token storage path (default: `~/.flxbl/tokens.json`) |
|
|
176
|
+
|
|
177
|
+
## Requirements
|
|
178
|
+
|
|
179
|
+
- Node.js >= 18
|
|
180
|
+
- A FLXBL instance with an active schema
|
|
181
|
+
- `@flxbl-dev/client` as a production dependency (for the generated client)
|
|
182
|
+
|
|
183
|
+
## License
|
|
184
|
+
|
|
185
|
+
MIT
|
package/bin/flxbl
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-generator.d.ts","sourceRoot":"","sources":["../../src/codegen/client-generator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM,CAmD/D"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client Generator — generates client.ts with TypedFlxblClient
|
|
3
|
+
*/
|
|
4
|
+
export function generateClient(entities) {
|
|
5
|
+
const lines = [
|
|
6
|
+
'// Auto-generated by @flxbl-dev/cli — DO NOT EDIT',
|
|
7
|
+
'// Re-run `flxbl generate` to regenerate',
|
|
8
|
+
'',
|
|
9
|
+
"import { FlxblClient, type FlxblClientConfig, type CollectionMethods } from '@flxbl-dev/client';",
|
|
10
|
+
];
|
|
11
|
+
// Import entity types
|
|
12
|
+
const entityImports = entities.map((e) => e.name).join(', ');
|
|
13
|
+
lines.push(`import type { ${entityImports} } from './entities.js';`);
|
|
14
|
+
// Import DTO types
|
|
15
|
+
const dtoImports = entities
|
|
16
|
+
.map((e) => `Create${e.name}Input, Update${e.name}Input`)
|
|
17
|
+
.join(', ');
|
|
18
|
+
lines.push(`import type { ${dtoImports} } from './create-dtos.js';`);
|
|
19
|
+
lines.push('');
|
|
20
|
+
// TypedFlxblClient class
|
|
21
|
+
lines.push(`export class TypedFlxblClient extends FlxblClient {`);
|
|
22
|
+
for (const entity of entities) {
|
|
23
|
+
const propName = toCamelCase(entity.name) + 's';
|
|
24
|
+
lines.push(` readonly ${propName}: CollectionMethods<${entity.name}, Create${entity.name}Input, Update${entity.name}Input>;`);
|
|
25
|
+
}
|
|
26
|
+
lines.push('');
|
|
27
|
+
lines.push(` constructor(config: FlxblClientConfig) {`);
|
|
28
|
+
lines.push(` super(config);`);
|
|
29
|
+
for (const entity of entities) {
|
|
30
|
+
const propName = toCamelCase(entity.name) + 's';
|
|
31
|
+
lines.push(` this.${propName} = this.createCollection<${entity.name}, Create${entity.name}Input, Update${entity.name}Input>('${entity.name}');`);
|
|
32
|
+
}
|
|
33
|
+
lines.push(` }`);
|
|
34
|
+
lines.push(`}`);
|
|
35
|
+
lines.push('');
|
|
36
|
+
// Factory function
|
|
37
|
+
lines.push(`export function createFlxblClient(config: FlxblClientConfig): TypedFlxblClient {`);
|
|
38
|
+
lines.push(` return new TypedFlxblClient(config);`);
|
|
39
|
+
lines.push(`}`);
|
|
40
|
+
lines.push('');
|
|
41
|
+
return lines.join('\n');
|
|
42
|
+
}
|
|
43
|
+
function toCamelCase(name) {
|
|
44
|
+
return name.charAt(0).toLowerCase() + name.slice(1);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=client-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-generator.js","sourceRoot":"","sources":["../../src/codegen/client-generator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,UAAU,cAAc,CAAC,QAAwB;IACrD,MAAM,KAAK,GAAa;QACtB,mDAAmD;QACnD,0CAA0C;QAC1C,EAAE;QACF,kGAAkG;KACnG,CAAC;IAEF,sBAAsB;IACtB,MAAM,aAAa,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7D,KAAK,CAAC,IAAI,CAAC,iBAAiB,aAAa,0BAA0B,CAAC,CAAC;IAErE,mBAAmB;IACnB,MAAM,UAAU,GAAG,QAAQ;SACxB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,gBAAgB,CAAC,CAAC,IAAI,OAAO,CAAC;SACxD,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,KAAK,CAAC,IAAI,CAAC,iBAAiB,UAAU,6BAA6B,CAAC,CAAC;IACrE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,yBAAyB;IACzB,KAAK,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;IAElE,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;QAChD,KAAK,CAAC,IAAI,CACR,cAAc,QAAQ,uBAAuB,MAAM,CAAC,IAAI,WAAW,MAAM,CAAC,IAAI,gBAAgB,MAAM,CAAC,IAAI,SAAS,CACnH,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;IACzD,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAEjC,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;QAChD,KAAK,CAAC,IAAI,CACR,YAAY,QAAQ,4BAA4B,MAAM,CAAC,IAAI,WAAW,MAAM,CAAC,IAAI,gBAAgB,MAAM,CAAC,IAAI,WAAW,MAAM,CAAC,IAAI,KAAK,CACxI,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,mBAAmB;IACnB,KAAK,CAAC,IAAI,CAAC,kFAAkF,CAAC,CAAC;IAC/F,KAAK,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;IACrD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Generation Pipeline
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates all generators to produce the typed SDK output.
|
|
5
|
+
*/
|
|
6
|
+
import type { TenantSchema } from '@flxbl-dev/shared';
|
|
7
|
+
export interface CodegenOptions {
|
|
8
|
+
/** Output directory for generated files */
|
|
9
|
+
outputDir: string;
|
|
10
|
+
/** Output format */
|
|
11
|
+
format: 'interface' | 'zod';
|
|
12
|
+
/** Include relationship types */
|
|
13
|
+
includeRelationships: boolean;
|
|
14
|
+
/** Include query type helpers */
|
|
15
|
+
includeQueryTypes: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface CodegenResult {
|
|
18
|
+
files: string[];
|
|
19
|
+
entityCount: number;
|
|
20
|
+
relationshipCount: number;
|
|
21
|
+
}
|
|
22
|
+
export declare function runCodegenPipeline(schema: TenantSchema, options: CodegenOptions): CodegenResult;
|
|
23
|
+
//# sourceMappingURL=codegen-pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codegen-pipeline.d.ts","sourceRoot":"","sources":["../../src/codegen/codegen-pipeline.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAQtD,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,oBAAoB;IACpB,MAAM,EAAE,WAAW,GAAG,KAAK,CAAC;IAC5B,iCAAiC;IACjC,oBAAoB,EAAE,OAAO,CAAC;IAC9B,iCAAiC;IACjC,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,cAAc,GACtB,aAAa,CA+Df"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Generation Pipeline
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates all generators to produce the typed SDK output.
|
|
5
|
+
*/
|
|
6
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
7
|
+
import { resolve, dirname } from 'node:path';
|
|
8
|
+
import { generateEntityTypes, generateCreateDtos } from './type-generator.js';
|
|
9
|
+
import { generateEnums } from './enum-generator.js';
|
|
10
|
+
import { generateRelationships } from './relationship-generator.js';
|
|
11
|
+
import { generateClient } from './client-generator.js';
|
|
12
|
+
import { generateIndex } from './index-generator.js';
|
|
13
|
+
import { generateQueryTypes } from './query-types-generator.js';
|
|
14
|
+
export function runCodegenPipeline(schema, options) {
|
|
15
|
+
const outDir = resolve(options.outputDir);
|
|
16
|
+
mkdirSync(outDir, { recursive: true });
|
|
17
|
+
const files = [];
|
|
18
|
+
const writeFile = (name, content) => {
|
|
19
|
+
const filePath = resolve(outDir, name);
|
|
20
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
21
|
+
writeFileSync(filePath, content, 'utf-8');
|
|
22
|
+
files.push(name);
|
|
23
|
+
};
|
|
24
|
+
// 1. Entity types
|
|
25
|
+
writeFile('entities.ts', generateEntityTypes(schema.entities));
|
|
26
|
+
// 2. Create/Update DTOs
|
|
27
|
+
writeFile('create-dtos.ts', generateCreateDtos(schema.entities));
|
|
28
|
+
// 3. Enums
|
|
29
|
+
writeFile('enums.ts', generateEnums(schema.entities));
|
|
30
|
+
// 4. Relationships
|
|
31
|
+
if (options.includeRelationships) {
|
|
32
|
+
writeFile('relationships.ts', generateRelationships(schema.relationships, schema.entities));
|
|
33
|
+
}
|
|
34
|
+
// 5. Query types
|
|
35
|
+
if (options.includeQueryTypes) {
|
|
36
|
+
writeFile('query-types.ts', generateQueryTypes(schema.entities));
|
|
37
|
+
}
|
|
38
|
+
// 6. Typed client
|
|
39
|
+
writeFile('client.ts', generateClient(schema.entities));
|
|
40
|
+
// 7. Barrel index
|
|
41
|
+
writeFile('index.ts', generateIndex({
|
|
42
|
+
includeRelationships: options.includeRelationships,
|
|
43
|
+
includeQueryTypes: options.includeQueryTypes,
|
|
44
|
+
}));
|
|
45
|
+
// 8. Metadata
|
|
46
|
+
const metadata = {
|
|
47
|
+
generatedAt: new Date().toISOString(),
|
|
48
|
+
schemaVersion: schema.version,
|
|
49
|
+
schemaId: schema.id,
|
|
50
|
+
generatorVersion: '0.1.0',
|
|
51
|
+
entityCount: schema.entities.length,
|
|
52
|
+
relationshipCount: schema.relationships.length,
|
|
53
|
+
};
|
|
54
|
+
writeFile('_metadata.json', JSON.stringify(metadata, null, 2));
|
|
55
|
+
return {
|
|
56
|
+
files,
|
|
57
|
+
entityCount: schema.entities.length,
|
|
58
|
+
relationshipCount: schema.relationships.length,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=codegen-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codegen-pipeline.js","sourceRoot":"","sources":["../../src/codegen/codegen-pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enum-generator.d.ts","sourceRoot":"","sources":["../../src/codegen/enum-generator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,YAAY,EAAa,MAAM,mBAAmB,CAAC;AAEjE,wBAAgB,aAAa,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM,CAyC9D"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enum Generator — generates enums.ts with union types for ENUM fields
|
|
3
|
+
*/
|
|
4
|
+
import { FieldType } from '@flxbl-dev/shared';
|
|
5
|
+
export function generateEnums(entities) {
|
|
6
|
+
const lines = [
|
|
7
|
+
'// Auto-generated by @flxbl-dev/cli — DO NOT EDIT',
|
|
8
|
+
'// Re-run `flxbl generate` to regenerate',
|
|
9
|
+
'',
|
|
10
|
+
];
|
|
11
|
+
const seen = new Set();
|
|
12
|
+
for (const entity of entities) {
|
|
13
|
+
for (const field of entity.fields) {
|
|
14
|
+
if (field.type === FieldType.ENUM &&
|
|
15
|
+
field.enumValues &&
|
|
16
|
+
field.enumValues.length > 0) {
|
|
17
|
+
// Use EntityName_FieldName as the type name to avoid collisions
|
|
18
|
+
const typeName = `${entity.name}${capitalize(field.name)}`;
|
|
19
|
+
if (seen.has(typeName))
|
|
20
|
+
continue;
|
|
21
|
+
seen.add(typeName);
|
|
22
|
+
const values = field.enumValues.map((v) => `'${v}'`).join(' | ');
|
|
23
|
+
lines.push(`export type ${typeName} = ${values};`);
|
|
24
|
+
// Also export the values as a const array
|
|
25
|
+
const arrayValues = field.enumValues.map((v) => `'${v}'`).join(', ');
|
|
26
|
+
lines.push(`export const ${typeName}Values = [${arrayValues}] as const;`);
|
|
27
|
+
lines.push('');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (lines.length <= 3) {
|
|
32
|
+
lines.push('// No ENUM fields found in the schema');
|
|
33
|
+
lines.push('');
|
|
34
|
+
}
|
|
35
|
+
return lines.join('\n');
|
|
36
|
+
}
|
|
37
|
+
function capitalize(s) {
|
|
38
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=enum-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enum-generator.js","sourceRoot":"","sources":["../../src/codegen/enum-generator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAqB,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEjE,MAAM,UAAU,aAAa,CAAC,QAAwB;IACpD,MAAM,KAAK,GAAa;QACtB,mDAAmD;QACnD,0CAA0C;QAC1C,EAAE;KACH,CAAC;IAEF,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClC,IACE,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI;gBAC7B,KAAK,CAAC,UAAU;gBAChB,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAC3B,CAAC;gBACD,gEAAgE;gBAChE,MAAM,QAAQ,GAAG,GAAG,MAAM,CAAC,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBAE3D,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;oBAAE,SAAS;gBACjC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBAEnB,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACjE,KAAK,CAAC,IAAI,CAAC,eAAe,QAAQ,MAAM,MAAM,GAAG,CAAC,CAAC;gBAEnD,0CAA0C;gBAC1C,MAAM,WAAW,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACrE,KAAK,CAAC,IAAI,CACR,gBAAgB,QAAQ,aAAa,WAAW,aAAa,CAC9D,CAAC;gBACF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;QACpD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,UAAU,CAAC,CAAS;IAC3B,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-generator.d.ts","sourceRoot":"","sources":["../../src/codegen/index-generator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,wBAAgB,aAAa,CAAC,OAAO,EAAE;IACrC,oBAAoB,EAAE,OAAO,CAAC;IAC9B,iBAAiB,EAAE,OAAO,CAAC;CAC5B,GAAG,MAAM,CAsBT"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Index Generator — generates barrel index.ts that re-exports everything
|
|
3
|
+
*/
|
|
4
|
+
export function generateIndex(options) {
|
|
5
|
+
const lines = [
|
|
6
|
+
'// Auto-generated by @flxbl-dev/cli — DO NOT EDIT',
|
|
7
|
+
'// Re-run `flxbl generate` to regenerate',
|
|
8
|
+
'',
|
|
9
|
+
"export * from './entities.js';",
|
|
10
|
+
"export * from './create-dtos.js';",
|
|
11
|
+
"export * from './enums.js';",
|
|
12
|
+
];
|
|
13
|
+
if (options.includeRelationships) {
|
|
14
|
+
lines.push("export * from './relationships.js';");
|
|
15
|
+
}
|
|
16
|
+
if (options.includeQueryTypes) {
|
|
17
|
+
lines.push("export * from './query-types.js';");
|
|
18
|
+
}
|
|
19
|
+
lines.push("export { TypedFlxblClient, createFlxblClient } from './client.js';");
|
|
20
|
+
lines.push('');
|
|
21
|
+
return lines.join('\n');
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=index-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-generator.js","sourceRoot":"","sources":["../../src/codegen/index-generator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,UAAU,aAAa,CAAC,OAG7B;IACC,MAAM,KAAK,GAAa;QACtB,mDAAmD;QACnD,0CAA0C;QAC1C,EAAE;QACF,gCAAgC;QAChC,mCAAmC;QACnC,6BAA6B;KAC9B,CAAC;IAEF,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;IACjF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query Types Generator — generates query-types.ts
|
|
3
|
+
*
|
|
4
|
+
* Provides entity-name union type and per-entity WhereClause/QueryOptions/QueryResult.
|
|
5
|
+
*/
|
|
6
|
+
import type { SchemaEntity } from '@flxbl-dev/shared';
|
|
7
|
+
export declare function generateQueryTypes(entities: SchemaEntity[]): string;
|
|
8
|
+
//# sourceMappingURL=query-types-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-types-generator.d.ts","sourceRoot":"","sources":["../../src/codegen/query-types-generator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM,CA2BnE"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query Types Generator — generates query-types.ts
|
|
3
|
+
*
|
|
4
|
+
* Provides entity-name union type and per-entity WhereClause/QueryOptions/QueryResult.
|
|
5
|
+
*/
|
|
6
|
+
export function generateQueryTypes(entities) {
|
|
7
|
+
const lines = [
|
|
8
|
+
'// Auto-generated by @flxbl-dev/cli — DO NOT EDIT',
|
|
9
|
+
'// Re-run `flxbl generate` to regenerate',
|
|
10
|
+
'',
|
|
11
|
+
"import type { QueryFilter, QueryOptions, QueryResult } from '@flxbl-dev/client';",
|
|
12
|
+
];
|
|
13
|
+
// Import entity types
|
|
14
|
+
const entityImports = entities.map((e) => e.name).join(', ');
|
|
15
|
+
lines.push(`import type { ${entityImports} } from './entities.js';`);
|
|
16
|
+
lines.push('');
|
|
17
|
+
// Entity name union
|
|
18
|
+
const nameUnion = entities.map((e) => `'${e.name}'`).join(' | ');
|
|
19
|
+
lines.push(`export type EntityName = ${nameUnion || 'never'};`);
|
|
20
|
+
lines.push('');
|
|
21
|
+
// Per-entity typed helpers
|
|
22
|
+
for (const entity of entities) {
|
|
23
|
+
lines.push(`export type ${entity.name}Where = { [K in keyof ${entity.name}]?: ${entity.name}[K] | QueryFilter };`);
|
|
24
|
+
lines.push(`export type ${entity.name}QueryOptions = QueryOptions<${entity.name}>;`);
|
|
25
|
+
lines.push(`export type ${entity.name}QueryResult = QueryResult<${entity.name}>;`);
|
|
26
|
+
lines.push('');
|
|
27
|
+
}
|
|
28
|
+
return lines.join('\n');
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=query-types-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-types-generator.js","sourceRoot":"","sources":["../../src/codegen/query-types-generator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,UAAU,kBAAkB,CAAC,QAAwB;IACzD,MAAM,KAAK,GAAa;QACtB,mDAAmD;QACnD,0CAA0C;QAC1C,EAAE;QACF,kFAAkF;KACnF,CAAC;IAEF,sBAAsB;IACtB,MAAM,aAAa,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7D,KAAK,CAAC,IAAI,CAAC,iBAAiB,aAAa,0BAA0B,CAAC,CAAC;IACrE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,oBAAoB;IACpB,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjE,KAAK,CAAC,IAAI,CAAC,4BAA4B,SAAS,IAAI,OAAO,GAAG,CAAC,CAAC;IAChE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,2BAA2B;IAC3B,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,eAAe,MAAM,CAAC,IAAI,yBAAyB,MAAM,CAAC,IAAI,OAAO,MAAM,CAAC,IAAI,sBAAsB,CAAC,CAAC;QACnH,KAAK,CAAC,IAAI,CAAC,eAAe,MAAM,CAAC,IAAI,+BAA+B,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC;QACrF,KAAK,CAAC,IAAI,CAAC,eAAe,MAAM,CAAC,IAAI,6BAA6B,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC;QACnF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Relationship Generator — generates relationships.ts
|
|
3
|
+
*/
|
|
4
|
+
import type { SchemaRelationship, SchemaEntity } from '@flxbl-dev/shared';
|
|
5
|
+
export declare function generateRelationships(relationships: SchemaRelationship[], entities: SchemaEntity[]): string;
|
|
6
|
+
//# sourceMappingURL=relationship-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationship-generator.d.ts","sourceRoot":"","sources":["../../src/codegen/relationship-generator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE1E,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,kBAAkB,EAAE,EACnC,QAAQ,EAAE,YAAY,EAAE,GACvB,MAAM,CAsCR"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Relationship Generator — generates relationships.ts
|
|
3
|
+
*/
|
|
4
|
+
export function generateRelationships(relationships, entities) {
|
|
5
|
+
const lines = [
|
|
6
|
+
'// Auto-generated by @flxbl-dev/cli — DO NOT EDIT',
|
|
7
|
+
'// Re-run `flxbl generate` to regenerate',
|
|
8
|
+
'',
|
|
9
|
+
];
|
|
10
|
+
if (relationships.length === 0) {
|
|
11
|
+
lines.push('// No relationships found in the schema');
|
|
12
|
+
lines.push('');
|
|
13
|
+
lines.push('export type RelationshipName = never;');
|
|
14
|
+
lines.push('');
|
|
15
|
+
return lines.join('\n');
|
|
16
|
+
}
|
|
17
|
+
// Build entity ID -> name map
|
|
18
|
+
const entityMap = new Map(entities.map((e) => [e.id, e.name]));
|
|
19
|
+
// Union type of all relationship names
|
|
20
|
+
const names = relationships.map((r) => `'${r.name}'`);
|
|
21
|
+
lines.push(`export type RelationshipName = ${names.join(' | ')};`);
|
|
22
|
+
lines.push('');
|
|
23
|
+
// Relationship definition interfaces
|
|
24
|
+
for (const rel of relationships) {
|
|
25
|
+
const sourceName = entityMap.get(rel.sourceEntityId) || 'Unknown';
|
|
26
|
+
const targetName = entityMap.get(rel.targetEntityId) || 'Unknown';
|
|
27
|
+
lines.push(`export interface ${capitalize(rel.name)}Relationship {`);
|
|
28
|
+
lines.push(` name: '${rel.name}';`);
|
|
29
|
+
lines.push(` source: '${sourceName}';`);
|
|
30
|
+
lines.push(` target: '${targetName}';`);
|
|
31
|
+
lines.push(` cardinality: '${rel.cardinality}';`);
|
|
32
|
+
lines.push(`}`);
|
|
33
|
+
lines.push('');
|
|
34
|
+
}
|
|
35
|
+
return lines.join('\n');
|
|
36
|
+
}
|
|
37
|
+
function capitalize(s) {
|
|
38
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=relationship-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationship-generator.js","sourceRoot":"","sources":["../../src/codegen/relationship-generator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,UAAU,qBAAqB,CACnC,aAAmC,EACnC,QAAwB;IAExB,MAAM,KAAK,GAAa;QACtB,mDAAmD;QACnD,0CAA0C;QAC1C,EAAE;KACH,CAAC;IAEF,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;QACtD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;QACpD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,8BAA8B;IAC9B,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAE/D,uCAAuC;IACvC,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;IACtD,KAAK,CAAC,IAAI,CAAC,kCAAkC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,qCAAqC;IACrC,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAChC,MAAM,UAAU,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,SAAS,CAAC;QAClE,MAAM,UAAU,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,SAAS,CAAC;QAElE,KAAK,CAAC,IAAI,CAAC,oBAAoB,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACrE,KAAK,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,cAAc,UAAU,IAAI,CAAC,CAAC;QACzC,KAAK,CAAC,IAAI,CAAC,cAAc,UAAU,IAAI,CAAC,CAAC;QACzC,KAAK,CAAC,IAAI,CAAC,mBAAmB,GAAG,CAAC,WAAW,IAAI,CAAC,CAAC;QACnD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,UAAU,CAAC,CAAS;IAC3B,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema Fetcher — retrieves the active schema from the FLXBL API
|
|
3
|
+
*/
|
|
4
|
+
import { FlxblApiClient, type TenantSchema } from '@flxbl-dev/shared';
|
|
5
|
+
export interface ResolvedAuth {
|
|
6
|
+
client: FlxblApiClient;
|
|
7
|
+
instanceUrl: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Resolves authentication and returns a configured FlxblApiClient.
|
|
11
|
+
*
|
|
12
|
+
* Auth resolution order:
|
|
13
|
+
* 1. CLI flag (apiKey option)
|
|
14
|
+
* 2. Environment variable (FLXBL_API_KEY, FLXBL_INSTANCE_URL)
|
|
15
|
+
* 3. Config file (instanceUrl only)
|
|
16
|
+
* 4. Default production URL (https://api.flxbl.dev)
|
|
17
|
+
* 5. Stored credentials (~/.flxbl/tokens.json)
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveAuth(options: {
|
|
20
|
+
apiKey?: string;
|
|
21
|
+
instanceUrl?: string;
|
|
22
|
+
}): Promise<ResolvedAuth>;
|
|
23
|
+
/**
|
|
24
|
+
* Fetches the active schema from the FLXBL API.
|
|
25
|
+
*/
|
|
26
|
+
export declare function fetchActiveSchema(client: FlxblApiClient): Promise<TenantSchema>;
|
|
27
|
+
//# sourceMappingURL=schema-fetcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-fetcher.d.ts","sourceRoot":"","sources":["../../src/codegen/schema-fetcher.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,cAAc,EAKd,KAAK,YAAY,EAClB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,YAAY,CAAC,CAqBxB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,YAAY,CAAC,CAQvB"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema Fetcher — retrieves the active schema from the FLXBL API
|
|
3
|
+
*/
|
|
4
|
+
import { FlxblApiClient, AuthManager, TokenStore, DEFAULT_INSTANCE_URL, } from '@flxbl-dev/shared';
|
|
5
|
+
/**
|
|
6
|
+
* Resolves authentication and returns a configured FlxblApiClient.
|
|
7
|
+
*
|
|
8
|
+
* Auth resolution order:
|
|
9
|
+
* 1. CLI flag (apiKey option)
|
|
10
|
+
* 2. Environment variable (FLXBL_API_KEY, FLXBL_INSTANCE_URL)
|
|
11
|
+
* 3. Config file (instanceUrl only)
|
|
12
|
+
* 4. Default production URL (https://api.flxbl.dev)
|
|
13
|
+
* 5. Stored credentials (~/.flxbl/tokens.json)
|
|
14
|
+
*/
|
|
15
|
+
export async function resolveAuth(options) {
|
|
16
|
+
const apiKey = options.apiKey || process.env.FLXBL_API_KEY;
|
|
17
|
+
const instanceUrl = options.instanceUrl || process.env.FLXBL_INSTANCE_URL || DEFAULT_INSTANCE_URL;
|
|
18
|
+
const config = {
|
|
19
|
+
instanceUrl: instanceUrl.replace(/\/$/, ''),
|
|
20
|
+
apiKey: apiKey || undefined,
|
|
21
|
+
authMode: apiKey ? 'api_key' : 'interactive',
|
|
22
|
+
tokenStorePath: process.env.FLXBL_TOKEN_PATH || '',
|
|
23
|
+
};
|
|
24
|
+
const client = new FlxblApiClient(config);
|
|
25
|
+
if (!apiKey) {
|
|
26
|
+
const tokenStore = new TokenStore();
|
|
27
|
+
const authManager = new AuthManager(config.instanceUrl, tokenStore);
|
|
28
|
+
client.setAuthManager(authManager);
|
|
29
|
+
}
|
|
30
|
+
return { client, instanceUrl: config.instanceUrl };
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Fetches the active schema from the FLXBL API.
|
|
34
|
+
*/
|
|
35
|
+
export async function fetchActiveSchema(client) {
|
|
36
|
+
const schema = await client.getActiveSchema();
|
|
37
|
+
if (!schema) {
|
|
38
|
+
throw new Error('No active schema found. Create and publish a schema first using the FLXBL dashboard or MCP tools.');
|
|
39
|
+
}
|
|
40
|
+
return schema;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=schema-fetcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-fetcher.js","sourceRoot":"","sources":["../../src/codegen/schema-fetcher.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,cAAc,EACd,WAAW,EACX,UAAU,EACV,oBAAoB,GAGrB,MAAM,mBAAmB,CAAC;AAO3B;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAGjC;IACC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAC3D,MAAM,WAAW,GACf,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,oBAAoB,CAAC;IAEhF,MAAM,MAAM,GAA0B;QACpC,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;QAC3C,MAAM,EAAE,MAAM,IAAI,SAAS;QAC3B,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa;QAC5C,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE;KACnD,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;IAE1C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;QACpC,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACpE,MAAM,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;IACrC,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;AACrD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAsB;IAEtB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,eAAe,EAAE,CAAC;IAC9C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,mGAAmG,CACpG,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type Generator — generates entities.ts and create-dtos.ts
|
|
3
|
+
*/
|
|
4
|
+
import { type SchemaEntity } from '@flxbl-dev/shared';
|
|
5
|
+
/**
|
|
6
|
+
* Generates TypeScript interfaces for each entity.
|
|
7
|
+
*/
|
|
8
|
+
export declare function generateEntityTypes(entities: SchemaEntity[]): string;
|
|
9
|
+
/**
|
|
10
|
+
* Generates Create/Update DTO interfaces for each entity.
|
|
11
|
+
*/
|
|
12
|
+
export declare function generateCreateDtos(entities: SchemaEntity[]): string;
|
|
13
|
+
//# sourceMappingURL=type-generator.d.ts.map
|