start-fapi 1.0.3 → 1.0.4-alpha.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 (153) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +5 -8
  3. package/.next/build-manifest.json +2 -2
  4. package/.next/fallback-build-manifest.json +2 -2
  5. package/.next/routes-manifest.json +15 -33
  6. package/.next/server/app/_global-error.html +2 -2
  7. package/.next/server/app/_global-error.rsc +1 -1
  8. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  9. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  13. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  14. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  15. package/.next/server/app/api/endpoints/export/route/app-paths-manifest.json +3 -0
  16. package/.next/server/app/api/endpoints/export/route.js +6 -0
  17. package/.next/server/app/api/endpoints/export/route.js.nft.json +1 -0
  18. package/.next/server/app/api/{import-endpoints → endpoints/export}/route_client-reference-manifest.js +1 -1
  19. package/.next/server/app/api/endpoints/import/route/app-paths-manifest.json +3 -0
  20. package/.next/server/app/api/endpoints/import/route.js +6 -0
  21. package/.next/server/app/api/endpoints/import/route.js.nft.json +1 -0
  22. package/.next/server/app/api/{export-endpoints → endpoints/import}/route_client-reference-manifest.js +1 -1
  23. package/.next/server/app/api/endpoints/response/route/app-paths-manifest.json +3 -0
  24. package/.next/server/app/api/endpoints/response/route.js +7 -0
  25. package/.next/server/app/api/endpoints/response/route.js.nft.json +1 -0
  26. package/.next/server/app/api/endpoints/response/route_client-reference-manifest.js +2 -0
  27. package/.next/server/app/api/endpoints/route/app-paths-manifest.json +3 -0
  28. package/.next/server/app/api/endpoints/route.js +7 -0
  29. package/.next/server/app/api/endpoints/route.js.nft.json +1 -0
  30. package/.next/server/app/api/endpoints/route_client-reference-manifest.js +2 -0
  31. package/.next/server/app/api/fapi/[[...path]]/route.js.nft.json +1 -1
  32. package/.next/server/app/api/health/route/app-paths-manifest.json +3 -0
  33. package/.next/server/app/api/health/route.js +6 -0
  34. package/.next/server/app/api/health/route.js.nft.json +1 -0
  35. package/.next/server/app/api/health/route_client-reference-manifest.js +2 -0
  36. package/.next/server/app/api/update-project-name/route.js.nft.json +1 -1
  37. package/.next/server/app/fapi-simulator/page.js.nft.json +1 -1
  38. package/.next/server/app/fapi-simulator/page_client-reference-manifest.js +1 -1
  39. package/.next/server/app/home/page.js.nft.json +1 -1
  40. package/.next/server/app/home/page_client-reference-manifest.js +1 -1
  41. package/.next/server/app/page.js.nft.json +1 -1
  42. package/.next/server/app/page_client-reference-manifest.js +1 -1
  43. package/.next/server/app-paths-manifest.json +5 -8
  44. package/.next/server/chunks/[root-of-the-server]__2e10f0e3._.js +3 -0
  45. package/.next/server/chunks/[root-of-the-server]__32ce7884._.js +1 -1
  46. package/.next/server/chunks/{[root-of-the-server]__491c7442._.js → [root-of-the-server]__4d997cfc._.js} +2 -2
  47. package/.next/server/chunks/[root-of-the-server]__5f9eba03._.js +1 -1
  48. package/.next/server/chunks/[root-of-the-server]__6c68b836._.js +1 -1
  49. package/.next/server/chunks/[root-of-the-server]__890ff7ac._.js +3 -0
  50. package/.next/server/chunks/{[root-of-the-server]__732dc754._.js → [root-of-the-server]__8abc799b._.js} +2 -2
  51. package/.next/server/chunks/[root-of-the-server]__bb8c172d._.js +1 -1
  52. package/.next/server/chunks/_next-internal_server_app_api_endpoints_export_route_actions_cf8b81dd.js +3 -0
  53. package/.next/server/chunks/_next-internal_server_app_api_endpoints_import_route_actions_f2444950.js +3 -0
  54. package/.next/server/chunks/_next-internal_server_app_api_endpoints_response_route_actions_534c9084.js +3 -0
  55. package/.next/server/chunks/_next-internal_server_app_api_endpoints_route_actions_49d8ad56.js +3 -0
  56. package/.next/server/chunks/_next-internal_server_app_api_health_route_actions_da3433c4.js +3 -0
  57. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_ee266cee.js +3 -0
  58. package/.next/server/chunks/ssr/[root-of-the-server]__1c7254d0._.js +1 -1
  59. package/.next/server/chunks/ssr/[root-of-the-server]__495a2284._.js +1 -1
  60. package/.next/server/chunks/ssr/_4eca4c4c._.js +1 -1
  61. package/.next/server/chunks/ssr/_95fb7656._.js +2 -2
  62. package/.next/server/chunks/ssr/_b00e3d9f._.js +2 -2
  63. package/.next/server/pages/500.html +2 -2
  64. package/.next/static/chunks/5028c6f415f38a6d.js +103 -0
  65. package/.next/static/chunks/6b1719852a02048b.css +3 -0
  66. package/.next/static/chunks/ab42dd423e9f9382.js +103 -0
  67. package/.next/static/chunks/c6f55f4b46a7a925.js +1 -0
  68. package/.next/static/chunks/f2dc08cdcf390d02.js +33 -0
  69. package/package.json +1 -1
  70. package/src/app/api/{get-endpoint-response → endpoints/response}/route.ts +5 -5
  71. package/src/app/api/endpoints/route.ts +430 -0
  72. package/src/app/fapi-simulator/page.tsx +16 -7
  73. package/src/app/layout.tsx +1 -1
  74. package/src/lib/editor/index.tsx +1 -1
  75. package/src/lib/modal/index.tsx +1 -0
  76. package/src/utils/data/paths/paths.api.constants.ts +8 -8
  77. package/src/utils/functions/deleteEndpoint.ts +1 -1
  78. package/src/utils/functions/updateFapiEndpoint.ts +1 -1
  79. package/.next/server/app/api/create-endpoint/route/app-paths-manifest.json +0 -3
  80. package/.next/server/app/api/create-endpoint/route.js +0 -7
  81. package/.next/server/app/api/create-endpoint/route.js.nft.json +0 -1
  82. package/.next/server/app/api/create-endpoint/route_client-reference-manifest.js +0 -2
  83. package/.next/server/app/api/delete-endpoint/route/app-paths-manifest.json +0 -3
  84. package/.next/server/app/api/delete-endpoint/route.js +0 -7
  85. package/.next/server/app/api/delete-endpoint/route.js.nft.json +0 -1
  86. package/.next/server/app/api/delete-endpoint/route_client-reference-manifest.js +0 -2
  87. package/.next/server/app/api/export-endpoints/route/app-paths-manifest.json +0 -3
  88. package/.next/server/app/api/export-endpoints/route.js +0 -6
  89. package/.next/server/app/api/export-endpoints/route.js.nft.json +0 -1
  90. package/.next/server/app/api/fapi-health-check/route/app-paths-manifest.json +0 -3
  91. package/.next/server/app/api/fapi-health-check/route.js +0 -6
  92. package/.next/server/app/api/fapi-health-check/route.js.nft.json +0 -1
  93. package/.next/server/app/api/fapi-health-check/route_client-reference-manifest.js +0 -2
  94. package/.next/server/app/api/get-endpoint-response/route/app-paths-manifest.json +0 -3
  95. package/.next/server/app/api/get-endpoint-response/route.js +0 -7
  96. package/.next/server/app/api/get-endpoint-response/route.js.nft.json +0 -1
  97. package/.next/server/app/api/get-endpoint-response/route_client-reference-manifest.js +0 -2
  98. package/.next/server/app/api/get-endpoints/route/app-paths-manifest.json +0 -3
  99. package/.next/server/app/api/get-endpoints/route/build-manifest.json +0 -11
  100. package/.next/server/app/api/get-endpoints/route/server-reference-manifest.json +0 -4
  101. package/.next/server/app/api/get-endpoints/route.js +0 -6
  102. package/.next/server/app/api/get-endpoints/route.js.nft.json +0 -1
  103. package/.next/server/app/api/get-endpoints/route_client-reference-manifest.js +0 -2
  104. package/.next/server/app/api/import-endpoints/route/app-paths-manifest.json +0 -3
  105. package/.next/server/app/api/import-endpoints/route/build-manifest.json +0 -11
  106. package/.next/server/app/api/import-endpoints/route/server-reference-manifest.json +0 -4
  107. package/.next/server/app/api/import-endpoints/route.js +0 -6
  108. package/.next/server/app/api/import-endpoints/route.js.nft.json +0 -1
  109. package/.next/server/app/api/update-endpoint/route/app-paths-manifest.json +0 -3
  110. package/.next/server/app/api/update-endpoint/route/build-manifest.json +0 -11
  111. package/.next/server/app/api/update-endpoint/route/server-reference-manifest.json +0 -4
  112. package/.next/server/app/api/update-endpoint/route.js +0 -7
  113. package/.next/server/app/api/update-endpoint/route.js.nft.json +0 -1
  114. package/.next/server/app/api/update-endpoint/route_client-reference-manifest.js +0 -2
  115. package/.next/server/chunks/[root-of-the-server]__38a55164._.js +0 -3
  116. package/.next/server/chunks/[root-of-the-server]__d0397225._.js +0 -3
  117. package/.next/server/chunks/[root-of-the-server]__d4824153._.js +0 -3
  118. package/.next/server/chunks/_next-internal_server_app_api_create-endpoint_route_actions_265d5d8d.js +0 -3
  119. package/.next/server/chunks/_next-internal_server_app_api_delete-endpoint_route_actions_29dea99c.js +0 -3
  120. package/.next/server/chunks/_next-internal_server_app_api_export-endpoints_route_actions_d5a9a039.js +0 -3
  121. package/.next/server/chunks/_next-internal_server_app_api_fapi-health-check_route_actions_17990631.js +0 -3
  122. package/.next/server/chunks/_next-internal_server_app_api_get-endpoint-response_route_actions_005f5808.js +0 -3
  123. package/.next/server/chunks/_next-internal_server_app_api_get-endpoints_route_actions_57061d88.js +0 -3
  124. package/.next/server/chunks/_next-internal_server_app_api_import-endpoints_route_actions_1bc78fec.js +0 -3
  125. package/.next/server/chunks/_next-internal_server_app_api_update-endpoint_route_actions_7a4d8909.js +0 -3
  126. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_920a1c5a.js +0 -3
  127. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_a42af0d7.js +0 -3
  128. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_ce3b320b.js +0 -3
  129. package/.next/static/chunks/4b0ce70190044c6d.js +0 -103
  130. package/.next/static/chunks/ab2c5010cf8c9d17.js +0 -33
  131. package/.next/static/chunks/b82debe0d7c674a8.css +0 -3
  132. package/.next/static/chunks/edf6fbd7b1893d1e.js +0 -1
  133. package/.next/static/chunks/f8ebb1847e4eeced.js +0 -103
  134. package/src/app/api/create-endpoint/route.ts +0 -103
  135. package/src/app/api/delete-endpoint/route.ts +0 -114
  136. package/src/app/api/get-endpoints/route.ts +0 -77
  137. package/src/app/api/update-endpoint/route.ts +0 -149
  138. /package/.next/server/app/api/{create-endpoint → endpoints/export}/route/build-manifest.json +0 -0
  139. /package/.next/server/app/api/{create-endpoint → endpoints/export}/route/server-reference-manifest.json +0 -0
  140. /package/.next/server/app/api/{delete-endpoint → endpoints/import}/route/build-manifest.json +0 -0
  141. /package/.next/server/app/api/{delete-endpoint → endpoints/import}/route/server-reference-manifest.json +0 -0
  142. /package/.next/server/app/api/{export-endpoints → endpoints/response}/route/build-manifest.json +0 -0
  143. /package/.next/server/app/api/{export-endpoints → endpoints/response}/route/server-reference-manifest.json +0 -0
  144. /package/.next/server/app/api/{fapi-health-check → endpoints}/route/build-manifest.json +0 -0
  145. /package/.next/server/app/api/{fapi-health-check → endpoints}/route/server-reference-manifest.json +0 -0
  146. /package/.next/server/app/api/{get-endpoint-response → health}/route/build-manifest.json +0 -0
  147. /package/.next/server/app/api/{get-endpoint-response → health}/route/server-reference-manifest.json +0 -0
  148. /package/.next/static/{rV7Td5Z3WV9jbK3kKlJoL → r88p2KN3g5HS6Ssbx0Ge7}/_buildManifest.js +0 -0
  149. /package/.next/static/{rV7Td5Z3WV9jbK3kKlJoL → r88p2KN3g5HS6Ssbx0Ge7}/_clientMiddlewareManifest.json +0 -0
  150. /package/.next/static/{rV7Td5Z3WV9jbK3kKlJoL → r88p2KN3g5HS6Ssbx0Ge7}/_ssgManifest.js +0 -0
  151. /package/src/app/api/{export-endpoints → endpoints/export}/route.ts +0 -0
  152. /package/src/app/api/{import-endpoints → endpoints/import}/route.ts +0 -0
  153. /package/src/app/api/{fapi-health-check → health}/route.ts +0 -0
@@ -0,0 +1 @@
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,33525,(e,t,a)=>{"use strict";Object.defineProperty(a,"__esModule",{value:!0}),Object.defineProperty(a,"warnOnce",{enumerable:!0,get:function(){return s}});let s=e=>{}},41556,e=>{e.v("/_next/static/media/fapi-logo.df2eabba.svg")},51321,e=>{e.v("/_next/static/media/fapi-slash-logo.8ad03fe8.svg")},43564,e=>{"use strict";var t=e.i(43476),a=e.i(71645),s=e.i(55487),n=e.i(42669);e.i(33999);var i=e.i(70948),o=e.i(59558),o=o,r=e.i(61746),r=r,l=e.i(18240),l=l,c=e.i(44605),c=c,d=e.i(50632),d=d;e.i(6399);var p=e.i(48456),u=e.i(99891),m=e.i(89532),g=e.i(45571),S=e.i(81961),I=e.i(22860);e.i(82109);var j=e.i(92719);e.i(56621);var x=e.i(50384),T=e.i(47877);e.i(59170);var f=e.i(60365),C=e.i(35689),O=e.i(19163);e.s(["default",0,()=>{let e=(0,s.useDispatch)(),[E,h]=(0,a.useState)("3000");(0,a.useEffect)(()=>{h(window.location.port||"3000")},[]);let b=(0,s.useSelector)(e=>e.endpoints.endpoints),_=(0,s.useSelector)(e=>e.endpoints.projectName),[N,A]=(0,a.useState)(!1),[R,P]=(0,a.useState)({isOpen:!1,message:"",backgroundColor:""});(0,a.useEffect)(()=>{(async()=>{let t=await (0,x.loadEndpoints)();t.success&&t.endpoints?e((0,j.hydrateEndpoints)({endpoints:t.endpoints,projectName:t.projectName||""})):console.error("Failed to load endpoints:",t.error)})()},[e]);let{currentProjectName:M,setCurrentProjectName:v,isSavingProjectName:y,projectNameError:k,hasProjectNameChanges:L,handleProjectNameChange:F,handleSaveProjectName:U}=(({initialProjectName:e,setSnackbar:t})=>{let n=(0,s.useDispatch)(),[i,o]=(0,a.useState)(e),[r,l]=(0,a.useState)(!1),[c,d]=(0,a.useState)(""),p=i!==e,u=(0,a.useCallback)(e=>{let t=e.target.value;f.FAPI_REGEX.PROJECT_NAME.test(t)?(d(""),o(t)):d("Only letters, numbers, and spaces are allowed")},[]),m=(0,a.useCallback)(async()=>{if(p&&!c){if(i.length>f.UI_LIMITS.PROJECT_NAME_MAX_LENGTH)return void d(`Project name cannot exceed ${f.UI_LIMITS.PROJECT_NAME_MAX_LENGTH} characters`);l(!0);try{let a=await (0,C.updateProjectName)(i);a.success?(n((0,j.setProjectName)(i)),t({isOpen:!0,message:"Project name saved successfully",backgroundColor:f.STATUS_COLORS.SUCCESS})):(t({isOpen:!0,message:a.error||"Failed to save project name",backgroundColor:f.STATUS_COLORS.ERROR}),o(e))}catch(a){t({isOpen:!0,message:"An unexpected error occurred",backgroundColor:f.STATUS_COLORS.ERROR}),o(e)}finally{l(!1)}}},[p,c,i,e,n,t]);return{currentProjectName:i,setCurrentProjectName:o,isSavingProjectName:r,projectNameError:c,hasProjectNameChanges:p,handleProjectNameChange:u,handleSaveProjectName:m}})({initialProjectName:_,setSnackbar:P}),{fileInputRef:w,isImporting:X,importModalOpen:B,pendingImportFile:D,handleImport:G,handleFileChange:$,handleImportStrategy:W,handleImportCancel:z}=(({currentEndpointCount:e,setSnackbar:t})=>{let n=(0,s.useDispatch)(),i=(0,a.useRef)(null),[o,r]=(0,a.useState)(!1),[l,c]=(0,a.useState)(!1),[d,p]=(0,a.useState)(null),u=(0,a.useCallback)(()=>{i.current?.click()},[]),m=(0,a.useCallback)(e=>{let a=e.target.files?.[0];if(a){if(a.size>f.FAPI_LIMITS.MAX_FILE_SIZE_BYTES){t({isOpen:!0,message:`File size exceeds ${f.FAPI_LIMITS.MAX_FILE_SIZE_MB}MB limit`,backgroundColor:f.STATUS_COLORS.ERROR}),i.current&&(i.current.value="");return}p(a),c(!0)}},[t]),g=(0,a.useCallback)(async a=>{if(!d)return;if(a===f.IMPORT_STRATEGY.MERGE&&e>=f.FAPI_LIMITS.MAX_ENDPOINTS){t({isOpen:!0,message:`Cannot merge: Already at maximum limit of ${f.FAPI_LIMITS.MAX_ENDPOINTS} endpoints`,backgroundColor:f.STATUS_COLORS.ERROR}),c(!1);return}c(!1),r(!0);let s=await (0,O.importEndpoints)(d,a,e);if(s.success){t({isOpen:!0,message:s.message||`Imported ${s.addedCount} endpoint(s)`,backgroundColor:f.STATUS_COLORS.SUCCESS});let e=await (0,x.loadEndpoints)();e.success&&e.endpoints&&n((0,j.hydrateEndpoints)({endpoints:e.endpoints,projectName:e.projectName||""}))}else t({isOpen:!0,message:s.error||"Failed to import endpoints",backgroundColor:f.STATUS_COLORS.ERROR});r(!1),p(null),i.current&&(i.current.value="")},[d,e,n,t]),S=(0,a.useCallback)(()=>{c(!1),p(null),i.current&&(i.current.value="")},[]);return{fileInputRef:i,isImporting:o,importModalOpen:l,pendingImportFile:d,handleImport:u,handleFileChange:m,handleImportStrategy:g,handleImportCancel:S}})({currentEndpointCount:Object.keys(b).length,setSnackbar:P});(0,a.useEffect)(()=>{v(_)},[_,v]),(0,a.useEffect)(()=>{_&&_.trim()?document.title=`FAPI x ${_.trim()}`:document.title="FAPI"},[_]);let H=(0,a.useMemo)(()=>Object.entries(b).map(([e,t])=>{let[a,...s]=e.split(" ");return{path:s.join(" "),method:a,details:t}}),[b]),Y=Object.keys(b).length,J=Y>=f.FAPI_LIMITS.MAX_ENDPOINTS;return(0,t.jsxs)("div",{className:"min-h-screen relative",children:[(0,t.jsx)(p.AnimatedBackground,{}),(0,t.jsx)("input",{type:"file",ref:w,onChange:$,accept:".json",style:{display:"none"}}),(0,t.jsx)("div",{className:"sticky top-0 z-10 backdrop-blur-md bg-black/30 px-6 py-4",style:{maskImage:"linear-gradient(to bottom, black 70%, transparent 100%)",WebkitMaskImage:"linear-gradient(to bottom, black 70%, transparent 100%)"},children:(0,t.jsxs)("div",{className:"mx-auto flex flex-col sm:flex-row justify-between items-center gap-4",style:{maxWidth:f.UI_LIMITS.UI_CONTAINER_MAX_WIDTH},children:[(0,t.jsx)(u.AppName,{logoWidth:134,logoHeight:48}),(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(n.Tooltip,{title:J?`Maximum limit of ${f.FAPI_LIMITS.MAX_ENDPOINTS} endpoints reached`:"Create a new FAPI endpoint",arrow:!0,placement:"top",children:(0,t.jsx)("span",{children:(0,t.jsx)(m.Button,{onClick:J?void 0:()=>A(!0),name:"Create a new FAPI",disabled:J})})}),(0,t.jsx)(c.default,{isImporting:X,currentEndpointCount:Y,projectName:_,onImport:G,setSnackbar:P})]})]})}),(0,t.jsx)("div",{className:"px-6 pb-6",children:(0,t.jsxs)("div",{className:"mx-auto",style:{maxWidth:f.UI_LIMITS.UI_CONTAINER_MAX_WIDTH},children:[(0,t.jsxs)("div",{className:"mb-8 flex flex-col lg:flex-row justify-between items-start lg:items-center gap-4",children:[(0,t.jsx)(r.default,{currentProjectName:M,projectNameError:k,hasProjectNameChanges:L,isSavingProjectName:y,onProjectNameChange:F,onSaveProjectName:U}),(0,t.jsx)(l.default,{currentEndpointCount:Y})]}),(0,t.jsx)("div",{className:"mb-8",children:(0,t.jsx)(S.PrivacyBanner,{})}),(0,t.jsxs)("div",{className:"mb-6 flex item-center gap-1",children:[(0,t.jsx)("span",{className:"text-gray-200 font-semibold size",children:"FAPIs are available at:"}),(0,t.jsxs)("code",{className:"text-yellow-400 font-googleSansCode pr-2.5",children:[`http://localhost:${E}/api/fapi/`,(0,t.jsx)("span",{className:"text-gray-500",children:"{your-endpoint}"})]}),(0,t.jsx)(g.CopyButton,{textToCopy:`http://localhost:${E}/api/fapi/`,size:14,tooltipText:"Copy base URL"})]}),(0,t.jsx)("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-x-5 gap-y-7",children:H.map(e=>(0,t.jsx)(o.default,{method:e.method,path:e.path,details:e.details},(0,T.createEndpointKey)(e.method,e.path)))})]})}),(0,t.jsx)(i.EndpointModal,{isOpen:N,onClose:()=>A(!1)}),(0,t.jsx)(I.Snackbar,{isOpen:R.isOpen,message:R.message,onClose:()=>P(e=>({...e,isOpen:!1})),backgroundColor:R.backgroundColor}),(0,t.jsx)(d.default,{isOpen:B,fileName:D?.name||"unknown file",isAtLimit:J,onMerge:()=>W(f.IMPORT_STRATEGY.MERGE),onReplace:()=>W(f.IMPORT_STRATEGY.REPLACE),onCancel:z})]})}],43564)}]);
@@ -0,0 +1,33 @@
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,4730,e=>{e.v({name:"start-fapi",version:"1.0.4-alpha.0",description:"A developer tool for creating and simulating Fake APIs (FAPIs) in seconds.",bin:{"start-fapi":"./bin/start-fapi.js"},files:["bin","src","public",".next/static",".next/server",".next/*.json",".next/*.js",".next/BUILD_ID","!**/*.map","next.config.js","postcss.config.js","tailwind.config.ts","tsconfig.json","package.json","README.md"],keywords:["fake-api","mock-api","api-simulator","development-tools","api-testing","fapi","mock-server","fake-server","fake-rest-api"],author:"Soham De Roy",license:"MIT",repository:{type:"git",url:"https://github.com/sohamderoy/FAPI-Fake-APIs.git"},bugs:{url:"https://github.com/sohamderoy/FAPI-Fake-APIs/issues"},homepage:"https://github.com/sohamderoy/FAPI-Fake-APIs#readme",engines:{node:">=20.9.0"},scripts:{dev:"node bin/dev-with-consent.js","dev:3001":"PORT=3001 node bin/dev-with-consent.js",build:"next build",start:"next start",lint:"next lint",prepublishOnly:"npm run build"},dependencies:{"@emotion/cache":"^11.14.0","@emotion/react":"^11.14.0","@emotion/styled":"^11.14.1","@monaco-editor/react":"^4.7.0","@mui/icons-material":"^7.3.6","@mui/material":"^7.3.6","@mui/material-nextjs":"^7.3.6","@reduxjs/toolkit":"^2.11.2","@tailwindcss/postcss":"^4.1.18","lucide-react":"^0.562.0",next:"^16.1.1",react:"^19.2.3","react-dom":"^19.2.3","react-redux":"^9.2.0",uuid:"^13.0.0"},devDependencies:{"@types/node":"^25.0.3","@types/react":"^19.2.7","@types/react-dom":"^19.2.3",autoprefixer:"^10.4.23",eslint:"^9.39.2","eslint-config-next":"^16.1.1",postcss:"^8.5.6",tailwindcss:"^4.1.18",typescript:"^5.9.3"}})},18566,(e,t,o)=>{t.exports=e.r(76562)},79459,(e,t,o)=>{t.exports=e.r(18566)},82540,e=>{e.v({className:"google_sans_flex_739028f6-module__1u14uq__className",variable:"google_sans_flex_739028f6-module__1u14uq__variable"})},62051,e=>{e.v({className:"google_sans_code_6aade507-module__domY0W__className",variable:"google_sans_code_6aade507-module__domY0W__variable"})},76938,e=>{"use strict";var t=e.i(43476);e.i(47167);var o=e.i(71645),r=e.i(48203),l=e.i(98533),l=l,s=e.i(79459);function a(e){let{options:a,CacheProvider:n=l.C,children:i}=e,[c]=o.useState(()=>{let e=(0,r.default)({...a,key:a?.key??"mui"});e.compat=!0;let t=e.insert,o=[];return e.insert=(...r)=>{a?.enableCssLayer&&!r[1].styles.match(/^@layer\s+[^{]*$/)&&(r[1].styles=`@layer mui {${r[1].styles}}`);let[l,s]=r;return void 0===e.inserted[s.name]&&o.push({name:s.name,isGlobal:!l}),t(...r)},{cache:e,flush:()=>{let e=o;return o=[],e}}});return(0,s.useServerInsertedHTML)(()=>{let e=c.flush();if(0===e.length)return null;let r="",l=c.cache.key,s=[];return e.forEach(({name:e,isGlobal:t})=>{let o=c.cache.inserted[e];"string"==typeof o&&(t?s.push({name:e,style:o}):(r+=o,l+=` ${e}`))}),(0,t.jsxs)(o.Fragment,{children:[s.map(({name:e,style:o})=>(0,t.jsx)("style",{nonce:a?.nonce,"data-emotion":`${c.cache.key}-global ${e}`,dangerouslySetInnerHTML:{__html:o}},e)),r&&(0,t.jsx)("style",{nonce:a?.nonce,"data-emotion":l,dangerouslySetInnerHTML:{__html:r}})]})}),(0,t.jsx)(n,{value:c.cache,children:i})}var n=e.i(82540);let i={className:n.default.className,style:{fontFamily:"'Google Sans Flex'",fontStyle:"normal"}};null!=n.default.variable&&(i.variable=n.default.variable);var c=e.i(62051);let d={className:c.default.className,style:{fontFamily:"'Google Sans Code'",fontStyle:"normal"}};null!=c.default.variable&&(d.variable=c.default.variable);let m=o.createContext(null);function u(){return o.useContext(m)}let h="function"==typeof Symbol&&Symbol.for?Symbol.for("mui.nested"):"__THEME_NESTED__",f=function(e){let{children:r,theme:l}=e,s=u(),a=o.useMemo(()=>{var e,t;let o=null===s?{...l}:(e=s,"function"==typeof(t=l)?t(e):{...e,...t});return null!=o&&(o[h]=null!==s),o},[l,s]);return(0,t.jsx)(m.Provider,{value:a,children:r})};var g=e.i(28419),p=e.i(86931),y=e.i(68308),S=e.i(86373),b=e.i(7558),v=e.i(57242),_=e.i(73852);let x={};function k(e,t,r,l=!1){return o.useMemo(()=>{let o=e&&t[e]||t;if("function"==typeof r){let s=r(o),a=e?{...t,[e]:s}:s;return l?()=>a:a}return e?{...t,[e]:r}:{...t,...r}},[e,t,r,l])}let C=function(e){let{children:o,theme:r,themeId:l}=e,s=(0,p.default)(x),a=u()||x,n=k(l,s,r),i=k(l,a,r,!0),c="rtl"===(l?n[l]:n).direction,d=function(e){let o=(0,p.default)(),r=(0,v.default)()||"",{modularCssLayers:l}=e,s="mui.global, mui.components, mui.theme, mui.custom, mui.sx";return(s=l&&null===o?"string"==typeof l?l.replace(/mui(?!\.)/g,s):`@layer ${s};`:"",(0,b.default)(()=>{let e=document.querySelector("head");if(!e)return;let t=e.firstChild;if(s){if(t&&t.hasAttribute?.("data-mui-layer-order")&&t.getAttribute("data-mui-layer-order")===r)return;let o=document.createElement("style");o.setAttribute("data-mui-layer-order",r),o.textContent=s,e.prepend(o)}else e.querySelector(`style[data-mui-layer-order="${r}"]`)?.remove()},[s,r]),s)?(0,t.jsx)(_.default,{styles:s}):null}(n);return(0,t.jsx)(f,{theme:i,children:(0,t.jsx)(g.ThemeContext.Provider,{value:n,children:(0,t.jsx)(y.default,{value:c,children:(0,t.jsxs)(S.default,{value:l?n[l].components:n.components,children:[d,o]})})})})};var j=e.i(2001);function w({theme:e,...o}){let r=j.default in e?e[j.default]:void 0;return(0,t.jsx)(C,{...o,themeId:r?j.default:void 0,theme:r||e})}var M=e.i(17028),$=e.i(98006);let A="mode",F="color-scheme";function I(){}let P=({key:e,storageWindow:t})=>(t||"undefined"==typeof window||(t=window),{get(o){let r;if("undefined"!=typeof window){if(!t)return o;try{r=t.localStorage.getItem(e)}catch{}return r||o}},set:o=>{if(t)try{t.localStorage.setItem(e,o)}catch{}},subscribe:o=>{if(!t)return I;let r=t=>{let r=t.newValue;t.key===e&&o(r)};return t.addEventListener("storage",r),()=>{t.removeEventListener("storage",r)}}});function E(){}function T(e){if("undefined"!=typeof window&&"function"==typeof window.matchMedia&&"system"===e)return window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}function L(e,t){return"light"===e.mode||"system"===e.mode&&"light"===e.systemMode?t("light"):"dark"===e.mode||"system"===e.mode&&"dark"===e.systemMode?t("dark"):void 0}var W=e.i(1937),O=e.i(35767);let{CssVarsProvider:B,useColorScheme:D,getInitColorSchemeScript:N}=function(e){let{themeId:r,theme:l={},modeStorageKey:s=A,colorSchemeStorageKey:a=F,disableTransitionOnChange:n=!1,defaultColorScheme:i,resolveTheme:c}=e,d={allColorSchemes:[],colorScheme:void 0,darkColorScheme:void 0,lightColorScheme:void 0,mode:void 0,setColorScheme:()=>{},setMode:()=>{},systemMode:void 0},m=o.createContext(void 0),h={},f={},g="string"==typeof i?i:i.light,p="string"==typeof i?i:i.dark;return{CssVarsProvider:function(e){let{children:d,theme:g,modeStorageKey:p=s,colorSchemeStorageKey:y=a,disableTransitionOnChange:S=n,storageManager:v,storageWindow:_="undefined"==typeof window?void 0:window,documentNode:x="undefined"==typeof document?void 0:document,colorSchemeNode:k="undefined"==typeof document?void 0:document.documentElement,disableNestedContext:j=!1,disableStyleSheetGeneration:w=!1,defaultMode:M="system",forceThemeRerender:I=!1,noSsr:W}=e,O=o.useRef(!1),B=u(),D=o.useContext(m),N=!!D&&!j,R=o.useMemo(()=>g||("function"==typeof l?l():l),[g]),z=R[r],K=z||R,{colorSchemes:V=h,components:H=f,cssVarPrefix:q}=K,G=Object.keys(V).filter(e=>!!V[e]).join(","),U=o.useMemo(()=>G.split(","),[G]),Y="string"==typeof i?i:i.light,J="string"==typeof i?i:i.dark,Q=V[Y]&&V[J]?M:V[K.defaultColorScheme]?.palette?.mode||K.palette?.mode,{mode:X,setMode:Z,systemMode:ee,lightColorScheme:et,darkColorScheme:eo,colorScheme:er,setColorScheme:el}=function(e){let{defaultMode:t="light",defaultLightColorScheme:r,defaultDarkColorScheme:l,supportedColorSchemes:s=[],modeStorageKey:a=A,colorSchemeStorageKey:n=F,storageWindow:i="undefined"==typeof window?void 0:window,storageManager:c=P,noSsr:d=!1}=e,m=s.join(","),u=s.length>1,h=o.useMemo(()=>c?.({key:a,storageWindow:i}),[c,a,i]),f=o.useMemo(()=>c?.({key:`${n}-light`,storageWindow:i}),[c,n,i]),g=o.useMemo(()=>c?.({key:`${n}-dark`,storageWindow:i}),[c,n,i]),[p,y]=o.useState(()=>{let e=h?.get(t)||t,o=f?.get(r)||r,s=g?.get(l)||l;return{mode:e,systemMode:T(e),lightColorScheme:o,darkColorScheme:s}}),[S,b]=o.useState(d||!u);o.useEffect(()=>{b(!0)},[]);let v=L(p,e=>"light"===e?p.lightColorScheme:"dark"===e?p.darkColorScheme:void 0),_=o.useCallback(e=>{y(o=>{if(e===o.mode)return o;let r=e??t;return h?.set(r),{...o,mode:r,systemMode:T(r)}})},[h,t]),x=o.useCallback(e=>{e?"string"==typeof e?e&&!m.includes(e)?console.error(`\`${e}\` does not exist in \`theme.colorSchemes\`.`):y(t=>{let o={...t};return L(t,t=>{"light"===t&&(f?.set(e),o.lightColorScheme=e),"dark"===t&&(g?.set(e),o.darkColorScheme=e)}),o}):y(t=>{let o={...t},s=null===e.light?r:e.light,a=null===e.dark?l:e.dark;return s&&(m.includes(s)?(o.lightColorScheme=s,f?.set(s)):console.error(`\`${s}\` does not exist in \`theme.colorSchemes\`.`)),a&&(m.includes(a)?(o.darkColorScheme=a,g?.set(a)):console.error(`\`${a}\` does not exist in \`theme.colorSchemes\`.`)),o}):y(e=>(f?.set(r),g?.set(l),{...e,lightColorScheme:r,darkColorScheme:l}))},[m,f,g,r,l]),k=o.useCallback(e=>{"system"===p.mode&&y(t=>{let o=e?.matches?"dark":"light";return t.systemMode===o?t:{...t,systemMode:o}})},[p.mode]),C=o.useRef(k);return C.current=k,o.useEffect(()=>{if("function"!=typeof window.matchMedia||!u)return;let e=(...e)=>C.current(...e),t=window.matchMedia("(prefers-color-scheme: dark)");return t.addListener(e),e(t),()=>{t.removeListener(e)}},[u]),o.useEffect(()=>{if(u){let e=h?.subscribe(e=>{(!e||["light","dark","system"].includes(e))&&_(e||t)})||E,o=f?.subscribe(e=>{(!e||m.match(e))&&x({light:e})})||E,r=g?.subscribe(e=>{(!e||m.match(e))&&x({dark:e})})||E;return()=>{e(),o(),r()}}},[x,_,m,t,i,u,h,f,g]),{...p,mode:S?p.mode:void 0,systemMode:S?p.systemMode:void 0,colorScheme:S?v:void 0,setMode:_,setColorScheme:x}}({supportedColorSchemes:U,defaultLightColorScheme:Y,defaultDarkColorScheme:J,modeStorageKey:p,colorSchemeStorageKey:y,defaultMode:Q,storageManager:v,storageWindow:_,noSsr:W}),es=X,ea=er;N&&(es=D.mode,ea=D.colorScheme);let en=ea||K.defaultColorScheme;K.vars&&!I&&(en=K.defaultColorScheme);let ei=o.useMemo(()=>{let e=K.generateThemeVars?.()||K.vars,t={...K,components:H,colorSchemes:V,cssVarPrefix:q,vars:e};if("function"==typeof t.generateSpacing&&(t.spacing=t.generateSpacing()),en){let e=V[en];e&&"object"==typeof e&&Object.keys(e).forEach(o=>{e[o]&&"object"==typeof e[o]?t[o]={...t[o],...e[o]}:t[o]=e[o]})}return c?c(t):t},[K,en,H,V,q]),ec=K.colorSchemeSelector;(0,b.default)(()=>{if(ea&&k&&ec&&"media"!==ec){let e=ec;if("class"===ec&&(e=".%s"),"data"===ec&&(e="[data-%s]"),ec?.startsWith("data-")&&!ec.includes("%s")&&(e=`[${ec}="%s"]`),e.startsWith("."))k.classList.remove(...U.map(t=>e.substring(1).replace("%s",t))),k.classList.add(e.substring(1).replace("%s",ea));else{let t=e.replace("%s",ea).match(/\[([^\]]+)\]/);if(t){let[e,o]=t[1].split("=");o||U.forEach(t=>{k.removeAttribute(e.replace(ea,t))}),k.setAttribute(e,o?o.replace(/"|'/g,""):"")}else k.setAttribute(e,ea)}}},[ea,ec,k,U]),o.useEffect(()=>{let e;if(S&&O.current&&x){let t=x.createElement("style");t.appendChild(x.createTextNode("*{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}")),x.head.appendChild(t),window.getComputedStyle(x.body),e=setTimeout(()=>{x.head.removeChild(t)},1)}return()=>{clearTimeout(e)}},[ea,S,x]),o.useEffect(()=>(O.current=!0,()=>{O.current=!1}),[]);let ed=o.useMemo(()=>({allColorSchemes:U,colorScheme:ea,darkColorScheme:eo,lightColorScheme:et,mode:es,setColorScheme:el,setMode:Z,systemMode:ee}),[U,ea,eo,et,es,el,Z,ee,ei.colorSchemeSelector]),em=!0;(w||!1===K.cssVariables||N&&B?.cssVarPrefix===q)&&(em=!1);let eu=(0,t.jsxs)(o.Fragment,{children:[(0,t.jsx)(C,{themeId:z?r:void 0,theme:ei,children:d}),em&&(0,t.jsx)($.GlobalStyles,{styles:ei.generateStyleSheets?.()||[]})]});return N?eu:(0,t.jsx)(m.Provider,{value:ed,children:eu})},useColorScheme:()=>o.useContext(m)||d,getInitColorSchemeScript:e=>(function(e){let{defaultMode:o="system",defaultLightColorScheme:r="light",defaultDarkColorScheme:l="dark",modeStorageKey:s=A,colorSchemeStorageKey:a=F,attribute:n="data-color-scheme",colorSchemeNode:i="document.documentElement",nonce:c}=e||{},d="",m=n;if("class"===n&&(m=".%s"),"data"===n&&(m="[data-%s]"),m.startsWith(".")){let e=m.substring(1);d+=`${i}.classList.remove('${e}'.replace('%s', light), '${e}'.replace('%s', dark));
2
+ ${i}.classList.add('${e}'.replace('%s', colorScheme));`}let u=m.match(/\[([^[\]]+)\]/);if(u){let[e,t]=u[1].split("=");t||(d+=`${i}.removeAttribute('${e}'.replace('%s', light));
3
+ ${i}.removeAttribute('${e}'.replace('%s', dark));`),d+=`
4
+ ${i}.setAttribute('${e}'.replace('%s', colorScheme), ${t?`${t}.replace('%s', colorScheme)`:'""'});`}else".%s"!==m&&(d+=`${i}.setAttribute('${m}', colorScheme);`);return(0,t.jsx)("script",{suppressHydrationWarning:!0,nonce:"undefined"==typeof window?c:"",dangerouslySetInnerHTML:{__html:`(function() {
5
+ try {
6
+ let colorScheme = '';
7
+ const mode = localStorage.getItem('${s}') || '${o}';
8
+ const dark = localStorage.getItem('${a}-dark') || '${l}';
9
+ const light = localStorage.getItem('${a}-light') || '${r}';
10
+ if (mode === 'system') {
11
+ // handle system mode
12
+ const mql = window.matchMedia('(prefers-color-scheme: dark)');
13
+ if (mql.matches) {
14
+ colorScheme = dark
15
+ } else {
16
+ colorScheme = light
17
+ }
18
+ }
19
+ if (mode === 'light') {
20
+ colorScheme = light;
21
+ }
22
+ if (mode === 'dark') {
23
+ colorScheme = dark;
24
+ }
25
+ if (colorScheme) {
26
+ ${d}
27
+ }
28
+ } catch(e){}})();`}},"mui-color-scheme-init")})({colorSchemeStorageKey:a,defaultLightColorScheme:g,defaultDarkColorScheme:p,modeStorageKey:s,...e})}}({themeId:j.default,theme:()=>(0,W.default)({cssVariables:!0}),colorSchemeStorageKey:"mui-color-scheme",modeStorageKey:"mui-mode",defaultColorScheme:{light:"light",dark:"dark"},resolveTheme:e=>{let t={...e,typography:(0,O.default)(e.palette,e.typography)};return t.unstable_sx=function(e){return(0,M.default)({sx:e,theme:this})},t}});function R({theme:e,...r}){let l=o.useMemo(()=>{if("function"==typeof e)return e;let t=j.default in e?e[j.default]:e;return"colorSchemes"in t?null:"vars"in t?e:{...e,vars:null}},[e]);return l?(0,t.jsx)(w,{theme:l,...r}):(0,t.jsx)(B,{theme:e,...r})}let z=(0,W.default)({palette:{mode:"dark",primary:{main:"#2563EB",light:"#3B82F6",dark:"#1D4ED8"},secondary:{main:"#8B5CF6",light:"#A78BFA",dark:"#7C3AED"},background:{default:"#000000",paper:"#111111"},text:{primary:"#F9FAFB",secondary:"#D1D5DB"}},typography:{fontFamily:"var(--font-google-sans-flex), sans-serif",h1:{fontFamily:"var(--font-google-sans-flex), sans-serif",fontSize:"3.5rem",fontWeight:700,letterSpacing:"0.2em"},h2:{fontFamily:"var(--font-google-sans-flex), sans-serif",fontSize:"2.5rem",fontWeight:600},h3:{fontFamily:"var(--font-google-sans-flex), sans-serif",fontSize:"2rem",fontWeight:600},body1:{fontFamily:"var(--font-google-sans-flex), sans-serif",fontSize:"1rem",lineHeight:1.5},button:{fontFamily:"var(--font-google-sans-flex), sans-serif",textTransform:"none",fontWeight:500}},components:{MuiCssBaseline:{styleOverrides:{body:{fontFamily:"var(--font-google-sans-flex), sans-serif",backgroundColor:"#000000"}}},MuiButton:{styleOverrides:{root:{borderRadius:8,padding:"8px 24px"}}},MuiCard:{styleOverrides:{root:{borderRadius:12,background:"#111111"}}},MuiPopover:{defaultProps:{disableScrollLock:!0}},MuiMenu:{defaultProps:{disableScrollLock:!0}},MuiModal:{defaultProps:{disableScrollLock:!0}}}});var K=e.i(35642),V=e.i(94425);let H="function"==typeof(0,K.globalCss)({}),q=(e,t=!1)=>{let o={};t&&e.colorSchemes&&"function"==typeof e.getColorSchemeSelector&&Object.entries(e.colorSchemes).forEach(([t,r])=>{let l=e.getColorSchemeSelector(t);l.startsWith("@")?o[l]={":root":{colorScheme:r.palette?.mode}}:o[l.replace(/\s*&/,"")]={colorScheme:r.palette?.mode}});let r={html:{WebkitFontSmoothing:"antialiased",MozOsxFontSmoothing:"grayscale",boxSizing:"border-box",WebkitTextSizeAdjust:"100%",...t&&!e.vars&&{colorScheme:e.palette.mode}},"*, *::before, *::after":{boxSizing:"inherit"},"strong, b":{fontWeight:e.typography.fontWeightBold},body:{margin:0,...{color:(e.vars||e).palette.text.primary,...e.typography.body1,backgroundColor:(e.vars||e).palette.background.default,"@media print":{backgroundColor:(e.vars||e).palette.common.white}},"&::backdrop":{backgroundColor:(e.vars||e).palette.background.default}},...o},l=e.components?.MuiCssBaseline?.styleOverrides;return l&&(r=[r,l]),r},G="mui-ecs",U=(0,K.globalCss)(H?({theme:e,enableColorScheme:t})=>q(e,t):({theme:e})=>{let t,o;return o=Array.isArray(t=q(e,!1))?t[0]:t,!e.vars&&o&&(o.html[`:root:has(${G})`]={colorScheme:e.palette.mode}),e.colorSchemes&&Object.entries(e.colorSchemes).forEach(([t,r])=>{let l=e.getColorSchemeSelector(t);l.startsWith("@")?o[l]={[`:root:not(:has(.${G}))`]:{colorScheme:r.palette?.mode}}:o[l.replace(/\s*&/,"")]={[`&:not(:has(.${G}))`]:{colorScheme:r.palette?.mode}}}),t}),Y=function(e){let{children:r,enableColorScheme:l=!1}=(0,V.useDefaultProps)({props:e,name:"MuiCssBaseline"});return(0,t.jsxs)(o.Fragment,{children:[H&&(0,t.jsx)(U,{enableColorScheme:l}),!H&&!l&&(0,t.jsx)("span",{className:G,style:{display:"none"}}),r]})};var J=e.i(4730);function Q({children:e}){return(0,o.useEffect)(()=>{let e=window.location.port||"3000";console.log(`%c ______ _____ ______ ______
29
+ | ____| | _ | | ___ | |_ _|
30
+ | |__ | |_| | | |__| | ||
31
+ | __| | _ | | ____/ ||
32
+ | | | | | | | | ||
33
+ |_| |_| |_| |_| |__| `,"color: #3b82f6; font-weight: bold;"),console.log("%cCreate & simulate Fake APIs (FAPIs) in seconds.","color: #9ca3af;"),console.log(""),console.log(`%cFAPI Version: %cv${J.default.version}`,"color: #9ca3af;","color: #22c55e; font-weight: bold;"),console.log(`%cFAPI running on PORT: %c${e}`,"color: #9ca3af;","color: #22c55e; font-weight: bold;"),console.log(`%cFAPIs are available at: %chttp://localhost:${e}/api/fapi/%c{your-endpoint}`,"color: #9ca3af;","color: #eab308;","color: #6b7280;")},[]),(0,t.jsx)("html",{lang:"en",className:`${i.variable} ${d.variable}`,children:(0,t.jsx)("body",{children:(0,t.jsx)(a,{children:(0,t.jsxs)(R,{theme:z,children:[(0,t.jsx)(Y,{}),e]})})})})}e.s(["default",()=>Q],76938)},40581,e=>{"use strict";var t=e.i(43476);e.i(82109);var o=e.i(90357),r=e.i(55487);e.s(["default",0,({children:e})=>(0,t.jsx)(r.Provider,{store:o.store,children:e})])}]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "start-fapi",
3
- "version": "1.0.3",
3
+ "version": "1.0.4-alpha.0",
4
4
  "description": "A developer tool for creating and simulating Fake APIs (FAPIs) in seconds.",
5
5
  "bin": {
6
6
  "start-fapi": "./bin/start-fapi.js"
@@ -6,7 +6,7 @@ import { getFapiStorageFilePathPerPort } from "@/utils/functions/getFapiStorageF
6
6
  import { createEndpointKey } from "@/utils/functions";
7
7
 
8
8
  // Force dynamic rendering - don't cache this route
9
- export const dynamic = 'force-dynamic';
9
+ export const dynamic = "force-dynamic";
10
10
  export const revalidate = 0;
11
11
 
12
12
  export const GET = async (req: NextRequest) => {
@@ -68,10 +68,10 @@ export const GET = async (req: NextRequest) => {
68
68
  {
69
69
  status: 200,
70
70
  headers: {
71
- 'Cache-Control': 'no-store, no-cache, must-revalidate, max-age=0',
72
- 'Pragma': 'no-cache',
73
- 'Expires': '0',
74
- }
71
+ "Cache-Control": "no-store, no-cache, must-revalidate, max-age=0",
72
+ Pragma: "no-cache",
73
+ Expires: "0",
74
+ },
75
75
  }
76
76
  );
77
77
  } catch (err) {
@@ -0,0 +1,430 @@
1
+ import { getFapiStorageFilePathPerPort } from "@/utils/functions/getFapiStorageFilePathPerPort.util";
2
+ import { NextRequest, NextResponse } from "next/server";
3
+ import { v4 as uuidv4 } from "uuid";
4
+ import { promises as fs } from "fs";
5
+ import { FapiEndpoint, FapiStorage, HttpMethods } from "@/types/fapi";
6
+ import { getStorageDirectory } from "@/utils/functions/getStorageDirectory.util";
7
+ import { createEndpointKey } from "@/utils/functions";
8
+
9
+ // Force dynamic rendering - don't cache this route
10
+ export const dynamic = "force-dynamic";
11
+ export const revalidate = 0;
12
+
13
+ /* GET /api/endpoints - Fetch all endpoints */
14
+ export const GET = async (req: NextRequest) => {
15
+ try {
16
+ const port = process.env.PORT || "3000";
17
+
18
+ if (!port?.trim()) {
19
+ return new NextResponse(
20
+ JSON.stringify({ error: "Invalid Port Configuration" }),
21
+ { status: 500 }
22
+ );
23
+ }
24
+
25
+ const fapiStorageDirectory = getStorageDirectory();
26
+ const fapiStorageFilePathPerPort = getFapiStorageFilePathPerPort(
27
+ fapiStorageDirectory,
28
+ port
29
+ );
30
+
31
+ // Read storage file
32
+ let storage: FapiStorage;
33
+ try {
34
+ const fileContent = await fs.readFile(fapiStorageFilePathPerPort, "utf-8");
35
+ storage = JSON.parse(fileContent);
36
+ } catch (err) {
37
+ // File doesn't exist or is invalid - return empty storage
38
+ return new NextResponse(
39
+ JSON.stringify({
40
+ success: true,
41
+ endpoints: {},
42
+ metadata: {
43
+ lastUpdated: new Date().toISOString(),
44
+ totalEndpoints: 0,
45
+ },
46
+ }),
47
+ { status: 200 }
48
+ );
49
+ }
50
+
51
+ // Strip response bodies to keep the listing payload lightweight
52
+ const endpointsWithoutResponses: Record<string, object> = {};
53
+ for (const [key, endpoint] of Object.entries(storage.endpoints)) {
54
+ const { response, ...rest } = endpoint;
55
+ endpointsWithoutResponses[key] = rest;
56
+ }
57
+
58
+ return new NextResponse(
59
+ JSON.stringify({
60
+ success: true,
61
+ endpoints: endpointsWithoutResponses,
62
+ metadata: storage.metadata,
63
+ }),
64
+ {
65
+ status: 200,
66
+ headers: {
67
+ "Cache-Control": "no-store, no-cache, must-revalidate, max-age=0",
68
+ Pragma: "no-cache",
69
+ Expires: "0",
70
+ },
71
+ }
72
+ );
73
+ } catch (err) {
74
+ console.error("ERROR_FETCHING_ENDPOINTS:", err);
75
+ return new NextResponse(
76
+ JSON.stringify({ error: "Internal Server Error" }),
77
+ { status: 500 }
78
+ );
79
+ }
80
+ };
81
+
82
+ /* POST /api/endpoints - Create a new endpoint */
83
+ export const POST = async (req: NextRequest) => {
84
+ try {
85
+ const data = (await req.json()) as FapiEndpoint;
86
+ const port = process.env.PORT || "3000";
87
+ const fapiStorageDirectory = getStorageDirectory();
88
+ const fapiStorageFilePathPerPort = getFapiStorageFilePathPerPort(
89
+ fapiStorageDirectory,
90
+ port
91
+ );
92
+
93
+ /* Check if port is not valid, then return */
94
+ if (!port?.trim()) {
95
+ console.warn("PORT_NOT_VALID_SKIPPING_STORAGE_INITIALIZATION");
96
+ return;
97
+ }
98
+
99
+ /* Checking if the req contains required fields */
100
+ if (!data.path || !data.method || !data.responseCode) {
101
+ return new NextResponse(
102
+ JSON.stringify({
103
+ error: "Missing Required Fields",
104
+ }),
105
+ {
106
+ status: 400,
107
+ }
108
+ );
109
+ }
110
+
111
+ /* Create storage directory if it does not exist */
112
+ await fs.mkdir(fapiStorageDirectory, { recursive: true });
113
+
114
+ /* Read existing storage if available or initialize a new one */
115
+ let storage: FapiStorage;
116
+ try {
117
+ const fileContent = await fs.readFile(
118
+ fapiStorageFilePathPerPort,
119
+ "utf-8"
120
+ );
121
+ storage = JSON.parse(fileContent);
122
+ } catch {
123
+ storage = {
124
+ endpoints: {},
125
+ metadata: {
126
+ lastUpdated: new Date().toISOString(),
127
+ totalEndpoints: 0,
128
+ },
129
+ };
130
+ }
131
+
132
+ const endpointKey = createEndpointKey(data.method, data.path);
133
+
134
+ /* Adding the new endpoint in the storage and updating metadata */
135
+ storage.endpoints[endpointKey] = {
136
+ id: uuidv4(),
137
+ path: data.path,
138
+ method: data.method,
139
+ responseCode: data.responseCode,
140
+ responseDelay: data.responseDelay || 0,
141
+ response: data.response ?? "",
142
+ createdAt: new Date().toISOString(),
143
+ };
144
+ storage.metadata = {
145
+ lastUpdated: new Date().toISOString(),
146
+ totalEndpoints: Object.keys(storage.endpoints).length,
147
+ };
148
+
149
+ /* Saving the new endpoint to storage along with any previous data */
150
+ await fs.writeFile(
151
+ fapiStorageFilePathPerPort,
152
+ JSON.stringify(storage, null, 2)
153
+ );
154
+
155
+ return new NextResponse(
156
+ JSON.stringify(
157
+ {
158
+ success: true,
159
+ message: "Endpoint Successfully Created With Following Details",
160
+ endpoint: storage.endpoints[endpointKey],
161
+ },
162
+ null,
163
+ 2
164
+ )
165
+ );
166
+ } catch (err) {
167
+ console.log("ERROR_CREATING_ENDPOINT: ", err);
168
+ return new NextResponse(
169
+ JSON.stringify({
170
+ err: "Internal Server Error",
171
+ }),
172
+ {
173
+ status: 500,
174
+ }
175
+ );
176
+ }
177
+ };
178
+
179
+ /* PUT /api/endpoints - Update an existing endpoint */
180
+ export const PUT = async (req: NextRequest) => {
181
+ try {
182
+ const {
183
+ method,
184
+ path,
185
+ response,
186
+ responseCode,
187
+ responseDelay,
188
+ }: {
189
+ method: HttpMethods;
190
+ path: string;
191
+ response?: string;
192
+ responseCode?: number;
193
+ responseDelay?: number;
194
+ } = await req.json();
195
+
196
+ /* Check if required fields are present */
197
+ if (!method || !path) {
198
+ return new NextResponse(
199
+ JSON.stringify({
200
+ error: "Missing Required Fields (method and path)",
201
+ }),
202
+ {
203
+ status: 400,
204
+ }
205
+ );
206
+ }
207
+
208
+ /* Check if at least one field to update is provided */
209
+ if (
210
+ response === undefined &&
211
+ responseCode === undefined &&
212
+ responseDelay === undefined
213
+ ) {
214
+ return new NextResponse(
215
+ JSON.stringify({
216
+ error:
217
+ "At least one field to update must be provided (response, responseCode, or responseDelay)",
218
+ }),
219
+ {
220
+ status: 400,
221
+ }
222
+ );
223
+ }
224
+
225
+ const port = process.env.PORT || "3000";
226
+ const fapiStorageDirectory = getStorageDirectory();
227
+ const fapiStorageFilePathPerPort = getFapiStorageFilePathPerPort(
228
+ fapiStorageDirectory,
229
+ port
230
+ );
231
+
232
+ /* Check if port is valid */
233
+ if (!port?.trim()) {
234
+ console.warn("PORT_NOT_VALID_CANNOT_UPDATE_ENDPOINT");
235
+ return new NextResponse(
236
+ JSON.stringify({
237
+ error: "Invalid Port Configuration",
238
+ }),
239
+ {
240
+ status: 500,
241
+ }
242
+ );
243
+ }
244
+
245
+ /* Read existing storage */
246
+ let storage: FapiStorage;
247
+ try {
248
+ const fileContent = await fs.readFile(
249
+ fapiStorageFilePathPerPort,
250
+ "utf-8"
251
+ );
252
+ storage = JSON.parse(fileContent);
253
+ } catch {
254
+ return new NextResponse(
255
+ JSON.stringify({
256
+ error: "Storage File Not Found",
257
+ }),
258
+ {
259
+ status: 404,
260
+ }
261
+ );
262
+ }
263
+
264
+ /* Generate endpoint key and check if endpoint exists */
265
+ const endpointKey = createEndpointKey(method, path);
266
+
267
+ if (!storage.endpoints[endpointKey]) {
268
+ return new NextResponse(
269
+ JSON.stringify({
270
+ error: "Endpoint Not Found",
271
+ }),
272
+ {
273
+ status: 404,
274
+ }
275
+ );
276
+ }
277
+
278
+ /* Update the endpoint with provided fields */
279
+ const updatedEndpoint = {
280
+ ...storage.endpoints[endpointKey],
281
+ ...(response !== undefined && { response }),
282
+ ...(responseCode !== undefined && { responseCode }),
283
+ ...(responseDelay !== undefined && { responseDelay }),
284
+ };
285
+
286
+ storage.endpoints[endpointKey] = updatedEndpoint;
287
+
288
+ /* Update metadata */
289
+ storage.metadata = {
290
+ lastUpdated: new Date().toISOString(),
291
+ totalEndpoints: Object.keys(storage.endpoints).length,
292
+ };
293
+
294
+ /* Write updated storage back to file */
295
+ await fs.writeFile(
296
+ fapiStorageFilePathPerPort,
297
+ JSON.stringify(storage, null, 2)
298
+ );
299
+
300
+ return new NextResponse(
301
+ JSON.stringify({
302
+ success: true,
303
+ message: "Endpoint Updated Successfully",
304
+ updatedEndpoint: storage.endpoints[endpointKey],
305
+ }),
306
+ {
307
+ status: 200,
308
+ }
309
+ );
310
+ } catch (err) {
311
+ console.error("ERROR_UPDATING_ENDPOINT: ", err);
312
+ return new NextResponse(
313
+ JSON.stringify({
314
+ error: "Internal Server Error",
315
+ }),
316
+ {
317
+ status: 500,
318
+ }
319
+ );
320
+ }
321
+ };
322
+
323
+ /* DELETE /api/endpoints - Delete an endpoint */
324
+ export const DELETE = async (req: NextRequest) => {
325
+ try {
326
+ const { method, path }: { method: HttpMethods; path: string } =
327
+ await req.json();
328
+
329
+ /* Check if required fields are present */
330
+ if (!method || !path) {
331
+ return new NextResponse(
332
+ JSON.stringify({
333
+ error: "Missing Required Fields",
334
+ }),
335
+ {
336
+ status: 400,
337
+ }
338
+ );
339
+ }
340
+
341
+ const port = process.env.PORT || "3000";
342
+ const fapiStorageDirectory = getStorageDirectory();
343
+ const fapiStorageFilePathPerPort = getFapiStorageFilePathPerPort(
344
+ fapiStorageDirectory,
345
+ port
346
+ );
347
+
348
+ /* Check if port is valid */
349
+ if (!port?.trim()) {
350
+ console.warn("PORT_NOT_VALID_CANNOT_DELETE_ENDPOINT");
351
+ return new NextResponse(
352
+ JSON.stringify({
353
+ error: "Invalid Port Configuration",
354
+ }),
355
+ {
356
+ status: 500,
357
+ }
358
+ );
359
+ }
360
+
361
+ /* Read existing storage */
362
+ let storage: FapiStorage;
363
+ try {
364
+ const fileContent = await fs.readFile(
365
+ fapiStorageFilePathPerPort,
366
+ "utf-8"
367
+ );
368
+ storage = JSON.parse(fileContent);
369
+ } catch {
370
+ return new NextResponse(
371
+ JSON.stringify({
372
+ error: "Storage File Not Found",
373
+ }),
374
+ {
375
+ status: 404,
376
+ }
377
+ );
378
+ }
379
+
380
+ /* Generate endpoint key and check if endpoint exists */
381
+ const endpointKey = createEndpointKey(method, path);
382
+
383
+ if (!storage.endpoints[endpointKey]) {
384
+ return new NextResponse(
385
+ JSON.stringify({
386
+ error: "Endpoint Not Found",
387
+ }),
388
+ {
389
+ status: 404,
390
+ }
391
+ );
392
+ }
393
+
394
+ /* Delete the endpoint from storage */
395
+ delete storage.endpoints[endpointKey];
396
+
397
+ /* Update metadata */
398
+ storage.metadata = {
399
+ lastUpdated: new Date().toISOString(),
400
+ totalEndpoints: Object.keys(storage.endpoints).length,
401
+ };
402
+
403
+ /* Write updated storage back to file */
404
+ await fs.writeFile(
405
+ fapiStorageFilePathPerPort,
406
+ JSON.stringify(storage, null, 2)
407
+ );
408
+
409
+ return new NextResponse(
410
+ JSON.stringify({
411
+ success: true,
412
+ message: "Endpoint Successfully Deleted",
413
+ deletedEndpoint: { method, path },
414
+ }),
415
+ {
416
+ status: 200,
417
+ }
418
+ );
419
+ } catch (err) {
420
+ console.error("ERROR_DELETING_ENDPOINT: ", err);
421
+ return new NextResponse(
422
+ JSON.stringify({
423
+ error: "Internal Server Error",
424
+ }),
425
+ {
426
+ status: 500,
427
+ }
428
+ );
429
+ }
430
+ };
@@ -134,7 +134,7 @@ const FapiSimulatorPage = () => {
134
134
  const isAtLimit = currentEndpointCount >= FAPI_LIMITS.MAX_ENDPOINTS;
135
135
 
136
136
  return (
137
- <div className="min-h-screen relative p-6 overflow-hidden">
137
+ <div className="min-h-screen relative">
138
138
  <AnimatedBackground />
139
139
 
140
140
  {/* Hidden file input for import */}
@@ -146,12 +146,12 @@ const FapiSimulatorPage = () => {
146
146
  style={{ display: "none" }}
147
147
  />
148
148
 
149
- <div
150
- className="mx-auto"
151
- style={{ maxWidth: UI_LIMITS.UI_CONTAINER_MAX_WIDTH }}
152
- >
153
- {/* Header Section - Title and Action Buttons*/}
154
- <div className="flex flex-col sm:flex-row justify-between items-center mb-8 gap-4">
149
+ {/* Header Section - Title and Action Buttons (sticky) */}
150
+ <div className="sticky top-0 z-10 backdrop-blur-md bg-black/30 px-6 py-4" style={{ maskImage: "linear-gradient(to bottom, black 70%, transparent 100%)", WebkitMaskImage: "linear-gradient(to bottom, black 70%, transparent 100%)" }}>
151
+ <div
152
+ className="mx-auto flex flex-col sm:flex-row justify-between items-center gap-4"
153
+ style={{ maxWidth: UI_LIMITS.UI_CONTAINER_MAX_WIDTH }}
154
+ >
155
155
  <AppName logoWidth={134} logoHeight={48} />
156
156
  <div className="flex items-center gap-2">
157
157
  {/* Create New FAPI Button */}
@@ -185,6 +185,14 @@ const FapiSimulatorPage = () => {
185
185
  />
186
186
  </div>
187
187
  </div>
188
+ </div>
189
+
190
+ {/* Scrollable content */}
191
+ <div className="px-6 pb-6">
192
+ <div
193
+ className="mx-auto"
194
+ style={{ maxWidth: UI_LIMITS.UI_CONTAINER_MAX_WIDTH }}
195
+ >
188
196
 
189
197
  {/* Project Name and FAPI Counter Section */}
190
198
  <div className="mb-8 flex flex-col lg:flex-row justify-between items-start lg:items-center gap-4">
@@ -234,6 +242,7 @@ const FapiSimulatorPage = () => {
234
242
  ></FapiSimulationCard>
235
243
  ))}
236
244
  </div>
245
+ </div>
237
246
  </div>
238
247
 
239
248
  <EndpointModal
@@ -4,7 +4,7 @@ import type { Metadata } from "next";
4
4
  import StoreProvider from "./storeProvider";
5
5
 
6
6
  export const metadata: Metadata = {
7
- title: "FAPI - Fake APIs on the fly",
7
+ title: "FAPI",
8
8
  description: "Generated by create next app",
9
9
  };
10
10
 
@@ -36,7 +36,7 @@ const Editor = ({ value, onChange }: EditorProps) => {
36
36
  onChange={onChange}
37
37
  height="100%"
38
38
  options={EDITOR_OPTIONS}
39
- onMount={(editor, monaco) => {
39
+ onMount={(editor) => {
40
40
  editor.layout();
41
41
  }}
42
42
  />
@@ -17,6 +17,7 @@ const Modal = ({
17
17
  <MuiModal
18
18
  open={isModalOpen}
19
19
  onClose={onClose}
20
+ disableEnforceFocus
20
21
  slots={{ backdrop: Backdrop }}
21
22
  slotProps={{
22
23
  backdrop: {
@@ -1,8 +1,8 @@
1
- export const CREATE_API_ENDPOINT_API_PATH = "/api/create-endpoint";
2
- export const DELETE_API_ENDPOINT_API_PATH = "/api/delete-endpoint";
3
- export const UPDATE_ENDPOINT_API_PATH = "/api/update-endpoint";
4
- export const FAPI_HEALTH_CHECK_API_PATH = "/api/fapi-health-check";
5
- export const GET_ENDPOINTS_API_PATH = "/api/get-endpoints";
6
- export const IMPORT_ENDPOINTS_API_PATH = "/api/import-endpoints";
7
- export const GET_ENDPOINT_RESPONSE_API_PATH = "/api/get-endpoint-response";
8
- export const EXPORT_ENDPOINTS_API_PATH = "/api/export-endpoints";
1
+ export const CREATE_API_ENDPOINT_API_PATH = "/api/endpoints";
2
+ export const DELETE_API_ENDPOINT_API_PATH = "/api/endpoints";
3
+ export const UPDATE_ENDPOINT_API_PATH = "/api/endpoints";
4
+ export const FAPI_HEALTH_CHECK_API_PATH = "/api/health";
5
+ export const GET_ENDPOINTS_API_PATH = "/api/endpoints";
6
+ export const IMPORT_ENDPOINTS_API_PATH = "/api/endpoints/import";
7
+ export const GET_ENDPOINT_RESPONSE_API_PATH = "/api/endpoints/response";
8
+ export const EXPORT_ENDPOINTS_API_PATH = "/api/endpoints/export";
@@ -7,7 +7,7 @@ export const deleteEndpoint = async (
7
7
  ): Promise<{ success: boolean; error?: string }> => {
8
8
  try {
9
9
  const deleteEndpointResponse = await fetch(DELETE_API_ENDPOINT_API_PATH, {
10
- method: "POST",
10
+ method: "DELETE",
11
11
  headers: {
12
12
  "Content-Type": "application/json",
13
13
  },
@@ -14,7 +14,7 @@ export const updateFapiEndpoint = async (
14
14
  ): Promise<{ success: boolean; error?: string }> => {
15
15
  try {
16
16
  const updateEndpointResponse = await fetch(UPDATE_ENDPOINT_API_PATH, {
17
- method: "POST",
17
+ method: "PUT",
18
18
  headers: {
19
19
  "Content-Type": "application/json",
20
20
  },