d1s 0.2.6 → 0.2.8

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 (247) hide show
  1. package/README.md +3 -1
  2. package/dist/.next/.next/BUILD_ID +1 -1
  3. package/dist/.next/.next/app-build-manifest.json +34 -27
  4. package/dist/.next/.next/app-path-routes-manifest.json +1 -1
  5. package/dist/.next/.next/build-manifest.json +2 -2
  6. package/dist/.next/.next/cache/.rscinfo +1 -1
  7. package/dist/.next/.next/cache/.tsbuildinfo +1 -1
  8. package/dist/.next/.next/cache/webpack/client-development/0.pack.gz +0 -0
  9. package/dist/.next/.next/cache/webpack/client-development/1.pack.gz +0 -0
  10. package/dist/.next/.next/cache/webpack/client-development/2.pack.gz +0 -0
  11. package/dist/.next/.next/cache/webpack/client-development/3.pack.gz +0 -0
  12. package/dist/.next/.next/cache/webpack/client-development/4.pack.gz +0 -0
  13. package/dist/.next/.next/cache/webpack/client-development/index.pack.gz +0 -0
  14. package/dist/.next/.next/cache/webpack/client-development/index.pack.gz.old +0 -0
  15. package/dist/.next/.next/cache/webpack/client-production/0.pack +0 -0
  16. package/dist/.next/.next/cache/webpack/client-production/1.pack +0 -0
  17. package/dist/.next/.next/cache/webpack/client-production/10.pack +0 -0
  18. package/dist/.next/.next/cache/webpack/client-production/11.pack +0 -0
  19. package/dist/.next/.next/cache/webpack/client-production/12.pack +0 -0
  20. package/dist/.next/.next/cache/webpack/client-production/13.pack +0 -0
  21. package/dist/.next/.next/cache/webpack/client-production/14.pack +0 -0
  22. package/dist/.next/.next/cache/webpack/client-production/2.pack +0 -0
  23. package/dist/.next/.next/cache/webpack/client-production/3.pack +0 -0
  24. package/dist/.next/.next/cache/webpack/client-production/4.pack +0 -0
  25. package/dist/.next/.next/cache/webpack/client-production/5.pack +0 -0
  26. package/dist/.next/.next/cache/webpack/client-production/6.pack +0 -0
  27. package/dist/.next/.next/cache/webpack/client-production/7.pack +0 -0
  28. package/dist/.next/.next/cache/webpack/client-production/8.pack +0 -0
  29. package/dist/.next/.next/cache/webpack/client-production/9.pack +0 -0
  30. package/dist/.next/.next/cache/webpack/client-production/index.pack +0 -0
  31. package/dist/.next/.next/cache/webpack/client-production/index.pack.old +0 -0
  32. package/dist/.next/.next/cache/webpack/edge-server-production/index.pack +0 -0
  33. package/dist/.next/.next/cache/webpack/server-development/0.pack.gz +0 -0
  34. package/dist/.next/.next/cache/webpack/server-development/1.pack.gz +0 -0
  35. package/dist/.next/.next/cache/webpack/server-development/2.pack.gz +0 -0
  36. package/dist/.next/.next/cache/webpack/server-development/3.pack.gz +0 -0
  37. package/dist/.next/.next/cache/webpack/server-development/4.pack.gz +0 -0
  38. package/dist/.next/.next/cache/webpack/server-development/index.pack.gz +0 -0
  39. package/dist/.next/.next/cache/webpack/server-development/index.pack.gz.old +0 -0
  40. package/dist/.next/.next/cache/webpack/server-production/0.pack +0 -0
  41. package/dist/.next/.next/cache/webpack/server-production/1.pack +0 -0
  42. package/dist/.next/.next/cache/webpack/server-production/10.pack +0 -0
  43. package/dist/.next/.next/cache/webpack/server-production/11.pack +0 -0
  44. package/dist/.next/.next/cache/webpack/server-production/12.pack +0 -0
  45. package/dist/.next/.next/cache/webpack/server-production/13.pack +0 -0
  46. package/dist/.next/.next/cache/webpack/server-production/2.pack +0 -0
  47. package/dist/.next/.next/cache/webpack/server-production/3.pack +0 -0
  48. package/dist/.next/.next/cache/webpack/server-production/4.pack +0 -0
  49. package/dist/.next/.next/cache/webpack/server-production/5.pack +0 -0
  50. package/dist/.next/.next/cache/webpack/server-production/6.pack +0 -0
  51. package/dist/.next/.next/cache/webpack/server-production/7.pack +0 -0
  52. package/dist/.next/.next/cache/webpack/server-production/8.pack +0 -0
  53. package/dist/.next/.next/cache/webpack/server-production/9.pack +0 -0
  54. package/dist/.next/.next/cache/webpack/server-production/index.pack +0 -0
  55. package/dist/.next/.next/cache/webpack/server-production/index.pack.old +0 -0
  56. package/dist/.next/.next/next-minimal-server.js.nft.json +1 -1
  57. package/dist/.next/.next/next-server.js.nft.json +1 -1
  58. package/dist/.next/.next/prerender-manifest.json +1 -1
  59. package/dist/.next/.next/server/app/_not-found/page.js +1 -1
  60. package/dist/.next/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  61. package/dist/.next/.next/server/app/_not-found.html +1 -1
  62. package/dist/.next/.next/server/app/_not-found.rsc +2 -2
  63. package/dist/.next/.next/server/app/api/cloudflare/route.js +1 -1
  64. package/dist/.next/.next/server/app/api/cloudflare/route.js.nft.json +1 -1
  65. package/dist/.next/.next/server/app/api/cloudflare/route_client-reference-manifest.js +1 -1
  66. package/dist/.next/.next/server/app/api/databases/route.js +1 -1
  67. package/dist/.next/.next/server/app/api/databases/route.js.nft.json +1 -1
  68. package/dist/.next/.next/server/app/api/databases/route_client-reference-manifest.js +1 -1
  69. package/dist/.next/.next/server/app/api/migrations/sync/route.js +3 -3
  70. package/dist/.next/.next/server/app/api/migrations/sync/route.js.nft.json +1 -1
  71. package/dist/.next/.next/server/app/api/migrations/sync/route_client-reference-manifest.js +1 -1
  72. package/dist/.next/.next/server/app/api/migrations/sync-files/route.js +1 -1
  73. package/dist/.next/.next/server/app/api/migrations/sync-files/route.js.nft.json +1 -1
  74. package/dist/.next/.next/server/app/api/migrations/sync-files/route_client-reference-manifest.js +1 -1
  75. package/dist/.next/.next/server/app/api/pull-remote/confirm/route.js +1 -1
  76. package/dist/.next/.next/server/app/api/pull-remote/confirm/route.js.nft.json +1 -1
  77. package/dist/.next/.next/server/app/api/pull-remote/confirm/route_client-reference-manifest.js +1 -1
  78. package/dist/.next/.next/server/app/api/pull-remote/preview/route.js +1 -1
  79. package/dist/.next/.next/server/app/api/pull-remote/preview/route.js.nft.json +1 -1
  80. package/dist/.next/.next/server/app/api/pull-remote/preview/route_client-reference-manifest.js +1 -1
  81. package/dist/.next/.next/server/app/api/push-remote/confirm/route.js +2 -2
  82. package/dist/.next/.next/server/app/api/push-remote/confirm/route.js.nft.json +1 -1
  83. package/dist/.next/.next/server/app/api/push-remote/confirm/route_client-reference-manifest.js +1 -1
  84. package/dist/.next/.next/server/app/api/push-remote/preview/route.js +2 -2
  85. package/dist/.next/.next/server/app/api/push-remote/preview/route.js.nft.json +1 -1
  86. package/dist/.next/.next/server/app/api/push-remote/preview/route_client-reference-manifest.js +1 -1
  87. package/dist/.next/.next/server/app/api/query/route.js +2 -2
  88. package/dist/.next/.next/server/app/api/query/route.js.nft.json +1 -1
  89. package/dist/.next/.next/server/app/api/query/route_client-reference-manifest.js +1 -1
  90. package/dist/.next/.next/server/app/api/tables/[name]/route.js +4 -4
  91. package/dist/.next/.next/server/app/api/tables/[name]/route.js.nft.json +1 -1
  92. package/dist/.next/.next/server/app/api/tables/[name]/route_client-reference-manifest.js +1 -1
  93. package/dist/.next/.next/server/app/api/tables/route.js +2 -2
  94. package/dist/.next/.next/server/app/api/tables/route.js.nft.json +1 -1
  95. package/dist/.next/.next/server/app/api/tables/route_client-reference-manifest.js +1 -1
  96. package/dist/.next/.next/server/app/api/update/route.js +5 -0
  97. package/dist/.next/.next/server/app/api/update/route.js.nft.json +1 -0
  98. package/dist/.next/.next/server/app/api/update/route_client-reference-manifest.js +1 -0
  99. package/dist/.next/.next/server/app/index.html +3 -3
  100. package/dist/.next/.next/server/app/index.rsc +3 -3
  101. package/dist/.next/.next/server/app/page.js +14 -12
  102. package/dist/.next/.next/server/app/page_client-reference-manifest.js +1 -1
  103. package/dist/.next/.next/server/app-paths-manifest.json +4 -3
  104. package/dist/.next/.next/server/chunks/336.js +1 -1
  105. package/dist/.next/.next/server/chunks/391.js +23 -0
  106. package/dist/.next/.next/server/chunks/452.js +1 -0
  107. package/dist/.next/.next/server/chunks/627.js +3 -3
  108. package/dist/.next/.next/server/chunks/638.js +3 -3
  109. package/dist/.next/.next/server/chunks/801.js +55 -0
  110. package/dist/.next/.next/server/chunks/992.js +3 -3
  111. package/dist/.next/.next/server/pages/404.html +1 -1
  112. package/dist/.next/.next/server/pages/500.html +1 -1
  113. package/dist/.next/.next/server/pages/_app.js +1 -1
  114. package/dist/.next/.next/server/pages/_document.js +1 -1
  115. package/dist/.next/.next/server/pages/_error.js +1 -1
  116. package/dist/.next/.next/server/pages-manifest.json +1 -1
  117. package/dist/.next/.next/server/server-reference-manifest.json +1 -1
  118. package/dist/.next/.next/static/JrwgdSDcipr0Zh7k19Cj_/_buildManifest.js +1 -0
  119. package/dist/.next/.next/static/chunks/958-98887928efebfdf7.js +1 -0
  120. package/dist/.next/.next/static/chunks/app/api/cloudflare/route-5133155a604f2719.js +1 -0
  121. package/dist/.next/.next/static/chunks/app/api/databases/route-63a31080b565794e.js +1 -0
  122. package/dist/.next/.next/static/chunks/app/api/migrations/sync/route-d97667565b4a59b6.js +1 -0
  123. package/dist/.next/.next/static/chunks/app/api/migrations/sync-files/route-7089bcbfeb6b5260.js +1 -0
  124. package/dist/.next/.next/static/chunks/app/api/pull-remote/confirm/route-9143e6e4c3f05162.js +1 -0
  125. package/dist/.next/.next/static/chunks/app/api/pull-remote/preview/route-c963d143a51aed66.js +1 -0
  126. package/dist/.next/.next/static/chunks/app/api/push-remote/confirm/route-072132c0a6cb3df3.js +1 -0
  127. package/dist/.next/.next/static/chunks/app/api/push-remote/preview/route-ca6bf35aa72661ee.js +1 -0
  128. package/dist/.next/.next/static/chunks/app/api/query/route-1466f6b7ffd8b6c0.js +1 -0
  129. package/dist/.next/.next/static/chunks/app/api/tables/[name]/route-898d3f85fc8544c4.js +1 -0
  130. package/dist/.next/.next/static/chunks/app/api/tables/route-91650359fc3735cb.js +1 -0
  131. package/dist/.next/.next/static/chunks/app/api/update/route-504d663df9124f97.js +1 -0
  132. package/dist/.next/.next/static/chunks/app/page-2c28a255a4ecd8d4.js +1 -0
  133. package/dist/.next/.next/static/chunks/app/page-3db7feef57019055.js +1 -0
  134. package/dist/.next/.next/static/css/4957328384ed5c42.css +3 -0
  135. package/dist/.next/.next/static/gc8l1G6KXOeLLOM7VJip6/_buildManifest.js +1 -0
  136. package/dist/.next/.next/static/kYsJoni86CJWDuTkc1xU6/_buildManifest.js +1 -0
  137. package/dist/.next/.next/static/kYsJoni86CJWDuTkc1xU6/_ssgManifest.js +1 -0
  138. package/dist/.next/.next/static/scC5qwQC9H7rR1groM0Q-/_ssgManifest.js +1 -0
  139. package/dist/.next/.next/static/tEHOI_-t-iqfJClNzuo9m/_buildManifest.js +1 -0
  140. package/dist/.next/.next/static/tEHOI_-t-iqfJClNzuo9m/_ssgManifest.js +1 -0
  141. package/dist/.next/.next/static/vin2VQs5pM_dH2e2_I7AN/_buildManifest.js +1 -0
  142. package/dist/.next/.next/static/vin2VQs5pM_dH2e2_I7AN/_ssgManifest.js +1 -0
  143. package/dist/.next/.next/static/wHKwQhaxin5_i06GFVDHb/_buildManifest.js +1 -0
  144. package/dist/.next/.next/static/wHKwQhaxin5_i06GFVDHb/_ssgManifest.js +1 -0
  145. package/dist/.next/.next/static/xW4MspD8XibrhXDi_q2IO/_ssgManifest.js +1 -0
  146. package/dist/.next/.next/trace +3 -3
  147. package/dist/.next/.next/types/app/api/update/route.ts +347 -0
  148. package/dist/.next/BUILD_ID +1 -1
  149. package/dist/.next/app-build-manifest.json +17 -17
  150. package/dist/.next/app-path-routes-manifest.json +1 -1
  151. package/dist/.next/build-manifest.json +2 -2
  152. package/dist/.next/cache/.rscinfo +1 -1
  153. package/dist/.next/cache/.tsbuildinfo +1 -1
  154. package/dist/.next/cache/webpack/client-production/0.pack +0 -0
  155. package/dist/.next/cache/webpack/client-production/index.pack +0 -0
  156. package/dist/.next/cache/webpack/edge-server-production/index.pack +0 -0
  157. package/dist/.next/cache/webpack/server-production/0.pack +0 -0
  158. package/dist/.next/cache/webpack/server-production/index.pack +0 -0
  159. package/dist/.next/next-minimal-server.js.nft.json +1 -1
  160. package/dist/.next/next-server.js.nft.json +1 -1
  161. package/dist/.next/prerender-manifest.json +1 -1
  162. package/dist/.next/server/app/_not-found.html +1 -1
  163. package/dist/.next/server/app/_not-found.rsc +1 -1
  164. package/dist/.next/server/app/api/cloudflare/route.js +1 -1
  165. package/dist/.next/server/app/api/databases/route.js +1 -1
  166. package/dist/.next/server/app/api/migrations/sync/route.js +3 -3
  167. package/dist/.next/server/app/api/migrations/sync/route.js.nft.json +1 -1
  168. package/dist/.next/server/app/api/migrations/sync-files/route.js +1 -1
  169. package/dist/.next/server/app/api/migrations/sync-files/route.js.nft.json +1 -1
  170. package/dist/.next/server/app/api/pull-remote/confirm/route.js +1 -1
  171. package/dist/.next/server/app/api/pull-remote/confirm/route.js.nft.json +1 -1
  172. package/dist/.next/server/app/api/pull-remote/preview/route.js +1 -1
  173. package/dist/.next/server/app/api/pull-remote/preview/route.js.nft.json +1 -1
  174. package/dist/.next/server/app/api/push-remote/confirm/route.js +2 -2
  175. package/dist/.next/server/app/api/push-remote/confirm/route.js.nft.json +1 -1
  176. package/dist/.next/server/app/api/push-remote/preview/route.js +2 -2
  177. package/dist/.next/server/app/api/push-remote/preview/route.js.nft.json +1 -1
  178. package/dist/.next/server/app/api/query/route.js +2 -2
  179. package/dist/.next/server/app/api/query/route.js.nft.json +1 -1
  180. package/dist/.next/server/app/api/tables/[name]/route.js +4 -4
  181. package/dist/.next/server/app/api/tables/route.js +2 -2
  182. package/dist/.next/server/app/index.html +1 -1
  183. package/dist/.next/server/app/index.rsc +1 -1
  184. package/dist/.next/server/app-paths-manifest.json +6 -6
  185. package/dist/.next/server/chunks/801.js +55 -0
  186. package/dist/.next/server/pages/404.html +1 -1
  187. package/dist/.next/server/pages/500.html +1 -1
  188. package/dist/.next/server/server-reference-manifest.json +1 -1
  189. package/dist/.next/static/ZwNOdZJ0LOtE0AJMNWwzY/_buildManifest.js +1 -0
  190. package/dist/.next/static/ZwNOdZJ0LOtE0AJMNWwzY/_ssgManifest.js +1 -0
  191. package/dist/.next/trace +14 -14
  192. package/dist/app/api/cloudflare/route.js +5 -1
  193. package/dist/app/api/databases/route.js +3 -4
  194. package/dist/app/api/migrations/sync/route.js +5 -3
  195. package/dist/app/api/pull-remote/confirm/route.js +24 -23
  196. package/dist/app/api/pull-remote/preview/route.js +4 -3
  197. package/dist/app/api/push-remote/preview/route.js +3 -2
  198. package/dist/app/api/query/route.js +11 -3
  199. package/dist/app/api/tables/[name]/route.js +3 -2
  200. package/dist/app/api/tables/route.js +6 -2
  201. package/dist/app/app/api/cloudflare/route.js +5 -1
  202. package/dist/app/app/api/databases/route.js +3 -4
  203. package/dist/app/app/api/migrations/sync/route.js +5 -3
  204. package/dist/app/app/api/pull-remote/confirm/route.js +24 -23
  205. package/dist/app/app/api/pull-remote/preview/route.js +4 -3
  206. package/dist/app/app/api/push-remote/preview/route.js +3 -2
  207. package/dist/app/app/api/query/route.js +11 -3
  208. package/dist/app/app/api/tables/[name]/route.js +3 -2
  209. package/dist/app/app/api/tables/route.js +6 -2
  210. package/dist/app/app/api/update/route.js +11 -0
  211. package/dist/app/app/page.jsx +7 -1
  212. package/dist/d1-studio.js +94 -58
  213. package/dist/lib/database-queue.js +34 -30
  214. package/dist/lib/find-wrangler-config.js +14 -8
  215. package/dist/lib/logger.js +11 -2
  216. package/dist/lib/migrations.js +4 -4
  217. package/dist/lib/schema-operations.js +4 -1
  218. package/dist/lib/sql-operations.js +8 -1
  219. package/package.json +3 -1
  220. package/scripts/studio.js +94 -58
  221. package/scripts/test.js +280 -82
  222. package/src/app/api/cloudflare/route.js +5 -1
  223. package/src/app/api/databases/route.js +3 -4
  224. package/src/app/api/migrations/sync/route.js +5 -3
  225. package/src/app/api/pull-remote/confirm/route.js +24 -23
  226. package/src/app/api/pull-remote/preview/route.js +4 -3
  227. package/src/app/api/push-remote/preview/route.js +3 -2
  228. package/src/app/api/query/route.js +11 -3
  229. package/src/app/api/tables/[name]/route.js +3 -2
  230. package/src/app/api/tables/route.js +6 -2
  231. package/src/app/api/update/route.js +11 -0
  232. package/src/app/page.jsx +7 -1
  233. package/src/components/update-banner.jsx +64 -0
  234. package/src/lib/database-queue.js +34 -30
  235. package/src/lib/find-wrangler-config.js +14 -8
  236. package/src/lib/logger.js +11 -2
  237. package/src/lib/migrations.js +4 -4
  238. package/src/lib/schema-operations.js +4 -1
  239. package/src/lib/sql-operations.js +8 -1
  240. package/dist/.next/.next/server/chunks/603.js +0 -55
  241. package/dist/.next/server/chunks/603.js +0 -55
  242. /package/dist/.next/.next/static/{HsZ8OanS5v86DqC9rErO- → IWRJZhjf8U8mjzz4h0VNE}/_buildManifest.js +0 -0
  243. /package/dist/.next/.next/static/{HsZ8OanS5v86DqC9rErO- → IWRJZhjf8U8mjzz4h0VNE}/_ssgManifest.js +0 -0
  244. /package/dist/.next/.next/static/{q6WmQmyONe88bMN0_jrC2 → JrwgdSDcipr0Zh7k19Cj_}/_ssgManifest.js +0 -0
  245. /package/dist/.next/{static/Tk1fnz_CXLavm23ZEeChG → .next/static/gc8l1G6KXOeLLOM7VJip6}/_ssgManifest.js +0 -0
  246. /package/dist/.next/.next/static/{q6WmQmyONe88bMN0_jrC2 → scC5qwQC9H7rR1groM0Q-}/_buildManifest.js +0 -0
  247. /package/dist/.next/{static/Tk1fnz_CXLavm23ZEeChG → .next/static/xW4MspD8XibrhXDi_q2IO}/_buildManifest.js +0 -0
@@ -1,12 +1,15 @@
1
- // lib/find-wrangler-config.js
2
1
  import { readFile } from 'fs/promises';
3
2
  import { findUp } from 'find-up';
4
3
  import { parse as parseToml } from '@iarna/toml';
5
4
  import stripJsonComments from 'strip-json-comments';
6
5
  import logger from './logger.js';
7
6
 
7
+ let cachedConfig = null;
8
+ let cachedProjectPath = null;
9
+
8
10
  /**
9
11
  * Finds and parses the Wrangler configuration file.
12
+ * This function caches the result so that the configuration is read and logged only once per project path.
10
13
  *
11
14
  * @param {string} userProjectPath - The path where to look for the config file
12
15
  * @returns {Promise<{config: object, projectPath: string}|null>}
@@ -17,8 +20,10 @@ export async function findWranglerConfig(userProjectPath) {
17
20
  throw new Error('Project path is required and must be a string');
18
21
  }
19
22
 
20
- // Uncomment the following line to log the search path if needed:
21
- // logger.debug(`Looking for wrangler configuration in: ${userProjectPath}`);
23
+ // Return the cached config if available for the same project path.
24
+ if (cachedConfig && cachedProjectPath === userProjectPath) {
25
+ return cachedConfig;
26
+ }
22
27
 
23
28
  // Define the possible configuration file names in priority order.
24
29
  const possibleFiles = ['wrangler.toml', 'wrangler.json', 'wrangler.jsonc'];
@@ -56,13 +61,14 @@ export async function findWranglerConfig(userProjectPath) {
56
61
  config = JSON.parse(configContent);
57
62
  }
58
63
 
59
- return {
60
- config,
61
- projectPath: userProjectPath
62
- };
64
+ // Cache the result.
65
+ cachedConfig = { config, projectPath: userProjectPath };
66
+ cachedProjectPath = userProjectPath;
67
+
68
+ return cachedConfig;
63
69
 
64
70
  } catch (error) {
65
71
  logger.error(`Error reading Wrangler configuration: ${error.message}`);
66
72
  throw error;
67
73
  }
68
- }
74
+ }
@@ -2,18 +2,27 @@ import winston from 'winston';
2
2
 
3
3
  const { combine, timestamp, printf, colorize } = winston.format;
4
4
 
5
+ const isDevelopment = process.env.NODE_ENV === 'development' || process.env.NODE_ENV === undefined;
6
+ const isProduction = process.env.NODE_ENV === 'production';
7
+ const isDebug = process.env.DEBUG === 'true';
8
+
5
9
  const logFormat = printf(({ level, message, timestamp }) => {
6
10
  return `${timestamp} ${level}: ${message}`;
7
11
  });
8
12
 
9
13
  const logger = winston.createLogger({
10
- level: process.env.NODE_ENV === 'development' ? 'debug' : 'info',
14
+ level: isProduction ? 'warn' : (isDebug ? 'debug' : 'info'),
11
15
  format: combine(
12
16
  timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
13
17
  colorize(),
14
18
  logFormat
15
19
  ),
16
- transports: [new winston.transports.Console()]
20
+ transports: [
21
+ new winston.transports.Console({
22
+ level: isProduction ? 'warn' : (isDebug ? 'debug' : 'info'),
23
+ silent: process.env.NODE_ENV === 'test'
24
+ })
25
+ ]
17
26
  });
18
27
 
19
28
  export default logger;
@@ -16,6 +16,7 @@ import {
16
16
  tableExists
17
17
  } from './sql-operations.js';
18
18
  import { analyzeDependencies } from '@/lib/schema-operations';
19
+ import logger from './logger.js';
19
20
 
20
21
  const execAsync = promisify(exec);
21
22
 
@@ -67,7 +68,7 @@ export async function initMigrationsTable(projectDir, databaseName, environment
67
68
  );
68
69
  }
69
70
  } catch (error) {
70
- console.error(`Failed to initialize migrations table in ${environment}:`, error);
71
+ logger.error(`Failed to initialize migrations table in ${environment}:`, error);
71
72
  throw error;
72
73
  }
73
74
  }
@@ -173,7 +174,6 @@ export async function getRemoteMigrations(projectDir, databaseName, env) {
173
174
  * @param {Object} migrationData { name, checksum }
174
175
  * @param {('local'|'remote')} environment
175
176
  */
176
- // Update tracking function to handle both cases
177
177
  export async function trackMigration(projectDir, databaseName, { name, checksum }, environment = 'local') {
178
178
  const flag = environment === 'remote' ? '--remote' : '--local';
179
179
 
@@ -215,7 +215,7 @@ export async function trackMigration(projectDir, databaseName, { name, checksum
215
215
  { cwd: projectDir }
216
216
  );
217
217
  } catch (error) {
218
- console.error('Failed to track migration:', error);
218
+ logger.error('Failed to track migration:', error);
219
219
  throw error;
220
220
  }
221
221
  }
@@ -273,7 +273,7 @@ export async function compareMigrations(projectDir, databaseName) {
273
273
  count: migrationMap.size
274
274
  };
275
275
  } catch (error) {
276
- console.error('Failed to compare migrations:', error);
276
+ logger.error('Failed to compare migrations:', error);
277
277
  throw error;
278
278
  }
279
279
  }
@@ -1,5 +1,7 @@
1
1
  // schema-operations.js
2
+
2
3
  import { executeSQL, ErrorTypes } from './sql-operations.js';
4
+ import logger from './logger.js';
3
5
 
4
6
  /**
5
7
  * Retrieves the current database schema (tables, indexes, triggers),
@@ -24,6 +26,7 @@ export async function getCurrentSchema(projectDir, databaseName, env = {}, remot
24
26
  const parsed = JSON.parse(result);
25
27
  return parsed[0]?.results || [];
26
28
  } catch (error) {
29
+ logger.error('Failed to get current schema:', error);
27
30
  throw {
28
31
  type: ErrorTypes.EXECUTION_ERROR,
29
32
  message: 'Failed to get current schema',
@@ -100,4 +103,4 @@ export function orderTables(dependencies) {
100
103
  }
101
104
  }
102
105
  return ordered;
103
- }
106
+ }
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { promisify } from 'util';
4
4
  import { exec } from 'child_process';
5
+ import logger from '@/lib/logger';
5
6
 
6
7
  const execAsync = promisify(exec);
7
8
 
@@ -293,13 +294,19 @@ export async function executeSQL(projectDir, databaseName, sql, env = {}, remote
293
294
  const npxCommand = isWindows ? 'npx.cmd' : 'npx';
294
295
  const executionFlag = remote ? '--remote' : '--local';
295
296
  const command = `${npxCommand} wrangler d1 execute ${databaseName} ${executionFlag} --command="${cleanSQL.replace(/"/g, '\\"')}"`;
297
+
298
+ // Only log in development
299
+ if (logger.shouldLog('debug')) {
300
+ logger.debug('Executing command:', command);
301
+ }
302
+
296
303
  const execOptions = {
297
304
  cwd: projectDir,
298
305
  env: { ...process.env, ...env },
299
306
  maxBuffer: 1024 * 1024 * 10,
300
307
  shell: true
301
308
  };
302
- console.log('Executing command:', command);
309
+ // console.log('Executing command:', command);
303
310
  const { stdout, stderr } = await execAsync(command, execOptions);
304
311
  if (stderr && !stderr.includes('🌀')) {
305
312
  throw new Error(stderr);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "d1s",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "type": "module",
5
5
  "description": "D1 Studio – a native studio for managing Cloudflare D1 databases.",
6
6
  "main": "./dist/d1-studio.js",
@@ -65,6 +65,7 @@
65
65
  "@radix-ui/react-tabs": "^1.1.2",
66
66
  "@radix-ui/react-toast": "^1.2.5",
67
67
  "@radix-ui/react-tooltip": "^1.1.7",
68
+ "axios": "^1.7.9",
68
69
  "chalk": "^4.1.2",
69
70
  "class-variance-authority": "^0.7.1",
70
71
  "clsx": "^2.1.1",
@@ -82,6 +83,7 @@
82
83
  "strip-json-comments": "^5.0.1",
83
84
  "tailwind-merge": "^2.6.0",
84
85
  "tailwindcss-animate": "^1.0.7",
86
+ "update-notifier": "^7.3.1",
85
87
  "winston": "^3.17.0"
86
88
  },
87
89
  "devDependencies": {
package/scripts/studio.js CHANGED
@@ -12,8 +12,13 @@ import { createServer } from 'http';
12
12
  import next from 'next';
13
13
  import { findWranglerConfig } from '../src/lib/find-wrangler-config.js';
14
14
  import logger from '../src/lib/logger.js';
15
+ import updateNotifier from 'update-notifier';
16
+ import pkg from '../package.json' assert { type: 'json' };
15
17
 
16
- // Compute the absolute path of this file and its directory.
18
+ const notifier = updateNotifier({ pkg, updateCheckInterval: 1000 * 60 * 60 * 24 });
19
+ notifier.notify({ defer: false });
20
+
21
+ // Compute the absolute path of this file and its directory
17
22
  const __filename = fileURLToPath(import.meta.url);
18
23
  const __dirname = dirname(__filename);
19
24
 
@@ -26,6 +31,70 @@ class LicenseError extends Error {
26
31
  }
27
32
  }
28
33
 
34
+ class StudioLicenseManager {
35
+ constructor() {
36
+ this.licenseDir = join(homedir(), '.d1studio');
37
+ this.licensePath = join(this.licenseDir, 'license.json');
38
+ }
39
+
40
+ async checkLicenseFile() {
41
+ try {
42
+ const licenseData = JSON.parse(await readFile(this.licensePath, 'utf8'));
43
+
44
+ // If no end_date or subscription_status, the license is valid (perpetual license)
45
+ if (!licenseData.end_date || !licenseData.subscription_status) {
46
+ return {
47
+ licenseData,
48
+ isValid: true,
49
+ isExpiringSoon: false
50
+ };
51
+ }
52
+
53
+ // Check subscription status first
54
+ if (licenseData.subscription_status !== 'active') {
55
+ return {
56
+ licenseData,
57
+ isValid: false,
58
+ isExpiringSoon: false
59
+ };
60
+ }
61
+
62
+ const endDate = new Date(licenseData.end_date);
63
+ const now = new Date();
64
+
65
+ // Check if subscription has ended
66
+ if (endDate < now) {
67
+ return {
68
+ licenseData,
69
+ isValid: false,
70
+ isExpiringSoon: false
71
+ };
72
+ }
73
+
74
+ // Check if subscription ends in next 7 days
75
+ const sevenDaysFromNow = new Date(now.getTime() + (7 * 24 * 60 * 60 * 1000));
76
+ const isExpiringSoon = endDate <= sevenDaysFromNow;
77
+
78
+ return {
79
+ licenseData,
80
+ isValid: true,
81
+ isExpiringSoon
82
+ };
83
+ } catch (error) {
84
+ return null;
85
+ }
86
+ }
87
+
88
+ async saveLicenseFile(licenseData) {
89
+ try {
90
+ await mkdir(this.licenseDir, { recursive: true });
91
+ await writeFile(this.licensePath, JSON.stringify(licenseData, null, 2));
92
+ } catch (error) {
93
+ throw new LicenseError('Failed to save license information', 'SAVE_ERROR');
94
+ }
95
+ }
96
+ }
97
+
29
98
  async function generateHardwareId() {
30
99
  const osInfo = {
31
100
  platform: process.platform,
@@ -60,13 +129,6 @@ async function validateLicenseRemote(licenseKey, email, hardwareId) {
60
129
  );
61
130
  }
62
131
 
63
- if (result.end_date && new Date(result.end_date) < new Date()) {
64
- throw new LicenseError(
65
- 'Your subscription has expired. Please renew your license to continue using D1 Studio.',
66
- 'SUBSCRIPTION_EXPIRED'
67
- );
68
- }
69
-
70
132
  return result;
71
133
  } catch (error) {
72
134
  if (error instanceof LicenseError) {
@@ -87,35 +149,6 @@ async function validateLicenseRemote(licenseKey, email, hardwareId) {
87
149
  }
88
150
  }
89
151
 
90
- async function checkLicenseFile() {
91
- const licenseDir = join(homedir(), '.d1studio');
92
- const licensePath = join(licenseDir, 'license.json');
93
-
94
- try {
95
- const licenseData = JSON.parse(await readFile(licensePath, 'utf8'));
96
- const hardwareId = await generateHardwareId();
97
-
98
- if (licenseData.hardwareId !== hardwareId) {
99
- return null;
100
- }
101
- return licenseData;
102
- } catch (error) {
103
- return null;
104
- }
105
- }
106
-
107
- async function saveLicenseFile(licenseData) {
108
- const licenseDir = join(homedir(), '.d1studio');
109
- const licensePath = join(licenseDir, 'license.json');
110
-
111
- try {
112
- await mkdir(licenseDir, { recursive: true });
113
- await writeFile(licensePath, JSON.stringify(licenseData, null, 2));
114
- } catch (error) {
115
- throw new LicenseError('Failed to save license information', 'SAVE_ERROR');
116
- }
117
- }
118
-
119
152
  async function startServer(port, projectDirectory) {
120
153
  return new Promise((resolvePromise, rejectPromise) => {
121
154
  // Determine Next.js app directory based on environment:
@@ -170,20 +203,14 @@ async function startStudio() {
170
203
  try {
171
204
  logger.info(chalk.green('Initializing D1 Studio...'));
172
205
 
173
- // Validate license
174
- let licenseData = await checkLicenseFile();
175
- logger.debug(chalk.blue(`License data found: ${JSON.stringify(licenseData)}`));
176
-
177
- const TWELVE_HOURS_MS = 43200000; // 12 hours
178
- let shouldRevalidate = true;
179
- if (licenseData) {
180
- const lastCheck = new Date(licenseData.lastValidatedAt || licenseData.activatedAt);
181
- if (Date.now() - lastCheck.getTime() < TWELVE_HOURS_MS) {
182
- shouldRevalidate = false;
183
- }
184
- }
206
+ const licenseManager = new StudioLicenseManager();
185
207
 
186
- if (!licenseData || shouldRevalidate) {
208
+ // Check existing license
209
+ const licenseCheck = await licenseManager.checkLicenseFile();
210
+
211
+ // Handle license validation
212
+ if (!licenseCheck || !licenseCheck.isValid) {
213
+ // Prompt for license information if needed
187
214
  const { default: inquirer } = await import('inquirer');
188
215
  logger.info(chalk.yellow('\nPlease enter your D1 Studio license information:'));
189
216
 
@@ -205,9 +232,8 @@ async function startStudio() {
205
232
  },
206
233
  ]);
207
234
 
208
- logger.debug(chalk.blue(`Entered license information: ${JSON.stringify(answers)}`));
209
-
210
235
  const hardwareId = await generateHardwareId();
236
+
211
237
  try {
212
238
  const validation = await validateLicenseRemote(
213
239
  answers.licenseKey,
@@ -215,19 +241,29 @@ async function startStudio() {
215
241
  hardwareId
216
242
  );
217
243
 
218
- licenseData = {
244
+ // Save the complete validation response
245
+ await licenseManager.saveLicenseFile({
219
246
  licenseKey: answers.licenseKey,
220
247
  email: answers.email,
221
- activatedAt: new Date().toISOString(),
222
- endDate: validation.end_date || null
223
- };
248
+ hardwareId,
249
+ end_date: validation.end_date,
250
+ subscription_status: validation.subscription_status,
251
+ type: validation.licenseType,
252
+ activatedAt: new Date().toISOString()
253
+ });
224
254
 
225
- await saveLicenseFile(licenseData);
226
255
  logger.info(chalk.green('\nLicense activated successfully!'));
227
256
  } catch (error) {
228
257
  logger.error(chalk.red(`\nLicense validation failed: ${error.message}`));
229
258
  process.exit(1);
230
259
  }
260
+ } else if (licenseCheck.isExpiringSoon) {
261
+ // Show warning about expiring subscription
262
+ const endDate = new Date(licenseCheck.licenseData.end_date).toLocaleDateString();
263
+ logger.warn(chalk.yellow(`
264
+ ⚠️ Your subscription will expire on ${endDate}
265
+ Please renew your subscription at https://d1-studio.com to continue using D1 Studio.
266
+ `));
231
267
  }
232
268
 
233
269
  // Get wrangler configuration
@@ -317,4 +353,4 @@ process.on('SIGTERM', () => {
317
353
  startStudio().catch((error) => {
318
354
  logger.error(chalk.red(`\nFailed to start D1 Studio: ${error}`));
319
355
  process.exit(1);
320
- });
356
+ });