[{"data":1,"prerenderedAt":4492},["ShallowReactive",2],{"navigation_docs_en":3,"-en-reference-extensions-data-connectors-operations":445,"-en-reference-extensions-data-connectors-operations-surround":4487},[4,30,72,132,260,436],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting Started",false,"\u002Fen\u002Fgetting-started","en\u002F1.getting-started",[10,15,20,25],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fen\u002Fgetting-started\u002Fintroduction","en\u002F1.getting-started\u002F2.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Quickstart","\u002Fen\u002Fgetting-started\u002Finstallation","en\u002F1.getting-started\u002F3.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Use Cases","\u002Fen\u002Fgetting-started\u002Fuse-cases","en\u002F1.getting-started\u002F4.use-cases","i-lucide-layers",{"title":26,"path":27,"stem":28,"icon":29},"Concepts","\u002Fen\u002Fgetting-started\u002Fconcepts","en\u002F1.getting-started\u002F5.concepts","i-lucide-book",{"title":26,"path":31,"stem":32,"children":33,"page":6},"\u002Fen\u002Fconcepts","en\u002F2.concepts",[34,38,43,48,53,58,63,68],{"title":35,"path":36,"stem":37,"icon":14},"Organization","\u002Fen\u002Fconcepts\u002Forganization","en\u002F2.concepts\u002F1.organization",{"title":39,"path":40,"stem":41,"icon":42},"Data Model","\u002Fen\u002Fconcepts\u002Fdata-model","en\u002F2.concepts\u002F2.data-model","i-lucide-database",{"title":44,"path":45,"stem":46,"icon":47},"Access Control","\u002Fen\u002Fconcepts\u002Faccess-permissions","en\u002F2.concepts\u002F3.access-permissions","i-lucide-user-key",{"title":49,"path":50,"stem":51,"icon":52},"Audit Logs","\u002Fen\u002Fconcepts\u002Faudit-logs","en\u002F2.concepts\u002F4.audit-logs","i-lucide-scroll-text",{"title":54,"path":55,"stem":56,"icon":57},"Introspection","\u002Fen\u002Fconcepts\u002Fintrospection","en\u002F2.concepts\u002F6.introspection","i-lucide-database-search",{"title":59,"path":60,"stem":61,"icon":62},"Query Engine","\u002Fen\u002Fconcepts\u002Fquery-engine","en\u002F2.concepts\u002F7.query-engine","i-lucide-workflow",{"title":64,"path":65,"stem":66,"icon":67},"AI","\u002Fen\u002Fconcepts\u002Fai","en\u002F2.concepts\u002F8.ai","i-lucide-sparkles",{"title":69,"path":70,"stem":71,"icon":42},"Caching","\u002Fen\u002Fconcepts\u002Fcaching","en\u002F2.concepts\u002F9.caching",{"title":73,"path":74,"stem":75,"children":76,"page":6},"Guides","\u002Fen\u002Fguides","en\u002F4.guides",[77,82,87,92,97,102,107,112],{"title":78,"path":79,"stem":80,"icon":81},"REST API Quickstart","\u002Fen\u002Fguides\u002Frest-api","en\u002F4.guides\u002F1.rest-api","i-lucide-plug",{"title":83,"path":84,"stem":85,"icon":86},"SDK Quickstart","\u002Fen\u002Fguides\u002Fsdk","en\u002F4.guides\u002F2.sdk","i-lucide-terminal",{"title":88,"path":89,"stem":90,"icon":91},"Configure SSO","\u002Fen\u002Fguides\u002Fconfigure-sso","en\u002F4.guides\u002F3.configure-sso","i-lucide-key-round",{"title":93,"path":94,"stem":95,"icon":96},"Configure MCP","\u002Fen\u002Fguides\u002Fmcp","en\u002F4.guides\u002F4.mcp","i-lucide-brain-cog",{"title":98,"path":99,"stem":100,"icon":101},"Customize Content Space","\u002Fen\u002Fguides\u002Fcustomize-content-space","en\u002F4.guides\u002F5.customize-content-space","i-lucide-columns-3-cog",{"title":103,"path":104,"stem":105,"icon":106},"Build an Application with AI Assistance","\u002Fen\u002Fguides\u002Fbuild-an-application","en\u002F4.guides\u002F6.build-an-application","i-lucide-route",{"title":108,"path":109,"stem":110,"icon":111},"Horizontal Scaling","\u002Fen\u002Fguides\u002Fhorizontal-scaling","en\u002F4.guides\u002F7.horizontal-scaling","i-lucide-network",{"title":113,"icon":114,"path":115,"stem":116,"children":117,"page":6},"Data Connectors","i-lucide-cable","\u002Fen\u002Fguides\u002Fdata-connectors","en\u002F4.guides\u002F8.data-connectors",[118,122,127],{"title":16,"path":119,"stem":120,"icon":121},"\u002Fen\u002Fguides\u002Fdata-connectors\u002Fquickstart","en\u002F4.guides\u002F8.data-connectors\u002F1.quickstart","i-lucide-rocket",{"title":123,"path":124,"stem":125,"icon":126},"Build a Stripe Connector","\u002Fen\u002Fguides\u002Fdata-connectors\u002Fstripe","en\u002F4.guides\u002F8.data-connectors\u002F2.stripe","i-lucide-hammer",{"title":128,"path":129,"stem":130,"icon":131},"Build with AI Agents","\u002Fen\u002Fguides\u002Fdata-connectors\u002Fai-agents","en\u002F4.guides\u002F8.data-connectors\u002F3.ai-agents","i-lucide-bot",{"title":133,"path":134,"stem":135,"children":136,"page":6},"Developer","\u002Fen\u002Fdeveloper","en\u002F5.developer",[137,191,215,220],{"title":138,"path":139,"stem":140,"children":141,"page":6},"Data Access","\u002Fen\u002Fdeveloper\u002Fapi","en\u002F5.developer\u002F1.api",[142,147,152,157,162,167,172,177,182,186],{"title":143,"path":144,"stem":145,"icon":146},"Overview","\u002Fen\u002Fdeveloper\u002Fapi\u002Foverview","en\u002F5.developer\u002F1.api\u002F1.overview","i-lucide-globe",{"title":148,"path":149,"stem":150,"icon":151},"Errors","\u002Fen\u002Fdeveloper\u002Fapi\u002Ferrors","en\u002F5.developer\u002F1.api\u002F10.errors","i-lucide-alert-triangle",{"title":153,"path":154,"stem":155,"icon":156},"Authentication","\u002Fen\u002Fdeveloper\u002Fapi\u002Fauthentication","en\u002F5.developer\u002F1.api\u002F2.authentication","i-lucide-lock",{"title":158,"path":159,"stem":160,"icon":161},"Reading Data","\u002Fen\u002Fdeveloper\u002Fapi\u002Freading-data","en\u002F5.developer\u002F1.api\u002F3.reading-data","i-lucide-book-open",{"title":163,"path":164,"stem":165,"icon":166},"Writing Data","\u002Fen\u002Fdeveloper\u002Fapi\u002Fwriting-data","en\u002F5.developer\u002F1.api\u002F4.writing-data","i-lucide-pencil",{"title":168,"path":169,"stem":170,"icon":171},"Filtering","\u002Fen\u002Fdeveloper\u002Fapi\u002Ffiltering","en\u002F5.developer\u002F1.api\u002F5.filtering","i-lucide-filter",{"title":173,"path":174,"stem":175,"icon":176},"Field Selection","\u002Fen\u002Fdeveloper\u002Fapi\u002Ffield-selection","en\u002F5.developer\u002F1.api\u002F6.field-selection","i-lucide-list-checks",{"title":178,"path":179,"stem":180,"icon":181},"Sorting & Pagination","\u002Fen\u002Fdeveloper\u002Fapi\u002Fsorting-pagination","en\u002F5.developer\u002F1.api\u002F7.sorting-pagination","i-lucide-arrow-up-down",{"title":183,"path":184,"stem":185,"icon":111},"Relational Data","\u002Fen\u002Fdeveloper\u002Fapi\u002Frelational-data","en\u002F5.developer\u002F1.api\u002F8.relational-data",{"title":187,"path":188,"stem":189,"icon":190},"Files & Assets","\u002Fen\u002Fdeveloper\u002Fapi\u002Ffiles","en\u002F5.developer\u002F1.api\u002F9.files","i-lucide-file-up",{"title":192,"path":193,"stem":194,"children":195,"page":6},"Client SDK","\u002Fen\u002Fdeveloper\u002Fsdk","en\u002F5.developer\u002F2.sdk",[196,200,205,210],{"title":197,"path":198,"stem":199,"icon":19},"Installation","\u002Fen\u002Fdeveloper\u002Fsdk\u002Finstallation","en\u002F5.developer\u002F2.sdk\u002F1.installation",{"title":201,"path":202,"stem":203,"icon":204},"Client Setup","\u002Fen\u002Fdeveloper\u002Fsdk\u002Fclient-setup","en\u002F5.developer\u002F2.sdk\u002F2.client-setup","i-lucide-settings",{"title":206,"path":207,"stem":208,"icon":209},"Type System","\u002Fen\u002Fdeveloper\u002Fsdk\u002Ftype-system","en\u002F5.developer\u002F2.sdk\u002F3.type-system","i-lucide-braces",{"title":211,"path":212,"stem":213,"icon":214},"Advanced","\u002Fen\u002Fdeveloper\u002Fsdk\u002Fadvanced","en\u002F5.developer\u002F2.sdk\u002F5.advanced","i-lucide-puzzle",{"title":216,"path":217,"stem":218,"icon":219},"Application Users","\u002Fen\u002Fdeveloper\u002Fapplication-users","en\u002F5.developer\u002F3.application-users","i-lucide-users",{"title":221,"path":222,"stem":223,"children":224,"icon":214},"Extensions","\u002Fen\u002Fdeveloper\u002Fextensions","en\u002F5.developer\u002F3.extensions\u002Findex",[225,226,231],{"title":143,"path":222,"stem":223,"icon":214},{"title":227,"path":228,"stem":229,"icon":230},"Install and Manage Extensions","\u002Fen\u002Fdeveloper\u002Fextensions\u002Finstall","en\u002F5.developer\u002F3.extensions\u002F1.install","i-lucide-package-plus",{"title":113,"path":232,"stem":233,"children":234,"icon":114},"\u002Fen\u002Fdeveloper\u002Fextensions\u002Fdata-connectors","en\u002F5.developer\u002F3.extensions\u002F2.data-connectors\u002Findex",[235,236,241,245,250,255],{"title":143,"path":232,"stem":233,"icon":114},{"title":237,"path":238,"stem":239,"icon":240},"How Data Connectors Run","\u002Fen\u002Fdeveloper\u002Fextensions\u002Fdata-connectors\u002Fruntime","en\u002F5.developer\u002F3.extensions\u002F2.data-connectors\u002F2.runtime","i-lucide-cpu",{"title":242,"path":243,"stem":244,"icon":42},"Data Sources","\u002Fen\u002Fdeveloper\u002Fextensions\u002Fdata-connectors\u002Fdata-sources","en\u002F5.developer\u002F3.extensions\u002F2.data-connectors\u002F3.data-sources",{"title":246,"path":247,"stem":248,"icon":249},"Map an External Data Source","\u002Fen\u002Fdeveloper\u002Fextensions\u002Fdata-connectors\u002Fdata-source-mapping","en\u002F5.developer\u002F3.extensions\u002F2.data-connectors\u002F4.data-source-mapping","i-lucide-map",{"title":251,"path":252,"stem":253,"icon":254},"Handle Errors","\u002Fen\u002Fdeveloper\u002Fextensions\u002Fdata-connectors\u002Ferrors","en\u002F5.developer\u002F3.extensions\u002F2.data-connectors\u002F5.errors","i-lucide-shield-alert",{"title":256,"path":257,"stem":258,"icon":259},"Test a Data Connector","\u002Fen\u002Fdeveloper\u002Fextensions\u002Fdata-connectors\u002Ftesting","en\u002F5.developer\u002F3.extensions\u002F2.data-connectors\u002F6.testing","i-lucide-flask-conical",{"title":261,"path":262,"stem":263,"children":264,"page":6},"Reference","\u002Fen\u002Freference","en\u002F6.reference",[265,269,274,279,295,299,304,340,369,374],{"title":266,"path":267,"stem":268,"icon":204},"Configuration","\u002Fen\u002Freference\u002Fenvironment-variables","en\u002F6.reference\u002F1.environment-variables",{"title":270,"path":271,"stem":272,"icon":273},"System Requirements","\u002Fen\u002Freference\u002Fsystem-requirements","en\u002F6.reference\u002F2.system-requirements","i-lucide-server",{"title":275,"path":276,"stem":277,"icon":278},"Licensing","\u002Fen\u002Freference\u002Flicensing","en\u002F6.reference\u002F3.licensing","i-lucide-gem",{"title":280,"path":281,"stem":282,"children":283,"icon":81},"Connectors","\u002Fen\u002Freference\u002Fconnectors","en\u002F6.reference\u002F4.connectors\u002Findex",[284,285,290],{"title":280,"path":281,"stem":282,"icon":81},{"title":286,"path":287,"stem":288,"icon":289},"PostgreSQL and Supabase","\u002Fen\u002Freference\u002Fconnectors\u002Fpostgresql-supabase","en\u002F6.reference\u002F4.connectors\u002F1.postgresql-supabase","i-simple-icons-postgresql",{"title":291,"path":292,"stem":293,"icon":294},"MySQL and MariaDB","\u002Fen\u002Freference\u002Fconnectors\u002Fmysql-mariadb","en\u002F6.reference\u002F4.connectors\u002F2.mysql-mariadb","i-simple-icons-mysql",{"title":296,"path":297,"stem":298,"icon":209},"Data Types Representation","\u002Fen\u002Freference\u002Fdata-types","en\u002F6.reference\u002F5.data-types",{"title":300,"path":301,"stem":302,"icon":303},"Permissions Reference","\u002Fen\u002Freference\u002Fpermissions","en\u002F6.reference\u002F6.permissions","i-lucide-shield",{"title":305,"path":306,"stem":307,"children":308,"page":6},"API Reference","\u002Fen\u002Freference\u002Fapi-reference","en\u002F6.reference\u002F7.api-reference",[309,313,318],{"title":310,"path":311,"stem":312,"icon":273},"System Endpoints","\u002Fen\u002Freference\u002Fapi-reference\u002Fsystem-endpoints","en\u002F6.reference\u002F7.api-reference\u002F1.system-endpoints",{"title":314,"path":315,"stem":316,"icon":317},"OpenAPI Spec","\u002Fen\u002Freference\u002Fapi-reference\u002Fopenapi-spec","en\u002F6.reference\u002F7.api-reference\u002F2.openapi-spec","i-lucide-file-code",{"title":319,"path":320,"stem":321,"children":322,"icon":324},"Schema Migration","\u002Fen\u002Freference\u002Fapi-reference\u002Fschema-migration","en\u002F6.reference\u002F7.api-reference\u002F3.schema-migration\u002Findex",[323,325,330,335],{"title":319,"path":320,"stem":321,"icon":324},"i-lucide-database-zap",{"title":326,"path":327,"stem":328,"icon":329},"Apply Migrations","\u002Fen\u002Freference\u002Fapi-reference\u002Fschema-migration\u002Fapply-migrations","en\u002F6.reference\u002F7.api-reference\u002F3.schema-migration\u002F1.apply-migrations","i-lucide-upload",{"title":331,"path":332,"stem":333,"icon":334},"Import Changes","\u002Fen\u002Freference\u002Fapi-reference\u002Fschema-migration\u002Fimport-changes","en\u002F6.reference\u002F7.api-reference\u002F3.schema-migration\u002F2.import-changes","i-lucide-refresh-cw",{"title":336,"path":337,"stem":338,"icon":339},"Operation Reference","\u002Fen\u002Freference\u002Fapi-reference\u002Fschema-migration\u002Foperation-reference","en\u002F6.reference\u002F7.api-reference\u002F3.schema-migration\u002F3.operation-reference","i-lucide-list-tree",{"title":341,"path":342,"stem":343,"children":344,"page":6},"Design Considerations","\u002Fen\u002Freference\u002Fdesign-considerations","en\u002F6.reference\u002F8.design-considerations",[345,349,354,359,364],{"title":143,"path":346,"stem":347,"icon":348},"\u002Fen\u002Freference\u002Fdesign-considerations\u002Foverview","en\u002F6.reference\u002F8.design-considerations\u002F1.overview","i-lucide-compass",{"title":350,"path":351,"stem":352,"icon":353},"Instance Configuration","\u002Fen\u002Freference\u002Fdesign-considerations\u002Finstance-configuration-related-problems","en\u002F6.reference\u002F8.design-considerations\u002F3.instance-configuration-related-problems","i-lucide-wrench",{"title":355,"path":356,"stem":357,"icon":358},"Overly Permissive Public Access","\u002Fen\u002Freference\u002Fdesign-considerations\u002Foverly-permissive","en\u002F6.reference\u002F8.design-considerations\u002F4.overly-permissive","i-lucide-shield-off",{"title":360,"path":361,"stem":362,"icon":363},"No Aggregates","\u002Fen\u002Freference\u002Fdesign-considerations\u002Fno-aggregates","en\u002F6.reference\u002F8.design-considerations\u002F5.no-aggregates","i-lucide-sigma",{"title":365,"path":366,"stem":367,"icon":368},"Cross-Data-Source Referential Integrity","\u002Fen\u002Freference\u002Fdesign-considerations\u002Fcross-data-source-referential-integrity","en\u002F6.reference\u002F8.design-considerations\u002F6.cross-data-source-referential-integrity","i-lucide-unlink",{"title":370,"path":371,"stem":372,"icon":373},"CLI","\u002Fen\u002Freference\u002Fcli","en\u002F6.reference\u002F9.cli","i-lucide-square-terminal",{"title":221,"path":375,"stem":376,"children":377,"page":6},"\u002Fen\u002Freference\u002Fextensions","en\u002F6.reference\u002F9.extensions",[378,383,386,405],{"title":379,"path":380,"stem":381,"icon":382},"Extension Config and Manifest","\u002Fen\u002Freference\u002Fextensions\u002Fmanifest","en\u002F6.reference\u002F9.extensions\u002F1.manifest","i-lucide-file-json",{"title":370,"path":384,"stem":385,"icon":86},"\u002Fen\u002Freference\u002Fextensions\u002Fcli","en\u002F6.reference\u002F9.extensions\u002F2.cli",{"title":387,"path":388,"stem":389,"children":390,"page":6},"Extension Kit","\u002Fen\u002Freference\u002Fextensions\u002Fextension-kit","en\u002F6.reference\u002F9.extensions\u002F3.extension-kit",[391,395,400],{"title":392,"path":393,"stem":394,"icon":81},"Data Connector","\u002Fen\u002Freference\u002Fextensions\u002Fextension-kit\u002Fdata-connector","en\u002F6.reference\u002F9.extensions\u002F3.extension-kit\u002F1.data-connector",{"title":396,"path":397,"stem":398,"icon":399},"Protocol","\u002Fen\u002Freference\u002Fextensions\u002Fextension-kit\u002Fprotocol","en\u002F6.reference\u002F9.extensions\u002F3.extension-kit\u002F2.protocol","i-lucide-arrow-left-right",{"title":401,"path":402,"stem":403,"icon":404},"Schema Helpers","\u002Fen\u002Freference\u002Fextensions\u002Fextension-kit\u002Fexperimental","en\u002F6.reference\u002F9.extensions\u002F3.extension-kit\u002F3.experimental","i-lucide-blocks",{"title":113,"path":406,"stem":407,"children":408,"page":6},"\u002Fen\u002Freference\u002Fextensions\u002Fdata-connectors","en\u002F6.reference\u002F9.extensions\u002F4.data-connectors",[409,413,417,421,426,431],{"title":410,"path":411,"stem":412,"icon":81},"Data Connector API","\u002Fen\u002Freference\u002Fextensions\u002Fdata-connectors\u002Fapi","en\u002F6.reference\u002F9.extensions\u002F4.data-connectors\u002F1.api",{"title":414,"path":415,"stem":416,"icon":176},"Operations and Operators","\u002Fen\u002Freference\u002Fextensions\u002Fdata-connectors\u002Foperations","en\u002F6.reference\u002F9.extensions\u002F4.data-connectors\u002F2.operations",{"title":148,"path":418,"stem":419,"icon":420},"\u002Fen\u002Freference\u002Fextensions\u002Fdata-connectors\u002Ferrors","en\u002F6.reference\u002F9.extensions\u002F4.data-connectors\u002F3.errors","i-lucide-triangle-alert",{"title":422,"path":423,"stem":424,"icon":425},"Runtime Limits","\u002Fen\u002Freference\u002Fextensions\u002Fdata-connectors\u002Flimits","en\u002F6.reference\u002F9.extensions\u002F4.data-connectors\u002F4.limits","i-lucide-gauge",{"title":427,"path":428,"stem":429,"icon":430},"Limitations","\u002Fen\u002Freference\u002Fextensions\u002Fdata-connectors\u002Flimitations","en\u002F6.reference\u002F9.extensions\u002F4.data-connectors\u002F5.limitations","i-lucide-ban",{"title":432,"path":433,"stem":434,"icon":435},"Network Permissions","\u002Fen\u002Freference\u002Fextensions\u002Fdata-connectors\u002Fpermissions","en\u002F6.reference\u002F9.extensions\u002F4.data-connectors\u002F6.permissions","i-lucide-shield-check",{"title":437,"icon":121,"path":438,"stem":439,"children":440,"page":6},"Release Notes","\u002Fen\u002Frelease-notes","en\u002F7.release-notes",[441],{"title":442,"path":443,"stem":444,"icon":121},"Changelog","\u002Fen\u002Frelease-notes\u002Fchangelog","en\u002F7.release-notes\u002F1.changelog",{"id":446,"title":414,"body":447,"description":4480,"extension":4481,"links":4482,"meta":4483,"navigation":4484,"path":415,"seo":4485,"stem":416,"__hash__":4486},"docs_en\u002Fen\u002F6.reference\u002F9.extensions\u002F4.data-connectors\u002F2.operations.md",{"type":448,"value":449,"toc":4455},"minimark",[450,453,458,496,503,522,1105,1133,1276,1294,1312,1316,1319,1488,1502,1506,1700,1794,1798,1801,2086,2102,2106,2109,2255,2271,2285,2289,2305,2308,2312,2390,2394,2397,2509,2513,2519,2635,2642,2662,2683,2698,2702,2712,2786,2804,2809,2812,2829,2903,2906,2910,2925,3073,3154,3165,3276,3280,3289,3435,3460,3464,3475,3568,3571,3585,3588,3593,3606,3615,3691,3753,3759,3776,3780,3802,3817,3844,3853,3868,3879,3980,3998,4040,4043,4059,4068,4128,4133,4242,4327,4331,4345,4397,4406,4415,4419,4451],[451,452],"preview",{},[454,455,457],"h2",{"id":456},"declare-operations","Declare Operations",[459,460,461,462,467,468,472,473,477,478,482,483,486,487,491,492,495],"p",{},"Every ",[463,464,466],"a",{"href":465},"\u002Fconcepts\u002Fdata-model#collections","collection"," a data connector extension exposes declares ",[469,470,471],"code",{},"operations",": the members it serves and what each one accepts. A collection holds ",[474,475,476],"strong",{},"items",", and each item carries named values called ",[463,479,481],{"href":480},"\u002Fconcepts\u002Fdata-model#fields","fields",". A ",[474,484,485],{},"data source"," is the connector configured in a ",[463,488,490],{"href":489},"\u002Fconcepts\u002Forganization#glossary","workspace",", and the ",[474,493,494],{},"external data source"," is the system the connector reads and writes.",[459,497,498,499,502],{},"Engine derives what it offers callers from the declaration: the operations, the filter operators, the sort fields, and the fields callers can read and write. Engine rejects a caller request outside it before the request reaches your connector, except for the shapes listed below the example. An absent member or argument is not offered, and ",[469,500,501],{},"operations: {}"," offers nothing.",[459,504,505,506,509,510,513,514,517,518,521],{},"The ",[469,507,508],{},"artists"," collection of the full Art Institute connector, which ",[463,511,246],{"href":512},"\u002Fdeveloper\u002Fextensions\u002Fdata-connectors\u002Fdata-source-mapping"," walks through, serves a filterable, sortable, paged list with a total count, and single-item reads, with ",[469,515,516],{},"id"," as its single-field primary key. It declares its operations with the helpers from ",[469,519,520],{},"@monospace\u002Fextension-kit\u002Fdata-connector\u002Fexperimental",":",[523,524,530],"pre",{"className":525,"code":526,"filename":527,"language":528,"meta":529,"style":529},"language-ts shiki shiki-themes monospace-light monospace-light monospace-dark","import { defineCollection, defineRelation, defineSchema, field, fields, filter, index, paging, sort } from '@monospace\u002Fextension-kit\u002Fdata-connector\u002Fexperimental';\n\n\u002F\u002F The operators the Art Institute's search API answers exactly. The relation's key fields, `id` and\n\u002F\u002F `artistId`, declare `in` as well as `equals`, because Engine resolves relations by filtering with `in`.\nconst exact = filter.field('equals', 'in');\nconst comparable = filter.field('equals', 'in', 'lessThan', 'lessThanOrEquals', 'greaterThan', 'greaterThanOrEquals');\n\u002F** Engine executes only `equals` on booleans. *\u002F\nconst booleanExact = filter.field('equals');\nconst eitherDirection = sort.field('ascending', 'descending');\n\u002F\u002F …\n\nconst artistFilter = {\n    fields: { id: exact, birthDate: comparable },\n    logicalOperators: filter.logical('and', 'or'),\n};\n\nexport const artists = defineCollection({\n    name: 'artists',\n    fields: {\n        id: field.int32(),\n        title: field.string(),\n        birthDate: field.int32({ nullable: true }),\n        deathDate: field.int32({ nullable: true }),\n    },\n    indexes: { artists_pkey: index.primary(['id']) },\n    operations: {\n        readMany: {\n            filter: artistFilter,\n            sort: { id: eitherDirection, birthDate: eitherDirection },\n            limit: paging.limit(),\n            offset: paging.offset(),\n            output: fields.all(),\n            meta: { totalCount: true },\n        },\n        readOne: { filter: artistFilter, output: fields.all() },\n    },\n});\n","src\u002Fdata-connectors\u002Fartic\u002Fschema.ts","ts","",[469,531,532,602,609,616,622,657,703,709,731,760,766,771,784,802,828,834,839,859,871,877,893,908,929,947,953,975,981,987,998,1013,1028,1043,1058,1068,1074,1094,1099],{"__ignoreMap":529},[533,534,537,541,545,549,552,555,557,560,562,565,567,569,571,574,576,579,581,584,586,589,592,595,599],"span",{"class":535,"line":536},"line",1,[533,538,540],{"class":539},"sLVBU","import",[533,542,544],{"class":543},"sTMul"," { ",[533,546,548],{"class":547},"sNJ9c","defineCollection",[533,550,551],{"class":543},", ",[533,553,554],{"class":547},"defineRelation",[533,556,551],{"class":543},[533,558,559],{"class":547},"defineSchema",[533,561,551],{"class":543},[533,563,564],{"class":547},"field",[533,566,551],{"class":543},[533,568,481],{"class":547},[533,570,551],{"class":543},[533,572,573],{"class":547},"filter",[533,575,551],{"class":543},[533,577,578],{"class":547},"index",[533,580,551],{"class":543},[533,582,583],{"class":547},"paging",[533,585,551],{"class":543},[533,587,588],{"class":547},"sort",[533,590,591],{"class":543}," } ",[533,593,594],{"class":539},"from",[533,596,598],{"class":597},"suKVh"," '@monospace\u002Fextension-kit\u002Fdata-connector\u002Fexperimental'",[533,600,601],{"class":543},";\n",[533,603,605],{"class":535,"line":604},2,[533,606,608],{"emptyLinePlaceholder":607},true,"\n",[533,610,612],{"class":535,"line":611},3,[533,613,615],{"class":614},"seNfP","\u002F\u002F The operators the Art Institute's search API answers exactly. The relation's key fields, `id` and\n",[533,617,619],{"class":535,"line":618},4,[533,620,621],{"class":614},"\u002F\u002F `artistId`, declare `in` as well as `equals`, because Engine resolves relations by filtering with `in`.\n",[533,623,625,628,632,635,638,641,643,646,649,651,654],{"class":535,"line":624},5,[533,626,627],{"class":539},"const",[533,629,631],{"class":630},"ssBNi"," exact",[533,633,634],{"class":539}," =",[533,636,637],{"class":547}," filter",[533,639,640],{"class":543},".",[533,642,564],{"class":630},[533,644,645],{"class":543},"(",[533,647,648],{"class":597},"'equals'",[533,650,551],{"class":543},[533,652,653],{"class":597},"'in'",[533,655,656],{"class":543},");\n",[533,658,660,662,665,667,669,671,673,675,677,679,681,683,686,688,691,693,696,698,701],{"class":535,"line":659},6,[533,661,627],{"class":539},[533,663,664],{"class":630}," comparable",[533,666,634],{"class":539},[533,668,637],{"class":547},[533,670,640],{"class":543},[533,672,564],{"class":630},[533,674,645],{"class":543},[533,676,648],{"class":597},[533,678,551],{"class":543},[533,680,653],{"class":597},[533,682,551],{"class":543},[533,684,685],{"class":597},"'lessThan'",[533,687,551],{"class":543},[533,689,690],{"class":597},"'lessThanOrEquals'",[533,692,551],{"class":543},[533,694,695],{"class":597},"'greaterThan'",[533,697,551],{"class":543},[533,699,700],{"class":597},"'greaterThanOrEquals'",[533,702,656],{"class":543},[533,704,706],{"class":535,"line":705},7,[533,707,708],{"class":614},"\u002F** Engine executes only `equals` on booleans. *\u002F\n",[533,710,712,714,717,719,721,723,725,727,729],{"class":535,"line":711},8,[533,713,627],{"class":539},[533,715,716],{"class":630}," booleanExact",[533,718,634],{"class":539},[533,720,637],{"class":547},[533,722,640],{"class":543},[533,724,564],{"class":630},[533,726,645],{"class":543},[533,728,648],{"class":597},[533,730,656],{"class":543},[533,732,734,736,739,741,744,746,748,750,753,755,758],{"class":535,"line":733},9,[533,735,627],{"class":539},[533,737,738],{"class":630}," eitherDirection",[533,740,634],{"class":539},[533,742,743],{"class":547}," sort",[533,745,640],{"class":543},[533,747,564],{"class":630},[533,749,645],{"class":543},[533,751,752],{"class":597},"'ascending'",[533,754,551],{"class":543},[533,756,757],{"class":597},"'descending'",[533,759,656],{"class":543},[533,761,763],{"class":535,"line":762},10,[533,764,765],{"class":614},"\u002F\u002F …\n",[533,767,769],{"class":535,"line":768},11,[533,770,608],{"emptyLinePlaceholder":607},[533,772,774,776,779,781],{"class":535,"line":773},12,[533,775,627],{"class":539},[533,777,778],{"class":630}," artistFilter",[533,780,634],{"class":539},[533,782,783],{"class":543}," {\n",[533,785,787,790,793,796,799],{"class":535,"line":786},13,[533,788,789],{"class":543},"    fields: { id: ",[533,791,792],{"class":547},"exact",[533,794,795],{"class":543},", birthDate: ",[533,797,798],{"class":547},"comparable",[533,800,801],{"class":543}," },\n",[533,803,805,808,810,812,815,817,820,822,825],{"class":535,"line":804},14,[533,806,807],{"class":543},"    logicalOperators: ",[533,809,573],{"class":547},[533,811,640],{"class":543},[533,813,814],{"class":630},"logical",[533,816,645],{"class":543},[533,818,819],{"class":597},"'and'",[533,821,551],{"class":543},[533,823,824],{"class":597},"'or'",[533,826,827],{"class":543},"),\n",[533,829,831],{"class":535,"line":830},15,[533,832,833],{"class":543},"};\n",[533,835,837],{"class":535,"line":836},16,[533,838,608],{"emptyLinePlaceholder":607},[533,840,842,845,848,851,853,856],{"class":535,"line":841},17,[533,843,844],{"class":539},"export",[533,846,847],{"class":539}," const",[533,849,850],{"class":630}," artists",[533,852,634],{"class":539},[533,854,855],{"class":630}," defineCollection",[533,857,858],{"class":543},"({\n",[533,860,862,865,868],{"class":535,"line":861},18,[533,863,864],{"class":543},"    name: ",[533,866,867],{"class":597},"'artists'",[533,869,870],{"class":543},",\n",[533,872,874],{"class":535,"line":873},19,[533,875,876],{"class":543},"    fields: {\n",[533,878,880,883,885,887,890],{"class":535,"line":879},20,[533,881,882],{"class":543},"        id: ",[533,884,564],{"class":547},[533,886,640],{"class":543},[533,888,889],{"class":630},"int32",[533,891,892],{"class":543},"(),\n",[533,894,896,899,901,903,906],{"class":535,"line":895},21,[533,897,898],{"class":543},"        title: ",[533,900,564],{"class":547},[533,902,640],{"class":543},[533,904,905],{"class":630},"string",[533,907,892],{"class":543},[533,909,911,914,916,918,920,923,926],{"class":535,"line":910},22,[533,912,913],{"class":543},"        birthDate: ",[533,915,564],{"class":547},[533,917,640],{"class":543},[533,919,889],{"class":630},[533,921,922],{"class":543},"({ nullable: ",[533,924,925],{"class":630},"true",[533,927,928],{"class":543}," }),\n",[533,930,932,935,937,939,941,943,945],{"class":535,"line":931},23,[533,933,934],{"class":543},"        deathDate: ",[533,936,564],{"class":547},[533,938,640],{"class":543},[533,940,889],{"class":630},[533,942,922],{"class":543},[533,944,925],{"class":630},[533,946,928],{"class":543},[533,948,950],{"class":535,"line":949},24,[533,951,952],{"class":543},"    },\n",[533,954,956,959,961,963,966,969,972],{"class":535,"line":955},25,[533,957,958],{"class":543},"    indexes: { artists_pkey: ",[533,960,578],{"class":547},[533,962,640],{"class":543},[533,964,965],{"class":630},"primary",[533,967,968],{"class":543},"([",[533,970,971],{"class":597},"'id'",[533,973,974],{"class":543},"]) },\n",[533,976,978],{"class":535,"line":977},26,[533,979,980],{"class":543},"    operations: {\n",[533,982,984],{"class":535,"line":983},27,[533,985,986],{"class":543},"        readMany: {\n",[533,988,990,993,996],{"class":535,"line":989},28,[533,991,992],{"class":543},"            filter: ",[533,994,995],{"class":547},"artistFilter",[533,997,870],{"class":543},[533,999,1001,1004,1007,1009,1011],{"class":535,"line":1000},29,[533,1002,1003],{"class":543},"            sort: { id: ",[533,1005,1006],{"class":547},"eitherDirection",[533,1008,795],{"class":543},[533,1010,1006],{"class":547},[533,1012,801],{"class":543},[533,1014,1016,1019,1021,1023,1026],{"class":535,"line":1015},30,[533,1017,1018],{"class":543},"            limit: ",[533,1020,583],{"class":547},[533,1022,640],{"class":543},[533,1024,1025],{"class":630},"limit",[533,1027,892],{"class":543},[533,1029,1031,1034,1036,1038,1041],{"class":535,"line":1030},31,[533,1032,1033],{"class":543},"            offset: ",[533,1035,583],{"class":547},[533,1037,640],{"class":543},[533,1039,1040],{"class":630},"offset",[533,1042,892],{"class":543},[533,1044,1046,1049,1051,1053,1056],{"class":535,"line":1045},32,[533,1047,1048],{"class":543},"            output: ",[533,1050,481],{"class":547},[533,1052,640],{"class":543},[533,1054,1055],{"class":630},"all",[533,1057,892],{"class":543},[533,1059,1061,1064,1066],{"class":535,"line":1060},33,[533,1062,1063],{"class":543},"            meta: { totalCount: ",[533,1065,925],{"class":630},[533,1067,801],{"class":543},[533,1069,1071],{"class":535,"line":1070},34,[533,1072,1073],{"class":543},"        },\n",[533,1075,1077,1080,1082,1085,1087,1089,1091],{"class":535,"line":1076},35,[533,1078,1079],{"class":543},"        readOne: { filter: ",[533,1081,995],{"class":547},[533,1083,1084],{"class":543},", output: ",[533,1086,481],{"class":547},[533,1088,640],{"class":543},[533,1090,1055],{"class":630},[533,1092,1093],{"class":543},"() },\n",[533,1095,1097],{"class":535,"line":1096},36,[533,1098,952],{"class":543},[533,1100,1102],{"class":535,"line":1101},37,[533,1103,1104],{"class":543},"});\n",[459,1106,1107,551,1110,551,1113,551,1116,551,1119,1122,1123,1126,1127,1129,1130,1132],{},[469,1108,1109],{},"filter.field(...)",[469,1111,1112],{},"filter.logical(...)",[469,1114,1115],{},"sort.field(...)",[469,1117,1118],{},"paging.limit()",[469,1120,1121],{},"paging.offset()"," and ",[469,1124,1125],{},"fields.all()"," build the declaration's values. ",[469,1128,508],{}," declares no member that writes, so the kit marks it read-only. In the schema document the connector returns, ",[469,1131,995],{}," becomes maps from each operator to its options:",[523,1134,1139],{"className":1135,"code":1136,"filename":1137,"language":1138,"meta":529,"style":529},"language-json shiki shiki-themes monospace-light monospace-light monospace-dark","{\n  \"fields\": {\n    \"id\": { \"operators\": { \"equals\": {}, \"in\": {} } },\n    \"birthDate\": {\n      \"operators\": {\n        \"equals\": {},\n        \"in\": {},\n        \"lessThan\": {},\n        \"lessThanOrEquals\": {},\n        \"greaterThan\": {},\n        \"greaterThanOrEquals\": {}\n      }\n    }\n  },\n  \"logicalOperators\": { \"and\": {}, \"or\": {} }\n}\n","schema-document.json","json",[469,1140,1141,1146,1155,1180,1187,1194,1202,1209,1216,1223,1230,1238,1243,1248,1253,1271],{"__ignoreMap":529},[533,1142,1143],{"class":535,"line":536},[533,1144,1145],{"class":543},"{\n",[533,1147,1148,1152],{"class":535,"line":604},[533,1149,1151],{"class":1150},"snHjA","  \"fields\"",[533,1153,1154],{"class":543},": {\n",[533,1156,1157,1160,1163,1166,1168,1171,1174,1177],{"class":535,"line":611},[533,1158,1159],{"class":1150},"    \"id\"",[533,1161,1162],{"class":543},": { ",[533,1164,1165],{"class":1150},"\"operators\"",[533,1167,1162],{"class":543},[533,1169,1170],{"class":1150},"\"equals\"",[533,1172,1173],{"class":543},": {}, ",[533,1175,1176],{"class":1150},"\"in\"",[533,1178,1179],{"class":543},": {} } },\n",[533,1181,1182,1185],{"class":535,"line":618},[533,1183,1184],{"class":1150},"    \"birthDate\"",[533,1186,1154],{"class":543},[533,1188,1189,1192],{"class":535,"line":624},[533,1190,1191],{"class":1150},"      \"operators\"",[533,1193,1154],{"class":543},[533,1195,1196,1199],{"class":535,"line":659},[533,1197,1198],{"class":1150},"        \"equals\"",[533,1200,1201],{"class":543},": {},\n",[533,1203,1204,1207],{"class":535,"line":705},[533,1205,1206],{"class":1150},"        \"in\"",[533,1208,1201],{"class":543},[533,1210,1211,1214],{"class":535,"line":711},[533,1212,1213],{"class":1150},"        \"lessThan\"",[533,1215,1201],{"class":543},[533,1217,1218,1221],{"class":535,"line":733},[533,1219,1220],{"class":1150},"        \"lessThanOrEquals\"",[533,1222,1201],{"class":543},[533,1224,1225,1228],{"class":535,"line":762},[533,1226,1227],{"class":1150},"        \"greaterThan\"",[533,1229,1201],{"class":543},[533,1231,1232,1235],{"class":535,"line":768},[533,1233,1234],{"class":1150},"        \"greaterThanOrEquals\"",[533,1236,1237],{"class":543},": {}\n",[533,1239,1240],{"class":535,"line":773},[533,1241,1242],{"class":543},"      }\n",[533,1244,1245],{"class":535,"line":786},[533,1246,1247],{"class":543},"    }\n",[533,1249,1250],{"class":535,"line":804},[533,1251,1252],{"class":543},"  },\n",[533,1254,1255,1258,1260,1263,1265,1268],{"class":535,"line":830},[533,1256,1257],{"class":1150},"  \"logicalOperators\"",[533,1259,1162],{"class":543},[533,1261,1262],{"class":1150},"\"and\"",[533,1264,1173],{"class":543},[533,1266,1267],{"class":1150},"\"or\"",[533,1269,1270],{"class":543},": {} }\n",[533,1272,1273],{"class":535,"line":836},[533,1274,1275],{"class":543},"}\n",[459,1277,1278,1279,1282,1283,1286,1287,1291,1292,640],{},"No operator has options yet, so each value is ",[469,1280,1281],{},"{}",". See ",[463,1284,401],{"href":1285},"\u002Freference\u002Fextensions\u002Fextension-kit\u002Fexperimental"," for every helper, and ",[463,1288,1290],{"href":1289},"\u002Freference\u002Fextensions\u002Fdata-connectors\u002Fapi#example-schema-document","Example Schema Document"," for the whole document the Art Institute connector returns for ",[469,1293,508],{},[459,1295,1296,1297,1300,1301,1304,1305,1307,1308,640],{},"Engine checks a caller's request against the declaration, but not the filters it sends to your connector. Some requests reach your connector in a shape the declaration doesn't list. These include caller shorthands Engine expands: shorthand equality, ",[469,1298,1299],{},"_null",", and sorting without a direction on a field that declares ",[469,1302,1303],{},"ascending",". A default ",[469,1306,1025],{},", Engine's own calls for relations and read-backs, and permission rule conditions are others. See ",[463,1309,1311],{"href":1310},"\u002Freference\u002Fextensions\u002Fdata-connectors\u002Fapi#handle-requests-you-didnt-declare","Handle Requests You Didn't Declare",[454,1313,1315],{"id":1314},"choose-members","Choose Members",[459,1317,1318],{},"A collection declares any of seven members:",[1320,1321,1322,1341],"table",{},[1323,1324,1325],"thead",{},[1326,1327,1328,1332,1335,1338],"tr",{},[1329,1330,1331],"th",{},"Member",[1329,1333,1334],{},"What it does",[1329,1336,1337],{},"Keyed",[1329,1339,1340],{},"Arguments",[1342,1343,1344,1374,1393,1412,1432,1452,1470],"tbody",{},[1326,1345,1346,1352,1355,1358],{},[1347,1348,1349],"td",{},[469,1350,1351],{},"readMany",[1347,1353,1354],{},"Reads the items matching a filter",[1347,1356,1357],{},"No",[1347,1359,1360,551,1362,551,1364,551,1366,551,1368,551,1371],{},[469,1361,573],{},[469,1363,588],{},[469,1365,1025],{},[469,1367,1040],{},[469,1369,1370],{},"output",[469,1372,1373],{},"meta",[1326,1375,1376,1381,1384,1387],{},[1347,1377,1378],{},[469,1379,1380],{},"readOne",[1347,1382,1383],{},"Reads one item by its key",[1347,1385,1386],{},"Yes",[1347,1388,1389,551,1391],{},[469,1390,573],{},[469,1392,1370],{},[1326,1394,1395,1400,1403,1405],{},[1347,1396,1397],{},[469,1398,1399],{},"create",[1347,1401,1402],{},"Creates one or more items",[1347,1404,1357],{},[1347,1406,1407,551,1410],{},[469,1408,1409],{},"data",[469,1411,1370],{},[1326,1413,1414,1419,1422,1424],{},[1347,1415,1416],{},[469,1417,1418],{},"updateMany",[1347,1420,1421],{},"Updates every item matching a filter",[1347,1423,1357],{},[1347,1425,1426,551,1428,551,1430],{},[469,1427,573],{},[469,1429,1409],{},[469,1431,1370],{},[1326,1433,1434,1439,1442,1444],{},[1347,1435,1436],{},[469,1437,1438],{},"updateOne",[1347,1440,1441],{},"Updates one item by its key",[1347,1443,1386],{},[1347,1445,1446,551,1448,551,1450],{},[469,1447,573],{},[469,1449,1409],{},[469,1451,1370],{},[1326,1453,1454,1459,1462,1464],{},[1347,1455,1456],{},[469,1457,1458],{},"deleteMany",[1347,1460,1461],{},"Deletes every item matching a filter",[1347,1463,1357],{},[1347,1465,1466,551,1468],{},[469,1467,573],{},[469,1469,1370],{},[1326,1471,1472,1477,1480,1482],{},[1347,1473,1474],{},[469,1475,1476],{},"deleteOne",[1347,1478,1479],{},"Deletes one item by its key",[1347,1481,1386],{},[1347,1483,1484,551,1486],{},[469,1485,573],{},[469,1487,1370],{},[459,1489,1490,1491,1494,1495,1497,1498,640],{},"A keyed member receives a ",[469,1492,1493],{},"key"," for the collection's primary key on every call. Its ",[469,1496,573],{}," declares only the guard sent beside the key, never the key itself. See ",[463,1499,1501],{"href":1500},"#use-keys-and-the-stable-id","Use Keys and the Stable ID",[1503,1504,1340],"h3",{"id":1505},"arguments",[1320,1507,1508,1521],{},[1323,1509,1510],{},[1326,1511,1512,1515,1518],{},[1329,1513,1514],{},"Argument",[1329,1516,1517],{},"Type",[1329,1519,1520],{},"Meaning",[1342,1522,1523,1561,1585,1609,1626,1643,1664],{},[1326,1524,1525,1529,1534],{},[1347,1526,1527],{},[469,1528,573],{},[1347,1530,1531],{},[469,1532,1533],{},"{ fields, logicalOperators? }",[1347,1535,1536,1537,1539,1540,1543,1544,1547,1548,1550,1551,551,1554,1122,1557,1560],{},"The fields callers can filter on, the operators per field, and how conditions combine. ",[469,1538,481],{}," maps each field to ",[469,1541,1542],{},"filter.field(...operators)",", and ",[469,1545,1546],{},"logicalOperators"," is ",[469,1549,1112],{}," with any of ",[469,1552,1553],{},"and",[469,1555,1556],{},"or",[469,1558,1559],{},"not",". No field is required. A declared operator can appear any number of times anywhere in the filter",[1326,1562,1563,1567,1572],{},[1347,1564,1565],{},[469,1566,588],{},[1347,1568,1569],{},[469,1570,1571],{},"Record\u003Cfield, SortField>",[1347,1573,1574,1575,1578,1579,551,1581,1584],{},"The fields callers can sort by, and in which directions. Each value is ",[469,1576,1577],{},"sort.field(...directions)"," with ",[469,1580,1303],{},[469,1582,1583],{},"descending"," or both",[1326,1586,1587,1591,1598],{},[1347,1588,1589],{},[469,1590,1025],{},[1347,1592,1593,1595,1596],{},[469,1594,1281],{},", built with ",[469,1597,1118],{},[1347,1599,1600,1601,1603,1604,1606,1607],{},"Present means callers can set ",[469,1602,1025],{},". You can't declare a maximum. Without it, ",[469,1605,1351],{}," still receives Engine's default ",[469,1608,1025],{},[1326,1610,1611,1615,1621],{},[1347,1612,1613],{},[469,1614,1040],{},[1347,1616,1617,1595,1619],{},[469,1618,1281],{},[469,1620,1121],{},[1347,1622,1600,1623,1625],{},[469,1624,1040],{},". You can't declare a maximum",[1326,1627,1628,1632,1640],{},[1347,1629,1630],{},[469,1631,1370],{},[1347,1633,1634,1637,1638],{},[469,1635,1636],{},"field[]",", or ",[469,1639,1125],{},[1347,1641,1642],{},"The fields callers can read from this member's results",[1326,1644,1645,1649,1654],{},[1347,1646,1647],{},[469,1648,1373],{},[1347,1650,1651],{},[469,1652,1653],{},"{ totalCount?: boolean }",[1347,1655,1656,1659,1660],{},[469,1657,1658],{},"totalCount: true"," lets callers ask for the total count. Your connector then answers ",[463,1661,1663],{"href":1662},"\u002Freference\u002Fextensions\u002Fdata-connectors\u002Fapi#count-reads","count reads",[1326,1665,1666,1670,1676],{},[1347,1667,1668],{},[469,1669,1409],{},[1347,1671,1672,1637,1674],{},[469,1673,1636],{},[469,1675,1125],{},[1347,1677,1678,1679,1681,1682,1685,1686,1688,1689,1691,1692,1695,1696,1699],{},"The fields callers can set. With the helpers, a field is writable exactly when a ",[469,1680,1409],{}," list names it. Absent and ",[469,1683,1684],{},"[]"," mean the same. On ",[469,1687,1399],{},", a foreign-key field in ",[469,1690,1409],{}," is set by Engine from the caller's relation input (",[469,1693,1694],{},"_connect"," or ",[469,1697,1698],{},"_create","), not directly by the caller",[1701,1702,1703,1710,1742,1763,1771],"ul",{},[1704,1705,1706,1709],"li",{},[474,1707,1708],{},"Field lists are sets."," Don't repeat a name within one list.",[1704,1711,1712,1720,1721,551,1723,1726,1727,1729,1730,1122,1736,640],{},[474,1713,1714,1715,1122,1717,1719],{},"Build ",[469,1716,1370],{},[469,1718,1409],{}," with the helpers."," ",[469,1722,1125],{},[469,1724,1725],{},"fieldsOf(fields).pick(...)"," and inline lists let ",[469,1728,548],{}," check their names at compile time. See ",[463,1731,1733],{"href":1732},"\u002Freference\u002Fextensions\u002Fextension-kit\u002Fexperimental#fieldsall",[469,1734,1735],{},"fields.all",[463,1737,1739],{"href":1738},"\u002Freference\u002Fextensions\u002Fextension-kit\u002Fexperimental#fieldsof",[469,1740,1741],{},"fieldsOf",[1704,1743,1744,1751,1752,1754,1755,1757,1758,482,1760,1762],{},[474,1745,1746,1748,1749,640],{},[469,1747,1409],{}," on ",[469,1750,1399],{}," Without ",[469,1753,1409],{},", callers set none of this collection's fields: each item reaches your connector as ",[469,1756,1281],{},", and your connector fills every field itself. A nested create into a related collection can still be offered, because it follows that collection's own ",[469,1759,1399],{},[469,1761,1409],{}," field that isn't nullable and has no default is required in the caller's create input.",[1704,1764,1765,1770],{},[474,1766,1767,1769],{},[469,1768,1409],{}," on an update."," An update that can set no field and no nested relation write sets nothing, so Engine doesn't offer it.",[1704,1772,1773,1780,1781,1784,1785,1787,1788,1790,1791,1793],{},[474,1774,1775,1776,1779],{},"Narrow ",[469,1777,1778],{},"readMany.output"," for detail-only fields."," A field listed in ",[469,1782,1783],{},"readOne.output"," but not in ",[469,1786,1778],{}," is readable through ",[469,1789,1380],{}," only. Each write member returns only the fields its own ",[469,1792,1370],{}," lists.",[1503,1795,1797],{"id":1796},"map-caller-operators-to-the-wire","Map Caller Operators to the Wire",[459,1799,1800],{},"Engine derives the filter operators callers see from what you declare. This table shows what each caller operator requires and how it reaches your connector.",[1320,1802,1803,1818],{},[1323,1804,1805],{},[1326,1806,1807,1810,1815],{},[1329,1808,1809],{},"Caller operator",[1329,1811,1812,1813],{},"Requires in the member's ",[469,1814,573],{},[1329,1816,1817],{},"Arrives as",[1342,1819,1820,1836,1856,1889,1914,1936,1968,1994,2010,2029,2057],{},[1326,1821,1822,1827,1832],{},[1347,1823,1824],{},[469,1825,1826],{},"_eq",[1347,1828,1829],{},[469,1830,1831],{},"equals",[1347,1833,1834],{},[469,1835,1831],{},[1326,1837,1838,1843,1849],{},[1347,1839,1840],{},[469,1841,1842],{},"_neq",[1347,1844,1845,1543,1847],{},[469,1846,1831],{},[469,1848,1559],{},[1347,1850,1851,1853,1854],{},[469,1852,1559],{}," around ",[469,1855,1831],{},[1326,1857,1858,1872,1886],{},[1347,1859,1860,551,1863,551,1866,551,1869],{},[469,1861,1862],{},"_lt",[469,1864,1865],{},"_lte",[469,1867,1868],{},"_gt",[469,1870,1871],{},"_gte",[1347,1873,1874,551,1877,551,1880,551,1883],{},[469,1875,1876],{},"lessThan",[469,1878,1879],{},"lessThanOrEquals",[469,1881,1882],{},"greaterThan",[469,1884,1885],{},"greaterThanOrEquals",[1347,1887,1888],{},"The same operator",[1326,1890,1891,1896,1905],{},[1347,1892,1893],{},[469,1894,1895],{},"_between",[1347,1897,1898,551,1900,1543,1902,1904],{},[469,1899,1885],{},[469,1901,1879],{},[469,1903,1553],{},", on a number, decimal, date or time field",[1347,1906,1907,1909,1910,1122,1912],{},[469,1908,1553],{}," of ",[469,1911,1885],{},[469,1913,1879],{},[1326,1915,1916,1921,1929],{},[1347,1917,1918],{},[469,1919,1920],{},"_nbetween",[1347,1922,1923,1924,1926,1927],{},"As ",[469,1925,1895],{},", plus ",[469,1928,1559],{},[1347,1930,1931,1933,1934],{},[469,1932,1559],{}," around that ",[469,1935,1553],{},[1326,1937,1938,1952,1966],{},[1347,1939,1940,551,1943,551,1946,551,1949],{},[469,1941,1942],{},"_contains",[469,1944,1945],{},"_icontains",[469,1947,1948],{},"_starts_with",[469,1950,1951],{},"_ends_with",[1347,1953,1954,551,1957,551,1960,551,1963],{},[469,1955,1956],{},"contains",[469,1958,1959],{},"icontains",[469,1961,1962],{},"startsWith",[469,1964,1965],{},"endsWith",[1347,1967,1888],{},[1326,1969,1970,1984,1989],{},[1347,1971,1972,551,1975,551,1978,551,1981],{},[469,1973,1974],{},"_ncontains",[469,1976,1977],{},"_nicontains",[469,1979,1980],{},"_nstarts_with",[469,1982,1983],{},"_nends_with",[1347,1985,1986,1987],{},"The positive operator, and ",[469,1988,1559],{},[1347,1990,1991,1993],{},[469,1992,1559],{}," around the positive operator",[1326,1995,1996,2001,2006],{},[1347,1997,1998],{},[469,1999,2000],{},"_in",[1347,2002,2003],{},[469,2004,2005],{},"in",[1347,2007,2008],{},[469,2009,2005],{},[1326,2011,2012,2017,2023],{},[1347,2013,2014],{},[469,2015,2016],{},"_nin",[1347,2018,2019,1543,2021],{},[469,2020,2005],{},[469,2022,1559],{},[1347,2024,2025,1853,2027],{},[469,2026,1559],{},[469,2028,2005],{},[1326,2030,2031,2035,2042],{},[1347,2032,2033],{},[469,2034,1299],{},[1347,2036,2037,2039,2040],{},[469,2038,1831],{}," on a nullable field, and ",[469,2041,1559],{},[1347,2043,2044,1578,2046,2049,2050,2053,2054,2056],{},[469,2045,1831],{},[469,2047,2048],{},"null","; ",[469,2051,2052],{},"_null: false"," as ",[469,2055,1559],{}," around it",[1326,2058,2059,2070,2078],{},[1347,2060,2061,551,2064,551,2067],{},[469,2062,2063],{},"_and",[469,2065,2066],{},"_or",[469,2068,2069],{},"_not",[1347,2071,2072,551,2074,551,2076],{},[469,2073,1553],{},[469,2075,1556],{},[469,2077,1559],{},[1347,2079,2080,551,2082,551,2084],{},[469,2081,1553],{},[469,2083,1556],{},[469,2085,1559],{},[459,2087,2088,2089,2091,2092,2094,2095,2097,2098,2101],{},"Several conditions in one filter object combine with an implicit ",[469,2090,1553],{},". Without ",[469,2093,1553],{}," in ",[469,2096,1546],{},", a caller's filter object can hold only one condition. A filter object always holds at least one. See ",[463,2099,168],{"href":2100},"\u002Fdeveloper\u002Fapi\u002Ffiltering"," for the caller-side syntax.",[454,2103,2105],{"id":2104},"match-operators-to-field-types","Match Operators to Field Types",[459,2107,2108],{},"Engine accepts an operator on a field only if it can execute that operator on the field's type:",[1320,2110,2111,2121],{},[1323,2112,2113],{},[1326,2114,2115,2118],{},[1329,2116,2117],{},"Field type",[1329,2119,2120],{},"Allowed operators",[1342,2122,2123,2151,2213,2226,2245],{},[1326,2124,2125,2129],{},[1347,2126,2127],{},[469,2128,905],{},[1347,2130,2131,551,2133,551,2135,551,2137,551,2139,551,2141,551,2143,551,2145,551,2147,551,2149],{},[469,2132,1831],{},[469,2134,1956],{},[469,2136,1959],{},[469,2138,1962],{},[469,2140,1965],{},[469,2142,1876],{},[469,2144,1879],{},[469,2146,1882],{},[469,2148,1885],{},[469,2150,2005],{},[1326,2152,2153,2199],{},[1347,2154,2155,551,2158,551,2161,551,2163,551,2166,551,2169,551,2172,551,2175,551,2178,551,2181,551,2184,551,2187,551,2190,551,2193,551,2196],{},[469,2156,2157],{},"int8",[469,2159,2160],{},"int16",[469,2162,889],{},[469,2164,2165],{},"int64",[469,2167,2168],{},"uint8",[469,2170,2171],{},"uint16",[469,2173,2174],{},"uint32",[469,2176,2177],{},"uint64",[469,2179,2180],{},"float32",[469,2182,2183],{},"float64",[469,2185,2186],{},"decimal",[469,2188,2189],{},"date",[469,2191,2192],{},"time",[469,2194,2195],{},"dateTime",[469,2197,2198],{},"dateTimeWithTimezone",[1347,2200,2201,551,2203,551,2205,551,2207,551,2209,551,2211],{},[469,2202,1831],{},[469,2204,1876],{},[469,2206,1879],{},[469,2208,1882],{},[469,2210,1885],{},[469,2212,2005],{},[1326,2214,2215,2220],{},[1347,2216,2217],{},[469,2218,2219],{},"uuid",[1347,2221,2222,551,2224],{},[469,2223,1831],{},[469,2225,2005],{},[1326,2227,2228,2241],{},[1347,2229,2230,551,2233,551,2235,551,2238],{},[469,2231,2232],{},"boolean",[469,2234,1138],{},[469,2236,2237],{},"bytes",[469,2239,2240],{},"geometry",[1347,2242,2243],{},[469,2244,1831],{},[1326,2246,2247,2252],{},[1347,2248,2249],{},[469,2250,2251],{},"unsupported",[1347,2253,2254],{},"None. The field can't be filtered, read or written",[459,2256,2257,2258,551,2260,1122,2262,2264,2265,2267,2268,2270],{},"Every collection can declare ",[469,2259,1553],{},[469,2261,1556],{},[469,2263,1559],{},". Every field in the collection's ",[469,2266,481],{}," can be declared in ",[469,2269,588],{},", in either direction. Relation fields can't be sorted.",[459,2272,2273,2274,2277,2278,2280,2281,2284],{},"Declaring an operator the type doesn't allow rejects the data source. The error names the collection, the path and the operator, for example \"",[469,2275,2276],{},"readMany.filter.fields.status"," declares ",[469,2279,1882],{},", which this engine cannot execute on ",[469,2282,2283],{},"Boolean","\".",[454,2286,2288],{"id":2287},"follow-the-declaration-rules","Follow the Declaration Rules",[459,2290,2291,2292,2295,2296,1695,2298,2300,2301,2304],{},"Engine checks every declaration when a data source is created or reintrospected. A declaration that breaks one of the rules below rejects the whole request with a ",[469,2293,2294],{},"422"," whose message names the collection and what to declare. A schema document Engine can't read at all, such as one that repeats a field name in ",[469,2297,1370],{},[469,2299,1409],{},", fails before these checks, with a ",[469,2302,2303],{},"500",". ",[459,2306,2307],{},"If a newer Engine refuses a declaration it stored earlier, the collection loads with no operations and Engine logs an error. It stays that way until you reintrospect the data source.",[1503,2309,2311],{"id":2310},"shape-rules","Shape Rules",[1701,2313,2314,2322,2337,2360,2369],{},[1704,2315,2316,2321],{},[474,2317,2318,2319,640],{},"Every collection declares ",[469,2320,471],{}," A collection without it is refused.",[1704,2323,2324,2327,2328,551,2330,551,2332,1695,2334,2336],{},[474,2325,2326],{},"Members name only the collection's own fields."," A ",[469,2329,573],{},[469,2331,588],{},[469,2333,1409],{},[469,2335,1370],{}," that names an unknown field is refused.",[1704,2338,2339,1720,2342,2345,2346,551,2349,2345,2351,1122,2354,2356,2357,2359],{},[474,2340,2341],{},"Lists aren't empty.",[469,2343,2344],{},"filter.fields",", each ",[469,2347,2348],{},"operators",[469,2350,588],{},[469,2352,2353],{},"directions",[469,2355,1370],{}," must list at least one entry. ",[469,2358,1409],{}," is the exception.",[1704,2361,2362,2365,2366,640],{},[474,2363,2364],{},"Operators fit the field type."," See ",[463,2367,2105],{"href":2368},"#match-operators-to-field-types",[1704,2370,2371,2376,2377,2379,2380,2382,2383,2386,2387,2389],{},[474,2372,2373,2375],{},[469,2374,1409],{}," lists writable fields."," A read-only field or an ",[469,2378,2251],{}," field can't be in ",[469,2381,1409],{},". The helpers derive each field's ",[469,2384,2385],{},"isReadonly"," from the ",[469,2388,1409],{}," lists, so they never conflict.",[1503,2391,2393],{"id":2392},"member-rules","Member Rules",[459,2395,2396],{},"Some members can't be declared on some collections:",[1320,2398,2399,2411],{},[1323,2400,2401],{},[1326,2402,2403,2405,2408],{},[1329,2404,1331],{},[1329,2406,2407],{},"Refused when the collection",[1329,2409,2410],{},"Message ends with",[1342,2412,2413,2425,2437,2449,2464,2476,2495],{},[1326,2414,2415,2419,2422],{},[1347,2416,2417],{},[469,2418,1380],{},[1347,2420,2421],{},"has no single-field primary index of a supported type",[1347,2423,2424],{},"\"has no single-field primary index of a supported type\"",[1326,2426,2427,2431,2434],{},[1347,2428,2429],{},[469,2430,1399],{},[1347,2432,2433],{},"is read-only",[1347,2435,2436],{},"\"is read-only\"",[1326,2438,2439,2443,2446],{},[1347,2440,2441],{},[469,2442,1399],{},[1347,2444,2445],{},"has a read-only, non-nullable field without a default",[1347,2447,2448],{},"\"has a required read-only field\"",[1326,2450,2451,2455,2461],{},[1347,2452,2453],{},[469,2454,1399],{},[1347,2456,2457,2458],{},"has no stable ID, and the connector doesn't declare ",[469,2459,2460],{},"insertReturning",[1347,2462,2463],{},"\"has neither a stable id nor `InsertReturning`\"",[1326,2465,2466,2472,2474],{},[1347,2467,2468,551,2470],{},[469,2469,1418],{},[469,2471,1458],{},[1347,2473,2433],{},[1347,2475,2436],{},[1326,2477,2478,2484,2492],{},[1347,2479,2480,551,2482],{},[469,2481,1418],{},[469,2483,1458],{},[1347,2485,2457,2486,1695,2489],{},[469,2487,2488],{},"updateReturning",[469,2490,2491],{},"deleteReturning",[1347,2493,2494],{},"\"has neither a stable id nor `UpdateReturning`\", or \"…nor `DeleteReturning`\"",[1326,2496,2497,2503,2506],{},[1347,2498,2499,551,2501],{},[469,2500,1438],{},[469,2502,1476],{},[1347,2504,2505],{},"is read-only, or has no single-field primary index of a supported type",[1347,2507,2508],{},"\"is read-only\", or \"has no single-field primary index of a supported type\"",[1503,2510,2512],{"id":2511},"rules-for-engines-own-calls","Rules for Engine's Own Calls",[459,2514,2515,2516,2518],{},"Engine re-reads and reads back items through ",[469,2517,1351],{},", addressing them by the collection's stable ID. The declaration must carry those calls:",[1701,2520,2521,2544,2565,2585],{},[1704,2522,2523,2529,2530,1909,2532,551,2534,551,2536,1122,2538,2540,2541,2543],{},[474,2524,2525,2526,640],{},"Write filters stay within ",[469,2527,2528],{},"readMany.filter"," The ",[469,2531,573],{},[469,2533,1418],{},[469,2535,1438],{},[469,2537,1458],{},[469,2539,1476],{}," can only use operators and logical operators that ",[469,2542,2528],{}," declares for the same fields.",[1704,2545,2546,1720,2552,1122,2554,2556,2557,2559,2560,2562,2563,640],{},[474,2547,2548,2549,2551],{},"Keyed writes need ",[469,2550,1831],{}," on the stable ID.",[469,2553,1438],{},[469,2555,1476],{}," require ",[469,2558,1831],{}," on every stable-ID field, and ",[469,2561,1553],{},", in ",[469,2564,2528],{},[1704,2566,2567,1720,2570,551,2572,1122,2574,2576,2577,2579,2580,2582,2583,640],{},[474,2568,2569],{},"Outputs carry the stable ID.",[469,2571,1351],{},[469,2573,1418],{},[469,2575,1438],{}," must list every stable-ID field in ",[469,2578,1370],{},". So must ",[469,2581,1399],{}," when the connector doesn't declare ",[469,2584,2460],{},[1704,2586,2587,2590,2591,2593,2594,2596,2597,2599,2600,2602,2603,2605,2606,2608,2609,2094,2611,2091,2613,551,2615,2617,2618,1122,2620,2622,2623,2625,2626,1122,2628,2304,2630,2632,2633,1793],{},[474,2588,2589],{},"Written items need a read-back path."," Engine reads the items of a write by stable ID through ",[469,2592,1351],{},": after a ",[469,2595,1399],{}," without ",[469,2598,2460],{},", before a delete without ",[469,2601,2491],{},", and for every update. With ",[469,2604,2488],{},", Engine can fold an update's read into the update call, but the declaration must carry the read either way. A collection with a stable ID that serves such a write needs ",[469,2607,2005],{}," on its stable-ID field and ",[469,2610,1553],{},[469,2612,2528],{},[469,2614,2005],{},[469,2616,1831],{}," on the field with ",[469,2619,1553],{},[469,2621,1556],{}," also works. A stable ID of several fields needs ",[469,2624,1831],{}," on each, with ",[469,2627,1553],{},[469,2629,1556],{},[469,2631,1778],{}," must list the stable ID and every field the write's ",[469,2634,1370],{},[459,2636,2637,2638,640],{},"A connector that doesn't declare every query capability adds more rules. See ",[463,2639,2641],{"href":2640},"#declare-query-capabilities","Declare Query Capabilities",[459,2643,2644,2645,551,2647,551,2649,1695,2651,2653,2654,2656,2657,2659,2660,640],{},"Some keys can't carry the read-back filter: a single ",[469,2646,2232],{},[469,2648,2237],{},[469,2650,1138],{},[469,2652,2240],{}," field, which has no ",[469,2655,2005],{},", or any key containing an ",[469,2658,2251],{}," field. Such a stable ID or relation key is exempt from the filter requirements of the read-back and relation rules only. Engine sends its read-backs and relation reads over it anyway, with an operator the declaration doesn't list. Serve them: see ",[463,2661,1311],{"href":1310},[459,2663,2664,2665,2667,2668,551,2670,1122,2672,2576,2674,2676,2677,2679,2680,2682],{},"A relation key's ",[469,2666,2251],{}," fields are also exempt from its output requirement. A stable ID's aren't: ",[469,2669,1351],{},[469,2671,1418],{},[469,2673,1438],{},[469,2675,1370],{},", and no ",[469,2678,1370],{}," can list an ",[469,2681,2251],{}," field, so a collection whose stable ID contains one can't declare those members.",[459,2684,2685,2686,1122,2688,2690,2691,2693,2694,2094,2696,640],{},"The keyed-write rule also still applies: ",[469,2687,1438],{},[469,2689,1476],{}," need ",[469,2692,1831],{}," on it and ",[469,2695,1553],{},[469,2697,2528],{},[1503,2699,2701],{"id":2700},"permission-rules","Permission Rules",[459,2703,2704,2705,2707,2708,2711],{},"Saving a policy, on create and on update, checks each rule's condition against the members that rule governs. A member that declares no ",[469,2706,573],{}," can't carry one: saving the rule fails with \"declares no ",[469,2709,2710],{},"\u003Cmember>.filter",", so it cannot be the subject of a permission rule\".",[1320,2713,2714,2727],{},[1323,2715,2716],{},[1326,2717,2718,2721],{},[1329,2719,2720],{},"Rule",[1329,2722,2723,2724,2726],{},"Its condition must fit the ",[469,2725,573],{}," of",[1342,2728,2729,2740,2755,2766,2777],{},[1326,2730,2731,2734],{},[1347,2732,2733],{},"Item filter for read",[1347,2735,2736,1122,2738],{},[469,2737,1351],{},[469,2739,1380],{},[1326,2741,2742,2745],{},[1347,2743,2744],{},"Field filter for read, on any field",[1347,2746,2747,551,2749,551,2751,1122,2753],{},[469,2748,1351],{},[469,2750,1380],{},[469,2752,1438],{},[469,2754,1476],{},[1326,2756,2757,2760],{},[1347,2758,2759],{},"Item filter for update",[1347,2761,2762,1122,2764],{},[469,2763,1418],{},[469,2765,1438],{},[1326,2767,2768,2771],{},[1347,2769,2770],{},"Item filter for delete",[1347,2772,2773,1122,2775],{},[469,2774,1458],{},[469,2776,1476],{},[1326,2778,2779,2782],{},[1347,2780,2781],{},"Item filter for create, field filter for create or update, validation rule",[1347,2783,2784],{},[469,2785,1351],{},[459,2787,2788,2789,2791,2792,2795,2796,2799,2800,2803],{},"A member the collection doesn't declare adds no constraint. A condition that names a field or operator one of these members doesn't offer fails with ",[469,2790,2294],{}," \"Invalid rule filter\", and nothing is saved. The error's message names the member's filter input, such as ",[469,2793,2794],{},"…UpdateOneFilterInput",". Its code is ",[469,2797,2798],{},"4003"," for an unknown field and ",[469,2801,2802],{},"4012"," for an unknown operator.",[459,2805,2806,2807,640],{},"A saved condition joins the filter of the calls it applies to. Engine checks it against the members above when the policy is saved, not when it sends a call. A field read rule's condition also joins the filter of a bulk update or delete that filters by the guarded field, and reaches your connector even when that call's member doesn't declare the condition's fields or operators. Declare them there too, or refuse the call: see ",[463,2808,1311],{"href":1310},[454,2810,2641],{"id":2811},"declare-query-capabilities",[459,2813,2814,2815,2094,2819,2094,2822,2825,2826,521],{},"A data connector entry declares its ",[463,2816,2818],{"href":2817},"\u002Freference\u002Fextensions\u002Fmanifest#capabilities","query capabilities",[469,2820,2821],{},"engine.capabilities.query",[469,2823,2824],{},"extension.config.json",". Each one promises that a kind of write answers with the items it wrote, carrying every field in the request's ",[469,2827,2828],{},"select",[1320,2830,2831,2844],{},[1323,2832,2833],{},[1326,2834,2835,2838,2841],{},[1329,2836,2837],{},"Capability",[1329,2839,2840],{},"Promise",[1329,2842,2843],{},"Without it, Engine",[1342,2845,2846,2865,2884],{},[1326,2847,2848,2852,2857],{},[1347,2849,2850],{},[469,2851,2460],{},[1347,2853,2854,2856],{},[469,2855,1399],{}," answers the created items",[1347,2858,2859,2860,2862,2863],{},"Asks ",[469,2861,1399],{}," for the stable ID only, then reads the created items back through ",[469,2864,1351],{},[1326,2866,2867,2871,2878],{},[1347,2868,2869],{},[469,2870,2488],{},[1347,2872,2873,1122,2875,2877],{},[469,2874,1418],{},[469,2876,1438],{}," answer the updated items",[1347,2879,2880,2881,2883],{},"Reads the stable IDs of the matching items, updates them through ",[469,2882,1418],{}," by stable ID, then reads them back twice",[1326,2885,2886,2890,2897],{},[1347,2887,2888],{},[469,2889,2491],{},[1347,2891,2892,1122,2894,2896],{},[469,2893,1458],{},[469,2895,1476],{}," answer the deleted items",[1347,2898,2899,2900,2902],{},"Reads the stable IDs of the matching items, then reads the items by stable ID, then deletes them through ",[469,2901,1458],{}," by stable ID",[459,2904,2905],{},"The capabilities apply to every collection of every data source that uses the entry. Absent, the entry declares none. A read-only connector declares none: Engine plans reads the same way with or without them.",[1503,2907,2909],{"id":2908},"what-engine-sends","What Engine Sends",[459,2911,2912,2913,2915,2916,2918,2919,2922,2923,521],{},"Engine sends one ",[469,2914,1399],{}," per item, with one object in ",[469,2917,1409],{},". The other writes are planned as follows, for a collection ",[469,2920,2921],{},"notes"," with the stable ID ",[469,2924,516],{},[1320,2926,2927,2940],{},[1323,2928,2929],{},[1326,2930,2931,2934,2937],{},[1329,2932,2933],{},"Caller request",[1329,2935,2936],{},"With the capability",[1329,2938,2939],{},"Without it",[1342,2941,2942,2969,3001,3025,3052],{},[1326,2943,2944,2947,2955],{},[1347,2945,2946],{},"Create items",[1347,2948,2949,2951,2952,2954],{},[469,2950,1399],{}," with the caller's ",[469,2953,2828],{},". Engine uses the answer as is",[1347,2956,2957,1578,2959,2961,2962,2965,2966,2968],{},[469,2958,1399],{},[469,2960,2828],{}," set to the stable-ID fields. Its answer must carry ",[469,2963,2964],{},"records"," with the stable ID of each created item. Then one ",[469,2967,1351],{}," by those stable IDs with the caller's selection",[1326,2970,2971,2974,2984],{},[1347,2972,2973],{},"Update one item by key",[1347,2975,2976,2978,2979,2981,2982],{},[469,2977,1438],{}," with the ",[469,2980,1493],{},", the guard, and the caller's ",[469,2983,2828],{},[1347,2985,2986,2988,2989,2991,2992,1578,2994,2997,2998,3000],{},[469,2987,1351],{}," for the stable ID, filtered by ",[469,2990,1831],{}," on the key and the guard. Then ",[469,2993,1418],{},[469,2995,2996],{},"select: []",", filtered by the stable IDs it found. Then ",[469,2999,1351],{}," by stable ID for the stable IDs, and another for the caller's selection",[1326,3002,3003,3006,3013],{},[1347,3004,3005],{},"Update items by filter",[1347,3007,3008,3010,3011],{},[469,3009,1418],{}," with the caller's filter and ",[469,3012,2828],{},[1347,3014,3015,3017,3018,1578,3020,3022,3023,3000],{},[469,3016,1351],{}," for the stable IDs, filtered by the caller's filter. Then ",[469,3019,1418],{},[469,3021,2996],{},", filtered by those stable IDs. Then ",[469,3024,1351],{},[1326,3026,3027,3030,3038],{},[1347,3028,3029],{},"Delete one item by key",[1347,3031,3032,2978,3034,2981,3036],{},[469,3033,1476],{},[469,3035,1493],{},[469,3037,2828],{},[1347,3039,3040,2988,3042,2991,3044,3046,3047,1578,3049,3051],{},[469,3041,1351],{},[469,3043,1831],{},[469,3045,1351],{}," by stable ID for the caller's selection. Then ",[469,3048,1458],{},[469,3050,2996],{},", filtered by the stable IDs",[1326,3053,3054,3057,3063],{},[1347,3055,3056],{},"Delete items by filter",[1347,3058,3059,3010,3061],{},[469,3060,1458],{},[469,3062,2828],{},[1347,3064,3065,3017,3067,3046,3069,1578,3071,3051],{},[469,3066,1351],{},[469,3068,1351],{},[469,3070,1458],{},[469,3072,2996],{},[1701,3074,3075,3099,3111,3138,3148],{},[1704,3076,3077,3083,3084,3086,3087,3089,3090,3092,3093,3095,3096,3098],{},[474,3078,3079,3080,3082],{},"A filter by stable ID uses the shape the called member's ",[469,3081,573],{}," declares."," That's ",[469,3085,2005],{}," on a single stable-ID field. Without ",[469,3088,2005],{},", and for a stable ID of several fields, it's ",[469,3091,1831],{}," on each field joined by ",[469,3094,1553],{}," for each item, and ",[469,3097,1556],{}," across the items.",[1704,3100,3101,3104,3105,3107,3108,3110],{},[474,3102,3103],{},"Other calls come on top, in both columns."," An update field rule adds a ",[469,3106,1351],{}," before the write, and relation fields in the caller's ",[469,3109,481],{}," add reads of the related collection.",[1704,3112,3113,3125,3126,1695,3128,3130,3131,3133,3134,3137],{},[474,3114,3115,3116,1695,3118,551,3120,1122,3122,3124],{},"Without ",[469,3117,2488],{},[469,3119,2491],{},[469,3121,1438],{},[469,3123,1476],{}," never reach your connector."," Engine sends ",[469,3127,1418],{},[469,3129,1458],{}," instead. When the first ",[469,3132,1351],{}," finds no item for the key, Engine answers the caller ",[469,3135,3136],{},"404"," without sending a write.",[1704,3139,3140,3145,3146,640],{},[474,3141,3142,3143,640],{},"Engine takes nothing from an answer to ",[469,3144,2996],{}," Answer it with the items you wrote, or with no ",[469,3147,2964],{},[1704,3149,3150,3153],{},[474,3151,3152],{},"The extra calls aren't atomic."," Another writer can change an item between them, and an external data source that is only eventually consistent can answer the read-back with stale data. Declare a capability whenever your connector can keep its promise.",[459,3155,3115,3156,3158,3159,3162,3163,521],{},[469,3157,2488],{},", a caller's update of the item ",[469,3160,3161],{},"n1"," reaches your connector as this ",[469,3164,1418],{},[523,3166,3169],{"className":1135,"code":3167,"filename":3168,"language":1138,"meta":529,"style":529},"{\n  \"query\": {\n    \"op\": \"updateMany\",\n    \"collection\": \"notes\",\n    \"select\": [],\n    \"filter\": { \"in\": { \"field\": \"id\" }, \"values\": [\"n1\"] },\n    \"data\": { \"title\": \"Renamed\" }\n  }\n}\n","request.json",[469,3170,3171,3175,3182,3195,3207,3215,3249,3267,3272],{"__ignoreMap":529},[533,3172,3173],{"class":535,"line":536},[533,3174,1145],{"class":543},[533,3176,3177,3180],{"class":535,"line":604},[533,3178,3179],{"class":1150},"  \"query\"",[533,3181,1154],{"class":543},[533,3183,3184,3187,3190,3193],{"class":535,"line":611},[533,3185,3186],{"class":1150},"    \"op\"",[533,3188,3189],{"class":543},": ",[533,3191,3192],{"class":597},"\"updateMany\"",[533,3194,870],{"class":543},[533,3196,3197,3200,3202,3205],{"class":535,"line":618},[533,3198,3199],{"class":1150},"    \"collection\"",[533,3201,3189],{"class":543},[533,3203,3204],{"class":597},"\"notes\"",[533,3206,870],{"class":543},[533,3208,3209,3212],{"class":535,"line":624},[533,3210,3211],{"class":1150},"    \"select\"",[533,3213,3214],{"class":543},": [],\n",[533,3216,3217,3220,3222,3224,3226,3229,3231,3234,3237,3240,3243,3246],{"class":535,"line":659},[533,3218,3219],{"class":1150},"    \"filter\"",[533,3221,1162],{"class":543},[533,3223,1176],{"class":1150},[533,3225,1162],{"class":543},[533,3227,3228],{"class":1150},"\"field\"",[533,3230,3189],{"class":543},[533,3232,3233],{"class":597},"\"id\"",[533,3235,3236],{"class":543}," }, ",[533,3238,3239],{"class":1150},"\"values\"",[533,3241,3242],{"class":543},": [",[533,3244,3245],{"class":597},"\"n1\"",[533,3247,3248],{"class":543},"] },\n",[533,3250,3251,3254,3256,3259,3261,3264],{"class":535,"line":705},[533,3252,3253],{"class":1150},"    \"data\"",[533,3255,1162],{"class":543},[533,3257,3258],{"class":1150},"\"title\"",[533,3260,3189],{"class":543},[533,3262,3263],{"class":597},"\"Renamed\"",[533,3265,3266],{"class":543}," }\n",[533,3268,3269],{"class":535,"line":711},[533,3270,3271],{"class":543},"  }\n",[533,3273,3274],{"class":535,"line":733},[533,3275,1275],{"class":543},[1503,3277,3279],{"id":3278},"rules-without-a-capability","Rules Without a Capability",[459,3281,3282,3283,3285,3286,3288],{},"Each missing capability adds rules to the declaration. Engine checks them with the others when a data source is created or reintrospected, and refuses a declaration that breaks one with ",[469,3284,2294],{},". These messages come from a collection ",[469,3287,2921],{}," whose connector declares no capability:",[1320,3290,3291,3303],{},[1323,3292,3293],{},[1326,3294,3295,3298,3300],{},[1329,3296,3297],{},"Missing",[1329,3299,2720],{},[1329,3301,3302],{},"Message when broken",[1342,3304,3305,3331,3346,3365,3385,3415],{},[1326,3306,3307,3315,3328],{},[1347,3308,3309,551,3311,1695,3313],{},[469,3310,2460],{},[469,3312,2488],{},[469,3314,2491],{},[1347,3316,3317,3318,3321,3322,551,3324,1695,3326],{},"The collection needs a ",[463,3319,3320],{"href":1500},"stable ID"," to declare ",[469,3323,1399],{},[469,3325,1418],{},[469,3327,1458],{},[1347,3329,3330],{},"\"collection `notes` cannot declare `create`: it has neither a stable id nor `InsertReturning`\"",[1326,3332,3333,3337,3343],{},[1347,3334,3335],{},[469,3336,2460],{},[1347,3338,3339,3342],{},[469,3340,3341],{},"create.output"," lists every stable-ID field",[1347,3344,3345],{},"\"collection `notes` declares `create`, from whose output the engine reads the stable id. Declare `id` in `create.output`\"",[1326,3347,3348,3354,3362],{},[1347,3349,3350,1695,3352],{},[469,3351,2460],{},[469,3353,2491],{},[1347,3355,3356,3358,3359],{},[469,3357,1351],{}," can read the created or deleted items by stable ID, as in ",[463,3360,2512],{"href":3361},"#rules-for-engines-own-calls",[1347,3363,3364],{},"\"collection `notes` declares `create`, whose written rows the engine reads back by stable id through `readMany`. Declare `owner` in `readMany.output`\"",[1326,3366,3367,3371,3382],{},[1347,3368,3369],{},[469,3370,2488],{},[1347,3372,3373,3374,3377,3378,3381],{},"Neither ",[469,3375,3376],{},"updateMany.data"," nor ",[469,3379,3380],{},"updateOne.data"," names a stable-ID field",[1347,3383,3384],{},"\"collection `notes` declares `id` in `updateMany.data`, which is outside its ceiling\"",[1326,3386,3387,3391,3412],{},[1347,3388,3389],{},[469,3390,2488],{},[1347,3392,3393,3394,1695,3396,3398,3399,3401,3402,3405,3406,3408,3409,3411],{},"A collection that declares ",[469,3395,1418],{},[469,3397,1438],{}," also declares ",[469,3400,1418],{},", with the read-back filter shape on the stable ID in ",[469,3403,3404],{},"updateMany.filter",", and a ",[469,3407,3376],{}," that lists every field any update member's ",[469,3410,1409],{}," lists",[1347,3413,3414],{},"\"collection `notes` declares `updateOne`, whose rows the engine writes through `updateMany` by stable id because the connector does not declare `updateReturning`. Declare `updateReturning` in the connector's `capabilities.query`, or `updateMany` with `in` on `id` and `and` in `updateMany.filter`, and `title`, `status` in `updateMany.data`\"",[1326,3416,3417,3421,3432],{},[1347,3418,3419],{},[469,3420,2491],{},[1347,3422,3393,3423,1695,3425,3398,3427,3401,3429],{},[469,3424,1458],{},[469,3426,1476],{},[469,3428,1458],{},[469,3430,3431],{},"deleteMany.filter",[1347,3433,3434],{},"\"collection `notes` declares `deleteOne`, whose rows the engine writes through `deleteMany` by stable id because the connector does not declare `deleteReturning`. Declare `deleteReturning` in the connector's `capabilities.query`, or `deleteMany` with `in` on `id` and `and` in `deleteMany.filter`\"",[459,3436,3437,3438,3440,3441,1637,3443,3445,3446,1122,3448,3450,3451,3453,3454,3456,3457,640],{},"The read-back filter shape is ",[469,3439,2005],{}," on a single stable-ID field with ",[469,3442,1553],{},[469,3444,1831],{}," on each stable-ID field with ",[469,3447,1553],{},[469,3449,1556],{},". The last two messages name only what's missing. When ",[469,3452,1418],{}," is declared but its ",[469,3455,1409],{}," misses a field, the message ends with \"or `status` in `updateMany.data`\". The first message names the capability in PascalCase; the others use the spelling of ",[469,3458,3459],{},"capabilities.query",[1503,3461,3463],{"id":3462},"when-the-capabilities-change","When the Capabilities Change",[459,3465,3466,3467,3471,3472,521],{},"Engine reads an entry's capabilities when it builds a workspace, and keeps them until it rebuilds that workspace. A restart loads a new build with its new capabilities directly. With ",[463,3468,3470],{"href":3469},"\u002Fdeveloper\u002Fextensions\u002Finstall#reload-extensions-automatically","automatic reloading"," on, Engine loads a new build as soon as you install it. When that build's capabilities differ, every existing data source of the entry refuses requests that reach its connector with ",[469,3473,3474],{},"503",[523,3476,3479],{"className":1135,"code":3477,"filename":3478,"language":1138,"meta":529,"style":529},"{\n  \"message\": \"Query failed\",\n  \"source\": {\n    \"message\": \"Data source is deactivated\",\n    \"source\": {\n      \"message\": \"the extension is deactivated\",\n      \"source\": {\n        \"message\": \"the connector now declares the query capabilities [insertReturning], but this data source was loaded with []. A restart applies the change.\"\n      }\n    }\n  }\n}\n","response.json",[469,3480,3481,3485,3497,3504,3516,3523,3535,3542,3552,3556,3560,3564],{"__ignoreMap":529},[533,3482,3483],{"class":535,"line":536},[533,3484,1145],{"class":543},[533,3486,3487,3490,3492,3495],{"class":535,"line":604},[533,3488,3489],{"class":1150},"  \"message\"",[533,3491,3189],{"class":543},[533,3493,3494],{"class":597},"\"Query failed\"",[533,3496,870],{"class":543},[533,3498,3499,3502],{"class":535,"line":611},[533,3500,3501],{"class":1150},"  \"source\"",[533,3503,1154],{"class":543},[533,3505,3506,3509,3511,3514],{"class":535,"line":618},[533,3507,3508],{"class":1150},"    \"message\"",[533,3510,3189],{"class":543},[533,3512,3513],{"class":597},"\"Data source is deactivated\"",[533,3515,870],{"class":543},[533,3517,3518,3521],{"class":535,"line":624},[533,3519,3520],{"class":1150},"    \"source\"",[533,3522,1154],{"class":543},[533,3524,3525,3528,3530,3533],{"class":535,"line":659},[533,3526,3527],{"class":1150},"      \"message\"",[533,3529,3189],{"class":543},[533,3531,3532],{"class":597},"\"the extension is deactivated\"",[533,3534,870],{"class":543},[533,3536,3537,3540],{"class":535,"line":705},[533,3538,3539],{"class":1150},"      \"source\"",[533,3541,1154],{"class":543},[533,3543,3544,3547,3549],{"class":535,"line":711},[533,3545,3546],{"class":1150},"        \"message\"",[533,3548,3189],{"class":543},[533,3550,3551],{"class":597},"\"the connector now declares the query capabilities [insertReturning], but this data source was loaded with []. A restart applies the change.\"\n",[533,3553,3554],{"class":535,"line":733},[533,3555,1242],{"class":543},[533,3557,3558],{"class":535,"line":762},[533,3559,1247],{"class":543},[533,3561,3562],{"class":535,"line":768},[533,3563,3271],{"class":543},[533,3565,3566],{"class":535,"line":773},[533,3567,1275],{"class":543},[459,3569,3570],{},"A restart of the instance applies the new capabilities, and so does anything else that rebuilds the workspace, such as creating another data source in it. Installing a build with the previous capabilities also restores the data source.",[459,3572,3573,3574,3576,3577,3580,3581,640],{},"A stored declaration that relies on a capability the connector no longer declares breaks a rule above. After the rebuild, its collection loads with no operations: every request to it fails with ",[469,3575,2294],{}," code ",[469,3578,3579],{},"4010",", such as \"readMany operation not found for collection `notes`\", and Engine logs \"Loaded the collection without operations: its stored declaration is unusable. Reintrospect the source to restore them.\" Fix the declaration, then ",[463,3582,3584],{"href":3583},"\u002Fdeveloper\u002Fextensions\u002Fdata-connectors\u002Fdata-sources#update-data-sources-after-an-extension-update","refresh the data source's schema",[454,3586,1501],{"id":3587},"use-keys-and-the-stable-id",[459,3589,505,3590,3592],{},[474,3591,3320],{}," is how Engine addresses one item. It's the collection's primary index or, without one, a unique index. With several unique indexes and no primary index, Engine picks one of them for the collection; declare a primary index to choose.",[459,3594,3595,3596,551,3598,551,3600,3602,3603,3605],{},"The keyed members (",[469,3597,1380],{},[469,3599,1438],{},[469,3601,1476],{},") need more: a primary index on exactly one field, of a type other than ",[469,3604,2251],{},". A unique index isn't enough for them.",[459,3607,3608,3609,3611,3612,521],{},"A ",[469,3610,1380],{}," request for the article with ID ",[469,3613,3614],{},"art_42",[523,3616,3618],{"className":1135,"code":3617,"filename":3168,"language":1138,"meta":529,"style":529},"{\n  \"query\": {\n    \"op\": \"readOne\",\n    \"collection\": \"articles\",\n    \"key\": { \"id\": \"art_42\" },\n    \"select\": [\"id\", \"title\"]\n  }\n}\n",[469,3619,3620,3624,3630,3641,3652,3668,3683,3687],{"__ignoreMap":529},[533,3621,3622],{"class":535,"line":536},[533,3623,1145],{"class":543},[533,3625,3626,3628],{"class":535,"line":604},[533,3627,3179],{"class":1150},[533,3629,1154],{"class":543},[533,3631,3632,3634,3636,3639],{"class":535,"line":611},[533,3633,3186],{"class":1150},[533,3635,3189],{"class":543},[533,3637,3638],{"class":597},"\"readOne\"",[533,3640,870],{"class":543},[533,3642,3643,3645,3647,3650],{"class":535,"line":618},[533,3644,3199],{"class":1150},[533,3646,3189],{"class":543},[533,3648,3649],{"class":597},"\"articles\"",[533,3651,870],{"class":543},[533,3653,3654,3657,3659,3661,3663,3666],{"class":535,"line":624},[533,3655,3656],{"class":1150},"    \"key\"",[533,3658,1162],{"class":543},[533,3660,3233],{"class":1150},[533,3662,3189],{"class":543},[533,3664,3665],{"class":597},"\"art_42\"",[533,3667,801],{"class":543},[533,3669,3670,3672,3674,3676,3678,3680],{"class":535,"line":659},[533,3671,3211],{"class":1150},[533,3673,3242],{"class":543},[533,3675,3233],{"class":597},[533,3677,551],{"class":543},[533,3679,3258],{"class":597},[533,3681,3682],{"class":543},"]\n",[533,3684,3685],{"class":535,"line":705},[533,3686,3271],{"class":543},[533,3688,3689],{"class":535,"line":711},[533,3690,1275],{"class":543},[1701,3692,3693,3699,3707,3720,3735,3747],{},[1704,3694,3695,3698],{},[474,3696,3697],{},"The key names the item."," It has one entry: the primary-key field.",[1704,3700,3701,2327,3704,3706],{},[474,3702,3703],{},"The guard narrows it.",[469,3705,573],{}," beside the key is a condition the item must also match. Otherwise change nothing.",[1704,3708,3709,3715,3716,3719],{},[474,3710,3711,3712,640],{},"Answer one ",[469,3713,3714],{},"record"," Answer ",[469,3717,3718],{},"{ \"record\": \u003Citem> }"," with the item the operation read, updated or deleted.",[1704,3721,3722,3728,3729,3732,3733,640],{},[474,3723,3724,3725,640],{},"A miss answers ",[469,3726,3727],{},"record: null"," When the key matches no item or the item fails the guard, answer ",[469,3730,3731],{},"{ \"record\": null }"," and change nothing. A miss isn't an error, so don't throw. Callers see ",[469,3734,3136],{},[1704,3736,3737,3742,3743,3746],{},[474,3738,3739,3740,640],{},"Never answer ",[469,3741,2964],{}," Engine fails a keyed operation that answers ",[469,3744,3745],{},"{ \"records\": [...] }",", even with one item, and can't undo a write your connector already made.",[1704,3748,3749,3752],{},[474,3750,3751],{},"Compound external keys need a synthetic field for keyed members."," If the external data source identifies an item by several values, expose a single string field that combines them and declare it as the primary index. A composite primary or unique index still works as the stable ID for the other members.",[459,3754,3755,3756,3758],{},"Engine can still read one item through ",[469,3757,1351],{}," by stable ID, for example to return what an update wrote.",[459,3760,3761,3762,3764,3765,551,3767,1122,3769,3771,3772,3775],{},"A collection without a primary or unique index has no stable ID. It can still declare ",[469,3763,1351],{},". It can declare ",[469,3766,1399],{},[469,3768,1418],{},[469,3770,1458],{}," only when the connector declares the matching ",[463,3773,3774],{"href":2640},"query capability",". Engine then returns what your connector answers for the write, without reading it back.",[454,3777,3779],{"id":3778},"resolve-relations","Resolve Relations",[459,3781,3608,3782,3785,3786,3789,3790,3793,3794,1282,3797,3801],{},[474,3783,3784],{},"relation"," links two collections. A ",[474,3787,3788],{},"to-one"," relation field returns a single related item; a ",[474,3791,3792],{},"to-many"," relation field returns several. You declare relations in the schema document's ",[469,3795,3796],{},"relations",[463,3798,3800],{"href":3799},"\u002Freference\u002Fextensions\u002Fdata-connectors\u002Fapi#relations","Relations"," for the shape.",[459,3803,3804,3805,1748,3808,1122,3811,1748,3813,3816],{},"A relation joins two collections through key fields: ",[469,3806,3807],{},"authorId",[469,3809,3810],{},"articles",[469,3812,516],{},[469,3814,3815],{},"authors"," in the example below.",[459,3818,3819,3820,1578,3822,3824,3825,3827,3828,1122,3830,3832,3833,3835,3836,3838,3839,3841,3842,640],{},"Engine resolves a relation field by filtering the other collection by its key field. It sends a ",[469,3821,1351],{},[469,3823,2005],{}," on the key field, joined with ",[469,3826,1553],{}," to any other conditions. Where the key field's filter declares ",[469,3829,1831],{},[469,3831,1556],{}," but no ",[469,3834,2005],{},", and for a key of several fields, it uses ",[469,3837,1831],{}," on each field, with ",[469,3840,1556],{},", instead of ",[469,3843,2005],{},[459,3845,3846,3847,3849,3850,3852],{},"A to-one include is one batched call. A to-many include with a ",[469,3848,1025],{}," or an ",[469,3851,1040],{}," becomes one call per distinct, non-null parent key, up to 16 of them at a time.",[459,3854,3855,3856,3858,3859,3862,3863,3867],{},"To-many includes carry the default ",[469,3857,1025],{}," of the ",[474,3860,3861],{},"instance"," (your Monospace deployment) unless the caller sets one, so that's the usual case. See ",[463,3864,3866],{"href":3865},"\u002Freference\u002Fextensions\u002Fdata-connectors\u002Fapi#relation-reads","Relation Reads"," for every case.",[459,3869,3870,3871,3874,3875,3878],{},"For a relation from ",[469,3872,3873],{},"articles.authorId"," to ",[469,3876,3877],{},"authors.id",", each direction needs its own call. Declare both rows to offer both relation fields:",[1320,3880,3881,3894],{},[1323,3882,3883],{},[1326,3884,3885,3888,3891],{},[1329,3886,3887],{},"To resolve",[1329,3889,3890],{},"Engine calls",[1329,3892,3893],{},"Declare",[1342,3895,3896,3939],{},[1326,3897,3898,3901,3911],{},[1347,3899,3900],{},"An article's author (to-one)",[1347,3902,3903,1720,3905,1578,3907,1748,3909],{},[469,3904,3815],{},[469,3906,1351],{},[469,3908,2005],{},[469,3910,516],{},[1347,3912,3913,1748,3915,1122,3917,2094,3919,1720,3921,3923,3924,1748,3926,1578,3928,1122,3930,3932,3933,2094,3935,1720,3937],{},[469,3914,2005],{},[469,3916,516],{},[469,3918,1553],{},[469,3920,3815],{},[469,3922,2528],{}," (or ",[469,3925,1831],{},[469,3927,516],{},[469,3929,1553],{},[469,3931,1556],{},"); ",[469,3934,516],{},[469,3936,3815],{},[469,3938,1778],{},[1326,3940,3941,3944,3954],{},[1347,3942,3943],{},"An author's articles (to-many)",[1347,3945,3946,1720,3948,1578,3950,1748,3952],{},[469,3947,3810],{},[469,3949,1351],{},[469,3951,2005],{},[469,3953,3807],{},[1347,3955,3956,1748,3958,1122,3960,2094,3962,1720,3964,3923,3966,1748,3968,1578,3970,1122,3972,3932,3974,2094,3976,1720,3978],{},[469,3957,2005],{},[469,3959,3807],{},[469,3961,1553],{},[469,3963,3810],{},[469,3965,2528],{},[469,3967,1831],{},[469,3969,3807],{},[469,3971,1553],{},[469,3973,1556],{},[469,3975,3807],{},[469,3977,3810],{},[469,3979,1778],{},[459,3981,3982,3983,3985,3986,1748,3988,551,3990,1748,3992,3994,3995,3997],{},"List each relation's key field in the ",[469,3984,1370],{}," of every member of its collection: ",[469,3987,3807],{},[469,3989,3810],{},[469,3991,516],{},[469,3993,3815],{},". A member whose ",[469,3996,1370],{}," lacks the key field doesn't offer the relation.",[1701,3999,4000,4014,4022,4034],{},[1704,4001,4002,4005,4006,1282,4009,4013],{},[474,4003,4004],{},"Unservable relations aren't offered."," Engine accepts a relation direction your declaration can't carry this way. It doesn't offer that direction for reading or for nested ",[469,4007,4008],{},"_update",[463,4010,4012],{"href":4011},"#declare-nested-writes","Declare Nested Writes"," for the other nested writes.",[1704,4015,4016,4019,4020,640],{},[474,4017,4018],{},"Engine logs what's missing."," When the workspace loads, a warning names the collection, what the relation loses, and what to declare. Keys that no declaration can filter are exempt; see ",[463,4021,2512],{"href":3361},[1704,4023,4024,4027,4028,4030,4031,4033],{},[474,4025,4026],{},"Relation keys pair by type name."," Paired fields must be scalar and share a type name (e.g., ",[469,4029,889],{}," doesn't pair with ",[469,4032,2165],{},"). The schema helpers reject mismatches.",[1704,4035,4036,4039],{},[474,4037,4038],{},"No filters across relations."," Callers can't filter through a relation into or out of a data connector collection, so your connector only ever receives filters on the collection's own fields.",[1503,4041,4012],{"id":4042},"declare-nested-writes",[459,4044,4045,4046,551,4048,551,4050,551,4052,1122,4055,4058],{},"Callers can write related items through a relation field with ",[469,4047,1698],{},[469,4049,1694],{},[469,4051,4008],{},[469,4053,4054],{},"_disconnect",[469,4056,4057],{},"_delete",". Engine splits a nested write into separate calls to each collection's own members.",[459,4060,505,4061,4064,4065,4067],{},[474,4062,4063],{},"foreign key"," is the key field on the constrained collection (",[469,4066,3807],{}," in the example). Engine writes it itself, through one member:",[1701,4069,4070,4080,4110],{},[1704,4071,4072,4075,4076,4079],{},[474,4073,4074],{},"On the item being created:"," that collection's ",[469,4077,4078],{},"create.data"," must list it.",[1704,4081,4082,4075,4085,4087,4088,4090,4091,1122,4093,3923,4095,1578,4097,1122,4099,4101,4102,4104,4105,1122,4107,4109],{},[474,4083,4084],{},"On the item being updated:",[469,4086,3376],{}," must list it. Engine addresses the item by its stable ID, so ",[469,4089,3404],{}," also needs the read-back shape on it: ",[469,4092,2005],{},[469,4094,1553],{},[469,4096,1831],{},[469,4098,1553],{},[469,4100,1556],{},") for a single-field stable ID, or ",[469,4103,1831],{}," on each field with ",[469,4106,1553],{},[469,4108,1556],{}," for several.",[1704,4111,4112,4115,4116,4118,4119,4121,4122,4118,4124,1122,4126,640],{},[474,4113,4114],{},"On the target:"," the target's ",[469,4117,4078],{}," for ",[469,4120,1698],{},", and its ",[469,4123,3376],{},[469,4125,1694],{},[469,4127,4054],{},[459,4129,4130,4131,640],{},"Engine offers each nested write only when the declarations below carry it, plus the extra conditions after the table for a to-one relation under an update. The member the write rides in must also list the relation's key field in its ",[469,4132,1370],{},[1320,4134,4135,4145],{},[1323,4136,4137],{},[1326,4138,4139,4142],{},[1329,4140,4141],{},"Nested write",[1329,4143,4144],{},"Needs",[1342,4146,4147,4165,4192,4216,4227],{},[1326,4148,4149,4153],{},[1347,4150,4151],{},[469,4152,1698],{},[1347,4154,4155,4156,4158,4159,4161,4162,4164],{},"The target's ",[469,4157,1399],{},", and the foreign key in the ",[469,4160,1409],{}," of the member that writes it. When the foreign key is on the item being written, the target's ",[469,4163,3341],{}," lists the field it points at",[1326,4166,4167,4171],{},[1347,4168,4169],{},[469,4170,1694],{},[1347,4172,4173,4174,4176,4177,4179,4180,1122,4182,4184,4185,1122,4187,4189,4190],{},"The foreign key in the ",[469,4175,1409],{}," of the member that writes it. When the foreign key is on the target, a unique target field with ",[469,4178,1831],{}," in both ",[469,4181,2528],{},[469,4183,3404],{},", each with ",[469,4186,1553],{},[469,4188,1556],{},". The relation's key fields, and that unique field, can't be ",[469,4191,2251],{},[1326,4193,4194,4198],{},[1347,4195,4196],{},[469,4197,4008],{},[1347,4199,4155,4200,1122,4202,4204,4205,4208,4209,4211,4212,4215],{},[469,4201,1351],{},[469,4203,1418],{},", each able to filter by the relation's key field as in ",[463,4206,3779],{"href":4207},"#resolve-relations",". The target's ",[469,4210,1418],{}," must itself be offered (see ",[463,4213,1340],{"href":4214},"#arguments",")",[1326,4217,4218,4222],{},[1347,4219,4220],{},[469,4221,4057],{},[1347,4223,4155,4224,4226],{},[469,4225,1458],{},", able to filter by the relation's key field the same way",[1326,4228,4229,4233],{},[1347,4230,4231],{},[469,4232,4054],{},[1347,4234,4235,4236,4238,4239,4241],{},"A nullable foreign key, in the ",[469,4237,1409],{}," of the member that writes it. When the foreign key is on the target, the target's ",[469,4240,1418],{}," must also filter by the key field",[1701,4243,4244,4260,4270,4290,4304,4316],{},[1704,4245,4246,1720,4253,551,4255,1122,4257,4259],{},[474,4247,4248,4249,1122,4251,640],{},"A create offers only ",[469,4250,1698],{},[469,4252,1694],{},[469,4254,4008],{},[469,4256,4057],{},[469,4258,4054],{}," exist only in update input.",[1704,4261,4262,4269],{},[474,4263,4264,4265,1695,4267,640],{},"A required to-one relation field offers no ",[469,4266,4057],{},[469,4268,4054],{}," Either would leave the foreign key without a target.",[1704,4271,4272,4275,4276,1695,4278,4280,4281,4283,4284,4286,4287,4289],{},[474,4273,4274],{},"Under an update, a to-one write through a foreign key on the target clears the previous target first."," Before ",[469,4277,1698],{},[469,4279,1694],{}," attaches a new target, Engine clears the foreign key on the target that pointed at the updated item until then. The target's ",[469,4282,3376],{}," must list the foreign key, and its ",[469,4285,3404],{}," must filter by it as in ",[463,4288,3779],{"href":4207},". Otherwise neither write is offered.",[1704,4291,4292,4295,4296,1122,4298,4300,4301,4303],{},[474,4293,4294],{},"One-to-one relations need nullable sides under an update."," When both relation fields are to-one, an update offers ",[469,4297,1698],{},[469,4299,1694],{}," only when both relation fields are nullable. It offers ",[469,4302,4054],{}," only when the other side is nullable as well.",[1704,4305,4306,4311,4312,4315],{},[474,4307,3608,4308,4310],{},[469,4309,1694],{}," that writes the foreign key on the item being written doesn't check the target."," Engine passes the key to your connector as is. Throw ",[469,4313,4314],{},"ForeignKeyConstraintViolation"," when the external data source rejects it.",[1704,4317,4318,4323,4324,4326],{},[474,4319,3608,4320,4322],{},[469,4321,1694],{}," that writes the foreign key on the target checks it first."," Engine reads the targets through their ",[469,4325,1351],{},", and fails unless every one exists.",[454,4328,4330],{"id":4329},"name-collections-and-fields","Name Collections and Fields",[459,4332,4333,4334,4336,4337,4340,4341,4344],{},"Each collection, and each field in its ",[469,4335,481],{},", has a ",[469,4338,4339],{},"name"," and an optional ",[469,4342,4343],{},"apiName",". Relation fields are named in the relation instead.",[1701,4346,4347,4363,4378,4384],{},[1704,4348,4349,4354,4355,4357,4358,4360,4361,640],{},[474,4350,4351,4353],{},[469,4352,4339],{}," is what your connector sees."," Every request names collections and fields by ",[469,4356,4339],{},". Items you return are keyed by ",[469,4359,4339],{}," and carry every field in the request's ",[469,4362,2828],{},[1704,4364,4365,4370,4371,4373,4374,640],{},[474,4366,4367,4369],{},[469,4368,4343],{}," is what callers use."," Without one, Engine derives it from ",[469,4372,4339],{}," using the workspace's naming convention, camelCase by default. See ",[463,4375,4377],{"href":4376},"\u002Fconcepts\u002Fintrospection#api-names","API Names",[1704,4379,4380,4383],{},[474,4381,4382],{},"Relation field names are used as declared."," Engine doesn't apply the naming convention to them.",[1704,4385,4386,4389,4390,4392,4393,4396],{},[474,4387,4388],{},"Names collide across data sources."," Collection API names are unique per workspace. When a derived name is taken, for example by another data source's ",[469,4391,3810],{},", Engine prefixes the namespace or appends a suffix (",[469,4394,4395],{},"articles_2",").",[459,4398,4399,4400,4402,4403,4405],{},"Declare ",[469,4401,4339],{}," in camelCase so that ",[469,4404,4339],{}," and the API name match in a camelCase workspace.",[459,4407,4408,4409,1282,4411,640],{},"API names are Monospace's own. A schema migration can rename a collection, field or relation field's API name on a data connector data source, and your connector keeps receiving ",[469,4410,4339],{},[463,4412,4414],{"href":4413},"\u002Freference\u002Fextensions\u002Fdata-connectors\u002Flimitations#no-schema-changes-from-monospace","No Schema Changes from Monospace",[454,4416,4418],{"id":4417},"see-also","See Also",[1701,4420,4421,4427,4434,4441,4446],{},[1704,4422,4423,4426],{},[463,4424,410],{"href":4425},"\u002Freference\u002Fextensions\u002Fdata-connectors\u002Fapi",": handlers, the schema document and the query wire format",[1704,4428,4429,4433],{},[463,4430,4432],{"href":4431},"\u002Freference\u002Fextensions\u002Fdata-connectors\u002Ferrors","Data Connector Errors",": what to throw when a request can't be served",[1704,4435,4436,4440],{},[463,4437,4439],{"href":4438},"\u002Freference\u002Fextensions\u002Fdata-connectors\u002Flimitations","Data Connector Limitations",": what a data connector can't declare",[1704,4442,4443,4445],{},[463,4444,168],{"href":2100},": the caller-side filter syntax",[1704,4447,4448,4450],{},[463,4449,246],{"href":512},": turn an external data source's query grammar into a declaration",[4452,4453,4454],"style",{},"html pre.shiki code .sLVBU, html code.shiki .sLVBU{--shiki-light:#0891B2;--shiki-default:#0891B2;--shiki-dark:#22D3EE}html pre.shiki code .sTMul, html code.shiki .sTMul{--shiki-light:#1F2937;--shiki-default:#1F2937;--shiki-dark:#94A3B8}html pre.shiki code .sNJ9c, html code.shiki .sNJ9c{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E2E8F0}html pre.shiki code .suKVh, html code.shiki .suKVh{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#F8FAFC}html pre.shiki code .seNfP, html code.shiki .seNfP{--shiki-light:#64748B;--shiki-default:#64748B;--shiki-dark:#94A3B8}html pre.shiki code .ssBNi, html code.shiki .ssBNi{--shiki-light:#1659E9;--shiki-default:#1659E9;--shiki-dark:#94B3F5}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .snHjA, html code.shiki .snHjA{--shiki-light:#124BC4;--shiki-default:#124BC4;--shiki-dark:#5B8EF4}",{"title":529,"searchDepth":604,"depth":604,"links":4456},[4457,4458,4462,4463,4469,4474,4475,4478,4479],{"id":456,"depth":604,"text":457},{"id":1314,"depth":604,"text":1315,"children":4459},[4460,4461],{"id":1505,"depth":611,"text":1340},{"id":1796,"depth":611,"text":1797},{"id":2104,"depth":604,"text":2105},{"id":2287,"depth":604,"text":2288,"children":4464},[4465,4466,4467,4468],{"id":2310,"depth":611,"text":2311},{"id":2392,"depth":611,"text":2393},{"id":2511,"depth":611,"text":2512},{"id":2700,"depth":611,"text":2701},{"id":2811,"depth":604,"text":2641,"children":4470},[4471,4472,4473],{"id":2908,"depth":611,"text":2909},{"id":3278,"depth":611,"text":3279},{"id":3462,"depth":611,"text":3463},{"id":3587,"depth":604,"text":1501},{"id":3778,"depth":604,"text":3779,"children":4476},[4477],{"id":4042,"depth":611,"text":4012},{"id":4329,"depth":604,"text":4330},{"id":4417,"depth":604,"text":4418},"Reference for the operations a data connector collection declares, the filter operators each field type allows, and the rules Engine enforces on a declaration.","md",null,{},{"icon":176},{"title":414,"description":4480},"MUv6kD92O_icmHcHCH0M_Mhx7NcZoeA4jDahE9purAI",[4488,4490],{"title":410,"path":411,"stem":412,"description":4489,"icon":81,"children":-1},"Reference for the dataConnector entry, what setup and the handlers must do, the schema document, and the query requests a data connector receives and answers.",{"title":148,"path":418,"stem":419,"description":4491,"icon":420,"children":-1},"Reference for the error classes a data connector extension throws, their codes, and how Engine treats and reports each one.",1790840089103]