@slingr/cli 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/README.md +320 -0
  2. package/bin/dev.cmd +3 -0
  3. package/bin/dev.js +5 -0
  4. package/bin/run.cmd +3 -0
  5. package/bin/run.js +5 -0
  6. package/dist/commands/cli-build.d.ts +9 -0
  7. package/dist/commands/cli-build.d.ts.map +1 -0
  8. package/dist/commands/cli-build.js +36 -0
  9. package/dist/commands/cli-build.js.map +1 -0
  10. package/dist/commands/create-app.d.ts +20 -0
  11. package/dist/commands/create-app.d.ts.map +1 -0
  12. package/dist/commands/create-app.js +246 -0
  13. package/dist/commands/create-app.js.map +1 -0
  14. package/dist/commands/ds.d.ts +28 -0
  15. package/dist/commands/ds.d.ts.map +1 -0
  16. package/dist/commands/ds.js +529 -0
  17. package/dist/commands/ds.js.map +1 -0
  18. package/dist/commands/gql.d.ts +22 -0
  19. package/dist/commands/gql.d.ts.map +1 -0
  20. package/dist/commands/gql.js +340 -0
  21. package/dist/commands/gql.js.map +1 -0
  22. package/dist/commands/infra/down.d.ts +13 -0
  23. package/dist/commands/infra/down.d.ts.map +1 -0
  24. package/dist/commands/infra/down.js +80 -0
  25. package/dist/commands/infra/down.js.map +1 -0
  26. package/dist/commands/infra/up.d.ts +13 -0
  27. package/dist/commands/infra/up.d.ts.map +1 -0
  28. package/dist/commands/infra/up.js +69 -0
  29. package/dist/commands/infra/up.js.map +1 -0
  30. package/dist/commands/infra/update.d.ts +14 -0
  31. package/dist/commands/infra/update.d.ts.map +1 -0
  32. package/dist/commands/infra/update.js +321 -0
  33. package/dist/commands/infra/update.js.map +1 -0
  34. package/dist/commands/run.d.ts +19 -0
  35. package/dist/commands/run.d.ts.map +1 -0
  36. package/dist/commands/run.js +315 -0
  37. package/dist/commands/run.js.map +1 -0
  38. package/dist/commands/setup.d.ts +18 -0
  39. package/dist/commands/setup.d.ts.map +1 -0
  40. package/dist/commands/setup.js +189 -0
  41. package/dist/commands/setup.js.map +1 -0
  42. package/dist/index.d.ts +2 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +8 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/projectStructure.d.ts +10 -0
  47. package/dist/projectStructure.d.ts.map +1 -0
  48. package/dist/projectStructure.js +153 -0
  49. package/dist/projectStructure.js.map +1 -0
  50. package/dist/scripts/generate-schema.d.ts +10 -0
  51. package/dist/scripts/generate-schema.d.ts.map +1 -0
  52. package/dist/scripts/generate-schema.js +130 -0
  53. package/dist/scripts/generate-schema.js.map +1 -0
  54. package/dist/scripts/generate-schema.ts +143 -0
  55. package/dist/templates/.github/copilot-instructions.md.template +17 -0
  56. package/dist/templates/config/datasource.ts.template +9 -0
  57. package/dist/templates/config/jest.config.ts +30 -0
  58. package/dist/templates/config/jest.setup.ts +1 -0
  59. package/dist/templates/config/tsconfig.json.template +30 -0
  60. package/dist/templates/dataSources/mysql.ts.template +13 -0
  61. package/dist/templates/dataSources/postgres.ts.template +13 -0
  62. package/dist/templates/dataset-generator-script.ts.template +140 -0
  63. package/dist/templates/datasets/mysql-default/Address.jsonl.template +4 -0
  64. package/dist/templates/datasets/mysql-default/App.jsonl.template +5 -0
  65. package/dist/templates/datasets/mysql-default/Company.jsonl.template +4 -0
  66. package/dist/templates/datasets/mysql-default/Person.jsonl.template +3 -0
  67. package/dist/templates/datasets/postgres-default/Address.jsonl.template +4 -0
  68. package/dist/templates/datasets/postgres-default/App.jsonl.template +5 -0
  69. package/dist/templates/datasets/postgres-default/Company.jsonl.template +4 -0
  70. package/dist/templates/datasets/postgres-default/Person.jsonl.template +3 -0
  71. package/dist/templates/docs/app-description.md.template +34 -0
  72. package/dist/templates/gql/codegen.yml.template +25 -0
  73. package/dist/templates/gql/index.ts.template +24 -0
  74. package/dist/templates/gql/operations.graphql.template +30 -0
  75. package/dist/templates/package.json.template +38 -0
  76. package/dist/templates/prompt-analysis.md.template +111 -0
  77. package/dist/templates/prompt-script-generation.md.template +259 -0
  78. package/dist/templates/src/Address.ts.template +31 -0
  79. package/dist/templates/src/App.ts.template +61 -0
  80. package/dist/templates/src/Company.ts.template +48 -0
  81. package/dist/templates/src/Models.test.ts.template +655 -0
  82. package/dist/templates/src/Person.test.ts.template +289 -0
  83. package/dist/templates/src/Person.ts.template +105 -0
  84. package/dist/templates/src/actions/index.ts.template +12 -0
  85. package/dist/templates/src/index.ts +66 -0
  86. package/dist/templates/src/types/gql.d.ts.template +18 -0
  87. package/dist/templates/vscode/extensions.json +3 -0
  88. package/dist/templates/vscode/settings.json +11 -0
  89. package/dist/utils/datasourceParser.d.ts +12 -0
  90. package/dist/utils/datasourceParser.d.ts.map +1 -0
  91. package/dist/utils/datasourceParser.js +91 -0
  92. package/dist/utils/datasourceParser.js.map +1 -0
  93. package/dist/utils/jsonlLoader.d.ts +140 -0
  94. package/dist/utils/jsonlLoader.d.ts.map +1 -0
  95. package/dist/utils/jsonlLoader.js +583 -0
  96. package/dist/utils/jsonlLoader.js.map +1 -0
  97. package/dist/utils/model-analyzer.d.ts +86 -0
  98. package/dist/utils/model-analyzer.d.ts.map +1 -0
  99. package/dist/utils/model-analyzer.js +458 -0
  100. package/dist/utils/model-analyzer.js.map +1 -0
  101. package/dist/utils/portChecker.d.ts +36 -0
  102. package/dist/utils/portChecker.d.ts.map +1 -0
  103. package/dist/utils/portChecker.js +308 -0
  104. package/dist/utils/portChecker.js.map +1 -0
  105. package/dist/utils/synthetic-data-generator.d.ts +74 -0
  106. package/dist/utils/synthetic-data-generator.d.ts.map +1 -0
  107. package/dist/utils/synthetic-data-generator.js +443 -0
  108. package/dist/utils/synthetic-data-generator.js.map +1 -0
  109. package/oclif.manifest.json +435 -0
  110. package/package.json +118 -0
  111. package/src/templates/.github/copilot-instructions.md.template +17 -0
  112. package/src/templates/config/datasource.ts.template +9 -0
  113. package/src/templates/config/jest.config.ts +30 -0
  114. package/src/templates/config/jest.setup.ts +1 -0
  115. package/src/templates/config/tsconfig.json.template +30 -0
  116. package/src/templates/dataSources/mysql.ts.template +13 -0
  117. package/src/templates/dataSources/postgres.ts.template +13 -0
  118. package/src/templates/dataset-generator-script.ts.template +140 -0
  119. package/src/templates/datasets/mysql-default/Address.jsonl.template +4 -0
  120. package/src/templates/datasets/mysql-default/App.jsonl.template +5 -0
  121. package/src/templates/datasets/mysql-default/Company.jsonl.template +4 -0
  122. package/src/templates/datasets/mysql-default/Person.jsonl.template +3 -0
  123. package/src/templates/datasets/postgres-default/Address.jsonl.template +4 -0
  124. package/src/templates/datasets/postgres-default/App.jsonl.template +5 -0
  125. package/src/templates/datasets/postgres-default/Company.jsonl.template +4 -0
  126. package/src/templates/datasets/postgres-default/Person.jsonl.template +3 -0
  127. package/src/templates/docs/app-description.md.template +34 -0
  128. package/src/templates/gql/codegen.yml.template +25 -0
  129. package/src/templates/gql/index.ts.template +24 -0
  130. package/src/templates/gql/operations.graphql.template +30 -0
  131. package/src/templates/package.json.template +38 -0
  132. package/src/templates/prompt-analysis.md.template +111 -0
  133. package/src/templates/prompt-script-generation.md.template +259 -0
  134. package/src/templates/src/Address.ts.template +31 -0
  135. package/src/templates/src/App.ts.template +61 -0
  136. package/src/templates/src/Company.ts.template +48 -0
  137. package/src/templates/src/Models.test.ts.template +655 -0
  138. package/src/templates/src/Person.test.ts.template +289 -0
  139. package/src/templates/src/Person.ts.template +105 -0
  140. package/src/templates/src/actions/index.ts.template +12 -0
  141. package/src/templates/src/index.ts +66 -0
  142. package/src/templates/src/types/gql.d.ts.template +18 -0
  143. package/src/templates/vscode/extensions.json +3 -0
  144. package/src/templates/vscode/settings.json +11 -0
@@ -0,0 +1,289 @@
1
+ import { Person } from './Person';
2
+
3
+ describe('Person Model', () => {
4
+ describe('Validation Tests', () => {
5
+ it('should validate a valid adult person', async () => {
6
+ const personData = {
7
+ additionalInfo: '<p>Some info</p>',
8
+ age: 25,
9
+ email: 'john@example.com',
10
+ firstName: 'John',
11
+ isActive: true,
12
+ lastName: 'Doe',
13
+ phoneNumber: '123-456-7890',
14
+ };
15
+
16
+ const person = Person.fromJSON(personData);
17
+ const errors = await person.validate();
18
+
19
+ expect(errors.length).toBe(0);
20
+ });
21
+
22
+ it('should validate a valid minor person with parent email', async () => {
23
+ const personData = {
24
+ additionalInfo: '<p>Minor info</p>',
25
+ age: 16,
26
+ email: 'jane@example.com',
27
+ firstName: 'Jane',
28
+ isActive: false,
29
+ lastName: 'Smith',
30
+ parentEmail: 'parent@example.com',
31
+ };
32
+
33
+ const person = Person.fromJSON(personData);
34
+ const errors = await person.validate();
35
+
36
+ expect(errors.length).toBe(0);
37
+ });
38
+
39
+ it('should fail validation when firstName is too short', async () => {
40
+ const personData = {
41
+ age: 25,
42
+ email: 'john@example.com',
43
+ firstName: 'J',
44
+ lastName: 'Doe',
45
+ };
46
+
47
+ const person = Person.fromJSON(personData);
48
+ const errors = await person.validate();
49
+
50
+ expect(errors.length).toBeGreaterThan(0);
51
+ const firstNameError = errors.find((e) => e.property === 'firstName');
52
+ expect(firstNameError).toBeDefined();
53
+ expect(firstNameError?.constraints).toHaveProperty('minLength');
54
+ });
55
+
56
+ it('should fail validation when firstName contains numbers', async () => {
57
+ const personData = {
58
+ age: 25,
59
+ email: 'john@example.com',
60
+ firstName: 'John123',
61
+ lastName: 'Doe',
62
+ };
63
+
64
+ const person = Person.fromJSON(personData);
65
+ const errors = await person.validate();
66
+
67
+ expect(errors.length).toBeGreaterThan(0);
68
+ const firstNameError = errors.find((e) => e.property === 'firstName');
69
+ expect(firstNameError).toBeDefined();
70
+ expect(firstNameError?.constraints).toHaveProperty('matches');
71
+ });
72
+
73
+ it('should fail validation when email is invalid', async () => {
74
+ const personData = {
75
+ age: 25,
76
+ email: 'invalid-email',
77
+ firstName: 'John',
78
+ lastName: 'Doe',
79
+ };
80
+
81
+ const person = Person.fromJSON(personData);
82
+ const errors = await person.validate();
83
+
84
+ expect(errors.length).toBeGreaterThan(0);
85
+ const emailError = errors.find((e) => e.property === 'email');
86
+ expect(emailError).toBeDefined();
87
+ expect(emailError?.constraints).toHaveProperty('isEmail');
88
+ });
89
+
90
+ it('should fail validation when age is negative', async () => {
91
+ const personData = {
92
+ age: -5,
93
+ email: 'john@example.com',
94
+ firstName: 'John',
95
+ lastName: 'Doe',
96
+ };
97
+
98
+ const person = Person.fromJSON(personData);
99
+ const errors = await person.validate();
100
+
101
+ expect(errors.length).toBeGreaterThan(0);
102
+ const ageError = errors.find((e) => e.property === 'age');
103
+ expect(ageError).toBeDefined();
104
+ expect(ageError?.constraints).toHaveProperty('invalidAge');
105
+ });
106
+
107
+ it('should fail validation when age is too high', async () => {
108
+ const personData = {
109
+ age: 150,
110
+ email: 'john@example.com',
111
+ firstName: 'John',
112
+ lastName: 'Doe',
113
+ };
114
+
115
+ const person = Person.fromJSON(personData);
116
+ const errors = await person.validate();
117
+
118
+ expect(errors.length).toBeGreaterThan(0);
119
+ const ageError = errors.find((e) => e.property === 'age');
120
+ expect(ageError).toBeDefined();
121
+ expect(ageError?.constraints).toHaveProperty('invalidAge');
122
+ });
123
+
124
+ it('should require parentEmail for minors', async () => {
125
+ const personData = {
126
+ age: 16,
127
+ email: 'jane@example.com',
128
+ firstName: 'Jane',
129
+ lastName: 'Smith',
130
+ // parentEmail missing
131
+ };
132
+
133
+ const person = Person.fromJSON(personData);
134
+ const errors = await person.validate();
135
+
136
+ expect(errors.length).toBeGreaterThan(0);
137
+ const parentEmailError = errors.find((e) => e.property === 'parentEmail');
138
+ expect(parentEmailError).toBeDefined();
139
+ expect(parentEmailError?.constraints).toHaveProperty('isNotEmpty');
140
+ });
141
+
142
+ it('should not require parentEmail for adults', async () => {
143
+ const personData = {
144
+ age: 25,
145
+ email: 'john@example.com',
146
+ firstName: 'John',
147
+ lastName: 'Doe',
148
+ // parentEmail not provided
149
+ };
150
+
151
+ const person = Person.fromJSON(personData);
152
+ const errors = await person.validate();
153
+
154
+ // Should not have parentEmail error
155
+ const parentEmailError = errors.find((e) => e.property === 'parentEmail');
156
+ expect(parentEmailError).toBeUndefined();
157
+ });
158
+ });
159
+
160
+ describe('JSON Serialization Tests', () => {
161
+ it('should exclude internalId from JSON output', () => {
162
+ const personData = {
163
+ age: 25,
164
+ email: 'john@example.com',
165
+ firstName: 'John',
166
+ internalId: 'secret-123',
167
+ isActive: true,
168
+ lastName: 'Doe',
169
+ };
170
+
171
+ const person = Person.fromJSON(personData);
172
+ const json = person.toJSON();
173
+
174
+ expect(json).not.toHaveProperty('internalId');
175
+ expect(json).toHaveProperty('firstName', 'John');
176
+ expect(json).toHaveProperty('lastName', 'Doe');
177
+ expect(json).toHaveProperty('email', 'john@example.com');
178
+ expect(json).toHaveProperty('age', 25);
179
+ expect(json).toHaveProperty('isActive', true);
180
+ });
181
+
182
+ it('should include phoneNumber for adults', () => {
183
+ const personData = {
184
+ age: 25,
185
+ email: 'john@example.com',
186
+ firstName: 'John',
187
+ lastName: 'Doe',
188
+ phoneNumber: '123-456-7890',
189
+ };
190
+
191
+ const person = Person.fromJSON(personData);
192
+ const json = person.toJSON();
193
+
194
+ expect(json).toHaveProperty('phoneNumber', '123-456-7890');
195
+ });
196
+
197
+ it('should exclude phoneNumber for minors', () => {
198
+ const personData = {
199
+ age: 16,
200
+ email: 'jane@example.com',
201
+ firstName: 'Jane',
202
+ lastName: 'Smith',
203
+ parentEmail: 'parent@example.com',
204
+ phoneNumber: '123-456-7890',
205
+ };
206
+
207
+ const person = Person.fromJSON(personData);
208
+ const json = person.toJSON();
209
+
210
+ expect(json).not.toHaveProperty('phoneNumber');
211
+ expect(json).toHaveProperty('firstName', 'Jane');
212
+ expect(json).toHaveProperty('parentEmail', 'parent@example.com');
213
+ });
214
+ });
215
+
216
+ describe('Field Type Tests', () => {
217
+ it('should handle boolean field correctly', async () => {
218
+ const personData = {
219
+ age: 25,
220
+ email: 'john@example.com',
221
+ firstName: 'John',
222
+ isActive: true,
223
+ lastName: 'Doe',
224
+ };
225
+
226
+ const person = Person.fromJSON(personData);
227
+ const errors = await person.validate();
228
+
229
+ expect(errors.length).toBe(0);
230
+ expect(person.isActive).toBe(true);
231
+ });
232
+
233
+ it('should handle HTML field correctly', async () => {
234
+ const personData = {
235
+ additionalInfo: '<p>This is <strong>HTML</strong> content</p>',
236
+ age: 25,
237
+ email: 'john@example.com',
238
+ firstName: 'John',
239
+ lastName: 'Doe',
240
+ };
241
+
242
+ const person = Person.fromJSON(personData);
243
+ const errors = await person.validate();
244
+
245
+ expect(errors.length).toBe(0);
246
+ expect(person.additionalInfo).toBe('<p>This is <strong>HTML</strong> content</p>');
247
+ });
248
+ });
249
+
250
+ describe('Edge Cases', () => {
251
+ it('should handle missing required fields', async () => {
252
+ const personData = {
253
+ // Missing firstName, lastName, age
254
+ email: 'john@example.com',
255
+ };
256
+
257
+ const person = Person.fromJSON(personData);
258
+ const errors = await person.validate();
259
+
260
+ expect(errors.length).toBeGreaterThan(0);
261
+
262
+ const firstNameError = errors.find((e) => e.property === 'firstName');
263
+ const lastNameError = errors.find((e) => e.property === 'lastName');
264
+ const ageError = errors.find((e) => e.property === 'age');
265
+
266
+ expect(firstNameError).toBeDefined();
267
+ expect(lastNameError).toBeDefined();
268
+ expect(ageError).toBeDefined();
269
+ });
270
+
271
+ it('should handle boundary age values', async () => {
272
+ const personData = {
273
+ age: 18, // Boundary between minor and adult
274
+ email: 'john@example.com',
275
+ firstName: 'John',
276
+ lastName: 'Doe',
277
+ };
278
+
279
+ const person = Person.fromJSON(personData);
280
+ const errors = await person.validate();
281
+
282
+ expect(errors.length).toBe(0);
283
+
284
+ // At 18, parentEmail should not be required
285
+ const parentEmailError = errors.find((e) => e.property === 'parentEmail');
286
+ expect(parentEmailError).toBeUndefined();
287
+ });
288
+ });
289
+ });
@@ -0,0 +1,105 @@
1
+ import { Field, Text, Email, Html, Boolean, Model, BaseModel, Uuid, Integer, SharedComposition } from "slingr-framework";
2
+ import { Address } from "./Address";
3
+ import { {{DATASOURCE_NAME}} } from "../dataSources/{{DATASOURCE_FILE}}";
4
+
5
+ @Model({
6
+ docs: "Represents a person",
7
+ dataSource: {{DATASOURCE_NAME}}
8
+ })
9
+ export class Person 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
+ required: true,
23
+ })
24
+ @Text({
25
+ minLength: 2,
26
+ maxLength: 30,
27
+ regex: /^[a-zA-Z]+$/,
28
+ regexMessage: "firstName must contain only letters",
29
+ })
30
+ firstName!: string;
31
+
32
+ @Field({
33
+ required: true,
34
+ })
35
+ @Text({
36
+ minLength: 2,
37
+ maxLength: 30,
38
+ regex: /^[a-zA-Z]+$/,
39
+ regexMessage: "lastName must contain only letters",
40
+ })
41
+ lastName!: string;
42
+
43
+ @Field()
44
+ @Email()
45
+ email!: string;
46
+
47
+ @Field({
48
+ validation: (_: number, person: Person) => {
49
+ let errors = [];
50
+ if (person.age < 0 || person.age > 120) {
51
+ errors.push({
52
+ constraint: "invalidAge",
53
+ message: "Age must be between 0 and 120",
54
+ });
55
+ }
56
+ return errors;
57
+ },
58
+ required: true,
59
+ })
60
+ @Integer()
61
+ age!: number;
62
+
63
+
64
+ @Field({
65
+ required: (person: Person) => {
66
+ return (person.age < 18);
67
+ },
68
+ })
69
+ @Email()
70
+ parentEmail!: string;
71
+
72
+
73
+ @Field({
74
+ available: false, // This field should be excluded from JSON operations
75
+ docs: "Internal identifier not exposed in JSON"
76
+ })
77
+ @Text()
78
+ internalId!: string;
79
+
80
+ @Field({
81
+ required: false,
82
+ available: (person: Person) => {
83
+ return person.age >= 18;
84
+ },
85
+ })
86
+ @Text()
87
+ phoneNumber!: string;
88
+
89
+ @Field()
90
+ @Html()
91
+ additionalInfo!: string;
92
+
93
+ @Field({
94
+ required: false,
95
+ })
96
+ @Boolean()
97
+ isActive!: boolean;
98
+
99
+ @Field({
100
+ required: false
101
+ })
102
+ @SharedComposition({ elementType: () => Address })
103
+ address!: Address;
104
+
105
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Actions index file for {{APP_NAME}}
3
+ * This file exports all actions that should be available in the GraphQL schema
4
+ */
5
+
6
+ // Import any custom actions here
7
+ // Example:
8
+ // export * from './userActions';
9
+ // export * from './companyActions';
10
+
11
+ // For now, we'll just export an empty object to make the file valid
12
+ export {};
@@ -0,0 +1,66 @@
1
+ import { app } from 'slingr-framework';
2
+
3
+ async function main() {
4
+ // Configure the application
5
+ app.configure({
6
+ graphql: {
7
+ port: 4000,
8
+ host: 'localhost',
9
+ enableExplorer: true,
10
+ },
11
+ });
12
+
13
+ // Start the application
14
+ await app.run();
15
+
16
+ console.log('');
17
+ console.log('✅ Application is ready!');
18
+ console.log('📊 GraphQL Playground: http://localhost:4000/graphql');
19
+ console.log('');
20
+
21
+ // Test a sample query (if SDK is available)
22
+ console.log('🔍 Testing GraphQL SDK...');
23
+
24
+ try {
25
+ // Check if SDK exists before trying to import it
26
+ const fs = await import('fs');
27
+ const path = await import('path');
28
+ const sdkPath = path.resolve(__dirname, '../generated/gql/index.ts');
29
+
30
+ if (fs.existsSync(sdkPath)) {
31
+ // Use dynamic import with variable to avoid TypeScript compile-time resolution
32
+ const sdkModule = '../generated/gql/index';
33
+ const gql = await import(sdkModule);
34
+
35
+ if (gql.default && typeof gql.default.TestQuery === 'function') {
36
+ const result = await gql.default.TestQuery();
37
+ console.log('✅ GraphQL SDK is working! Test query result:', JSON.stringify(result, null, 2));
38
+ console.log('🚀 Your GraphQL API is ready to use with type-safe queries!');
39
+ console.log('💡 Import using: import gql from "@gql" (alias) or "../generated/gql"');
40
+ } else {
41
+ console.log('✅ GraphQL SDK loaded successfully!');
42
+ console.log('â„šī¸ No test query available, but the SDK is ready for your custom operations.');
43
+ console.log('📝 Edit operations.graphql to add your GraphQL queries and mutations.');
44
+ }
45
+ } else {
46
+ console.log('â„šī¸ GraphQL SDK not available yet.');
47
+ console.log('💡 Run the complete setup to generate schema and SDK:');
48
+ console.log(' npx slingr setup');
49
+ }
50
+ } catch (error: any) {
51
+ console.log('â„šī¸ GraphQL SDK may need to be regenerated after recent changes.');
52
+ console.log('💡 Try regenerating the SDK:');
53
+ console.log(' npx slingr gql generate-schema');
54
+ console.log(' npx slingr gql generate-sdk');
55
+ }
56
+
57
+ console.log('');
58
+
59
+ console.log('');
60
+ console.log('Press Ctrl+C to stop');
61
+ }
62
+
63
+ main().catch(error => {
64
+ console.error('❌ Failed to start application:', error);
65
+ process.exit(1);
66
+ });
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Temporary type declaration for @gql module
3
+ * This file prevents TypeScript compilation errors when the GraphQL SDK hasn't been generated yet.
4
+ * It will be automatically replaced when you run: slingr gql generate-sdk
5
+ */
6
+
7
+ declare module '@gql' {
8
+ // Placeholder interface for when SDK is not generated yet
9
+ interface PlaceholderGQL {
10
+ TestQuery?: () => Promise<any>;
11
+ [key: string]: any;
12
+ }
13
+
14
+ const gql: PlaceholderGQL;
15
+ export default gql;
16
+ }
17
+
18
+ // This file can be safely deleted after running: slingr gql generate-sdk
@@ -0,0 +1,3 @@
1
+ {
2
+ "recommendations": ["github.copilot", "slingr.slingr"]
3
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "editor.formatOnSave": true,
3
+ "editor.inlineSuggest.enabled": true,
4
+ "github.copilot.advanced": {},
5
+ "github.copilot.enable": {
6
+ "*": true,
7
+ "markdown": true,
8
+ "plaintext": true
9
+ },
10
+ "typescript.preferences.importModuleSpecifier": "relative"
11
+ }