@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
@@ -0,0 +1,288 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.loadDataSource = loadDataSource;
7
+ exports.loadUserModel = loadUserModel;
8
+ exports.loadRoleEnum = loadRoleEnum;
9
+ exports.findUserByEmail = findUserByEmail;
10
+ exports.getUserRepository = getUserRepository;
11
+ exports.validateRoles = validateRoles;
12
+ exports.getAvailableRoles = getAvailableRoles;
13
+ exports.generateRandomPassword = generateRandomPassword;
14
+ exports.validateEmail = validateEmail;
15
+ exports.promptPassword = promptPassword;
16
+ exports.promptConfirmation = promptConfirmation;
17
+ exports.formatUser = formatUser;
18
+ const node_path_1 = __importDefault(require("node:path"));
19
+ const node_url_1 = require("node:url");
20
+ const fs_extra_1 = __importDefault(require("fs-extra"));
21
+ const inquirer_1 = __importDefault(require("inquirer"));
22
+ require("reflect-metadata");
23
+ const datasourceParser_js_1 = require("./datasourceParser.js");
24
+ const checkFramework_js_1 = require("./checkFramework.js");
25
+ const datasourceParser_js_2 = require("./datasourceParser.js");
26
+ // Metadata key used by the @DataModel decorator to store the datasource
27
+ // This matches the internal framework constant
28
+ const MODEL_DATASOURCE = 'model:dataSource';
29
+ /**
30
+ * Get the datasource used by the User model by inspecting the User model metadata
31
+ */
32
+ async function getUserDataSource() {
33
+ const UserModel = await loadUserModel();
34
+ // Get the datasource from the model's metadata using reflect-metadata API
35
+ // The @DataModel decorator stores this information using Reflect.defineMetadata()
36
+ const dataSource = Reflect.getMetadata(MODEL_DATASOURCE, UserModel);
37
+ if (!dataSource) {
38
+ throw new Error(`User model does not have a datasource configured. ` +
39
+ `Make sure the User class has @DataModel({ dataSource: yourDataSource }) decorator.`);
40
+ }
41
+ // Try to get TypeORM datasource info, but it might not be initialized yet
42
+ let typeormDs;
43
+ try {
44
+ typeormDs = dataSource.getTypeOrmDataSource();
45
+ if (typeormDs) {
46
+ console.log(`\n📊 Using datasource: ${typeormDs.options?.type || 'unknown'} (${typeormDs.options?.database || 'unknown db'})`);
47
+ if (typeormDs.isInitialized) {
48
+ console.log('✅ TypeORM datasource already initialized\n');
49
+ return dataSource;
50
+ }
51
+ }
52
+ }
53
+ catch (error) {
54
+ // If getTypeOrmDataSource() throws, it means it's not initialized yet
55
+ console.log('\n⚙️ TypeORM datasource not initialized yet, initializing now...');
56
+ }
57
+ // Initialize the datasource
58
+ console.log('🔧 Initializing datasource...');
59
+ await dataSource.initialize();
60
+ // Log success with datasource info
61
+ const initializedDs = dataSource.getTypeOrmDataSource();
62
+ if (initializedDs) {
63
+ console.log(`✅ Datasource initialized: ${initializedDs.options?.type || 'unknown'} (${initializedDs.options?.database || 'unknown db'})\n`);
64
+ }
65
+ else {
66
+ console.log('✅ Datasource initialized\n');
67
+ }
68
+ return dataSource;
69
+ }
70
+ /**
71
+ * Load and initialize the datasource used by the User model
72
+ * This is the recommended way to get the datasource for user operations
73
+ */
74
+ async function loadDataSource(dsName) {
75
+ // If no datasource name is provided, discover it from the User model
76
+ if (!dsName) {
77
+ return await getUserDataSource();
78
+ }
79
+ await (0, datasourceParser_js_1.discoverDatasourceFile)(dsName);
80
+ const dsConfig = await (0, datasourceParser_js_2.loadDataSourceFromFile)(dsName);
81
+ if (!dsConfig.getTypeOrmDataSource()?.isInitialized) {
82
+ await dsConfig.initialize();
83
+ }
84
+ return dsConfig;
85
+ }
86
+ /**
87
+ * Recursively find a file by name under a directory.
88
+ */
89
+ async function findFileRecursive(dir, filename) {
90
+ if (!(await fs_extra_1.default.pathExists(dir))) {
91
+ return null;
92
+ }
93
+ const entries = await fs_extra_1.default.readdir(dir, { withFileTypes: true });
94
+ for (const entry of entries) {
95
+ const fullPath = node_path_1.default.join(dir, entry.name);
96
+ if (entry.isDirectory()) {
97
+ const found = await findFileRecursive(fullPath, filename);
98
+ if (found) {
99
+ return found;
100
+ }
101
+ }
102
+ else if (entry.name === filename) {
103
+ return fullPath;
104
+ }
105
+ }
106
+ return null;
107
+ }
108
+ /**
109
+ * Load the User model from the compiled app
110
+ */
111
+ async function loadUserModel() {
112
+ const backendPath = (0, checkFramework_js_1.getBackendPath)();
113
+ const dataDir = node_path_1.default.join(backendPath, 'dist', 'src', 'data');
114
+ const userModulePath = await findFileRecursive(dataDir, 'User.js');
115
+ if (!userModulePath) {
116
+ throw new Error('User model not found. Make sure the app is built (npm run build from backend directory) and User.ts exists somewhere under backend/src/data/');
117
+ }
118
+ try {
119
+ const userModule = await import((0, node_url_1.pathToFileURL)(userModulePath).href);
120
+ return userModule.User || userModule.default;
121
+ }
122
+ catch (error) {
123
+ if (error.code === 'MODULE_NOT_FOUND' || error.code === 'ERR_MODULE_NOT_FOUND') {
124
+ throw new Error('User model not found. Make sure the app is built (npm run build from backend directory) and User.ts exists somewhere under backend/src/data/');
125
+ }
126
+ throw error;
127
+ }
128
+ }
129
+ /**
130
+ * Load the Role enum from the compiled app
131
+ */
132
+ async function loadRoleEnum() {
133
+ const backendPath = (0, checkFramework_js_1.getBackendPath)();
134
+ const dataDir = node_path_1.default.join(backendPath, 'dist', 'src', 'data');
135
+ const userModulePath = await findFileRecursive(dataDir, 'User.js');
136
+ if (!userModulePath) {
137
+ return undefined;
138
+ } // Role enum is optional
139
+ try {
140
+ const userModule = await import((0, node_url_1.pathToFileURL)(userModulePath).href);
141
+ return userModule.Role;
142
+ }
143
+ catch (error) {
144
+ return undefined; // Role enum is optional
145
+ }
146
+ }
147
+ /**
148
+ * Find a user by email
149
+ */
150
+ async function findUserByEmail(email, userRepo) {
151
+ return await userRepo.findOne({ where: { email } });
152
+ }
153
+ /**
154
+ * Get user repository from datasource
155
+ */
156
+ async function getUserRepository(dataSource) {
157
+ console.log(' 🔍 Loading User model...');
158
+ const UserModel = await loadUserModel();
159
+ console.log(' ✅ User model loaded');
160
+ console.log(' 🔍 Getting TypeORM datasource...');
161
+ const typeormDs = dataSource.getTypeOrmDataSource();
162
+ console.log(` ✅ TypeORM datasource: ${typeormDs ? 'found' : 'NOT FOUND'}`);
163
+ if (typeormDs) {
164
+ console.log(` 📊 Datasource initialized: ${typeormDs.isInitialized}`);
165
+ }
166
+ else {
167
+ console.log(' ⚠️ WARNING: TypeORM datasource is null/undefined!');
168
+ }
169
+ console.log(' 🔍 Getting repository...');
170
+ return dataSource.native().getRepository(UserModel);
171
+ }
172
+ /**
173
+ * Validate roles against the app's Role enum
174
+ */
175
+ async function validateRoles(roles) {
176
+ try {
177
+ const RoleEnum = await loadRoleEnum();
178
+ const validRoles = Object.values(RoleEnum);
179
+ const invalidRoles = roles.filter(role => !validRoles.includes(role));
180
+ return {
181
+ valid: invalidRoles.length === 0,
182
+ invalidRoles,
183
+ };
184
+ }
185
+ catch (error) {
186
+ // If we can't load the enum, assume roles are valid
187
+ return { valid: true, invalidRoles: [] };
188
+ }
189
+ }
190
+ /**
191
+ * Get available roles from the app's Role enum
192
+ */
193
+ async function getAvailableRoles() {
194
+ try {
195
+ const RoleEnum = await loadRoleEnum();
196
+ return Object.values(RoleEnum);
197
+ }
198
+ catch (error) {
199
+ return [];
200
+ }
201
+ }
202
+ /**
203
+ * Generate a secure random password
204
+ */
205
+ function generateRandomPassword(length = 12) {
206
+ const uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
207
+ const lowercase = 'abcdefghijklmnopqrstuvwxyz';
208
+ const numbers = '0123456789';
209
+ const symbols = '@$!%*?&';
210
+ const allChars = uppercase + lowercase + numbers + symbols;
211
+ let password = '';
212
+ // Ensure at least one of each type
213
+ password += uppercase[Math.floor(Math.random() * uppercase.length)];
214
+ password += lowercase[Math.floor(Math.random() * lowercase.length)];
215
+ password += numbers[Math.floor(Math.random() * numbers.length)];
216
+ password += symbols[Math.floor(Math.random() * symbols.length)];
217
+ // Fill the rest randomly
218
+ for (let i = password.length; i < length; i++) {
219
+ password += allChars[Math.floor(Math.random() * allChars.length)];
220
+ }
221
+ // Shuffle the password
222
+ return password
223
+ .split('')
224
+ .sort(() => Math.random() - 0.5)
225
+ .join('');
226
+ }
227
+ /**
228
+ * Validate email format
229
+ */
230
+ function validateEmail(email) {
231
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
232
+ return emailRegex.test(email);
233
+ }
234
+ /**
235
+ * Interactive password prompt with confirmation
236
+ */
237
+ async function promptPassword(message = 'Password') {
238
+ const answers = await inquirer_1.default.prompt([
239
+ {
240
+ type: 'password',
241
+ name: 'password',
242
+ message: message,
243
+ mask: '*',
244
+ validate: (input) => {
245
+ if (input.length < 8) {
246
+ return 'Password must be at least 8 characters long';
247
+ }
248
+ return true;
249
+ },
250
+ },
251
+ {
252
+ type: 'password',
253
+ name: 'confirmPassword',
254
+ message: 'Confirm password',
255
+ mask: '*',
256
+ validate: (input, answers) => {
257
+ if (input !== answers?.password) {
258
+ return 'Passwords do not match';
259
+ }
260
+ return true;
261
+ },
262
+ },
263
+ ]);
264
+ return answers.password;
265
+ }
266
+ /**
267
+ * Interactive confirmation prompt
268
+ */
269
+ async function promptConfirmation(message, defaultValue = false) {
270
+ const answer = await inquirer_1.default.prompt([
271
+ {
272
+ type: 'confirm',
273
+ name: 'confirm',
274
+ message: message,
275
+ default: defaultValue,
276
+ },
277
+ ]);
278
+ return answer.confirm;
279
+ }
280
+ /**
281
+ * Format user for display
282
+ */
283
+ function formatUser(user) {
284
+ const rolesText = user.roles ? user.roles.join(', ') : 'None';
285
+ const statusText = user.status === 'active' ? '[ACTIVE]' : ' [INACTIVE]';
286
+ return `${user.email} - ${user.firstName} ${user.lastName} (${rolesText})${statusText}`;
287
+ }
288
+ //# sourceMappingURL=userManagement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"userManagement.js","sourceRoot":"","sources":["../../src/utils/userManagement.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Generates the context.ts file for custom views.
3
+ * This file exports a polyfill for require.context that registers all views.
4
+ *
5
+ * The generated file will:
6
+ * 1. Import all .tsx files from the views directory (excluding tests and context.tsx itself)
7
+ * 2. Create a registry mapping relative paths to module exports
8
+ * 3. Export a polyfill function that mimics webpack's require.context interface
9
+ *
10
+ * @param cwd - The working directory (defaults to process.cwd())
11
+ * @param verbose - Whether to print progress messages (defaults to true)
12
+ * @returns true if context.ts was generated, false if no views were found
13
+ */
14
+ export declare function generateViewsContext(cwd?: string, verbose?: boolean): Promise<boolean>;
15
+ //# sourceMappingURL=viewsGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewsGenerator.d.ts","sourceRoot":"","sources":["../../src/utils/viewsGenerator.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;GAYG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,GAAE,MAAsB,EAAE,OAAO,GAAE,OAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAyQjH"}
@@ -0,0 +1,311 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.generateViewsContext = generateViewsContext;
7
+ const fs_extra_1 = __importDefault(require("fs-extra"));
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const glob_1 = require("glob");
10
+ const buildCache_js_1 = require("./buildCache.js");
11
+ /**
12
+ * Generates the context.ts file for custom views.
13
+ * This file exports a polyfill for require.context that registers all views.
14
+ *
15
+ * The generated file will:
16
+ * 1. Import all .tsx files from the views directory (excluding tests and context.tsx itself)
17
+ * 2. Create a registry mapping relative paths to module exports
18
+ * 3. Export a polyfill function that mimics webpack's require.context interface
19
+ *
20
+ * @param cwd - The working directory (defaults to process.cwd())
21
+ * @param verbose - Whether to print progress messages (defaults to true)
22
+ * @returns true if context.ts was generated, false if no views were found
23
+ */
24
+ async function generateViewsContext(cwd = process.cwd(), verbose = true) {
25
+ const viewsDir = node_path_1.default.join(cwd, 'frontend', 'src', 'views');
26
+ const generatedDir = node_path_1.default.join(cwd, 'frontend', 'generated');
27
+ const contextFilePath = node_path_1.default.join(generatedDir, 'context.ts');
28
+ const frontendViewsFilePath = node_path_1.default.join(generatedDir, 'views.ts');
29
+ const backendGeneratedDir = node_path_1.default.join(cwd, 'backend', 'generated');
30
+ const backendViewsFilePath = node_path_1.default.join(backendGeneratedDir, 'views.ts');
31
+ // Check if views directory exists
32
+ if (!(await fs_extra_1.default.pathExists(viewsDir))) {
33
+ if (verbose) {
34
+ console.log('⚠️ Views directory not found, skipping context.ts generation');
35
+ }
36
+ return false;
37
+ }
38
+ // Find all .tsx files in views directory (excluding tests and context.tsx itself)
39
+ const viewFiles = await (0, glob_1.glob)('**/*.tsx', {
40
+ cwd: viewsDir,
41
+ absolute: false,
42
+ ignore: ['**/*.test.tsx', '**/*.spec.tsx', 'context.tsx'],
43
+ });
44
+ // If no views found, skip context.ts creation
45
+ if (viewFiles.length === 0) {
46
+ if (verbose) {
47
+ console.log('ℹ️ No views found, skipping context.ts generation');
48
+ }
49
+ return false;
50
+ }
51
+ // Use a sidecar file to track the set of view files for up-to-date check
52
+ const upToDate = await (0, buildCache_js_1.isUpToDate)({
53
+ cwd,
54
+ sourceGlobs: ['frontend/src/views/**/*.tsx'],
55
+ outputFiles: ['frontend/generated/context.ts', 'frontend/generated/views.ts', 'backend/generated/views.ts'],
56
+ sidecarFile: 'frontend/generated/context.ts.sources.json',
57
+ });
58
+ if (upToDate) {
59
+ if (verbose) {
60
+ console.log('✅ Views context up-to-date, skipping');
61
+ }
62
+ return true;
63
+ }
64
+ if (verbose) {
65
+ console.log(`📝 Scanning ${viewFiles.length} .tsx file(s) for views...`);
66
+ }
67
+ // Generate import statements and registry entries
68
+ const imports = [];
69
+ const registryEntries = [];
70
+ const viewRegistryEntries = [];
71
+ const viewTypeImports = [];
72
+ const byType = {
73
+ table: [],
74
+ read: [],
75
+ edit: [],
76
+ create: [],
77
+ action: [],
78
+ custom: [],
79
+ };
80
+ for (const file of viewFiles) {
81
+ // Normalize path separators to forward slashes for consistent registry keys
82
+ const normalizedPath = file.replace(/\\/g, '/');
83
+ const viewType = await detectViewType(node_path_1.default.join(viewsDir, normalizedPath));
84
+ if (!viewType) {
85
+ continue;
86
+ } // skip helpers and non-view .tsx files
87
+ // Generate a unique variable name from the file path
88
+ // e.g., "customViews/welcome.tsx" -> "CustomViewsWelcome"
89
+ // e.g., "admin/users.tsx" -> "AdminUsers"
90
+ const varName = generateVariableName(normalizedPath);
91
+ // Generate import statement with relative path (from frontend/generated/ to frontend/src/views/)
92
+ const importPath = '../src/views/' + normalizedPath.replace(/\.tsx$/, '');
93
+ imports.push(`import ${varName} from '${importPath}';`);
94
+ // Add registry entry
95
+ registryEntries.push(` './${normalizedPath}': { default: ${varName} }`);
96
+ const baseName = node_path_1.default.basename(normalizedPath, '.tsx');
97
+ const viewClassName = baseName.charAt(0).toUpperCase() + baseName.slice(1);
98
+ byType[viewType].push(viewClassName);
99
+ viewRegistryEntries.push(` ${viewClassName}: typeof import('${importPath}').default;`);
100
+ viewTypeImports.push(` | typeof import('${importPath}').default`);
101
+ }
102
+ const viewCount = Object.values(byType).reduce((sum, names) => sum + names.length, 0);
103
+ // Ensure the generated directories exist
104
+ await fs_extra_1.default.ensureDir(generatedDir);
105
+ await fs_extra_1.default.ensureDir(backendGeneratedDir);
106
+ // Generate the complete context.ts file
107
+ const content = `/**
108
+ * Context Loader - Auto-generated
109
+ *
110
+ * This file is automatically generated by the Slingr CLI.
111
+ * Do not edit manually - changes will be overwritten.
112
+ *
113
+ * Generated: ${new Date().toISOString()}
114
+ * Views: ${viewCount}
115
+ */
116
+
117
+ // Import and register field metadata before any views are loaded
118
+ import './gql';
119
+ ${imports.join('\n')}
120
+
121
+ // Create a map of filename -> module
122
+ const views: Record<string, any> = {
123
+ ${registryEntries.join(',\n')}
124
+ };
125
+
126
+ // Create a polyfill for require.context
127
+ // The framework expects a function that takes a key and returns the module
128
+ const contextPolyfill = (key: string) => {
129
+ return views[key];
130
+ };
131
+
132
+ // Attach the 'keys' method which returns the list of filenames
133
+ (contextPolyfill as any).keys = () => Object.keys(views);
134
+
135
+ export const customViewsContext = contextPolyfill as any;
136
+
137
+ export type AppViewClass =
138
+ ${viewTypeImports.join('\n')};
139
+
140
+ declare global {
141
+ interface SlingrViewRegistry {
142
+ ${viewRegistryEntries.join('\n')}
143
+ }
144
+ }
145
+
146
+ export {};`;
147
+ const categoryMeta = [
148
+ {
149
+ key: 'table',
150
+ exportName: 'tableViewNames',
151
+ typeName: 'TableViewName',
152
+ ifaceName: 'SlingrTableViewNameRegistry',
153
+ },
154
+ {
155
+ key: 'read',
156
+ exportName: 'readViewNames',
157
+ typeName: 'ReadViewName',
158
+ ifaceName: 'SlingrReadViewNameRegistry',
159
+ },
160
+ {
161
+ key: 'edit',
162
+ exportName: 'editViewNames',
163
+ typeName: 'EditViewName',
164
+ ifaceName: 'SlingrEditViewNameRegistry',
165
+ },
166
+ {
167
+ key: 'create',
168
+ exportName: 'createViewNames',
169
+ typeName: 'CreateViewName',
170
+ ifaceName: 'SlingrCreateViewNameRegistry',
171
+ },
172
+ {
173
+ key: 'action',
174
+ exportName: 'actionViewNames',
175
+ typeName: 'ActionViewName',
176
+ ifaceName: 'SlingrActionViewNameRegistry',
177
+ },
178
+ {
179
+ key: 'custom',
180
+ exportName: 'customViewNames',
181
+ typeName: 'CustomViewName',
182
+ ifaceName: 'SlingrCustomViewNameRegistry',
183
+ },
184
+ ];
185
+ const categoryBlocks = categoryMeta.map(({ key, exportName, typeName }) => {
186
+ const names = byType[key];
187
+ return `export const ${exportName} = [\n${names.map(n => ` '${n}'`).join(',\n')}\n] as const;\nexport type ${typeName} = typeof ${exportName}[number];`;
188
+ });
189
+ const allViewNames = categoryMeta.flatMap(({ key }) => byType[key]);
190
+ const allViewNameRegistryEntries = allViewNames.map(n => ` ${n}: true;`);
191
+ const categoryRegistryBlocks = categoryMeta.map(({ ifaceName, key }) => ` interface ${ifaceName} {\n${byType[key].map(n => ` ${n}: true;`).join('\n')}\n }`);
192
+ const sharedViewsContent = `/**
193
+ * View Names - Auto-generated
194
+ *
195
+ * This file is automatically generated by the Slingr CLI.
196
+ * Do not edit manually - changes will be overwritten.
197
+ *
198
+ * Generated: ${new Date().toISOString()}
199
+ * Views: ${viewCount}
200
+ */
201
+
202
+ ${categoryBlocks.join('\n\n')}
203
+
204
+ export const viewNames = [
205
+ ...tableViewNames,
206
+ ...readViewNames,
207
+ ...editViewNames,
208
+ ...createViewNames,
209
+ ...actionViewNames,
210
+ ...customViewNames,
211
+ ] as const;
212
+
213
+ export type ViewName = typeof viewNames[number];
214
+
215
+ declare global {
216
+ ${categoryRegistryBlocks.join('\n')}
217
+ interface SlingrViewNameRegistry {
218
+ ${allViewNameRegistryEntries.join('\n')}
219
+ }
220
+ }
221
+
222
+ export {};
223
+ `;
224
+ // Backend views file: module format (with declare global + exports) so that
225
+ // a static import in generate-schema.ts activates the type augmentations for
226
+ // schema compilation via ts-node.
227
+ const backendViewsContent = `/**
228
+ * View Name Type Registries - Auto-generated
229
+ *
230
+ * This file is automatically generated by the Slingr CLI.
231
+ * Do not edit manually - changes will be overwritten.
232
+ *
233
+ * Generated: ${new Date().toISOString()}
234
+ * Views: ${viewCount}
235
+ *
236
+ * Imported by the schema generation script so that declare global augmentations
237
+ * are active during TypeScript compilation of backend models.
238
+ */
239
+
240
+ declare global {
241
+ ${categoryRegistryBlocks.join('\n')}
242
+ interface SlingrViewNameRegistry {
243
+ ${allViewNameRegistryEntries.join('\n')}
244
+ }
245
+ }
246
+
247
+ export {};
248
+ `;
249
+ // Write the generated files
250
+ await fs_extra_1.default.writeFile(contextFilePath, content, 'utf-8');
251
+ await fs_extra_1.default.writeFile(frontendViewsFilePath, sharedViewsContent, 'utf-8');
252
+ await fs_extra_1.default.writeFile(backendViewsFilePath, backendViewsContent, 'utf-8');
253
+ // Update the sidecar file with the current set of view files
254
+ await (0, buildCache_js_1.updateFileSetSidecar)({
255
+ cwd,
256
+ sourceGlobs: ['frontend/src/views/**/*.tsx'],
257
+ outputFiles: ['frontend/generated/context.ts', 'frontend/generated/views.ts', 'backend/generated/views.ts'],
258
+ sidecarFile: 'frontend/generated/context.ts.sources.json',
259
+ });
260
+ if (verbose) {
261
+ console.log(`✅ Generated context.ts with ${viewCount} view(s)`);
262
+ }
263
+ return true;
264
+ }
265
+ /**
266
+ * Detects the view type of a .tsx file by scanning for a recognized view decorator.
267
+ * Returns null if no recognized decorator is found (e.g. layout helpers).
268
+ */
269
+ async function detectViewType(filePath) {
270
+ const content = await fs_extra_1.default.readFile(filePath, 'utf-8');
271
+ if (/@TableView[\s<(]/.test(content)) {
272
+ return 'table';
273
+ }
274
+ if (/@ReadView[\s<(]/.test(content)) {
275
+ return 'read';
276
+ }
277
+ if (/@EditView[\s<(]/.test(content)) {
278
+ return 'edit';
279
+ }
280
+ if (/@CreateView[\s<(]/.test(content)) {
281
+ return 'create';
282
+ }
283
+ if (/@ActionView[\s<(]/.test(content)) {
284
+ return 'action';
285
+ }
286
+ if (/@CustomView[\s<(]/.test(content)) {
287
+ return 'custom';
288
+ }
289
+ return null;
290
+ }
291
+ /**
292
+ * Generates a unique variable name from a file path.
293
+ *
294
+ * Examples:
295
+ * - "customViews/welcome.tsx" -> "CustomViewsWelcome"
296
+ * - "admin/users.tsx" -> "AdminUsers"
297
+ * - "user.tsx" -> "User"
298
+ *
299
+ * @param filePath - The file path relative to views directory
300
+ * @returns A valid TypeScript variable name in PascalCase
301
+ */
302
+ function generateVariableName(filePath) {
303
+ // Remove .tsx extension
304
+ const withoutExt = filePath.replace(/\.tsx$/, '');
305
+ // Split by path separators and non-alphanumeric characters
306
+ const parts = withoutExt.split(/[\/\-_\.]/);
307
+ // Convert to PascalCase
308
+ const pascalCase = parts.map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join('');
309
+ return pascalCase || 'View';
310
+ }
311
+ //# sourceMappingURL=viewsGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewsGenerator.js","sourceRoot":"","sources":["../../src/utils/viewsGenerator.ts"],"names":[],"mappings":"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"}