nextjs-studio 0.3.0 → 1.0.0

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 (238) hide show
  1. package/README.md +3 -1
  2. package/dist/bin/nextjs-studio.js +315 -54
  3. package/dist/bin/nextjs-studio.js.map +1 -1
  4. package/dist/cli/ui/.next/BUILD_ID +1 -0
  5. package/dist/cli/ui/.next/app-path-routes-manifest.json +12 -0
  6. package/dist/cli/ui/.next/build-manifest.json +20 -0
  7. package/dist/cli/ui/.next/export-marker.json +6 -0
  8. package/dist/cli/ui/.next/images-manifest.json +67 -0
  9. package/dist/cli/ui/.next/next-minimal-server.js.nft.json +1 -0
  10. package/dist/cli/ui/.next/next-server.js.nft.json +1 -0
  11. package/dist/cli/ui/.next/package.json +1 -0
  12. package/dist/cli/ui/.next/prerender-manifest.json +61 -0
  13. package/dist/cli/ui/.next/react-loadable-manifest.json +286 -0
  14. package/dist/cli/ui/.next/required-server-files.js +338 -0
  15. package/dist/cli/ui/.next/required-server-files.json +338 -0
  16. package/dist/cli/ui/.next/routes-manifest.json +125 -0
  17. package/dist/cli/ui/.next/server/app/_global-error/page.js +3 -0
  18. package/dist/cli/ui/.next/server/app/_global-error/page.js.nft.json +1 -0
  19. package/dist/cli/ui/.next/server/app/_global-error/page_client-reference-manifest.js +1 -0
  20. package/dist/cli/ui/.next/server/app/_global-error.html +2 -0
  21. package/dist/cli/ui/.next/server/app/_global-error.meta +16 -0
  22. package/dist/cli/ui/.next/server/app/_global-error.rsc +12 -0
  23. package/dist/cli/ui/.next/server/app/_global-error.segments/_full.segment.rsc +12 -0
  24. package/dist/cli/ui/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +5 -0
  25. package/dist/cli/ui/.next/server/app/_global-error.segments/_global-error.segment.rsc +4 -0
  26. package/dist/cli/ui/.next/server/app/_global-error.segments/_head.segment.rsc +5 -0
  27. package/dist/cli/ui/.next/server/app/_global-error.segments/_index.segment.rsc +4 -0
  28. package/dist/cli/ui/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -0
  29. package/dist/cli/ui/.next/server/app/_not-found/page.js +2 -0
  30. package/dist/cli/ui/.next/server/app/_not-found/page.js.nft.json +1 -0
  31. package/dist/cli/ui/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
  32. package/dist/cli/ui/.next/server/app/_not-found.html +1 -0
  33. package/dist/cli/ui/.next/server/app/_not-found.meta +16 -0
  34. package/dist/cli/ui/.next/server/app/_not-found.rsc +15 -0
  35. package/dist/cli/ui/.next/server/app/_not-found.segments/_full.segment.rsc +15 -0
  36. package/dist/cli/ui/.next/server/app/_not-found.segments/_head.segment.rsc +5 -0
  37. package/dist/cli/ui/.next/server/app/_not-found.segments/_index.segment.rsc +7 -0
  38. package/dist/cli/ui/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +5 -0
  39. package/dist/cli/ui/.next/server/app/_not-found.segments/_not-found.segment.rsc +4 -0
  40. package/dist/cli/ui/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -0
  41. package/dist/cli/ui/.next/server/app/api/media/[collection]/[filename]/route.js +1 -0
  42. package/dist/cli/ui/.next/server/app/api/media/[collection]/[filename]/route.js.nft.json +1 -0
  43. package/dist/cli/ui/.next/server/app/api/media/[collection]/[filename]/route_client-reference-manifest.js +1 -0
  44. package/dist/cli/ui/.next/server/app/api/media/[collection]/route.js +1 -0
  45. package/dist/cli/ui/.next/server/app/api/media/[collection]/route.js.nft.json +1 -0
  46. package/dist/cli/ui/.next/server/app/api/media/[collection]/route_client-reference-manifest.js +1 -0
  47. package/dist/cli/ui/.next/server/app/api/public/[...path]/route.js +1 -0
  48. package/dist/cli/ui/.next/server/app/api/public/[...path]/route.js.nft.json +1 -0
  49. package/dist/cli/ui/.next/server/app/api/public/[...path]/route_client-reference-manifest.js +1 -0
  50. package/dist/cli/ui/.next/server/app/api/sync/[collection]/route.js +1 -0
  51. package/dist/cli/ui/.next/server/app/api/sync/[collection]/route.js.nft.json +1 -0
  52. package/dist/cli/ui/.next/server/app/api/sync/[collection]/route_client-reference-manifest.js +1 -0
  53. package/dist/cli/ui/.next/server/app/api/watch/route.js +3 -0
  54. package/dist/cli/ui/.next/server/app/api/watch/route.js.nft.json +1 -0
  55. package/dist/cli/ui/.next/server/app/api/watch/route_client-reference-manifest.js +1 -0
  56. package/dist/cli/ui/.next/server/app/collection/[name]/[slug]/page.js +99 -0
  57. package/dist/cli/ui/.next/server/app/collection/[name]/[slug]/page.js.nft.json +1 -0
  58. package/dist/cli/ui/.next/server/app/collection/[name]/[slug]/page_client-reference-manifest.js +1 -0
  59. package/dist/cli/ui/.next/server/app/collection/[name]/page.js +5 -0
  60. package/dist/cli/ui/.next/server/app/collection/[name]/page.js.nft.json +1 -0
  61. package/dist/cli/ui/.next/server/app/collection/[name]/page_client-reference-manifest.js +1 -0
  62. package/dist/cli/ui/.next/server/app/page.js +2 -0
  63. package/dist/cli/ui/.next/server/app/page.js.nft.json +1 -0
  64. package/dist/cli/ui/.next/server/app/page_client-reference-manifest.js +1 -0
  65. package/dist/cli/ui/.next/server/app-paths-manifest.json +12 -0
  66. package/dist/cli/ui/.next/server/chunks/1875.js +1 -0
  67. package/dist/cli/ui/.next/server/chunks/2198.js +1 -0
  68. package/dist/cli/ui/.next/server/chunks/2446.js +36 -0
  69. package/dist/cli/ui/.next/server/chunks/2474.js +148 -0
  70. package/dist/cli/ui/.next/server/chunks/2490.js +55 -0
  71. package/dist/cli/ui/.next/server/chunks/2717.js +56 -0
  72. package/dist/cli/ui/.next/server/chunks/2729.js +166 -0
  73. package/dist/cli/ui/.next/server/chunks/2774.js +1 -0
  74. package/dist/cli/ui/.next/server/chunks/2796.js +1 -0
  75. package/dist/cli/ui/.next/server/chunks/3145.js +1 -0
  76. package/dist/cli/ui/.next/server/chunks/3186.js +1 -0
  77. package/dist/cli/ui/.next/server/chunks/3494.js +24 -0
  78. package/dist/cli/ui/.next/server/chunks/3610.js +1 -0
  79. package/dist/cli/ui/.next/server/chunks/3659.js +93 -0
  80. package/dist/cli/ui/.next/server/chunks/3744.js +1 -0
  81. package/dist/cli/ui/.next/server/chunks/3806.js +136 -0
  82. package/dist/cli/ui/.next/server/chunks/408.js +1 -0
  83. package/dist/cli/ui/.next/server/chunks/4189.js +62 -0
  84. package/dist/cli/ui/.next/server/chunks/4293.js +1 -0
  85. package/dist/cli/ui/.next/server/chunks/4469.js +4 -0
  86. package/dist/cli/ui/.next/server/chunks/4484.js +1 -0
  87. package/dist/cli/ui/.next/server/chunks/449.js +82 -0
  88. package/dist/cli/ui/.next/server/chunks/4607.js +22 -0
  89. package/dist/cli/ui/.next/server/chunks/479.js +5 -0
  90. package/dist/cli/ui/.next/server/chunks/4931.js +63 -0
  91. package/dist/cli/ui/.next/server/chunks/528.js +1 -0
  92. package/dist/cli/ui/.next/server/chunks/5341.js +1 -0
  93. package/dist/cli/ui/.next/server/chunks/5585.js +29 -0
  94. package/dist/cli/ui/.next/server/chunks/5677.js +1 -0
  95. package/dist/cli/ui/.next/server/chunks/5724.js +1 -0
  96. package/dist/cli/ui/.next/server/chunks/5760.js +174 -0
  97. package/dist/cli/ui/.next/server/chunks/5784.js +24 -0
  98. package/dist/cli/ui/.next/server/chunks/6.js +262 -0
  99. package/dist/cli/ui/.next/server/chunks/6040.js +1 -0
  100. package/dist/cli/ui/.next/server/chunks/6067.js +13 -0
  101. package/dist/cli/ui/.next/server/chunks/6553.js +1 -0
  102. package/dist/cli/ui/.next/server/chunks/6656.js +201 -0
  103. package/dist/cli/ui/.next/server/chunks/6672.js +1 -0
  104. package/dist/cli/ui/.next/server/chunks/6872.js +1 -0
  105. package/dist/cli/ui/.next/server/chunks/7146.js +59 -0
  106. package/dist/cli/ui/.next/server/chunks/7354.js +1 -0
  107. package/dist/cli/ui/.next/server/chunks/7677.js +1 -0
  108. package/dist/cli/ui/.next/server/chunks/7781.js +1 -0
  109. package/dist/cli/ui/.next/server/chunks/8194.js +215 -0
  110. package/dist/cli/ui/.next/server/chunks/8231.js +1 -0
  111. package/dist/cli/ui/.next/server/chunks/8319.js +2 -0
  112. package/dist/cli/ui/.next/server/chunks/8339.js +1 -0
  113. package/dist/cli/ui/.next/server/chunks/8775.js +1 -0
  114. package/dist/cli/ui/.next/server/chunks/9503.js +43 -0
  115. package/dist/cli/ui/.next/server/chunks/958.js +131 -0
  116. package/dist/cli/ui/.next/server/chunks/9739.js +1 -0
  117. package/dist/cli/ui/.next/server/functions-config-manifest.json +4 -0
  118. package/dist/cli/ui/.next/server/interception-route-rewrite-manifest.js +1 -0
  119. package/dist/cli/ui/.next/server/middleware-build-manifest.js +1 -0
  120. package/dist/cli/ui/.next/server/middleware-manifest.json +6 -0
  121. package/dist/cli/ui/.next/server/middleware-react-loadable-manifest.js +1 -0
  122. package/dist/cli/ui/.next/server/next-font-manifest.js +1 -0
  123. package/dist/cli/ui/.next/server/next-font-manifest.json +1 -0
  124. package/dist/cli/ui/.next/server/pages/404.html +1 -0
  125. package/dist/cli/ui/.next/server/pages/500.html +2 -0
  126. package/dist/cli/ui/.next/server/pages-manifest.json +4 -0
  127. package/dist/cli/ui/.next/server/server-reference-manifest.js +1 -0
  128. package/dist/cli/ui/.next/server/server-reference-manifest.json +1 -0
  129. package/dist/cli/ui/.next/server/webpack-runtime.js +1 -0
  130. package/dist/cli/ui/.next/static/chunks/0937d497-2b220e2d0368e918.js +1 -0
  131. package/dist/cli/ui/.next/static/chunks/1013.5541c1c75688ef6e.js +1 -0
  132. package/dist/cli/ui/.next/static/chunks/1039.d26ef6a818f26d70.js +4 -0
  133. package/dist/cli/ui/.next/static/chunks/1325.cb67348b484ce7a0.js +24 -0
  134. package/dist/cli/ui/.next/static/chunks/1858-d10f8bead2218ad2.js +2 -0
  135. package/dist/cli/ui/.next/static/chunks/1882.05c68ab6bdcd8c31.js +1 -0
  136. package/dist/cli/ui/.next/static/chunks/2011.7e73842f1e8e2cde.js +1 -0
  137. package/dist/cli/ui/.next/static/chunks/2046.73486ea936c9afd2.js +1 -0
  138. package/dist/cli/ui/.next/static/chunks/2389.b73d3a1286a228d0.js +1 -0
  139. package/dist/cli/ui/.next/static/chunks/2430.08df5899978ebf26.js +43 -0
  140. package/dist/cli/ui/.next/static/chunks/2462-4255d8f51dc56f12.js +1 -0
  141. package/dist/cli/ui/.next/static/chunks/3098-4269da0468edc350.js +1 -0
  142. package/dist/cli/ui/.next/static/chunks/317.b4fcc40f219152b1.js +1 -0
  143. package/dist/cli/ui/.next/static/chunks/3197.d2f3398e552228e4.js +1 -0
  144. package/dist/cli/ui/.next/static/chunks/3212-1a9c9d110d15abab.js +4 -0
  145. package/dist/cli/ui/.next/static/chunks/3809.8df186de2ff997f8.js +1 -0
  146. package/dist/cli/ui/.next/static/chunks/3918.caaf4eb4f6450524.js +1 -0
  147. package/dist/cli/ui/.next/static/chunks/3987-6d3217e36ae5b4dc.js +1 -0
  148. package/dist/cli/ui/.next/static/chunks/3c774391-ec08594272867fd5.js +79 -0
  149. package/dist/cli/ui/.next/static/chunks/4075052f.9006147a6182ed95.js +1 -0
  150. package/dist/cli/ui/.next/static/chunks/4389.e7a3c58aa62118e3.js +82 -0
  151. package/dist/cli/ui/.next/static/chunks/46bdbe0e-f5103600b23143b8.js +1 -0
  152. package/dist/cli/ui/.next/static/chunks/4860.2ba51d1d81857c81.js +1 -0
  153. package/dist/cli/ui/.next/static/chunks/4882.794e2a9231f129e5.js +55 -0
  154. package/dist/cli/ui/.next/static/chunks/5149.8de9918b9ace58f5.js +166 -0
  155. package/dist/cli/ui/.next/static/chunks/5230.b7c87400f0d8516f.js +215 -0
  156. package/dist/cli/ui/.next/static/chunks/5263.7adc3ade53cd4ed3.js +24 -0
  157. package/dist/cli/ui/.next/static/chunks/5313.1dfcc2126f85a8f8.js +1 -0
  158. package/dist/cli/ui/.next/static/chunks/5350-17c792e27bf38c77.js +1 -0
  159. package/dist/cli/ui/.next/static/chunks/5638.e3a2119354708654.js +1 -0
  160. package/dist/cli/ui/.next/static/chunks/5758.33b45c6c407ecd94.js +1 -0
  161. package/dist/cli/ui/.next/static/chunks/589.019158de5d02c262.js +1 -0
  162. package/dist/cli/ui/.next/static/chunks/6013.e33e73569339afee.js +62 -0
  163. package/dist/cli/ui/.next/static/chunks/6084.7511ad4ebb4f9df5.js +1 -0
  164. package/dist/cli/ui/.next/static/chunks/612.d3aeebcaaaf06fb2.js +1 -0
  165. package/dist/cli/ui/.next/static/chunks/6239.6c0cd99ea36222b6.js +5 -0
  166. package/dist/cli/ui/.next/static/chunks/6299-79a74877b87acf9f.js +1 -0
  167. package/dist/cli/ui/.next/static/chunks/6484.d38aa531768c3452.js +148 -0
  168. package/dist/cli/ui/.next/static/chunks/6505.731f74c28b8980b3.js +1 -0
  169. package/dist/cli/ui/.next/static/chunks/6584.be94a55391bcdcce.js +262 -0
  170. package/dist/cli/ui/.next/static/chunks/6800.1066ad1f5add7c75.js +1 -0
  171. package/dist/cli/ui/.next/static/chunks/7052.89e2de773d10ac20.js +131 -0
  172. package/dist/cli/ui/.next/static/chunks/7127.360abfa43dc4427e.js +36 -0
  173. package/dist/cli/ui/.next/static/chunks/7430.2b247d9ac6ef694c.js +149 -0
  174. package/dist/cli/ui/.next/static/chunks/7444.66c4d6bbc19309b3.js +59 -0
  175. package/dist/cli/ui/.next/static/chunks/7546.4cb4db4685212384.js +63 -0
  176. package/dist/cli/ui/.next/static/chunks/7564.7b9271fcf06df80c.js +29 -0
  177. package/dist/cli/ui/.next/static/chunks/7664.8268c156d8988844.js +174 -0
  178. package/dist/cli/ui/.next/static/chunks/7722-04e64cc1b26cfa65.js +1 -0
  179. package/dist/cli/ui/.next/static/chunks/8701.3995b58a75e43147.js +56 -0
  180. package/dist/cli/ui/.next/static/chunks/8800.548c3da26cfebf06.js +1 -0
  181. package/dist/cli/ui/.next/static/chunks/8814-7b64110c79ce7209.js +15 -0
  182. package/dist/cli/ui/.next/static/chunks/9058.a195d15265251194.js +1 -0
  183. package/dist/cli/ui/.next/static/chunks/9211.91144a0d23e4cf6d.js +1 -0
  184. package/dist/cli/ui/.next/static/chunks/9690.c1f08c02a675b9ce.js +1 -0
  185. package/dist/cli/ui/.next/static/chunks/9919.1ccc9ca4a749d9b7.js +93 -0
  186. package/dist/cli/ui/.next/static/chunks/app/_global-error/page-ad53913b77389472.js +1 -0
  187. package/dist/cli/ui/.next/static/chunks/app/_not-found/page-202c1e16a4b86ac8.js +1 -0
  188. package/dist/cli/ui/.next/static/chunks/app/api/media/[collection]/[filename]/route-ad53913b77389472.js +1 -0
  189. package/dist/cli/ui/.next/static/chunks/app/api/media/[collection]/route-ad53913b77389472.js +1 -0
  190. package/dist/cli/ui/.next/static/chunks/app/api/public/[...path]/route-ad53913b77389472.js +1 -0
  191. package/dist/cli/ui/.next/static/chunks/app/api/sync/[collection]/route-ad53913b77389472.js +1 -0
  192. package/dist/cli/ui/.next/static/chunks/app/api/watch/route-ad53913b77389472.js +1 -0
  193. package/dist/cli/ui/.next/static/chunks/app/collection/[name]/[slug]/page-7ea9eff252374845.js +6 -0
  194. package/dist/cli/ui/.next/static/chunks/app/collection/[name]/loading-03fc0b653e7060ae.js +1 -0
  195. package/dist/cli/ui/.next/static/chunks/app/collection/[name]/page-ad5976bebc9820cf.js +1 -0
  196. package/dist/cli/ui/.next/static/chunks/app/layout-74cd2ebe3fac00e7.js +1 -0
  197. package/dist/cli/ui/.next/static/chunks/app/page-ed5acadf20146966.js +1 -0
  198. package/dist/cli/ui/.next/static/chunks/b1767599.6a816b06e55b02a1.js +1 -0
  199. package/dist/cli/ui/.next/static/chunks/c6164070.3b9741bce302db0f.js +136 -0
  200. package/dist/cli/ui/.next/static/chunks/fb2ceba8.7fc23e46ca00cfd1.js +53 -0
  201. package/dist/cli/ui/.next/static/chunks/framework-ada624c9bf38edc6.js +1 -0
  202. package/dist/cli/ui/.next/static/chunks/main-0513ff42a7f2e1a0.js +5 -0
  203. package/dist/cli/ui/.next/static/chunks/main-app-b8d23dfb755744e8.js +1 -0
  204. package/dist/cli/ui/.next/static/chunks/next/dist/client/components/builtin/app-error-ad53913b77389472.js +1 -0
  205. package/dist/cli/ui/.next/static/chunks/next/dist/client/components/builtin/forbidden-ad53913b77389472.js +1 -0
  206. package/dist/cli/ui/.next/static/chunks/next/dist/client/components/builtin/global-error-558ee1074f45044b.js +1 -0
  207. package/dist/cli/ui/.next/static/chunks/next/dist/client/components/builtin/not-found-ad53913b77389472.js +1 -0
  208. package/dist/cli/ui/.next/static/chunks/next/dist/client/components/builtin/unauthorized-ad53913b77389472.js +1 -0
  209. package/dist/cli/ui/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  210. package/dist/cli/ui/.next/static/chunks/webpack-acb903cd88aafa6f.js +1 -0
  211. package/dist/cli/ui/.next/static/css/e143949aa3f17880.css +3 -0
  212. package/dist/cli/ui/.next/static/media/034d78ad42e9620c-s.woff2 +0 -0
  213. package/dist/cli/ui/.next/static/media/0484562807a97172-s.p.woff2 +0 -0
  214. package/dist/cli/ui/.next/static/media/29a4aea02fdee119-s.woff2 +0 -0
  215. package/dist/cli/ui/.next/static/media/29e7bbdce9332268-s.woff2 +0 -0
  216. package/dist/cli/ui/.next/static/media/4c285fdca692ea22-s.p.woff2 +0 -0
  217. package/dist/cli/ui/.next/static/media/6c177e25b87fd9cd-s.woff2 +0 -0
  218. package/dist/cli/ui/.next/static/media/6c9a125e97d835e1-s.woff2 +0 -0
  219. package/dist/cli/ui/.next/static/media/8888a3826f4a3af4-s.p.woff2 +0 -0
  220. package/dist/cli/ui/.next/static/media/a1386beebedccca4-s.woff2 +0 -0
  221. package/dist/cli/ui/.next/static/media/b957ea75a84b6ea7-s.p.woff2 +0 -0
  222. package/dist/cli/ui/.next/static/media/c3bc380753a8436c-s.woff2 +0 -0
  223. package/dist/cli/ui/.next/static/media/db911767852bc875-s.woff2 +0 -0
  224. package/dist/cli/ui/.next/static/media/eafabf029ad39a43-s.p.woff2 +0 -0
  225. package/dist/cli/ui/.next/static/media/f10b8e9d91f3edcb-s.woff2 +0 -0
  226. package/dist/cli/ui/.next/static/media/fe0777f1195381cb-s.woff2 +0 -0
  227. package/dist/cli/ui/.next/static/zkOuvkSWApTVHCrj7neNk/_buildManifest.js +1 -0
  228. package/dist/cli/ui/.next/static/zkOuvkSWApTVHCrj7neNk/_ssgManifest.js +1 -0
  229. package/dist/cli/ui/next.config.js +1 -0
  230. package/dist/cli/ui/package.json +4 -0
  231. package/dist/core/index.d.ts +34 -356
  232. package/dist/core/index.js +112 -332
  233. package/dist/core/index.js.map +1 -1
  234. package/dist/core/server.d.ts +135 -0
  235. package/dist/core/server.js +707 -0
  236. package/dist/core/server.js.map +1 -0
  237. package/dist/query-builder-KXz9cPzF.d.ts +330 -0
  238. package/package.json +32 -11
@@ -5,8 +5,6 @@ import { filter, orderBy, get, slice } from "lodash-es";
5
5
  import slugify from "@sindresorhus/slugify";
6
6
 
7
7
  // src/shared/constants.ts
8
- var SUPPORTED_EXTENSIONS = [".mdx", ".json"];
9
- var COLLECTION_ORDER_FILE = "collection.json";
10
8
  var IMAGE_MIME_TYPES = [
11
9
  "image/png",
12
10
  "image/jpeg",
@@ -28,233 +26,76 @@ var MEDIA_MIME_TYPES = [...IMAGE_MIME_TYPES, ...VIDEO_MIME_TYPES, ...AUDIO_MIME_
28
26
 
29
27
  // src/core/parsers/parser-mdx.ts
30
28
  import matter from "gray-matter";
31
- function parseMdx(content) {
32
- const { data, content: body } = matter(content);
33
- return { data, body: body.trim() };
34
- }
35
29
 
36
- // src/core/parsers/parser-json.ts
37
- function parseJson(content) {
38
- const parsed = JSON.parse(content);
39
- if (Array.isArray(parsed)) {
40
- return {
41
- type: "json-array",
42
- entries: parsed
43
- };
44
- }
45
- if (typeof parsed === "object" && parsed !== null) {
46
- return {
47
- type: "json-object",
48
- data: parsed
49
- };
50
- }
51
- throw new Error("JSON content must be an array or object");
30
+ // src/core/frontmatter-binder.ts
31
+ var TOKEN_REGEX = /\{frontmatter\.([a-zA-Z0-9_.]+)\}/g;
32
+ function bindFrontmatter(body, data) {
33
+ return body.replace(TOKEN_REGEX, (_match, path) => {
34
+ const value = resolvePath(data, path);
35
+ if (value === void 0 || value === null) return _match;
36
+ if (typeof value === "object") return JSON.stringify(value);
37
+ return String(value);
38
+ });
39
+ }
40
+ function extractFrontmatterTokens(body) {
41
+ const tokens = [];
42
+ let match;
43
+ const regex = new RegExp(TOKEN_REGEX.source, "g");
44
+ while ((match = regex.exec(body)) !== null) {
45
+ tokens.push(match[1]);
46
+ }
47
+ return tokens;
48
+ }
49
+ function resolvePath(obj, path) {
50
+ const keys = path.split(".");
51
+ let current = obj;
52
+ for (const key of keys) {
53
+ if (typeof current !== "object" || current === null) return void 0;
54
+ current = current[key];
55
+ }
56
+ return current;
52
57
  }
53
58
 
54
- // src/core/schema-inferrer.ts
55
- var RE_ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
56
- var RE_ISO_DATETIME = /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:?\d{2})?$/;
57
- var RE_EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
58
- var RE_URL = /^https?:\/\/.+/;
59
- var LONG_TEXT_THRESHOLD = 200;
60
- function isISODate(value) {
61
- return RE_ISO_DATE.test(value);
62
- }
63
- function isISODateTime(value) {
64
- return RE_ISO_DATETIME.test(value);
65
- }
66
- function isEmail(value) {
67
- return RE_EMAIL.test(value);
68
- }
69
- function isUrl(value) {
70
- return RE_URL.test(value);
71
- }
72
- function inferStringField(name, strings) {
73
- if (strings.every(isEmail)) return { name, type: "email" };
74
- if (strings.every(isUrl)) return { name, type: "url" };
75
- if (strings.every(isISODateTime)) return { name, type: "date", includeTime: true };
76
- if (strings.every(isISODate)) return { name, type: "date" };
77
- const isLong = strings.some((s) => s.length > LONG_TEXT_THRESHOLD || s.includes("\n"));
78
- return { name, type: isLong ? "long-text" : "text" };
79
- }
80
- function inferArrayField(name, items) {
81
- if (items.length === 0) return { name, type: "array", itemFields: [] };
82
- if (items.every((item) => typeof item === "string")) {
83
- const unique = [...new Set(items)].slice(0, 50);
84
- const options = unique.map((v) => ({ label: v, value: v }));
85
- return { name, type: "multi-select", options };
86
- }
87
- if (items.every((item) => typeof item === "object" && item !== null && !Array.isArray(item))) {
88
- return { name, type: "array", itemFields: inferFields(items) };
89
- }
90
- return { name, type: "array", itemFields: [] };
59
+ // src/core/locale-parser.ts
60
+ var LOCALE_REGEX = /\.([a-z]{2}(?:-[A-Z]{2})?)\.mdx$/;
61
+ function parseLocaleFromFilename(filename) {
62
+ const match = LOCALE_REGEX.exec(filename);
63
+ return match?.[1];
64
+ }
65
+ function stripLocaleFromSlug(slug, locale) {
66
+ if (!locale) return slug;
67
+ const dotSuffix = `.${locale}`;
68
+ if (slug.endsWith(dotSuffix)) return slug.slice(0, -dotSuffix.length);
69
+ const dashSuffix = `-${locale}`;
70
+ if (slug.endsWith(dashSuffix)) return slug.slice(0, -dashSuffix.length);
71
+ return slug;
91
72
  }
92
- function inferFieldDefinition(name, values) {
93
- const present = values.filter((v) => v !== null && v !== void 0);
94
- if (present.length === 0) return { name, type: "text" };
95
- if (present.every((v) => typeof v === "boolean")) return { name, type: "boolean" };
96
- if (present.every((v) => typeof v === "number")) {
97
- const format = present.every((v) => Number.isInteger(v)) ? "integer" : "decimal";
98
- return { name, type: "number", format };
99
- }
100
- if (present.every((v) => typeof v === "string")) {
101
- return inferStringField(name, present);
102
- }
103
- if (present.every((v) => Array.isArray(v))) {
104
- return inferArrayField(name, present.flat());
105
- }
106
- if (present.every((v) => typeof v === "object" && v !== null && !Array.isArray(v))) {
107
- return { name, type: "object", fields: inferFields(present) };
108
- }
109
- return { name, type: "text" };
110
- }
111
- function inferFields(rows) {
112
- const keySet = new Set(rows.flatMap((row) => Object.keys(row)));
113
- return Array.from(keySet).map((key) => inferFieldDefinition(key, rows.map((row) => row[key])));
114
- }
115
- function inferSchema(entries, collectionName) {
116
- const rows = entries.map((entry) => entry.data);
117
- return { collection: collectionName, fields: inferFields(rows) };
118
- }
119
-
120
- // src/core/indexer.ts
121
- var ContentIndex = class {
122
- entries = /* @__PURE__ */ new Map();
123
- collections = /* @__PURE__ */ new Map();
124
- fs;
125
- constructor(fsAdapter) {
126
- this.fs = fsAdapter;
127
- }
128
- async build(config) {
129
- this.clear();
130
- const dirs = await this.fs.listDirectories(".");
131
- for (const dir of dirs) {
132
- const dirName = this.fs.basename(dir);
133
- const collectionName = slugify(dirName);
134
- const collectionConfig = config?.collections?.[collectionName];
135
- await this.indexCollection(dirName, collectionName, collectionConfig?.schema);
136
- }
137
- }
138
- getCollection(name) {
139
- return this.entries.get(name) ?? [];
140
- }
141
- getCollections() {
142
- return Array.from(this.collections.values());
143
- }
144
- clear() {
145
- this.entries.clear();
146
- this.collections.clear();
147
- }
148
- async indexCollection(dirName, collectionName, manualSchema) {
149
- const entries = [];
150
- await this.scanDir(dirName, collectionName, dirName, entries);
151
- const orderPath = this.fs.join(dirName, COLLECTION_ORDER_FILE);
152
- const ordering = await this.readOrdering(orderPath);
153
- if (ordering) {
154
- this.applyOrdering(entries, ordering);
155
- }
156
- const schema = manualSchema ?? inferSchema(entries, collectionName);
157
- this.entries.set(collectionName, entries);
158
- this.collections.set(collectionName, {
159
- name: collectionName,
160
- type: this.detectCollectionType(entries),
161
- count: entries.length,
162
- basePath: dirName,
163
- schema
164
- });
165
- }
166
- async scanDir(dirName, collectionName, dirPath, entries) {
167
- const subDirs = await this.fs.listDirectories(dirPath);
168
- for (const subDir of subDirs) {
169
- await this.scanDir(dirName, collectionName, subDir, entries);
170
- }
171
- const files = await this.fs.listFiles(dirPath);
172
- for (const filePath of files) {
173
- const fileName = this.fs.basename(filePath);
174
- if (fileName === COLLECTION_ORDER_FILE) continue;
175
- const ext = this.fs.extname(fileName);
176
- const content = await this.fs.readFile(filePath);
177
- const relativePath = this.fs.relative(dirName, filePath);
178
- const slug = this.fs.normalizeSlug(relativePath, ext).split("/").map((segment) => slugify(segment)).join("/");
179
- if (ext === ".mdx") {
180
- entries.push(this.buildMdxEntry(collectionName, slug, content));
181
- } else if (ext === ".json") {
182
- entries.push(...this.buildJsonEntries(collectionName, slug, content));
183
- }
184
- }
185
- }
186
- buildMdxEntry(collectionName, slug, content) {
187
- const parsed = parseMdx(content);
188
- return {
189
- collection: collectionName,
190
- slug,
191
- path: `/${collectionName}/${slug}`,
192
- body: parsed.body,
193
- data: parsed.data
194
- };
195
- }
196
- buildJsonEntries(collectionName, slug, content) {
197
- const parsed = parseJson(content);
198
- if (parsed.type === "json-array") {
199
- return parsed.entries.map((data, index) => {
200
- const entrySlug = typeof data["slug"] === "string" ? slugify(data["slug"]) : `${slug}/${index}`;
201
- return {
202
- collection: collectionName,
203
- slug: entrySlug,
204
- path: `/${collectionName}/${entrySlug}`,
205
- data
206
- };
207
- });
208
- }
209
- return [{ collection: collectionName, slug, path: `/${collectionName}/${slug}`, data: parsed.data }];
210
- }
211
- async readOrdering(orderPath) {
212
- if (!await this.fs.exists(orderPath)) return null;
213
- try {
214
- const content = await this.fs.readFile(orderPath);
215
- const parsed = JSON.parse(content);
216
- if (Array.isArray(parsed)) return parsed;
217
- } catch (error) {
218
- console.warn(`[Nextjs Studio] Failed to parse ordering file: ${orderPath}`, error);
219
- }
220
- return null;
221
- }
222
- applyOrdering(entries, ordering) {
223
- const orderMap = new Map(ordering.map((slug, index) => [slug, index]));
224
- entries.sort((a, b) => {
225
- const aIndex = orderMap.get(a.slug) ?? Infinity;
226
- const bIndex = orderMap.get(b.slug) ?? Infinity;
227
- return aIndex - bIndex;
228
- });
229
- }
230
- detectCollectionType(entries) {
231
- if (entries.length === 0) return "mdx";
232
- const first = entries[0];
233
- if (first.body !== void 0) return "mdx";
234
- if (entries.length === 1 && !first.slug.includes("/")) return "json-object";
235
- return "json-array";
236
- }
237
- };
238
73
 
239
74
  // src/core/content-store.ts
240
75
  var store = null;
241
76
  function getStore() {
242
77
  if (!store) {
243
- throw new Error("Content not loaded. Call loadContent() before querying.");
78
+ throw new Error(
79
+ "Content not loaded. Auto-init requires 'nextjs-studio/server' \u2014 use loadContentSync() in a server context, or queryCollection() will auto-init when imported from 'nextjs-studio/server'."
80
+ );
244
81
  }
245
82
  return store;
246
83
  }
247
- async function loadContent(fsAdapter, config) {
248
- const index = new ContentIndex(fsAdapter);
249
- await index.build(config);
250
- store = index;
251
- return index;
84
+
85
+ // src/core/draft-filter.ts
86
+ function isDraft(entry) {
87
+ return entry.data.draft === true;
88
+ }
89
+ function filterDrafts(entries) {
90
+ return entries.filter((entry) => !isDraft(entry));
252
91
  }
253
92
 
254
93
  // src/core/query-builder.ts
255
94
  var QueryBuilder = class {
256
95
  collectionName;
257
96
  options = {};
97
+ _excludeDrafts = false;
98
+ _locale;
258
99
  constructor(collection) {
259
100
  this.collectionName = collection;
260
101
  }
@@ -274,8 +115,23 @@ var QueryBuilder = class {
274
115
  this.options.offset = count;
275
116
  return this;
276
117
  }
118
+ excludeDrafts() {
119
+ this._excludeDrafts = true;
120
+ return this;
121
+ }
122
+ locale(code) {
123
+ this._locale = code;
124
+ return this;
125
+ }
277
126
  all() {
278
127
  let entries = [...getStore().getCollection(this.collectionName)];
128
+ if (this._excludeDrafts) {
129
+ entries = entries.filter((entry) => !isDraft(entry));
130
+ }
131
+ if (this._locale) {
132
+ const loc = this._locale;
133
+ entries = entries.filter((entry) => entry.locale === loc);
134
+ }
279
135
  if (this.options.where) {
280
136
  const conditions = this.options.where;
281
137
  entries = filter(
@@ -289,132 +145,54 @@ var QueryBuilder = class {
289
145
  }
290
146
  const start = this.options.offset ?? 0;
291
147
  const end = this.options.limit ? start + this.options.limit : void 0;
292
- return slice(entries, start, end);
148
+ return slice(entries, start, end).map((e) => ({
149
+ collection: e.collection,
150
+ slug: e.slug,
151
+ path: e.path,
152
+ body: e.body,
153
+ locale: e.locale,
154
+ ...e.data
155
+ }));
293
156
  }
294
157
  first() {
295
158
  return this.limit(1).all()[0];
296
159
  }
160
+ one() {
161
+ const result = this.limit(1).all()[0];
162
+ if (result === void 0) {
163
+ throw new Error(`Collection "${this.collectionName}" is empty \u2014 expected exactly one entry.`);
164
+ }
165
+ return result;
166
+ }
297
167
  count() {
298
168
  return this.all().length;
299
169
  }
300
170
  };
301
- function queryCollection(collection) {
302
- return new QueryBuilder(collection);
303
- }
304
-
305
- // src/core/init.ts
306
- import path2 from "path";
307
-
308
- // src/cli/adapters/fs-adapter.ts
309
- import fs from "fs/promises";
310
- import path from "path";
311
- var FsAdapter = class {
312
- basePath;
313
- constructor(basePath) {
314
- this.basePath = path.resolve(basePath);
315
- }
316
- resolve(...segments) {
317
- return path.resolve(this.basePath, ...segments);
318
- }
319
- async readFile(filePath) {
320
- return fs.readFile(this.resolve(filePath), "utf-8");
321
- }
322
- async writeFile(filePath, content) {
323
- const fullPath = this.resolve(filePath);
324
- await fs.mkdir(path.dirname(fullPath), { recursive: true });
325
- await fs.writeFile(fullPath, content, "utf-8");
326
- }
327
- async deleteFile(filePath) {
328
- await fs.unlink(this.resolve(filePath));
329
- }
330
- async exists(filePath) {
331
- try {
332
- await fs.access(this.resolve(filePath));
333
- return true;
334
- } catch {
335
- return false;
336
- }
337
- }
338
- async getStats(filePath) {
339
- const fullPath = this.resolve(filePath);
340
- const stats = await fs.stat(fullPath);
341
- return { path: filePath, size: stats.size, modifiedAt: stats.mtime };
342
- }
343
- async listFiles(dirPath, extensions) {
344
- const fullPath = this.resolve(dirPath);
345
- const filterExts = extensions ?? SUPPORTED_EXTENSIONS;
346
- let entries;
347
- try {
348
- entries = await fs.readdir(fullPath, { withFileTypes: true });
349
- } catch {
350
- return [];
351
- }
352
- return entries.filter((entry) => entry.isFile() && filterExts.some((ext) => entry.name.endsWith(ext))).map((entry) => this.join(dirPath, entry.name));
353
- }
354
- async listDirectories(dirPath) {
355
- const fullPath = this.resolve(dirPath);
356
- let entries;
357
- try {
358
- entries = await fs.readdir(fullPath, { withFileTypes: true });
359
- } catch {
360
- return [];
361
- }
362
- return entries.filter((entry) => entry.isDirectory()).map((entry) => this.join(dirPath, entry.name));
363
- }
364
- async readBuffer(filePath) {
365
- return fs.readFile(this.resolve(filePath));
366
- }
367
- async writeBuffer(filePath, data) {
368
- const fullPath = this.resolve(filePath);
369
- await fs.mkdir(path.dirname(fullPath), { recursive: true });
370
- await fs.writeFile(fullPath, data);
371
- }
372
- async listAllFiles(dirPath) {
373
- const fullPath = this.resolve(dirPath);
374
- let entries;
375
- try {
376
- entries = await fs.readdir(fullPath, { withFileTypes: true });
377
- } catch {
378
- return [];
379
- }
380
- const results = [];
381
- for (const entry of entries) {
382
- if (!entry.isFile()) continue;
383
- const relativePath = this.join(dirPath, entry.name);
384
- const stats = await fs.stat(this.resolve(relativePath));
385
- results.push({ name: entry.name, relativePath, size: stats.size, modifiedAt: stats.mtime });
171
+ var FLUENT_METHODS = /* @__PURE__ */ new Set(["where", "sort", "limit", "offset", "excludeDrafts", "locale"]);
172
+ function wrapWithArrayProxy(builder) {
173
+ let cache = null;
174
+ return new Proxy(builder, {
175
+ get(target, prop, receiver) {
176
+ if (FLUENT_METHODS.has(String(prop))) {
177
+ const method = Reflect.get(target, prop);
178
+ return (...args) => {
179
+ cache = null;
180
+ method.apply(target, args);
181
+ return receiver;
182
+ };
183
+ }
184
+ if (prop in target) {
185
+ const value2 = Reflect.get(target, prop, receiver);
186
+ return typeof value2 === "function" ? value2.bind(target) : value2;
187
+ }
188
+ if (!cache) cache = target.all();
189
+ const value = Reflect.get(cache, prop);
190
+ return typeof value === "function" ? value.bind(cache) : value;
386
191
  }
387
- return results;
388
- }
389
- join(...segments) {
390
- return path.join(...segments);
391
- }
392
- basename(filePath) {
393
- return path.basename(filePath);
394
- }
395
- extname(filePath) {
396
- return path.extname(filePath);
397
- }
398
- relative(from, to) {
399
- return path.relative(from, to);
400
- }
401
- normalizeSlug(relativePath, ext) {
402
- return relativePath.replace(ext, "").split(path.sep).join("/");
403
- }
404
- };
405
-
406
- // src/core/init.ts
407
- async function initStudio(contentsDir, config) {
408
- const dir = contentsDir ?? path2.join(process.cwd(), "contents");
409
- await loadContent(new FsAdapter(dir), config);
192
+ });
410
193
  }
411
- function isStudioInitialized() {
412
- try {
413
- getStore();
414
- return true;
415
- } catch {
416
- return false;
417
- }
194
+ function queryCollection(name) {
195
+ return wrapWithArrayProxy(new QueryBuilder(name));
418
196
  }
419
197
 
420
198
  // src/shared/field-utils.ts
@@ -426,12 +204,14 @@ function keyLabel(name) {
426
204
  return fieldLabel({ name });
427
205
  }
428
206
  export {
429
- ContentIndex,
207
+ bindFrontmatter,
208
+ extractFrontmatterTokens,
430
209
  fieldLabel,
431
- initStudio,
432
- isStudioInitialized,
210
+ filterDrafts,
211
+ isDraft,
433
212
  keyLabel,
434
- loadContent,
435
- queryCollection
213
+ parseLocaleFromFilename,
214
+ queryCollection,
215
+ stripLocaleFromSlug
436
216
  };
437
217
  //# sourceMappingURL=index.js.map