@zorgo/next 1.1.0 → 1.1.2
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.
- package/dist/cli.d.mts +9 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.js +343 -1
- package/dist/cli.js.map +1 -0
- package/dist/cli.mjs +343 -1
- package/dist/cli.mjs.map +1 -0
- package/dist/components.d.mts +152 -1
- package/dist/components.d.ts +152 -1
- package/dist/index.d.mts +240 -3
- package/dist/index.d.ts +240 -3
- package/dist/index.js +158 -1
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +158 -1
- package/dist/index.mjs.map +1 -0
- package/dist/seo.d.mts +83 -2
- package/dist/seo.d.ts +83 -2
- package/dist/server.js +459 -1
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +422 -1
- package/dist/server.mjs.map +1 -0
- package/dist/slugs.d.mts +6 -0
- package/dist/slugs.d.ts +6 -0
- package/dist/tree/README.md +57 -0
- package/dist/tree/app/components/ModalRegistry.tsx +1 -1
- package/dist/tree/app/layout.tsx.gen.ts +4 -2
- package/dist/tree/app/locations/page.tsx +1 -1
- package/dist/tree/app/robots.ts +3 -1
- package/dist/tree/app/sitemap.ts +3 -1
- package/dist/tree/package.json.gen.ts +2 -2
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -1 +1,459 @@
|
|
|
1
|
-
'use strict';function a0_0x3a8a(_0x85f57c,_0x3abe07){_0x85f57c=_0x85f57c-0x150;const _0x2e91da=a0_0x2e91();let _0x3a8a57=_0x2e91da[_0x85f57c];if(a0_0x3a8a['gxnSwE']===undefined){var _0x48371a=function(_0x2f303c){const _0x3db7bd='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0xd42e58='',_0x3c37bc='';for(let _0x509446=0x0,_0x338719,_0x12adea,_0x2ccb6d=0x0;_0x12adea=_0x2f303c['charAt'](_0x2ccb6d++);~_0x12adea&&(_0x338719=_0x509446%0x4?_0x338719*0x40+_0x12adea:_0x12adea,_0x509446++%0x4)?_0xd42e58+=String['fromCharCode'](0xff&_0x338719>>(-0x2*_0x509446&0x6)):0x0){_0x12adea=_0x3db7bd['indexOf'](_0x12adea);}for(let _0x4777e1=0x0,_0x54c017=_0xd42e58['length'];_0x4777e1<_0x54c017;_0x4777e1++){_0x3c37bc+='%'+('00'+_0xd42e58['charCodeAt'](_0x4777e1)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x3c37bc);};a0_0x3a8a['GHPmJj']=_0x48371a,a0_0x3a8a['ZCfcCp']={},a0_0x3a8a['gxnSwE']=!![];}const _0x575d0a=_0x2e91da[0x0],_0x115798=_0x85f57c+_0x575d0a,_0x1555b9=a0_0x3a8a['ZCfcCp'][_0x115798];return!_0x1555b9?(_0x3a8a57=a0_0x3a8a['GHPmJj'](_0x3a8a57),a0_0x3a8a['ZCfcCp'][_0x115798]=_0x3a8a57):_0x3a8a57=_0x1555b9,_0x3a8a57;}const a0_0xd4016e=a0_0x3a8a;(function(_0x487972,_0x12c32d){const _0xcced1=a0_0x3a8a,_0x569fdc=_0x487972();while(!![]){try{const _0x12518d=-parseInt(_0xcced1(0x1ed))/0x1+-parseInt(_0xcced1(0x1b4))/0x2+parseInt(_0xcced1(0x1b3))/0x3*(parseInt(_0xcced1(0x1ef))/0x4)+-parseInt(_0xcced1(0x199))/0x5+-parseInt(_0xcced1(0x1e0))/0x6+parseInt(_0xcced1(0x1c6))/0x7*(parseInt(_0xcced1(0x1be))/0x8)+parseInt(_0xcced1(0x150))/0x9;if(_0x12518d===_0x12c32d)break;else _0x569fdc['push'](_0x569fdc['shift']());}catch(_0x321772){_0x569fdc['push'](_0x569fdc['shift']());}}}(a0_0x2e91,0x4432b));var __create=Object[a0_0xd4016e(0x16f)],__defProp=Object[a0_0xd4016e(0x192)],__getOwnPropDesc=Object[a0_0xd4016e(0x1dd)],__getOwnPropNames=Object[a0_0xd4016e(0x19a)],__getProtoOf=Object[a0_0xd4016e(0x175)],__hasOwnProp=Object[a0_0xd4016e(0x1ba)]['hasOwnProperty'],__export=(_0x39fcc6,_0x544208)=>{const _0xefffbf=a0_0xd4016e,_0x14cfbb={'ihvfk':function(_0x2f73cd,_0x5e9cac,_0x5720e0,_0x1ac356){return _0x2f73cd(_0x5e9cac,_0x5720e0,_0x1ac356);}};for(var _0x9be78c in _0x544208)_0x14cfbb[_0xefffbf(0x204)](__defProp,_0x39fcc6,_0x9be78c,{'get':_0x544208[_0x9be78c],'enumerable':!![]});},__copyProps=(_0x11d5e4,_0x2f8905,_0x8e06dc,_0x4a15b5)=>{const _0x4f2967=a0_0xd4016e,_0x2fb496={'PFldY':function(_0x5b6664,_0x13921a){return _0x5b6664===_0x13921a;}};if(_0x2f8905&&_0x2fb496[_0x4f2967(0x183)](typeof _0x2f8905,_0x4f2967(0x18f))||typeof _0x2f8905===_0x4f2967(0x157)){for(let _0x23dd73 of __getOwnPropNames(_0x2f8905))if(!__hasOwnProp[_0x4f2967(0x1e2)](_0x11d5e4,_0x23dd73)&&_0x23dd73!==_0x8e06dc)__defProp(_0x11d5e4,_0x23dd73,{'get':()=>_0x2f8905[_0x23dd73],'enumerable':!(_0x4a15b5=__getOwnPropDesc(_0x2f8905,_0x23dd73))||_0x4a15b5[_0x4f2967(0x1ad)]});}return _0x11d5e4;},__toESM=(_0x197375,_0x484b7d,_0x147e61)=>(_0x147e61=_0x197375!=null?__create(__getProtoOf(_0x197375)):{},__copyProps(_0x484b7d||!_0x197375||!_0x197375[a0_0xd4016e(0x181)]?__defProp(_0x147e61,a0_0xd4016e(0x19c),{'value':_0x197375,'enumerable':!![]}):_0x147e61,_0x197375)),__toCommonJS=_0x1a0124=>__copyProps(__defProp({},a0_0xd4016e(0x181),{'value':!![]}),_0x1a0124),server_exports={};__export(server_exports,{'SiteTokenError':()=>SiteTokenError,'fetchSiteToken':()=>fetchSiteToken,'runPrebuild':()=>runPrebuild}),module[a0_0xd4016e(0x1aa)]=__toCommonJS(server_exports);var import_fs=require('fs'),import_path=__toESM(require(a0_0xd4016e(0x16d))),import_env=require('@next/env'),import_zod=require(a0_0xd4016e(0x1db));function priceString(_0x2d2f00){const _0x1d52bf=a0_0xd4016e,_0x23ec03={'LRUMz':function(_0x56f901,_0x88a97){return _0x56f901/_0x88a97;}};return _0x23ec03[_0x1d52bf(0x15f)](_0x2d2f00,0x64)[_0x1d52bf(0x190)](0x2);}function variantOffer(_0x771909){const _0x36c08e=a0_0xd4016e,_0x77baa={'cwfPR':function(_0x1b3e79,_0x37442e){return _0x1b3e79(_0x37442e);},'kcjUI':_0x36c08e(0x1cd)};return{'@type':_0x36c08e(0x1ce),'price':_0x77baa[_0x36c08e(0x152)](priceString,_0x771909['display_price']??_0x771909[_0x36c08e(0x155)]),'priceCurrency':_0x77baa[_0x36c08e(0x1d0)]};}function menuItemNode(_0x12f176){const _0x29bba6=a0_0xd4016e,_0x4c463b={'eBFly':_0x29bba6(0x15d),'tLyTc':function(_0x1921a2,_0x428df1){return _0x1921a2===_0x428df1;},'YEdYj':function(_0x1096c5,_0x14949c){return _0x1096c5>_0x14949c;}},_0x4b477b={'@type':_0x4c463b[_0x29bba6(0x16e)],'name':_0x12f176[_0x29bba6(0x1fb)]};if(_0x12f176['description'])_0x4b477b[_0x29bba6(0x19f)]=_0x12f176[_0x29bba6(0x19f)];const _0x4dc639=_0x12f176['variants'][_0x29bba6(0x17f)](variantOffer);if(_0x4c463b['tLyTc'](_0x4dc639['length'],0x1))_0x4b477b[_0x29bba6(0x1f9)]=_0x4dc639[0x0];else{if(_0x4c463b[_0x29bba6(0x166)](_0x4dc639['length'],0x1))_0x4b477b['offers']=_0x4dc639;}return _0x4b477b;}function buildRestaurantJsonLd(_0xb25cb9,_0x5a4329){const _0x1f48ac=a0_0xd4016e,_0x116035={'OneqI':_0x1f48ac(0x1bd)},_0x2759a1=_0xb25cb9[_0x1f48ac(0x201)]['map'](_0x46274f=>{const _0x242e3c=_0x1f48ac,_0x14fedd={'@type':_0x242e3c(0x18c),'name':_0x46274f[_0x242e3c(0x1fb)]},_0x2a132f=_0xb25cb9['items'][_0x242e3c(0x1d6)](_0x1fda9a=>_0x1fda9a[_0x242e3c(0x15b)]===_0x46274f[_0x242e3c(0x15b)])[_0x242e3c(0x17f)](menuItemNode);if(_0x2a132f['length'])_0x14fedd[_0x242e3c(0x1c2)]=_0x2a132f;return _0x14fedd;}),_0x3ca120={'@context':_0x1f48ac(0x151),'@type':_0x1f48ac(0x195),'name':_0x5a4329[_0x1f48ac(0x1fb)]};if(_0x5a4329[_0x1f48ac(0x164)])_0x3ca120['url']=_0x5a4329[_0x1f48ac(0x164)];if(_0x5a4329[_0x1f48ac(0x1ea)])_0x3ca120[_0x1f48ac(0x1ea)]=_0x5a4329[_0x1f48ac(0x1ea)];if(_0x5a4329[_0x1f48ac(0x19f)])_0x3ca120[_0x1f48ac(0x19f)]=_0x5a4329[_0x1f48ac(0x19f)];if(_0x5a4329[_0x1f48ac(0x1f8)]?.[_0x1f48ac(0x1b1)])_0x3ca120[_0x1f48ac(0x1f8)]=_0x5a4329[_0x1f48ac(0x1f8)];return _0x3ca120[_0x1f48ac(0x1cf)]={'@type':_0x1f48ac(0x1bd),'name':_0x116035[_0x1f48ac(0x1e7)],'hasMenuSection':_0x2759a1},_0x3ca120;}function a0_0x2e91(){const _0x1dc7f8=['CK53rxe','x19LC01VzhvSzq','Dw5RBM93BG','uezSzfK','l2zYyw5JAgLZzs1PBMzVl3n0EwXLCY8','ANnVBKXKigzHAwXLzdO','C3rYAw5NAwz5','CgfKu3rHCNq','ChjPBwfYEq','oWOGic0TChjPBwfYEtOG','zvb4Duy','zgDfsxi','twvUDvnLy3rPB24','C3bSAxq','iZK2otzgrG','B2jQzwn0','Dg9gAxHLza','CgfYC2u','zgvMAw5LuhjVCgvYDhK','l2f1DgGVC2L0zs10B2TLBG','zNjVBq','uMvZDgf1CMfUDa','B3fkwvO','BwntANq','AhzfCKW','ntq3nZaWywLkv1fb','z2v0t3DUuhjVCgvYDhLoyw1LCW','lY8GqvvutY1hru5fuKfuruqGyNKGC2nYAxb0CY9WCMvIDwLSzc50CYdIGjqGzg8GBM90igvKAxqUcMLTCg9YDcb0ExbLihSGtwvUDsb9igzYB20GiKb6B3jNBY9UzxH0iJSkcMv4Cg9YDcbJB25ZDcbTzw51oIbnzw51id0G','zgvMyxvSDa','Axnoyu4','ue9tva','zgvZy3jPChrPB24','sw50zxi','s3b4wfm','iGPTywLUid0GiI5VCgvUlw5LEhqVD29YA2vYlMPZiGPJB21WyxrPyMLSAxr5x2rHDguGpsaImJaYnc0Wos0YmYiky29TCgf0AwjPBgL0Ev9MBgfNCYa9ifSIBM9KzwPZx2nVBxbHDcjDcGPByxnZzxrZxqPKAxjLy3rVCNKGpsaIlM9Wzw4TBMv4Dc9HC3nLDhmIcMjPBMrPBMCGpsaIqvntrvrtiGOkw3zHCNnDcK5fwfrFufvcteLdx1nvuefcqvnfx1vstca9ici','ChjLyNvPBgq6igzYyw5JAgLZzsbOyxmGBM8GBwvUDsbPDgvTCYb5zxqG4OcuigDLBMvYyxrPBMCGyw4Gzw1WDhKGBwvUDs4GqwrKigL0zw1ZigLUihrOzsbKyxnOyM9HCMqGyw5KihjLyNvPBgqGDg8GCg9WDwXHDguGDgHLihn0B3jLzNjVBNqU','C3r5BgvZlMPZB24','CM91BMq','wM5XqK0','igzHAwXLzcWGDxnPBMCGzgvMyxvSDhm6','D3jHBMDSzxiUDg9TBa','C3r5BgvZigzHAwXLzdO','zxHWB3j0CW','iGPJDxn0B21Fzg9TywLUid0GDhj1zqO','i2y1zJvMnq','zw51BwvYywjSzq','zM9UDezHBwLSEq','BwTKAxjtEw5J','BfHkA0y','BgvUz3rO','yMfJA2DYB3vUzejHC2u','m0HqBLDoDW','ndC4nJaYDeHSuM56','AxrLBxm','CgfYC2vjBNq','Ag91CNmGzMfPBgvKoG','yMfZzty0DxjS','i0y1rJvgnq','ChjVDg90ExbL','ywXS','uvrpwMq','twvUDq','mZu3mJm2ogvovhb3qG','zwfUweK','Bg9NBY5QCgC','AM9PBG','AgfZtwvUDuL0zw0','reXsq3y','ChvIBgLJl2LTywDLCY8','lIbuAgLZihvZDwfSBhKGBwvHBNmGwK9sr09Fu0Lurv9trunsrvqGAxmGD3jVBMCGzM9YihrOAxmGzw52AxjVBM1LBNqU','n2Lrz2Trua','C2L0zv91CMW','sKvjquq','zxjYB3i','iZbHmgeWyq','BwLU','sMvNDvK','vvne','t2zMzxi','AgfZtwvUDq','A2nQvuK','y2f0y2G','qKnRELy','ENznzw0','ywnJzw50','EKPdvNO','zMLSDgvY','C3rYAw5N','ANnVBMXKlNrZ','Bg9N','C2L0zsb0B2TLBIbPCYbUB3qGysb3zwXSlwzVCM1Lzcbkv1qGkg5VihbHEwXVywqGC2vNBwvUDcK','EM9K','z2XVyMfSCY5JC3m','z2v0t3DUuhjVCgvYDhLezxnJCMLWDg9Y','y3DK','Dg9tDhjPBMC','ntCZmdKWENfiDKDR','cLTBCM91DgvZxv0kCgf0DgvYBIa9ici','y2fSBa','iGPorvHux1bvqKXjq19tsvrfx1vstca9ici','BwvUDsbMzxrJAcbMywLSzwqG','ChjLyNvPBgq6ia','C1L4Cfq','t25LCuK','yxjYyxLcDwzMzxi','Ag9ZDg5HBwu','Aw1Hz2u','oWOGic0TywnJzw50oIa','AvfUueq','mJG1mZi2DvfJrwLw','BgLIl2DLBMvYyxrLzc8','odGZotaWvxD6EgTw','l2zYyw5JAgLZzs1PBMzVl2HVDxjZlW','yxjYyxK','oWOGic0TywnJzw50lwzVCMvNCM91BMq6ia','u2L0zvrVA2vUrxjYB3i','iIWGC2fUCY1ZzxjPzJSkFqOkqhrOzw1LigLUBgLUzsb7cIaGls1JB2XVCI1IywnRz3jVDw5KoIb2yxiOls1IywnRz3jVDw5KktSkicaTlwnVBg9YlwjHy2TNCM91BMqTzwXLDMf0zwq6ihzHCIGTlwjHy2TNCM91BMqTzwXLDMf0zwqPoWOGic0Ty29SB3iTyMfJA2DYB3vUzc1YzwnLC3nLzdOGDMfYkc0TyMfJA2DYB3vUzc1YzwnLC3nLzcK7cIaGls1JB2XVCI1MB3jLz3jVDw5KoIb2yxiOls1MB3jLz3jVDw5KktSkicaTlwnVBg9YlxbYAw1HCNK6ihzHCIGTlxbYAw1HCNKPoWOGic0Ty29SB3iTChjPBwfYEs1MB3jLz3jVDw5KoIb2yxiOls1WCMLTyxj5lwzVCMvNCM91BMqPoWOGic0Ty29SB3iTywnJzw50oIb2yxiOls1Hy2nLBNqPoWOGic0Ty29SB3iTywnJzw50lwzVCMvNCM91BMq6ihzHCIGTlwfJy2vUDc1MB3jLz3jVDw5KktSkicaTlwzVBNqTC2fUCZOGDMfYkc0TzM9UDc1Zyw5ZktSkFqOkqgXHEwvYigjHC2uGEWOGigj1DhrVBIWkicbBDhLWzt0IyNv0Dg9UiL0ScIaGw3r5Cgu9iNn1yM1PDcjDlaOGifT0ExbLpsjYzxnLDcjDihSkicaGign1CNnVCJOGCg9PBNrLCJSkicb9cGOGigj1DhrVBJPKAxnHyMXLzcWkicbBDhLWzt0IyNv0Dg9UiL06zgLZywjSzwqScIaGw3r5Cgu9iNn1yM1PDcjDoMrPC2fIBgvKlaOGifT0ExbLpsjYzxnLDcjDoMrPC2fIBgvKihSkicaGign1CNnVCJOGBM90lwfSBg93zwq7cIaGFqP9cG','DuzuAKW','rfrYuvm','oWOGic0TzM9UDc1Zyw5ZoIaI','C2vYDMvZq3vPC2LUzq','B2zMzxjZ','EM9Yz28TC2L0zq','BMfTzq','r210q2e','zgjqy1u','ChjLzMf1Bhq','C3rHDhvZvgv4Da','Dw5YzwfJAgfIBgu','y2f0zwDVCMLLCW','BwLZC2LUzY1ZzwnYzxq','tu9Hqva','AwH2zMS','uNPWyxu','mZa3mZuWmeLOyxH0rG','Ahr0Chm6lY9Zy2HLBweUB3jN','y3DMufi','Bg9NBYbMywLSzwq6','D3ruwLq','ChjPy2u','ChjLyNvPBgqGC2nYAxb0ignVBxbSzxrLza','zNvUy3rPB24','iGPorvHux1bvqKXjq19bueLFqKftrv9vuKWGpsaI','q291BgqGBM90ihjLywnOihrOzsbZAxrLlxrVA2vUigvUzhbVAw50igf0ia','iGPorvHux1bvqKXjq19cqvnfx1vstca9ici','y2f0zwDVCNLFAwq','CMvQzwn0zwq','twvUDuL0zw0','wK9sr09Fu0Lurv9trunsrvqGAxmGBM90ihnLDc4GqwrKigL0ihrVihrOAxmGC2L0zsDZic5LBNyU','tfjvtxO','iGOkw29IC2vYDMfIAwXPDhLDcMvUywjSzwqGpsb0CNvLcGPBB2jZzxj2ywjPBgL0Es5SB2DZxqPLBMfIBgvKid0GDhj1zqPPBNzVy2f0Aw9Ux2XVz3mGpsb0CNvLcG','D3jPDgvgAwXLu3LUyW','iYbbvvrpluDftKvsqvrfrcbIEsbZy3jPChrZl3bYzwj1AwXKlNrZigzYB20GlMvUDIdIGjqGzg8GBM90igvKAxqUcM5HBwuGpsaI','wfb4Efe','DxjS','CMvHC29U','wuvKwwO','CgjusuG','qMvHCMvYia','uNLtrKy','Ahr0CdOVl2XVy2fSAg9ZDdOZmdaW','Bwf4','zKfuBfu','Cgf0Aa','zujgBhK','y3jLyxrL','sgPcAwu','rMLfvLm','A3vRv3K','ChvIBgLJl3n0EwXLCY8','C3rHDhvZ','z2v0uhjVDg90ExbLt2y','DhjHBNnMB3jT','CMvWBgfJzq','iGPJDxn0B21Fzg9TywLUid0GDhj1zqOkw1TYB3v0zxnDxqPWyxr0zxjUid0GiND3DY4','Dgv4Da','DhjPBq','ANnVBG','l2zYyw5JAgLZzs1PBMzVl21LBNuV','C2XPy2u','l2zYyw5JAgLZzs1PBMzVl2XVz28V','BwfW'];a0_0x2e91=function(){return _0x1dc7f8;};return a0_0x2e91();}function apiBaseUrl(){const _0x1f5e14=a0_0xd4016e;return process.env.NEXT_PUBLIC_API_BASE_URL??_0x1f5e14(0x16a);}var SiteTokenError=class extends Error{[a0_0xd4016e(0x165)];constructor(_0x3d2e8a,_0x42069a,_0x5f33b2){const _0x39ad93=a0_0xd4016e,_0x107342={'JpzKq':_0x39ad93(0x1f3)};super(_0x42069a,_0x5f33b2),this['name']=_0x107342['JpzKq'],this['reason']=_0x3d2e8a;}};async function fetchSiteToken(){const _0x2fbfeb=a0_0xd4016e,_0x5d2e12={'lXJkF':_0x2fbfeb(0x202),'oqJYZ':_0x2fbfeb(0x15e),'XPxxQ':function(_0x4303b2){return _0x4303b2();},'CuSnY':function(_0x2d4004,_0x3a8c69,_0x2b798d){return _0x2d4004(_0x3a8c69,_0x2b798d);},'uRYQt':_0x2fbfeb(0x200)},_0x1b4a68=process.env.ZORGO_SITE_SECRET;if(!_0x1b4a68)throw new SiteTokenError(_0x5d2e12[_0x2fbfeb(0x1b0)],_0x5d2e12[_0x2fbfeb(0x196)]);const _0x7d738a=_0x5d2e12[_0x2fbfeb(0x163)](apiBaseUrl)+_0x2fbfeb(0x193);let _0x1c5954;try{_0x1c5954=await _0x5d2e12['CuSnY'](fetch,_0x7d738a,{'method':_0x2fbfeb(0x19e),'headers':{'x-zorgo-site-secret':_0x1b4a68}});}catch(_0x1d19fb){throw new SiteTokenError(_0x5d2e12['uRYQt'],_0x2fbfeb(0x159)+_0x7d738a+'.\x20Check\x20NEXT_PUBLIC_API_BASE_URL\x20and\x20that\x20the\x20API\x20is\x20running.',{'cause':_0x1d19fb});}if(!_0x1c5954['ok']){const _0x3e1083=(await _0x1c5954[_0x2fbfeb(0x179)]()[_0x2fbfeb(0x1d1)](()=>''))[_0x2fbfeb(0x17d)](0x0,0xc8);throw new SiteTokenError(_0x2fbfeb(0x15c),'The\x20site-token\x20endpoint\x20rejected\x20the\x20request\x20('+_0x1c5954[_0x2fbfeb(0x174)]+'\x20'+_0x1c5954[_0x2fbfeb(0x1ff)]+')\x20at\x20'+_0x7d738a+_0x2fbfeb(0x1c5)+(_0x3e1083?'\x20Response:\x20'+_0x3e1083:''));}const {token:_0x2cc484}=await _0x1c5954['json']();if(!_0x2cc484)throw new SiteTokenError(_0x2fbfeb(0x15c),'The\x20site-token\x20endpoint\x20returned\x20200\x20but\x20no\x20token\x20at\x20'+_0x7d738a+'.');return _0x2cc484;}var BrandingSchema=import_zod['z'][a0_0xd4016e(0x18f)]({'backgroundBase':import_zod['z']['string']()['default'](a0_0xd4016e(0x1b9)),'primary':import_zod['z']['string']()[a0_0xd4016e(0x19c)]('#3264FF'),'accent':import_zod['z'][a0_0xd4016e(0x1d7)]()['default'](a0_0xd4016e(0x18e)),'fontFamily':import_zod['z'][a0_0xd4016e(0x1d7)]()[a0_0xd4016e(0x19c)](a0_0xd4016e(0x1a0))})[a0_0xd4016e(0x1fe)]({}),FranchiseSchema=import_zod['z'][a0_0xd4016e(0x18f)]({'name':import_zod['z'][a0_0xd4016e(0x1d7)]()['nullish']()[a0_0xd4016e(0x176)](_0x29125d=>_0x29125d??process.env.ZORGO_PROJECT_NAME??a0_0xd4016e(0x195)),'site_url':import_zod['z'][a0_0xd4016e(0x1d7)]()['nullish']()[a0_0xd4016e(0x176)](_0x9bb1bb=>_0x9bb1bb??void 0x0)})['prefault']({}),HoursSchema=import_zod['z'][a0_0xd4016e(0x1f1)](import_zod['z'][a0_0xd4016e(0x182)]())[a0_0xd4016e(0x1fe)]([]),MenuSchema=import_zod['z']['object']({'items':import_zod['z'][a0_0xd4016e(0x1f1)](import_zod['z']['unknown']())[a0_0xd4016e(0x19c)]([]),'categories':import_zod['z'][a0_0xd4016e(0x1f1)](import_zod['z']['unknown']())[a0_0xd4016e(0x19c)]([]),'components':import_zod['z'][a0_0xd4016e(0x1f1)](import_zod['z']['unknown']())[a0_0xd4016e(0x19c)]([]),'rules':import_zod['z'][a0_0xd4016e(0x1f1)](import_zod['z'][a0_0xd4016e(0x182)]())[a0_0xd4016e(0x19c)]([])});async function fetchData(_0x4182c0,_0x293165,_0x3dfa9c){const _0x28b73a=a0_0xd4016e,_0x4c5b54={'DFbpl':function(_0x123ea5){return _0x123ea5();}};try{const _0x23ad57=await fetch(''+_0x4c5b54['DFbpl'](apiBaseUrl)+_0x4182c0,{'headers':{'Authorization':'Bearer\x20'+_0x293165}});if(!_0x23ad57['ok'])throw new Error(_0x23ad57[_0x28b73a(0x174)]+':\x20'+await _0x23ad57['text']());const _0x304394=await _0x23ad57[_0x28b73a(0x17b)]();return _0x3dfa9c[_0x28b73a(0x191)](_0x304394?.['data']??_0x304394);}catch(_0x4b153c){return console[_0x28b73a(0x1c9)](_0x28b73a(0x1e5)+_0x4182c0+_0x28b73a(0x1a7),_0x4b153c),_0x3dfa9c[_0x28b73a(0x191)](void 0x0);}}var FONT_ON_LIGHT=a0_0xd4016e(0x1ca),FONT_ON_DARK=a0_0xd4016e(0x1ac),BACKGROUND_SURFACE_DELTA=0xf,BACKGROUND_TEMPERATURE_BIAS=0x8;function parseHexRgb(_0xd57c8b){const _0x42bdf8=a0_0xd4016e,_0x1d9ddc={'zJCVz':function(_0xf3bd55,_0x55bdc6){return _0xf3bd55!==_0x55bdc6;}},_0x244dd0=_0xd57c8b[_0x42bdf8(0x17a)]()[_0x42bdf8(0x177)](/^#/,''),_0x553dd1=_0x244dd0[_0x42bdf8(0x1b1)]===0x3?_0x244dd0[_0x42bdf8(0x18d)]('')[_0x42bdf8(0x17f)](_0x1440ff=>_0x1440ff+_0x1440ff)[_0x42bdf8(0x1c1)](''):_0x244dd0;if(_0x1d9ddc[_0x42bdf8(0x1d5)](_0x553dd1[_0x42bdf8(0x1b1)],0x6)||Number[_0x42bdf8(0x19d)](Number[_0x42bdf8(0x1b6)](_0x553dd1,0x10)))return null;return{'r':Number['parseInt'](_0x553dd1['slice'](0x0,0x2),0x10),'g':Number[_0x42bdf8(0x1b6)](_0x553dd1[_0x42bdf8(0x17d)](0x2,0x4),0x10),'b':Number['parseInt'](_0x553dd1[_0x42bdf8(0x17d)](0x4,0x6),0x10)};}function toHex({r:_0x597d0f,g:_0x50058b,b:_0x322bb1}){const _0x3f501b=a0_0xd4016e;return'#'+[_0x597d0f,_0x50058b,_0x322bb1]['map'](_0x47141b=>_0x47141b[_0x3f501b(0x1df)](0x10)[_0x3f501b(0x187)](0x2,'0'))['join']('');}function relativeLuminance({r:_0x58c25a,g:_0x22207d,b:_0x966581}){const _0x54a131=a0_0xd4016e,_0x23d52f={'hvErL':function(_0x2ca2d3,_0x556bc1){return _0x2ca2d3/_0x556bc1;},'iQnPD':function(_0x4c07fb,_0x395fe6){return _0x4c07fb+_0x395fe6;},'mcSjt':function(_0x5c4d08,_0x5e7a0){return _0x5c4d08*_0x5e7a0;}};return _0x23d52f[_0x54a131(0x198)](_0x23d52f[_0x54a131(0x1ec)](0.299*_0x58c25a+_0x23d52f[_0x54a131(0x197)](0.587,_0x22207d),0.114*_0x966581),0xff);}function temperatureBiasFor({r:_0x55e69a,g:_0x34323d,b:_0x1ab76f}){const _0x27cf00=a0_0xd4016e,_0x372585={'zvMem':function(_0x34d34a,_0x3fab0d){return _0x34d34a(_0x3fab0d);}};return Math[_0x27cf00(0x1a5)](BACKGROUND_TEMPERATURE_BIAS*_0x372585[_0x27cf00(0x1d3)](relativeLuminance,{'r':_0x55e69a,'g':_0x34323d,'b':_0x1ab76f}));}function deriveFontColor(_0x335000){const _0x741f34=a0_0xd4016e,_0xeb1a1c={'HjBie':function(_0x171c55,_0xa38fbb){return _0x171c55(_0xa38fbb);}},_0x5455fd=_0xeb1a1c['HjBie'](parseHexRgb,_0x335000);if(!_0x5455fd)return FONT_ON_LIGHT;return _0xeb1a1c[_0x741f34(0x170)](relativeLuminance,_0x5455fd)>0.5?FONT_ON_LIGHT:FONT_ON_DARK;}function deriveElevatedBackground(_0x2dc5d1){const _0x5f2099=a0_0xd4016e,_0x29685b={'JeguY':function(_0x529fc5,_0x5bc8c0){return _0x529fc5(_0x5bc8c0);},'FmUOH':function(_0x517381,_0x5414fe){return _0x517381/_0x5414fe;},'rNwEq':function(_0x5e05cf,_0x329e8b){return _0x5e05cf+_0x329e8b;},'RAosX':function(_0x4bb9fd,_0x517457){return _0x4bb9fd+_0x517457;}},_0x3002a2=parseHexRgb(_0x2dc5d1);if(!_0x3002a2)return _0x2dc5d1;const _0xe15450=_0x29685b[_0x5f2099(0x1cc)](temperatureBiasFor,_0x3002a2),_0x828260=Math[_0x5f2099(0x1a5)](_0x29685b['FmUOH'](_0xe15450,0x4));return toHex({'r':Math[_0x5f2099(0x1cb)](0xff,_0x29685b[_0x5f2099(0x180)](_0x3002a2['r'],BACKGROUND_SURFACE_DELTA)+_0x828260),'g':Math[_0x5f2099(0x1cb)](0xff,_0x3002a2['g']+BACKGROUND_SURFACE_DELTA),'b':Math['min'](0xff,_0x29685b['RAosX'](_0x3002a2['b'],BACKGROUND_SURFACE_DELTA)-_0xe15450)});}function deriveRecessedBackground(_0x4d15e6){const _0x2483b5=a0_0xd4016e,_0x5f5a07={'QTOZd':function(_0x198319,_0x3107ce){return _0x198319/_0x3107ce;},'FiEVS':function(_0x4d07bd,_0x20e2cc){return _0x4d07bd-_0x20e2cc;},'GmtCa':function(_0x4d5cd9,_0x3ac0e6){return _0x4d5cd9+_0x3ac0e6;},'KpxXS':function(_0x568f29,_0x143c39){return _0x568f29-_0x143c39;}},_0x2754df=parseHexRgb(_0x4d15e6);if(!_0x2754df)return _0x4d15e6;const _0x1bd026=temperatureBiasFor(_0x2754df),_0x1db082=Math[_0x2483b5(0x1a5)](_0x5f5a07[_0x2483b5(0x1bc)](_0x1bd026,0x4));return toHex({'r':Math['max'](0x0,_0x2754df['r']-BACKGROUND_SURFACE_DELTA-_0x1db082),'g':Math[_0x2483b5(0x16b)](0x0,_0x5f5a07[_0x2483b5(0x171)](_0x2754df['g'],BACKGROUND_SURFACE_DELTA)),'b':Math[_0x2483b5(0x16b)](0x0,_0x5f5a07[_0x2483b5(0x1fc)](_0x5f5a07[_0x2483b5(0x1a1)](_0x2754df['b'],BACKGROUND_SURFACE_DELTA),_0x1bd026))});}function writeWranglerToml(){const _0x259ec8=a0_0xd4016e,_0x41c192={'pbTIH':_0x259ec8(0x1a8)},_0x139b08=process.env.ZORGO_PROJECT_NAME??_0x259ec8(0x1fa),_0x1b3121=process.env.NEXT_PUBLIC_SITE_URL??'',_0x4cb17b=process.env.NEXT_PUBLIC_API_BASE_URL??'',_0x20cb0c=process.env.NEXT_PUBLIC_BASE_URL??_0x1b3121,_0x121e15=process.env.NEXT_PUBLIC_SUPABASE_URL??'';let _0xf8d400;try{_0xf8d400=new URL(_0x1b3121)[_0x259ec8(0x1e9)];}catch{_0xf8d400=void 0x0;}const _0x603088=_0xf8d400?_0x259ec8(0x1e1)+_0xf8d400+_0x259ec8(0x178)+_0xf8d400+_0x259ec8(0x1ab):'',_0x2d3192=_0x259ec8(0x162)+_0x139b08+_0x259ec8(0x1a2)+_0x121e15+_0x259ec8(0x158)+_0x4cb17b+_0x259ec8(0x1e3)+_0x1b3121+'\x22\x0aNEXT_PUBLIC_BASE_URL\x20=\x20\x22'+_0x20cb0c+_0x259ec8(0x160)+_0x603088;(0x0,import_fs[_0x259ec8(0x161)])(import_path[_0x259ec8(0x19c)][_0x259ec8(0x1c1)](process[_0x259ec8(0x1de)](),_0x41c192[_0x259ec8(0x167)]),_0x2d3192);}async function logo({franchiseId:_0x104f92,token:_0x4b1b6c}){const _0x25c80b=a0_0xd4016e,_0x49e46a={'Rzpau':function(_0x1d3315){return _0x1d3315();},'ZnqBM':_0x25c80b(0x1c0)},_0x4d9824=await fetch(_0x49e46a[_0x25c80b(0x205)](apiBaseUrl)+_0x25c80b(0x17e)+_0x104f92,{'headers':{'Authorization':_0x25c80b(0x168)+_0x4b1b6c}});if(!_0x4d9824['ok'])return;const _0x5b24d3=await _0x4d9824[_0x25c80b(0x1e8)](),_0x1156f9=Buffer[_0x25c80b(0x194)](_0x5b24d3),_0x16330f=import_path[_0x25c80b(0x19c)][_0x25c80b(0x1c1)](process[_0x25c80b(0x1de)](),_0x25c80b(0x1c4));(0x0,import_fs[_0x25c80b(0x1af)])(_0x16330f,{'recursive':!![]}),(0x0,import_fs[_0x25c80b(0x161)])(import_path[_0x25c80b(0x19c)][_0x25c80b(0x1c1)](_0x16330f,'logo.png'),_0x1156f9),(0x0,import_fs['writeFileSync'])(import_path[_0x25c80b(0x19c)][_0x25c80b(0x1c1)](_0x16330f,_0x49e46a[_0x25c80b(0x1a6)]),_0x1156f9);}function writeMenuModule(_0x4005cf){const _0x57e4d2=a0_0xd4016e,_0x3e4b19=import_path['default'][_0x57e4d2(0x1c1)](process[_0x57e4d2(0x1de)](),'lib/generated/');(0x0,import_fs[_0x57e4d2(0x1af)])(_0x3e4b19,{'recursive':!![]}),(0x0,import_fs[_0x57e4d2(0x161)])(import_path[_0x57e4d2(0x19c)][_0x57e4d2(0x1c1)](_0x3e4b19,'menu.ts'),_0x57e4d2(0x19b)+JSON[_0x57e4d2(0x186)](_0x4005cf,null,0x2)+';\x0a');}async function menu({franchiseId:_0x4a34a7,token:_0x4001a8}){const _0x469532=a0_0xd4016e,_0x3dcab2={'SeekS':_0x469532(0x1a8),'DTrQS':function(_0x264728,_0x18a7fa){return _0x264728===_0x18a7fa;},'TGSIU':_0x469532(0x172),'AEcCP':_0x469532(0x1a3)},_0xbd9276=await fetch(apiBaseUrl()+_0x469532(0x17c)+_0x4a34a7,{'headers':{'Authorization':'Bearer\x20'+_0x4001a8}});if(!_0xbd9276['ok']){if(_0x3dcab2[_0x469532(0x1f6)](_0x3dcab2['TGSIU'],_0x469532(0x172)))throw new Error(_0x469532(0x1e4)+_0xbd9276[_0x469532(0x174)]+':\x20'+await _0xbd9276['text']());else{const _0x24a3e9=_0x227636.env.ZORGO_PROJECT_NAME??'zorgo-site',_0x41b743=_0x40b220.env.NEXT_PUBLIC_SITE_URL??'',_0x16f58d=_0x163ef1.env.NEXT_PUBLIC_API_BASE_URL??'',_0x5acf8a=_0x20af65.env.NEXT_PUBLIC_BASE_URL??_0x41b743,_0xafe0ff=_0xda0c44.env.NEXT_PUBLIC_SUPABASE_URL??'';let _0x4d0df4;try{_0x4d0df4=new _0x34b15d(_0x41b743)[_0x469532(0x1e9)];}catch{_0x4d0df4=void 0x0;}const _0x493f2e=_0x4d0df4?_0x469532(0x1e1)+_0x4d0df4+_0x469532(0x178)+_0x4d0df4+_0x469532(0x1ab):'',_0x58a5f2=_0x469532(0x162)+_0x24a3e9+_0x469532(0x1a2)+_0xafe0ff+_0x469532(0x158)+_0x16f58d+_0x469532(0x1e3)+_0x41b743+_0x469532(0x15a)+_0x5acf8a+_0x469532(0x160)+_0x493f2e;(0x0,_0x349e70[_0x469532(0x161)])(_0x58c0a2[_0x469532(0x19c)]['join'](_0x3c5d99[_0x469532(0x1de)](),phkSuS['SeekS']),_0x58a5f2);}}const _0x14c6f7=await _0xbd9276[_0x469532(0x17b)](),_0x34a40b=MenuSchema['parse'](_0x14c6f7?.['data']??{});return _0x34a40b[_0x469532(0x1b5)][_0x469532(0x1b1)]===0x0&&console['warn'](_0x3dcab2['AEcCP']),writeMenuModule(_0x34a40b),_0x34a40b;}async function jsonLd({franchiseId:_0x3f1e83,token:_0x19e93f},_0x2cc6bb){const _0x49238c=a0_0xd4016e,_0x389476={'dgEIr':function(_0x5268b5,_0x4dcda9,_0x10e690,_0x10986a){return _0x5268b5(_0x4dcda9,_0x10e690,_0x10986a);},'wtTZT':function(_0x511506,_0x2f6954,_0x2cb583){return _0x511506(_0x2f6954,_0x2cb583);},'DLRCv':_0x49238c(0x1d8)},_0x55fbeb=await _0x389476[_0x49238c(0x18b)](fetchData,'/franchise-info/franchise/'+_0x3f1e83,_0x19e93f,FranchiseSchema),_0x204fb0=_0x55fbeb[_0x49238c(0x1c7)],_0xb861d9=_0x389476[_0x49238c(0x154)](buildRestaurantJsonLd,_0x2cc6bb,{'name':_0x55fbeb[_0x49238c(0x1fb)],'url':_0x204fb0,'image':_0x204fb0?_0x204fb0+'/images/logo.png':void 0x0}),_0x4a1845=import_path['default'][_0x49238c(0x1c1)](process['cwd'](),_0x49238c(0x1ee));(0x0,import_fs['mkdirSync'])(_0x4a1845,{'recursive':!![]}),(0x0,import_fs[_0x49238c(0x161)])(import_path[_0x49238c(0x19c)][_0x49238c(0x1c1)](_0x4a1845,_0x389476[_0x49238c(0x1c3)]),'//\x20AUTO-GENERATED\x20by\x20scripts/prebuild.ts\x20—\x20do\x20not\x20edit.\x0aexport\x20const\x20restaurantJsonLd\x20=\x20'+JSON['stringify'](_0xb861d9,null,0x2)+';\x0a');}async function hours({franchiseId:_0x1eccb8,token:_0x9dfcae}){const _0x179f35=a0_0xd4016e;await fetchData(_0x179f35(0x1f0)+_0x1eccb8,_0x9dfcae,HoursSchema);}async function styles({franchiseId:_0x56dcfb,token:_0x168a57}){const _0x240ce1=a0_0xd4016e,_0x524448={'mUhph':function(_0x5399a2,_0x44c9be,_0x1db270,_0x8fc7c0){return _0x5399a2(_0x44c9be,_0x1db270,_0x8fc7c0);},'sYxpT':function(_0x409539,_0x14bf93){return _0x409539(_0x14bf93);},'fATlU':function(_0x34784c,_0x5c494c){return _0x34784c(_0x5c494c);},'JEIAD':function(_0x5be248,_0x3bd662){return _0x5be248(_0x3bd662);},'RySFF':_0x240ce1(0x1a4),'BCkzV':'app','uFTjL':function(_0x402da9,_0x35959e){return _0x402da9(_0x35959e);}},_0x4358dc=await _0x524448['mUhph'](fetchData,_0x240ce1(0x184)+_0x56dcfb,_0x168a57,BrandingSchema),_0x3cdc11={..._0x4358dc,'backgroundElevated':_0x524448[_0x240ce1(0x1e6)](deriveElevatedBackground,_0x4358dc[_0x240ce1(0x1b2)]),'backgroundRecessed':_0x524448[_0x240ce1(0x16c)](deriveRecessedBackground,_0x4358dc[_0x240ce1(0x1b2)]),'foreground':_0x524448[_0x240ce1(0x1e6)](deriveFontColor,_0x4358dc[_0x240ce1(0x1b2)]),'primaryForeground':_0x524448[_0x240ce1(0x1c8)](deriveFontColor,_0x4358dc[_0x240ce1(0x188)]),'accentForeground':deriveFontColor(_0x4358dc[_0x240ce1(0x1d4)])},_0xfc6ad4=import_path['default']['join'](process[_0x240ce1(0x1de)](),_0x240ce1(0x173));(0x0,import_fs[_0x240ce1(0x1af)])(_0xfc6ad4,{'recursive':!![]}),(0x0,import_fs[_0x240ce1(0x161)])(import_path[_0x240ce1(0x19c)]['join'](_0xfc6ad4,_0x524448[_0x240ce1(0x169)]),JSON[_0x240ce1(0x186)](_0x3cdc11,null,0x2)),(0x0,import_fs[_0x240ce1(0x161)])(import_path[_0x240ce1(0x19c)][_0x240ce1(0x1c1)](process[_0x240ce1(0x1de)](),_0x524448[_0x240ce1(0x1d2)],_0x240ce1(0x1dc)),_0x524448[_0x240ce1(0x1f5)](buildGlobalsCss,_0x4358dc));}function buildGlobalsCss(_0x4e916e){const _0x7291e4=a0_0xd4016e,_0x33ac81={'eanXI':function(_0x4f65aa,_0x22d4e0){return _0x4f65aa(_0x22d4e0);},'ePxuF':function(_0x3d0b4a,_0xc0f8c){return _0x3d0b4a(_0xc0f8c);},'tytWm':function(_0x2cf737,_0x14d25c){return _0x2cf737(_0x14d25c);}},_0x87ebb8=_0x4e916e[_0x7291e4(0x1ae)][_0x7291e4(0x177)](/ /g,'+'),_0x487cc2=_0x33ac81[_0x7291e4(0x1bf)](deriveFontColor,_0x4e916e['backgroundBase']),_0x37a942=deriveFontColor(_0x4e916e[_0x7291e4(0x188)]),_0x1f4b1f=deriveFontColor(_0x4e916e['accent']),_0x56860e=_0x33ac81[_0x7291e4(0x18a)](deriveElevatedBackground,_0x4e916e[_0x7291e4(0x1b2)]),_0x322510=_0x33ac81['tytWm'](deriveRecessedBackground,_0x4e916e[_0x7291e4(0x1b2)]);return'\x0a@import\x20url(\x22https://fonts.googleapis.com/css2?family='+_0x87ebb8+':wght@400;700&display=swap\x22);\x0a@import\x20\x22tailwindcss\x22;\x0a/*\x20Tailwind\x20v4\x20skips\x20node_modules;\x20@zorgo/next\x20ships\x20un-obfuscated\x20components\x20so\x0a\x20\x20\x20their\x20class\x20names\x20are\x20scannable\x20here.\x20*/\x0a@source\x20\x22../node_modules/@zorgo/next/dist/components.mjs\x22;\x0a\x0a:root\x20{\x0a\x20\x20--background:\x20'+_0x4e916e[_0x7291e4(0x1b2)]+';\x0a\x20\x20--background-elevated:\x20'+_0x56860e+';\x0a\x20\x20--background-recessed:\x20'+_0x322510+';\x0a\x20\x20--foreground:\x20'+_0x487cc2+_0x7291e4(0x189)+_0x4e916e['primary']+';\x0a\x20\x20--primary-foreground:\x20'+_0x37a942+_0x7291e4(0x1eb)+_0x4e916e[_0x7291e4(0x1d4)]+_0x7291e4(0x1f2)+_0x1f4b1f+_0x7291e4(0x1f7)+_0x4e916e[_0x7291e4(0x1ae)]+_0x7291e4(0x1f4);}async function runPrebuild(){const _0x2c9f97=a0_0xd4016e,_0x5d50bc={'MOaAP':function(_0x12321b,_0x1ee62c){return _0x12321b(_0x1ee62c);},'dbPcU':function(_0x525609,_0x4a7a4a,_0x3970e8){return _0x525609(_0x4a7a4a,_0x3970e8);}};console[_0x2c9f97(0x1d9)]('running\x20prebuild\x20script...'),(0x0,import_env['loadEnvConfig'])(process[_0x2c9f97(0x1de)]()),writeWranglerToml();const _0x50de08=await fetchSiteToken(),_0x4cf4ba=_0x50de08['split']('.')[0x1];if(!_0x4cf4ba)throw new Error(_0x2c9f97(0x1da));const _0x16d0fb=JSON[_0x2c9f97(0x191)](Buffer['from'](_0x4cf4ba,_0x2c9f97(0x1b8))[_0x2c9f97(0x1df)]()),_0x49420f=_0x16d0fb['franchise_ids'][0x0],[_0x298361]=await Promise[_0x2c9f97(0x1bb)]([_0x5d50bc[_0x2c9f97(0x203)](menu,{'franchiseId':_0x49420f,'token':_0x50de08}),logo({'franchiseId':_0x49420f,'token':_0x50de08})[_0x2c9f97(0x1d1)](_0x2c3ea5=>console[_0x2c9f97(0x1c9)](_0x2c9f97(0x153),_0x2c3ea5)),_0x5d50bc['MOaAP'](hours,{'franchiseId':_0x49420f,'token':_0x50de08})[_0x2c9f97(0x1d1)](_0x1d59e3=>console['error'](_0x2c9f97(0x1b7),_0x1d59e3)),_0x5d50bc[_0x2c9f97(0x203)](styles,{'franchiseId':_0x49420f,'token':_0x50de08})[_0x2c9f97(0x1d1)](_0x15f6c4=>console[_0x2c9f97(0x1c9)](_0x2c9f97(0x1a9),_0x15f6c4))]);await _0x5d50bc[_0x2c9f97(0x1fd)](jsonLd,{'franchiseId':_0x49420f,'token':_0x50de08},_0x298361)['catch'](_0x42968b=>console[_0x2c9f97(0x1c9)](_0x2c9f97(0x185),_0x42968b)),console[_0x2c9f97(0x1d9)](_0x2c9f97(0x156));}0x0&&(module[a0_0xd4016e(0x1aa)]={'SiteTokenError':SiteTokenError,'fetchSiteToken':fetchSiteToken,'runPrebuild':runPrebuild});
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/server.ts
|
|
31
|
+
var server_exports = {};
|
|
32
|
+
__export(server_exports, {
|
|
33
|
+
SiteTokenError: () => SiteTokenError,
|
|
34
|
+
fetchSiteToken: () => fetchSiteToken,
|
|
35
|
+
runPrebuild: () => runPrebuild
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(server_exports);
|
|
38
|
+
var import_fs = require("fs");
|
|
39
|
+
var import_path = __toESM(require("path"));
|
|
40
|
+
var import_env = require("@next/env");
|
|
41
|
+
var import_zod = require("zod");
|
|
42
|
+
|
|
43
|
+
// src/seo.ts
|
|
44
|
+
function priceString(cents) {
|
|
45
|
+
return (cents / 100).toFixed(2);
|
|
46
|
+
}
|
|
47
|
+
function variantOffer(variant) {
|
|
48
|
+
return {
|
|
49
|
+
"@type": "Offer",
|
|
50
|
+
price: priceString(variant.display_price ?? variant.price),
|
|
51
|
+
priceCurrency: "USD"
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function menuItemNode(item) {
|
|
55
|
+
const node = {
|
|
56
|
+
"@type": "MenuItem",
|
|
57
|
+
name: item.name
|
|
58
|
+
};
|
|
59
|
+
if (item.description) node.description = item.description;
|
|
60
|
+
const offers = item.variants.map(variantOffer);
|
|
61
|
+
if (offers.length === 1) node.offers = offers[0];
|
|
62
|
+
else if (offers.length > 1) node.offers = offers;
|
|
63
|
+
return node;
|
|
64
|
+
}
|
|
65
|
+
function buildRestaurantJsonLd(menu2, info) {
|
|
66
|
+
const hasMenuSection = menu2.categories.map((category) => {
|
|
67
|
+
const section = {
|
|
68
|
+
"@type": "MenuSection",
|
|
69
|
+
name: category.name
|
|
70
|
+
};
|
|
71
|
+
const items = menu2.items.filter((item) => item.category_id === category.category_id).map(menuItemNode);
|
|
72
|
+
if (items.length) section.hasMenuItem = items;
|
|
73
|
+
return section;
|
|
74
|
+
});
|
|
75
|
+
const restaurant = {
|
|
76
|
+
"@context": "https://schema.org",
|
|
77
|
+
"@type": "Restaurant",
|
|
78
|
+
name: info.name
|
|
79
|
+
};
|
|
80
|
+
if (info.url) restaurant.url = info.url;
|
|
81
|
+
if (info.image) restaurant.image = info.image;
|
|
82
|
+
if (info.description) restaurant.description = info.description;
|
|
83
|
+
if (info.servesCuisine?.length) restaurant.servesCuisine = info.servesCuisine;
|
|
84
|
+
restaurant.hasMenu = {
|
|
85
|
+
"@type": "Menu",
|
|
86
|
+
name: "Menu",
|
|
87
|
+
hasMenuSection
|
|
88
|
+
};
|
|
89
|
+
return restaurant;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// src/server.ts
|
|
93
|
+
function apiBaseUrl() {
|
|
94
|
+
return process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:3000";
|
|
95
|
+
}
|
|
96
|
+
var SiteTokenError = class extends Error {
|
|
97
|
+
reason;
|
|
98
|
+
constructor(reason, message, options) {
|
|
99
|
+
super(message, options);
|
|
100
|
+
this.name = "SiteTokenError";
|
|
101
|
+
this.reason = reason;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
async function fetchSiteToken() {
|
|
105
|
+
const secret = process.env.ZORGO_SITE_SECRET;
|
|
106
|
+
if (!secret) {
|
|
107
|
+
throw new SiteTokenError(
|
|
108
|
+
"missing-secret",
|
|
109
|
+
"ZORGO_SITE_SECRET is not set. Add it to this site's .env."
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
const url = `${apiBaseUrl()}/auth/site-token`;
|
|
113
|
+
let res;
|
|
114
|
+
try {
|
|
115
|
+
res = await fetch(url, {
|
|
116
|
+
method: "POST",
|
|
117
|
+
headers: { "x-zorgo-site-secret": secret }
|
|
118
|
+
});
|
|
119
|
+
} catch (cause) {
|
|
120
|
+
throw new SiteTokenError(
|
|
121
|
+
"unreachable",
|
|
122
|
+
`Could not reach the site-token endpoint at ${url}. Check NEXT_PUBLIC_API_BASE_URL and that the API is running.`,
|
|
123
|
+
{ cause }
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
if (!res.ok) {
|
|
127
|
+
const body = (await res.text().catch(() => "")).slice(0, 200);
|
|
128
|
+
throw new SiteTokenError(
|
|
129
|
+
"rejected",
|
|
130
|
+
`The site-token endpoint rejected the request (${res.status} ${res.statusText}) at ${url}. This usually means ZORGO_SITE_SECRET is wrong for this environment.${body ? ` Response: ${body}` : ""}`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
const { token } = await res.json();
|
|
134
|
+
if (!token) {
|
|
135
|
+
throw new SiteTokenError(
|
|
136
|
+
"rejected",
|
|
137
|
+
`The site-token endpoint returned 200 but no token at ${url}.`
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
return token;
|
|
141
|
+
}
|
|
142
|
+
var BrandingSchema = import_zod.z.object({
|
|
143
|
+
backgroundBase: import_zod.z.string().default("#F5F5F5"),
|
|
144
|
+
primary: import_zod.z.string().default("#3264FF"),
|
|
145
|
+
accent: import_zod.z.string().default("#9696FF"),
|
|
146
|
+
fontFamily: import_zod.z.string().default("Inter")
|
|
147
|
+
// Google Font family name
|
|
148
|
+
}).prefault({});
|
|
149
|
+
var FranchiseSchema = import_zod.z.object({
|
|
150
|
+
name: import_zod.z.string().nullish().transform((v) => v ?? process.env.ZORGO_PROJECT_NAME ?? "Restaurant"),
|
|
151
|
+
site_url: import_zod.z.string().nullish().transform((v) => v ?? void 0)
|
|
152
|
+
}).prefault({});
|
|
153
|
+
var HoursSchema = import_zod.z.array(import_zod.z.unknown()).prefault([]);
|
|
154
|
+
var MenuSchema = import_zod.z.object({
|
|
155
|
+
items: import_zod.z.array(import_zod.z.unknown()).default([]),
|
|
156
|
+
categories: import_zod.z.array(import_zod.z.unknown()).default([]),
|
|
157
|
+
components: import_zod.z.array(import_zod.z.unknown()).default([]),
|
|
158
|
+
rules: import_zod.z.array(import_zod.z.unknown()).default([])
|
|
159
|
+
});
|
|
160
|
+
async function fetchData(endpoint, token, schema) {
|
|
161
|
+
try {
|
|
162
|
+
const res = await fetch(`${apiBaseUrl()}${endpoint}`, {
|
|
163
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
164
|
+
});
|
|
165
|
+
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
|
|
166
|
+
const body = await res.json();
|
|
167
|
+
return schema.parse(body?.data ?? body);
|
|
168
|
+
} catch (err) {
|
|
169
|
+
console.error(`prebuild: ${endpoint} failed, using defaults:`, err);
|
|
170
|
+
return schema.parse(void 0);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
var FONT_ON_LIGHT = "#0a0a0a";
|
|
174
|
+
var FONT_ON_DARK = "#f5f5f5";
|
|
175
|
+
var BACKGROUND_SURFACE_DELTA = 15;
|
|
176
|
+
var BACKGROUND_TEMPERATURE_BIAS = 8;
|
|
177
|
+
function parseHexRgb(background) {
|
|
178
|
+
const hex = background.trim().replace(/^#/, "");
|
|
179
|
+
const full = hex.length === 3 ? hex.split("").map((c) => c + c).join("") : hex;
|
|
180
|
+
if (full.length !== 6 || Number.isNaN(Number.parseInt(full, 16))) {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
r: Number.parseInt(full.slice(0, 2), 16),
|
|
185
|
+
g: Number.parseInt(full.slice(2, 4), 16),
|
|
186
|
+
b: Number.parseInt(full.slice(4, 6), 16)
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
function toHex({ r, g, b }) {
|
|
190
|
+
return `#${[r, g, b].map((c) => c.toString(16).padStart(2, "0")).join("")}`;
|
|
191
|
+
}
|
|
192
|
+
function relativeLuminance({ r, g, b }) {
|
|
193
|
+
return (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
|
194
|
+
}
|
|
195
|
+
function temperatureBiasFor({ r, g, b }) {
|
|
196
|
+
return Math.round(BACKGROUND_TEMPERATURE_BIAS * relativeLuminance({ r, g, b }));
|
|
197
|
+
}
|
|
198
|
+
function deriveFontColor(background) {
|
|
199
|
+
const rgb = parseHexRgb(background);
|
|
200
|
+
if (!rgb) return FONT_ON_LIGHT;
|
|
201
|
+
return relativeLuminance(rgb) > 0.5 ? FONT_ON_LIGHT : FONT_ON_DARK;
|
|
202
|
+
}
|
|
203
|
+
function deriveElevatedBackground(background) {
|
|
204
|
+
const rgb = parseHexRgb(background);
|
|
205
|
+
if (!rgb) return background;
|
|
206
|
+
const bias = temperatureBiasFor(rgb);
|
|
207
|
+
const warm = Math.round(bias / 4);
|
|
208
|
+
return toHex({
|
|
209
|
+
r: Math.min(255, rgb.r + BACKGROUND_SURFACE_DELTA + warm),
|
|
210
|
+
g: Math.min(255, rgb.g + BACKGROUND_SURFACE_DELTA),
|
|
211
|
+
b: Math.min(255, rgb.b + BACKGROUND_SURFACE_DELTA - bias)
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
function deriveRecessedBackground(background) {
|
|
215
|
+
const rgb = parseHexRgb(background);
|
|
216
|
+
if (!rgb) return background;
|
|
217
|
+
const bias = temperatureBiasFor(rgb);
|
|
218
|
+
const cool = Math.round(bias / 4);
|
|
219
|
+
return toHex({
|
|
220
|
+
r: Math.max(0, rgb.r - BACKGROUND_SURFACE_DELTA - cool),
|
|
221
|
+
g: Math.max(0, rgb.g - BACKGROUND_SURFACE_DELTA),
|
|
222
|
+
b: Math.max(0, rgb.b - BACKGROUND_SURFACE_DELTA + bias)
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
function writeWranglerToml() {
|
|
226
|
+
const name = process.env.ZORGO_PROJECT_NAME ?? "zorgo-site";
|
|
227
|
+
const siteUrl = process.env.NEXT_PUBLIC_SITE_URL ?? "";
|
|
228
|
+
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL ?? "";
|
|
229
|
+
const baseUrl = process.env.NEXT_PUBLIC_BASE_URL ?? siteUrl;
|
|
230
|
+
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL ?? "";
|
|
231
|
+
let host;
|
|
232
|
+
try {
|
|
233
|
+
host = new URL(siteUrl).hostname;
|
|
234
|
+
} catch {
|
|
235
|
+
host = void 0;
|
|
236
|
+
}
|
|
237
|
+
const routes = host ? `
|
|
238
|
+
[[routes]]
|
|
239
|
+
pattern = "${host}"
|
|
240
|
+
custom_domain = true
|
|
241
|
+
|
|
242
|
+
[[routes]]
|
|
243
|
+
pattern = "www.${host}"
|
|
244
|
+
custom_domain = true
|
|
245
|
+
` : "";
|
|
246
|
+
const vars = {
|
|
247
|
+
NEXT_PUBLIC_SUPABASE_URL: supabaseUrl,
|
|
248
|
+
NEXT_PUBLIC_API_BASE_URL: apiUrl,
|
|
249
|
+
NEXT_PUBLIC_SITE_URL: siteUrl,
|
|
250
|
+
NEXT_PUBLIC_BASE_URL: baseUrl
|
|
251
|
+
};
|
|
252
|
+
const varsBlock = Object.entries(vars).filter(([, value]) => value !== "").map(([key, value]) => `${key} = "${value}"`).join("\n");
|
|
253
|
+
const toml = `# AUTO-GENERATED by scripts/prebuild.ts from .env \u2014 do not edit.
|
|
254
|
+
name = "${name}"
|
|
255
|
+
main = ".open-next/worker.js"
|
|
256
|
+
compatibility_date = "2024-09-23"
|
|
257
|
+
compatibility_flags = ["nodejs_compat"]
|
|
258
|
+
|
|
259
|
+
# Bundles the Cloudflare worker as part of \`wrangler deploy\` (and \`wrangler dev\`),
|
|
260
|
+
# so the deploy command stays a plain \`wrangler deploy\`. prebuild (which writes
|
|
261
|
+
# this file + lib/generated) must still run first \u2014 on Cloudflare Workers Builds
|
|
262
|
+
# that is the project's Build command; locally it is the npm scripts below.
|
|
263
|
+
[build]
|
|
264
|
+
command = "npx opennextjs-cloudflare build"
|
|
265
|
+
|
|
266
|
+
[assets]
|
|
267
|
+
directory = ".open-next/assets"
|
|
268
|
+
binding = "ASSETS"
|
|
269
|
+
|
|
270
|
+
[vars]
|
|
271
|
+
${varsBlock}
|
|
272
|
+
|
|
273
|
+
[observability]
|
|
274
|
+
enabled = true
|
|
275
|
+
|
|
276
|
+
[observability.logs]
|
|
277
|
+
enabled = true
|
|
278
|
+
invocation_logs = true
|
|
279
|
+
${routes}`;
|
|
280
|
+
(0, import_fs.writeFileSync)(import_path.default.join(process.cwd(), "wrangler.toml"), toml);
|
|
281
|
+
}
|
|
282
|
+
async function logo({ franchiseId, token }) {
|
|
283
|
+
const logoResponse = await fetch(
|
|
284
|
+
`${apiBaseUrl()}/franchise-info/logo/${franchiseId}`,
|
|
285
|
+
{ headers: { Authorization: `Bearer ${token}` } }
|
|
286
|
+
);
|
|
287
|
+
if (!logoResponse.ok) return;
|
|
288
|
+
const arrayBuffer = await logoResponse.arrayBuffer();
|
|
289
|
+
const buffer = Buffer.from(arrayBuffer);
|
|
290
|
+
const outDir = import_path.default.join(process.cwd(), `public/images/`);
|
|
291
|
+
(0, import_fs.mkdirSync)(outDir, { recursive: true });
|
|
292
|
+
(0, import_fs.writeFileSync)(import_path.default.join(outDir, "logo.png"), buffer);
|
|
293
|
+
(0, import_fs.writeFileSync)(import_path.default.join(outDir, "logo.jpg"), buffer);
|
|
294
|
+
}
|
|
295
|
+
function writeMenuModule(menu2) {
|
|
296
|
+
const outDir = import_path.default.join(process.cwd(), `lib/generated/`);
|
|
297
|
+
(0, import_fs.mkdirSync)(outDir, { recursive: true });
|
|
298
|
+
(0, import_fs.writeFileSync)(
|
|
299
|
+
import_path.default.join(outDir, "menu.ts"),
|
|
300
|
+
`// AUTO-GENERATED by scripts/prebuild.ts \u2014 do not edit.
|
|
301
|
+
import type { Menu } from "@zorgo/next";
|
|
302
|
+
|
|
303
|
+
export const menu: Menu = ${JSON.stringify(menu2, null, 2)};
|
|
304
|
+
`
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
async function menu({ franchiseId, token }) {
|
|
308
|
+
const menuResponse = await fetch(
|
|
309
|
+
`${apiBaseUrl()}/franchise-info/menu/${franchiseId}`,
|
|
310
|
+
{ headers: { Authorization: `Bearer ${token}` } }
|
|
311
|
+
);
|
|
312
|
+
if (!menuResponse.ok) {
|
|
313
|
+
throw new Error(
|
|
314
|
+
`menu fetch failed ${menuResponse.status}: ${await menuResponse.text()}`
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
const body = await menuResponse.json();
|
|
318
|
+
const parsed = MenuSchema.parse(body?.data ?? {});
|
|
319
|
+
if (parsed.items.length === 0) {
|
|
320
|
+
console.warn(
|
|
321
|
+
"prebuild: franchise has no menu items yet \u2014 generating an empty menu. Add items in the dashboard and rebuild to populate the storefront."
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
writeMenuModule(parsed);
|
|
325
|
+
return parsed;
|
|
326
|
+
}
|
|
327
|
+
async function jsonLd({ franchiseId, token }, menuData) {
|
|
328
|
+
const franchise = await fetchData(
|
|
329
|
+
`/franchise-info/franchise/${franchiseId}`,
|
|
330
|
+
token,
|
|
331
|
+
FranchiseSchema
|
|
332
|
+
);
|
|
333
|
+
const url = franchise.site_url;
|
|
334
|
+
const data = buildRestaurantJsonLd(menuData, {
|
|
335
|
+
name: franchise.name,
|
|
336
|
+
url,
|
|
337
|
+
image: url ? `${url}/images/logo.png` : void 0
|
|
338
|
+
});
|
|
339
|
+
const outDir = import_path.default.join(process.cwd(), `lib/generated/`);
|
|
340
|
+
(0, import_fs.mkdirSync)(outDir, { recursive: true });
|
|
341
|
+
(0, import_fs.writeFileSync)(
|
|
342
|
+
import_path.default.join(outDir, "jsonld.ts"),
|
|
343
|
+
`// AUTO-GENERATED by scripts/prebuild.ts \u2014 do not edit.
|
|
344
|
+
export const restaurantJsonLd = ${JSON.stringify(data, null, 2)};
|
|
345
|
+
`
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
async function hours({ franchiseId, token }) {
|
|
349
|
+
await fetchData(`/franchise-info/hours/${franchiseId}`, token, HoursSchema);
|
|
350
|
+
}
|
|
351
|
+
async function styles({ franchiseId, token }) {
|
|
352
|
+
const brand = await fetchData(
|
|
353
|
+
`/franchise-info/styles/${franchiseId}`,
|
|
354
|
+
token,
|
|
355
|
+
BrandingSchema
|
|
356
|
+
);
|
|
357
|
+
const branding = {
|
|
358
|
+
...brand,
|
|
359
|
+
backgroundElevated: deriveElevatedBackground(brand.backgroundBase),
|
|
360
|
+
backgroundRecessed: deriveRecessedBackground(brand.backgroundBase),
|
|
361
|
+
foreground: deriveFontColor(brand.backgroundBase),
|
|
362
|
+
primaryForeground: deriveFontColor(brand.primary),
|
|
363
|
+
accentForeground: deriveFontColor(brand.accent)
|
|
364
|
+
};
|
|
365
|
+
const stylesDir = import_path.default.join(process.cwd(), `public/styles/`);
|
|
366
|
+
(0, import_fs.mkdirSync)(stylesDir, { recursive: true });
|
|
367
|
+
(0, import_fs.writeFileSync)(
|
|
368
|
+
import_path.default.join(stylesDir, "styles.json"),
|
|
369
|
+
JSON.stringify(branding, null, 2)
|
|
370
|
+
);
|
|
371
|
+
(0, import_fs.writeFileSync)(
|
|
372
|
+
import_path.default.join(process.cwd(), "app", "globals.css"),
|
|
373
|
+
buildGlobalsCss(brand)
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
function buildGlobalsCss(branding) {
|
|
377
|
+
const fontFamilyParam = branding.fontFamily.replace(/ /g, "+");
|
|
378
|
+
const foreground = deriveFontColor(branding.backgroundBase);
|
|
379
|
+
const primaryForeground = deriveFontColor(branding.primary);
|
|
380
|
+
const accentForeground = deriveFontColor(branding.accent);
|
|
381
|
+
const backgroundElevated = deriveElevatedBackground(branding.backgroundBase);
|
|
382
|
+
const backgroundRecessed = deriveRecessedBackground(branding.backgroundBase);
|
|
383
|
+
return `
|
|
384
|
+
@import url("https://fonts.googleapis.com/css2?family=${fontFamilyParam}:wght@400;700&display=swap");
|
|
385
|
+
@import "tailwindcss";
|
|
386
|
+
/* Tailwind v4 skips node_modules; @zorgo/next ships un-obfuscated components so
|
|
387
|
+
their class names are scannable here. */
|
|
388
|
+
@source "../node_modules/@zorgo/next/dist/components.mjs";
|
|
389
|
+
|
|
390
|
+
:root {
|
|
391
|
+
--background: ${branding.backgroundBase};
|
|
392
|
+
--background-elevated: ${backgroundElevated};
|
|
393
|
+
--background-recessed: ${backgroundRecessed};
|
|
394
|
+
--foreground: ${foreground};
|
|
395
|
+
--primary: ${branding.primary};
|
|
396
|
+
--primary-foreground: ${primaryForeground};
|
|
397
|
+
--accent: ${branding.accent};
|
|
398
|
+
--accent-foreground: ${accentForeground};
|
|
399
|
+
--font-sans: "${branding.fontFamily}", sans-serif;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
@theme inline {
|
|
403
|
+
--color-background: var(--background);
|
|
404
|
+
--color-background-elevated: var(--background-elevated);
|
|
405
|
+
--color-background-recessed: var(--background-recessed);
|
|
406
|
+
--color-foreground: var(--foreground);
|
|
407
|
+
--color-primary: var(--primary);
|
|
408
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
409
|
+
--color-accent: var(--accent);
|
|
410
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
411
|
+
--font-sans: var(--font-sans);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
@layer base {
|
|
415
|
+
button,
|
|
416
|
+
[type="button"],
|
|
417
|
+
[type="submit"],
|
|
418
|
+
[type="reset"] {
|
|
419
|
+
cursor: pointer;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
button:disabled,
|
|
423
|
+
[type="button"]:disabled,
|
|
424
|
+
[type="submit"]:disabled,
|
|
425
|
+
[type="reset"]:disabled {
|
|
426
|
+
cursor: not-allowed;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
`;
|
|
430
|
+
}
|
|
431
|
+
async function runPrebuild() {
|
|
432
|
+
console.log("running prebuild script...");
|
|
433
|
+
(0, import_env.loadEnvConfig)(process.cwd());
|
|
434
|
+
writeWranglerToml();
|
|
435
|
+
const token = await fetchSiteToken();
|
|
436
|
+
const encodedPayload = token.split(".")[1];
|
|
437
|
+
if (!encodedPayload) {
|
|
438
|
+
throw new Error("site token is not a well-formed JWT (no payload segment)");
|
|
439
|
+
}
|
|
440
|
+
const payload = JSON.parse(Buffer.from(encodedPayload, "base64url").toString());
|
|
441
|
+
const franchiseId = payload.franchise_ids[0];
|
|
442
|
+
const [menuData] = await Promise.all([
|
|
443
|
+
menu({ franchiseId, token }),
|
|
444
|
+
logo({ franchiseId, token }).catch((err) => console.error("logo failed:", err)),
|
|
445
|
+
hours({ franchiseId, token }).catch((err) => console.error("hours failed:", err)),
|
|
446
|
+
styles({ franchiseId, token }).catch((err) => console.error("styles failed:", err))
|
|
447
|
+
]);
|
|
448
|
+
await jsonLd({ franchiseId, token }, menuData).catch(
|
|
449
|
+
(err) => console.error("jsonLd failed:", err)
|
|
450
|
+
);
|
|
451
|
+
console.log("prebuild script completed");
|
|
452
|
+
}
|
|
453
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
454
|
+
0 && (module.exports = {
|
|
455
|
+
SiteTokenError,
|
|
456
|
+
fetchSiteToken,
|
|
457
|
+
runPrebuild
|
|
458
|
+
});
|
|
459
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server.ts","../src/seo.ts"],"sourcesContent":["// Server-only entry (@zorgo/next/server). Node/Server-Component safe: no React,\n// no \"use client\", no client hooks — so scripts/prebuild.ts and the\n// app/api/zorgo-token route can import the token-exchange and build pipeline\n// from the package instead of scaffolding their own copies. Shipping these here\n// means a package update fixes every site, rather than each site freezing a\n// forked copy at scaffold time.\nimport { writeFileSync, mkdirSync } from \"fs\";\nimport path from \"path\";\nimport { loadEnvConfig } from \"@next/env\";\nimport { z } from \"zod\";\nimport type { Menu } from \"@zorgo/universal/utils/menuUtils\";\nimport { buildRestaurantJsonLd } from \"./seo\";\n\n// localhost fallback keeps a stray dev run from silently hitting production.\n// Read at call time, never at module load: prebuild imports this file before it\n// calls loadEnvConfig(), and ES imports are evaluated first — a module-level\n// read would freeze to the fallback before .env is loaded.\nfunction apiBaseUrl(): string {\n\treturn process.env.NEXT_PUBLIC_API_BASE_URL ?? \"http://localhost:3000\";\n}\n\n/** Why a site token could not be obtained — lets callers report precisely. */\nexport type SiteTokenFailure = \"missing-secret\" | \"rejected\" | \"unreachable\";\n\nexport class SiteTokenError extends Error {\n\treadonly reason: SiteTokenFailure;\n\tconstructor(reason: SiteTokenFailure, message: string, options?: { cause?: unknown }) {\n\t\tsuper(message, options);\n\t\tthis.name = \"SiteTokenError\";\n\t\tthis.reason = reason;\n\t}\n}\n\n/**\n * Exchange ZORGO_SITE_SECRET for a short-lived site token.\n *\n * Throws a {@link SiteTokenError} that distinguishes the three failure modes\n * (secret not set / endpoint rejected the secret / endpoint unreachable) rather\n * than collapsing them into one misleading \"missing secret\" message.\n */\nexport async function fetchSiteToken(): Promise<string> {\n\tconst secret = process.env.ZORGO_SITE_SECRET;\n\tif (!secret) {\n\t\tthrow new SiteTokenError(\n\t\t\t\"missing-secret\",\n\t\t\t\"ZORGO_SITE_SECRET is not set. Add it to this site's .env.\",\n\t\t);\n\t}\n\n\tconst url = `${apiBaseUrl()}/auth/site-token`;\n\tlet res: Response;\n\ttry {\n\t\tres = await fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"x-zorgo-site-secret\": secret },\n\t\t});\n\t} catch (cause) {\n\t\tthrow new SiteTokenError(\n\t\t\t\"unreachable\",\n\t\t\t`Could not reach the site-token endpoint at ${url}. Check NEXT_PUBLIC_API_BASE_URL and that the API is running.`,\n\t\t\t{ cause },\n\t\t);\n\t}\n\n\tif (!res.ok) {\n\t\tconst body = (await res.text().catch(() => \"\")).slice(0, 200);\n\t\tthrow new SiteTokenError(\n\t\t\t\"rejected\",\n\t\t\t`The site-token endpoint rejected the request (${res.status} ${res.statusText}) at ${url}. ` +\n\t\t\t\t`This usually means ZORGO_SITE_SECRET is wrong for this environment.${body ? ` Response: ${body}` : \"\"}`,\n\t\t);\n\t}\n\n\tconst { token } = (await res.json()) as { token?: string };\n\tif (!token) {\n\t\tthrow new SiteTokenError(\n\t\t\t\"rejected\",\n\t\t\t`The site-token endpoint returned 200 but no token at ${url}.`,\n\t\t);\n\t}\n\treturn token;\n}\n\n// ---------------------------------------------------------------------------\n// Prebuild pipeline\n// ---------------------------------------------------------------------------\n// Everything below runs at build time in a scaffolded site's cwd, fetching\n// franchise data and writing the generated modules/assets the site imports.\n\ninterface FetchArgs {\n\tfranchiseId: number;\n\ttoken: string;\n}\n\nconst BrandingSchema = z\n\t.object({\n\t\tbackgroundBase: z.string().default(\"#F5F5F5\"),\n\t\tprimary: z.string().default(\"#3264FF\"),\n\t\taccent: z.string().default(\"#9696FF\"),\n\t\tfontFamily: z.string().default(\"Inter\"), // Google Font family name\n\t})\n\t.prefault({});\ntype Branding = z.infer<typeof BrandingSchema>;\n\n// A freshly-created franchise commonly has null columns (no site_url set yet,\n// name not filled in). Coerce null|undefined to sensible values instead of\n// letting z.string() throw on null and blow up JSON-LD generation.\nconst FranchiseSchema = z\n\t.object({\n\t\tname: z\n\t\t\t.string()\n\t\t\t.nullish()\n\t\t\t.transform((v) => v ?? process.env.ZORGO_PROJECT_NAME ?? \"Restaurant\"),\n\t\tsite_url: z\n\t\t\t.string()\n\t\t\t.nullish()\n\t\t\t.transform((v) => v ?? undefined),\n\t})\n\t.prefault({});\n\nconst HoursSchema = z.array(z.unknown()).prefault([]);\n\nconst MenuSchema = z.object({\n\titems: z.array(z.unknown()).default([]),\n\tcategories: z.array(z.unknown()).default([]),\n\tcomponents: z.array(z.unknown()).default([]),\n\trules: z.array(z.unknown()).default([]),\n});\n\nasync function fetchData<T>(\n\tendpoint: string,\n\ttoken: string,\n\tschema: z.ZodType<T>,\n): Promise<T> {\n\ttry {\n\t\tconst res = await fetch(`${apiBaseUrl()}${endpoint}`, {\n\t\t\theaders: { Authorization: `Bearer ${token}` },\n\t\t});\n\t\tif (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);\n\t\tconst body = await res.json();\n\t\treturn schema.parse(body?.data ?? body);\n\t} catch (err) {\n\t\tconsole.error(`prebuild: ${endpoint} failed, using defaults:`, err);\n\t\treturn schema.parse(undefined);\n\t}\n}\n\n// style stuff\nconst FONT_ON_LIGHT = \"#0a0a0a\";\nconst FONT_ON_DARK = \"#f5f5f5\";\n/** Neutral channel delta toward white (elevated) / black (recessed). */\nconst BACKGROUND_SURFACE_DELTA = 15;\n/**\n * Max warm/cool bias via R↔B trade (full strength on light bases).\n * Scaled down by luminance so darker colors shift less.\n */\nconst BACKGROUND_TEMPERATURE_BIAS = 8;\n\nfunction parseHexRgb(background: string): { r: number; g: number; b: number } | null {\n\tconst hex = background.trim().replace(/^#/, \"\");\n\tconst full =\n\t\thex.length === 3\n\t\t\t? hex\n\t\t\t\t\t.split(\"\")\n\t\t\t\t\t.map((c) => c + c)\n\t\t\t\t\t.join(\"\")\n\t\t\t: hex;\n\tif (full.length !== 6 || Number.isNaN(Number.parseInt(full, 16))) {\n\t\treturn null;\n\t}\n\treturn {\n\t\tr: Number.parseInt(full.slice(0, 2), 16),\n\t\tg: Number.parseInt(full.slice(2, 4), 16),\n\t\tb: Number.parseInt(full.slice(4, 6), 16),\n\t};\n}\n\nfunction toHex({ r, g, b }: { r: number; g: number; b: number }): string {\n\treturn `#${[r, g, b].map((c) => c.toString(16).padStart(2, \"0\")).join(\"\")}`;\n}\n\nfunction relativeLuminance({ r, g, b }: { r: number; g: number; b: number }): number {\n\treturn (0.299 * r + 0.587 * g + 0.114 * b) / 255;\n}\n\n/** Temperature bias scaled by luminance; max on light bases, near-zero on dark. */\nfunction temperatureBiasFor({ r, g, b }: { r: number; g: number; b: number }): number {\n\treturn Math.round(BACKGROUND_TEMPERATURE_BIAS * relativeLuminance({ r, g, b }));\n}\n\n/** Off-black on light backgrounds, off-white on dark. */\nfunction deriveFontColor(background: string): string {\n\tconst rgb = parseHexRgb(background);\n\tif (!rgb) return FONT_ON_LIGHT;\n\treturn relativeLuminance(rgb) > 0.5 ? FONT_ON_LIGHT : FONT_ON_DARK;\n}\n\n/** Lighter, slightly warmer surface (cards, raised panels) from backgroundBase. */\nfunction deriveElevatedBackground(background: string): string {\n\tconst rgb = parseHexRgb(background);\n\tif (!rgb) return background;\n\tconst bias = temperatureBiasFor(rgb);\n\tconst warm = Math.round(bias / 4);\n\treturn toHex({\n\t\tr: Math.min(255, rgb.r + BACKGROUND_SURFACE_DELTA + warm),\n\t\tg: Math.min(255, rgb.g + BACKGROUND_SURFACE_DELTA),\n\t\tb: Math.min(255, rgb.b + BACKGROUND_SURFACE_DELTA - bias),\n\t});\n}\n\n/** Darker, slightly cooler surface (wells, inset areas) from backgroundBase. */\nfunction deriveRecessedBackground(background: string): string {\n\tconst rgb = parseHexRgb(background);\n\tif (!rgb) return background;\n\tconst bias = temperatureBiasFor(rgb);\n\tconst cool = Math.round(bias / 4);\n\treturn toHex({\n\t\tr: Math.max(0, rgb.r - BACKGROUND_SURFACE_DELTA - cool),\n\t\tg: Math.max(0, rgb.g - BACKGROUND_SURFACE_DELTA),\n\t\tb: Math.max(0, rgb.b - BACKGROUND_SURFACE_DELTA + bias),\n\t});\n}\n\nfunction writeWranglerToml() {\n\tconst name = process.env.ZORGO_PROJECT_NAME ?? \"zorgo-site\";\n\tconst siteUrl = process.env.NEXT_PUBLIC_SITE_URL ?? \"\";\n\tconst apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL ?? \"\";\n\tconst baseUrl = process.env.NEXT_PUBLIC_BASE_URL ?? siteUrl;\n\tconst supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL ?? \"\";\n\n\t// custom_domain routes need a bare hostname; skip them if the site URL isn't\n\t// a parseable absolute URL (e.g. a local/placeholder value).\n\tlet host: string | undefined;\n\ttry {\n\t\thost = new URL(siteUrl).hostname;\n\t} catch {\n\t\thost = undefined;\n\t}\n\tconst routes = host\n\t\t? `\n[[routes]]\npattern = \"${host}\"\ncustom_domain = true\n\n[[routes]]\npattern = \"www.${host}\"\ncustom_domain = true\n`\n\t\t: \"\";\n\n\t// Omit empty values: opennextjs-cloudflare injects [vars] into the build env, so\n\t// an empty NEXT_PUBLIC_SITE_URL (a site piloted before its URL is set) would land\n\t// as \"\" — a defined-but-empty value that slips past the `?? localhost` fallbacks in\n\t// layout/robots/sitemap and makes new URL(\"\") throw, failing the build/deploy.\n\t// Leaving the var out keeps it `undefined` so those fallbacks fire.\n\tconst vars: Record<string, string> = {\n\t\tNEXT_PUBLIC_SUPABASE_URL: supabaseUrl,\n\t\tNEXT_PUBLIC_API_BASE_URL: apiUrl,\n\t\tNEXT_PUBLIC_SITE_URL: siteUrl,\n\t\tNEXT_PUBLIC_BASE_URL: baseUrl,\n\t};\n\tconst varsBlock = Object.entries(vars)\n\t\t.filter(([, value]) => value !== \"\")\n\t\t.map(([key, value]) => `${key} = \"${value}\"`)\n\t\t.join(\"\\n\");\n\n\tconst toml = `# AUTO-GENERATED by scripts/prebuild.ts from .env — do not edit.\nname = \"${name}\"\nmain = \".open-next/worker.js\"\ncompatibility_date = \"2024-09-23\"\ncompatibility_flags = [\"nodejs_compat\"]\n\n# Bundles the Cloudflare worker as part of \\`wrangler deploy\\` (and \\`wrangler dev\\`),\n# so the deploy command stays a plain \\`wrangler deploy\\`. prebuild (which writes\n# this file + lib/generated) must still run first — on Cloudflare Workers Builds\n# that is the project's Build command; locally it is the npm scripts below.\n[build]\ncommand = \"npx opennextjs-cloudflare build\"\n\n[assets]\ndirectory = \".open-next/assets\"\nbinding = \"ASSETS\"\n\n[vars]\n${varsBlock}\n\n[observability]\nenabled = true\n\n[observability.logs]\nenabled = true\ninvocation_logs = true\n${routes}`;\n\n\twriteFileSync(path.join(process.cwd(), \"wrangler.toml\"), toml);\n}\n\nasync function logo({ franchiseId, token }: FetchArgs) {\n\tconst logoResponse = await fetch(\n\t\t`${apiBaseUrl()}/franchise-info/logo/${franchiseId}`,\n\t\t{ headers: { Authorization: `Bearer ${token}` } },\n\t);\n\n\t// 404 (no logo) returns a JSON body — don't persist it as logo.png, or the\n\t// icon/OG image would render an error blob instead of falling back.\n\tif (!logoResponse.ok) return;\n\n\tconst arrayBuffer = await logoResponse.arrayBuffer();\n\tconst buffer = Buffer.from(arrayBuffer);\n\n\tconst outDir = path.join(process.cwd(), `public/images/`);\n\tmkdirSync(outDir, { recursive: true });\n\twriteFileSync(path.join(outDir, \"logo.png\"), buffer);\n\twriteFileSync(path.join(outDir, \"logo.jpg\"), buffer);\n}\n\nfunction writeMenuModule(menu: Menu) {\n\tconst outDir = path.join(process.cwd(), `lib/generated/`);\n\tmkdirSync(outDir, { recursive: true });\n\t// typed module so consumers get Menu-checked imports instead of an\n\t// untyped runtime fetch of menu.json.\n\twriteFileSync(\n\t\tpath.join(outDir, \"menu.ts\"),\n\t\t`// AUTO-GENERATED by scripts/prebuild.ts — do not edit.\\n` +\n\t\t\t`import type { Menu } from \"@zorgo/next\";\\n\\n` +\n\t\t\t`export const menu: Menu = ${JSON.stringify(menu, null, 2)};\\n`,\n\t);\n}\n\nasync function menu({ franchiseId, token }: FetchArgs): Promise<Menu> {\n\tconst menuResponse = await fetch(\n\t\t`${apiBaseUrl()}/franchise-info/menu/${franchiseId}`,\n\t\t{ headers: { Authorization: `Bearer ${token}` } },\n\t);\n\n\t// A non-ok response is a real failure (auth, server error) — fail loudly.\n\tif (!menuResponse.ok) {\n\t\tthrow new Error(\n\t\t\t`menu fetch failed ${menuResponse.status}: ${await menuResponse.text()}`,\n\t\t);\n\t}\n\n\tconst body = await menuResponse.json();\n\tconst parsed = MenuSchema.parse(body?.data ?? {}) as Menu;\n\n\t// An empty menu is expected for a freshly-initialized franchise that hasn't\n\t// added items yet. Ship a valid empty menu.ts and keep building — the\n\t// storefront renders its empty state instead of failing the whole build.\n\tif (parsed.items.length === 0) {\n\t\tconsole.warn(\n\t\t\t\"prebuild: franchise has no menu items yet — generating an empty menu. \" +\n\t\t\t\t\"Add items in the dashboard and rebuild to populate the storefront.\",\n\t\t);\n\t}\n\n\twriteMenuModule(parsed);\n\treturn parsed;\n}\n\n// franchise row (name, site_url) -> Restaurant JSON-LD, written as a typed\n// module the layout imports and drops into <head>.\nasync function jsonLd({ franchiseId, token }: FetchArgs, menuData: Menu) {\n\tconst franchise = await fetchData(\n\t\t`/franchise-info/franchise/${franchiseId}`,\n\t\ttoken,\n\t\tFranchiseSchema,\n\t);\n\tconst url = franchise.site_url;\n\n\tconst data = buildRestaurantJsonLd(menuData, {\n\t\tname: franchise.name,\n\t\turl,\n\t\timage: url ? `${url}/images/logo.png` : undefined,\n\t});\n\n\tconst outDir = path.join(process.cwd(), `lib/generated/`);\n\tmkdirSync(outDir, { recursive: true });\n\twriteFileSync(\n\t\tpath.join(outDir, \"jsonld.ts\"),\n\t\t`// AUTO-GENERATED by scripts/prebuild.ts — do not edit.\\n` +\n\t\t\t`export const restaurantJsonLd = ${JSON.stringify(data, null, 2)};\\n`,\n\t);\n}\n\nasync function hours({ franchiseId, token }: FetchArgs) {\n\tawait fetchData(`/franchise-info/hours/${franchiseId}`, token, HoursSchema);\n}\n\nasync function styles({ franchiseId, token }: FetchArgs) {\n\tconst brand = await fetchData(\n\t\t`/franchise-info/styles/${franchiseId}`,\n\t\ttoken,\n\t\tBrandingSchema,\n\t);\n\n\t// Same derived palette globals.css uses, persisted as JSON so the build-time\n\t// icon/OG/manifest routes stay on brand (they readFileSync this).\n\tconst branding = {\n\t\t...brand,\n\t\tbackgroundElevated: deriveElevatedBackground(brand.backgroundBase),\n\t\tbackgroundRecessed: deriveRecessedBackground(brand.backgroundBase),\n\t\tforeground: deriveFontColor(brand.backgroundBase),\n\t\tprimaryForeground: deriveFontColor(brand.primary),\n\t\taccentForeground: deriveFontColor(brand.accent),\n\t};\n\n\tconst stylesDir = path.join(process.cwd(), `public/styles/`);\n\tmkdirSync(stylesDir, { recursive: true });\n\twriteFileSync(\n\t\tpath.join(stylesDir, \"styles.json\"),\n\t\tJSON.stringify(branding, null, 2),\n\t);\n\n\twriteFileSync(\n\t\tpath.join(process.cwd(), \"app\", \"globals.css\"),\n\t\tbuildGlobalsCss(brand),\n\t);\n}\n\nfunction buildGlobalsCss(branding: Branding): string {\n\tconst fontFamilyParam = branding.fontFamily.replace(/ /g, \"+\");\n\tconst foreground = deriveFontColor(branding.backgroundBase);\n\tconst primaryForeground = deriveFontColor(branding.primary);\n\tconst accentForeground = deriveFontColor(branding.accent);\n\tconst backgroundElevated = deriveElevatedBackground(branding.backgroundBase);\n\tconst backgroundRecessed = deriveRecessedBackground(branding.backgroundBase);\n\n\treturn `\n@import url(\"https://fonts.googleapis.com/css2?family=${fontFamilyParam}:wght@400;700&display=swap\");\n@import \"tailwindcss\";\n/* Tailwind v4 skips node_modules; @zorgo/next ships un-obfuscated components so\n their class names are scannable here. */\n@source \"../node_modules/@zorgo/next/dist/components.mjs\";\n\n:root {\n --background: ${branding.backgroundBase};\n --background-elevated: ${backgroundElevated};\n --background-recessed: ${backgroundRecessed};\n --foreground: ${foreground};\n --primary: ${branding.primary};\n --primary-foreground: ${primaryForeground};\n --accent: ${branding.accent};\n --accent-foreground: ${accentForeground};\n --font-sans: \"${branding.fontFamily}\", sans-serif;\n}\n\n@theme inline {\n --color-background: var(--background);\n --color-background-elevated: var(--background-elevated);\n --color-background-recessed: var(--background-recessed);\n --color-foreground: var(--foreground);\n --color-primary: var(--primary);\n --color-primary-foreground: var(--primary-foreground);\n --color-accent: var(--accent);\n --color-accent-foreground: var(--accent-foreground);\n --font-sans: var(--font-sans);\n}\n\n@layer base {\n button,\n [type=\"button\"],\n [type=\"submit\"],\n [type=\"reset\"] {\n cursor: pointer;\n }\n\n button:disabled,\n [type=\"button\"]:disabled,\n [type=\"submit\"]:disabled,\n [type=\"reset\"]:disabled {\n cursor: not-allowed;\n }\n}\n`;\n}\n\n/**\n * Full prebuild pipeline for a scaffolded site. Loads the site's .env, exchanges\n * the site secret for a token, then fetches franchise data and writes the\n * generated modules/assets (wrangler.toml, menu.ts, jsonld.ts, styles, logo).\n * Called from the site's thin scripts/prebuild.ts wrapper.\n */\nexport async function runPrebuild(): Promise<void> {\n\tconsole.log(\"running prebuild script...\");\n\n\t// Load .env here so the wrapper stays a one-liner and can't reintroduce the\n\t// import-order bug (env must be loaded before any env read below).\n\tloadEnvConfig(process.cwd());\n\n\t// regenerate deploy config from .env before any network work\n\twriteWranglerToml();\n\n\tconst token = await fetchSiteToken();\n\n\tconst encodedPayload = token.split(\".\")[1];\n\tif (!encodedPayload) {\n\t\tthrow new Error(\"site token is not a well-formed JWT (no payload segment)\");\n\t}\n\tconst payload = JSON.parse(Buffer.from(encodedPayload, \"base64url\").toString());\n\tconst franchiseId = payload.franchise_ids[0];\n\n\t// menu + franchise feed the JSON-LD; a menu *fetch* failure breaks the build\n\t// loudly, but an empty menu (new franchise) is tolerated inside menu().\n\tconst [menuData] = await Promise.all([\n\t\tmenu({ franchiseId, token }),\n\t\tlogo({ franchiseId, token }).catch((err) => console.error(\"logo failed:\", err)),\n\t\thours({ franchiseId, token }).catch((err) => console.error(\"hours failed:\", err)),\n\t\tstyles({ franchiseId, token }).catch((err) => console.error(\"styles failed:\", err)),\n\t]);\n\n\tawait jsonLd({ franchiseId, token }, menuData).catch((err) =>\n\t\tconsole.error(\"jsonLd failed:\", err),\n\t);\n\n\tconsole.log(\"prebuild script completed\");\n}\n","import type { Menu } from \"@zorgo/universal/utils/menuUtils\";\nimport type { ItemVariant, MenuItem } from \"@zorgo/universal/interfaces\";\n\n/** Franchise-level facts for the Restaurant node. Everything but `name` is\n * optional so the schema degrades gracefully when a field is missing. */\nexport interface RestaurantInfo {\n\tname: string;\n\turl?: string;\n\timage?: string;\n\tdescription?: string;\n\tservesCuisine?: string[];\n}\n\n// cents -> \"5.49\" (schema.org Offer.price is a string in major currency units)\nfunction priceString(cents: number): string {\n\treturn (cents / 100).toFixed(2);\n}\n\nfunction variantOffer(variant: ItemVariant) {\n\treturn {\n\t\t\"@type\": \"Offer\",\n\t\tprice: priceString(variant.display_price ?? variant.price),\n\t\tpriceCurrency: \"USD\",\n\t};\n}\n\nfunction menuItemNode(item: MenuItem) {\n\tconst node: Record<string, unknown> = {\n\t\t\"@type\": \"MenuItem\",\n\t\tname: item.name,\n\t};\n\tif (item.description) node.description = item.description;\n\t// one Offer for a single price, an array when the item has size/variant prices\n\tconst offers = item.variants.map(variantOffer);\n\tif (offers.length === 1) node.offers = offers[0];\n\telse if (offers.length > 1) node.offers = offers;\n\treturn node;\n}\n\n/**\n * Builds a standalone schema.org JSON-LD object for a single menu item, for\n * embedding in that item's `/menu/[slug]` page `<head>`. Reuses `menuItemNode`\n * (the same node shape used inside the Restaurant menu) and adds the\n * `@context` a top-level node needs. Pure — safe to run at build time.\n */\nexport function buildMenuItemJsonLd(item: MenuItem) {\n\treturn { \"@context\": \"https://schema.org\", ...menuItemNode(item) };\n}\n\n/**\n * Builds a schema.org Restaurant JSON-LD object from a prebuilt Menu and\n * franchise info. Categories become MenuSections; the items in each become\n * MenuItems. Pure — same inputs, same output — so it can run at prebuild time\n * and be embedded straight into the site's <head>.\n */\nexport function buildRestaurantJsonLd(menu: Menu, info: RestaurantInfo) {\n\tconst hasMenuSection = menu.categories.map((category) => {\n\t\tconst section: Record<string, unknown> = {\n\t\t\t\"@type\": \"MenuSection\",\n\t\t\tname: category.name,\n\t\t};\n\t\tconst items = menu.items\n\t\t\t.filter((item) => item.category_id === category.category_id)\n\t\t\t.map(menuItemNode);\n\t\tif (items.length) section.hasMenuItem = items;\n\t\treturn section;\n\t});\n\n\tconst restaurant: Record<string, unknown> = {\n\t\t\"@context\": \"https://schema.org\",\n\t\t\"@type\": \"Restaurant\",\n\t\tname: info.name,\n\t};\n\tif (info.url) restaurant.url = info.url;\n\tif (info.image) restaurant.image = info.image;\n\tif (info.description) restaurant.description = info.description;\n\tif (info.servesCuisine?.length) restaurant.servesCuisine = info.servesCuisine;\n\trestaurant.hasMenu = {\n\t\t\"@type\": \"Menu\",\n\t\tname: \"Menu\",\n\t\thasMenuSection,\n\t};\n\n\treturn restaurant;\n}\n"],"mappings":"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","names":["menu","path","menu"]}
|