@slingr/cli 0.0.2 → 0.0.4

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.
Files changed (251) hide show
  1. package/LICENSE.txt +202 -0
  2. package/README.md +490 -319
  3. package/bin/dev.cmd +2 -2
  4. package/bin/dev.js +5 -5
  5. package/bin/run.cmd +2 -2
  6. package/bin/run.js +4 -4
  7. package/bin/slingr +1 -0
  8. package/dist/commands/build.d.ts +20 -0
  9. package/dist/commands/build.d.ts.map +1 -0
  10. package/dist/commands/build.js +206 -0
  11. package/dist/commands/build.js.map +1 -0
  12. package/dist/commands/create-app.d.ts +0 -1
  13. package/dist/commands/create-app.d.ts.map +1 -1
  14. package/dist/commands/create-app.js +38 -57
  15. package/dist/commands/create-app.js.map +1 -1
  16. package/dist/commands/debug.d.ts +28 -0
  17. package/dist/commands/debug.d.ts.map +1 -0
  18. package/dist/commands/debug.js +474 -0
  19. package/dist/commands/debug.js.map +1 -0
  20. package/dist/commands/ds.d.ts +14 -1
  21. package/dist/commands/ds.d.ts.map +1 -1
  22. package/dist/commands/ds.js +450 -121
  23. package/dist/commands/ds.js.map +1 -1
  24. package/dist/commands/gql.d.ts +1 -1
  25. package/dist/commands/gql.d.ts.map +1 -1
  26. package/dist/commands/gql.js +190 -184
  27. package/dist/commands/gql.js.map +1 -1
  28. package/dist/commands/infra/down.d.ts.map +1 -1
  29. package/dist/commands/infra/down.js +8 -7
  30. package/dist/commands/infra/down.js.map +1 -1
  31. package/dist/commands/infra/up.d.ts.map +1 -1
  32. package/dist/commands/infra/up.js +8 -7
  33. package/dist/commands/infra/up.js.map +1 -1
  34. package/dist/commands/infra/update.d.ts +1 -0
  35. package/dist/commands/infra/update.d.ts.map +1 -1
  36. package/dist/commands/infra/update.js +33 -69
  37. package/dist/commands/infra/update.js.map +1 -1
  38. package/dist/commands/run.d.ts +29 -2
  39. package/dist/commands/run.d.ts.map +1 -1
  40. package/dist/commands/run.js +628 -130
  41. package/dist/commands/run.js.map +1 -1
  42. package/dist/commands/setup.d.ts +1 -1
  43. package/dist/commands/setup.d.ts.map +1 -1
  44. package/dist/commands/setup.js +34 -71
  45. package/dist/commands/setup.js.map +1 -1
  46. package/dist/commands/sync-metadata.d.ts +15 -0
  47. package/dist/commands/sync-metadata.d.ts.map +1 -0
  48. package/dist/commands/sync-metadata.js +225 -0
  49. package/dist/commands/sync-metadata.js.map +1 -0
  50. package/dist/commands/users.d.ts +30 -0
  51. package/dist/commands/users.d.ts.map +1 -0
  52. package/dist/commands/users.js +472 -0
  53. package/dist/commands/users.js.map +1 -0
  54. package/dist/commands/views.d.ts +11 -0
  55. package/dist/commands/views.d.ts.map +1 -0
  56. package/dist/commands/views.js +73 -0
  57. package/dist/commands/views.js.map +1 -0
  58. package/dist/projectStructure.d.ts +2 -2
  59. package/dist/projectStructure.d.ts.map +1 -1
  60. package/dist/projectStructure.js +281 -69
  61. package/dist/projectStructure.js.map +1 -1
  62. package/dist/scripts/generate-metadata.d.ts +13 -0
  63. package/dist/scripts/generate-metadata.d.ts.map +1 -0
  64. package/dist/scripts/generate-metadata.js +412 -0
  65. package/dist/scripts/generate-metadata.js.map +1 -0
  66. package/dist/scripts/generate-metadata.ts +498 -0
  67. package/dist/scripts/generate-schema.d.ts +1 -1
  68. package/dist/scripts/generate-schema.js +168 -74
  69. package/dist/scripts/generate-schema.js.map +1 -1
  70. package/dist/scripts/generate-schema.ts +258 -143
  71. package/dist/templates/.env.template +23 -0
  72. package/dist/templates/.firebaserc.template +5 -0
  73. package/dist/templates/.github/copilot-instructions.md.template +652 -17
  74. package/dist/templates/backend/Dockerfile.template +30 -0
  75. package/dist/templates/config/datasource.ts.template +12 -9
  76. package/dist/templates/config/jest.config.ts +30 -30
  77. package/dist/templates/config/jest.setup.ts +1 -1
  78. package/dist/templates/config/tsconfig.json.template +50 -29
  79. package/dist/templates/dataSources/mysql.ts.template +16 -13
  80. package/dist/templates/dataSources/postgres.ts.template +15 -13
  81. package/dist/templates/dataset-generator-script.ts.template +139 -139
  82. package/dist/templates/datasets/mysql-default/.slingr-schema.json.template +5 -0
  83. package/dist/templates/datasets/mysql-default/Address.jsonl.template +3 -3
  84. package/dist/templates/datasets/mysql-default/App.jsonl.template +4 -4
  85. package/dist/templates/datasets/mysql-default/Company.jsonl.template +3 -3
  86. package/dist/templates/datasets/mysql-default/Person.jsonl.template +2 -2
  87. package/dist/templates/datasets/mysql-default/User.jsonl.template +1 -0
  88. package/dist/templates/datasets/mysql-default/instructions.md.template +1 -0
  89. package/dist/templates/datasets/postgres-default/.slingr-schema.json.template +5 -0
  90. package/dist/templates/datasets/postgres-default/Address.jsonl.template +3 -3
  91. package/dist/templates/datasets/postgres-default/App.jsonl.template +4 -4
  92. package/dist/templates/datasets/postgres-default/Company.jsonl.template +3 -3
  93. package/dist/templates/datasets/postgres-default/Person.jsonl.template +2 -2
  94. package/dist/templates/datasets/postgres-default/User.jsonl.template +1 -0
  95. package/dist/templates/datasets/postgres-default/instructions.md.template +1 -0
  96. package/dist/templates/docker-compose.prod-test.yml.template +32 -0
  97. package/dist/templates/docker-compose.yml.template +24 -0
  98. package/dist/templates/docs/app-description.md.template +33 -33
  99. package/dist/templates/firebase.json.template +68 -0
  100. package/dist/templates/frontend/.umirc.ts.template +23 -0
  101. package/dist/templates/frontend/package.json.template +45 -0
  102. package/dist/templates/frontend/public/config.json +6 -0
  103. package/dist/templates/frontend/public/logo.svg +6 -0
  104. package/dist/templates/frontend/src/app.tsx.template +44 -0
  105. package/dist/templates/frontend/src/global.less.template +117 -0
  106. package/dist/templates/frontend/src/layouts/MainLayout.tsx.template +75 -0
  107. package/dist/templates/frontend/src/types/graphql-augmentation.d.ts.template +44 -0
  108. package/dist/templates/frontend/src/views/customViews/user/UserCreateView.tsx.template +18 -0
  109. package/dist/templates/frontend/src/views/customViews/user/UserEditView.tsx.template +29 -0
  110. package/dist/templates/frontend/src/views/customViews/user/UserReadView.tsx.template +24 -0
  111. package/dist/templates/frontend/src/views/customViews/user/UserTableView.tsx.template +38 -0
  112. package/dist/templates/frontend/src/views/customViews/welcome.tsx.template +34 -0
  113. package/dist/templates/frontend/tsconfig.json.template +50 -0
  114. package/dist/templates/gql/codegen.yml.template +25 -25
  115. package/dist/templates/gql/index.ts.template +17 -24
  116. package/dist/templates/gql/operations.graphql.template +30 -30
  117. package/dist/templates/ops/README.md.template +1045 -0
  118. package/dist/templates/ops/cloudbuild.yaml.template +161 -0
  119. package/dist/templates/ops/scripts/_utils.js.template +217 -0
  120. package/dist/templates/ops/scripts/deploy.js.template +145 -0
  121. package/dist/templates/ops/scripts/setup-gcp.js.template +330 -0
  122. package/dist/templates/ops/scripts/setup-secrets.js.template +76 -0
  123. package/dist/templates/ops/scripts/test-prod-local.js.template +49 -0
  124. package/dist/templates/package.json.template +50 -38
  125. package/dist/templates/pnpm-workspace.yaml.template +3 -0
  126. package/dist/templates/prompt-analysis.md.template +110 -110
  127. package/dist/templates/prompt-script-generation.md.template +258 -258
  128. package/dist/templates/src/Address.ts.template +28 -31
  129. package/dist/templates/src/App.ts.template +17 -61
  130. package/dist/templates/src/Company.ts.template +41 -47
  131. package/dist/templates/src/Models.test.ts.template +654 -654
  132. package/dist/templates/src/Person.test.ts.template +289 -289
  133. package/dist/templates/src/Person.ts.template +90 -105
  134. package/dist/templates/src/actions/index.ts.template +11 -11
  135. package/dist/templates/src/auth/permissions.ts.template +34 -0
  136. package/dist/templates/src/data/App.ts.template +48 -0
  137. package/dist/templates/src/data/User.ts.template +35 -0
  138. package/dist/templates/src/types/gql.d.ts.template +17 -17
  139. package/dist/templates/vscode/extensions.json +4 -3
  140. package/dist/templates/vscode/settings.json +17 -11
  141. package/dist/templates/workspace-package.json.template +21 -0
  142. package/dist/utils/buildCache.d.ts +12 -0
  143. package/dist/utils/buildCache.d.ts.map +1 -0
  144. package/dist/utils/buildCache.js +102 -0
  145. package/dist/utils/buildCache.js.map +1 -0
  146. package/dist/utils/checkFramework.d.ts +27 -0
  147. package/dist/utils/checkFramework.d.ts.map +1 -0
  148. package/dist/utils/checkFramework.js +104 -0
  149. package/dist/utils/checkFramework.js.map +1 -0
  150. package/dist/utils/datasourceParser.d.ts +11 -0
  151. package/dist/utils/datasourceParser.d.ts.map +1 -1
  152. package/dist/utils/datasourceParser.js +154 -56
  153. package/dist/utils/datasourceParser.js.map +1 -1
  154. package/dist/utils/dockerManager.d.ts +25 -0
  155. package/dist/utils/dockerManager.d.ts.map +1 -0
  156. package/dist/utils/dockerManager.js +281 -0
  157. package/dist/utils/dockerManager.js.map +1 -0
  158. package/dist/utils/infraFileParser.d.ts +26 -0
  159. package/dist/utils/infraFileParser.d.ts.map +1 -0
  160. package/dist/utils/infraFileParser.js +75 -0
  161. package/dist/utils/infraFileParser.js.map +1 -0
  162. package/dist/utils/jsonlLoader.d.ts +91 -12
  163. package/dist/utils/jsonlLoader.d.ts.map +1 -1
  164. package/dist/utils/jsonlLoader.js +674 -63
  165. package/dist/utils/jsonlLoader.js.map +1 -1
  166. package/dist/utils/model-analyzer.d.ts.map +1 -1
  167. package/dist/utils/model-analyzer.js +67 -13
  168. package/dist/utils/model-analyzer.js.map +1 -1
  169. package/dist/utils/userManagement.d.ts +57 -0
  170. package/dist/utils/userManagement.d.ts.map +1 -0
  171. package/dist/utils/userManagement.js +288 -0
  172. package/dist/utils/userManagement.js.map +1 -0
  173. package/dist/utils/viewsGenerator.d.ts +15 -0
  174. package/dist/utils/viewsGenerator.d.ts.map +1 -0
  175. package/dist/utils/viewsGenerator.js +311 -0
  176. package/dist/utils/viewsGenerator.js.map +1 -0
  177. package/oclif.manifest.json +445 -20
  178. package/package.json +29 -27
  179. package/src/templates/.env.template +23 -0
  180. package/src/templates/.firebaserc.template +5 -0
  181. package/src/templates/.github/copilot-instructions.md.template +652 -17
  182. package/src/templates/backend/Dockerfile.template +30 -0
  183. package/src/templates/config/datasource.ts.template +12 -9
  184. package/src/templates/config/jest.config.ts +30 -30
  185. package/src/templates/config/jest.setup.ts +1 -1
  186. package/src/templates/config/tsconfig.json.template +50 -29
  187. package/src/templates/dataSources/mysql.ts.template +16 -13
  188. package/src/templates/dataSources/postgres.ts.template +15 -13
  189. package/src/templates/dataset-generator-script.ts.template +139 -139
  190. package/src/templates/datasets/mysql-default/.slingr-schema.json.template +5 -0
  191. package/src/templates/datasets/mysql-default/Address.jsonl.template +3 -3
  192. package/src/templates/datasets/mysql-default/App.jsonl.template +4 -4
  193. package/src/templates/datasets/mysql-default/Company.jsonl.template +3 -3
  194. package/src/templates/datasets/mysql-default/Person.jsonl.template +2 -2
  195. package/src/templates/datasets/mysql-default/User.jsonl.template +1 -0
  196. package/src/templates/datasets/mysql-default/instructions.md.template +1 -0
  197. package/src/templates/datasets/postgres-default/.slingr-schema.json.template +5 -0
  198. package/src/templates/datasets/postgres-default/Address.jsonl.template +3 -3
  199. package/src/templates/datasets/postgres-default/App.jsonl.template +4 -4
  200. package/src/templates/datasets/postgres-default/Company.jsonl.template +3 -3
  201. package/src/templates/datasets/postgres-default/Person.jsonl.template +2 -2
  202. package/src/templates/datasets/postgres-default/User.jsonl.template +1 -0
  203. package/src/templates/datasets/postgres-default/instructions.md.template +1 -0
  204. package/src/templates/docker-compose.prod-test.yml.template +32 -0
  205. package/src/templates/docker-compose.yml.template +24 -0
  206. package/src/templates/docs/app-description.md.template +33 -33
  207. package/src/templates/firebase.json.template +68 -0
  208. package/src/templates/frontend/.umirc.ts.template +23 -0
  209. package/src/templates/frontend/package.json.template +45 -0
  210. package/src/templates/frontend/public/config.json +6 -0
  211. package/src/templates/frontend/public/logo.svg +6 -0
  212. package/src/templates/frontend/src/app.tsx.template +44 -0
  213. package/src/templates/frontend/src/global.less.template +117 -0
  214. package/src/templates/frontend/src/layouts/MainLayout.tsx.template +75 -0
  215. package/src/templates/frontend/src/types/graphql-augmentation.d.ts.template +44 -0
  216. package/src/templates/frontend/src/views/customViews/user/UserCreateView.tsx.template +18 -0
  217. package/src/templates/frontend/src/views/customViews/user/UserEditView.tsx.template +29 -0
  218. package/src/templates/frontend/src/views/customViews/user/UserReadView.tsx.template +24 -0
  219. package/src/templates/frontend/src/views/customViews/user/UserTableView.tsx.template +38 -0
  220. package/src/templates/frontend/src/views/customViews/welcome.tsx.template +34 -0
  221. package/src/templates/frontend/tsconfig.json.template +50 -0
  222. package/src/templates/gql/codegen.yml.template +25 -25
  223. package/src/templates/gql/index.ts.template +17 -24
  224. package/src/templates/gql/operations.graphql.template +30 -30
  225. package/src/templates/ops/README.md.template +1045 -0
  226. package/src/templates/ops/cloudbuild.yaml.template +161 -0
  227. package/src/templates/ops/scripts/_utils.js.template +217 -0
  228. package/src/templates/ops/scripts/deploy.js.template +145 -0
  229. package/src/templates/ops/scripts/setup-gcp.js.template +330 -0
  230. package/src/templates/ops/scripts/setup-secrets.js.template +76 -0
  231. package/src/templates/ops/scripts/test-prod-local.js.template +49 -0
  232. package/src/templates/package.json.template +50 -38
  233. package/src/templates/pnpm-workspace.yaml.template +3 -0
  234. package/src/templates/prompt-analysis.md.template +110 -110
  235. package/src/templates/prompt-script-generation.md.template +258 -258
  236. package/src/templates/src/Address.ts.template +28 -31
  237. package/src/templates/src/App.ts.template +17 -61
  238. package/src/templates/src/Company.ts.template +41 -47
  239. package/src/templates/src/Models.test.ts.template +654 -654
  240. package/src/templates/src/Person.test.ts.template +289 -289
  241. package/src/templates/src/Person.ts.template +90 -105
  242. package/src/templates/src/actions/index.ts.template +11 -11
  243. package/src/templates/src/auth/permissions.ts.template +34 -0
  244. package/src/templates/src/data/App.ts.template +48 -0
  245. package/src/templates/src/data/User.ts.template +35 -0
  246. package/src/templates/src/types/gql.d.ts.template +17 -17
  247. package/src/templates/vscode/extensions.json +4 -3
  248. package/src/templates/vscode/settings.json +17 -11
  249. package/src/templates/workspace-package.json.template +21 -0
  250. package/dist/templates/src/index.ts +0 -66
  251. package/src/templates/src/index.ts +0 -66
@@ -1,259 +1,259 @@
1
- # Generate Realistic Dataset Script: "{{DATASOURCE}}-{{DATASET}}"
2
-
3
- ## ⚠️ CRITICAL: DO NOT MODIFY MODELS
4
- **Your task is to generate a TypeScript script that creates realistic synthetic data.**
5
- **DO NOT modify, suggest changes to, or question the model definitions.**
6
- The models in `src/data/*.ts` are correct and final. Your script must generate data that fits these exact models.
7
-
8
- ---
9
-
10
- ## Project Context
11
- {{PROJECT_DESCRIPTION}}
12
-
13
- ## Task Overview
14
- Generate a **complete, production-ready TypeScript script** that creates {{TOTAL_RECORDS}} realistic records ({{COUNT}} per model) for the dataset `{{DATASOURCE}}-{{DATASET}}`.
15
-
16
- ### Target Models (READ-ONLY, DO NOT MODIFY)
17
- {{MODEL_DESCRIPTIONS}}
18
-
19
- ---
20
-
21
- ## Script Requirements
22
-
23
- ### 1. **Data Realism - Top Priority**
24
- Your generated data MUST be:
25
- - ✅ **Realistic**: Use appropriate Faker.js methods for each field type and name
26
- - ✅ **Coherent**: Related fields must make logical sense together
27
- - ✅ **Domain-appropriate**: Values should reflect real business scenarios
28
- - ✅ **Diverse**: Include typical values, edge cases, and variations
29
-
30
- ### 2. **Smart Field Generation**
31
- Use intelligent generation based on field names and types:
32
-
33
- ```typescript
34
- // ❌ BAD: Generic random data
35
- firstName: faker.lorem.word() // → "dolor"
36
-
37
- // ✅ GOOD: Contextual, realistic data
38
- firstName: faker.person.firstName() // → "María"
39
- ```
40
-
41
- **Field Name Patterns to Handle:**
42
- - `firstName`, `first_name` → `faker.person.firstName()`
43
- - `lastName`, `last_name` → `faker.person.lastName()`
44
- - `email` → `faker.internet.email()`
45
- - `phone`, `phoneNumber` → `faker.phone.number()`
46
- - `age` → `faker.number.int({ min: 18, max: 85 })`
47
- - `company`, `companyName` → `faker.company.name()`
48
- - `address`, `street` → `faker.location.streetAddress()`
49
- - `city` → `faker.location.city()`
50
- - `country` → `faker.location.country()`
51
- - `zipCode`, `postalCode` → `faker.location.zipCode()`
52
- - `price`, `amount` → Appropriate range based on context
53
- - `description` → `faker.lorem.paragraph()` or `faker.commerce.productDescription()`
54
- - `url`, `website` → `faker.internet.url()`
55
- - `date`, `createdAt` → `faker.date.past()` or `faker.date.recent()`
56
-
57
- ### 3. **Field Constraint Compliance**
58
- Your script MUST respect ALL model constraints:
59
- - ✅ **Required fields**: Never null/undefined when required
60
- - ✅ **Length constraints**: Stay within minLength/maxLength bounds
61
- - ✅ **Numeric ranges**: Respect min/max values
62
- - ✅ **Regex patterns**: Generate values that match the pattern
63
- - ✅ **Conditional required/available**: Handle age-dependent fields correctly
64
-
65
- ### 4. **Relationship Handling**
66
- For compositions and references:
67
- - **Compositions**: Generate complete nested objects with all required fields
68
- - **References**: Reuse previously generated records when possible
69
- - **Consistency**: Ensure referential integrity across related models
70
-
71
- ### 5. **Conditional Logic**
72
- Handle field dependencies correctly:
73
-
74
- ```typescript
75
- // Example: parentEmail only required if age < 18
76
- const age = faker.number.int({ min: 1, max: 90 });
77
- const person = {
78
- age,
79
- parentEmail: age < 18 ? faker.internet.email() : undefined,
80
- // ... other fields
81
- };
82
- ```
83
-
84
- ---
85
-
86
- ## Script Template
87
-
88
- Complete this template with realistic data generation:
89
-
90
- ```typescript
91
- /**
92
- * Realistic Dataset Generator for {{PROJECT_NAME}}
93
- * Dataset: {{DATASOURCE}}-{{DATASET}}
94
- * Generated: {{TIMESTAMP}}
95
- *
96
- * ⚠️ This script generates synthetic data for testing.
97
- * All data must pass model validation constraints.
98
- */
99
-
100
- import { faker } from '@faker-js/faker';
101
- import fs from 'fs-extra';
102
- import path from 'path';
103
-
104
- class {{DATASET_CLASS_NAME}}Generator {
105
- private outputDir: string;
106
-
107
- constructor() {
108
- this.outputDir = path.join(
109
- process.cwd(),
110
- 'src',
111
- 'datasets',
112
- '{{DATASOURCE}}-{{DATASET}}'
113
- );
114
-
115
- // Set seed for reproducible results
116
- faker.seed({{SEED}});
117
-
118
- // Use locale: {{LOCALE}}
119
- // faker.locale = '{{LOCALE}}';
120
- }
121
-
122
- async generateAll(): Promise<void> {
123
- console.log('🎯 Generating {{TOTAL_RECORDS}} realistic records...\n');
124
- await fs.ensureDir(this.outputDir);
125
-
126
- // TODO: Call generation methods in dependency order
127
- // Models with no dependencies should be generated first
128
- // Example:
129
- // await this.generateAddressData();
130
- // await this.generatePersonData();
131
-
132
- console.log('\n🎉 Dataset generation completed successfully!');
133
- console.log(`📁 Output: ${this.outputDir}`);
134
- console.log('\n💡 Next step: slingr ds {{DATASOURCE}} load {{DATASET}}');
135
- }
136
-
137
- // TODO: Implement generation methods for each model
138
- // Use the examples below as templates:
139
-
140
- /**
141
- * Example generation method - adapt for each model
142
- */
143
- private async generateExampleData(): Promise<void> {
144
- console.log('📝 Generating Example records...');
145
-
146
- const records = [];
147
- for (let i = 0; i < {{COUNT}}; i++) {
148
- const record = {
149
- // Generate each field with appropriate Faker method
150
- // id: faker.string.uuid(), // if not auto-generated
151
- // name: faker.person.fullName(),
152
- // email: faker.internet.email(),
153
- // age: faker.number.int({ min: 18, max: 85 }),
154
- // createdAt: faker.date.past().toISOString(),
155
- // isActive: faker.datatype.boolean(),
156
- };
157
-
158
- records.push(record);
159
- }
160
-
161
- await this.saveToFile(records, 'Example');
162
- console.log(`✅ Generated ${records.length} Example records`);
163
- }
164
-
165
- /**
166
- * Save records to JSONL file
167
- */
168
- private async saveToFile<T>(records: T[], modelName: string): Promise<void> {
169
- const filePath = path.join(this.outputDir, `${modelName}.jsonl`);
170
- const jsonlContent = records.map(r => JSON.stringify(r)).join('\n');
171
- await fs.writeFile(filePath, jsonlContent, 'utf-8');
172
- }
173
- }
174
-
175
- // Execute if run directly
176
- if (require.main === module) {
177
- new {{DATASET_CLASS_NAME}}Generator()
178
- .generateAll()
179
- .then(() => {
180
- console.log('✨ Success! Dataset is ready to load.');
181
- process.exit(0);
182
- })
183
- .catch((error) => {
184
- console.error('❌ Generation failed:', error.message);
185
- console.error(error.stack);
186
- process.exit(1);
187
- });
188
- }
189
-
190
- export { {{DATASET_CLASS_NAME}}Generator };
191
- ```
192
-
193
- ---
194
-
195
- ## Your Deliverable
196
-
197
- Provide a **complete, runnable TypeScript script** that:
198
-
199
- 1. ✅ Generates {{COUNT}} realistic records for each of the {{TOTAL_MODELS}} models
200
- 2. ✅ Uses appropriate Faker.js methods based on field names and types
201
- 3. ✅ Respects ALL field constraints (required, min/max, regex, etc.)
202
- 4. ✅ Handles conditional fields correctly (e.g., age-based requirements)
203
- 5. ✅ Creates coherent data where related fields make logical sense
204
- 6. ✅ Maintains referential integrity for relationships
205
- 7. ✅ Includes proper error handling and logging
206
- 8. ✅ Can be executed with: `npm run build && node dist/scripts/generate-{{DATASOURCE}}-{{DATASET}}.js`
207
-
208
- ---
209
-
210
- ## Quality Checklist
211
-
212
- Before providing your script, verify:
213
-
214
- - [ ] All model field names are spelled correctly
215
- - [ ] Each field uses an appropriate Faker.js method
216
- - [ ] Required fields are never null/undefined
217
- - [ ] Length and numeric constraints are respected
218
- - [ ] Conditional logic (age-based, etc.) is implemented
219
- - [ ] Relationships are handled properly
220
- - [ ] The script has no syntax errors
221
- - [ ] All imports are correct
222
- - [ ] The script is complete and ready to run
223
-
224
- ---
225
-
226
- ## Example of Good vs. Bad Data Generation
227
-
228
- ### ❌ Bad Example (Avoid This):
229
- ```typescript
230
- {
231
- firstName: faker.lorem.word(), // → "dolor"
232
- lastName: faker.lorem.word(), // → "ipsum"
233
- email: faker.lorem.word(), // → "sit" (invalid!)
234
- age: faker.number.int({ min: 0, max: 200 }), // → 187 (unrealistic)
235
- phoneNumber: faker.lorem.word(), // → "amet" (invalid!)
236
- }
237
- ```
238
-
239
- ### ✅ Good Example (Follow This):
240
- ```typescript
241
- {
242
- firstName: faker.person.firstName(), // → "María"
243
- lastName: faker.person.lastName(), // → "García"
244
- email: faker.internet.email(), // → "maria.garcia@example.com"
245
- age: faker.number.int({ min: 18, max: 85 }), // → 34 (realistic)
246
- phoneNumber: faker.phone.number(), // → "+1-234-567-8900"
247
- }
248
- ```
249
-
250
- ---
251
-
252
- ## Technical Details
253
- - **Framework**: Slingr Framework (TypeScript + TypeORM)
254
- - **Output Format**: JSONL (one JSON object per line)
255
- - **Library**: @faker-js/faker (already installed)
256
- - **Seed**: {{SEED}} (for reproducible results)
257
- - **Locale**: {{LOCALE}}
258
-
1
+ # Generate Realistic Dataset Script: "{{DATASOURCE}}-{{DATASET}}"
2
+
3
+ ## ⚠️ CRITICAL: DO NOT MODIFY MODELS
4
+ **Your task is to generate a TypeScript script that creates realistic synthetic data.**
5
+ **DO NOT modify, suggest changes to, or question the model definitions.**
6
+ The models in `src/data/*.ts` are correct and final. Your script must generate data that fits these exact models.
7
+
8
+ ---
9
+
10
+ ## Project Context
11
+ {{PROJECT_DESCRIPTION}}
12
+
13
+ ## Task Overview
14
+ Generate a **complete, production-ready TypeScript script** that creates {{TOTAL_RECORDS}} realistic records ({{COUNT}} per model) for the dataset `{{DATASOURCE}}-{{DATASET}}`.
15
+
16
+ ### Target Models (READ-ONLY, DO NOT MODIFY)
17
+ {{MODEL_DESCRIPTIONS}}
18
+
19
+ ---
20
+
21
+ ## Script Requirements
22
+
23
+ ### 1. **Data Realism - Top Priority**
24
+ Your generated data MUST be:
25
+ - ✅ **Realistic**: Use appropriate Faker.js methods for each field type and name
26
+ - ✅ **Coherent**: Related fields must make logical sense together
27
+ - ✅ **Domain-appropriate**: Values should reflect real business scenarios
28
+ - ✅ **Diverse**: Include typical values, edge cases, and variations
29
+
30
+ ### 2. **Smart Field Generation**
31
+ Use intelligent generation based on field names and types:
32
+
33
+ ```typescript
34
+ // ❌ BAD: Generic random data
35
+ firstName: faker.lorem.word() // → "dolor"
36
+
37
+ // ✅ GOOD: Contextual, realistic data
38
+ firstName: faker.person.firstName() // → "María"
39
+ ```
40
+
41
+ **Field Name Patterns to Handle:**
42
+ - `firstName`, `first_name` → `faker.person.firstName()`
43
+ - `lastName`, `last_name` → `faker.person.lastName()`
44
+ - `email` → `faker.internet.email()`
45
+ - `phone`, `phoneNumber` → `faker.phone.number()`
46
+ - `age` → `faker.number.int({ min: 18, max: 85 })`
47
+ - `company`, `companyName` → `faker.company.name()`
48
+ - `address`, `street` → `faker.location.streetAddress()`
49
+ - `city` → `faker.location.city()`
50
+ - `country` → `faker.location.country()`
51
+ - `zipCode`, `postalCode` → `faker.location.zipCode()`
52
+ - `price`, `amount` → Appropriate range based on context
53
+ - `description` → `faker.lorem.paragraph()` or `faker.commerce.productDescription()`
54
+ - `url`, `website` → `faker.internet.url()`
55
+ - `date`, `createdAt` → `faker.date.past()` or `faker.date.recent()`
56
+
57
+ ### 3. **Field Constraint Compliance**
58
+ Your script MUST respect ALL model constraints:
59
+ - ✅ **Required fields**: Never null/undefined when required
60
+ - ✅ **Length constraints**: Stay within minLength/maxLength bounds
61
+ - ✅ **Numeric ranges**: Respect min/max values
62
+ - ✅ **Regex patterns**: Generate values that match the pattern
63
+ - ✅ **Conditional required/available**: Handle age-dependent fields correctly
64
+
65
+ ### 4. **Relationship Handling**
66
+ For compositions and references:
67
+ - **Compositions**: Generate complete nested objects with all required fields
68
+ - **References**: Reuse previously generated records when possible
69
+ - **Consistency**: Ensure referential integrity across related models
70
+
71
+ ### 5. **Conditional Logic**
72
+ Handle field dependencies correctly:
73
+
74
+ ```typescript
75
+ // Example: parentEmail only required if age < 18
76
+ const age = faker.number.int({ min: 1, max: 90 });
77
+ const person = {
78
+ age,
79
+ parentEmail: age < 18 ? faker.internet.email() : undefined,
80
+ // ... other fields
81
+ };
82
+ ```
83
+
84
+ ---
85
+
86
+ ## Script Template
87
+
88
+ Complete this template with realistic data generation:
89
+
90
+ ```typescript
91
+ /**
92
+ * Realistic Dataset Generator for {{PROJECT_NAME}}
93
+ * Dataset: {{DATASOURCE}}-{{DATASET}}
94
+ * Generated: {{TIMESTAMP}}
95
+ *
96
+ * ⚠️ This script generates synthetic data for testing.
97
+ * All data must pass model validation constraints.
98
+ */
99
+
100
+ import { faker } from '@faker-js/faker';
101
+ import fs from 'fs-extra';
102
+ import path from 'path';
103
+
104
+ class {{DATASET_CLASS_NAME}}Generator {
105
+ private outputDir: string;
106
+
107
+ constructor() {
108
+ this.outputDir = path.join(
109
+ process.cwd(),
110
+ 'src',
111
+ 'datasets',
112
+ '{{DATASOURCE}}-{{DATASET}}'
113
+ );
114
+
115
+ // Set seed for reproducible results
116
+ faker.seed({{SEED}});
117
+
118
+ // Use locale: {{LOCALE}}
119
+ // faker.locale = '{{LOCALE}}';
120
+ }
121
+
122
+ async generateAll(): Promise<void> {
123
+ console.log('🎯 Generating {{TOTAL_RECORDS}} realistic records...\n');
124
+ await fs.ensureDir(this.outputDir);
125
+
126
+ // TODO: Call generation methods in dependency order
127
+ // Models with no dependencies should be generated first
128
+ // Example:
129
+ // await this.generateAddressData();
130
+ // await this.generatePersonData();
131
+
132
+ console.log('\n🎉 Dataset generation completed successfully!');
133
+ console.log(`📁 Output: ${this.outputDir}`);
134
+ console.log('\n💡 Next step: slingr ds {{DATASOURCE}} load {{DATASET}}');
135
+ }
136
+
137
+ // TODO: Implement generation methods for each model
138
+ // Use the examples below as templates:
139
+
140
+ /**
141
+ * Example generation method - adapt for each model
142
+ */
143
+ private async generateExampleData(): Promise<void> {
144
+ console.log('📝 Generating Example records...');
145
+
146
+ const records = [];
147
+ for (let i = 0; i < {{COUNT}}; i++) {
148
+ const record = {
149
+ // Generate each field with appropriate Faker method
150
+ // id: faker.string.uuid(), // if not auto-generated
151
+ // name: faker.person.fullName(),
152
+ // email: faker.internet.email(),
153
+ // age: faker.number.int({ min: 18, max: 85 }),
154
+ // createdAt: faker.date.past().toISOString(),
155
+ // isActive: faker.datatype.boolean(),
156
+ };
157
+
158
+ records.push(record);
159
+ }
160
+
161
+ await this.saveToFile(records, 'Example');
162
+ console.log(`✅ Generated ${records.length} Example records`);
163
+ }
164
+
165
+ /**
166
+ * Save records to JSONL file
167
+ */
168
+ private async saveToFile<T>(records: T[], modelName: string): Promise<void> {
169
+ const filePath = path.join(this.outputDir, `${modelName}.jsonl`);
170
+ const jsonlContent = records.map(r => JSON.stringify(r)).join('\n');
171
+ await fs.writeFile(filePath, jsonlContent, 'utf-8');
172
+ }
173
+ }
174
+
175
+ // Execute if run directly
176
+ if (require.main === module) {
177
+ new {{DATASET_CLASS_NAME}}Generator()
178
+ .generateAll()
179
+ .then(() => {
180
+ console.log('✨ Success! Dataset is ready to load.');
181
+ process.exit(0);
182
+ })
183
+ .catch((error) => {
184
+ console.error('❌ Generation failed:', error.message);
185
+ console.error(error.stack);
186
+ process.exit(1);
187
+ });
188
+ }
189
+
190
+ export { {{DATASET_CLASS_NAME}}Generator };
191
+ ```
192
+
193
+ ---
194
+
195
+ ## Your Deliverable
196
+
197
+ Provide a **complete, runnable TypeScript script** that:
198
+
199
+ 1. ✅ Generates {{COUNT}} realistic records for each of the {{TOTAL_MODELS}} models
200
+ 2. ✅ Uses appropriate Faker.js methods based on field names and types
201
+ 3. ✅ Respects ALL field constraints (required, min/max, regex, etc.)
202
+ 4. ✅ Handles conditional fields correctly (e.g., age-based requirements)
203
+ 5. ✅ Creates coherent data where related fields make logical sense
204
+ 6. ✅ Maintains referential integrity for relationships
205
+ 7. ✅ Includes proper error handling and logging
206
+ 8. ✅ Can be executed with: `pnpm run build && node dist/scripts/generate-{{DATASOURCE}}-{{DATASET}}.js`
207
+
208
+ ---
209
+
210
+ ## Quality Checklist
211
+
212
+ Before providing your script, verify:
213
+
214
+ - [ ] All model field names are spelled correctly
215
+ - [ ] Each field uses an appropriate Faker.js method
216
+ - [ ] Required fields are never null/undefined
217
+ - [ ] Length and numeric constraints are respected
218
+ - [ ] Conditional logic (age-based, etc.) is implemented
219
+ - [ ] Relationships are handled properly
220
+ - [ ] The script has no syntax errors
221
+ - [ ] All imports are correct
222
+ - [ ] The script is complete and ready to run
223
+
224
+ ---
225
+
226
+ ## Example of Good vs. Bad Data Generation
227
+
228
+ ### ❌ Bad Example (Avoid This):
229
+ ```typescript
230
+ {
231
+ firstName: faker.lorem.word(), // → "dolor"
232
+ lastName: faker.lorem.word(), // → "ipsum"
233
+ email: faker.lorem.word(), // → "sit" (invalid!)
234
+ age: faker.number.int({ min: 0, max: 200 }), // → 187 (unrealistic)
235
+ phoneNumber: faker.lorem.word(), // → "amet" (invalid!)
236
+ }
237
+ ```
238
+
239
+ ### ✅ Good Example (Follow This):
240
+ ```typescript
241
+ {
242
+ firstName: faker.person.firstName(), // → "María"
243
+ lastName: faker.person.lastName(), // → "García"
244
+ email: faker.internet.email(), // → "maria.garcia@example.com"
245
+ age: faker.number.int({ min: 18, max: 85 }), // → 34 (realistic)
246
+ phoneNumber: faker.phone.number(), // → "+1-234-567-8900"
247
+ }
248
+ ```
249
+
250
+ ---
251
+
252
+ ## Technical Details
253
+ - **Framework**: Slingr Framework (TypeScript + TypeORM)
254
+ - **Output Format**: JSONL (one JSON object per line)
255
+ - **Library**: @faker-js/faker (already installed)
256
+ - **Seed**: {{SEED}} (for reproducible results)
257
+ - **Locale**: {{LOCALE}}
258
+
259
259
  **Now provide the complete script that implements realistic data generation for all {{TOTAL_MODELS}} models!**
@@ -1,31 +1,28 @@
1
- import { Field, Text, Model, BaseModel, Uuid } from 'slingr-framework';
2
-
3
- import { {{DATASOURCE_NAME}} } from '../dataSources/{{DATASOURCE_FILE}}';
4
-
5
- @Model({ dataSource: {{DATASOURCE_NAME}} })
6
- export class Address extends BaseModel {
7
- @Field({
8
- required: true,
9
- primaryKey: true,
10
- })
11
- @Uuid({ generated: true })
12
- id!: string;
13
-
14
- @Field({
15
- required: true,
16
- })
17
- @Text({})
18
- street!: string;
19
-
20
- @Field({
21
- required: true,
22
- })
23
- @Text({})
24
- zipCode!: string;
25
-
26
- @Field({
27
- required: true,
28
- })
29
- @Text({})
30
- country!: string;
31
- }
1
+ import { TextField, DataModel, BaseDataModel, UuidField } from '@slingr/framework-backend';
2
+
3
+ import { {{DATASOURCE_NAME}} } from '@/dataSources/{{DATASOURCE_FILE}}';
4
+
5
+ @DataModel({ dataSource: {{DATASOURCE_NAME}} })
6
+ export class Address extends BaseDataModel {
7
+ @UuidField({
8
+ required: true,
9
+ primaryKey: true,
10
+ generated: true
11
+ })
12
+ id!: string;
13
+
14
+ @TextField({
15
+ required: true,
16
+ })
17
+ street!: string;
18
+
19
+ @TextField({
20
+ required: true,
21
+ })
22
+ zipCode!: string;
23
+
24
+ @TextField({
25
+ required: true,
26
+ })
27
+ country!: string;
28
+ }
@@ -1,61 +1,17 @@
1
- import { Field, Text, Model, BaseModel, Reference, Uuid } from "slingr-framework";
2
- import { Company } from "./Company";
3
- import { {{DATASOURCE_NAME}} } from "../dataSources/{{DATASOURCE_FILE}}";
4
-
5
- @Model({
6
- docs: "Represents an application containing info",
7
- dataSource: {{DATASOURCE_NAME}}
8
- })
9
- export class App extends BaseModel {
10
- @Field({
11
- required: true,
12
- primaryKey: true,
13
- })
14
- @Uuid(
15
- {
16
- generated: true
17
- }
18
- )
19
- id!: string;
20
-
21
- @Field({
22
- docs: "The name of the application",
23
- required: true
24
- })
25
- @Text({
26
- minLength: 4,
27
- maxLength: 20,
28
- // Regex: allows letters, dots (not at start/end), no underscores, no consecutive dots
29
- regex: /^(?!\.)([a-zA-Z]+(\.[a-zA-Z]+)*)?(?<!\.)$/,
30
- regexMessage: "Name must contain only letters and dots (no underscores, no consecutive dots, no dot at start/end)",
31
- })
32
- name!: string;
33
-
34
- @Field({
35
- docs: "The version of the application in format AA.BB.CC",
36
- required: true
37
- })
38
- @Text({
39
- minLength: 5,
40
- maxLength: 8,
41
- regex: /^\d{2}\.\d{2}\.\d{2}$/,
42
- regexMessage: "Version must be in the format AA.BB.CC, where AA, BB, and CC are two-digit numbers"
43
- })
44
- version!: string;
45
-
46
- @Field({
47
- docs: "The description of the application"
48
- })
49
- @Text({
50
- minLength: 10,
51
- maxLength: 500,
52
- })
53
- description!: string;
54
-
55
- @Field({
56
- docs: "The owning company of the application",
57
- required: true
58
- })
59
- @Reference({ load: true, elementType: () => Company })
60
- ownerCompany!: Company;
61
- }
1
+ import { App, BaseApp, logger } from '@slingr/framework-backend';
2
+ import { {{DATASOURCE_NAME}} } from './dataSources/{{DATASOURCE_FILE}}';
3
+
4
+ @App({ workflowsDataSource: {{DATASOURCE_NAME}} })
5
+ export class {{APP_CLASS_NAME}}App extends BaseApp {
6
+ override async afterStart(): Promise<void> {
7
+ logger.info('{{APP_NAME}} started');
8
+ }
9
+
10
+ override async beforeStop(): Promise<void> {
11
+ logger.info('{{APP_NAME}} stopping');
12
+ }
13
+
14
+ override async onError(error: Error): Promise<void> {
15
+ logger.error('Unhandled startup error', error);
16
+ }
17
+ }