@joystick.js/cli-canary 0.0.0-canary.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 (231) hide show
  1. package/.build/getFilesToBuild.js +38 -0
  2. package/.build/index.js +69 -0
  3. package/HMRNOTES.txt +23 -0
  4. package/README.md +7 -0
  5. package/_package.json +55 -0
  6. package/canary.js +12 -0
  7. package/dist/cli.js +69 -0
  8. package/dist/functions/build/getTarIgnoreList.js +25 -0
  9. package/dist/functions/build/index.js +54 -0
  10. package/dist/functions/create/buildPackageJSON.js +20 -0
  11. package/dist/functions/create/index.js +193 -0
  12. package/dist/functions/create/templates/api/index.js +4 -0
  13. package/dist/functions/create/templates/i18n/en-US.js +4 -0
  14. package/dist/functions/create/templates/index.client.js +7 -0
  15. package/dist/functions/create/templates/index.css +20 -0
  16. package/dist/functions/create/templates/index.html +23 -0
  17. package/dist/functions/create/templates/index.server.js +21 -0
  18. package/dist/functions/create/templates/public/apple-touch-icon-152x152.png +0 -0
  19. package/dist/functions/create/templates/public/favicon.ico +0 -0
  20. package/dist/functions/create/templates/public/manifest.json +25 -0
  21. package/dist/functions/create/templates/public/service-worker.js +32 -0
  22. package/dist/functions/create/templates/public/splash-screen-1024x1024.png +0 -0
  23. package/dist/functions/create/templates/settings.development.json +27 -0
  24. package/dist/functions/create/templates/ui/components/button/index.js +50 -0
  25. package/dist/functions/create/templates/ui/layouts/app/index.js +13 -0
  26. package/dist/functions/create/templates/ui/pages/error/index.js +31 -0
  27. package/dist/functions/create/templates/ui/pages/index/index.js +94 -0
  28. package/dist/functions/index.js +243 -0
  29. package/dist/functions/logout/index.js +20 -0
  30. package/dist/functions/push/checkIfProvisionAvailable.js +19 -0
  31. package/dist/functions/push/deploy/index.js +173 -0
  32. package/dist/functions/push/deploy/initial.js +100 -0
  33. package/dist/functions/push/deploy/version.js +100 -0
  34. package/dist/functions/push/domains.js +23 -0
  35. package/dist/functions/push/getAvailableCDN.js +23 -0
  36. package/dist/functions/push/getDeployment.js +41 -0
  37. package/dist/functions/push/getDeploymentSummary.js +38 -0
  38. package/dist/functions/push/getInstanceSizeRegions.js +37 -0
  39. package/dist/functions/push/getInstanceSizesForRegion.js +34 -0
  40. package/dist/functions/push/getProviderInstanceSizes.js +34 -0
  41. package/dist/functions/push/getProviderRegions.js +36 -0
  42. package/dist/functions/push/getProvidersWithConnectionStatus.js +20 -0
  43. package/dist/functions/push/getSessionToken.js +23 -0
  44. package/dist/functions/push/getUserFromSessionToken.js +37 -0
  45. package/dist/functions/push/index.js +210 -0
  46. package/dist/functions/push/loginToCheatCode.js +33 -0
  47. package/dist/functions/push/pingProvisionAPI.js +31 -0
  48. package/dist/functions/push/prompts.js +332 -0
  49. package/dist/functions/push/providerMap.js +11 -0
  50. package/dist/functions/push/providers.js +9 -0
  51. package/dist/functions/reset/index.js +0 -0
  52. package/dist/functions/reset/reset.js +127 -0
  53. package/dist/functions/start/bootstrapLayoutComponent.js +54 -0
  54. package/dist/functions/start/bootstrapPageComponent.js +51 -0
  55. package/dist/functions/start/buildFile.js +85 -0
  56. package/dist/functions/start/buildFiles.js +76 -0
  57. package/dist/functions/start/buildPlugins.js +183 -0
  58. package/dist/functions/start/checkIfPortAvailable.js +18 -0
  59. package/dist/functions/start/cleanup/index.js +18 -0
  60. package/dist/functions/start/databases/mongodb/availableQueryParameters.js +42 -0
  61. package/dist/functions/start/databases/mongodb/buildConnectionString.js +22 -0
  62. package/dist/functions/start/databases/mongodb/buildQueryParameters.js +14 -0
  63. package/dist/functions/start/databases/mongodb/checkConnection.js +38 -0
  64. package/dist/functions/start/databases/mongodb/connect.js +25 -0
  65. package/dist/functions/start/databases/mongodb/index.js +93 -0
  66. package/dist/functions/start/databases/postgresql/checkConnection.js +41 -0
  67. package/dist/functions/start/databases/postgresql/connect.js +27 -0
  68. package/dist/functions/start/databases/postgresql/index.js +106 -0
  69. package/dist/functions/start/databases/redis.js +0 -0
  70. package/dist/functions/start/databases/startProvider.js +16 -0
  71. package/dist/functions/start/fileDependencyMapper.js +22 -0
  72. package/dist/functions/start/filesToCopy.js +18 -0
  73. package/dist/functions/start/generateId.js +74 -0
  74. package/dist/functions/start/getCodependenciesForFile.js +64 -0
  75. package/dist/functions/start/getFilesToBuild.js +39 -0
  76. package/dist/functions/start/getProcessIdFromPort.js +60 -0
  77. package/dist/functions/start/hmrServer.js +66 -0
  78. package/dist/functions/start/index.js +535 -0
  79. package/dist/functions/start/isWindows.js +5 -0
  80. package/dist/functions/start/minifyFile.js +12 -0
  81. package/dist/functions/start/onWarn.js +63 -0
  82. package/dist/functions/start/readFileDependencyMap.js +16 -0
  83. package/dist/functions/start/removeDeletedDependenciesFromMap.js +18 -0
  84. package/dist/functions/start/setComponentId.js +46 -0
  85. package/dist/functions/start/updateFileMap.js +67 -0
  86. package/dist/functions/update/index.js +21 -0
  87. package/dist/functions/use/index.js +61 -0
  88. package/dist/index.js +8 -0
  89. package/dist/lib/CLILog.js +49 -0
  90. package/dist/lib/buildResolvePlugin.js +21 -0
  91. package/dist/lib/checkIfValidJSON.js +11 -0
  92. package/dist/lib/colorLog.js +7 -0
  93. package/dist/lib/getArgs.js +14 -0
  94. package/dist/lib/getCodeFrame.js +10 -0
  95. package/dist/lib/getOptions.js +15 -0
  96. package/dist/lib/getPlatformSafePath.js +7 -0
  97. package/dist/lib/getProvider.js +8 -0
  98. package/dist/lib/help.js +56 -0
  99. package/dist/lib/isObject.js +6 -0
  100. package/dist/lib/isValidJSONString.js +11 -0
  101. package/dist/lib/isWindows.js +5 -0
  102. package/dist/lib/killProcesses.js +0 -0
  103. package/dist/lib/loadSettings.js +33 -0
  104. package/dist/lib/loader.js +82 -0
  105. package/dist/lib/masterIgnoreList.js +16 -0
  106. package/dist/lib/nodeEnvironment.js +9 -0
  107. package/dist/lib/nodeEnvironments.js +8 -0
  108. package/dist/lib/parseCookiesFromLogin.js +18 -0
  109. package/dist/lib/rainbowRoad.js +7 -0
  110. package/dist/lib/readDirectorySync.js +14 -0
  111. package/dist/lib/regexes.js +12 -0
  112. package/dist/lib/replaceBackslashesWithForwardSlashes.js +8 -0
  113. package/dist/lib/replaceFileProtocol.js +8 -0
  114. package/dist/lib/serializeQueryParameters.js +8 -0
  115. package/dist/lib/settings.js +4 -0
  116. package/dist/lib/validateDatabasesFromSettings.js +34 -0
  117. package/dist/lib/wait.js +8 -0
  118. package/package.json +54 -0
  119. package/release.js +40 -0
  120. package/src/cli.js +88 -0
  121. package/src/functions/build/getTarIgnoreList.js +30 -0
  122. package/src/functions/build/index.js +63 -0
  123. package/src/functions/create/buildPackageJSON.js +18 -0
  124. package/src/functions/create/index.js +209 -0
  125. package/src/functions/create/templates/api/index.js +4 -0
  126. package/src/functions/create/templates/i18n/en-US.js +4 -0
  127. package/src/functions/create/templates/index.client.js +7 -0
  128. package/src/functions/create/templates/index.css +20 -0
  129. package/src/functions/create/templates/index.html +23 -0
  130. package/src/functions/create/templates/index.server.js +21 -0
  131. package/src/functions/create/templates/public/apple-touch-icon-152x152.png +0 -0
  132. package/src/functions/create/templates/public/favicon.ico +0 -0
  133. package/src/functions/create/templates/public/manifest.json +25 -0
  134. package/src/functions/create/templates/public/service-worker.js +32 -0
  135. package/src/functions/create/templates/public/splash-screen-1024x1024.png +0 -0
  136. package/src/functions/create/templates/settings.development.json +27 -0
  137. package/src/functions/create/templates/ui/components/button/index.js +50 -0
  138. package/src/functions/create/templates/ui/layouts/app/index.js +13 -0
  139. package/src/functions/create/templates/ui/pages/error/index.js +31 -0
  140. package/src/functions/create/templates/ui/pages/index/index.js +94 -0
  141. package/src/functions/index.js +243 -0
  142. package/src/functions/logout/index.js +20 -0
  143. package/src/functions/push/checkIfProvisionAvailable.js +20 -0
  144. package/src/functions/push/deploy/index.js +199 -0
  145. package/src/functions/push/deploy/initial.js +108 -0
  146. package/src/functions/push/deploy/version.js +108 -0
  147. package/src/functions/push/domains.js +23 -0
  148. package/src/functions/push/getAvailableCDN.js +27 -0
  149. package/src/functions/push/getDeployment.js +43 -0
  150. package/src/functions/push/getDeploymentSummary.js +39 -0
  151. package/src/functions/push/getInstanceSizeRegions.js +40 -0
  152. package/src/functions/push/getInstanceSizesForRegion.js +35 -0
  153. package/src/functions/push/getProviderInstanceSizes.js +35 -0
  154. package/src/functions/push/getProviderRegions.js +39 -0
  155. package/src/functions/push/getProvidersWithConnectionStatus.js +25 -0
  156. package/src/functions/push/getSessionToken.js +26 -0
  157. package/src/functions/push/getUserFromSessionToken.js +39 -0
  158. package/src/functions/push/index.js +245 -0
  159. package/src/functions/push/loginToCheatCode.js +34 -0
  160. package/src/functions/push/pingProvisionAPI.js +33 -0
  161. package/src/functions/push/prompts.js +276 -0
  162. package/src/functions/push/providerMap.js +8 -0
  163. package/src/functions/push/providers.js +6 -0
  164. package/src/functions/reset/index.js +0 -0
  165. package/src/functions/reset/reset.js +163 -0
  166. package/src/functions/start/bootstrapLayoutComponent.js +57 -0
  167. package/src/functions/start/bootstrapPageComponent.js +54 -0
  168. package/src/functions/start/buildFile.js +97 -0
  169. package/src/functions/start/buildFiles.js +101 -0
  170. package/src/functions/start/buildPlugins.js +215 -0
  171. package/src/functions/start/checkIfPortAvailable.js +21 -0
  172. package/src/functions/start/cleanup/index.js +23 -0
  173. package/src/functions/start/databases/mongodb/availableQueryParameters.js +39 -0
  174. package/src/functions/start/databases/mongodb/buildConnectionString.js +28 -0
  175. package/src/functions/start/databases/mongodb/buildQueryParameters.js +15 -0
  176. package/src/functions/start/databases/mongodb/checkConnection.js +40 -0
  177. package/src/functions/start/databases/mongodb/connect.js +25 -0
  178. package/src/functions/start/databases/mongodb/index.js +108 -0
  179. package/src/functions/start/databases/postgresql/checkConnection.js +43 -0
  180. package/src/functions/start/databases/postgresql/connect.js +27 -0
  181. package/src/functions/start/databases/postgresql/index.js +127 -0
  182. package/src/functions/start/databases/redis.js +0 -0
  183. package/src/functions/start/databases/startProvider.js +15 -0
  184. package/src/functions/start/fileDependencyMapper.js +24 -0
  185. package/src/functions/start/filesToCopy.js +15 -0
  186. package/src/functions/start/generateId.js +73 -0
  187. package/src/functions/start/getCodependenciesForFile.js +84 -0
  188. package/src/functions/start/getFilesToBuild.js +49 -0
  189. package/src/functions/start/getProcessIdFromPort.js +92 -0
  190. package/src/functions/start/hmrServer.js +78 -0
  191. package/src/functions/start/index.js +688 -0
  192. package/src/functions/start/isWindows.js +3 -0
  193. package/src/functions/start/minifyFile.js +10 -0
  194. package/src/functions/start/onWarn.js +68 -0
  195. package/src/functions/start/readFileDependencyMap.js +19 -0
  196. package/src/functions/start/removeDeletedDependenciesFromMap.js +19 -0
  197. package/src/functions/start/setComponentId.js +58 -0
  198. package/src/functions/start/updateFileMap.js +100 -0
  199. package/src/functions/update/index.js +20 -0
  200. package/src/functions/use/index.js +62 -0
  201. package/src/index.js +13 -0
  202. package/src/lib/CLILog.js +40 -0
  203. package/src/lib/buildResolvePlugin.js +32 -0
  204. package/src/lib/checkIfValidJSON.js +8 -0
  205. package/src/lib/colorLog.js +5 -0
  206. package/src/lib/getArgs.js +14 -0
  207. package/src/lib/getCodeFrame.js +8 -0
  208. package/src/lib/getOptions.js +12 -0
  209. package/src/lib/getPlatformSafePath.js +6 -0
  210. package/src/lib/getProvider.js +5 -0
  211. package/src/lib/help.js +56 -0
  212. package/src/lib/isObject.js +3 -0
  213. package/src/lib/isValidJSONString.js +8 -0
  214. package/src/lib/isWindows.js +3 -0
  215. package/src/lib/killProcesses.js +5 -0
  216. package/src/lib/loadSettings.js +40 -0
  217. package/src/lib/loader.js +94 -0
  218. package/src/lib/masterIgnoreList.js +13 -0
  219. package/src/lib/nodeEnvironment.js +6 -0
  220. package/src/lib/nodeEnvironments.js +8 -0
  221. package/src/lib/parseCookiesFromLogin.js +21 -0
  222. package/src/lib/rainbowRoad.js +5 -0
  223. package/src/lib/readDirectorySync.js +13 -0
  224. package/src/lib/regexes.js +5 -0
  225. package/src/lib/replaceBackslashesWithForwardSlashes.js +8 -0
  226. package/src/lib/replaceFileProtocol.js +8 -0
  227. package/src/lib/serializeQueryParameters.js +5 -0
  228. package/src/lib/settings.js +1 -0
  229. package/src/lib/validateDatabasesFromSettings.js +37 -0
  230. package/src/lib/wait.js +5 -0
  231. package/storage/.verdaccio-db.json +1 -0
@@ -0,0 +1,66 @@
1
+ import fs from "fs";
2
+ import { WebSocketServer } from "ws";
3
+ import generateId from "./generateId";
4
+ var hmrServer_default = (() => {
5
+ const websocketServer = new WebSocketServer({
6
+ port: parseInt(process.env.PORT, 10) + 1,
7
+ path: "/_joystick/hmr"
8
+ });
9
+ process.on("message", (message) => {
10
+ if (typeof process.HMR_CONNECTIONS === "object") {
11
+ const parsedMessage = JSON.parse(message);
12
+ const connections = Object.values(process.HMR_CONNECTIONS);
13
+ for (let i = 0; i < connections?.length; i += 1) {
14
+ const connection = connections[i];
15
+ if (connection?.connection?.send) {
16
+ connection.connection.send(
17
+ JSON.stringify({
18
+ type: "FILE_CHANGE",
19
+ settings: {
20
+ global: parsedMessage?.settings?.global,
21
+ public: parsedMessage?.settings?.public
22
+ },
23
+ indexHTMLChanged: parsedMessage?.indexHTMLChanged
24
+ })
25
+ );
26
+ }
27
+ }
28
+ }
29
+ });
30
+ websocketServer.on("connection", function connection(websocketConnection) {
31
+ const connectionId = generateId();
32
+ process.HMR_CONNECTIONS = {
33
+ ...process.HMR_CONNECTIONS || {},
34
+ [connectionId]: {
35
+ connection: websocketConnection,
36
+ watchlist: []
37
+ }
38
+ };
39
+ if (Object.keys(process.HMR_CONNECTIONS || {})?.length > 0) {
40
+ process.send({ type: "HAS_HMR_CONNECTIONS" });
41
+ }
42
+ websocketConnection.on("message", (message) => {
43
+ const parsedMessage = JSON.parse(message);
44
+ if (parsedMessage?.type === "HMR_UPDATE_COMPLETE") {
45
+ process.send({ type: "HMR_UPDATE_COMPLETED", sessions: parsedMessage?.sessions });
46
+ }
47
+ if (parsedMessage?.type === "HMR_WATCHLIST") {
48
+ process.HMR_CONNECTIONS[connectionId]?.watchlist?.push(
49
+ ...parsedMessage?.tags || []
50
+ );
51
+ }
52
+ });
53
+ websocketConnection.on("close", () => {
54
+ if (process.HMR_CONNECTIONS[connectionId]) {
55
+ delete process.HMR_CONNECTIONS[connectionId];
56
+ if (Object.keys(process.HMR_CONNECTIONS || {})?.length === 0) {
57
+ process.send({ type: "HAS_NO_HMR_CONNECTIONS" });
58
+ }
59
+ }
60
+ });
61
+ });
62
+ return true;
63
+ })();
64
+ export {
65
+ hmrServer_default as default
66
+ };
@@ -0,0 +1,535 @@
1
+ import child_process from "child_process";
2
+ import path, { dirname } from "path";
3
+ import { fileURLToPath } from "url";
4
+ import ps from "ps-node";
5
+ import { killPortProcess } from "kill-port-process";
6
+ import fs from "fs";
7
+ import chokidar from "chokidar";
8
+ import Loader from "../../lib/loader.js";
9
+ import getFilesToBuild from "./getFilesToBuild.js";
10
+ import buildFiles from "./buildFiles.js";
11
+ import filesToCopy from "./filesToCopy.js";
12
+ import checkIfPortAvailable from "./checkIfPortAvailable.js";
13
+ import getCodependenciesForFile from "./getCodependenciesForFile.js";
14
+ import isValidJSONString from "../../lib/isValidJSONString.js";
15
+ import startDatabaseProvider from "./databases/startProvider.js";
16
+ import CLILog from "../../lib/CLILog.js";
17
+ import removeDeletedDependenciesFromMap from "./removeDeletedDependenciesFromMap.js";
18
+ import validateDatabasesFromSettings from "../../lib/validateDatabasesFromSettings.js";
19
+ import wait from "../../lib/wait.js";
20
+ const majorVersion = parseInt(
21
+ process?.version?.split(".")[0]?.replace("v", ""),
22
+ 10
23
+ );
24
+ const __filename = fileURLToPath(import.meta.url);
25
+ const __dirname = dirname(__filename);
26
+ const killProcess = (pid = 0) => {
27
+ return new Promise((resolve) => {
28
+ ps.kill(pid, () => {
29
+ resolve();
30
+ });
31
+ });
32
+ };
33
+ const watchlist = [
34
+ { path: "ui" },
35
+ { path: "lib" },
36
+ { path: "i18n" },
37
+ { path: "api" },
38
+ { path: "email" },
39
+ { path: "fixtures" },
40
+ { path: "routes" },
41
+ { path: "index.client.js" },
42
+ { path: "index.server.js" },
43
+ ...filesToCopy
44
+ ];
45
+ const requiredFileCheck = () => {
46
+ return new Promise((resolve) => {
47
+ const requiredFiles = [
48
+ { path: "index.server.js", type: "file" },
49
+ { path: "index.html", type: "file" },
50
+ { path: "index.client.js", type: "file" },
51
+ { path: "api", type: "directory" },
52
+ { path: "i18n", type: "directory" },
53
+ { path: "lib", type: "directory" },
54
+ { path: "public", type: "directory" },
55
+ { path: "ui", type: "directory" },
56
+ { path: "ui/components", type: "directory" },
57
+ { path: "ui/layouts", type: "directory" },
58
+ { path: "ui/pages", type: "directory" }
59
+ ];
60
+ requiredFiles.forEach((requiredFile) => {
61
+ const exists = fs.existsSync(`${process.cwd()}/${requiredFile.path}`);
62
+ const stats = exists && fs.statSync(`${process.cwd()}/${requiredFile.path}`);
63
+ const isFile = stats && stats.isFile();
64
+ const isDirectory = stats && stats.isDirectory();
65
+ if (requiredFile && requiredFile.type === "file") {
66
+ if (!exists || exists && !isFile) {
67
+ CLILog(
68
+ `The path ${requiredFile.path} must exist in your project and must be a file (not a directory).`,
69
+ {
70
+ level: "danger",
71
+ docs: "https://github.com/cheatcode/joystick#folder-and-file-structure"
72
+ }
73
+ );
74
+ process.exit(0);
75
+ }
76
+ }
77
+ if (requiredFile && requiredFile.type === "directory") {
78
+ if (!exists || exists && !isDirectory) {
79
+ CLILog(
80
+ `The path ${requiredFile.path} must exist in your project and must be a directory (not a file).`,
81
+ {
82
+ level: "danger",
83
+ docs: "https://github.com/cheatcode/joystick#folder-and-file-structure"
84
+ }
85
+ );
86
+ process.exit(0);
87
+ }
88
+ }
89
+ });
90
+ resolve();
91
+ });
92
+ };
93
+ const handleCleanup = async (processIds = [process?.serverProcess?.pid, process?.hmrProcess?.pid]) => {
94
+ for (let i = 0; i < processIds?.length; i += 1) {
95
+ const processId = processIds[i];
96
+ if (processId) {
97
+ await killProcess(processId);
98
+ }
99
+ }
100
+ const databases = Object.entries(process._databases || {});
101
+ for (let i = 0; i < databases?.length; i += 1) {
102
+ const [provider, providerConnection] = databases[i];
103
+ if (providerConnection?.pid) {
104
+ await killProcess(providerConnection.pid);
105
+ }
106
+ if (!providerConnection?.pid) {
107
+ const providerConnections = Object.entries(providerConnection);
108
+ for (let pc = 0; pc < providerConnections?.length; pc += 1) {
109
+ const [_connectionName, connection] = providerConnections[pc];
110
+ if (connection?.pid) {
111
+ await killProcess(connection?.pid);
112
+ }
113
+ }
114
+ }
115
+ }
116
+ };
117
+ const getDatabaseProcessIds = () => {
118
+ const databaseProcessIds = [];
119
+ const databases = Object.entries(process._databases || {});
120
+ for (let i = 0; i < databases?.length; i += 1) {
121
+ const [_provider, providerConnection] = databases[i];
122
+ if (providerConnection?.pid) {
123
+ databaseProcessIds.push(providerConnection.pid);
124
+ }
125
+ if (!providerConnection?.pid) {
126
+ const providerConnections = Object.entries(providerConnection);
127
+ for (let pc = 0; pc < providerConnections?.length; pc += 1) {
128
+ const [_connectionName, connection] = providerConnections[pc];
129
+ if (connection?.pid) {
130
+ databaseProcessIds.push(connection.pid);
131
+ }
132
+ }
133
+ }
134
+ }
135
+ return databaseProcessIds;
136
+ };
137
+ const handleSignalEvents = (processIds = []) => {
138
+ const execArgv = ["--no-warnings"];
139
+ if (majorVersion < 19) {
140
+ execArgv.push("--experimental-specifier-resolution=node");
141
+ }
142
+ const cleanupProcess = child_process.fork(
143
+ path.resolve(`${__dirname}/cleanup/index.js`),
144
+ [],
145
+ {
146
+ // NOTE: Run in detached mode so when parent process dies, the child still runs
147
+ // and cleanup completes.
148
+ detached: true,
149
+ execArgv,
150
+ // NOTE: Pipe stdin, stdout, and stderr. IPC establishes a message channel so we
151
+ // communicate with the child_process.
152
+ silent: true
153
+ }
154
+ );
155
+ process.on("SIGINT", async () => {
156
+ const databaseProcessIds = getDatabaseProcessIds();
157
+ cleanupProcess.send(JSON.stringify({ processIds: [...processIds, ...databaseProcessIds] }));
158
+ process.exit();
159
+ });
160
+ process.on("SIGTERM", async () => {
161
+ const databaseProcessIds = getDatabaseProcessIds();
162
+ cleanupProcess.send(JSON.stringify({ processIds: [...processIds, ...databaseProcessIds] }));
163
+ process.exit();
164
+ });
165
+ };
166
+ const handleHMRProcessMessages = () => {
167
+ process.hmrProcess.on("message", (message) => {
168
+ const processMessages = [
169
+ "SERVER_CLOSED",
170
+ "HAS_HMR_CONNECTIONS",
171
+ "HAS_NO_HMR_CONNECTIONS",
172
+ "HMR_UPDATE_COMPLETED"
173
+ ];
174
+ if (!processMessages.includes(message?.type)) {
175
+ process.loader.stable(message);
176
+ }
177
+ if (message?.type === "HAS_HMR_CONNECTIONS") {
178
+ process.hmrProcess.hasConnections = true;
179
+ }
180
+ if (message?.type === "HAS_NO_HMR_CONNECTIONS") {
181
+ process.hmrProcess.hasConnections = false;
182
+ }
183
+ if (message?.type === "HMR_UPDATE_COMPLETED") {
184
+ setTimeout(() => {
185
+ restartApplicationProcess(message?.sessions);
186
+ }, 500);
187
+ }
188
+ });
189
+ };
190
+ const handleHMRProcessSTDIO = () => {
191
+ try {
192
+ if (process.hmrProcess) {
193
+ process.hmrProcess.on("error", (error) => {
194
+ CLILog(error.toString(), {
195
+ level: "danger",
196
+ docs: "https://github.com/cheatcode/joystick"
197
+ });
198
+ });
199
+ process.hmrProcess.stdout.on("data", (data) => {
200
+ console.log(data.toString());
201
+ });
202
+ process.hmrProcess.stderr.on("data", (data) => {
203
+ process.loader.stop();
204
+ CLILog(data.toString(), {
205
+ level: "danger",
206
+ docs: "https://github.com/cheatcode/joystick"
207
+ });
208
+ });
209
+ }
210
+ } catch (exception) {
211
+ throw new Error(`[dev.handleHMRProcessSTDIO] ${exception.message}`);
212
+ }
213
+ };
214
+ const startHMRProcess = () => {
215
+ const execArgv = ["--no-warnings"];
216
+ if (majorVersion < 19) {
217
+ execArgv.push("--experimental-specifier-resolution=node");
218
+ }
219
+ const hmrProcess = child_process.fork(
220
+ path.resolve(`${__dirname}/hmrServer.js`),
221
+ [],
222
+ {
223
+ execArgv,
224
+ // NOTE: Pipe stdin, stdout, and stderr. IPC establishes a message channel so we
225
+ // communicate with the child_process.
226
+ silent: true
227
+ }
228
+ );
229
+ process.hmrProcess = hmrProcess;
230
+ handleHMRProcessSTDIO();
231
+ handleHMRProcessMessages();
232
+ };
233
+ const notifyHMRClients = (indexHTMLChanged = false) => {
234
+ const settings = loadSettings(process.env.NODE_ENV);
235
+ process.hmrProcess.send(
236
+ JSON.stringify({
237
+ type: "RESTART_SERVER",
238
+ settings,
239
+ indexHTMLChanged
240
+ })
241
+ );
242
+ };
243
+ const handleServerProcessMessages = () => {
244
+ process.serverProcess.on("message", (message) => {
245
+ const processMessages = ["SERVER_CLOSED"];
246
+ if (!processMessages.includes(message)) {
247
+ process.loader.stable(message);
248
+ }
249
+ });
250
+ };
251
+ const handleServerProcessSTDIO = () => {
252
+ try {
253
+ if (process.serverProcess) {
254
+ process.serverProcess.on("error", (error) => {
255
+ console.log(error);
256
+ });
257
+ process.serverProcess.stdout.on("data", (data) => {
258
+ const message = data.toString();
259
+ if (message && message.includes("App running at:")) {
260
+ process.loader.stable(message);
261
+ } else {
262
+ if (message && !message.includes("BUILD_ERROR")) {
263
+ console.log(message);
264
+ }
265
+ }
266
+ });
267
+ process.serverProcess.stderr.on("data", (data) => {
268
+ process.loader.stop();
269
+ CLILog(data.toString(), {
270
+ level: "danger",
271
+ docs: "https://github.com/cheatcode/joystick"
272
+ });
273
+ });
274
+ }
275
+ } catch (exception) {
276
+ throw new Error(`[dev.handleServerProcessSTDIO] ${exception.message}`);
277
+ }
278
+ };
279
+ const startApplicationProcess = (sessionsBeforeHMRUpdate = null) => {
280
+ const execArgv = ["--no-warnings"];
281
+ if (majorVersion < 19) {
282
+ execArgv.push("--experimental-specifier-resolution=node");
283
+ }
284
+ if (process.env.NODE_ENV === "development" && process.env.IS_DEBUG_MODE === "true") {
285
+ execArgv.push("--inspect");
286
+ }
287
+ const serverProcess = child_process.fork(
288
+ path.resolve(".joystick/build/index.server.js"),
289
+ [],
290
+ {
291
+ execArgv,
292
+ // NOTE: Pipe stdin, stdout, and stderr. IPC establishes a message channel so we
293
+ // communicate with the child_process.
294
+ silent: true,
295
+ env: {
296
+ FORCE_COLOR: "1",
297
+ LOGS_PATH: process.env.LOGS_PATH,
298
+ NODE_ENV: process.env.NODE_ENV,
299
+ ROOT_URL: process.env.ROOT_URL,
300
+ PORT: process.env.PORT,
301
+ JOYSTICK_SETTINGS: process.env.JOYSTICK_SETTINGS,
302
+ HMR_SESSIONS: sessionsBeforeHMRUpdate
303
+ }
304
+ }
305
+ );
306
+ process.serverProcess = serverProcess;
307
+ handleServerProcessSTDIO();
308
+ handleServerProcessMessages();
309
+ return serverProcess;
310
+ };
311
+ const restartApplicationProcess = async (sessionsBeforeHMRUpdate = null) => {
312
+ if (process.serverProcess && process.serverProcess.pid) {
313
+ process.loader.text("Restarting app...");
314
+ process.serverProcess.kill();
315
+ startApplicationProcess(sessionsBeforeHMRUpdate);
316
+ return Promise.resolve();
317
+ }
318
+ process.loader.text("Starting app...");
319
+ startApplicationProcess();
320
+ if (!process.hmrProcess) {
321
+ startHMRProcess();
322
+ }
323
+ };
324
+ const initialBuild = async (buildSettings = {}) => {
325
+ const buildPath = `.joystick/build`;
326
+ const fileMapPath = `.joystick/build/fileMap.json`;
327
+ if (!fs.existsSync(buildPath)) {
328
+ fs.mkdirSync(".joystick/build");
329
+ }
330
+ if (fs.existsSync(fileMapPath)) {
331
+ fs.unlinkSync(fileMapPath);
332
+ }
333
+ process.loader.text("Building app...");
334
+ await requiredFileCheck();
335
+ const filesToBuild = getFilesToBuild(buildSettings?.excludedPaths, "start");
336
+ const fileResults = await buildFiles(
337
+ filesToBuild,
338
+ null,
339
+ process.env.NODE_ENV
340
+ );
341
+ const hasErrors = [...fileResults].filter((result) => !!result).map(({ success }) => success).includes(false);
342
+ if (!hasErrors) {
343
+ startApplicationProcess();
344
+ startHMRProcess();
345
+ }
346
+ };
347
+ const startWatcher = async (buildSettings = {}) => {
348
+ await initialBuild(buildSettings);
349
+ const watcher = chokidar.watch(
350
+ watchlist.map(({ path: path2 }) => path2),
351
+ {
352
+ ignoreInitial: true
353
+ }
354
+ );
355
+ watcher.on("all", async (event, path2) => {
356
+ await requiredFileCheck();
357
+ process.loader.text("Rebuilding app...");
358
+ const isHTMLUpdate = path2 === "index.html";
359
+ const isUIPath = path2?.includes("ui/") || path2 === "index.css" || isHTMLUpdate;
360
+ const isUIUpdate = process.hmrProcess.hasConnections && isUIPath || false;
361
+ if (["addDir"].includes(event) && fs.existsSync(path2) && fs.lstatSync(path2).isDirectory() && !fs.existsSync(`./.joystick/build/${path2}`)) {
362
+ fs.mkdirSync(`./.joystick/build/${path2}`);
363
+ if (isUIUpdate) {
364
+ notifyHMRClients(isHTMLUpdate);
365
+ } else {
366
+ restartApplicationProcess();
367
+ }
368
+ return;
369
+ }
370
+ if (!!filesToCopy.find((fileToCopy) => fileToCopy.path === path2)) {
371
+ const isDirectory = fs.statSync(path2).isDirectory();
372
+ if (isDirectory && !fs.existsSync(`./.joystick/build/${path2}`)) {
373
+ fs.mkdirSync(`./.joystick/build/${path2}`);
374
+ }
375
+ if (!isDirectory) {
376
+ fs.writeFileSync(`./.joystick/build/${path2}`, fs.readFileSync(path2));
377
+ }
378
+ loadSettings(process.env.NODE_ENV);
379
+ if (isUIUpdate) {
380
+ notifyHMRClients(isHTMLUpdate);
381
+ } else {
382
+ restartApplicationProcess();
383
+ }
384
+ return;
385
+ }
386
+ if (["add", "change"].includes(event) && fs.existsSync(path2)) {
387
+ const codependencies = getCodependenciesForFile(path2);
388
+ const fileResults = await buildFiles(
389
+ [path2, ...codependencies?.existing || []],
390
+ null,
391
+ process.env.NODE_ENV
392
+ );
393
+ const fileResultsHaveErrors = fileResults.filter((result) => !!result).map(({ success }) => success).includes(false);
394
+ removeDeletedDependenciesFromMap(codependencies.deleted);
395
+ const hasErrors = fileResultsHaveErrors;
396
+ if (process.serverProcess && hasErrors) {
397
+ process.serverProcess.send(
398
+ JSON.stringify({
399
+ error: "BUILD_ERROR",
400
+ paths: fileResults.filter(({ success }) => !success).map(({ path: pathWithError, error }) => ({
401
+ path: pathWithError,
402
+ error
403
+ }))
404
+ })
405
+ );
406
+ return;
407
+ }
408
+ if (!hasErrors) {
409
+ process.initialBuildComplete = true;
410
+ if (isUIUpdate) {
411
+ notifyHMRClients(isHTMLUpdate);
412
+ } else {
413
+ restartApplicationProcess();
414
+ }
415
+ return;
416
+ }
417
+ }
418
+ if (["unlink", "unlinkDir"].includes(event) && !fs.existsSync(`./.joystick/build/${path2}`)) {
419
+ if (isUIUpdate) {
420
+ notifyHMRClients(isHTMLUpdate);
421
+ } else {
422
+ restartApplicationProcess();
423
+ }
424
+ return;
425
+ }
426
+ if (["unlink", "unlinkDir"].includes(event) && fs.existsSync(`./.joystick/build/${path2}`)) {
427
+ const pathToUnlink = `./.joystick/build/${path2}`;
428
+ const stats = fs.lstatSync(pathToUnlink);
429
+ if (stats.isDirectory()) {
430
+ fs.rmdirSync(pathToUnlink, { recursive: true });
431
+ }
432
+ if (stats.isFile()) {
433
+ fs.unlinkSync(pathToUnlink);
434
+ }
435
+ if (isUIUpdate) {
436
+ notifyHMRClients(isHTMLUpdate);
437
+ } else {
438
+ restartApplicationProcess();
439
+ }
440
+ return;
441
+ }
442
+ });
443
+ };
444
+ const startDatabase = async (database = {}, databasePort = 2610, hasMultipleOfProvider = false) => {
445
+ process._databases = {
446
+ ...process._databases || {},
447
+ [database.provider]: !hasMultipleOfProvider ? await startDatabaseProvider(database, databasePort) : {
448
+ ...process._databases && process._databases[database.provider] || {},
449
+ [database?.name || `${database.provider}_${databasePort}`]: await startDatabaseProvider(database, databasePort)
450
+ }
451
+ };
452
+ return Promise.resolve(process._databases);
453
+ };
454
+ const startDatabases = async (databasePortStart = 2610) => {
455
+ try {
456
+ const hasSettings = !!process.env.JOYSTICK_SETTINGS;
457
+ const settings = hasSettings && JSON.parse(process.env.JOYSTICK_SETTINGS);
458
+ const databases = settings?.config?.databases || [];
459
+ if (databases && Array.isArray(databases) && databases.length > 0) {
460
+ validateDatabasesFromSettings(databases);
461
+ for (let i = 0; i < databases?.length; i += 1) {
462
+ const database = databases[i];
463
+ const hasMultipleOfProvider = databases?.filter((database2) => database2?.provider === database2?.provider)?.length > 1;
464
+ await startDatabase(database, databasePortStart + i, hasMultipleOfProvider);
465
+ }
466
+ return Promise.resolve();
467
+ }
468
+ return Promise.resolve();
469
+ } catch (exception) {
470
+ console.warn(exception);
471
+ }
472
+ };
473
+ const loadSettings = () => {
474
+ const environment = process.env.NODE_ENV;
475
+ const settingsFilePath = `${process.cwd()}/settings.${environment}.json`;
476
+ const hasSettingsFile = fs.existsSync(settingsFilePath);
477
+ if (!hasSettingsFile) {
478
+ CLILog(
479
+ `A settings file could not be found for this environment (${environment}). Create a settings.${environment}.json file at the root of your project and restart Joystick.`,
480
+ {
481
+ level: "danger",
482
+ docs: "https://github.com/cheatcode/joystick#settings"
483
+ }
484
+ );
485
+ process.exit(0);
486
+ }
487
+ const rawSettingsFile = fs.readFileSync(settingsFilePath, "utf-8");
488
+ const isValidJSON = isValidJSONString(rawSettingsFile);
489
+ if (!isValidJSON) {
490
+ CLILog(
491
+ `Failed to parse settings file. Double-check the syntax in your settings.${environment}.json file at the root of your project and restart Joystick.`,
492
+ {
493
+ level: "danger",
494
+ docs: "https://github.com/cheatcode/joystick#settings",
495
+ tools: [{ title: "JSON Linter", url: "https://jsonlint.com/" }]
496
+ }
497
+ );
498
+ process.exit(0);
499
+ }
500
+ const settingsFile = isValidJSON ? rawSettingsFile : "{}";
501
+ process.env.JOYSTICK_SETTINGS = settingsFile;
502
+ return JSON.parse(settingsFile);
503
+ };
504
+ const checkIfJoystickProject = () => {
505
+ return fs.existsSync(`${process.cwd()}/.joystick`);
506
+ };
507
+ var start_default = async (args = {}, options = {}) => {
508
+ process.loader = new Loader({ defaultMessage: "Starting app..." });
509
+ const port = options?.port ? parseInt(options?.port) : 2600;
510
+ const databasePortStart = port + 10;
511
+ const isJoystickProject = checkIfJoystickProject();
512
+ if (!isJoystickProject) {
513
+ CLILog(
514
+ "This is not a Joystick project. A .joystick folder could not be found.",
515
+ {
516
+ level: "danger",
517
+ docs: "https://github.com/cheatcode/joystick"
518
+ }
519
+ );
520
+ process.exit(0);
521
+ }
522
+ await killPortProcess([port, port + 1]);
523
+ process.title = "joystick";
524
+ process.env.LOGS_PATH = options?.logs || null;
525
+ process.env.NODE_ENV = options?.environment || "development";
526
+ process.env.PORT = options?.port ? parseInt(options?.port) : 2600;
527
+ process.env.IS_DEBUG_MODE = options?.debug;
528
+ const settings = loadSettings(process.env.NODE_ENV);
529
+ await startDatabases(databasePortStart);
530
+ startWatcher(settings?.config?.build);
531
+ handleSignalEvents([]);
532
+ };
533
+ export {
534
+ start_default as default
535
+ };
@@ -0,0 +1,5 @@
1
+ import os from "os";
2
+ var isWindows_default = os.platform() === "win32";
3
+ export {
4
+ isWindows_default as default
5
+ };
@@ -0,0 +1,12 @@
1
+ import fs from "fs";
2
+ import esbuild from "esbuild";
3
+ var minifyFile_default = async (path = "") => {
4
+ if (fs.existsSync(path)) {
5
+ const file = fs.readFileSync(path, "utf-8");
6
+ const minified = await esbuild.transform(file, { minify: true });
7
+ fs.writeFileSync(path, minified.code);
8
+ }
9
+ };
10
+ export {
11
+ minifyFile_default as default
12
+ };
@@ -0,0 +1,63 @@
1
+ import chalk from "chalk";
2
+ import { OBJECT_REGEX } from "../../lib/regexes.js";
3
+ import rainbowRoad from "../../lib/rainbowRoad.js";
4
+ import getCodeFrame from "../../lib/getCodeFrame.js";
5
+ const removeLocationDataFromStackTrace = (stackTrace = "") => {
6
+ return stackTrace.replace(OBJECT_REGEX, "");
7
+ };
8
+ const logError = (warning = {}) => {
9
+ const snippetParts = warning?.snippet?.split(`
10
+ `);
11
+ console.log("\n");
12
+ console.log(`${rainbowRoad()}
13
+ `);
14
+ if (warning.file) {
15
+ console.log(chalk.yellowBright(`Build Error in ${warning?.file}:
16
+ `));
17
+ }
18
+ if (snippetParts && snippetParts.length > 0) {
19
+ snippetParts.forEach((line) => {
20
+ if (line.includes(`> ${warning.line} |`)) {
21
+ return console.log(` ${chalk.red(line)}`);
22
+ }
23
+ return console.log(` ${chalk.gray(line)}`);
24
+ });
25
+ }
26
+ if (warning?.stack) {
27
+ console.log(chalk.magentaBright("\nStack Trace:\n"));
28
+ console.log(chalk.yellow(` ${removeLocationDataFromStackTrace(warning?.stack)}
29
+ `));
30
+ }
31
+ process.loader.error(
32
+ "Build error. Fix the error above to continue building your app."
33
+ );
34
+ console.log("\n");
35
+ console.log(`${rainbowRoad()}
36
+ `);
37
+ };
38
+ const parseWarning = (warning = {}, type = "") => {
39
+ if (type && type === "BUILD_ERROR") {
40
+ return {
41
+ file: warning?.file,
42
+ snippet: warning?.snippet || getCodeFrame(warning.file, {
43
+ line: warning?.line,
44
+ column: warning?.column
45
+ }),
46
+ stack: warning?.stack,
47
+ line: warning?.line,
48
+ character: warning?.column,
49
+ message: warning?.message
50
+ };
51
+ }
52
+ return null;
53
+ };
54
+ var onWarn_default = (warning) => {
55
+ const parsedWarning = parseWarning(warning, "BUILD_ERROR");
56
+ if (parsedWarning) {
57
+ logError(parsedWarning);
58
+ }
59
+ return parsedWarning;
60
+ };
61
+ export {
62
+ onWarn_default as default
63
+ };
@@ -0,0 +1,16 @@
1
+ import fs from "fs";
2
+ var readFileDependencyMap_default = () => {
3
+ const fileDependencyMapPath = `.joystick/build/fileMap.json`;
4
+ if (fs.existsSync(fileDependencyMapPath)) {
5
+ const fileDependencyMapAsJSON = fs.readFileSync(
6
+ fileDependencyMapPath,
7
+ "utf-8"
8
+ );
9
+ const fileMap = fileDependencyMapAsJSON ? JSON.parse(fileDependencyMapAsJSON) : {};
10
+ return fileMap;
11
+ }
12
+ return {};
13
+ };
14
+ export {
15
+ readFileDependencyMap_default as default
16
+ };