@slingr/cli 0.0.3 → 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 -26
  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,143 +1,258 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Script to generate GraphQL schema from slingr-framework
4
- * This script is executed in the context of a user's Slingr application
5
- *
6
- * By default, the script generates the schema and exits immediately.
7
- * Use --no-exit flag to start Apollo Server for schema exploration.
8
- */
9
-
10
- import fs from 'fs';
11
- import path from 'path';
12
- import { pathToFileURL } from 'url';
13
-
14
- async function generateSchema() {
15
- try {
16
- console.log('šŸ”„ Generating GraphQL schema from your Slingr application...');
17
-
18
- // IMPORTANT: Import actions BEFORE importing slingr-framework
19
- // This ensures action decorators are executed before the schema is built
20
-
21
- // Try to load the compiled JavaScript version first, then fallback to TypeScript
22
- // Note: TypeScript compilation with rootDir inferred from src/ will output to dist/actions/
23
- // (without the src folder in the path)
24
- let actionsIndexPath = path.join(process.cwd(), 'dist', 'actions', 'index.js');
25
- let usingCompiledVersion = true;
26
- let hasActions = false;
27
-
28
- if (fs.existsSync(actionsIndexPath)) {
29
- hasActions = true;
30
- } else {
31
- // Also check the alternative path (dist/src/actions/index.js) for backwards compatibility
32
- const altActionsIndexPath = path.join(process.cwd(), 'dist', 'src', 'actions', 'index.js');
33
- if (fs.existsSync(altActionsIndexPath)) {
34
- actionsIndexPath = altActionsIndexPath;
35
- hasActions = true;
36
- } else {
37
- // Fallback to TypeScript source
38
- actionsIndexPath = path.join(process.cwd(), 'src', 'actions', 'index.ts');
39
- usingCompiledVersion = false;
40
-
41
- if (fs.existsSync(actionsIndexPath)) {
42
- hasActions = true;
43
- console.log(
44
- 'āš ļø TypeScript source files detected. For best compatibility, run "npm run build" to compile your application first.'
45
- );
46
- } else {
47
- // Check if actions directory exists at all
48
- const actionsDir = path.join(process.cwd(), 'src', 'actions');
49
- if (fs.existsSync(actionsDir)) {
50
- console.log(
51
- 'āš ļø Actions directory found but no index file. Please ensure src/actions/index.ts exists or run "slingr run" to generate it automatically.'
52
- );
53
- } else {
54
- console.log('ā„¹ļø No actions directory found. Schema will be generated with framework base types only.');
55
- }
56
- hasActions = false;
57
- }
58
- }
59
- }
60
-
61
- if (hasActions) {
62
- console.log(`šŸ“¦ Loading actions from ${usingCompiledVersion ? 'compiled' : 'source'} files...`);
63
-
64
- // If using TypeScript files, show a warning and try to continue
65
- if (!usingCompiledVersion) {
66
- throw new Error(
67
- 'TypeScript source files found but not compiled. Please run "npm run build" to compile your application first, then try again.'
68
- );
69
- }
70
-
71
- // Import the actions index which will register all actions via @Action decorators
72
- // Convert Windows paths to file:// URLs for ESM compatibility
73
- const actionsIndexUrl = pathToFileURL(actionsIndexPath).href;
74
- await import(actionsIndexUrl);
75
- } else {
76
- console.log('šŸ“¦ No actions to load. Generating schema with framework base types...');
77
- } // Import framework functions and printSchema from slingr-framework
78
- // We must use printSchema from the same GraphQL instance as the framework
79
- // to avoid "Cannot use GraphQLType from another module or realm" errors
80
- const slingrFramework = await import('slingr-framework');
81
- const { getGraphQLSchema, rebuildGraphQLSchema, printSchema } = slingrFramework;
82
-
83
- // Force rebuild the schema to include all registered actions
84
- rebuildGraphQLSchema();
85
- const schema = getGraphQLSchema();
86
-
87
- if (!schema) {
88
- throw new Error('Could not generate GraphQL schema. Please ensure slingr-framework is properly installed.');
89
- }
90
-
91
- const schemaString = printSchema(schema);
92
-
93
- // Ensure generated/gql directory exists
94
- const generatedDir = path.join(process.cwd(), 'generated', 'gql');
95
- if (!fs.existsSync(generatedDir)) {
96
- fs.mkdirSync(generatedDir, { recursive: true });
97
- }
98
-
99
- // Write schema to file
100
- const schemaFilePath = path.join(generatedDir, 'schema.graphql');
101
- fs.writeFileSync(schemaFilePath, schemaString, 'utf8');
102
-
103
- console.log(`āœ… GraphQL schema generated successfully at: ${schemaFilePath}`);
104
-
105
- // Show a preview of the generated schema
106
- const lines = schemaString.split('\n');
107
- if (lines.length > 0) {
108
- console.log('\nšŸ“‹ Schema preview:');
109
- console.log(lines.slice(0, Math.min(15, lines.length)).join('\n'));
110
- if (lines.length > 15) {
111
- console.log(`... (${lines.length - 15} more lines)`);
112
- }
113
- }
114
-
115
- // Check for --no-exit parameter
116
- const noExit = process.argv.includes('--no-exit');
117
- if (noExit) {
118
- console.log('\n Starting Apollo Server to explore the schema...');
119
- console.log('šŸ’” Remove --no-exit parameter to exit immediately after generating schema.');
120
-
121
- // Start Apollo Server for schema exploration
122
- const { startGraphQLServer } = slingrFramework;
123
- await startGraphQLServer({
124
- port: 4000,
125
- enableExplorer: true,
126
- });
127
-
128
- console.log('🌐 Apollo Explorer available at: http://localhost:4000/graphql');
129
- console.log('šŸ“– GraphQL schema introspection enabled');
130
- console.log('ā¹ļø Press Ctrl+C to stop the server');
131
- } else {
132
- console.log('\nāœ… Schema generation completed. Script will terminate now.');
133
- console.log('šŸ’” Use --no-exit parameter to start Apollo Server and explore the schema.');
134
- process.exit(0);
135
- }
136
- } catch (error: any) {
137
- console.error(`Failed to generate schema: ${error.message}`);
138
- console.error(error);
139
- process.exit(1);
140
- }
141
- }
142
-
143
- generateSchema();
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Script to generate GraphQL schema from @slingr/framework-backend
4
+ * This script is executed in the context of a user's Slingr application
5
+ *
6
+ * By default, the script generates the schema and exits immediately.
7
+ * Use --no-exit flag to start Apollo Server for schema exploration.
8
+ */
9
+
10
+ import fs from 'fs';
11
+ import path from 'path';
12
+ // Load generated view type registries if they exist so declare global augmentations are active
13
+ // during schema compilation. The file may not exist yet on the first run.
14
+ const generatedViewsPath = path.join(process.cwd(), 'generated', 'views');
15
+ if (fs.existsSync(generatedViewsPath + '.ts') || fs.existsSync(generatedViewsPath + '.js')) {
16
+ require(generatedViewsPath);
17
+ }
18
+ // @ts-ignore - temp-generate-metadata.ts is copied at runtime by the CLI
19
+ import { generateMetadataFile } from './temp-generate-metadata';
20
+
21
+ /**
22
+ * Load data sources from src/dataSources directory.
23
+ * Loads directly from TypeScript source files using ts-node.
24
+ */
25
+ async function loadDataSources() {
26
+ const dataSourcesPath = path.join(process.cwd(), 'src', 'dataSources');
27
+
28
+ if (!fs.existsSync(dataSourcesPath)) {
29
+ console.log('ā„¹ļø No dataSources directory found. Schema will be generated without CRUD operations.');
30
+ return;
31
+ }
32
+
33
+ console.log('šŸ“¦ Loading data sources from TypeScript source files...');
34
+
35
+ // Get all data source files
36
+ const files = fs.readdirSync(dataSourcesPath).filter(file => file.endsWith('.ts') && !file.endsWith('.d.ts'));
37
+
38
+ if (files.length === 0) {
39
+ console.log('ā„¹ļø No data source files found.');
40
+ return;
41
+ }
42
+
43
+ // Import each data source file using CommonJS require
44
+ for (const file of files) {
45
+ const filePath = path.join(dataSourcesPath, file);
46
+ require(filePath);
47
+ }
48
+
49
+ console.log(`āœ… Loaded ${files.length} data source(s)`);
50
+ }
51
+
52
+ /**
53
+ * Recursively collect all files matching an extension from a directory.
54
+ */
55
+ function collectFilesRecursively(dir: string, extension: string): string[] {
56
+ const results: string[] = [];
57
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
58
+ for (const entry of entries) {
59
+ const fullPath = path.join(dir, entry.name);
60
+ if (entry.isDirectory()) {
61
+ results.push(...collectFilesRecursively(fullPath, extension));
62
+ } else if (
63
+ entry.isFile() &&
64
+ entry.name.endsWith(extension) &&
65
+ !entry.name.endsWith('.d.ts') &&
66
+ !/\.test\.|\.spec\./i.test(entry.name)
67
+ ) {
68
+ results.push(fullPath);
69
+ }
70
+ }
71
+ return results;
72
+ }
73
+
74
+ /**
75
+ * Load model files from src/data directory (including subdirectories).
76
+ * Loads directly from TypeScript source files using tsx to avoid double decorator execution.
77
+ * @returns Array of loaded model classes
78
+ */
79
+ async function loadModels(): Promise<Array<new (...args: any[]) => any>> {
80
+ const loadedModels: Array<new (...args: any[]) => any> = [];
81
+
82
+ const modelsPath = path.join(process.cwd(), 'src', 'data');
83
+
84
+ if (!fs.existsSync(modelsPath)) {
85
+ console.log('ā„¹ļø No data directory found. Schema will be generated without model CRUD operations.');
86
+ return loadedModels;
87
+ }
88
+
89
+ console.log('šŸ“¦ Loading models from TypeScript source files...');
90
+
91
+ // Recursively get all model files, excluding tests/specs and declaration files
92
+ const files = collectFilesRecursively(modelsPath, '.ts');
93
+
94
+ if (files.length === 0) {
95
+ console.log('ā„¹ļø No model files found.');
96
+ return loadedModels;
97
+ }
98
+
99
+ // Import each model file (which will trigger @DataModel decorators and register CRUD operations)
100
+ for (const filePath of files) {
101
+ const moduleExports = require(filePath);
102
+
103
+ // Extract model classes from the module exports
104
+ for (const exportName of Object.keys(moduleExports)) {
105
+ const exported = moduleExports[exportName];
106
+ if (typeof exported === 'function' && exported.prototype) {
107
+ loadedModels.push(exported as new (...args: any[]) => any);
108
+ }
109
+ }
110
+ }
111
+
112
+ console.log(`āœ… Loaded ${files.length} model(s)`);
113
+
114
+ return loadedModels;
115
+ }
116
+
117
+ async function generateSchema() {
118
+ try {
119
+ console.log('šŸ”„ Generating GraphQL schema from your Slingr application...');
120
+
121
+ // Dynamic import to avoid compile-time dependency on @slingr/framework-backend
122
+ // This script runs in the user's project context where @slingr/framework-backend is installed
123
+ // @ts-ignore
124
+ const slingrFramework = await import('@slingr/framework-backend');
125
+ const { generateActionsIndex, getGraphQLSchema, printSchema, rebuildGraphQLSchema, startGraphQLServer } =
126
+ slingrFramework;
127
+
128
+ // Import framework functions first to get access to rebuildGraphQLSchema
129
+ // We must use printSchema from the same GraphQL instance as the framework
130
+ // to avoid "Cannot use GraphQLType from another module or realm" errors
131
+
132
+ // Destructure directly from the imported module (works for both ESM and CJS)
133
+ // The named exports are available directly on the module namespace object
134
+
135
+ // Rebuild the schema FIRST to clear any previous state before loading anything
136
+ // This ensures we start with a clean slate
137
+ rebuildGraphQLSchema();
138
+
139
+ // IMPORTANT: Load actions AFTER rebuilding the schema
140
+ // When actions are imported, they will register themselves in the clean schema builder
141
+
142
+ // Check if actions directory exists
143
+ const actionsDir = path.join(process.cwd(), 'src', 'actions');
144
+ let hasActions = false;
145
+
146
+ if (fs.existsSync(actionsDir)) {
147
+ // Generate the actions index at generated/actions/index.ts
148
+ console.log('šŸ“¦ Generating actions index...');
149
+
150
+ // Generate the actions index
151
+ await generateActionsIndex(process.cwd(), 'src/actions');
152
+
153
+ // Check if the generated index exists
154
+ const generatedActionsIndexPath = path.resolve(process.cwd(), 'generated', 'actions', 'index.ts');
155
+ if (fs.existsSync(generatedActionsIndexPath)) {
156
+ hasActions = true;
157
+ console.log('šŸ“¦ Loading actions from generated TypeScript index...');
158
+
159
+ require(generatedActionsIndexPath);
160
+ } else {
161
+ console.log('āš ļø Failed to generate actions index.');
162
+ hasActions = false;
163
+ }
164
+ } else {
165
+ console.log('ā„¹ļø No actions directory found. Schema will be generated with framework base types only.');
166
+ }
167
+
168
+ if (!hasActions) {
169
+ console.log('šŸ“¦ No actions to load. Generating schema with framework base types...');
170
+ }
171
+
172
+ // Load data sources and models (which will register CRUD operations)
173
+
174
+ // Import framework functions and printSchema from slingr-framework
175
+ // We must use printSchema from the same GraphQL instance as the framework
176
+ // to avoid "Cannot use GraphQLType from another module or realm" errors
177
+ const { registerAllUiGraphQL, registerCrudOperations, generateCrudActions } = slingrFramework;
178
+
179
+ // Load data sources and models
180
+ // Actions will be generated but NOT registered in GraphQL during model import
181
+ await loadDataSources();
182
+ const loadedModels = await loadModels();
183
+ console.log('šŸ“¦ Registering UI operations for all UI-enabled models...');
184
+ await registerAllUiGraphQL();
185
+ console.log('āœ… UI operations registered');
186
+
187
+ // Register CRUD GraphQL operations for models with crud configuration
188
+ if (loadedModels.length > 0) {
189
+ for (const modelClass of loadedModels) {
190
+ const modelOptions = (Reflect as any).getMetadata('model:options', modelClass);
191
+ const crudOptions = modelOptions?.crud;
192
+
193
+ if (crudOptions && crudOptions.api === 'gql' && crudOptions.generate) {
194
+ const dataSource = (Reflect as any).getMetadata('model:dataSource', modelClass);
195
+ if (dataSource) {
196
+ // First generate CRUD actions (normally done by decorator)
197
+ generateCrudActions(modelClass, dataSource, crudOptions);
198
+ // Then register GraphQL operations
199
+ registerCrudOperations(modelClass);
200
+ }
201
+ }
202
+ }
203
+ }
204
+
205
+ // Get schema (which will build it with all registered operations)
206
+ const schema = getGraphQLSchema();
207
+ if (!schema) {
208
+ throw new Error('Could not generate GraphQL schema. Please ensure @slingr/framework-backend is properly installed.');
209
+ }
210
+
211
+ const schemaString = printSchema(schema);
212
+
213
+ // Ensure generated/gql directory exists
214
+ const generatedDir = path.join(process.cwd(), 'generated', 'gql');
215
+ if (!fs.existsSync(generatedDir)) {
216
+ fs.mkdirSync(generatedDir, { recursive: true });
217
+ }
218
+
219
+ // Write schema to file
220
+ const schemaFilePath = path.join(generatedDir, 'schema.graphql');
221
+ try {
222
+ fs.writeFileSync(schemaFilePath, schemaString, 'utf8');
223
+ } catch (writeError: unknown) {
224
+ const msg = writeError instanceof Error ? writeError.message : String(writeError);
225
+ console.error(`āŒ Failed to write schema file at ${schemaFilePath}: ${msg}`);
226
+ throw writeError instanceof Error ? writeError : new Error(msg);
227
+ }
228
+
229
+ // Verify file creation and log size
230
+ try {
231
+ const stats = fs.statSync(schemaFilePath);
232
+ console.log(`āœ… GraphQL schema written: ${schemaFilePath} (${stats.size} bytes)`);
233
+ } catch (statError: unknown) {
234
+ const msg = statError instanceof Error ? statError.message : String(statError);
235
+ console.warn(`āš ļø Schema file write succeeded but verification failed: ${msg}`);
236
+ console.log(`ā„¹ļø Please check that the path exists and you have write permissions: ${schemaFilePath}`);
237
+ }
238
+
239
+ // Show a preview of the generated schema
240
+ const lines = schemaString.split('\n');
241
+ if (lines.length > 0) {
242
+ console.log('\nšŸ“‹ Schema preview:');
243
+ console.log(lines.slice(0, Math.min(15, lines.length)).join('\n'));
244
+ if (lines.length > 15) {
245
+ console.log(`... (${lines.length - 15} more lines)`);
246
+ }
247
+ }
248
+ await generateMetadataFile();
249
+ console.log('\nāœ… Schema generation completed. Script will terminate now.');
250
+ process.exit(0);
251
+ } catch (error: any) {
252
+ console.error(`Failed to generate schema: ${error.message}`);
253
+ console.error(error);
254
+ process.exit(1);
255
+ }
256
+ }
257
+
258
+ generateSchema();
@@ -0,0 +1,23 @@
1
+ # Slingr Application Configuration
2
+ # This file contains environment-specific configuration for your Slingr app.
3
+ # Copy this file to .env and customize the values as needed.
4
+
5
+ # GraphQL Server Configuration
6
+ GRAPHQL_HOST=localhost
7
+ GRAPHQL_PORT=3000
8
+ GRAPHQL_ENABLE_EXPLORER=true
9
+
10
+ # Note: These values can be overridden by:
11
+ # 1. app.configure() method in your code
12
+ # 2. app.run() options parameter
13
+ # Configuration priority: .env < configure() < run(options)
14
+
15
+ # JWT Configuration
16
+ JWT_SECRET=your-secret-key-change-in-production
17
+
18
+ # Database Configuration
19
+ DB_HOST=localhost
20
+ DB_PORT=5432
21
+ DB_USER=postgres
22
+ DB_PASSWORD=postgres
23
+ DB_NAME={{APP_NAME}}
@@ -0,0 +1,5 @@
1
+ {
2
+ "projects": {
3
+ "default": "YOUR_GCP_PROJECT_ID"
4
+ }
5
+ }