[{"data":1,"prerenderedAt":4558},["ShallowReactive",2],{"content-query-CV40MF2ldj":3,"related-posts-/blog/nuxt-cloudflare-queues-and-vectorize-data-sync-pipeline-/blog/nuxt-cloudflare-vectorize-semantic-matching-/blog/build-and-deploy-nuxt3-static-site-with-pinia-and-stripe-checkout-on-firebase":4541},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"layout":10,"date":11,"intro":9,"preview_image":12,"featured_image":13,"openGraph":14,"breadcrumbs":20,"datePublished":11,"dateModified":11,"related":24,"body":28,"_type":4535,"_id":4536,"_source":4537,"_file":4538,"_stem":4539,"_extension":4540},"/blog/nuxt-and-cloudflare-vectorize-setting-up-d1-drizzle-and-workers-ai","blog",false,"en","Nuxt & Cloudflare Vectorize: Setting up D1, Drizzle, and Workers AI","Learn how to build a Nuxt application hosted on Cloudflare. We'll use direct bindings for the D1 database and Workers AI. We’ll also use Wrangler to configure Cloudflare bindings for our Nuxt application. We'll also use Drizzle ORM and Drizzle Kit for database schema and migrations.","article","2025-12-19","/nuxt-cloudflare-vectorize-d1-drizzle-setup/nuxt-cloudflare-vectorize-d1-drizzle-setup.webp","/nuxt-cloudflare-vectorize-d1-drizzle-setup/nuxt-cloudflare-vectorize-d1-drizzle-setup_featured.webp",{"image":15},{"url":16,"width":17,"height":18,"type":19},"/images/og/nuxt-cloudflare-vectorize-d1-drizzle-setup.png",1200,630,"image/png",[21],{"title":22,"url":23},"Blog","/blog/",[25,26,27],"/blog/nuxt-cloudflare-queues-and-vectorize-data-sync-pipeline","/blog/nuxt-cloudflare-vectorize-semantic-matching","/blog/build-and-deploy-nuxt3-static-site-with-pinia-and-stripe-checkout-on-firebase",{"type":29,"children":30,"toc":4522},"root",[31,41,47,99,104,140,145,152,157,162,167,174,179,212,217,227,236,241,255,261,266,385,398,613,619,632,734,739,775,780,1474,1479,1492,1498,1511,2685,2697,2702,2707,2720,2726,2731,2764,2776,2843,2856,2864,2877,3078,3099,3150,3155,3197,3201,3207,3212,3217,3226,3239,3244,3257,4317,4322,4385,4390,4399,4405,4411,4425,4430,4442,4453,4480,4485,4491,4503,4516],{"type":32,"tag":33,"props":34,"children":35},"element","p",{},[36],{"type":32,"tag":37,"props":38,"children":40},"img",{"alt":8,"height":18,"src":39,"title":8,"width":17},"/images/blog/articles/nuxt-cloudflare-vectorize-d1-drizzle-setup/nuxt-cloudflare-vectorize-d1-drizzle-setup.webp",[],{"type":32,"tag":33,"props":42,"children":43},{},[44],{"type":45,"value":46},"text","Recently, I started working on a project that requires several data normalisation features. One of which is getting external data and intelligently linking it with existing internal data. Data normalisation is a common requirement, especially recently, since we can augment searches and matches as we deem fit by vectorising our data and querying the vectors with embedding models.",{"type":32,"tag":33,"props":48,"children":49},{},[50,52,62,64,71,73,80,82,88,90,97],{"type":45,"value":51},"The project is built with ",{"type":32,"tag":53,"props":54,"children":59},"a",{"href":55,"rel":56,"target":58},"https://nuxt.com/",[57],"nofollow","_blank",[60],{"type":45,"value":61},"Nuxt",{"type":45,"value":63}," and hosted on ",{"type":32,"tag":53,"props":65,"children":68},{"href":66,"rel":67,"target":58},"https://workers.cloudflare.com/",[57],[69],{"type":45,"value":70},"Cloudflare",{"type":45,"value":72}," for Edge availability. I initially set it up through NuxtHub Admin for CI/CD and used two core module server composables: ",{"type":32,"tag":74,"props":75,"children":77},"code",{"className":76},[],[78],{"type":45,"value":79},"hubVectorize()",{"type":45,"value":81}," and ",{"type":32,"tag":74,"props":83,"children":85},{"className":84},[],[86],{"type":45,"value":87},"hubAi()",{"type":45,"value":89},". ",{"type":32,"tag":53,"props":91,"children":94},{"href":92,"rel":93,"target":58},"https://hub.nuxt.com/changelog/self-hosting-first",[57],[95],{"type":45,"value":96},"NuxtHub is sunsetting the NuxtHub Admin",{"type":45,"value":98}," at the end of this month. The core module no longer features Cloudflare’s automatic binding setup. Here, I share my experience building a demo application with similar AI requirements using Nuxt on Cloudflare, without the NuxtHub wrapper.",{"type":32,"tag":33,"props":100,"children":101},{},[102],{"type":45,"value":103},"This article is the first of the Nuxt & Cloudflare AI Vector Pipeline Series, a three-part series.",{"type":32,"tag":105,"props":106,"children":107},"ul",{},[108,118,129],{"type":32,"tag":109,"props":110,"children":111},"li",{},[112],{"type":32,"tag":113,"props":114,"children":115},"strong",{},[116],{"type":45,"value":117},"Part one -  Nuxt & Cloudflare Vectorize: Setting up D1, Drizzle, and Workers AI",{"type":32,"tag":109,"props":119,"children":120},{},[121,123],{"type":45,"value":122},"Part two - ",{"type":32,"tag":53,"props":124,"children":126},{"href":125},"/blog/nuxt-cloudflare-queues-and-vectorize-data-sync-pipeline/",[127],{"type":45,"value":128},"Nuxt & Cloudflare Queues: Building a Data Sync Pipeline using Vectorize",{"type":32,"tag":109,"props":130,"children":131},{},[132,134],{"type":45,"value":133},"Part three - ",{"type":32,"tag":53,"props":135,"children":137},{"href":136},"/blog/nuxt-cloudflare-vectorize-semantic-matching/",[138],{"type":45,"value":139},"Implementing semantic matching in Nuxt with Cloudflare Vectorize",{"type":32,"tag":33,"props":141,"children":142},{},[143],{"type":45,"value":144},"Let’s get going 😁",{"type":32,"tag":146,"props":147,"children":149},"h2",{"id":148},"building-an-ai-powered-real-estate-listing-nuxt-application",[150],{"type":45,"value":151},"Building an AI-powered real estate listing Nuxt application",{"type":32,"tag":33,"props":153,"children":154},{},[155],{"type":45,"value":156},"Together, we will build the backend of a fictitious real estate property listings aggregator website. If it were real, it would feature property listings from multiple real estate agencies. The app needs to regularly retrieve a feed of listings from these agencies and add them to the internal properties database. We need to link each agent property to a standardised location.",{"type":32,"tag":33,"props":158,"children":159},{},[160],{"type":45,"value":161},"The challenge with such scenarios is that the data feed may not be categorised as needed; for example, an agent may include the location using a postcode, some might omit the postcode and use the area names, and others might mention the location in the property listing title. In all cases, human errors can prevail, such as typos and incomplete words. We will use AI to match agents' property locations against our locations database to correctly categorise the properties internally.",{"type":32,"tag":33,"props":163,"children":164},{},[165],{"type":45,"value":166},"We will do this on a single Nuxt app, working with a Cloudflare AI worker, a Vector store, a D1 database, and a couple of Queue workers. Almost a monolith, but not precisely so. Since we are binding to multiple Cloudflare services, we can call this a distributed setup 😅.",{"type":32,"tag":168,"props":169,"children":171},"h3",{"id":170},"the-messy-data-challenge",[172],{"type":45,"value":173},"The messy data challenge",{"type":32,"tag":33,"props":175,"children":176},{},[177],{"type":45,"value":178},"For example, a single property in Shoreditch (an area of London) might appear in three completely different ways across our incoming feeds:",{"type":32,"tag":105,"props":180,"children":181},{},[182,192,202],{"type":32,"tag":109,"props":183,"children":184},{},[185,190],{"type":32,"tag":113,"props":186,"children":187},{},[188],{"type":45,"value":189},"Agent A:",{"type":45,"value":191}," Uses the postcode \"E1 6AN\" as a specific postcode attribute.",{"type":32,"tag":109,"props":193,"children":194},{},[195,200],{"type":32,"tag":113,"props":196,"children":197},{},[198],{"type":45,"value":199},"Agent B:",{"type":45,"value":201}," Uses the standard area name \"Shoreditch\" as a specific location attribute.",{"type":32,"tag":109,"props":203,"children":204},{},[205,210],{"type":32,"tag":113,"props":206,"children":207},{},[208],{"type":45,"value":209},"Agent C:",{"type":45,"value":211}," Does not include postcode or location but instead adds the location as part of the property title “Hidden Gem 💎 (around Shoreditch)”.",{"type":32,"tag":33,"props":213,"children":214},{},[215],{"type":45,"value":216},"While our database schema includes a list of postcodes mapped to areas, it lacks a native way to categorise a property's locations from a mix of postcodes, addresses, and descriptions, especially when they conflict or are misspelt. Without a smart normalisation layer, we cannot reliably categorise these listings, leaving our database fragmented and preventing us from maintaining a clean \"Source of Truth\" for our application.",{"type":32,"tag":218,"props":219,"children":226},"cta-section",{":sub-link":220,"button-text":221,"link":222,"sub-link-text":223,"text":224,"title":225},"/services/nuxt-consultant/","Discuss your project","/contact","Nuxt consultant","I guide you and your team through the challenges of building scalable systems, helping you prevent costly rewrites before they happen.","Facing complex Nuxt decisions?",[],{"type":32,"tag":228,"props":229,"children":230},"blockquote",{},[231],{"type":32,"tag":33,"props":232,"children":233},{},[234],{"type":45,"value":235},"💡 It is not always ideal to process business logic on an Edge provider such as Cloudflare, and it is often unnecessary. Let me know in the comments or on socials if you’d like me to write about some of the many alternative architectures that preserve Edge availability while reducing development and operational infrastructure costs.",{"type":32,"tag":33,"props":237,"children":238},{},[239],{"type":45,"value":240},"In this article, we’ll set up the internal database, schema migrations, and ORM, deploy it to a Cloudflare D1 database, and prepare the AI worker binding for later.",{"type":32,"tag":33,"props":242,"children":243},{},[244,246,253],{"type":45,"value":245},"The code for the entire demo application is publicly available on ",{"type":32,"tag":53,"props":247,"children":250},{"href":248,"rel":249,":target":58},"https://github.com/keithmifsud/nuxt-data-sync-pipeline-with-cloudflare-cron-queues-and-ai-vectorize-demo",[57],[251],{"type":45,"value":252},"GitHub: Nuxt & Cloudflare AI Vector Pipeline Series",{"type":45,"value":254}," - give it a ⭐.",{"type":32,"tag":146,"props":256,"children":258},{"id":257},"drizzle-db-schema-on-cloudflare-d1",[259],{"type":45,"value":260},"Drizzle DB Schema on Cloudflare D1",{"type":32,"tag":33,"props":262,"children":263},{},[264],{"type":45,"value":265},"Let’s start with a fresh Nuxt install, install Drizzle, Drizzle Kit for generating database schema migration files, and the Cloudflare / Wrangler dependencies:",{"type":32,"tag":267,"props":268,"children":273},"pre",{"className":269,"code":270,"language":271,"meta":272,"style":272},"language-shell shiki shiki-themes monokai","pnpm dlx nuxi@latest init nuxt-data-ai-sync\ncd nuxt-data-ai-sync\npnpm add drizzle-orm postgres\npnpm add -D drizzle-kit wrangler @types/node nitro-cloudflare-dev\n","shell","",[274],{"type":32,"tag":74,"props":275,"children":276},{"__ignoreMap":272},[277,310,324,347],{"type":32,"tag":278,"props":279,"children":282},"span",{"class":280,"line":281},"line",1,[283,289,295,300,305],{"type":32,"tag":278,"props":284,"children":286},{"style":285},"--shiki-default:#A6E22E",[287],{"type":45,"value":288},"pnpm",{"type":32,"tag":278,"props":290,"children":292},{"style":291},"--shiki-default:#E6DB74",[293],{"type":45,"value":294}," dlx",{"type":32,"tag":278,"props":296,"children":297},{"style":291},[298],{"type":45,"value":299}," nuxi@latest",{"type":32,"tag":278,"props":301,"children":302},{"style":291},[303],{"type":45,"value":304}," init",{"type":32,"tag":278,"props":306,"children":307},{"style":291},[308],{"type":45,"value":309}," nuxt-data-ai-sync\n",{"type":32,"tag":278,"props":311,"children":313},{"class":280,"line":312},2,[314,320],{"type":32,"tag":278,"props":315,"children":317},{"style":316},"--shiki-default:#66D9EF",[318],{"type":45,"value":319},"cd",{"type":32,"tag":278,"props":321,"children":322},{"style":291},[323],{"type":45,"value":309},{"type":32,"tag":278,"props":325,"children":327},{"class":280,"line":326},3,[328,332,337,342],{"type":32,"tag":278,"props":329,"children":330},{"style":285},[331],{"type":45,"value":288},{"type":32,"tag":278,"props":333,"children":334},{"style":291},[335],{"type":45,"value":336}," add",{"type":32,"tag":278,"props":338,"children":339},{"style":291},[340],{"type":45,"value":341}," drizzle-orm",{"type":32,"tag":278,"props":343,"children":344},{"style":291},[345],{"type":45,"value":346}," postgres\n",{"type":32,"tag":278,"props":348,"children":350},{"class":280,"line":349},4,[351,355,359,365,370,375,380],{"type":32,"tag":278,"props":352,"children":353},{"style":285},[354],{"type":45,"value":288},{"type":32,"tag":278,"props":356,"children":357},{"style":291},[358],{"type":45,"value":336},{"type":32,"tag":278,"props":360,"children":362},{"style":361},"--shiki-default:#AE81FF",[363],{"type":45,"value":364}," -D",{"type":32,"tag":278,"props":366,"children":367},{"style":291},[368],{"type":45,"value":369}," drizzle-kit",{"type":32,"tag":278,"props":371,"children":372},{"style":291},[373],{"type":45,"value":374}," wrangler",{"type":32,"tag":278,"props":376,"children":377},{"style":291},[378],{"type":45,"value":379}," @types/node",{"type":32,"tag":278,"props":381,"children":382},{"style":291},[383],{"type":45,"value":384}," nitro-cloudflare-dev\n",{"type":32,"tag":33,"props":386,"children":387},{},[388,390,396],{"type":45,"value":389},"We can also configure Nuxt to use Nitro’s experimental features, which we will need later. Mainly tasks and asyncContext. Your ",{"type":32,"tag":74,"props":391,"children":393},{"className":392},[],[394],{"type":45,"value":395},"/nuxt.config.ts",{"type":45,"value":397}," should include the correct Nitro preset and Nitro’s experimental features:",{"type":32,"tag":267,"props":399,"children":403},{"className":400,"code":401,"language":402,"meta":272,"style":272},"language-typescript shiki shiki-themes monokai","export default defineNuxtConfig({\n  compatibilityDate: '2025-12-06',\n  devtools: { enabled: true },\n  modules: [\n    'nitro-cloudflare-dev',\n  ],\n  nitro: {\n\n    preset: 'cloudflare_module',\n\n    experimental: {\n      tasks: true,\n      asyncContext: true,\n    },\n  },\n})\n","typescript",[404],{"type":32,"tag":74,"props":405,"children":406},{"__ignoreMap":272},[407,432,450,468,476,489,498,507,517,535,543,552,569,586,595,604],{"type":32,"tag":278,"props":408,"children":409},{"class":280,"line":281},[410,416,421,426],{"type":32,"tag":278,"props":411,"children":413},{"style":412},"--shiki-default:#F92672",[414],{"type":45,"value":415},"export",{"type":32,"tag":278,"props":417,"children":418},{"style":412},[419],{"type":45,"value":420}," default",{"type":32,"tag":278,"props":422,"children":423},{"style":285},[424],{"type":45,"value":425}," defineNuxtConfig",{"type":32,"tag":278,"props":427,"children":429},{"style":428},"--shiki-default:#F8F8F2",[430],{"type":45,"value":431},"({\n",{"type":32,"tag":278,"props":433,"children":434},{"class":280,"line":312},[435,440,445],{"type":32,"tag":278,"props":436,"children":437},{"style":428},[438],{"type":45,"value":439},"  compatibilityDate: ",{"type":32,"tag":278,"props":441,"children":442},{"style":291},[443],{"type":45,"value":444},"'2025-12-06'",{"type":32,"tag":278,"props":446,"children":447},{"style":428},[448],{"type":45,"value":449},",\n",{"type":32,"tag":278,"props":451,"children":452},{"class":280,"line":326},[453,458,463],{"type":32,"tag":278,"props":454,"children":455},{"style":428},[456],{"type":45,"value":457},"  devtools: { enabled: ",{"type":32,"tag":278,"props":459,"children":460},{"style":361},[461],{"type":45,"value":462},"true",{"type":32,"tag":278,"props":464,"children":465},{"style":428},[466],{"type":45,"value":467}," },\n",{"type":32,"tag":278,"props":469,"children":470},{"class":280,"line":349},[471],{"type":32,"tag":278,"props":472,"children":473},{"style":428},[474],{"type":45,"value":475},"  modules: [\n",{"type":32,"tag":278,"props":477,"children":479},{"class":280,"line":478},5,[480,485],{"type":32,"tag":278,"props":481,"children":482},{"style":291},[483],{"type":45,"value":484},"    'nitro-cloudflare-dev'",{"type":32,"tag":278,"props":486,"children":487},{"style":428},[488],{"type":45,"value":449},{"type":32,"tag":278,"props":490,"children":492},{"class":280,"line":491},6,[493],{"type":32,"tag":278,"props":494,"children":495},{"style":428},[496],{"type":45,"value":497},"  ],\n",{"type":32,"tag":278,"props":499,"children":501},{"class":280,"line":500},7,[502],{"type":32,"tag":278,"props":503,"children":504},{"style":428},[505],{"type":45,"value":506},"  nitro: {\n",{"type":32,"tag":278,"props":508,"children":510},{"class":280,"line":509},8,[511],{"type":32,"tag":278,"props":512,"children":514},{"emptyLinePlaceholder":513},true,[515],{"type":45,"value":516},"\n",{"type":32,"tag":278,"props":518,"children":520},{"class":280,"line":519},9,[521,526,531],{"type":32,"tag":278,"props":522,"children":523},{"style":428},[524],{"type":45,"value":525},"    preset: ",{"type":32,"tag":278,"props":527,"children":528},{"style":291},[529],{"type":45,"value":530},"'cloudflare_module'",{"type":32,"tag":278,"props":532,"children":533},{"style":428},[534],{"type":45,"value":449},{"type":32,"tag":278,"props":536,"children":538},{"class":280,"line":537},10,[539],{"type":32,"tag":278,"props":540,"children":541},{"emptyLinePlaceholder":513},[542],{"type":45,"value":516},{"type":32,"tag":278,"props":544,"children":546},{"class":280,"line":545},11,[547],{"type":32,"tag":278,"props":548,"children":549},{"style":428},[550],{"type":45,"value":551},"    experimental: {\n",{"type":32,"tag":278,"props":553,"children":555},{"class":280,"line":554},12,[556,561,565],{"type":32,"tag":278,"props":557,"children":558},{"style":428},[559],{"type":45,"value":560},"      tasks: ",{"type":32,"tag":278,"props":562,"children":563},{"style":361},[564],{"type":45,"value":462},{"type":32,"tag":278,"props":566,"children":567},{"style":428},[568],{"type":45,"value":449},{"type":32,"tag":278,"props":570,"children":572},{"class":280,"line":571},13,[573,578,582],{"type":32,"tag":278,"props":574,"children":575},{"style":428},[576],{"type":45,"value":577},"      asyncContext: ",{"type":32,"tag":278,"props":579,"children":580},{"style":361},[581],{"type":45,"value":462},{"type":32,"tag":278,"props":583,"children":584},{"style":428},[585],{"type":45,"value":449},{"type":32,"tag":278,"props":587,"children":589},{"class":280,"line":588},14,[590],{"type":32,"tag":278,"props":591,"children":592},{"style":428},[593],{"type":45,"value":594},"    },\n",{"type":32,"tag":278,"props":596,"children":598},{"class":280,"line":597},15,[599],{"type":32,"tag":278,"props":600,"children":601},{"style":428},[602],{"type":45,"value":603},"  },\n",{"type":32,"tag":278,"props":605,"children":607},{"class":280,"line":606},16,[608],{"type":32,"tag":278,"props":609,"children":610},{"style":428},[611],{"type":45,"value":612},"})\n",{"type":32,"tag":168,"props":614,"children":616},{"id":615},"deploy-nuxt-as-a-worker-on-cloudflare",[617],{"type":45,"value":618},"Deploy Nuxt as a worker on Cloudflare",{"type":32,"tag":33,"props":620,"children":621},{},[622,624,630],{"type":45,"value":623},"Now’s a good time to add the initial Wrangler configuration so we can deploy to Cloudflare for the first time. Create the ",{"type":32,"tag":74,"props":625,"children":627},{"className":626},[],[628],{"type":45,"value":629},"/wrangler.toml",{"type":45,"value":631}," file at the project’s root and fill in the initial content:",{"type":32,"tag":267,"props":633,"children":637},{"className":634,"code":635,"language":636,"meta":272,"style":272},"language-toml shiki shiki-themes monokai","name = \"property-sync-app\"\nmain = \"./.output/server/index.mjs\"\ncompatibility_date = \"2025-08-02\"\naccount_id = \"xxxx\" # \u003C-- your account ID here\n\nassets = { directory = \"./.output/public\", binding = \"ASSETS\" }\n","toml",[638],{"type":32,"tag":74,"props":639,"children":640},{"__ignoreMap":272},[641,654,667,680,699,706],{"type":32,"tag":278,"props":642,"children":643},{"class":280,"line":281},[644,649],{"type":32,"tag":278,"props":645,"children":646},{"style":428},[647],{"type":45,"value":648},"name = ",{"type":32,"tag":278,"props":650,"children":651},{"style":291},[652],{"type":45,"value":653},"\"property-sync-app\"\n",{"type":32,"tag":278,"props":655,"children":656},{"class":280,"line":312},[657,662],{"type":32,"tag":278,"props":658,"children":659},{"style":428},[660],{"type":45,"value":661},"main = ",{"type":32,"tag":278,"props":663,"children":664},{"style":291},[665],{"type":45,"value":666},"\"./.output/server/index.mjs\"\n",{"type":32,"tag":278,"props":668,"children":669},{"class":280,"line":326},[670,675],{"type":32,"tag":278,"props":671,"children":672},{"style":428},[673],{"type":45,"value":674},"compatibility_date = ",{"type":32,"tag":278,"props":676,"children":677},{"style":291},[678],{"type":45,"value":679},"\"2025-08-02\"\n",{"type":32,"tag":278,"props":681,"children":682},{"class":280,"line":349},[683,688,693],{"type":32,"tag":278,"props":684,"children":685},{"style":428},[686],{"type":45,"value":687},"account_id = ",{"type":32,"tag":278,"props":689,"children":690},{"style":291},[691],{"type":45,"value":692},"\"xxxx\"",{"type":32,"tag":278,"props":694,"children":696},{"style":695},"--shiki-default:#88846F",[697],{"type":45,"value":698}," # \u003C-- your account ID here\n",{"type":32,"tag":278,"props":700,"children":701},{"class":280,"line":478},[702],{"type":32,"tag":278,"props":703,"children":704},{"emptyLinePlaceholder":513},[705],{"type":45,"value":516},{"type":32,"tag":278,"props":707,"children":708},{"class":280,"line":491},[709,714,719,724,729],{"type":32,"tag":278,"props":710,"children":711},{"style":428},[712],{"type":45,"value":713},"assets = { directory = ",{"type":32,"tag":278,"props":715,"children":716},{"style":291},[717],{"type":45,"value":718},"\"./.output/public\"",{"type":32,"tag":278,"props":720,"children":721},{"style":428},[722],{"type":45,"value":723},", binding = ",{"type":32,"tag":278,"props":725,"children":726},{"style":291},[727],{"type":45,"value":728},"\"ASSETS\"",{"type":32,"tag":278,"props":730,"children":731},{"style":428},[732],{"type":45,"value":733}," }\n",{"type":32,"tag":33,"props":735,"children":736},{},[737],{"type":45,"value":738},"Now we can build and deploy our so far useless app on Cloudflare:",{"type":32,"tag":267,"props":740,"children":742},{"className":269,"code":741,"language":271,"meta":272,"style":272},"pnpm build\nnpx wrangler deploy\n",[743],{"type":32,"tag":74,"props":744,"children":745},{"__ignoreMap":272},[746,758],{"type":32,"tag":278,"props":747,"children":748},{"class":280,"line":281},[749,753],{"type":32,"tag":278,"props":750,"children":751},{"style":285},[752],{"type":45,"value":288},{"type":32,"tag":278,"props":754,"children":755},{"style":291},[756],{"type":45,"value":757}," build\n",{"type":32,"tag":278,"props":759,"children":760},{"class":280,"line":312},[761,766,770],{"type":32,"tag":278,"props":762,"children":763},{"style":285},[764],{"type":45,"value":765},"npx",{"type":32,"tag":278,"props":767,"children":768},{"style":291},[769],{"type":45,"value":374},{"type":32,"tag":278,"props":771,"children":772},{"style":291},[773],{"type":45,"value":774}," deploy\n",{"type":32,"tag":33,"props":776,"children":777},{},[778],{"type":45,"value":779},"The output should look similar to the following;",{"type":32,"tag":267,"props":781,"children":785},{"className":782,"code":783,"language":784,"meta":272,"style":272},"language-bash shiki shiki-themes monokai","⛅️ wrangler 4.53.0\n───────────────────\n🌀 Building list of assets...\n✨ Read 14 files from the assets directory /home/keithmifsud/projects/keithmifsud/nuxt-data-ai-sync/.output/public\n🌀 Starting asset upload...\n🌀 Found 10 new or modified static assets to upload. Proceeding with upload...\n+ /robots.txt\n+ /_nuxt/error-500.pPqbDRtt.css\n+ /favicon.ico\n+ /_nuxt/b-_NRaZA.js\n+ /_nuxt/builds/latest.json\n+ /_nuxt/error-404.ClksgLvO.css\n+ /_nuxt/entry.ClxZN-oh.css\n+ /_nuxt/builds/meta/23e8b19f-c1c2-45ca-83bc-9cad6a8adfcf.json\n+ /_nuxt/Cv0oBIJc.js\n+ /_nuxt/BVjrWf75.js\nUploaded 3 of 10 assets\nUploaded 6 of 10 assets\nUploaded 10 of 10 assets\n✨ Success! Uploaded 10 files (3.21 sec)\n\nTotal Upload: 685.31 KiB / gzip: 184.57 KiB\nWorker Startup Time: 7 ms\nYour Worker has access to the following bindings:\nBinding            Resource      \nenv.ASSETS         Assets        \n\nUploaded property-sync-app (15.49 sec)\nDeployed property-sync-app triggers (4.65 sec)\n  https://property-sync-app.mifsud-k.workers.dev\nCurrent Version ID: 3d88b77c-2d1f-4c8e-8f01-22823a4a1c61\n\n","bash",[786],{"type":32,"tag":74,"props":787,"children":788},{"__ignoreMap":272},[789,806,814,842,890,912,977,990,1002,1014,1026,1038,1050,1062,1074,1086,1098,1125,1150,1174,1215,1223,1267,1296,1338,1357,1376,1384,1410,1441,1450],{"type":32,"tag":278,"props":790,"children":791},{"class":280,"line":281},[792,797,801],{"type":32,"tag":278,"props":793,"children":794},{"style":285},[795],{"type":45,"value":796},"⛅️",{"type":32,"tag":278,"props":798,"children":799},{"style":291},[800],{"type":45,"value":374},{"type":32,"tag":278,"props":802,"children":803},{"style":361},[804],{"type":45,"value":805}," 4.53.0\n",{"type":32,"tag":278,"props":807,"children":808},{"class":280,"line":312},[809],{"type":32,"tag":278,"props":810,"children":811},{"style":285},[812],{"type":45,"value":813},"───────────────────\n",{"type":32,"tag":278,"props":815,"children":816},{"class":280,"line":326},[817,822,827,832,837],{"type":32,"tag":278,"props":818,"children":819},{"style":285},[820],{"type":45,"value":821},"🌀",{"type":32,"tag":278,"props":823,"children":824},{"style":291},[825],{"type":45,"value":826}," Building",{"type":32,"tag":278,"props":828,"children":829},{"style":291},[830],{"type":45,"value":831}," list",{"type":32,"tag":278,"props":833,"children":834},{"style":291},[835],{"type":45,"value":836}," of",{"type":32,"tag":278,"props":838,"children":839},{"style":291},[840],{"type":45,"value":841}," assets...\n",{"type":32,"tag":278,"props":843,"children":844},{"class":280,"line":349},[845,850,855,860,865,870,875,880,885],{"type":32,"tag":278,"props":846,"children":847},{"style":285},[848],{"type":45,"value":849},"✨",{"type":32,"tag":278,"props":851,"children":852},{"style":291},[853],{"type":45,"value":854}," Read",{"type":32,"tag":278,"props":856,"children":857},{"style":361},[858],{"type":45,"value":859}," 14",{"type":32,"tag":278,"props":861,"children":862},{"style":291},[863],{"type":45,"value":864}," files",{"type":32,"tag":278,"props":866,"children":867},{"style":291},[868],{"type":45,"value":869}," from",{"type":32,"tag":278,"props":871,"children":872},{"style":291},[873],{"type":45,"value":874}," the",{"type":32,"tag":278,"props":876,"children":877},{"style":291},[878],{"type":45,"value":879}," assets",{"type":32,"tag":278,"props":881,"children":882},{"style":291},[883],{"type":45,"value":884}," directory",{"type":32,"tag":278,"props":886,"children":887},{"style":291},[888],{"type":45,"value":889}," /home/keithmifsud/projects/keithmifsud/nuxt-data-ai-sync/.output/public\n",{"type":32,"tag":278,"props":891,"children":892},{"class":280,"line":478},[893,897,902,907],{"type":32,"tag":278,"props":894,"children":895},{"style":285},[896],{"type":45,"value":821},{"type":32,"tag":278,"props":898,"children":899},{"style":291},[900],{"type":45,"value":901}," Starting",{"type":32,"tag":278,"props":903,"children":904},{"style":291},[905],{"type":45,"value":906}," asset",{"type":32,"tag":278,"props":908,"children":909},{"style":291},[910],{"type":45,"value":911}," upload...\n",{"type":32,"tag":278,"props":913,"children":914},{"class":280,"line":491},[915,919,924,929,934,939,944,949,953,958,963,968,973],{"type":32,"tag":278,"props":916,"children":917},{"style":285},[918],{"type":45,"value":821},{"type":32,"tag":278,"props":920,"children":921},{"style":291},[922],{"type":45,"value":923}," Found",{"type":32,"tag":278,"props":925,"children":926},{"style":361},[927],{"type":45,"value":928}," 10",{"type":32,"tag":278,"props":930,"children":931},{"style":291},[932],{"type":45,"value":933}," new",{"type":32,"tag":278,"props":935,"children":936},{"style":291},[937],{"type":45,"value":938}," or",{"type":32,"tag":278,"props":940,"children":941},{"style":291},[942],{"type":45,"value":943}," modified",{"type":32,"tag":278,"props":945,"children":946},{"style":291},[947],{"type":45,"value":948}," static",{"type":32,"tag":278,"props":950,"children":951},{"style":291},[952],{"type":45,"value":879},{"type":32,"tag":278,"props":954,"children":955},{"style":291},[956],{"type":45,"value":957}," to",{"type":32,"tag":278,"props":959,"children":960},{"style":291},[961],{"type":45,"value":962}," upload.",{"type":32,"tag":278,"props":964,"children":965},{"style":291},[966],{"type":45,"value":967}," Proceeding",{"type":32,"tag":278,"props":969,"children":970},{"style":291},[971],{"type":45,"value":972}," with",{"type":32,"tag":278,"props":974,"children":975},{"style":291},[976],{"type":45,"value":911},{"type":32,"tag":278,"props":978,"children":979},{"class":280,"line":500},[980,985],{"type":32,"tag":278,"props":981,"children":982},{"style":285},[983],{"type":45,"value":984},"+",{"type":32,"tag":278,"props":986,"children":987},{"style":291},[988],{"type":45,"value":989}," /robots.txt\n",{"type":32,"tag":278,"props":991,"children":992},{"class":280,"line":509},[993,997],{"type":32,"tag":278,"props":994,"children":995},{"style":285},[996],{"type":45,"value":984},{"type":32,"tag":278,"props":998,"children":999},{"style":291},[1000],{"type":45,"value":1001}," /_nuxt/error-500.pPqbDRtt.css\n",{"type":32,"tag":278,"props":1003,"children":1004},{"class":280,"line":519},[1005,1009],{"type":32,"tag":278,"props":1006,"children":1007},{"style":285},[1008],{"type":45,"value":984},{"type":32,"tag":278,"props":1010,"children":1011},{"style":291},[1012],{"type":45,"value":1013}," /favicon.ico\n",{"type":32,"tag":278,"props":1015,"children":1016},{"class":280,"line":537},[1017,1021],{"type":32,"tag":278,"props":1018,"children":1019},{"style":285},[1020],{"type":45,"value":984},{"type":32,"tag":278,"props":1022,"children":1023},{"style":291},[1024],{"type":45,"value":1025}," /_nuxt/b-_NRaZA.js\n",{"type":32,"tag":278,"props":1027,"children":1028},{"class":280,"line":545},[1029,1033],{"type":32,"tag":278,"props":1030,"children":1031},{"style":285},[1032],{"type":45,"value":984},{"type":32,"tag":278,"props":1034,"children":1035},{"style":291},[1036],{"type":45,"value":1037}," /_nuxt/builds/latest.json\n",{"type":32,"tag":278,"props":1039,"children":1040},{"class":280,"line":554},[1041,1045],{"type":32,"tag":278,"props":1042,"children":1043},{"style":285},[1044],{"type":45,"value":984},{"type":32,"tag":278,"props":1046,"children":1047},{"style":291},[1048],{"type":45,"value":1049}," /_nuxt/error-404.ClksgLvO.css\n",{"type":32,"tag":278,"props":1051,"children":1052},{"class":280,"line":571},[1053,1057],{"type":32,"tag":278,"props":1054,"children":1055},{"style":285},[1056],{"type":45,"value":984},{"type":32,"tag":278,"props":1058,"children":1059},{"style":291},[1060],{"type":45,"value":1061}," /_nuxt/entry.ClxZN-oh.css\n",{"type":32,"tag":278,"props":1063,"children":1064},{"class":280,"line":588},[1065,1069],{"type":32,"tag":278,"props":1066,"children":1067},{"style":285},[1068],{"type":45,"value":984},{"type":32,"tag":278,"props":1070,"children":1071},{"style":291},[1072],{"type":45,"value":1073}," /_nuxt/builds/meta/23e8b19f-c1c2-45ca-83bc-9cad6a8adfcf.json\n",{"type":32,"tag":278,"props":1075,"children":1076},{"class":280,"line":597},[1077,1081],{"type":32,"tag":278,"props":1078,"children":1079},{"style":285},[1080],{"type":45,"value":984},{"type":32,"tag":278,"props":1082,"children":1083},{"style":291},[1084],{"type":45,"value":1085}," /_nuxt/Cv0oBIJc.js\n",{"type":32,"tag":278,"props":1087,"children":1088},{"class":280,"line":606},[1089,1093],{"type":32,"tag":278,"props":1090,"children":1091},{"style":285},[1092],{"type":45,"value":984},{"type":32,"tag":278,"props":1094,"children":1095},{"style":291},[1096],{"type":45,"value":1097}," /_nuxt/BVjrWf75.js\n",{"type":32,"tag":278,"props":1099,"children":1101},{"class":280,"line":1100},17,[1102,1107,1112,1116,1120],{"type":32,"tag":278,"props":1103,"children":1104},{"style":285},[1105],{"type":45,"value":1106},"Uploaded",{"type":32,"tag":278,"props":1108,"children":1109},{"style":361},[1110],{"type":45,"value":1111}," 3",{"type":32,"tag":278,"props":1113,"children":1114},{"style":291},[1115],{"type":45,"value":836},{"type":32,"tag":278,"props":1117,"children":1118},{"style":361},[1119],{"type":45,"value":928},{"type":32,"tag":278,"props":1121,"children":1122},{"style":291},[1123],{"type":45,"value":1124}," assets\n",{"type":32,"tag":278,"props":1126,"children":1128},{"class":280,"line":1127},18,[1129,1133,1138,1142,1146],{"type":32,"tag":278,"props":1130,"children":1131},{"style":285},[1132],{"type":45,"value":1106},{"type":32,"tag":278,"props":1134,"children":1135},{"style":361},[1136],{"type":45,"value":1137}," 6",{"type":32,"tag":278,"props":1139,"children":1140},{"style":291},[1141],{"type":45,"value":836},{"type":32,"tag":278,"props":1143,"children":1144},{"style":361},[1145],{"type":45,"value":928},{"type":32,"tag":278,"props":1147,"children":1148},{"style":291},[1149],{"type":45,"value":1124},{"type":32,"tag":278,"props":1151,"children":1153},{"class":280,"line":1152},19,[1154,1158,1162,1166,1170],{"type":32,"tag":278,"props":1155,"children":1156},{"style":285},[1157],{"type":45,"value":1106},{"type":32,"tag":278,"props":1159,"children":1160},{"style":361},[1161],{"type":45,"value":928},{"type":32,"tag":278,"props":1163,"children":1164},{"style":291},[1165],{"type":45,"value":836},{"type":32,"tag":278,"props":1167,"children":1168},{"style":361},[1169],{"type":45,"value":928},{"type":32,"tag":278,"props":1171,"children":1172},{"style":291},[1173],{"type":45,"value":1124},{"type":32,"tag":278,"props":1175,"children":1177},{"class":280,"line":1176},20,[1178,1182,1187,1192,1196,1200,1205,1210],{"type":32,"tag":278,"props":1179,"children":1180},{"style":285},[1181],{"type":45,"value":849},{"type":32,"tag":278,"props":1183,"children":1184},{"style":291},[1185],{"type":45,"value":1186}," Success!",{"type":32,"tag":278,"props":1188,"children":1189},{"style":291},[1190],{"type":45,"value":1191}," Uploaded",{"type":32,"tag":278,"props":1193,"children":1194},{"style":361},[1195],{"type":45,"value":928},{"type":32,"tag":278,"props":1197,"children":1198},{"style":291},[1199],{"type":45,"value":864},{"type":32,"tag":278,"props":1201,"children":1202},{"style":428},[1203],{"type":45,"value":1204}," (3.21 ",{"type":32,"tag":278,"props":1206,"children":1207},{"style":291},[1208],{"type":45,"value":1209},"sec",{"type":32,"tag":278,"props":1211,"children":1212},{"style":428},[1213],{"type":45,"value":1214},")\n",{"type":32,"tag":278,"props":1216,"children":1218},{"class":280,"line":1217},21,[1219],{"type":32,"tag":278,"props":1220,"children":1221},{"emptyLinePlaceholder":513},[1222],{"type":45,"value":516},{"type":32,"tag":278,"props":1224,"children":1226},{"class":280,"line":1225},22,[1227,1232,1237,1242,1247,1252,1257,1262],{"type":32,"tag":278,"props":1228,"children":1229},{"style":285},[1230],{"type":45,"value":1231},"Total",{"type":32,"tag":278,"props":1233,"children":1234},{"style":291},[1235],{"type":45,"value":1236}," Upload:",{"type":32,"tag":278,"props":1238,"children":1239},{"style":361},[1240],{"type":45,"value":1241}," 685.31",{"type":32,"tag":278,"props":1243,"children":1244},{"style":291},[1245],{"type":45,"value":1246}," KiB",{"type":32,"tag":278,"props":1248,"children":1249},{"style":291},[1250],{"type":45,"value":1251}," /",{"type":32,"tag":278,"props":1253,"children":1254},{"style":291},[1255],{"type":45,"value":1256}," gzip:",{"type":32,"tag":278,"props":1258,"children":1259},{"style":361},[1260],{"type":45,"value":1261}," 184.57",{"type":32,"tag":278,"props":1263,"children":1264},{"style":291},[1265],{"type":45,"value":1266}," KiB\n",{"type":32,"tag":278,"props":1268,"children":1270},{"class":280,"line":1269},23,[1271,1276,1281,1286,1291],{"type":32,"tag":278,"props":1272,"children":1273},{"style":285},[1274],{"type":45,"value":1275},"Worker",{"type":32,"tag":278,"props":1277,"children":1278},{"style":291},[1279],{"type":45,"value":1280}," Startup",{"type":32,"tag":278,"props":1282,"children":1283},{"style":291},[1284],{"type":45,"value":1285}," Time:",{"type":32,"tag":278,"props":1287,"children":1288},{"style":361},[1289],{"type":45,"value":1290}," 7",{"type":32,"tag":278,"props":1292,"children":1293},{"style":291},[1294],{"type":45,"value":1295}," ms\n",{"type":32,"tag":278,"props":1297,"children":1299},{"class":280,"line":1298},24,[1300,1305,1310,1315,1320,1324,1328,1333],{"type":32,"tag":278,"props":1301,"children":1302},{"style":285},[1303],{"type":45,"value":1304},"Your",{"type":32,"tag":278,"props":1306,"children":1307},{"style":291},[1308],{"type":45,"value":1309}," Worker",{"type":32,"tag":278,"props":1311,"children":1312},{"style":291},[1313],{"type":45,"value":1314}," has",{"type":32,"tag":278,"props":1316,"children":1317},{"style":291},[1318],{"type":45,"value":1319}," access",{"type":32,"tag":278,"props":1321,"children":1322},{"style":291},[1323],{"type":45,"value":957},{"type":32,"tag":278,"props":1325,"children":1326},{"style":291},[1327],{"type":45,"value":874},{"type":32,"tag":278,"props":1329,"children":1330},{"style":291},[1331],{"type":45,"value":1332}," following",{"type":32,"tag":278,"props":1334,"children":1335},{"style":291},[1336],{"type":45,"value":1337}," bindings:\n",{"type":32,"tag":278,"props":1339,"children":1341},{"class":280,"line":1340},25,[1342,1347,1352],{"type":32,"tag":278,"props":1343,"children":1344},{"style":285},[1345],{"type":45,"value":1346},"Binding",{"type":32,"tag":278,"props":1348,"children":1349},{"style":291},[1350],{"type":45,"value":1351},"            Resource",{"type":32,"tag":278,"props":1353,"children":1354},{"style":428},[1355],{"type":45,"value":1356},"      \n",{"type":32,"tag":278,"props":1358,"children":1360},{"class":280,"line":1359},26,[1361,1366,1371],{"type":32,"tag":278,"props":1362,"children":1363},{"style":285},[1364],{"type":45,"value":1365},"env.ASSETS",{"type":32,"tag":278,"props":1367,"children":1368},{"style":291},[1369],{"type":45,"value":1370},"         Assets",{"type":32,"tag":278,"props":1372,"children":1373},{"style":428},[1374],{"type":45,"value":1375},"        \n",{"type":32,"tag":278,"props":1377,"children":1379},{"class":280,"line":1378},27,[1380],{"type":32,"tag":278,"props":1381,"children":1382},{"emptyLinePlaceholder":513},[1383],{"type":45,"value":516},{"type":32,"tag":278,"props":1385,"children":1387},{"class":280,"line":1386},28,[1388,1392,1397,1402,1406],{"type":32,"tag":278,"props":1389,"children":1390},{"style":285},[1391],{"type":45,"value":1106},{"type":32,"tag":278,"props":1393,"children":1394},{"style":291},[1395],{"type":45,"value":1396}," property-sync-app",{"type":32,"tag":278,"props":1398,"children":1399},{"style":428},[1400],{"type":45,"value":1401}," (15.49 ",{"type":32,"tag":278,"props":1403,"children":1404},{"style":291},[1405],{"type":45,"value":1209},{"type":32,"tag":278,"props":1407,"children":1408},{"style":428},[1409],{"type":45,"value":1214},{"type":32,"tag":278,"props":1411,"children":1413},{"class":280,"line":1412},29,[1414,1419,1423,1428,1433,1437],{"type":32,"tag":278,"props":1415,"children":1416},{"style":285},[1417],{"type":45,"value":1418},"Deployed",{"type":32,"tag":278,"props":1420,"children":1421},{"style":291},[1422],{"type":45,"value":1396},{"type":32,"tag":278,"props":1424,"children":1425},{"style":291},[1426],{"type":45,"value":1427}," triggers",{"type":32,"tag":278,"props":1429,"children":1430},{"style":428},[1431],{"type":45,"value":1432}," (4.65 ",{"type":32,"tag":278,"props":1434,"children":1435},{"style":291},[1436],{"type":45,"value":1209},{"type":32,"tag":278,"props":1438,"children":1439},{"style":428},[1440],{"type":45,"value":1214},{"type":32,"tag":278,"props":1442,"children":1444},{"class":280,"line":1443},30,[1445],{"type":32,"tag":278,"props":1446,"children":1447},{"style":285},[1448],{"type":45,"value":1449},"  https://property-sync-app.mifsud-k.workers.dev\n",{"type":32,"tag":278,"props":1451,"children":1453},{"class":280,"line":1452},31,[1454,1459,1464,1469],{"type":32,"tag":278,"props":1455,"children":1456},{"style":285},[1457],{"type":45,"value":1458},"Current",{"type":32,"tag":278,"props":1460,"children":1461},{"style":291},[1462],{"type":45,"value":1463}," Version",{"type":32,"tag":278,"props":1465,"children":1466},{"style":291},[1467],{"type":45,"value":1468}," ID:",{"type":32,"tag":278,"props":1470,"children":1471},{"style":291},[1472],{"type":45,"value":1473}," 3d88b77c-2d1f-4c8e-8f01-22823a4a1c61\n",{"type":32,"tag":33,"props":1475,"children":1476},{},[1477],{"type":45,"value":1478},"Thus, you can test that the URL shows the Nuxt welcome page.",{"type":32,"tag":33,"props":1480,"children":1481},{},[1482,1484,1490],{"type":45,"value":1483},"I like to get the noticeable housekeeping tasks tackled as soon as possible. Since we will definitely be dealing with queued processes, we will be working across different contexts (Cloudflare Workers using the V8 Engine and Nitro Runtime using Node.js) asynchronously. Give the worker settings in Cloudflare’s UI a once-over and make sure your runtime has the ",{"type":32,"tag":74,"props":1485,"children":1487},{"className":1486},[],[1488],{"type":45,"value":1489},"nodejs_compat",{"type":45,"value":1491}," flag enabled.",{"type":32,"tag":168,"props":1493,"children":1495},{"id":1494},"modelling-the-database-schema-using-drizzle-orm",[1496],{"type":45,"value":1497},"Modelling the database schema using Drizzle ORM",{"type":32,"tag":33,"props":1499,"children":1500},{},[1501,1503,1509],{"type":45,"value":1502},"Since our schema is relatively small, we can place it in a single file. Create ",{"type":32,"tag":74,"props":1504,"children":1506},{"className":1505},[],[1507],{"type":45,"value":1508},"/server/database/schema.ts",{"type":45,"value":1510}," with:",{"type":32,"tag":267,"props":1512,"children":1514},{"className":400,"code":1513,"language":402,"meta":272,"style":272},"import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core'\nimport { relations, sql } from 'drizzle-orm'\n\nconst generateUUID = () => crypto.randomUUID()\n\n// Agents\nexport const agents = sqliteTable('agents', {\n  id: text('id').primaryKey().$defaultFn(generateUUID),\n  name: text('name').notNull(),\n  apiRoute: text('api_route').notNull().unique(),\n  createdAt: text('created_at').default(sql`(CURRENT_TIMESTAMP)`),\n})\n\n// Locations (Canonical)\nexport const locations = sqliteTable('locations', {\n  id: text('id').primaryKey().$defaultFn(generateUUID),\n  name: text('name').notNull(),\n  // D1/SQLite stores arrays as strings. We handle parsing in the app.\n  postcodes: text('postcodes', { mode: 'json' }).$type\u003Cstring[]>().notNull(),\n  createdAt: text('created_at').default(sql`(CURRENT_TIMESTAMP)`),\n})\n\n// Properties (Incoming)\nexport const properties = sqliteTable('properties', {\n  id: text('id').primaryKey().$defaultFn(generateUUID),\n  externalRef: text('external_ref').notNull(), // Agent's ID for the property\n  agentId: text('agent_id').references(() => agents.id).notNull(),\n  locationId: text('location_id').references(() => locations.id).notNull(),\n  title: text('title').notNull(),\n  originalLocation: text('original_location').notNull(), // The messy string\n  createdAt: text('created_at').default(sql`(CURRENT_TIMESTAMP)`),\n})\n\nexport const agentsRelations = relations(agents, ({ many }) => ({\n  properties: many(properties),\n}))\n\nexport const propertiesRelations = relations(properties, ({ one }) => ({\n  agent: one(agents, {\n    fields: [properties.agentId],\n    references: [agents.id],\n  }),\n  location: one(locations, {\n    fields: [properties.locationId],\n    references: [locations.id],\n  }),\n}))\n\n",[1515],{"type":32,"tag":74,"props":1516,"children":1517},{"__ignoreMap":272},[1518,1541,1562,1569,1613,1620,1628,1670,1716,1751,1793,1842,1849,1856,1864,1901,1940,1971,1979,2043,2086,2093,2100,2108,2145,2184,2223,2275,2325,2358,2396,2439,2447,2455,2506,2524,2533,2541,2588,2606,2615,2624,2633,2651,2660,2669,2677],{"type":32,"tag":278,"props":1519,"children":1520},{"class":280,"line":281},[1521,1526,1531,1536],{"type":32,"tag":278,"props":1522,"children":1523},{"style":412},[1524],{"type":45,"value":1525},"import",{"type":32,"tag":278,"props":1527,"children":1528},{"style":428},[1529],{"type":45,"value":1530}," { sqliteTable, text, integer } ",{"type":32,"tag":278,"props":1532,"children":1533},{"style":412},[1534],{"type":45,"value":1535},"from",{"type":32,"tag":278,"props":1537,"children":1538},{"style":291},[1539],{"type":45,"value":1540}," 'drizzle-orm/sqlite-core'\n",{"type":32,"tag":278,"props":1542,"children":1543},{"class":280,"line":312},[1544,1548,1553,1557],{"type":32,"tag":278,"props":1545,"children":1546},{"style":412},[1547],{"type":45,"value":1525},{"type":32,"tag":278,"props":1549,"children":1550},{"style":428},[1551],{"type":45,"value":1552}," { relations, sql } ",{"type":32,"tag":278,"props":1554,"children":1555},{"style":412},[1556],{"type":45,"value":1535},{"type":32,"tag":278,"props":1558,"children":1559},{"style":291},[1560],{"type":45,"value":1561}," 'drizzle-orm'\n",{"type":32,"tag":278,"props":1563,"children":1564},{"class":280,"line":326},[1565],{"type":32,"tag":278,"props":1566,"children":1567},{"emptyLinePlaceholder":513},[1568],{"type":45,"value":516},{"type":32,"tag":278,"props":1570,"children":1571},{"class":280,"line":349},[1572,1578,1583,1588,1593,1598,1603,1608],{"type":32,"tag":278,"props":1573,"children":1575},{"style":1574},"--shiki-default:#66D9EF;--shiki-default-font-style:italic",[1576],{"type":45,"value":1577},"const",{"type":32,"tag":278,"props":1579,"children":1580},{"style":285},[1581],{"type":45,"value":1582}," generateUUID",{"type":32,"tag":278,"props":1584,"children":1585},{"style":412},[1586],{"type":45,"value":1587}," =",{"type":32,"tag":278,"props":1589,"children":1590},{"style":428},[1591],{"type":45,"value":1592}," () ",{"type":32,"tag":278,"props":1594,"children":1595},{"style":1574},[1596],{"type":45,"value":1597},"=>",{"type":32,"tag":278,"props":1599,"children":1600},{"style":428},[1601],{"type":45,"value":1602}," crypto.",{"type":32,"tag":278,"props":1604,"children":1605},{"style":285},[1606],{"type":45,"value":1607},"randomUUID",{"type":32,"tag":278,"props":1609,"children":1610},{"style":428},[1611],{"type":45,"value":1612},"()\n",{"type":32,"tag":278,"props":1614,"children":1615},{"class":280,"line":478},[1616],{"type":32,"tag":278,"props":1617,"children":1618},{"emptyLinePlaceholder":513},[1619],{"type":45,"value":516},{"type":32,"tag":278,"props":1621,"children":1622},{"class":280,"line":491},[1623],{"type":32,"tag":278,"props":1624,"children":1625},{"style":695},[1626],{"type":45,"value":1627},"// Agents\n",{"type":32,"tag":278,"props":1629,"children":1630},{"class":280,"line":500},[1631,1635,1640,1645,1650,1655,1660,1665],{"type":32,"tag":278,"props":1632,"children":1633},{"style":412},[1634],{"type":45,"value":415},{"type":32,"tag":278,"props":1636,"children":1637},{"style":1574},[1638],{"type":45,"value":1639}," const",{"type":32,"tag":278,"props":1641,"children":1642},{"style":428},[1643],{"type":45,"value":1644}," agents ",{"type":32,"tag":278,"props":1646,"children":1647},{"style":412},[1648],{"type":45,"value":1649},"=",{"type":32,"tag":278,"props":1651,"children":1652},{"style":285},[1653],{"type":45,"value":1654}," sqliteTable",{"type":32,"tag":278,"props":1656,"children":1657},{"style":428},[1658],{"type":45,"value":1659},"(",{"type":32,"tag":278,"props":1661,"children":1662},{"style":291},[1663],{"type":45,"value":1664},"'agents'",{"type":32,"tag":278,"props":1666,"children":1667},{"style":428},[1668],{"type":45,"value":1669},", {\n",{"type":32,"tag":278,"props":1671,"children":1672},{"class":280,"line":509},[1673,1678,1682,1686,1691,1696,1701,1706,1711],{"type":32,"tag":278,"props":1674,"children":1675},{"style":428},[1676],{"type":45,"value":1677},"  id: ",{"type":32,"tag":278,"props":1679,"children":1680},{"style":285},[1681],{"type":45,"value":45},{"type":32,"tag":278,"props":1683,"children":1684},{"style":428},[1685],{"type":45,"value":1659},{"type":32,"tag":278,"props":1687,"children":1688},{"style":291},[1689],{"type":45,"value":1690},"'id'",{"type":32,"tag":278,"props":1692,"children":1693},{"style":428},[1694],{"type":45,"value":1695},").",{"type":32,"tag":278,"props":1697,"children":1698},{"style":285},[1699],{"type":45,"value":1700},"primaryKey",{"type":32,"tag":278,"props":1702,"children":1703},{"style":428},[1704],{"type":45,"value":1705},"().",{"type":32,"tag":278,"props":1707,"children":1708},{"style":285},[1709],{"type":45,"value":1710},"$defaultFn",{"type":32,"tag":278,"props":1712,"children":1713},{"style":428},[1714],{"type":45,"value":1715},"(generateUUID),\n",{"type":32,"tag":278,"props":1717,"children":1718},{"class":280,"line":519},[1719,1724,1728,1732,1737,1741,1746],{"type":32,"tag":278,"props":1720,"children":1721},{"style":428},[1722],{"type":45,"value":1723},"  name: ",{"type":32,"tag":278,"props":1725,"children":1726},{"style":285},[1727],{"type":45,"value":45},{"type":32,"tag":278,"props":1729,"children":1730},{"style":428},[1731],{"type":45,"value":1659},{"type":32,"tag":278,"props":1733,"children":1734},{"style":291},[1735],{"type":45,"value":1736},"'name'",{"type":32,"tag":278,"props":1738,"children":1739},{"style":428},[1740],{"type":45,"value":1695},{"type":32,"tag":278,"props":1742,"children":1743},{"style":285},[1744],{"type":45,"value":1745},"notNull",{"type":32,"tag":278,"props":1747,"children":1748},{"style":428},[1749],{"type":45,"value":1750},"(),\n",{"type":32,"tag":278,"props":1752,"children":1753},{"class":280,"line":537},[1754,1759,1763,1767,1772,1776,1780,1784,1789],{"type":32,"tag":278,"props":1755,"children":1756},{"style":428},[1757],{"type":45,"value":1758},"  apiRoute: ",{"type":32,"tag":278,"props":1760,"children":1761},{"style":285},[1762],{"type":45,"value":45},{"type":32,"tag":278,"props":1764,"children":1765},{"style":428},[1766],{"type":45,"value":1659},{"type":32,"tag":278,"props":1768,"children":1769},{"style":291},[1770],{"type":45,"value":1771},"'api_route'",{"type":32,"tag":278,"props":1773,"children":1774},{"style":428},[1775],{"type":45,"value":1695},{"type":32,"tag":278,"props":1777,"children":1778},{"style":285},[1779],{"type":45,"value":1745},{"type":32,"tag":278,"props":1781,"children":1782},{"style":428},[1783],{"type":45,"value":1705},{"type":32,"tag":278,"props":1785,"children":1786},{"style":285},[1787],{"type":45,"value":1788},"unique",{"type":32,"tag":278,"props":1790,"children":1791},{"style":428},[1792],{"type":45,"value":1750},{"type":32,"tag":278,"props":1794,"children":1795},{"class":280,"line":545},[1796,1801,1805,1809,1814,1818,1823,1827,1832,1837],{"type":32,"tag":278,"props":1797,"children":1798},{"style":428},[1799],{"type":45,"value":1800},"  createdAt: ",{"type":32,"tag":278,"props":1802,"children":1803},{"style":285},[1804],{"type":45,"value":45},{"type":32,"tag":278,"props":1806,"children":1807},{"style":428},[1808],{"type":45,"value":1659},{"type":32,"tag":278,"props":1810,"children":1811},{"style":291},[1812],{"type":45,"value":1813},"'created_at'",{"type":32,"tag":278,"props":1815,"children":1816},{"style":428},[1817],{"type":45,"value":1695},{"type":32,"tag":278,"props":1819,"children":1820},{"style":285},[1821],{"type":45,"value":1822},"default",{"type":32,"tag":278,"props":1824,"children":1825},{"style":428},[1826],{"type":45,"value":1659},{"type":32,"tag":278,"props":1828,"children":1829},{"style":285},[1830],{"type":45,"value":1831},"sql",{"type":32,"tag":278,"props":1833,"children":1834},{"style":291},[1835],{"type":45,"value":1836},"`(CURRENT_TIMESTAMP)`",{"type":32,"tag":278,"props":1838,"children":1839},{"style":428},[1840],{"type":45,"value":1841},"),\n",{"type":32,"tag":278,"props":1843,"children":1844},{"class":280,"line":554},[1845],{"type":32,"tag":278,"props":1846,"children":1847},{"style":428},[1848],{"type":45,"value":612},{"type":32,"tag":278,"props":1850,"children":1851},{"class":280,"line":571},[1852],{"type":32,"tag":278,"props":1853,"children":1854},{"emptyLinePlaceholder":513},[1855],{"type":45,"value":516},{"type":32,"tag":278,"props":1857,"children":1858},{"class":280,"line":588},[1859],{"type":32,"tag":278,"props":1860,"children":1861},{"style":695},[1862],{"type":45,"value":1863},"// Locations (Canonical)\n",{"type":32,"tag":278,"props":1865,"children":1866},{"class":280,"line":597},[1867,1871,1875,1880,1884,1888,1892,1897],{"type":32,"tag":278,"props":1868,"children":1869},{"style":412},[1870],{"type":45,"value":415},{"type":32,"tag":278,"props":1872,"children":1873},{"style":1574},[1874],{"type":45,"value":1639},{"type":32,"tag":278,"props":1876,"children":1877},{"style":428},[1878],{"type":45,"value":1879}," locations ",{"type":32,"tag":278,"props":1881,"children":1882},{"style":412},[1883],{"type":45,"value":1649},{"type":32,"tag":278,"props":1885,"children":1886},{"style":285},[1887],{"type":45,"value":1654},{"type":32,"tag":278,"props":1889,"children":1890},{"style":428},[1891],{"type":45,"value":1659},{"type":32,"tag":278,"props":1893,"children":1894},{"style":291},[1895],{"type":45,"value":1896},"'locations'",{"type":32,"tag":278,"props":1898,"children":1899},{"style":428},[1900],{"type":45,"value":1669},{"type":32,"tag":278,"props":1902,"children":1903},{"class":280,"line":606},[1904,1908,1912,1916,1920,1924,1928,1932,1936],{"type":32,"tag":278,"props":1905,"children":1906},{"style":428},[1907],{"type":45,"value":1677},{"type":32,"tag":278,"props":1909,"children":1910},{"style":285},[1911],{"type":45,"value":45},{"type":32,"tag":278,"props":1913,"children":1914},{"style":428},[1915],{"type":45,"value":1659},{"type":32,"tag":278,"props":1917,"children":1918},{"style":291},[1919],{"type":45,"value":1690},{"type":32,"tag":278,"props":1921,"children":1922},{"style":428},[1923],{"type":45,"value":1695},{"type":32,"tag":278,"props":1925,"children":1926},{"style":285},[1927],{"type":45,"value":1700},{"type":32,"tag":278,"props":1929,"children":1930},{"style":428},[1931],{"type":45,"value":1705},{"type":32,"tag":278,"props":1933,"children":1934},{"style":285},[1935],{"type":45,"value":1710},{"type":32,"tag":278,"props":1937,"children":1938},{"style":428},[1939],{"type":45,"value":1715},{"type":32,"tag":278,"props":1941,"children":1942},{"class":280,"line":1100},[1943,1947,1951,1955,1959,1963,1967],{"type":32,"tag":278,"props":1944,"children":1945},{"style":428},[1946],{"type":45,"value":1723},{"type":32,"tag":278,"props":1948,"children":1949},{"style":285},[1950],{"type":45,"value":45},{"type":32,"tag":278,"props":1952,"children":1953},{"style":428},[1954],{"type":45,"value":1659},{"type":32,"tag":278,"props":1956,"children":1957},{"style":291},[1958],{"type":45,"value":1736},{"type":32,"tag":278,"props":1960,"children":1961},{"style":428},[1962],{"type":45,"value":1695},{"type":32,"tag":278,"props":1964,"children":1965},{"style":285},[1966],{"type":45,"value":1745},{"type":32,"tag":278,"props":1968,"children":1969},{"style":428},[1970],{"type":45,"value":1750},{"type":32,"tag":278,"props":1972,"children":1973},{"class":280,"line":1127},[1974],{"type":32,"tag":278,"props":1975,"children":1976},{"style":695},[1977],{"type":45,"value":1978},"  // D1/SQLite stores arrays as strings. We handle parsing in the app.\n",{"type":32,"tag":278,"props":1980,"children":1981},{"class":280,"line":1152},[1982,1987,1991,1995,2000,2005,2010,2015,2020,2025,2030,2035,2039],{"type":32,"tag":278,"props":1983,"children":1984},{"style":428},[1985],{"type":45,"value":1986},"  postcodes: ",{"type":32,"tag":278,"props":1988,"children":1989},{"style":285},[1990],{"type":45,"value":45},{"type":32,"tag":278,"props":1992,"children":1993},{"style":428},[1994],{"type":45,"value":1659},{"type":32,"tag":278,"props":1996,"children":1997},{"style":291},[1998],{"type":45,"value":1999},"'postcodes'",{"type":32,"tag":278,"props":2001,"children":2002},{"style":428},[2003],{"type":45,"value":2004},", { mode: ",{"type":32,"tag":278,"props":2006,"children":2007},{"style":291},[2008],{"type":45,"value":2009},"'json'",{"type":32,"tag":278,"props":2011,"children":2012},{"style":428},[2013],{"type":45,"value":2014}," }).",{"type":32,"tag":278,"props":2016,"children":2017},{"style":285},[2018],{"type":45,"value":2019},"$type",{"type":32,"tag":278,"props":2021,"children":2022},{"style":428},[2023],{"type":45,"value":2024},"\u003C",{"type":32,"tag":278,"props":2026,"children":2027},{"style":1574},[2028],{"type":45,"value":2029},"string",{"type":32,"tag":278,"props":2031,"children":2032},{"style":428},[2033],{"type":45,"value":2034},"[]>().",{"type":32,"tag":278,"props":2036,"children":2037},{"style":285},[2038],{"type":45,"value":1745},{"type":32,"tag":278,"props":2040,"children":2041},{"style":428},[2042],{"type":45,"value":1750},{"type":32,"tag":278,"props":2044,"children":2045},{"class":280,"line":1176},[2046,2050,2054,2058,2062,2066,2070,2074,2078,2082],{"type":32,"tag":278,"props":2047,"children":2048},{"style":428},[2049],{"type":45,"value":1800},{"type":32,"tag":278,"props":2051,"children":2052},{"style":285},[2053],{"type":45,"value":45},{"type":32,"tag":278,"props":2055,"children":2056},{"style":428},[2057],{"type":45,"value":1659},{"type":32,"tag":278,"props":2059,"children":2060},{"style":291},[2061],{"type":45,"value":1813},{"type":32,"tag":278,"props":2063,"children":2064},{"style":428},[2065],{"type":45,"value":1695},{"type":32,"tag":278,"props":2067,"children":2068},{"style":285},[2069],{"type":45,"value":1822},{"type":32,"tag":278,"props":2071,"children":2072},{"style":428},[2073],{"type":45,"value":1659},{"type":32,"tag":278,"props":2075,"children":2076},{"style":285},[2077],{"type":45,"value":1831},{"type":32,"tag":278,"props":2079,"children":2080},{"style":291},[2081],{"type":45,"value":1836},{"type":32,"tag":278,"props":2083,"children":2084},{"style":428},[2085],{"type":45,"value":1841},{"type":32,"tag":278,"props":2087,"children":2088},{"class":280,"line":1217},[2089],{"type":32,"tag":278,"props":2090,"children":2091},{"style":428},[2092],{"type":45,"value":612},{"type":32,"tag":278,"props":2094,"children":2095},{"class":280,"line":1225},[2096],{"type":32,"tag":278,"props":2097,"children":2098},{"emptyLinePlaceholder":513},[2099],{"type":45,"value":516},{"type":32,"tag":278,"props":2101,"children":2102},{"class":280,"line":1269},[2103],{"type":32,"tag":278,"props":2104,"children":2105},{"style":695},[2106],{"type":45,"value":2107},"// Properties (Incoming)\n",{"type":32,"tag":278,"props":2109,"children":2110},{"class":280,"line":1298},[2111,2115,2119,2124,2128,2132,2136,2141],{"type":32,"tag":278,"props":2112,"children":2113},{"style":412},[2114],{"type":45,"value":415},{"type":32,"tag":278,"props":2116,"children":2117},{"style":1574},[2118],{"type":45,"value":1639},{"type":32,"tag":278,"props":2120,"children":2121},{"style":428},[2122],{"type":45,"value":2123}," properties ",{"type":32,"tag":278,"props":2125,"children":2126},{"style":412},[2127],{"type":45,"value":1649},{"type":32,"tag":278,"props":2129,"children":2130},{"style":285},[2131],{"type":45,"value":1654},{"type":32,"tag":278,"props":2133,"children":2134},{"style":428},[2135],{"type":45,"value":1659},{"type":32,"tag":278,"props":2137,"children":2138},{"style":291},[2139],{"type":45,"value":2140},"'properties'",{"type":32,"tag":278,"props":2142,"children":2143},{"style":428},[2144],{"type":45,"value":1669},{"type":32,"tag":278,"props":2146,"children":2147},{"class":280,"line":1340},[2148,2152,2156,2160,2164,2168,2172,2176,2180],{"type":32,"tag":278,"props":2149,"children":2150},{"style":428},[2151],{"type":45,"value":1677},{"type":32,"tag":278,"props":2153,"children":2154},{"style":285},[2155],{"type":45,"value":45},{"type":32,"tag":278,"props":2157,"children":2158},{"style":428},[2159],{"type":45,"value":1659},{"type":32,"tag":278,"props":2161,"children":2162},{"style":291},[2163],{"type":45,"value":1690},{"type":32,"tag":278,"props":2165,"children":2166},{"style":428},[2167],{"type":45,"value":1695},{"type":32,"tag":278,"props":2169,"children":2170},{"style":285},[2171],{"type":45,"value":1700},{"type":32,"tag":278,"props":2173,"children":2174},{"style":428},[2175],{"type":45,"value":1705},{"type":32,"tag":278,"props":2177,"children":2178},{"style":285},[2179],{"type":45,"value":1710},{"type":32,"tag":278,"props":2181,"children":2182},{"style":428},[2183],{"type":45,"value":1715},{"type":32,"tag":278,"props":2185,"children":2186},{"class":280,"line":1359},[2187,2192,2196,2200,2205,2209,2213,2218],{"type":32,"tag":278,"props":2188,"children":2189},{"style":428},[2190],{"type":45,"value":2191},"  externalRef: ",{"type":32,"tag":278,"props":2193,"children":2194},{"style":285},[2195],{"type":45,"value":45},{"type":32,"tag":278,"props":2197,"children":2198},{"style":428},[2199],{"type":45,"value":1659},{"type":32,"tag":278,"props":2201,"children":2202},{"style":291},[2203],{"type":45,"value":2204},"'external_ref'",{"type":32,"tag":278,"props":2206,"children":2207},{"style":428},[2208],{"type":45,"value":1695},{"type":32,"tag":278,"props":2210,"children":2211},{"style":285},[2212],{"type":45,"value":1745},{"type":32,"tag":278,"props":2214,"children":2215},{"style":428},[2216],{"type":45,"value":2217},"(), ",{"type":32,"tag":278,"props":2219,"children":2220},{"style":695},[2221],{"type":45,"value":2222},"// Agent's ID for the property\n",{"type":32,"tag":278,"props":2224,"children":2225},{"class":280,"line":1378},[2226,2231,2235,2239,2244,2248,2253,2258,2262,2267,2271],{"type":32,"tag":278,"props":2227,"children":2228},{"style":428},[2229],{"type":45,"value":2230},"  agentId: ",{"type":32,"tag":278,"props":2232,"children":2233},{"style":285},[2234],{"type":45,"value":45},{"type":32,"tag":278,"props":2236,"children":2237},{"style":428},[2238],{"type":45,"value":1659},{"type":32,"tag":278,"props":2240,"children":2241},{"style":291},[2242],{"type":45,"value":2243},"'agent_id'",{"type":32,"tag":278,"props":2245,"children":2246},{"style":428},[2247],{"type":45,"value":1695},{"type":32,"tag":278,"props":2249,"children":2250},{"style":285},[2251],{"type":45,"value":2252},"references",{"type":32,"tag":278,"props":2254,"children":2255},{"style":428},[2256],{"type":45,"value":2257},"(() ",{"type":32,"tag":278,"props":2259,"children":2260},{"style":1574},[2261],{"type":45,"value":1597},{"type":32,"tag":278,"props":2263,"children":2264},{"style":428},[2265],{"type":45,"value":2266}," agents.id).",{"type":32,"tag":278,"props":2268,"children":2269},{"style":285},[2270],{"type":45,"value":1745},{"type":32,"tag":278,"props":2272,"children":2273},{"style":428},[2274],{"type":45,"value":1750},{"type":32,"tag":278,"props":2276,"children":2277},{"class":280,"line":1386},[2278,2283,2287,2291,2296,2300,2304,2308,2312,2317,2321],{"type":32,"tag":278,"props":2279,"children":2280},{"style":428},[2281],{"type":45,"value":2282},"  locationId: ",{"type":32,"tag":278,"props":2284,"children":2285},{"style":285},[2286],{"type":45,"value":45},{"type":32,"tag":278,"props":2288,"children":2289},{"style":428},[2290],{"type":45,"value":1659},{"type":32,"tag":278,"props":2292,"children":2293},{"style":291},[2294],{"type":45,"value":2295},"'location_id'",{"type":32,"tag":278,"props":2297,"children":2298},{"style":428},[2299],{"type":45,"value":1695},{"type":32,"tag":278,"props":2301,"children":2302},{"style":285},[2303],{"type":45,"value":2252},{"type":32,"tag":278,"props":2305,"children":2306},{"style":428},[2307],{"type":45,"value":2257},{"type":32,"tag":278,"props":2309,"children":2310},{"style":1574},[2311],{"type":45,"value":1597},{"type":32,"tag":278,"props":2313,"children":2314},{"style":428},[2315],{"type":45,"value":2316}," locations.id).",{"type":32,"tag":278,"props":2318,"children":2319},{"style":285},[2320],{"type":45,"value":1745},{"type":32,"tag":278,"props":2322,"children":2323},{"style":428},[2324],{"type":45,"value":1750},{"type":32,"tag":278,"props":2326,"children":2327},{"class":280,"line":1412},[2328,2333,2337,2341,2346,2350,2354],{"type":32,"tag":278,"props":2329,"children":2330},{"style":428},[2331],{"type":45,"value":2332},"  title: ",{"type":32,"tag":278,"props":2334,"children":2335},{"style":285},[2336],{"type":45,"value":45},{"type":32,"tag":278,"props":2338,"children":2339},{"style":428},[2340],{"type":45,"value":1659},{"type":32,"tag":278,"props":2342,"children":2343},{"style":291},[2344],{"type":45,"value":2345},"'title'",{"type":32,"tag":278,"props":2347,"children":2348},{"style":428},[2349],{"type":45,"value":1695},{"type":32,"tag":278,"props":2351,"children":2352},{"style":285},[2353],{"type":45,"value":1745},{"type":32,"tag":278,"props":2355,"children":2356},{"style":428},[2357],{"type":45,"value":1750},{"type":32,"tag":278,"props":2359,"children":2360},{"class":280,"line":1443},[2361,2366,2370,2374,2379,2383,2387,2391],{"type":32,"tag":278,"props":2362,"children":2363},{"style":428},[2364],{"type":45,"value":2365},"  originalLocation: ",{"type":32,"tag":278,"props":2367,"children":2368},{"style":285},[2369],{"type":45,"value":45},{"type":32,"tag":278,"props":2371,"children":2372},{"style":428},[2373],{"type":45,"value":1659},{"type":32,"tag":278,"props":2375,"children":2376},{"style":291},[2377],{"type":45,"value":2378},"'original_location'",{"type":32,"tag":278,"props":2380,"children":2381},{"style":428},[2382],{"type":45,"value":1695},{"type":32,"tag":278,"props":2384,"children":2385},{"style":285},[2386],{"type":45,"value":1745},{"type":32,"tag":278,"props":2388,"children":2389},{"style":428},[2390],{"type":45,"value":2217},{"type":32,"tag":278,"props":2392,"children":2393},{"style":695},[2394],{"type":45,"value":2395},"// The messy string\n",{"type":32,"tag":278,"props":2397,"children":2398},{"class":280,"line":1452},[2399,2403,2407,2411,2415,2419,2423,2427,2431,2435],{"type":32,"tag":278,"props":2400,"children":2401},{"style":428},[2402],{"type":45,"value":1800},{"type":32,"tag":278,"props":2404,"children":2405},{"style":285},[2406],{"type":45,"value":45},{"type":32,"tag":278,"props":2408,"children":2409},{"style":428},[2410],{"type":45,"value":1659},{"type":32,"tag":278,"props":2412,"children":2413},{"style":291},[2414],{"type":45,"value":1813},{"type":32,"tag":278,"props":2416,"children":2417},{"style":428},[2418],{"type":45,"value":1695},{"type":32,"tag":278,"props":2420,"children":2421},{"style":285},[2422],{"type":45,"value":1822},{"type":32,"tag":278,"props":2424,"children":2425},{"style":428},[2426],{"type":45,"value":1659},{"type":32,"tag":278,"props":2428,"children":2429},{"style":285},[2430],{"type":45,"value":1831},{"type":32,"tag":278,"props":2432,"children":2433},{"style":291},[2434],{"type":45,"value":1836},{"type":32,"tag":278,"props":2436,"children":2437},{"style":428},[2438],{"type":45,"value":1841},{"type":32,"tag":278,"props":2440,"children":2442},{"class":280,"line":2441},32,[2443],{"type":32,"tag":278,"props":2444,"children":2445},{"style":428},[2446],{"type":45,"value":612},{"type":32,"tag":278,"props":2448,"children":2450},{"class":280,"line":2449},33,[2451],{"type":32,"tag":278,"props":2452,"children":2453},{"emptyLinePlaceholder":513},[2454],{"type":45,"value":516},{"type":32,"tag":278,"props":2456,"children":2458},{"class":280,"line":2457},34,[2459,2463,2467,2472,2476,2481,2486,2492,2497,2501],{"type":32,"tag":278,"props":2460,"children":2461},{"style":412},[2462],{"type":45,"value":415},{"type":32,"tag":278,"props":2464,"children":2465},{"style":1574},[2466],{"type":45,"value":1639},{"type":32,"tag":278,"props":2468,"children":2469},{"style":428},[2470],{"type":45,"value":2471}," agentsRelations ",{"type":32,"tag":278,"props":2473,"children":2474},{"style":412},[2475],{"type":45,"value":1649},{"type":32,"tag":278,"props":2477,"children":2478},{"style":285},[2479],{"type":45,"value":2480}," relations",{"type":32,"tag":278,"props":2482,"children":2483},{"style":428},[2484],{"type":45,"value":2485},"(agents, ({ ",{"type":32,"tag":278,"props":2487,"children":2489},{"style":2488},"--shiki-default:#FD971F;--shiki-default-font-style:italic",[2490],{"type":45,"value":2491},"many",{"type":32,"tag":278,"props":2493,"children":2494},{"style":428},[2495],{"type":45,"value":2496}," }) ",{"type":32,"tag":278,"props":2498,"children":2499},{"style":1574},[2500],{"type":45,"value":1597},{"type":32,"tag":278,"props":2502,"children":2503},{"style":428},[2504],{"type":45,"value":2505}," ({\n",{"type":32,"tag":278,"props":2507,"children":2509},{"class":280,"line":2508},35,[2510,2515,2519],{"type":32,"tag":278,"props":2511,"children":2512},{"style":428},[2513],{"type":45,"value":2514},"  properties: ",{"type":32,"tag":278,"props":2516,"children":2517},{"style":285},[2518],{"type":45,"value":2491},{"type":32,"tag":278,"props":2520,"children":2521},{"style":428},[2522],{"type":45,"value":2523},"(properties),\n",{"type":32,"tag":278,"props":2525,"children":2527},{"class":280,"line":2526},36,[2528],{"type":32,"tag":278,"props":2529,"children":2530},{"style":428},[2531],{"type":45,"value":2532},"}))\n",{"type":32,"tag":278,"props":2534,"children":2536},{"class":280,"line":2535},37,[2537],{"type":32,"tag":278,"props":2538,"children":2539},{"emptyLinePlaceholder":513},[2540],{"type":45,"value":516},{"type":32,"tag":278,"props":2542,"children":2544},{"class":280,"line":2543},38,[2545,2549,2553,2558,2562,2566,2571,2576,2580,2584],{"type":32,"tag":278,"props":2546,"children":2547},{"style":412},[2548],{"type":45,"value":415},{"type":32,"tag":278,"props":2550,"children":2551},{"style":1574},[2552],{"type":45,"value":1639},{"type":32,"tag":278,"props":2554,"children":2555},{"style":428},[2556],{"type":45,"value":2557}," propertiesRelations ",{"type":32,"tag":278,"props":2559,"children":2560},{"style":412},[2561],{"type":45,"value":1649},{"type":32,"tag":278,"props":2563,"children":2564},{"style":285},[2565],{"type":45,"value":2480},{"type":32,"tag":278,"props":2567,"children":2568},{"style":428},[2569],{"type":45,"value":2570},"(properties, ({ ",{"type":32,"tag":278,"props":2572,"children":2573},{"style":2488},[2574],{"type":45,"value":2575},"one",{"type":32,"tag":278,"props":2577,"children":2578},{"style":428},[2579],{"type":45,"value":2496},{"type":32,"tag":278,"props":2581,"children":2582},{"style":1574},[2583],{"type":45,"value":1597},{"type":32,"tag":278,"props":2585,"children":2586},{"style":428},[2587],{"type":45,"value":2505},{"type":32,"tag":278,"props":2589,"children":2591},{"class":280,"line":2590},39,[2592,2597,2601],{"type":32,"tag":278,"props":2593,"children":2594},{"style":428},[2595],{"type":45,"value":2596},"  agent: ",{"type":32,"tag":278,"props":2598,"children":2599},{"style":285},[2600],{"type":45,"value":2575},{"type":32,"tag":278,"props":2602,"children":2603},{"style":428},[2604],{"type":45,"value":2605},"(agents, {\n",{"type":32,"tag":278,"props":2607,"children":2609},{"class":280,"line":2608},40,[2610],{"type":32,"tag":278,"props":2611,"children":2612},{"style":428},[2613],{"type":45,"value":2614},"    fields: [properties.agentId],\n",{"type":32,"tag":278,"props":2616,"children":2618},{"class":280,"line":2617},41,[2619],{"type":32,"tag":278,"props":2620,"children":2621},{"style":428},[2622],{"type":45,"value":2623},"    references: [agents.id],\n",{"type":32,"tag":278,"props":2625,"children":2627},{"class":280,"line":2626},42,[2628],{"type":32,"tag":278,"props":2629,"children":2630},{"style":428},[2631],{"type":45,"value":2632},"  }),\n",{"type":32,"tag":278,"props":2634,"children":2636},{"class":280,"line":2635},43,[2637,2642,2646],{"type":32,"tag":278,"props":2638,"children":2639},{"style":428},[2640],{"type":45,"value":2641},"  location: ",{"type":32,"tag":278,"props":2643,"children":2644},{"style":285},[2645],{"type":45,"value":2575},{"type":32,"tag":278,"props":2647,"children":2648},{"style":428},[2649],{"type":45,"value":2650},"(locations, {\n",{"type":32,"tag":278,"props":2652,"children":2654},{"class":280,"line":2653},44,[2655],{"type":32,"tag":278,"props":2656,"children":2657},{"style":428},[2658],{"type":45,"value":2659},"    fields: [properties.locationId],\n",{"type":32,"tag":278,"props":2661,"children":2663},{"class":280,"line":2662},45,[2664],{"type":32,"tag":278,"props":2665,"children":2666},{"style":428},[2667],{"type":45,"value":2668},"    references: [locations.id],\n",{"type":32,"tag":278,"props":2670,"children":2672},{"class":280,"line":2671},46,[2673],{"type":32,"tag":278,"props":2674,"children":2675},{"style":428},[2676],{"type":45,"value":2632},{"type":32,"tag":278,"props":2678,"children":2680},{"class":280,"line":2679},47,[2681],{"type":32,"tag":278,"props":2682,"children":2683},{"style":428},[2684],{"type":45,"value":2532},{"type":32,"tag":33,"props":2686,"children":2687},{},[2688,2690,2695],{"type":45,"value":2689},"Note that SQLite does not support UUID types, which is why we’re using the ",{"type":32,"tag":74,"props":2691,"children":2693},{"className":2692},[],[2694],{"type":45,"value":45},{"type":45,"value":2696}," type and a function to generate the UUIDs.",{"type":32,"tag":33,"props":2698,"children":2699},{},[2700],{"type":45,"value":2701},"We will populate the agents' table with a list of agents from whom we'll fetch a listings feed. The locations table will hold our known locations, which we'll later use to populate the vector index and eventually match against the agent property listings. Finally, the properties table will hold agent properties with a resolved location.",{"type":32,"tag":33,"props":2703,"children":2704},{},[2705],{"type":45,"value":2706},"I’ve also added a couple of soft relations as an example.",{"type":32,"tag":33,"props":2708,"children":2709},{},[2710,2712,2718],{"type":45,"value":2711},"While we're here, we can generate the database migration files using Drizzle Kit. Generating them is relatively straightforward (unless you're working in a team; Drizzle Kit can result in several conflicts with the migration files order 😮‍💨). Just run ",{"type":32,"tag":74,"props":2713,"children":2715},{"className":2714},[],[2716],{"type":45,"value":2717},"npx drizzle-kit generate",{"type":45,"value":2719}," to generate the migration files from the schema we just wrote.",{"type":32,"tag":168,"props":2721,"children":2723},{"id":2722},"running-drizzle-migrations-on-a-cloudflare-d1-database",[2724],{"type":45,"value":2725},"Running Drizzle migrations on a Cloudflare D1 database",{"type":32,"tag":33,"props":2727,"children":2728},{},[2729],{"type":45,"value":2730},"We can now create a new D1 database on Cloudflare. We can do this using Wrangler CLI:",{"type":32,"tag":267,"props":2732,"children":2734},{"className":269,"code":2733,"language":271,"meta":272,"style":272},"npx wrangler d1 create property-sync-db\n",[2735],{"type":32,"tag":74,"props":2736,"children":2737},{"__ignoreMap":272},[2738],{"type":32,"tag":278,"props":2739,"children":2740},{"class":280,"line":281},[2741,2745,2749,2754,2759],{"type":32,"tag":278,"props":2742,"children":2743},{"style":285},[2744],{"type":45,"value":765},{"type":32,"tag":278,"props":2746,"children":2747},{"style":291},[2748],{"type":45,"value":374},{"type":32,"tag":278,"props":2750,"children":2751},{"style":291},[2752],{"type":45,"value":2753}," d1",{"type":32,"tag":278,"props":2755,"children":2756},{"style":291},[2757],{"type":45,"value":2758}," create",{"type":32,"tag":278,"props":2760,"children":2761},{"style":291},[2762],{"type":45,"value":2763}," property-sync-db\n",{"type":32,"tag":33,"props":2765,"children":2766},{},[2767,2769,2774],{"type":45,"value":2768},"And add the database binding to ",{"type":32,"tag":74,"props":2770,"children":2772},{"className":2771},[],[2773],{"type":45,"value":629},{"type":45,"value":2775},":",{"type":32,"tag":267,"props":2777,"children":2779},{"className":634,"code":2778,"language":636,"meta":272,"style":272},"[[d1_databases]]\nbinding = \"DB\"\ndatabase_name = \"property-sync-db\"\ndatabase_id = \"the-id-returned-from-the-wrangler-command\"\nmigrations_dir = \"server/database/migrations\"\n",[2780],{"type":32,"tag":74,"props":2781,"children":2782},{"__ignoreMap":272},[2783,2791,2804,2817,2830],{"type":32,"tag":278,"props":2784,"children":2785},{"class":280,"line":281},[2786],{"type":32,"tag":278,"props":2787,"children":2788},{"style":428},[2789],{"type":45,"value":2790},"[[d1_databases]]\n",{"type":32,"tag":278,"props":2792,"children":2793},{"class":280,"line":312},[2794,2799],{"type":32,"tag":278,"props":2795,"children":2796},{"style":428},[2797],{"type":45,"value":2798},"binding = ",{"type":32,"tag":278,"props":2800,"children":2801},{"style":291},[2802],{"type":45,"value":2803},"\"DB\"\n",{"type":32,"tag":278,"props":2805,"children":2806},{"class":280,"line":326},[2807,2812],{"type":32,"tag":278,"props":2808,"children":2809},{"style":428},[2810],{"type":45,"value":2811},"database_name = ",{"type":32,"tag":278,"props":2813,"children":2814},{"style":291},[2815],{"type":45,"value":2816},"\"property-sync-db\"\n",{"type":32,"tag":278,"props":2818,"children":2819},{"class":280,"line":349},[2820,2825],{"type":32,"tag":278,"props":2821,"children":2822},{"style":428},[2823],{"type":45,"value":2824},"database_id = ",{"type":32,"tag":278,"props":2826,"children":2827},{"style":291},[2828],{"type":45,"value":2829},"\"the-id-returned-from-the-wrangler-command\"\n",{"type":32,"tag":278,"props":2831,"children":2832},{"class":280,"line":478},[2833,2838],{"type":32,"tag":278,"props":2834,"children":2835},{"style":428},[2836],{"type":45,"value":2837},"migrations_dir = ",{"type":32,"tag":278,"props":2839,"children":2840},{"style":291},[2841],{"type":45,"value":2842},"\"server/database/migrations\"\n",{"type":32,"tag":33,"props":2844,"children":2845},{},[2846,2848,2854],{"type":45,"value":2847},"Creating the D1 database on Cloudflare does not automatically bind it to our worker. Bindings are added on deployment based on the ",{"type":32,"tag":74,"props":2849,"children":2851},{"className":2850},[],[2852],{"type":45,"value":2853},"wrangler.toml",{"type":45,"value":2855}," file entries. Notice that we're also specifying the migrations directory location, which we will need soon.",{"type":32,"tag":228,"props":2857,"children":2858},{},[2859],{"type":32,"tag":33,"props":2860,"children":2861},{},[2862],{"type":45,"value":2863},"⚠️ Note: Cloudflare’s D1 is not always a good fit. Scaling large datasets requires manual sharding, and as with all SQLite databases, D1 lacks several key features that production-grade applications often need.",{"type":32,"tag":33,"props":2865,"children":2866},{},[2867,2869,2875],{"type":45,"value":2868},"We also need to enter some database credentials in ",{"type":32,"tag":74,"props":2870,"children":2872},{"className":2871},[],[2873],{"type":45,"value":2874},"/drizzle.config.ts",{"type":45,"value":2876},".",{"type":32,"tag":267,"props":2878,"children":2880},{"className":400,"code":2879,"language":402,"meta":272,"style":272},"import { defineConfig } from 'drizzle-kit'\n\nexport default defineConfig({\n  dialect: 'sqlite',\n  schema: './server/database/schema.ts',\n  out: './server/database/migrations',\n  driver: 'd1-http',\n\n  dbCredentials: {\n      accountId: process.env.CLOUDFLARE_ACCOUNT_ID!,\n      databaseId: process.env.CLOUDFLARE_DATABASE_ID!,\n      token: process.env.DRIZZLE_API_TOKEN!,\n  },\n})\n\n",[2881],{"type":32,"tag":74,"props":2882,"children":2883},{"__ignoreMap":272},[2884,2905,2912,2932,2949,2966,2983,3000,3007,3015,3032,3048,3064,3071],{"type":32,"tag":278,"props":2885,"children":2886},{"class":280,"line":281},[2887,2891,2896,2900],{"type":32,"tag":278,"props":2888,"children":2889},{"style":412},[2890],{"type":45,"value":1525},{"type":32,"tag":278,"props":2892,"children":2893},{"style":428},[2894],{"type":45,"value":2895}," { defineConfig } ",{"type":32,"tag":278,"props":2897,"children":2898},{"style":412},[2899],{"type":45,"value":1535},{"type":32,"tag":278,"props":2901,"children":2902},{"style":291},[2903],{"type":45,"value":2904}," 'drizzle-kit'\n",{"type":32,"tag":278,"props":2906,"children":2907},{"class":280,"line":312},[2908],{"type":32,"tag":278,"props":2909,"children":2910},{"emptyLinePlaceholder":513},[2911],{"type":45,"value":516},{"type":32,"tag":278,"props":2913,"children":2914},{"class":280,"line":326},[2915,2919,2923,2928],{"type":32,"tag":278,"props":2916,"children":2917},{"style":412},[2918],{"type":45,"value":415},{"type":32,"tag":278,"props":2920,"children":2921},{"style":412},[2922],{"type":45,"value":420},{"type":32,"tag":278,"props":2924,"children":2925},{"style":285},[2926],{"type":45,"value":2927}," defineConfig",{"type":32,"tag":278,"props":2929,"children":2930},{"style":428},[2931],{"type":45,"value":431},{"type":32,"tag":278,"props":2933,"children":2934},{"class":280,"line":349},[2935,2940,2945],{"type":32,"tag":278,"props":2936,"children":2937},{"style":428},[2938],{"type":45,"value":2939},"  dialect: ",{"type":32,"tag":278,"props":2941,"children":2942},{"style":291},[2943],{"type":45,"value":2944},"'sqlite'",{"type":32,"tag":278,"props":2946,"children":2947},{"style":428},[2948],{"type":45,"value":449},{"type":32,"tag":278,"props":2950,"children":2951},{"class":280,"line":478},[2952,2957,2962],{"type":32,"tag":278,"props":2953,"children":2954},{"style":428},[2955],{"type":45,"value":2956},"  schema: ",{"type":32,"tag":278,"props":2958,"children":2959},{"style":291},[2960],{"type":45,"value":2961},"'./server/database/schema.ts'",{"type":32,"tag":278,"props":2963,"children":2964},{"style":428},[2965],{"type":45,"value":449},{"type":32,"tag":278,"props":2967,"children":2968},{"class":280,"line":491},[2969,2974,2979],{"type":32,"tag":278,"props":2970,"children":2971},{"style":428},[2972],{"type":45,"value":2973},"  out: ",{"type":32,"tag":278,"props":2975,"children":2976},{"style":291},[2977],{"type":45,"value":2978},"'./server/database/migrations'",{"type":32,"tag":278,"props":2980,"children":2981},{"style":428},[2982],{"type":45,"value":449},{"type":32,"tag":278,"props":2984,"children":2985},{"class":280,"line":500},[2986,2991,2996],{"type":32,"tag":278,"props":2987,"children":2988},{"style":428},[2989],{"type":45,"value":2990},"  driver: ",{"type":32,"tag":278,"props":2992,"children":2993},{"style":291},[2994],{"type":45,"value":2995},"'d1-http'",{"type":32,"tag":278,"props":2997,"children":2998},{"style":428},[2999],{"type":45,"value":449},{"type":32,"tag":278,"props":3001,"children":3002},{"class":280,"line":509},[3003],{"type":32,"tag":278,"props":3004,"children":3005},{"emptyLinePlaceholder":513},[3006],{"type":45,"value":516},{"type":32,"tag":278,"props":3008,"children":3009},{"class":280,"line":519},[3010],{"type":32,"tag":278,"props":3011,"children":3012},{"style":428},[3013],{"type":45,"value":3014},"  dbCredentials: {\n",{"type":32,"tag":278,"props":3016,"children":3017},{"class":280,"line":537},[3018,3023,3028],{"type":32,"tag":278,"props":3019,"children":3020},{"style":428},[3021],{"type":45,"value":3022},"      accountId: process.env.CLOUDFLARE_ACCOUNT_ID",{"type":32,"tag":278,"props":3024,"children":3025},{"style":412},[3026],{"type":45,"value":3027},"!",{"type":32,"tag":278,"props":3029,"children":3030},{"style":428},[3031],{"type":45,"value":449},{"type":32,"tag":278,"props":3033,"children":3034},{"class":280,"line":545},[3035,3040,3044],{"type":32,"tag":278,"props":3036,"children":3037},{"style":428},[3038],{"type":45,"value":3039},"      databaseId: process.env.CLOUDFLARE_DATABASE_ID",{"type":32,"tag":278,"props":3041,"children":3042},{"style":412},[3043],{"type":45,"value":3027},{"type":32,"tag":278,"props":3045,"children":3046},{"style":428},[3047],{"type":45,"value":449},{"type":32,"tag":278,"props":3049,"children":3050},{"class":280,"line":554},[3051,3056,3060],{"type":32,"tag":278,"props":3052,"children":3053},{"style":428},[3054],{"type":45,"value":3055},"      token: process.env.DRIZZLE_API_TOKEN",{"type":32,"tag":278,"props":3057,"children":3058},{"style":412},[3059],{"type":45,"value":3027},{"type":32,"tag":278,"props":3061,"children":3062},{"style":428},[3063],{"type":45,"value":449},{"type":32,"tag":278,"props":3065,"children":3066},{"class":280,"line":571},[3067],{"type":32,"tag":278,"props":3068,"children":3069},{"style":428},[3070],{"type":45,"value":603},{"type":32,"tag":278,"props":3072,"children":3073},{"class":280,"line":588},[3074],{"type":32,"tag":278,"props":3075,"children":3076},{"style":428},[3077],{"type":45,"value":612},{"type":32,"tag":33,"props":3079,"children":3080},{},[3081,3083,3089,3091,3097],{"type":45,"value":3082},"You should add the environment variables and use them instead of adding them directly in the config file. This so you can swap them for different environments. We don’t have ",{"type":32,"tag":74,"props":3084,"children":3086},{"className":3085},[],[3087],{"type":45,"value":3088},"dbCredentials.token",{"type":45,"value":3090},", but migrations seem to fail if not included. My ",{"type":32,"tag":74,"props":3092,"children":3094},{"className":3093},[],[3095],{"type":45,"value":3096},".env",{"type":45,"value":3098}," file looks like this:",{"type":32,"tag":267,"props":3100,"children":3104},{"className":3101,"code":3102,"language":3103,"meta":272,"style":272},"language-dotenv shiki shiki-themes monokai","CLOUDFLARE_ACCOUNT_ID=\"my_cloudflare_account_id\"\nCLOUDFLARE_DATABASE_ID=\"the_database_id_from_cloudflare\"\n# Notice I don't have DRIZZLE_API_TOKEN\n","dotenv",[3105],{"type":32,"tag":74,"props":3106,"children":3107},{"__ignoreMap":272},[3108,3125,3142],{"type":32,"tag":278,"props":3109,"children":3110},{"class":280,"line":281},[3111,3116,3120],{"type":32,"tag":278,"props":3112,"children":3113},{"style":428},[3114],{"type":45,"value":3115},"CLOUDFLARE_ACCOUNT_ID",{"type":32,"tag":278,"props":3117,"children":3118},{"style":412},[3119],{"type":45,"value":1649},{"type":32,"tag":278,"props":3121,"children":3122},{"style":291},[3123],{"type":45,"value":3124},"\"my_cloudflare_account_id\"\n",{"type":32,"tag":278,"props":3126,"children":3127},{"class":280,"line":312},[3128,3133,3137],{"type":32,"tag":278,"props":3129,"children":3130},{"style":428},[3131],{"type":45,"value":3132},"CLOUDFLARE_DATABASE_ID",{"type":32,"tag":278,"props":3134,"children":3135},{"style":412},[3136],{"type":45,"value":1649},{"type":32,"tag":278,"props":3138,"children":3139},{"style":291},[3140],{"type":45,"value":3141},"\"the_database_id_from_cloudflare\"\n",{"type":32,"tag":278,"props":3143,"children":3144},{"class":280,"line":326},[3145],{"type":32,"tag":278,"props":3146,"children":3147},{"style":695},[3148],{"type":45,"value":3149},"# Notice I don't have DRIZZLE_API_TOKEN\n",{"type":32,"tag":33,"props":3151,"children":3152},{},[3153],{"type":45,"value":3154},"And with that, we can run the database migrations directly on the D1 instance by running:",{"type":32,"tag":267,"props":3156,"children":3158},{"className":269,"code":3157,"language":271,"meta":272,"style":272},"npx wrangler d1 migrations apply property-sync-db --remote\n",[3159],{"type":32,"tag":74,"props":3160,"children":3161},{"__ignoreMap":272},[3162],{"type":32,"tag":278,"props":3163,"children":3164},{"class":280,"line":281},[3165,3169,3173,3177,3182,3187,3192],{"type":32,"tag":278,"props":3166,"children":3167},{"style":285},[3168],{"type":45,"value":765},{"type":32,"tag":278,"props":3170,"children":3171},{"style":291},[3172],{"type":45,"value":374},{"type":32,"tag":278,"props":3174,"children":3175},{"style":291},[3176],{"type":45,"value":2753},{"type":32,"tag":278,"props":3178,"children":3179},{"style":291},[3180],{"type":45,"value":3181}," migrations",{"type":32,"tag":278,"props":3183,"children":3184},{"style":291},[3185],{"type":45,"value":3186}," apply",{"type":32,"tag":278,"props":3188,"children":3189},{"style":291},[3190],{"type":45,"value":3191}," property-sync-db",{"type":32,"tag":278,"props":3193,"children":3194},{"style":361},[3195],{"type":45,"value":3196}," --remote\n",{"type":32,"tag":3198,"props":3199,"children":3200},"newsletter-form",{},[],{"type":32,"tag":168,"props":3202,"children":3204},{"id":3203},"lets-seed-some-data-on-our-cloudflare-d1-database",[3205],{"type":45,"value":3206},"Let’s seed some data on our Cloudflare D1 Database",{"type":32,"tag":33,"props":3208,"children":3209},{},[3210],{"type":45,"value":3211},"I'm going to create an API endpoint to seed some needed data into the D1 database. You'd obviously not do this, this way, in a real application. Still, this way we can move this task forward faster and lay some groundwork for when we need other internal API endpoints later, since Cloudflare's AI features don't run in dev environments. However, to make it harder for attackers, we should add an environment variable to the Cloudflare worker.",{"type":32,"tag":33,"props":3213,"children":3214},{},[3215],{"type":45,"value":3216},"We can add the secret using Wrangler:",{"type":32,"tag":33,"props":3218,"children":3219},{},[3220],{"type":32,"tag":74,"props":3221,"children":3223},{"className":3222},[],[3224],{"type":45,"value":3225},"npx wrangler secret put NUXT_INTERNAL_API_SECRET",{"type":32,"tag":33,"props":3227,"children":3228},{},[3229,3231,3237],{"type":45,"value":3230},"Or from Cloudflare’s dashboard, navigate to Worker & Pages, select this worker, and go to settings. Then add an encrypted environment variable named ",{"type":32,"tag":74,"props":3232,"children":3234},{"className":3233},[],[3235],{"type":45,"value":3236},"NUXT_INTERNAL_API_SECRET",{"type":45,"value":3238}," with a secret string. Feel free to add the same variable locally if you intend to use the upcoming API endpoint from localhost.",{"type":32,"tag":33,"props":3240,"children":3241},{},[3242],{"type":45,"value":3243},"We need to seed some dummy agents and a few locations so we can generate text embeddings, add the locations to the vector store, and later use AI to resolve the messy listings from the agents' feeds.",{"type":32,"tag":33,"props":3245,"children":3246},{},[3247,3249,3255],{"type":45,"value":3248},"Create an API endpoint at: ",{"type":32,"tag":74,"props":3250,"children":3252},{"className":3251},[],[3253],{"type":45,"value":3254},"/server/api/internals/seed.get.ts",{"type":45,"value":3256}," and add the following contents:",{"type":32,"tag":267,"props":3258,"children":3260},{"className":400,"code":3259,"language":402,"meta":272,"style":272},"import { drizzle } from 'drizzle-orm/d1'\nimport { agents, locations } from '~~/server/database/schema'\n\nexport default defineEventHandler(async (event) => {\n\n  const config = useRuntimeConfig()\n\n  if (getHeader(event, 'x-secret') !== config.internalApiSecret) {\n    throw createError({ statusCode: 401, statusMessage: 'Unauthorized' })\n  }\n\n  const env = event.context.cloudflare.env\n\n  if (!env.DB) {\n    throw createError(\n      { statusCode: 500, statusMessage: 'Database not found in environment' })\n  }\n\n  const db = drizzle(env.DB)\n\n  console.log('🌱 Starting Seed...')\n\n  // 3. Seed Agents\n  const agentsData = [\n    {\n      name: 'The Formalist',\n      apiRoute: '/api/agents/formalist',\n    },\n    {\n      name: 'The Traditionalist',\n      apiRoute: '/api/agents/traditionalist',\n    },\n    {\n      name: 'The Marketer',\n      apiRoute: '/api/agents/marketer',\n    },\n  ]\n  await db.insert(agents).values(agentsData)\n\n  // 4. Seed Locations (Corrected Data)\n  const locationsData = [\n    {\n      name: 'Shoreditch',\n      postcodes: ['E1', 'E2', 'EC1', 'EC2', 'N1'],\n    },\n    {\n      name: 'Canary Wharf',\n      postcodes: ['E14'],\n    },\n    {\n      name: 'Brixton',\n      postcodes: ['SW2', 'SW9'],\n    },\n    {\n      name: 'Notting Hill',\n      postcodes: ['W10', 'W11', 'W2'],\n    },\n  ]\n  await db.insert(locations).values(locationsData)\n\n  return {\n    success: true,\n    message: 'Database Seeded',\n    stats: {\n      agents: agentsData.length,\n      locations: locationsData.length,\n    },\n  }\n})\n\n",[3261],{"type":32,"tag":74,"props":3262,"children":3263},{"__ignoreMap":272},[3264,3285,3306,3313,3362,3369,3395,3402,3443,3481,3489,3496,3517,3524,3544,3560,3586,3593,3600,3626,3633,3659,3666,3674,3695,3703,3720,3737,3744,3751,3767,3783,3790,3797,3813,3829,3836,3844,3877,3884,3892,3912,3919,3935,3990,3997,4004,4020,4037,4045,4053,4070,4096,4104,4112,4129,4164,4172,4180,4210,4218,4231,4248,4266,4275,4284,4293,4301,4309],{"type":32,"tag":278,"props":3265,"children":3266},{"class":280,"line":281},[3267,3271,3276,3280],{"type":32,"tag":278,"props":3268,"children":3269},{"style":412},[3270],{"type":45,"value":1525},{"type":32,"tag":278,"props":3272,"children":3273},{"style":428},[3274],{"type":45,"value":3275}," { drizzle } ",{"type":32,"tag":278,"props":3277,"children":3278},{"style":412},[3279],{"type":45,"value":1535},{"type":32,"tag":278,"props":3281,"children":3282},{"style":291},[3283],{"type":45,"value":3284}," 'drizzle-orm/d1'\n",{"type":32,"tag":278,"props":3286,"children":3287},{"class":280,"line":312},[3288,3292,3297,3301],{"type":32,"tag":278,"props":3289,"children":3290},{"style":412},[3291],{"type":45,"value":1525},{"type":32,"tag":278,"props":3293,"children":3294},{"style":428},[3295],{"type":45,"value":3296}," { agents, locations } ",{"type":32,"tag":278,"props":3298,"children":3299},{"style":412},[3300],{"type":45,"value":1535},{"type":32,"tag":278,"props":3302,"children":3303},{"style":291},[3304],{"type":45,"value":3305}," '~~/server/database/schema'\n",{"type":32,"tag":278,"props":3307,"children":3308},{"class":280,"line":326},[3309],{"type":32,"tag":278,"props":3310,"children":3311},{"emptyLinePlaceholder":513},[3312],{"type":45,"value":516},{"type":32,"tag":278,"props":3314,"children":3315},{"class":280,"line":349},[3316,3320,3324,3329,3333,3338,3343,3348,3353,3357],{"type":32,"tag":278,"props":3317,"children":3318},{"style":412},[3319],{"type":45,"value":415},{"type":32,"tag":278,"props":3321,"children":3322},{"style":412},[3323],{"type":45,"value":420},{"type":32,"tag":278,"props":3325,"children":3326},{"style":285},[3327],{"type":45,"value":3328}," defineEventHandler",{"type":32,"tag":278,"props":3330,"children":3331},{"style":428},[3332],{"type":45,"value":1659},{"type":32,"tag":278,"props":3334,"children":3335},{"style":412},[3336],{"type":45,"value":3337},"async",{"type":32,"tag":278,"props":3339,"children":3340},{"style":428},[3341],{"type":45,"value":3342}," (",{"type":32,"tag":278,"props":3344,"children":3345},{"style":2488},[3346],{"type":45,"value":3347},"event",{"type":32,"tag":278,"props":3349,"children":3350},{"style":428},[3351],{"type":45,"value":3352},") ",{"type":32,"tag":278,"props":3354,"children":3355},{"style":1574},[3356],{"type":45,"value":1597},{"type":32,"tag":278,"props":3358,"children":3359},{"style":428},[3360],{"type":45,"value":3361}," {\n",{"type":32,"tag":278,"props":3363,"children":3364},{"class":280,"line":478},[3365],{"type":32,"tag":278,"props":3366,"children":3367},{"emptyLinePlaceholder":513},[3368],{"type":45,"value":516},{"type":32,"tag":278,"props":3370,"children":3371},{"class":280,"line":491},[3372,3377,3382,3386,3391],{"type":32,"tag":278,"props":3373,"children":3374},{"style":1574},[3375],{"type":45,"value":3376},"  const",{"type":32,"tag":278,"props":3378,"children":3379},{"style":428},[3380],{"type":45,"value":3381}," config ",{"type":32,"tag":278,"props":3383,"children":3384},{"style":412},[3385],{"type":45,"value":1649},{"type":32,"tag":278,"props":3387,"children":3388},{"style":285},[3389],{"type":45,"value":3390}," useRuntimeConfig",{"type":32,"tag":278,"props":3392,"children":3393},{"style":428},[3394],{"type":45,"value":1612},{"type":32,"tag":278,"props":3396,"children":3397},{"class":280,"line":500},[3398],{"type":32,"tag":278,"props":3399,"children":3400},{"emptyLinePlaceholder":513},[3401],{"type":45,"value":516},{"type":32,"tag":278,"props":3403,"children":3404},{"class":280,"line":509},[3405,3410,3414,3419,3424,3429,3433,3438],{"type":32,"tag":278,"props":3406,"children":3407},{"style":412},[3408],{"type":45,"value":3409},"  if",{"type":32,"tag":278,"props":3411,"children":3412},{"style":428},[3413],{"type":45,"value":3342},{"type":32,"tag":278,"props":3415,"children":3416},{"style":285},[3417],{"type":45,"value":3418},"getHeader",{"type":32,"tag":278,"props":3420,"children":3421},{"style":428},[3422],{"type":45,"value":3423},"(event, ",{"type":32,"tag":278,"props":3425,"children":3426},{"style":291},[3427],{"type":45,"value":3428},"'x-secret'",{"type":32,"tag":278,"props":3430,"children":3431},{"style":428},[3432],{"type":45,"value":3352},{"type":32,"tag":278,"props":3434,"children":3435},{"style":412},[3436],{"type":45,"value":3437},"!==",{"type":32,"tag":278,"props":3439,"children":3440},{"style":428},[3441],{"type":45,"value":3442}," config.internalApiSecret) {\n",{"type":32,"tag":278,"props":3444,"children":3445},{"class":280,"line":519},[3446,3451,3456,3461,3466,3471,3476],{"type":32,"tag":278,"props":3447,"children":3448},{"style":412},[3449],{"type":45,"value":3450},"    throw",{"type":32,"tag":278,"props":3452,"children":3453},{"style":285},[3454],{"type":45,"value":3455}," createError",{"type":32,"tag":278,"props":3457,"children":3458},{"style":428},[3459],{"type":45,"value":3460},"({ statusCode: ",{"type":32,"tag":278,"props":3462,"children":3463},{"style":361},[3464],{"type":45,"value":3465},"401",{"type":32,"tag":278,"props":3467,"children":3468},{"style":428},[3469],{"type":45,"value":3470},", statusMessage: ",{"type":32,"tag":278,"props":3472,"children":3473},{"style":291},[3474],{"type":45,"value":3475},"'Unauthorized'",{"type":32,"tag":278,"props":3477,"children":3478},{"style":428},[3479],{"type":45,"value":3480}," })\n",{"type":32,"tag":278,"props":3482,"children":3483},{"class":280,"line":537},[3484],{"type":32,"tag":278,"props":3485,"children":3486},{"style":428},[3487],{"type":45,"value":3488},"  }\n",{"type":32,"tag":278,"props":3490,"children":3491},{"class":280,"line":545},[3492],{"type":32,"tag":278,"props":3493,"children":3494},{"emptyLinePlaceholder":513},[3495],{"type":45,"value":516},{"type":32,"tag":278,"props":3497,"children":3498},{"class":280,"line":554},[3499,3503,3508,3512],{"type":32,"tag":278,"props":3500,"children":3501},{"style":1574},[3502],{"type":45,"value":3376},{"type":32,"tag":278,"props":3504,"children":3505},{"style":428},[3506],{"type":45,"value":3507}," env ",{"type":32,"tag":278,"props":3509,"children":3510},{"style":412},[3511],{"type":45,"value":1649},{"type":32,"tag":278,"props":3513,"children":3514},{"style":428},[3515],{"type":45,"value":3516}," event.context.cloudflare.env\n",{"type":32,"tag":278,"props":3518,"children":3519},{"class":280,"line":571},[3520],{"type":32,"tag":278,"props":3521,"children":3522},{"emptyLinePlaceholder":513},[3523],{"type":45,"value":516},{"type":32,"tag":278,"props":3525,"children":3526},{"class":280,"line":588},[3527,3531,3535,3539],{"type":32,"tag":278,"props":3528,"children":3529},{"style":412},[3530],{"type":45,"value":3409},{"type":32,"tag":278,"props":3532,"children":3533},{"style":428},[3534],{"type":45,"value":3342},{"type":32,"tag":278,"props":3536,"children":3537},{"style":412},[3538],{"type":45,"value":3027},{"type":32,"tag":278,"props":3540,"children":3541},{"style":428},[3542],{"type":45,"value":3543},"env.DB) {\n",{"type":32,"tag":278,"props":3545,"children":3546},{"class":280,"line":597},[3547,3551,3555],{"type":32,"tag":278,"props":3548,"children":3549},{"style":412},[3550],{"type":45,"value":3450},{"type":32,"tag":278,"props":3552,"children":3553},{"style":285},[3554],{"type":45,"value":3455},{"type":32,"tag":278,"props":3556,"children":3557},{"style":428},[3558],{"type":45,"value":3559},"(\n",{"type":32,"tag":278,"props":3561,"children":3562},{"class":280,"line":606},[3563,3568,3573,3577,3582],{"type":32,"tag":278,"props":3564,"children":3565},{"style":428},[3566],{"type":45,"value":3567},"      { statusCode: ",{"type":32,"tag":278,"props":3569,"children":3570},{"style":361},[3571],{"type":45,"value":3572},"500",{"type":32,"tag":278,"props":3574,"children":3575},{"style":428},[3576],{"type":45,"value":3470},{"type":32,"tag":278,"props":3578,"children":3579},{"style":291},[3580],{"type":45,"value":3581},"'Database not found in environment'",{"type":32,"tag":278,"props":3583,"children":3584},{"style":428},[3585],{"type":45,"value":3480},{"type":32,"tag":278,"props":3587,"children":3588},{"class":280,"line":1100},[3589],{"type":32,"tag":278,"props":3590,"children":3591},{"style":428},[3592],{"type":45,"value":3488},{"type":32,"tag":278,"props":3594,"children":3595},{"class":280,"line":1127},[3596],{"type":32,"tag":278,"props":3597,"children":3598},{"emptyLinePlaceholder":513},[3599],{"type":45,"value":516},{"type":32,"tag":278,"props":3601,"children":3602},{"class":280,"line":1152},[3603,3607,3612,3616,3621],{"type":32,"tag":278,"props":3604,"children":3605},{"style":1574},[3606],{"type":45,"value":3376},{"type":32,"tag":278,"props":3608,"children":3609},{"style":428},[3610],{"type":45,"value":3611}," db ",{"type":32,"tag":278,"props":3613,"children":3614},{"style":412},[3615],{"type":45,"value":1649},{"type":32,"tag":278,"props":3617,"children":3618},{"style":285},[3619],{"type":45,"value":3620}," drizzle",{"type":32,"tag":278,"props":3622,"children":3623},{"style":428},[3624],{"type":45,"value":3625},"(env.DB)\n",{"type":32,"tag":278,"props":3627,"children":3628},{"class":280,"line":1176},[3629],{"type":32,"tag":278,"props":3630,"children":3631},{"emptyLinePlaceholder":513},[3632],{"type":45,"value":516},{"type":32,"tag":278,"props":3634,"children":3635},{"class":280,"line":1217},[3636,3641,3646,3650,3655],{"type":32,"tag":278,"props":3637,"children":3638},{"style":428},[3639],{"type":45,"value":3640},"  console.",{"type":32,"tag":278,"props":3642,"children":3643},{"style":285},[3644],{"type":45,"value":3645},"log",{"type":32,"tag":278,"props":3647,"children":3648},{"style":428},[3649],{"type":45,"value":1659},{"type":32,"tag":278,"props":3651,"children":3652},{"style":291},[3653],{"type":45,"value":3654},"'🌱 Starting Seed...'",{"type":32,"tag":278,"props":3656,"children":3657},{"style":428},[3658],{"type":45,"value":1214},{"type":32,"tag":278,"props":3660,"children":3661},{"class":280,"line":1225},[3662],{"type":32,"tag":278,"props":3663,"children":3664},{"emptyLinePlaceholder":513},[3665],{"type":45,"value":516},{"type":32,"tag":278,"props":3667,"children":3668},{"class":280,"line":1269},[3669],{"type":32,"tag":278,"props":3670,"children":3671},{"style":695},[3672],{"type":45,"value":3673},"  // 3. Seed Agents\n",{"type":32,"tag":278,"props":3675,"children":3676},{"class":280,"line":1298},[3677,3681,3686,3690],{"type":32,"tag":278,"props":3678,"children":3679},{"style":1574},[3680],{"type":45,"value":3376},{"type":32,"tag":278,"props":3682,"children":3683},{"style":428},[3684],{"type":45,"value":3685}," agentsData ",{"type":32,"tag":278,"props":3687,"children":3688},{"style":412},[3689],{"type":45,"value":1649},{"type":32,"tag":278,"props":3691,"children":3692},{"style":428},[3693],{"type":45,"value":3694}," [\n",{"type":32,"tag":278,"props":3696,"children":3697},{"class":280,"line":1340},[3698],{"type":32,"tag":278,"props":3699,"children":3700},{"style":428},[3701],{"type":45,"value":3702},"    {\n",{"type":32,"tag":278,"props":3704,"children":3705},{"class":280,"line":1359},[3706,3711,3716],{"type":32,"tag":278,"props":3707,"children":3708},{"style":428},[3709],{"type":45,"value":3710},"      name: ",{"type":32,"tag":278,"props":3712,"children":3713},{"style":291},[3714],{"type":45,"value":3715},"'The Formalist'",{"type":32,"tag":278,"props":3717,"children":3718},{"style":428},[3719],{"type":45,"value":449},{"type":32,"tag":278,"props":3721,"children":3722},{"class":280,"line":1378},[3723,3728,3733],{"type":32,"tag":278,"props":3724,"children":3725},{"style":428},[3726],{"type":45,"value":3727},"      apiRoute: ",{"type":32,"tag":278,"props":3729,"children":3730},{"style":291},[3731],{"type":45,"value":3732},"'/api/agents/formalist'",{"type":32,"tag":278,"props":3734,"children":3735},{"style":428},[3736],{"type":45,"value":449},{"type":32,"tag":278,"props":3738,"children":3739},{"class":280,"line":1386},[3740],{"type":32,"tag":278,"props":3741,"children":3742},{"style":428},[3743],{"type":45,"value":594},{"type":32,"tag":278,"props":3745,"children":3746},{"class":280,"line":1412},[3747],{"type":32,"tag":278,"props":3748,"children":3749},{"style":428},[3750],{"type":45,"value":3702},{"type":32,"tag":278,"props":3752,"children":3753},{"class":280,"line":1443},[3754,3758,3763],{"type":32,"tag":278,"props":3755,"children":3756},{"style":428},[3757],{"type":45,"value":3710},{"type":32,"tag":278,"props":3759,"children":3760},{"style":291},[3761],{"type":45,"value":3762},"'The Traditionalist'",{"type":32,"tag":278,"props":3764,"children":3765},{"style":428},[3766],{"type":45,"value":449},{"type":32,"tag":278,"props":3768,"children":3769},{"class":280,"line":1452},[3770,3774,3779],{"type":32,"tag":278,"props":3771,"children":3772},{"style":428},[3773],{"type":45,"value":3727},{"type":32,"tag":278,"props":3775,"children":3776},{"style":291},[3777],{"type":45,"value":3778},"'/api/agents/traditionalist'",{"type":32,"tag":278,"props":3780,"children":3781},{"style":428},[3782],{"type":45,"value":449},{"type":32,"tag":278,"props":3784,"children":3785},{"class":280,"line":2441},[3786],{"type":32,"tag":278,"props":3787,"children":3788},{"style":428},[3789],{"type":45,"value":594},{"type":32,"tag":278,"props":3791,"children":3792},{"class":280,"line":2449},[3793],{"type":32,"tag":278,"props":3794,"children":3795},{"style":428},[3796],{"type":45,"value":3702},{"type":32,"tag":278,"props":3798,"children":3799},{"class":280,"line":2457},[3800,3804,3809],{"type":32,"tag":278,"props":3801,"children":3802},{"style":428},[3803],{"type":45,"value":3710},{"type":32,"tag":278,"props":3805,"children":3806},{"style":291},[3807],{"type":45,"value":3808},"'The Marketer'",{"type":32,"tag":278,"props":3810,"children":3811},{"style":428},[3812],{"type":45,"value":449},{"type":32,"tag":278,"props":3814,"children":3815},{"class":280,"line":2508},[3816,3820,3825],{"type":32,"tag":278,"props":3817,"children":3818},{"style":428},[3819],{"type":45,"value":3727},{"type":32,"tag":278,"props":3821,"children":3822},{"style":291},[3823],{"type":45,"value":3824},"'/api/agents/marketer'",{"type":32,"tag":278,"props":3826,"children":3827},{"style":428},[3828],{"type":45,"value":449},{"type":32,"tag":278,"props":3830,"children":3831},{"class":280,"line":2526},[3832],{"type":32,"tag":278,"props":3833,"children":3834},{"style":428},[3835],{"type":45,"value":594},{"type":32,"tag":278,"props":3837,"children":3838},{"class":280,"line":2535},[3839],{"type":32,"tag":278,"props":3840,"children":3841},{"style":428},[3842],{"type":45,"value":3843},"  ]\n",{"type":32,"tag":278,"props":3845,"children":3846},{"class":280,"line":2543},[3847,3852,3857,3862,3867,3872],{"type":32,"tag":278,"props":3848,"children":3849},{"style":412},[3850],{"type":45,"value":3851},"  await",{"type":32,"tag":278,"props":3853,"children":3854},{"style":428},[3855],{"type":45,"value":3856}," db.",{"type":32,"tag":278,"props":3858,"children":3859},{"style":285},[3860],{"type":45,"value":3861},"insert",{"type":32,"tag":278,"props":3863,"children":3864},{"style":428},[3865],{"type":45,"value":3866},"(agents).",{"type":32,"tag":278,"props":3868,"children":3869},{"style":285},[3870],{"type":45,"value":3871},"values",{"type":32,"tag":278,"props":3873,"children":3874},{"style":428},[3875],{"type":45,"value":3876},"(agentsData)\n",{"type":32,"tag":278,"props":3878,"children":3879},{"class":280,"line":2590},[3880],{"type":32,"tag":278,"props":3881,"children":3882},{"emptyLinePlaceholder":513},[3883],{"type":45,"value":516},{"type":32,"tag":278,"props":3885,"children":3886},{"class":280,"line":2608},[3887],{"type":32,"tag":278,"props":3888,"children":3889},{"style":695},[3890],{"type":45,"value":3891},"  // 4. Seed Locations (Corrected Data)\n",{"type":32,"tag":278,"props":3893,"children":3894},{"class":280,"line":2617},[3895,3899,3904,3908],{"type":32,"tag":278,"props":3896,"children":3897},{"style":1574},[3898],{"type":45,"value":3376},{"type":32,"tag":278,"props":3900,"children":3901},{"style":428},[3902],{"type":45,"value":3903}," locationsData ",{"type":32,"tag":278,"props":3905,"children":3906},{"style":412},[3907],{"type":45,"value":1649},{"type":32,"tag":278,"props":3909,"children":3910},{"style":428},[3911],{"type":45,"value":3694},{"type":32,"tag":278,"props":3913,"children":3914},{"class":280,"line":2626},[3915],{"type":32,"tag":278,"props":3916,"children":3917},{"style":428},[3918],{"type":45,"value":3702},{"type":32,"tag":278,"props":3920,"children":3921},{"class":280,"line":2635},[3922,3926,3931],{"type":32,"tag":278,"props":3923,"children":3924},{"style":428},[3925],{"type":45,"value":3710},{"type":32,"tag":278,"props":3927,"children":3928},{"style":291},[3929],{"type":45,"value":3930},"'Shoreditch'",{"type":32,"tag":278,"props":3932,"children":3933},{"style":428},[3934],{"type":45,"value":449},{"type":32,"tag":278,"props":3936,"children":3937},{"class":280,"line":2653},[3938,3943,3948,3953,3958,3962,3967,3971,3976,3980,3985],{"type":32,"tag":278,"props":3939,"children":3940},{"style":428},[3941],{"type":45,"value":3942},"      postcodes: [",{"type":32,"tag":278,"props":3944,"children":3945},{"style":291},[3946],{"type":45,"value":3947},"'E1'",{"type":32,"tag":278,"props":3949,"children":3950},{"style":428},[3951],{"type":45,"value":3952},", ",{"type":32,"tag":278,"props":3954,"children":3955},{"style":291},[3956],{"type":45,"value":3957},"'E2'",{"type":32,"tag":278,"props":3959,"children":3960},{"style":428},[3961],{"type":45,"value":3952},{"type":32,"tag":278,"props":3963,"children":3964},{"style":291},[3965],{"type":45,"value":3966},"'EC1'",{"type":32,"tag":278,"props":3968,"children":3969},{"style":428},[3970],{"type":45,"value":3952},{"type":32,"tag":278,"props":3972,"children":3973},{"style":291},[3974],{"type":45,"value":3975},"'EC2'",{"type":32,"tag":278,"props":3977,"children":3978},{"style":428},[3979],{"type":45,"value":3952},{"type":32,"tag":278,"props":3981,"children":3982},{"style":291},[3983],{"type":45,"value":3984},"'N1'",{"type":32,"tag":278,"props":3986,"children":3987},{"style":428},[3988],{"type":45,"value":3989},"],\n",{"type":32,"tag":278,"props":3991,"children":3992},{"class":280,"line":2662},[3993],{"type":32,"tag":278,"props":3994,"children":3995},{"style":428},[3996],{"type":45,"value":594},{"type":32,"tag":278,"props":3998,"children":3999},{"class":280,"line":2671},[4000],{"type":32,"tag":278,"props":4001,"children":4002},{"style":428},[4003],{"type":45,"value":3702},{"type":32,"tag":278,"props":4005,"children":4006},{"class":280,"line":2679},[4007,4011,4016],{"type":32,"tag":278,"props":4008,"children":4009},{"style":428},[4010],{"type":45,"value":3710},{"type":32,"tag":278,"props":4012,"children":4013},{"style":291},[4014],{"type":45,"value":4015},"'Canary Wharf'",{"type":32,"tag":278,"props":4017,"children":4018},{"style":428},[4019],{"type":45,"value":449},{"type":32,"tag":278,"props":4021,"children":4023},{"class":280,"line":4022},48,[4024,4028,4033],{"type":32,"tag":278,"props":4025,"children":4026},{"style":428},[4027],{"type":45,"value":3942},{"type":32,"tag":278,"props":4029,"children":4030},{"style":291},[4031],{"type":45,"value":4032},"'E14'",{"type":32,"tag":278,"props":4034,"children":4035},{"style":428},[4036],{"type":45,"value":3989},{"type":32,"tag":278,"props":4038,"children":4040},{"class":280,"line":4039},49,[4041],{"type":32,"tag":278,"props":4042,"children":4043},{"style":428},[4044],{"type":45,"value":594},{"type":32,"tag":278,"props":4046,"children":4048},{"class":280,"line":4047},50,[4049],{"type":32,"tag":278,"props":4050,"children":4051},{"style":428},[4052],{"type":45,"value":3702},{"type":32,"tag":278,"props":4054,"children":4056},{"class":280,"line":4055},51,[4057,4061,4066],{"type":32,"tag":278,"props":4058,"children":4059},{"style":428},[4060],{"type":45,"value":3710},{"type":32,"tag":278,"props":4062,"children":4063},{"style":291},[4064],{"type":45,"value":4065},"'Brixton'",{"type":32,"tag":278,"props":4067,"children":4068},{"style":428},[4069],{"type":45,"value":449},{"type":32,"tag":278,"props":4071,"children":4073},{"class":280,"line":4072},52,[4074,4078,4083,4087,4092],{"type":32,"tag":278,"props":4075,"children":4076},{"style":428},[4077],{"type":45,"value":3942},{"type":32,"tag":278,"props":4079,"children":4080},{"style":291},[4081],{"type":45,"value":4082},"'SW2'",{"type":32,"tag":278,"props":4084,"children":4085},{"style":428},[4086],{"type":45,"value":3952},{"type":32,"tag":278,"props":4088,"children":4089},{"style":291},[4090],{"type":45,"value":4091},"'SW9'",{"type":32,"tag":278,"props":4093,"children":4094},{"style":428},[4095],{"type":45,"value":3989},{"type":32,"tag":278,"props":4097,"children":4099},{"class":280,"line":4098},53,[4100],{"type":32,"tag":278,"props":4101,"children":4102},{"style":428},[4103],{"type":45,"value":594},{"type":32,"tag":278,"props":4105,"children":4107},{"class":280,"line":4106},54,[4108],{"type":32,"tag":278,"props":4109,"children":4110},{"style":428},[4111],{"type":45,"value":3702},{"type":32,"tag":278,"props":4113,"children":4115},{"class":280,"line":4114},55,[4116,4120,4125],{"type":32,"tag":278,"props":4117,"children":4118},{"style":428},[4119],{"type":45,"value":3710},{"type":32,"tag":278,"props":4121,"children":4122},{"style":291},[4123],{"type":45,"value":4124},"'Notting Hill'",{"type":32,"tag":278,"props":4126,"children":4127},{"style":428},[4128],{"type":45,"value":449},{"type":32,"tag":278,"props":4130,"children":4132},{"class":280,"line":4131},56,[4133,4137,4142,4146,4151,4155,4160],{"type":32,"tag":278,"props":4134,"children":4135},{"style":428},[4136],{"type":45,"value":3942},{"type":32,"tag":278,"props":4138,"children":4139},{"style":291},[4140],{"type":45,"value":4141},"'W10'",{"type":32,"tag":278,"props":4143,"children":4144},{"style":428},[4145],{"type":45,"value":3952},{"type":32,"tag":278,"props":4147,"children":4148},{"style":291},[4149],{"type":45,"value":4150},"'W11'",{"type":32,"tag":278,"props":4152,"children":4153},{"style":428},[4154],{"type":45,"value":3952},{"type":32,"tag":278,"props":4156,"children":4157},{"style":291},[4158],{"type":45,"value":4159},"'W2'",{"type":32,"tag":278,"props":4161,"children":4162},{"style":428},[4163],{"type":45,"value":3989},{"type":32,"tag":278,"props":4165,"children":4167},{"class":280,"line":4166},57,[4168],{"type":32,"tag":278,"props":4169,"children":4170},{"style":428},[4171],{"type":45,"value":594},{"type":32,"tag":278,"props":4173,"children":4175},{"class":280,"line":4174},58,[4176],{"type":32,"tag":278,"props":4177,"children":4178},{"style":428},[4179],{"type":45,"value":3843},{"type":32,"tag":278,"props":4181,"children":4183},{"class":280,"line":4182},59,[4184,4188,4192,4196,4201,4205],{"type":32,"tag":278,"props":4185,"children":4186},{"style":412},[4187],{"type":45,"value":3851},{"type":32,"tag":278,"props":4189,"children":4190},{"style":428},[4191],{"type":45,"value":3856},{"type":32,"tag":278,"props":4193,"children":4194},{"style":285},[4195],{"type":45,"value":3861},{"type":32,"tag":278,"props":4197,"children":4198},{"style":428},[4199],{"type":45,"value":4200},"(locations).",{"type":32,"tag":278,"props":4202,"children":4203},{"style":285},[4204],{"type":45,"value":3871},{"type":32,"tag":278,"props":4206,"children":4207},{"style":428},[4208],{"type":45,"value":4209},"(locationsData)\n",{"type":32,"tag":278,"props":4211,"children":4213},{"class":280,"line":4212},60,[4214],{"type":32,"tag":278,"props":4215,"children":4216},{"emptyLinePlaceholder":513},[4217],{"type":45,"value":516},{"type":32,"tag":278,"props":4219,"children":4221},{"class":280,"line":4220},61,[4222,4227],{"type":32,"tag":278,"props":4223,"children":4224},{"style":412},[4225],{"type":45,"value":4226},"  return",{"type":32,"tag":278,"props":4228,"children":4229},{"style":428},[4230],{"type":45,"value":3361},{"type":32,"tag":278,"props":4232,"children":4234},{"class":280,"line":4233},62,[4235,4240,4244],{"type":32,"tag":278,"props":4236,"children":4237},{"style":428},[4238],{"type":45,"value":4239},"    success: ",{"type":32,"tag":278,"props":4241,"children":4242},{"style":361},[4243],{"type":45,"value":462},{"type":32,"tag":278,"props":4245,"children":4246},{"style":428},[4247],{"type":45,"value":449},{"type":32,"tag":278,"props":4249,"children":4251},{"class":280,"line":4250},63,[4252,4257,4262],{"type":32,"tag":278,"props":4253,"children":4254},{"style":428},[4255],{"type":45,"value":4256},"    message: ",{"type":32,"tag":278,"props":4258,"children":4259},{"style":291},[4260],{"type":45,"value":4261},"'Database Seeded'",{"type":32,"tag":278,"props":4263,"children":4264},{"style":428},[4265],{"type":45,"value":449},{"type":32,"tag":278,"props":4267,"children":4269},{"class":280,"line":4268},64,[4270],{"type":32,"tag":278,"props":4271,"children":4272},{"style":428},[4273],{"type":45,"value":4274},"    stats: {\n",{"type":32,"tag":278,"props":4276,"children":4278},{"class":280,"line":4277},65,[4279],{"type":32,"tag":278,"props":4280,"children":4281},{"style":428},[4282],{"type":45,"value":4283},"      agents: agentsData.length,\n",{"type":32,"tag":278,"props":4285,"children":4287},{"class":280,"line":4286},66,[4288],{"type":32,"tag":278,"props":4289,"children":4290},{"style":428},[4291],{"type":45,"value":4292},"      locations: locationsData.length,\n",{"type":32,"tag":278,"props":4294,"children":4296},{"class":280,"line":4295},67,[4297],{"type":32,"tag":278,"props":4298,"children":4299},{"style":428},[4300],{"type":45,"value":594},{"type":32,"tag":278,"props":4302,"children":4304},{"class":280,"line":4303},68,[4305],{"type":32,"tag":278,"props":4306,"children":4307},{"style":428},[4308],{"type":45,"value":3488},{"type":32,"tag":278,"props":4310,"children":4312},{"class":280,"line":4311},69,[4313],{"type":32,"tag":278,"props":4314,"children":4315},{"style":428},[4316],{"type":45,"value":612},{"type":32,"tag":33,"props":4318,"children":4319},{},[4320],{"type":45,"value":4321},"That’s it, build, deploy, and run the seeder:",{"type":32,"tag":267,"props":4323,"children":4325},{"className":782,"code":4324,"language":784,"meta":272,"style":272},"pnpm build\nnpx wrangler deploy\n\ncurl -H \"x-secret: [YOUR_SECRET]\" \"https://[YOUR_WORKER_URL]/api/internals/seed\n",[4326],{"type":32,"tag":74,"props":4327,"children":4328},{"__ignoreMap":272},[4329,4340,4355,4362],{"type":32,"tag":278,"props":4330,"children":4331},{"class":280,"line":281},[4332,4336],{"type":32,"tag":278,"props":4333,"children":4334},{"style":285},[4335],{"type":45,"value":288},{"type":32,"tag":278,"props":4337,"children":4338},{"style":291},[4339],{"type":45,"value":757},{"type":32,"tag":278,"props":4341,"children":4342},{"class":280,"line":312},[4343,4347,4351],{"type":32,"tag":278,"props":4344,"children":4345},{"style":285},[4346],{"type":45,"value":765},{"type":32,"tag":278,"props":4348,"children":4349},{"style":291},[4350],{"type":45,"value":374},{"type":32,"tag":278,"props":4352,"children":4353},{"style":291},[4354],{"type":45,"value":774},{"type":32,"tag":278,"props":4356,"children":4357},{"class":280,"line":326},[4358],{"type":32,"tag":278,"props":4359,"children":4360},{"emptyLinePlaceholder":513},[4361],{"type":45,"value":516},{"type":32,"tag":278,"props":4363,"children":4364},{"class":280,"line":349},[4365,4370,4375,4380],{"type":32,"tag":278,"props":4366,"children":4367},{"style":285},[4368],{"type":45,"value":4369},"curl",{"type":32,"tag":278,"props":4371,"children":4372},{"style":361},[4373],{"type":45,"value":4374}," -H",{"type":32,"tag":278,"props":4376,"children":4377},{"style":291},[4378],{"type":45,"value":4379}," \"x-secret: [YOUR_SECRET]\"",{"type":32,"tag":278,"props":4381,"children":4382},{"style":291},[4383],{"type":45,"value":4384}," \"https://[YOUR_WORKER_URL]/api/internals/seed\n",{"type":32,"tag":33,"props":4386,"children":4387},{},[4388],{"type":45,"value":4389},"You can now see the seeded data through Cloudflare’s Database Explorer by navigating to:",{"type":32,"tag":33,"props":4391,"children":4392},{},[4393],{"type":32,"tag":74,"props":4394,"children":4396},{"className":4395},[],[4397],{"type":45,"value":4398},"Storage & databases → D1 SQL database → property-sync-db → Explore Data",{"type":32,"tag":218,"props":4400,"children":4404},{":sub-link":220,"button-text":4401,"link":222,"sub-link-text":223,"text":4402,"title":4403},"Get in touch","Don't let the infrastructure details slow you down. I help your team cut through the complexity and ship a solid, scalable Nuxt application.","Need to launch your Nuxt project?",[],{"type":32,"tag":146,"props":4406,"children":4408},{"id":4407},"cloudflare-workers-ai",[4409],{"type":45,"value":4410},"Cloudflare Workers AI",{"type":32,"tag":33,"props":4412,"children":4413},{},[4414,4416,4423],{"type":45,"value":4415},"Although this is not a tutorial about AI, it is important to note the difference between Cloudflare Workers AI and Cloudflare Vectorize. Vector stores are \"simply\" a database of vectors; ",{"type":32,"tag":53,"props":4417,"children":4420},{"href":4418,"rel":4419,"target":58},"https://www.pinecone.io/",[57],[4421],{"type":45,"value":4422},"Pinecone",{"type":45,"value":4424}," is a popular alternative to Cloudflare Vectorize. In contrast, Workers AI is the compute part, the processor that generates text embedding from our data, which can later be stored as vectors.",{"type":32,"tag":33,"props":4426,"children":4427},{},[4428],{"type":45,"value":4429},"In short, Vectorize is the memory, and Workers AI is the brain. With standalone solutions like Pinecone, you generally still need separate services for the memory and the brain (e.g., Pinecone + OpenAI). The Cloudflare ecosystem bundles the generation of embeddings (Workers AI) and their storage (Vectorize) into a single, low-latency workflow.",{"type":32,"tag":33,"props":4431,"children":4432},{},[4433,4435,4440],{"type":45,"value":4434},"Since Workers AI is a built-in platform service, we only need to specify the binding in our ",{"type":32,"tag":74,"props":4436,"children":4438},{"className":4437},[],[4439],{"type":45,"value":2853},{"type":45,"value":4441}," config to access it directly form our Nuxt application.",{"type":32,"tag":33,"props":4443,"children":4444},{},[4445,4447,4452],{"type":45,"value":4446},"Go ahead and add the binding in ",{"type":32,"tag":74,"props":4448,"children":4450},{"className":4449},[],[4451],{"type":45,"value":2853},{"type":45,"value":2775},{"type":32,"tag":267,"props":4454,"children":4456},{"className":634,"code":4455,"language":636,"meta":272,"style":272},"[ai]\nbinding = \"AI\"\n",[4457],{"type":32,"tag":74,"props":4458,"children":4459},{"__ignoreMap":272},[4460,4468],{"type":32,"tag":278,"props":4461,"children":4462},{"class":280,"line":281},[4463],{"type":32,"tag":278,"props":4464,"children":4465},{"style":428},[4466],{"type":45,"value":4467},"[ai]\n",{"type":32,"tag":278,"props":4469,"children":4470},{"class":280,"line":312},[4471,4475],{"type":32,"tag":278,"props":4472,"children":4473},{"style":428},[4474],{"type":45,"value":2798},{"type":32,"tag":278,"props":4476,"children":4477},{"style":291},[4478],{"type":45,"value":4479},"\"AI\"\n",{"type":32,"tag":33,"props":4481,"children":4482},{},[4483],{"type":45,"value":4484},"This binding will be effective on our next deployment.",{"type":32,"tag":146,"props":4486,"children":4488},{"id":4487},"moving-forward-with-storing-vectors-on-cloudflares-vectorize-index",[4489],{"type":45,"value":4490},"Moving forward with storing vectors on Cloudflare’s Vectorize Index",{"type":32,"tag":33,"props":4492,"children":4493},{},[4494,4496,4501],{"type":45,"value":4495},"In the next part of this Nuxt & Cloudflare AI Vector Pipeline Series, we will be ",{"type":32,"tag":53,"props":4497,"children":4498},{"href":125},[4499],{"type":45,"value":4500},"building a Background Data Sync Pipeline using Vectorize",{"type":45,"value":4502},". In the article, we will also take a deep dive into working with Cloudflare Queues from our Nuxt application and, most importantly, listen and handle the dispatched Queue messages from the same Nuxt application, i.e., the same Cloudflare Worker.",{"type":32,"tag":33,"props":4504,"children":4505},{},[4506,4508,4514],{"type":45,"value":4507},"I hope you found this article helpful. Feel free to ask me anything in the comments below or on Social. Please share it with your peers and ",{"type":32,"tag":53,"props":4509,"children":4511},{"href":4510},"/subscribe/",[4512],{"type":45,"value":4513},"subscribe",{"type":45,"value":4515}," to get notified when I publish new articles 💙.",{"type":32,"tag":4517,"props":4518,"children":4519},"style",{},[4520],{"type":45,"value":4521},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":272,"searchDepth":312,"depth":312,"links":4523},[4524,4527,4533,4534],{"id":148,"depth":312,"text":151,"children":4525},[4526],{"id":170,"depth":326,"text":173},{"id":257,"depth":312,"text":260,"children":4528},[4529,4530,4531,4532],{"id":615,"depth":326,"text":618},{"id":1494,"depth":326,"text":1497},{"id":2722,"depth":326,"text":2725},{"id":3203,"depth":326,"text":3206},{"id":4407,"depth":312,"text":4410},{"id":4487,"depth":312,"text":4490},"markdown","content:blog:10.nuxt-and-cloudflare-vectorize-setting-up-d1-drizzle-and-workers-ai:index.md","content","blog/10.nuxt-and-cloudflare-vectorize-setting-up-d1-drizzle-and-workers-ai/index.md","blog/10.nuxt-and-cloudflare-vectorize-setting-up-d1-drizzle-and-workers-ai/index","md",[4542,4548,4553],{"_path":26,"title":4543,"date":4544,"preview_image":4545,"featured_image":4546,"_id":4547},"Implementing Semantic Matching in Nuxt with Cloudflare Vectorize","2025-12-21","/nuxt-cloudflare-vectorize-semantic-matching/nuxt-cloudflare-vectorize-semantic-matching.webp","/nuxt-cloudflare-vectorize-semantic-matching/nuxt-cloudflare-vectorize-semantic-matching_featured.webp","content:blog:12.nuxt-cloudflare-vectorize-semantic-matching:index.md",{"_path":25,"title":128,"date":4549,"preview_image":4550,"featured_image":4551,"_id":4552},"2025-12-20","/nuxt-cloudflare-queues-data-sync-pipeline/nuxt-cloudflare-queues-data-sync-pipeline.webp","/nuxt-cloudflare-queues-data-sync-pipeline/nuxt-cloudflare-queues-data-sync-pipeline_featured.webp","content:blog:11.nuxt-cloudflare-queues-and-vectorize-data-sync-pipeline:index.md",{"_path":27,"title":4554,"date":4555,"preview_image":4556,"_id":4557},"Build and deploy a static online shop with Nuxt3 using Pinia Store and Stripe Checkout to Firebase","2022-11-13","/build-and-deploy-nuxt3-static-site-with-pinia-and-stripe-checkout-on-firebase/nuxt3-static-shop.png","content:blog:9.build-and-deploy-nuxt3-static-site-with-pinia-and-stripe-checkout-on-firebase:index.md",1776233981250]