Skip to content

Commit 38a6c1a

Browse files
authored
feat: add init and add command (#70)
* feat: add init and add command * chore: zod schema for config
1 parent 8f528b2 commit 38a6c1a

File tree

15 files changed

+913
-126
lines changed

15 files changed

+913
-126
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ package-lock.json
77
.env
88
.DS_Store
99
dist
10+
/tmp

README.md

Lines changed: 98 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,102 @@ pnpm install
4040
pnpm run build
4141
```
4242

43+
## Quick Start
44+
45+
Initialize a new configuration and start ingesting data in minutes:
46+
47+
```bash
48+
# Create a new configuration directory
49+
gql-ingest init ./my-config
50+
51+
# Add a new entity
52+
gql-ingest add users -p ./my-config -f json --fields "id,name,email"
53+
54+
# Run ingestion
55+
gql-ingest -e https://your-api.com/graphql -c ./my-config
56+
```
57+
4358
## Usage
4459

60+
### CLI Commands
61+
62+
#### Initialize Configuration
63+
64+
Create a new configuration directory with example files:
65+
66+
```bash
67+
gql-ingest init [path] [options]
68+
69+
Options:
70+
--no-example Skip creating example entity files
71+
--no-config Skip creating config.yaml
72+
-f, --force Overwrite existing files
73+
-q, --quiet Suppress output
74+
```
75+
76+
This creates:
77+
78+
- `data/` - Data files directory
79+
- `graphql/` - GraphQL mutation files
80+
- `mappings/` - Mapping configuration files
81+
- `config.yaml` - Processing configuration
82+
- Example entity files (by default)
83+
84+
#### Add Entity
85+
86+
Add a new entity to an existing configuration:
87+
88+
```bash
89+
gql-ingest add <entity-name> [options]
90+
91+
Options:
92+
-p, --path <path> Config directory path (default: current directory)
93+
-f, --format <format> Data format (csv, json, yaml, jsonl)
94+
--fields <fields> Comma-separated field names
95+
--mutation <name> GraphQL mutation name
96+
--no-interactive Skip prompts, use defaults only
97+
-q, --quiet Suppress output
98+
```
99+
100+
Interactive mode prompts for format, fields, and mutation name. Use `--no-interactive` with flags for CI/CD.
101+
102+
#### Run Ingestion
103+
104+
Ingest data from configuration into GraphQL API:
105+
106+
```bash
107+
gql-ingest [options]
108+
109+
Options:
110+
-e, --endpoint <url> GraphQL endpoint URL (required)
111+
-c, --config <path> Path to configuration directory (required)
112+
-n, --entities <list> Comma-separated list of entities to process
113+
-h, --headers <headers> JSON string of headers
114+
-f, --format <format> Override data format detection
115+
-q, --quiet Suppress output
116+
```
117+
118+
### CLI Examples
119+
120+
```bash
121+
# Basic usage
122+
gql-ingest \
123+
-e https://your-graphql-api.com/graphql \
124+
-c ./examples/demo
125+
126+
# With authentication headers
127+
gql-ingest \
128+
-e https://your-graphql-api.com/graphql \
129+
-c ./examples/demo \
130+
-h '{"Authorization": "Bearer YOUR_TOKEN"}'
131+
132+
# Process specific entities only
133+
gql-ingest \
134+
-e https://your-graphql-api.com/graphql \
135+
-c ./examples/demo \
136+
-n users,products
137+
```
138+
45139
### Programmatic API
46140

47141
GQL Ingest provides a full programmatic API for integration into your Node.js applications.
@@ -63,7 +157,7 @@ const client = new GQLIngest({
63157
headers: {
64158
Authorization: "Bearer YOUR_TOKEN",
65159
},
66-
logger: createConsoleLogger(), // Optional: enable console logging
160+
logger: createConsoleLogger({ prefix: "my-app" }), // Optional: enable logging with prefix
67161
});
68162

69163
// Ingest all data from a configuration
@@ -152,7 +246,9 @@ const client = new GQLIngest({
152246
client.on("started", (p) => console.log(`Starting ${p.totalEntities} entities`));
153247
client.on("progress", (p) => console.log(`${p.progressPercent.toFixed(1)}% complete`));
154248
client.on("entityStart", (p) => console.log(`Processing ${p.entityName}`));
155-
client.on("entityComplete", (p) => console.log(`${p.entityName}: ${p.metrics.successfulRows} rows`));
249+
client.on("entityComplete", (p) =>
250+
console.log(`${p.entityName}: ${p.metrics.successfulRows} rows`),
251+
);
156252
client.on("rowSuccess", (p) => console.log(`Row ${p.rowIndex} OK`));
157253
client.on("rowFailure", (p) => console.error(`Row ${p.rowIndex} failed: ${p.error.message}`));
158254
client.on("finished", (p) => console.log(`Done in ${p.durationMs}ms`));
@@ -220,55 +316,6 @@ import type {
220316
} from "@jackchuka/gql-ingest";
221317
```
222318

223-
### CLI Options
224-
225-
```bash
226-
gql-ingest [options]
227-
228-
Options:
229-
-V, --version output the version number
230-
-e, --endpoint <url> GraphQL endpoint URL (required)
231-
-c, --config <path> Path to configuration directory (required)
232-
-n, --entities <list> Comma-separated list of specific entities to process
233-
-h, --headers <headers> JSON string of headers to include in requests
234-
-f, --format <format> Override data format detection (csv, json, yaml, jsonl)
235-
-v, --verbose Show detailed request results and responses
236-
--help display help for command
237-
```
238-
239-
### Examples
240-
241-
```bash
242-
# Basic usage
243-
npx @jackchuka/gql-ingest \
244-
--endpoint https://your-graphql-api.com/graphql \
245-
--config ./examples/demo
246-
247-
# With authentication headers
248-
npx @jackchuka/gql-ingest \
249-
--endpoint https://your-graphql-api.com/graphql \
250-
--config ./examples/demo \
251-
--headers '{"Authorization": "Bearer YOUR_TOKEN"}'
252-
253-
# With custom headers
254-
npx @jackchuka/gql-ingest \
255-
--endpoint https://api.example.com/graphql \
256-
--config ./my-config \
257-
--headers '{"X-API-Key": "your-api-key", "Content-Type": "application/json"}'
258-
259-
# Process specific entities only
260-
npx @jackchuka/gql-ingest \
261-
--endpoint https://your-graphql-api.com/graphql \
262-
--config ./examples/demo \
263-
--entities users,products
264-
265-
# Process a single entity
266-
npx @jackchuka/gql-ingest \
267-
--endpoint https://your-graphql-api.com/graphql \
268-
--config ./examples/demo \
269-
--entities items
270-
```
271-
272319
## Parallel Processing 🚀
273320

274321
GQL Ingest supports advanced parallel processing with dependency management for high-performance data ingestion:

esbuild.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const build = async () => {
1919
"csv-parser",
2020
"graphql-request",
2121
"commander",
22+
"@inquirer/prompts",
2223
],
2324
});
2425

examples/api/typescript-usage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ async function basicTypedUsage(): Promise<void> {
2424
headers: {
2525
Authorization: "Bearer YOUR_TOKEN",
2626
},
27-
logger: createConsoleLogger(),
27+
logger: createConsoleLogger({ prefix: "gql-ingest" }), // Optional prefix
2828
formatOverride: "csv",
2929
};
3030

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@jackchuka/gql-ingest",
3-
"version": "3.0.0",
3+
"version": "3.1.0",
44
"description": "A CLI tool for ingesting data from files into a GraphQL API. Supports CSV, JSON, JSONL, and YAML file formats.",
55
"keywords": [
66
"api",
@@ -43,11 +43,13 @@
4343
"prepublishOnly": "pnpm run build:all"
4444
},
4545
"dependencies": {
46+
"@inquirer/prompts": "^8.2.0",
4647
"commander": "^14.0.0",
4748
"csv-parser": "^3.0.0",
4849
"graphql": "16.12.0",
4950
"graphql-request": "^7.2.0",
50-
"js-yaml": "^4.1.0"
51+
"js-yaml": "^4.1.0",
52+
"zod": "^4.3.5"
5153
},
5254
"devDependencies": {
5355
"@types/jest": "^30.0.0",

0 commit comments

Comments
 (0)