supatool 0.1.23 → 0.3.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 +227 -25
- package/dist/bin/helptext.js +106 -20
- package/dist/bin/supatool.js +172 -21
- package/dist/generator/client.js +9 -0
- package/dist/generator/crudGenerator.js +57 -0
- package/dist/generator/docGenerator.js +64 -0
- package/dist/generator/rlsGenerator.js +111 -0
- package/dist/generator/schemaCrudGenerator.js +560 -0
- package/dist/generator/sqlGenerator.js +100 -0
- package/dist/generator/typeGenerator.js +55 -0
- package/dist/generator/types.js +2 -0
- package/dist/parser/modelParser.js +18 -0
- package/dist/sync/config.js +98 -0
- package/dist/sync/definitionExtractor.js +1205 -0
- package/dist/sync/fetchRemoteSchemas.js +369 -0
- package/dist/sync/generateMigration.js +276 -0
- package/dist/sync/index.js +22 -0
- package/dist/sync/migrationRunner.js +271 -0
- package/dist/sync/parseLocalSchemas.js +97 -0
- package/dist/sync/sync.js +208 -0
- package/dist/sync/utils.js +52 -0
- package/dist/sync/writeSchema.js +161 -0
- package/package.json +18 -3
package/README.md
CHANGED
@@ -14,36 +14,88 @@ pnpm add -g supatool
|
|
14
14
|
|
15
15
|
## Usage
|
16
16
|
|
17
|
-
1.
|
17
|
+
### 1. Extract Database Schema (NEW in v0.3.0)
|
18
18
|
|
19
|
+
Extract and categorize all database objects from your Supabase project:
|
20
|
+
|
21
|
+
```bash
|
22
|
+
# Set connection string in environment (recommended)
|
23
|
+
echo "SUPABASE_CONNECTION_STRING=postgresql://..." >> .env.local
|
24
|
+
|
25
|
+
# Extract all database objects with AI-friendly index
|
26
|
+
supatool extract --all -o supabase/schemas
|
27
|
+
|
28
|
+
# Extract only tables and views
|
29
|
+
supatool extract -o supabase/schemas
|
30
|
+
|
31
|
+
# Extract specific tables with pattern
|
32
|
+
supatool extract -t "user_*" -o supabase/schemas
|
33
|
+
|
34
|
+
# Extract from specific schemas (comma-separated)
|
35
|
+
supatool extract --all --schema public,auth,extensions -o supabase/schemas
|
36
|
+
|
37
|
+
# Alternative: specify connection directly
|
38
|
+
supatool extract --all -c "postgresql://..." -o supabase/schemas
|
39
|
+
```
|
40
|
+
|
41
|
+
**Output structure:**
|
19
42
|
```
|
20
|
-
|
43
|
+
supabase/schemas/
|
44
|
+
├── index.md # Human-readable index with comments
|
45
|
+
├── llms.txt # AI-friendly structured data with comments
|
46
|
+
├── tables/ # Table definitions with comments
|
47
|
+
├── views/ # View definitions with comments
|
48
|
+
├── rls/ # RLS policies
|
49
|
+
└── rpc/ # Functions & triggers
|
21
50
|
```
|
22
51
|
|
23
|
-
2.
|
52
|
+
### 2. Generate CRUD Code
|
24
53
|
|
25
|
-
|
54
|
+
Generate TypeScript CRUD functions from Supabase types:
|
55
|
+
|
56
|
+
```bash
|
57
|
+
# Generate from Supabase type definitions
|
26
58
|
supatool crud
|
59
|
+
|
60
|
+
# Generate from schema SQL files
|
61
|
+
supatool gen:schema-crud --include-views --react-query
|
62
|
+
|
63
|
+
# Generate from model YAML
|
64
|
+
supatool gen:crud model.yaml
|
27
65
|
```
|
28
|
-
- Output: `src/integrations/supabase/crud-autogen/`
|
29
66
|
|
30
|
-
|
67
|
+
**Output:** `src/integrations/supabase/crud-autogen/`
|
68
|
+
|
69
|
+
### 3. Environment Configuration
|
70
|
+
|
71
|
+
For security and convenience, set your connection string in environment variables:
|
72
|
+
|
73
|
+
```bash
|
74
|
+
# Create .env.local file with your connection details
|
75
|
+
cat > .env.local << EOF
|
76
|
+
SUPABASE_CONNECTION_STRING=postgresql://user:password@host:port/database
|
77
|
+
# Alternative: use DATABASE_URL
|
78
|
+
DATABASE_URL=postgresql://user:password@host:port/database
|
79
|
+
EOF
|
80
|
+
|
81
|
+
# Now you can run commands without -c flag
|
82
|
+
supatool extract --all -o supabase/schemas
|
83
|
+
```
|
31
84
|
|
32
|
-
|
85
|
+
**Supported environment variables:**
|
86
|
+
- `SUPABASE_CONNECTION_STRING` (preferred)
|
87
|
+
- `DATABASE_URL` (fallback)
|
88
|
+
- `SUPATOOL_MAX_CONCURRENT` (max concurrent table processing, default: 20, max: 50)
|
33
89
|
|
34
|
-
|
35
|
-
```sh
|
36
|
-
supatool help
|
37
|
-
```
|
90
|
+
### 4. Additional Commands
|
38
91
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
```
|
92
|
+
```bash
|
93
|
+
# Show help for all commands
|
94
|
+
supatool help
|
43
95
|
|
44
|
-
|
45
|
-
-
|
46
|
-
|
96
|
+
# Specify custom input/output paths
|
97
|
+
supatool crud -i path/to/types -o path/to/output
|
98
|
+
```
|
47
99
|
|
48
100
|
## Note: Supabase Client Requirement
|
49
101
|
|
@@ -56,22 +108,41 @@ import { createClient } from '@supabase/supabase-js'
|
|
56
108
|
export const supabase = createClient('YOUR_SUPABASE_URL', 'YOUR_SUPABASE_ANON_KEY')
|
57
109
|
```
|
58
110
|
|
59
|
-
## VSCode/Cursor
|
111
|
+
## VSCode/Cursor Integration
|
60
112
|
|
61
|
-
|
113
|
+
Add these tasks to `.vscode/tasks.json` for quick access:
|
62
114
|
|
63
|
-
> **Note:**
|
64
|
-
> After installing supatool, please restart VSCode (or your terminal) before using the task, so that the new command is recognized.
|
115
|
+
> **Note:** Restart VSCode/Cursor after installing supatool to ensure the command is recognized.
|
65
116
|
|
66
117
|
```json
|
67
118
|
{
|
68
119
|
"version": "2.0.0",
|
69
120
|
"tasks": [
|
70
121
|
{
|
71
|
-
"label": "
|
122
|
+
"label": "Extract Schema and Generate CRUD",
|
123
|
+
"type": "shell",
|
124
|
+
"command": "supatool extract --all -o supabase/schemas && supatool gen:schema-crud --react-query",
|
125
|
+
"group": "build",
|
126
|
+
"dependsOn": "setup-env"
|
127
|
+
},
|
128
|
+
{
|
129
|
+
"label": "setup-env",
|
72
130
|
"type": "shell",
|
73
|
-
"command": "
|
131
|
+
"command": "echo 'Ensure SUPABASE_CONNECTION_STRING is set in .env.local'",
|
74
132
|
"group": "build"
|
133
|
+
},
|
134
|
+
{
|
135
|
+
"label": "Generate Types and CRUD (Legacy)",
|
136
|
+
"type": "shell",
|
137
|
+
"command": "mkdir -p shared && npx supabase gen types typescript --project-id ${input:projectId} --schema public > shared/types.ts && supatool crud --force",
|
138
|
+
"group": "build"
|
139
|
+
}
|
140
|
+
],
|
141
|
+
"inputs": [
|
142
|
+
{
|
143
|
+
"id": "projectId",
|
144
|
+
"description": "Supabase project ID",
|
145
|
+
"default": "your_project_id"
|
75
146
|
}
|
76
147
|
]
|
77
148
|
}
|
@@ -128,4 +199,135 @@ For more details, see the project on GitHub: [https://github.com/idea-garage/sup
|
|
128
199
|
|
129
200
|
## Acknowledgements
|
130
201
|
|
131
|
-
This project is inspired by and made possible thanks to the amazing work of [Supabase](https://supabase.com/).
|
202
|
+
This project is inspired by and made possible thanks to the amazing work of [Supabase](https://supabase.com/).
|
203
|
+
|
204
|
+
## Complete Workflow Examples
|
205
|
+
|
206
|
+
### Database-First Development
|
207
|
+
|
208
|
+
Extract your existing database schema and generate CRUD code using [Supabase's declarative schema workflow](https://supabase.com/docs/guides/local-development/declarative-database-schemas):
|
209
|
+
|
210
|
+
```bash
|
211
|
+
# 1. Set connection string in .env.local
|
212
|
+
echo "SUPABASE_CONNECTION_STRING=postgresql://..." >> .env.local
|
213
|
+
|
214
|
+
# 2. Extract all database objects to supabase/schemas (declarative schema format)
|
215
|
+
supatool extract --all -o supabase/schemas
|
216
|
+
|
217
|
+
# 3. Generate migrations from declarative schema
|
218
|
+
supabase db diff -f initial_schema
|
219
|
+
|
220
|
+
# 4. Generate TypeScript types with Supabase CLI
|
221
|
+
npx supabase gen types typescript --local > src/types/database.ts
|
222
|
+
|
223
|
+
# 5. Generate CRUD functions with React Query support
|
224
|
+
supatool gen:schema-crud --include-views --react-query
|
225
|
+
```
|
226
|
+
|
227
|
+
### Model-First Development
|
228
|
+
|
229
|
+
Start from YAML model definitions:
|
230
|
+
|
231
|
+
```bash
|
232
|
+
# 1. Create model definition
|
233
|
+
supatool create model.yaml
|
234
|
+
|
235
|
+
# 2. Generate everything from model
|
236
|
+
supatool gen:all model.yaml
|
237
|
+
```
|
238
|
+
|
239
|
+
### Extract Command Options
|
240
|
+
|
241
|
+
Extract database objects in Supabase declarative schema format:
|
242
|
+
|
243
|
+
```bash
|
244
|
+
# Recommended: Set connection in .env.local first
|
245
|
+
echo "SUPABASE_CONNECTION_STRING=postgresql://..." >> .env.local
|
246
|
+
|
247
|
+
# Extract all database objects to categorized directories (recommended)
|
248
|
+
supatool extract --all -o supabase/schemas
|
249
|
+
# Output: supabase/schemas/{index.md,tables/,views/,rls/,rpc/}
|
250
|
+
# Compatible with: supabase db diff
|
251
|
+
|
252
|
+
# Extract only tables and views
|
253
|
+
supatool extract -o supabase/schemas
|
254
|
+
# Output: supabase/schemas/{index.md,tables/,views/}
|
255
|
+
|
256
|
+
# Extract to single directory (for simple projects)
|
257
|
+
supatool extract --no-separate -o supabase/schemas
|
258
|
+
# Output: supabase/schemas/{index.md,*.sql}
|
259
|
+
|
260
|
+
# Extract with pattern matching
|
261
|
+
supatool extract -t "user_*" -o ./user-tables
|
262
|
+
|
263
|
+
# Extract from specific schemas (default: public)
|
264
|
+
supatool extract --all --schema public,auth,extensions -o supabase/schemas
|
265
|
+
|
266
|
+
# Alternative: specify connection directly
|
267
|
+
supatool extract --all -c "postgresql://..." -o supabase/schemas
|
268
|
+
```
|
269
|
+
|
270
|
+
## New Features (v0.3.0)
|
271
|
+
|
272
|
+
- **🔍 Schema Extraction**: Extract and categorize all database objects (tables, views, RLS, functions, triggers)
|
273
|
+
- **📋 Supabase Declarative Schema**: Fully compliant with [Supabase's declarative database schemas](https://supabase.com/docs/guides/local-development/declarative-database-schemas) workflow
|
274
|
+
- **🤖 AI-Friendly Index**: Auto-generated index.md and llms.txt files for better AI understanding of schema structure
|
275
|
+
- **💬 Comment Support**: Automatically extracts and includes database comments in generated files
|
276
|
+
- **📁 Organized Output**: Separate directories for different object types with flexible organization options
|
277
|
+
- **🎯 Pattern Matching**: Extract specific tables/views using wildcard patterns
|
278
|
+
- **👁️ View Support**: Enhanced CRUD generation with SELECT-only operations for database views
|
279
|
+
- **⚛️ React Query Integration**: Generate modern React hooks for data fetching
|
280
|
+
- **🔧 Flexible Workflows**: Support both database-first and model-first development approaches
|
281
|
+
|
282
|
+
## Changelog
|
283
|
+
|
284
|
+
## Database Comments
|
285
|
+
|
286
|
+
Supatool automatically extracts and includes PostgreSQL comments in all generated files. Comments enhance documentation and AI understanding of your schema.
|
287
|
+
|
288
|
+
### Adding Comments to Your Database
|
289
|
+
|
290
|
+
```sql
|
291
|
+
-- Table comments
|
292
|
+
COMMENT ON TABLE users IS 'User account information and authentication data';
|
293
|
+
|
294
|
+
-- View comments
|
295
|
+
COMMENT ON VIEW user_profiles IS 'Combined user data with profile information';
|
296
|
+
|
297
|
+
-- Function comments
|
298
|
+
COMMENT ON FUNCTION update_timestamp() IS 'Automatically updates the updated_at column';
|
299
|
+
|
300
|
+
-- Custom type comments
|
301
|
+
COMMENT ON TYPE user_status IS 'Enumeration of possible user account statuses';
|
302
|
+
```
|
303
|
+
|
304
|
+
### Comment Integration
|
305
|
+
|
306
|
+
Comments appear in:
|
307
|
+
- **index.md**: Human-readable file listings with descriptions (tables/views only)
|
308
|
+
- **llms.txt**: AI-friendly format (`type:name:path:comment`)
|
309
|
+
- **Generated SQL**: As `COMMENT ON` statements for full schema recreation
|
310
|
+
|
311
|
+
**Example output:**
|
312
|
+
```markdown
|
313
|
+
## Tables
|
314
|
+
- [users](tables/users.sql) - User account information and authentication data
|
315
|
+
- [posts](tables/posts.sql) - User-generated content and blog posts
|
316
|
+
```
|
317
|
+
|
318
|
+
## Changelog
|
319
|
+
|
320
|
+
### v0.3.0
|
321
|
+
- **NEW**: `extract` command for database schema extraction
|
322
|
+
- **NEW**: Full compliance with Supabase declarative database schemas workflow
|
323
|
+
- **NEW**: AI-friendly index.md and llms.txt generation for better schema understanding
|
324
|
+
- **NEW**: Database comment extraction and integration
|
325
|
+
- **NEW**: Organized directory structure (tables/, views/, rls/, rpc/)
|
326
|
+
- **NEW**: Pattern matching for selective extraction
|
327
|
+
- **ENHANCED**: Support for all database object types (RLS, functions, triggers, cron jobs, custom types)
|
328
|
+
- **ENHANCED**: Flexible output options with --no-separate compatibility
|
329
|
+
|
330
|
+
### v0.2.0
|
331
|
+
- Added `gen:` commands for code and schema generation
|
332
|
+
- Enhanced `create` command
|
333
|
+
- Introduced model schema support (`schemas/supatool-data.schema.ts`)
|
package/dist/bin/helptext.js
CHANGED
@@ -1,36 +1,122 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.helpText = void 0;
|
3
|
+
exports.modelSchemaHelp = exports.helpText = void 0;
|
4
4
|
// See: [src/bin/helptext.ts](./src/bin/helptext.ts) from project root
|
5
5
|
// Help text (command section from README, English only)
|
6
6
|
exports.helpText = `
|
7
|
-
Supatool CLI -
|
7
|
+
Supatool CLI - Supabase database schema extraction and TypeScript CRUD generation
|
8
8
|
|
9
9
|
Usage:
|
10
|
-
supatool
|
11
|
-
supatool help
|
10
|
+
supatool <command> [options]
|
12
11
|
|
13
12
|
Commands:
|
14
|
-
|
15
|
-
|
13
|
+
extract Extract and categorize database objects from Supabase
|
14
|
+
gen:schema-crud Generate CRUD code from supabase/schemas SQL files
|
15
|
+
crud Generate CRUD code from Supabase type definitions
|
16
|
+
gen:types Generate TypeScript types from model YAML
|
17
|
+
gen:crud Generate CRUD TypeScript code from model YAML
|
18
|
+
gen:docs Generate Markdown documentation from model YAML
|
19
|
+
gen:sql Generate SQL (tables, relations, RLS/security) from model YAML
|
20
|
+
gen:rls Generate RLS/security SQL from model YAML
|
21
|
+
gen:all Generate all outputs from model YAML
|
22
|
+
create Generate a template model YAML
|
23
|
+
config:init Generate configuration template
|
24
|
+
help Show help
|
16
25
|
|
17
|
-
Options:
|
18
|
-
-
|
19
|
-
-
|
20
|
-
-t, --tables <
|
21
|
-
-
|
22
|
-
-
|
23
|
-
|
26
|
+
Extract Options:
|
27
|
+
-c, --connection <string> Supabase connection string
|
28
|
+
-o, --output-dir <path> Output directory (default: ./supabase/schemas)
|
29
|
+
-t, --tables <pattern> Table pattern with wildcards (default: *)
|
30
|
+
--tables-only Extract only table definitions
|
31
|
+
--views-only Extract only view definitions
|
32
|
+
--all Extract all DB objects (tables, views, RLS, functions, triggers, cron, types)
|
33
|
+
--no-separate Output all objects in same directory
|
34
|
+
--schema <schemas> Target schemas, comma-separated (default: public)
|
24
35
|
|
25
36
|
Examples:
|
37
|
+
# Set connection in .env.local (recommended)
|
38
|
+
echo "SUPABASE_CONNECTION_STRING=postgresql://..." >> .env.local
|
39
|
+
|
40
|
+
# Extract all database objects with AI-friendly index
|
41
|
+
supatool extract --all -o supabase/schemas
|
42
|
+
# Output:
|
43
|
+
# supabase/schemas/index.md (Human-readable index with table/view comments)
|
44
|
+
# supabase/schemas/llms.txt (AI-friendly structured data with comments)
|
45
|
+
# supabase/schemas/tables/*.sql (Tables with comments)
|
46
|
+
# supabase/schemas/views/*.sql (Views with comments)
|
47
|
+
# supabase/schemas/rls/*.sql (RLS policies)
|
48
|
+
# supabase/schemas/rpc/*.sql (Functions & triggers)
|
49
|
+
# supabase/schemas/cron/*.sql (Cron jobs)
|
50
|
+
# supabase/schemas/types/*.sql (Custom types)
|
51
|
+
|
52
|
+
# Extract only tables and views (default)
|
53
|
+
supatool extract -o supabase/schemas
|
54
|
+
|
55
|
+
# Extract to single directory (legacy mode)
|
56
|
+
supatool extract --no-separate -o supabase/schemas
|
57
|
+
|
58
|
+
# Extract specific pattern
|
59
|
+
supatool extract -t "user_*" -o ./user-tables
|
60
|
+
|
61
|
+
# Extract from specific schemas (default: public)
|
62
|
+
supatool extract --all --schema public,auth,extensions -o supabase/schemas
|
63
|
+
|
64
|
+
# Alternative: specify connection directly
|
65
|
+
supatool extract --all -c "postgresql://..." -o supabase/schemas
|
66
|
+
|
67
|
+
# Complete database-first workflow
|
68
|
+
echo "SUPABASE_CONNECTION_STRING=postgresql://..." >> .env.local
|
69
|
+
supatool extract --all -o supabase/schemas
|
70
|
+
supatool gen:schema-crud --include-views --react-query
|
71
|
+
|
72
|
+
# Model-first workflow
|
73
|
+
supatool create model.yaml
|
74
|
+
supatool gen:all model.yaml
|
75
|
+
|
76
|
+
# Legacy CRUD generation
|
26
77
|
supatool crud
|
27
|
-
- Import path: shared/
|
28
|
-
- Export path: src/integrations/supabase/
|
29
78
|
|
30
|
-
|
31
|
-
|
32
|
-
|
79
|
+
Database Comments:
|
80
|
+
Supatool automatically extracts and includes database comments in generated files.
|
81
|
+
|
82
|
+
To add comments to your database objects:
|
83
|
+
|
84
|
+
# Table comments
|
85
|
+
COMMENT ON TABLE users IS 'User account information';eha,
|
86
|
+
|
87
|
+
# View comments
|
88
|
+
COMMENT ON VIEW user_profiles IS 'Combined user data with profile information';
|
89
|
+
|
90
|
+
# Function comments
|
91
|
+
COMMENT ON FUNCTION update_timestamp() IS 'Automatically updates the updated_at column';
|
92
|
+
|
93
|
+
# Custom type comments
|
94
|
+
COMMENT ON TYPE user_status IS 'Enumeration of possible user account statuses';
|
95
|
+
|
96
|
+
Comments will appear in:
|
97
|
+
- index.md: Human-readable list with descriptions (tables/views only)
|
98
|
+
- llms.txt: AI-friendly format (type:name:path:comment)
|
99
|
+
- Generated SQL files: As COMMENT statements
|
100
|
+
`;
|
101
|
+
// Model Schema Usage
|
102
|
+
exports.modelSchemaHelp = `
|
103
|
+
Model Schema Usage (schemas/supatool-data.schema.ts):
|
104
|
+
|
105
|
+
- Import in TypeScript:
|
106
|
+
import { SUPATOOL_MODEL_SCHEMA } from 'supatool/schemas/supatool-data.schema';
|
107
|
+
|
108
|
+
- Validate with ajv:
|
109
|
+
import Ajv from 'ajv';
|
110
|
+
const ajv = new Ajv();
|
111
|
+
const validate = ajv.compile(SUPATOOL_MODEL_SCHEMA);
|
112
|
+
const data = /* your YAML/JSON parsed object */;
|
113
|
+
if (!validate(data)) {
|
114
|
+
console.error(validate.errors);
|
115
|
+
} else {
|
116
|
+
console.log('Valid!');
|
117
|
+
}
|
33
118
|
|
34
|
-
|
35
|
-
|
119
|
+
- Use with AI:
|
120
|
+
const schemaJson = JSON.stringify(SUPATOOL_MODEL_SCHEMA, null, 2);
|
121
|
+
// Pass schemaJson to your AI prompt or API
|
36
122
|
`;
|
package/dist/bin/supatool.js
CHANGED
@@ -1,50 +1,201 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
"use strict";
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
5
|
+
};
|
3
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
4
7
|
// CLI entry point
|
5
8
|
// Subcommand support with commander
|
6
9
|
const commander_1 = require("commander");
|
7
10
|
const index_1 = require("../index");
|
8
|
-
const
|
11
|
+
const helptext_1 = require("./helptext"); // Import help text from external file
|
9
12
|
const package_json_1 = require("../../package.json");
|
13
|
+
const modelParser_1 = require("../parser/modelParser");
|
14
|
+
const docGenerator_1 = require("../generator/docGenerator");
|
15
|
+
const typeGenerator_1 = require("../generator/typeGenerator");
|
16
|
+
const crudGenerator_1 = require("../generator/crudGenerator");
|
17
|
+
const sqlGenerator_1 = require("../generator/sqlGenerator");
|
18
|
+
const rlsGenerator_1 = require("../generator/rlsGenerator");
|
19
|
+
const sync_1 = require("../sync");
|
20
|
+
const definitionExtractor_1 = require("../sync/definitionExtractor");
|
21
|
+
const fs_1 = __importDefault(require("fs"));
|
22
|
+
const path_1 = __importDefault(require("path"));
|
10
23
|
const program = new commander_1.Command();
|
11
24
|
program
|
12
25
|
.name('supatool')
|
13
26
|
.description('Supatool CLI')
|
14
27
|
.version(package_json_1.version);
|
15
|
-
//
|
28
|
+
// extract command
|
16
29
|
program
|
17
|
-
.command('
|
18
|
-
.description('
|
19
|
-
.option('-
|
20
|
-
.option('-
|
21
|
-
.option('-t, --tables <
|
22
|
-
.option('-
|
23
|
-
.
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
30
|
+
.command('extract')
|
31
|
+
.description('Extract and categorize database objects from Supabase')
|
32
|
+
.option('-c, --connection <string>', 'Supabase connection string')
|
33
|
+
.option('-o, --output-dir <path>', 'Output directory', './supabase/schemas')
|
34
|
+
.option('-t, --tables <pattern>', 'Table pattern with wildcards', '*')
|
35
|
+
.option('--tables-only', 'Extract only table definitions')
|
36
|
+
.option('--views-only', 'Extract only view definitions')
|
37
|
+
.option('--all', 'Extract all DB objects (tables, views, RLS, functions, triggers, cron, types)')
|
38
|
+
.option('--no-separate', 'Output all objects in same directory')
|
39
|
+
.option('--schema <schemas>', 'Target schemas, comma-separated (default: public)')
|
40
|
+
.option('--config <path>', 'Configuration file path')
|
41
|
+
.option('-f, --force', 'Force overwrite without confirmation')
|
42
|
+
.action(async (options) => {
|
43
|
+
const config = (0, sync_1.resolveConfig)({
|
44
|
+
connectionString: options.connection
|
45
|
+
}, options.config);
|
46
|
+
if (!config.connectionString) {
|
47
|
+
console.error('Connection string is required. Set it using one of:');
|
48
|
+
console.error('1. --connection option');
|
49
|
+
console.error('2. SUPABASE_CONNECTION_STRING environment variable');
|
50
|
+
console.error('3. DATABASE_URL environment variable');
|
51
|
+
console.error('4. supatool.config.json configuration file');
|
52
|
+
process.exit(1);
|
53
|
+
}
|
54
|
+
try {
|
55
|
+
// --schema オプションの処理
|
56
|
+
let schemas = ['public']; // デフォルト
|
57
|
+
if (options.schema) {
|
58
|
+
schemas = options.schema.split(',').map((s) => s.trim());
|
59
|
+
}
|
60
|
+
await (0, definitionExtractor_1.extractDefinitions)({
|
61
|
+
connectionString: config.connectionString,
|
62
|
+
outputDir: options.outputDir,
|
63
|
+
separateDirectories: options.separate !== false,
|
64
|
+
tablesOnly: options.tablesOnly,
|
65
|
+
viewsOnly: options.viewsOnly,
|
66
|
+
all: options.all,
|
67
|
+
tablePattern: options.tables,
|
68
|
+
force: options.force,
|
69
|
+
schemas: schemas
|
70
|
+
});
|
28
71
|
}
|
29
|
-
|
30
|
-
|
72
|
+
catch (error) {
|
73
|
+
console.error('⚠️ Extraction error:', error);
|
74
|
+
process.exit(1);
|
31
75
|
}
|
32
|
-
|
33
|
-
|
76
|
+
});
|
77
|
+
// config:init サブコマンド
|
78
|
+
program
|
79
|
+
.command('config:init')
|
80
|
+
.description('設定ファイル雛形を生成')
|
81
|
+
.option('-o, --out <path>', '出力先パス', 'supatool.config.json')
|
82
|
+
.action((options) => {
|
83
|
+
(0, sync_1.createConfigTemplate)(options.out);
|
84
|
+
});
|
85
|
+
// gen:types サブコマンド
|
86
|
+
program
|
87
|
+
.command('gen:types <modelPath>')
|
88
|
+
.description('モデルYAMLからTypeScript型定義を生成')
|
89
|
+
.option('-o, --out <path>', '出力先パス', 'docs/generated/types.ts')
|
90
|
+
.action((modelPath, options) => {
|
91
|
+
const model = (0, modelParser_1.parseModelYaml)(modelPath);
|
92
|
+
(0, typeGenerator_1.generateTypesFromModel)(model, options.out);
|
93
|
+
console.log('TypeScript型定義を出力:', options.out);
|
94
|
+
});
|
95
|
+
// gen:crud サブコマンド
|
96
|
+
program
|
97
|
+
.command('gen:crud <modelPath>')
|
98
|
+
.description('Generate CRUD TypeScript code from model YAML')
|
99
|
+
.option('-o, --out <dir>', '出力先ディレクトリ', 'docs/generated/crud')
|
100
|
+
.action((modelPath, options) => {
|
101
|
+
const model = (0, modelParser_1.parseModelYaml)(modelPath);
|
102
|
+
(0, crudGenerator_1.generateCrudFromModel)(model, options.out);
|
103
|
+
console.log('Generated CRUD TypeScript code:', options.out);
|
104
|
+
});
|
105
|
+
// gen:docs サブコマンド
|
106
|
+
program
|
107
|
+
.command('gen:docs <modelPath>')
|
108
|
+
.description('モデルYAMLからドキュメント(Markdown)を生成')
|
109
|
+
.option('-o, --out <path>', 'テーブル定義書出力先', 'docs/generated/table-doc.md')
|
110
|
+
.action((modelPath, options) => {
|
111
|
+
const model = (0, modelParser_1.parseModelYaml)(modelPath);
|
112
|
+
(0, docGenerator_1.generateTableDocMarkdown)(model, options.out);
|
113
|
+
(0, docGenerator_1.generateRelationsMarkdown)(model, 'docs/generated/relations.md');
|
114
|
+
console.log('テーブル定義書を出力:', options.out);
|
115
|
+
console.log('リレーション一覧を出力: docs/generated/relations.md');
|
116
|
+
});
|
117
|
+
// gen:sql サブコマンド
|
118
|
+
program
|
119
|
+
.command('gen:sql <modelPath>')
|
120
|
+
.description('モデルYAMLからテーブル・リレーション・RLS/セキュリティSQLを一括生成')
|
121
|
+
.option('-o, --out <path>', '出力先パス', 'docs/generated/schema.sql')
|
122
|
+
.action((modelPath, options) => {
|
123
|
+
const model = (0, modelParser_1.parseModelYaml)(modelPath);
|
124
|
+
// 一時ファイルに個別出力
|
125
|
+
const tmpSchema = 'docs/generated/.tmp_schema.sql';
|
126
|
+
const tmpRls = 'docs/generated/.tmp_rls.sql';
|
127
|
+
(0, sqlGenerator_1.generateSqlFromModel)(model, tmpSchema);
|
128
|
+
(0, rlsGenerator_1.generateRlsSqlFromModel)(model, tmpRls);
|
129
|
+
// 結合して1ファイルにまとめる
|
130
|
+
const schema = fs_1.default.readFileSync(tmpSchema, 'utf-8');
|
131
|
+
const rls = fs_1.default.readFileSync(tmpRls, 'utf-8');
|
132
|
+
fs_1.default.writeFileSync(options.out, schema + '\n' + rls);
|
133
|
+
fs_1.default.unlinkSync(tmpSchema);
|
134
|
+
fs_1.default.unlinkSync(tmpRls);
|
135
|
+
console.log('テーブル・リレーション・RLS/セキュリティSQLを一括出力:', options.out);
|
136
|
+
});
|
137
|
+
// gen:rls サブコマンド
|
138
|
+
program
|
139
|
+
.command('gen:rls <modelPath>')
|
140
|
+
.description('モデルYAMLからRLS/セキュリティポリシーSQLを生成')
|
141
|
+
.option('-o, --out <path>', '出力先パス', 'docs/generated/rls.sql')
|
142
|
+
.action((modelPath, options) => {
|
143
|
+
const model = (0, modelParser_1.parseModelYaml)(modelPath);
|
144
|
+
(0, rlsGenerator_1.generateRlsSqlFromModel)(model, options.out);
|
145
|
+
console.log('RLS/セキュリティポリシーSQLを出力:', options.out);
|
146
|
+
});
|
147
|
+
// gen:all サブコマンド
|
148
|
+
program
|
149
|
+
.command('gen:all <modelPath>')
|
150
|
+
.description('モデルYAMLから全て一括生成')
|
151
|
+
.action((modelPath) => {
|
152
|
+
const model = (0, modelParser_1.parseModelYaml)(modelPath);
|
153
|
+
(0, typeGenerator_1.generateTypesFromModel)(model, 'docs/generated/types.ts');
|
154
|
+
(0, crudGenerator_1.generateCrudFromModel)(model, 'docs/generated/crud');
|
155
|
+
(0, docGenerator_1.generateTableDocMarkdown)(model, 'docs/generated/table-doc.md');
|
156
|
+
(0, docGenerator_1.generateRelationsMarkdown)(model, 'docs/generated/relations.md');
|
157
|
+
console.log('TypeScript型定義を出力: docs/generated/types.ts');
|
158
|
+
console.log('CRUD関数TypeScriptコードを出力: docs/generated/crud/');
|
159
|
+
console.log('テーブル定義書を出力: docs/generated/table-doc.md');
|
160
|
+
console.log('リレーション一覧を出力: docs/generated/relations.md');
|
161
|
+
});
|
162
|
+
// create サブコマンド
|
163
|
+
program
|
164
|
+
.command('create <template>')
|
165
|
+
.description('テンプレートYAML雛形を生成')
|
166
|
+
.option('-o, --out <path>', '出力先パス', 'docs/model-schema-example.yaml')
|
167
|
+
.action((template, options) => {
|
168
|
+
const srcPath = path_1.default.join(__dirname, '../templates/yaml', `${template}.yaml`);
|
169
|
+
const destPath = options.out;
|
170
|
+
if (!fs_1.default.existsSync(srcPath)) {
|
171
|
+
console.error(`テンプレートが見つかりません: ${srcPath}`);
|
172
|
+
process.exit(1);
|
34
173
|
}
|
35
|
-
|
174
|
+
fs_1.default.copyFileSync(srcPath, destPath);
|
175
|
+
console.log(`テンプレート雛形を生成: ${destPath}`);
|
176
|
+
});
|
177
|
+
// crud コマンド(Supabase型定義→CRUD生成)
|
178
|
+
program
|
179
|
+
.command('crud')
|
180
|
+
.description('Supabase型定義(TypeScript)からCRUD関数TypeScriptコードを生成')
|
181
|
+
.option('-i, --input <path>', '型定義の入力パス', 'shared/')
|
182
|
+
.option('-o, --output <path>', 'CRUDコード出力先', 'src/integrations/supabase/')
|
183
|
+
.option('-t, --tables <names>', '生成対象テーブル(カンマ区切り)')
|
184
|
+
.option('-f, --force', '出力先を強制上書き')
|
185
|
+
.action((options) => {
|
186
|
+
// コマンドライン引数をmain()に渡すため、process.argvをそのまま利用
|
36
187
|
(0, index_1.main)();
|
37
188
|
});
|
38
|
-
// help
|
189
|
+
// helpサブコマンド
|
39
190
|
program
|
40
191
|
.command('help')
|
41
192
|
.description('Show help')
|
42
193
|
.action(() => {
|
43
|
-
console.log(
|
194
|
+
console.log(helptext_1.helpText);
|
44
195
|
});
|
45
196
|
// If no subcommand is specified, show helpText only (do not call main)
|
46
197
|
if (!process.argv.slice(2).length) {
|
47
|
-
console.log(
|
198
|
+
console.log(helptext_1.helpText);
|
48
199
|
process.exit(0);
|
49
200
|
}
|
50
201
|
program.parse(process.argv);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.supabase = void 0;
|
4
|
+
// Supabaseクライアント定義(自動生成/手動編集可)
|
5
|
+
// 日本語コメント
|
6
|
+
const supabase_js_1 = require("@supabase/supabase-js");
|
7
|
+
const supabaseUrl = process.env.SUPABASE_URL || '';
|
8
|
+
const supabaseKey = process.env.SUPABASE_KEY || '';
|
9
|
+
exports.supabase = (0, supabase_js_1.createClient)(supabaseUrl, supabaseKey);
|